2013-02-07 10:34:27 +01:00
|
|
|
/************** PlugUtil C Program Source Code File (.C) ***************/
|
|
|
|
/* */
|
|
|
|
/* PROGRAM NAME: PLUGUTIL */
|
|
|
|
/* ------------- */
|
2014-11-15 18:28:24 +01:00
|
|
|
/* Version 2.9 */
|
2013-02-07 10:34:27 +01:00
|
|
|
/* */
|
|
|
|
/* COPYRIGHT: */
|
|
|
|
/* ---------- */
|
2015-03-18 13:30:14 +01:00
|
|
|
/* (C) Copyright to the author Olivier BERTRAND 1993-2015 */
|
2013-02-07 10:34:27 +01:00
|
|
|
/* */
|
|
|
|
/* WHAT THIS PROGRAM DOES: */
|
|
|
|
/* ----------------------- */
|
|
|
|
/* This program are initialization and utility Plug routines. */
|
|
|
|
/* */
|
|
|
|
/* WHAT YOU NEED TO COMPILE THIS PROGRAM: */
|
|
|
|
/* -------------------------------------- */
|
|
|
|
/* */
|
|
|
|
/* REQUIRED FILES: */
|
|
|
|
/* --------------- */
|
|
|
|
/* See Readme.C for a list and description of required SYSTEM files. */
|
|
|
|
/* */
|
|
|
|
/* PLUG.C - Source code */
|
|
|
|
/* GLOBAL.H - Global declaration file */
|
|
|
|
/* OPTION.H - Option declaration file */
|
|
|
|
/* */
|
|
|
|
/* REQUIRED LIBRARIES: */
|
|
|
|
/* ------------------- */
|
|
|
|
/* */
|
|
|
|
/* OS2.LIB - OS2 libray */
|
|
|
|
/* LLIBCE.LIB - Protect mode/standard combined large model C */
|
|
|
|
/* library */
|
|
|
|
/* */
|
|
|
|
/* REQUIRED PROGRAMS: */
|
|
|
|
/* ------------------ */
|
|
|
|
/* */
|
|
|
|
/* IBM C Compiler */
|
|
|
|
/* IBM Linker */
|
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Include relevant MariaDB header file. */
|
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
#include "my_global.h"
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-02-07 10:34:27 +01:00
|
|
|
//#include <windows.h>
|
|
|
|
#else
|
|
|
|
#if defined(UNIX) || defined(UNIV_LINUX)
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
//#define __stdcall
|
|
|
|
#else
|
|
|
|
#include <dir.h>
|
|
|
|
#endif
|
|
|
|
#include <stdarg.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(WIN)
|
|
|
|
#include <alloc.h>
|
|
|
|
#endif
|
|
|
|
#include <errno.h> /* definitions of ERANGE ENOMEM */
|
|
|
|
#if !defined(UNIX) && !defined(UNIV_LINUX)
|
|
|
|
#include <direct.h> /* Directory management library */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Include application header files */
|
|
|
|
/* */
|
|
|
|
/* global.h is header containing all global declarations. */
|
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
#define STORAGE /* Initialize global variables */
|
|
|
|
|
|
|
|
#include "osutil.h"
|
|
|
|
#include "global.h"
|
2014-11-15 18:28:24 +01:00
|
|
|
#if defined(NEWMSG)
|
|
|
|
#include "rcmsg.h"
|
|
|
|
#endif // NEWMSG
|
2013-02-07 10:34:27 +01:00
|
|
|
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-02-07 10:34:27 +01:00
|
|
|
extern HINSTANCE s_hModule; /* Saved module handle */
|
2015-05-27 16:23:38 +02:00
|
|
|
#endif // __WIN__
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
#if defined(XMSG)
|
2014-11-08 13:35:03 +01:00
|
|
|
extern char *msg_path;
|
|
|
|
char *msglang(void);
|
2013-02-07 10:34:27 +01:00
|
|
|
#endif // XMSG
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Local Definitions and static variables */
|
|
|
|
/***********************************************************************/
|
|
|
|
typedef struct {
|
|
|
|
ushort Segsize;
|
|
|
|
ushort Size;
|
|
|
|
} AREASIZE;
|
|
|
|
|
|
|
|
ACTIVITY defActivity = { /* Describes activity and language */
|
|
|
|
NULL, /* Points to user work area(s) */
|
|
|
|
"Unknown"}; /* Application name */
|
|
|
|
|
|
|
|
#if defined(XMSG) || defined(NEWMSG)
|
|
|
|
static char stmsg[200];
|
|
|
|
#endif // XMSG || NEWMSG
|
|
|
|
|
|
|
|
#if defined(UNIX) || defined(UNIV_LINUX)
|
2013-05-13 13:57:49 +02:00
|
|
|
#include "rcmsg.h"
|
2013-02-07 10:34:27 +01:00
|
|
|
#endif // UNIX
|
|
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
/* Tracing output function. */
|
|
|
|
/**************************************************************************/
|
|
|
|
void htrc(char const *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
|
|
|
|
|
|
|
|
//if (trace == 1)
|
|
|
|
// vfprintf(debug, fmt, ap);
|
|
|
|
//else
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
|
|
|
|
va_end (ap);
|
|
|
|
} // end of htrc
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Plug initialization routine. */
|
|
|
|
/* Language points on initial language name and eventual path. */
|
|
|
|
/* Return value is the pointer to the Global structure. */
|
|
|
|
/***********************************************************************/
|
|
|
|
PGLOBAL PlugInit(LPCSTR Language, uint worksize)
|
|
|
|
{
|
|
|
|
PGLOBAL g;
|
|
|
|
|
|
|
|
if (trace > 1)
|
2014-03-22 08:57:32 +01:00
|
|
|
htrc("PlugInit: Language='%s'\n",
|
2013-02-07 10:34:27 +01:00
|
|
|
((!Language) ? "Null" : (char*)Language));
|
|
|
|
|
2017-05-23 19:35:50 +02:00
|
|
|
try {
|
|
|
|
g = new GLOBAL;
|
|
|
|
} catch (...) {
|
|
|
|
fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
|
|
|
|
return NULL;
|
|
|
|
} // end try/catch
|
|
|
|
|
|
|
|
//if (!(g = (PGLOBAL)malloc(sizeof(GLOBAL)))) {
|
|
|
|
// fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL));
|
|
|
|
// return NULL;
|
|
|
|
// } else {
|
2015-12-04 22:38:16 +01:00
|
|
|
g->Sarea = NULL;
|
2013-03-23 19:47:51 +01:00
|
|
|
g->Createas = 0;
|
2014-02-03 16:14:13 +01:00
|
|
|
g->Alchecked = 0;
|
2014-03-22 08:57:32 +01:00
|
|
|
g->Mrr = 0;
|
2017-05-23 19:35:50 +02:00
|
|
|
g->Activityp = NULL;
|
2013-04-09 23:14:45 +02:00
|
|
|
g->Xchk = NULL;
|
2015-02-22 17:53:02 +01:00
|
|
|
g->N = 0;
|
2017-05-23 19:35:50 +02:00
|
|
|
g->More = 0;
|
2013-02-07 10:34:27 +01:00
|
|
|
strcpy(g->Message, "");
|
|
|
|
|
|
|
|
/*******************************************************************/
|
|
|
|
/* Allocate the main work segment. */
|
|
|
|
/*******************************************************************/
|
2015-12-04 22:38:16 +01:00
|
|
|
if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
|
2017-05-23 19:35:50 +02:00
|
|
|
char errmsg[MAX_STR];
|
2013-02-07 10:34:27 +01:00
|
|
|
sprintf(errmsg, MSG(WORK_AREA), g->Message);
|
|
|
|
strcpy(g->Message, errmsg);
|
2014-11-15 18:28:24 +01:00
|
|
|
g->Sarea_Size = 0;
|
|
|
|
} else
|
|
|
|
g->Sarea_Size = worksize;
|
2013-02-07 10:34:27 +01:00
|
|
|
|
2017-05-23 19:35:50 +02:00
|
|
|
//} /* endif g */
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
g->jump_level = -1; /* New setting to allow recursive call of Plug */
|
|
|
|
return(g);
|
|
|
|
} /* end of PlugInit */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* PlugExit: Terminate Plug operations. */
|
|
|
|
/***********************************************************************/
|
|
|
|
int PlugExit(PGLOBAL g)
|
|
|
|
{
|
2013-03-01 22:21:48 +01:00
|
|
|
int rc = 0;
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
if (!g)
|
|
|
|
return rc;
|
|
|
|
|
2013-05-19 19:25:06 +02:00
|
|
|
if (g->Sarea)
|
|
|
|
free(g->Sarea);
|
|
|
|
|
2017-05-23 19:35:50 +02:00
|
|
|
delete g;
|
2013-02-07 10:34:27 +01:00
|
|
|
return rc;
|
|
|
|
} /* end of PlugExit */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Remove the file type from a file name. */
|
|
|
|
/* Note: this routine is not really implemented for Unix. */
|
|
|
|
/***********************************************************************/
|
|
|
|
LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName)
|
|
|
|
{
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-02-07 10:34:27 +01:00
|
|
|
char drive[_MAX_DRIVE];
|
|
|
|
#else
|
|
|
|
char *drive = NULL;
|
|
|
|
#endif
|
|
|
|
char direc[_MAX_DIR];
|
|
|
|
char fname[_MAX_FNAME];
|
|
|
|
char ftype[_MAX_EXT];
|
|
|
|
|
|
|
|
_splitpath(FileName, drive, direc, fname, ftype);
|
|
|
|
|
|
|
|
if (trace > 1) {
|
|
|
|
htrc("after _splitpath: FileName=%s\n", FileName);
|
|
|
|
htrc("drive=%s dir=%s fname=%s ext=%s\n",
|
|
|
|
SVP(drive), direc, fname, ftype);
|
|
|
|
} // endif trace
|
|
|
|
|
|
|
|
_makepath(pBuff, drive, direc, fname, "");
|
|
|
|
|
|
|
|
if (trace > 1)
|
|
|
|
htrc("buff='%s'\n", pBuff);
|
|
|
|
|
|
|
|
return pBuff;
|
|
|
|
} // end of PlugRemoveType
|
|
|
|
|
2013-05-21 16:29:10 +02:00
|
|
|
|
|
|
|
BOOL PlugIsAbsolutePath(LPCSTR path)
|
|
|
|
{
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-05-21 16:29:10 +02:00
|
|
|
return ((path[0] >= 'a' && path[0] <= 'z') ||
|
|
|
|
(path[0] >= 'A' && path[0] <= 'Z')) && path[1] == ':';
|
|
|
|
#else
|
|
|
|
return path[0] == '/';
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-02-07 10:34:27 +01:00
|
|
|
/***********************************************************************/
|
|
|
|
/* Set the full path of a file relatively to a given path. */
|
|
|
|
/* Note: this routine is not really implemented for Unix. */
|
|
|
|
/***********************************************************************/
|
2013-05-21 16:29:10 +02:00
|
|
|
LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
|
2013-02-07 10:34:27 +01:00
|
|
|
{
|
|
|
|
char newname[_MAX_PATH];
|
2014-11-15 18:28:24 +01:00
|
|
|
char direc[_MAX_DIR], defdir[_MAX_DIR], tmpdir[_MAX_DIR];
|
2013-02-07 10:34:27 +01:00
|
|
|
char fname[_MAX_FNAME];
|
|
|
|
char ftype[_MAX_EXT];
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-02-07 10:34:27 +01:00
|
|
|
char drive[_MAX_DRIVE], defdrv[_MAX_DRIVE];
|
|
|
|
#else
|
|
|
|
char *drive = NULL, *defdrv = NULL;
|
|
|
|
#endif
|
|
|
|
|
2017-01-17 19:39:49 +01:00
|
|
|
if (trace > 1)
|
|
|
|
htrc("prefix=%s fn=%s path=%s\n", prefix, FileName, defpath);
|
|
|
|
|
2013-02-07 10:34:27 +01:00
|
|
|
if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) {
|
|
|
|
strcpy(pBuff, FileName); // Remote file
|
|
|
|
return pBuff;
|
|
|
|
} // endif
|
|
|
|
|
2013-05-21 16:29:10 +02:00
|
|
|
if (PlugIsAbsolutePath(FileName))
|
|
|
|
{
|
|
|
|
strcpy(pBuff, FileName); // FileName includes absolute path
|
|
|
|
return pBuff;
|
|
|
|
} // endif
|
2014-03-31 01:20:35 +02:00
|
|
|
|
2015-05-27 16:23:38 +02:00
|
|
|
#if !defined(__WIN__)
|
2014-03-31 01:20:35 +02:00
|
|
|
if (*FileName == '~') {
|
|
|
|
if (_fullpath(pBuff, FileName, _MAX_PATH)) {
|
|
|
|
if (trace > 1)
|
|
|
|
htrc("pbuff='%s'\n", pBuff);
|
|
|
|
|
|
|
|
return pBuff;
|
|
|
|
} else
|
|
|
|
return FileName; // Error, return unchanged name
|
|
|
|
|
|
|
|
} // endif FileName
|
2015-05-27 16:23:38 +02:00
|
|
|
#endif // !__WIN__
|
2014-03-31 01:20:35 +02:00
|
|
|
|
2014-11-15 18:28:24 +01:00
|
|
|
if (prefix && strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
|
2013-05-21 16:29:10 +02:00
|
|
|
{
|
|
|
|
char tmp[_MAX_PATH];
|
|
|
|
int len= snprintf(tmp, sizeof(tmp) - 1, "%s%s%s",
|
|
|
|
prefix, defpath, FileName);
|
|
|
|
memcpy(pBuff, tmp, (size_t) len);
|
|
|
|
pBuff[len]= '\0';
|
|
|
|
return pBuff;
|
|
|
|
}
|
|
|
|
|
2013-02-07 10:34:27 +01:00
|
|
|
_splitpath(FileName, drive, direc, fname, ftype);
|
2014-11-15 18:28:24 +01:00
|
|
|
|
|
|
|
if (defpath) {
|
|
|
|
char c = defpath[strlen(defpath) - 1];
|
|
|
|
|
|
|
|
strcpy(tmpdir, defpath);
|
|
|
|
|
|
|
|
if (c != '/' && c != '\\')
|
|
|
|
strcat(tmpdir, "/");
|
|
|
|
|
|
|
|
} else
|
|
|
|
strcpy(tmpdir, "./");
|
|
|
|
|
|
|
|
_splitpath(tmpdir, defdrv, defdir, NULL, NULL);
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
if (trace > 1) {
|
|
|
|
htrc("after _splitpath: FileName=%s\n", FileName);
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-02-07 10:34:27 +01:00
|
|
|
htrc("drive=%s dir=%s fname=%s ext=%s\n", drive, direc, fname, ftype);
|
|
|
|
htrc("defdrv=%s defdir=%s\n", defdrv, defdir);
|
2015-05-27 16:23:38 +02:00
|
|
|
#else
|
|
|
|
htrc("dir=%s fname=%s ext=%s\n", direc, fname, ftype);
|
2013-02-07 10:34:27 +01:00
|
|
|
#endif
|
|
|
|
} // endif trace
|
|
|
|
|
|
|
|
if (drive && !*drive)
|
|
|
|
strcpy(drive, defdrv);
|
|
|
|
|
|
|
|
switch (*direc) {
|
|
|
|
case '\0':
|
|
|
|
strcpy(direc, defdir);
|
|
|
|
break;
|
|
|
|
case '\\':
|
|
|
|
case '/':
|
|
|
|
break;
|
|
|
|
default:
|
2014-03-22 08:57:32 +01:00
|
|
|
// This supposes that defdir ends with a SLASH
|
2013-02-07 10:34:27 +01:00
|
|
|
strcpy(direc, strcat(defdir, direc));
|
|
|
|
} // endswitch
|
|
|
|
|
|
|
|
_makepath(newname, drive, direc, fname, ftype);
|
|
|
|
|
|
|
|
if (trace > 1)
|
|
|
|
htrc("newname='%s'\n", newname);
|
|
|
|
|
|
|
|
if (_fullpath(pBuff, newname, _MAX_PATH)) {
|
|
|
|
if (trace > 1)
|
|
|
|
htrc("pbuff='%s'\n", pBuff);
|
|
|
|
|
|
|
|
return pBuff;
|
|
|
|
} else
|
|
|
|
return FileName; // Error, return unchanged name
|
|
|
|
|
|
|
|
} // end of PlugSetPath
|
|
|
|
|
|
|
|
#if defined(XMSG)
|
|
|
|
/***********************************************************************/
|
|
|
|
/* PlugGetMessage: get a message from the message file. */
|
|
|
|
/***********************************************************************/
|
2014-03-22 08:57:32 +01:00
|
|
|
char *PlugReadMessage(PGLOBAL g, int mid, char *m)
|
2013-02-07 10:34:27 +01:00
|
|
|
{
|
|
|
|
char msgfile[_MAX_PATH], msgid[32], buff[256];
|
|
|
|
char *msg;
|
|
|
|
FILE *mfile = NULL;
|
|
|
|
|
2014-11-08 13:35:03 +01:00
|
|
|
//GetPrivateProfileString("Message", msglang, "Message\\english.msg",
|
|
|
|
// msgfile, _MAX_PATH, plgini);
|
2014-11-15 18:28:24 +01:00
|
|
|
//strcat(strcat(strcpy(msgfile, msg_path), msglang()), ".msg");
|
|
|
|
strcat(strcpy(buff, msglang()), ".msg");
|
|
|
|
PlugSetPath(msgfile, NULL, buff, msg_path);
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
if (!(mfile = fopen(msgfile, "rt"))) {
|
2014-11-15 18:28:24 +01:00
|
|
|
sprintf(stmsg, "Fail to open message file %s", msgfile);
|
2013-02-07 10:34:27 +01:00
|
|
|
goto err;
|
|
|
|
} // endif mfile
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
if (!fgets(buff, 256, mfile)) {
|
|
|
|
sprintf(stmsg, "Cannot get message %d %s", mid, SVP(m));
|
|
|
|
goto fin;
|
|
|
|
} else
|
|
|
|
if (atoi(buff) == mid)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (sscanf(buff, " %*d %s \"%[^\"]", msgid, stmsg) < 2) {
|
|
|
|
// Old message file
|
|
|
|
if (!sscanf(buff, " %*d \"%[^\"]", stmsg)) {
|
|
|
|
sprintf(stmsg, "Bad message file for %d %s", mid, SVP(m));
|
|
|
|
goto fin;
|
|
|
|
} else
|
|
|
|
m = NULL;
|
|
|
|
|
|
|
|
} // endif sscanf
|
|
|
|
|
|
|
|
if (m && strcmp(m, msgid)) {
|
|
|
|
// Message file is out of date
|
|
|
|
strcpy(stmsg, m);
|
|
|
|
goto fin;
|
|
|
|
} // endif m
|
|
|
|
|
|
|
|
fin:
|
|
|
|
fclose(mfile);
|
|
|
|
|
|
|
|
err:
|
|
|
|
if (g) {
|
|
|
|
// Called by STEP
|
2015-03-18 13:30:14 +01:00
|
|
|
msg = PlugDup(g, stmsg);
|
2013-02-07 10:34:27 +01:00
|
|
|
} else // Called by MSG or PlgGetErrorMsg
|
|
|
|
msg = stmsg;
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
} // end of PlugReadMessage
|
|
|
|
|
|
|
|
#elif defined(NEWMSG)
|
|
|
|
/***********************************************************************/
|
|
|
|
/* PlugGetMessage: get a message from the resource string table. */
|
|
|
|
/***********************************************************************/
|
2014-03-22 08:57:32 +01:00
|
|
|
char *PlugGetMessage(PGLOBAL g, int mid)
|
2013-02-07 10:34:27 +01:00
|
|
|
{
|
|
|
|
char *msg;
|
|
|
|
|
2014-11-15 18:28:24 +01:00
|
|
|
#if 0 // was !defined(UNIX) && !defined(UNIV_LINUX)
|
2013-02-07 10:34:27 +01:00
|
|
|
int n = LoadString(s_hModule, (uint)mid, (LPTSTR)stmsg, 200);
|
|
|
|
|
|
|
|
if (n == 0) {
|
|
|
|
DWORD rc = GetLastError();
|
|
|
|
msg = (char*)PlugSubAlloc(g, NULL, 512); // Extend buf allocation
|
|
|
|
n = sprintf(msg, "Message %d, rc=%d: ", mid, rc);
|
|
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
|
|
|
|
(LPTSTR)(msg + n), 512 - n, NULL);
|
|
|
|
return msg;
|
|
|
|
} // endif n
|
|
|
|
|
2014-11-15 18:28:24 +01:00
|
|
|
#else // ALL
|
2013-02-07 10:34:27 +01:00
|
|
|
if (!GetRcString(mid, stmsg, 200))
|
|
|
|
sprintf(stmsg, "Message %d not found", mid);
|
2014-11-15 18:28:24 +01:00
|
|
|
#endif // ALL
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
if (g) {
|
|
|
|
// Called by STEP
|
2015-03-18 13:30:14 +01:00
|
|
|
msg = PlugDup(g, stmsg);
|
2013-02-07 10:34:27 +01:00
|
|
|
} else // Called by MSG or PlgGetErrorMsg
|
|
|
|
msg = stmsg;
|
|
|
|
|
|
|
|
return msg;
|
|
|
|
} // end of PlugGetMessage
|
|
|
|
#endif // NEWMSG
|
|
|
|
|
2015-05-27 16:23:38 +02:00
|
|
|
#if defined(__WIN__)
|
2013-02-07 10:34:27 +01:00
|
|
|
/***********************************************************************/
|
|
|
|
/* Return the line length of the console screen buffer. */
|
|
|
|
/***********************************************************************/
|
|
|
|
short GetLineLength(PGLOBAL g)
|
|
|
|
{
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO coninfo;
|
|
|
|
HANDLE hcons = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
BOOL b = GetConsoleScreenBufferInfo(hcons, &coninfo);
|
|
|
|
|
|
|
|
return (b) ? coninfo.dwSize.X : 0;
|
|
|
|
} // end of GetLineLength
|
2015-05-27 16:23:38 +02:00
|
|
|
#endif // __WIN__
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Program for memory allocation of work and language areas. */
|
|
|
|
/***********************************************************************/
|
|
|
|
void *PlugAllocMem(PGLOBAL g, uint size)
|
|
|
|
{
|
|
|
|
void *areap; /* Pointer to allocated area */
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
/* This is the allocation routine for the WIN32/UNIX/AIX version. */
|
|
|
|
/*********************************************************************/
|
|
|
|
if (!(areap = malloc(size)))
|
|
|
|
sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
|
|
|
|
|
|
|
|
if (trace > 1) {
|
|
|
|
if (areap)
|
|
|
|
htrc("Memory of %u allocated at %p\n", size, areap);
|
|
|
|
else
|
|
|
|
htrc("PlugAllocMem: %s\n", g->Message);
|
2014-03-22 08:57:32 +01:00
|
|
|
|
2013-02-07 10:34:27 +01:00
|
|
|
} // endif trace
|
|
|
|
|
|
|
|
return (areap);
|
|
|
|
} /* end of PlugAllocMem */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Program for SubSet initialization of memory pools. */
|
|
|
|
/* Here there should be some verification done such as validity of */
|
|
|
|
/* the address and size not larger than memory size. */
|
|
|
|
/***********************************************************************/
|
2013-08-21 17:20:22 +02:00
|
|
|
BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size)
|
2013-02-07 10:34:27 +01:00
|
|
|
{
|
2017-05-23 19:35:50 +02:00
|
|
|
PPOOLHEADER pph = (PPOOLHEADER)memp;
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
pph->To_Free = (OFFSET)sizeof(POOLHEADER);
|
|
|
|
pph->FreeBlk = size - pph->To_Free;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
} /* end of PlugSubSet */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Program for sub-allocating one item in a storage area. */
|
|
|
|
/* Note: SubAlloc routines of OS/2 are no more used to increase the */
|
|
|
|
/* code portability and avoid problems when a grammar compiled under */
|
|
|
|
/* one version of OS/2 is used under another version. */
|
|
|
|
/* The simple way things are done here is also based on the fact */
|
|
|
|
/* that no freeing of suballocated blocks is permitted in Plug. */
|
|
|
|
/***********************************************************************/
|
|
|
|
void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
|
|
|
|
{
|
|
|
|
PPOOLHEADER pph; /* Points on area header. */
|
|
|
|
|
|
|
|
if (!memp)
|
|
|
|
/*******************************************************************/
|
|
|
|
/* Allocation is to be done in the Sarea. */
|
|
|
|
/*******************************************************************/
|
|
|
|
memp = g->Sarea;
|
|
|
|
|
|
|
|
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
|
|
|
|
pph = (PPOOLHEADER)memp;
|
|
|
|
|
2015-05-30 10:59:34 +02:00
|
|
|
if (trace > 3)
|
2014-04-05 19:26:32 +02:00
|
|
|
htrc("SubAlloc in %p size=%d used=%d free=%d\n",
|
|
|
|
memp, size, pph->To_Free, pph->FreeBlk);
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
|
2017-05-23 19:35:50 +02:00
|
|
|
PCSZ pname = "Work";
|
2013-02-07 10:34:27 +01:00
|
|
|
|
|
|
|
sprintf(g->Message,
|
|
|
|
"Not enough memory in %s area for request of %u (used=%d free=%d)",
|
2017-05-23 19:35:50 +02:00
|
|
|
pname, (uint)size, pph->To_Free, pph->FreeBlk);
|
2013-02-07 10:34:27 +01:00
|
|
|
|
2014-04-05 19:26:32 +02:00
|
|
|
if (trace)
|
|
|
|
htrc("PlugSubAlloc: %s\n", g->Message);
|
2013-02-07 10:34:27 +01:00
|
|
|
|
2017-05-23 19:35:50 +02:00
|
|
|
throw 1234;
|
2013-02-07 10:34:27 +01:00
|
|
|
} /* endif size OS32 code */
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
/* Do the suballocation the simplest way. */
|
|
|
|
/*********************************************************************/
|
|
|
|
memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */
|
2017-05-23 19:35:50 +02:00
|
|
|
pph->To_Free += (OFFSET)size; /* New offset of pool free block */
|
|
|
|
pph->FreeBlk -= (uint)size; /* New size of pool free block */
|
2014-04-05 19:26:32 +02:00
|
|
|
|
2015-05-30 10:59:34 +02:00
|
|
|
if (trace > 3)
|
2014-04-05 19:26:32 +02:00
|
|
|
htrc("Done memp=%p used=%d free=%d\n",
|
|
|
|
memp, pph->To_Free, pph->FreeBlk);
|
|
|
|
|
2013-02-07 10:34:27 +01:00
|
|
|
return (memp);
|
|
|
|
} /* end of PlugSubAlloc */
|
|
|
|
|
2015-03-18 13:30:14 +01:00
|
|
|
/***********************************************************************/
|
|
|
|
/* Program for sub-allocating and copying a string in a storage area. */
|
|
|
|
/***********************************************************************/
|
|
|
|
char *PlugDup(PGLOBAL g, const char *str)
|
|
|
|
{
|
|
|
|
if (str) {
|
|
|
|
char *sm = (char*)PlugSubAlloc(g, NULL, strlen(str) + 1);
|
|
|
|
|
|
|
|
strcpy(sm, str);
|
|
|
|
return sm;
|
|
|
|
} else
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
} // end of PlugDup
|
|
|
|
|
|
|
|
#if 0
|
2013-06-16 19:07:27 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
/* This routine suballocate a copy of the passed string. */
|
|
|
|
/***********************************************************************/
|
|
|
|
char *PlugDup(PGLOBAL g, const char *str)
|
|
|
|
{
|
2014-03-22 08:57:32 +01:00
|
|
|
char *buf;
|
2013-06-16 19:07:27 +02:00
|
|
|
size_t len;
|
|
|
|
|
|
|
|
if (str && (len = strlen(str))) {
|
|
|
|
buf = (char*)PlugSubAlloc(g, NULL, len + 1);
|
|
|
|
strcpy(buf, str);
|
|
|
|
} else
|
|
|
|
buf = NULL;
|
|
|
|
|
|
|
|
return(buf);
|
|
|
|
} /* end of PlugDup */
|
2015-03-18 13:30:14 +01:00
|
|
|
#endif // 0
|
2013-06-16 19:07:27 +02:00
|
|
|
|
2013-02-07 10:34:27 +01:00
|
|
|
/***********************************************************************/
|
|
|
|
/* This routine makes a pointer from an offset to a memory pointer. */
|
|
|
|
/***********************************************************************/
|
|
|
|
void *MakePtr(void *memp, OFFSET offset)
|
|
|
|
{
|
|
|
|
return ((offset == 0) ? NULL : &((char *)memp)[offset]);
|
|
|
|
} /* end of MakePtr */
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* This routine makes an offset from a pointer new format. */
|
|
|
|
/***********************************************************************/
|
2013-05-13 13:23:24 +02:00
|
|
|
#if 0
|
2013-02-07 10:34:27 +01:00
|
|
|
OFFSET MakeOff(void *memp, void *ptr)
|
|
|
|
{
|
|
|
|
return ((!ptr) ? 0 : (OFFSET)((char *)ptr - (char *)memp));
|
|
|
|
} /* end of MakeOff */
|
2013-05-13 13:23:24 +02:00
|
|
|
#endif
|
2013-02-07 10:34:27 +01:00
|
|
|
/*--------------------- End of PLUGUTIL program -----------------------*/
|