<..signals messages: 2--4..>
"Illegal storage address\n", 2 segmentation
"Floating-point\n", 3
"Interrupt with Cntr-C\n", 4
-_-_-
<..warn and err messages..>
<.command line options.>, 0
"Insufficient memory\n", 1
<.signals messages: 2--4.>
"Can’t find/open file ‘%s’\n", 5
-_-_-
<..defines..>+
#define bad_arg err_arg(0)
#define bad_mem err_i(1)
-_-_-
<..header functions..>+
static void err_i( ARG_I(int) );
-_-_-
<..functions..>+
static void err_i(n) int n
;{ (IGNORED) fprintf(stderr,"--- error --- ");
(IGNORED) fprintf(stderr, "%s", warn_err_mssg[n]);
exit(EXIT_FAILURE);
}
-_-_-
<..header functions..>+
static void err_arg( ARG_I(int) );
-_-_-
<..functions..>+
static void err_arg(n) int n
;{ (IGNORED) fprintf(stderr,"--- error --- ");
(IGNORED) fprintf(stderr, "%s", warn_err_mssg[n]);
exit(EXIT_FAILURE);
}
-_-_-
<..header functions..>+
static void warn_i_str( ARG_II(int,const Q_CHAR *) );
-_-_-
<..functions..>+
static void warn_i_str(n,str)
int n;
const Q_CHAR *str
;{ (IGNORED) fprintf(stderr,"--- warning --- ");
(IGNORED) fprintf(stderr,warn_err_mssg[n], str);
}
-_-_-
<..vars..>+
static const C_CHAR *warn_err_mssg[]={ <.warn and err messages.> "" };
-_-_-
<..resplit argv for windows..>
#ifdef WIN32
/* See comments in tex4ht */
if (argc > 2) {
int i, nargc;
char **nargv, **pnargv, **pargv;
nargv = (char **) xmalloc (2 * argc * sizeof (char *));
pnargv = nargv;
pargv = argv;
*pnargv++ = xstrdup (*pargv++);
*pnargv++ = xstrdup (*pargv++);
nargc = 2;
for (i=2; i < argc; i++) {
char *p, *q, *r;
p = q = *pargv++;
while (*p == ’ ’ || *p == ’\t’) {
p++;
q++;
}
while (*p != ’ ’ && *p != ’\t’ && *p) {
p++;
if (*p == ’\0’) {
*pnargv++ = xstrdup(q);
nargc++;
} else if (*p == ’ ’ || *p == ’\t’) {
r = p;
while (*p == ’ ’ || *p == ’\t’)
p++;
if (*p == ’-’ || *p == ’\0’) {
*r = ’\0’;
*pnargv++ = xstrdup(q);
nargc++;
q = p;
}
}
}
}
nargv[nargc] = NULL;
argv = nargv;
argc = nargc;
}
#endif
-_-_-
<..h-include..>+
#include <signal.h>
-_-_-
<..header functions..>+
static void
<.CDECL.>
sig_err(ARG_I(int));
-_-_-
<..functions..>+
static void
<.CDECL.>
sig_err(s) int s
;{
(void) signal(s,SIG_IGN); ignore the signal
switch( s ){
#ifdef SIGSEGV
case SIGSEGV: err_i(2);
#endif
case SIGFPE : err_i(3);
#if defined(SIGINT) && !defined(WIN32)
case SIGINT : err_i(4);
#endif
}
<.DJGPP signals.>
}
-_-_-
Forgetting ‘_pascal’ and ‘_cdecl’ modifiers: Each C function may be either ‘_pascal’ or ‘_cdecl’. This modifier defines how parameters are passed to it. Default for Smalltalk definition is ‘_cdecl’. Default for C functions depends on compiler settings, and you can use other types uncompatible with Smalltalk. In Windows API 16-bit functions are ‘_pascal’ and 32-bit ‘_cdecl’.
<..CDECL..>
#ifdef CDECL
CDECL
#endif
-_-_-
<..set signals..>
#ifdef SIGSEGV
(void) signal(SIGSEGV,sig_err);
#endif
(void) signal(SIGFPE,sig_err);
#ifdef KWIN32
<.KWIN32 signals.>
#else
#ifdef SIGINT
(void) signal(SIGINT,sig_err); Control-c, user interrupt
#endif
#endif
-_-_-
SIGFPE is handled by the C library, SIGSEGV too but not generated by the system, so it does nothing but is harmless
SetConsoleCtrlHandler is need to catch Ctrl+C and Ctrl+Break under Windows, SIGINT is not generated by the system.
<..KWIN32 signals..>
SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler, TRUE);
-_-_-
SIGSEGV, SIGILL, SIGTERM not implemented in MS-DOS. They are supplied just for compatibility. Looks like that SIGINT is defined for windows but not for dos. [more]
Msvc recommends not using printf, but we ignoring this recommendation here with the assumption that the recommendation relates to I/O interrupts that are not considered here.
<..header functions..>+
#ifdef KWIN32
static BOOL sigint_handler(ARG_I(DWORD));
#endif
-_-_-
<..functions..>+
#ifdef KWIN32
static BOOL sigint_handler(dwCtrlType) DWORD dwCtrlType
;{
err_i(32);
return FALSE; return value obligatory
}
#endif
-_-_-
<..vars..>+
static Q_CHAR command[255];
static int system_return;
-_-_-
The library ‘<stdlib.h>’ includes a function ‘int system(const char *cmdstring);’. When cmdstring is NULL, the return value is 0 iff the platform does not support system calls.
<..vars..>+
static BOOL system_yes;
-_-_-
<..main’s init..>+
{ C_CHAR *yes = NULL;
system_yes = (<.system exist?.>);
}
-_-_-
Solaris-? issues the command ‘-c: bad option(s)’ if we check for the presence of the system function.
<..system exist?..>
#ifdef SYSTEM_FUNCTION_OK
0
#else
system( yes ) != 0
#endif
-_-_-
<..execute system command..>
(IGNORED) call_sys(command);
-_-_-
<..header functions..>+
static void call_sys(ARG_I(Q_CHAR *));
-_-_-
<..functions..>+
static void call_sys(command) Q_CHAR * command
;{
if( *command ){
(IGNORED) printf("System call: %s\n", command);
system_return = system_yes? (int) system(command) : -1;
(IGNORED) printf("%sSystem return: %d\n",
system_return? "--- Warning --- " : "", system_return );
if( always_call_sys ){ system_return = 0; }
}
}
-_-_-
<..vars..>+
static BOOL always_call_sys = FALSE;
-_-_-
<..defines..>+
#define eq_str(x,y) (!strcmp(x,y))
-_-_-
strcat should be in string.h, but c++ doesn’t find it there. We use it just for concatenating an extension of file name. Should have the interface ‘char *strcat( ARG_II(C_CHAR *, const Q_CHAR *) );’.
<..header functions..>+
static void strct( ARG_II(C_CHAR *, const C_CHAR *) );
-_-_-
<..functions..>+
static void strct( str1, str2 )
C_CHAR * str1;
const C_CHAR * str2
;{ Q_CHAR * ch;
ch = str1 + (int) strlen((char *) str1);
(IGNORED) strcpy((char *) ch, str2 );
}
-_-_-
<..header functions..>+
static long int get_long_int( ARG_I(Q_CHAR *) );
-_-_-
<..functions..>+
static long int get_long_int(str)
Q_CHAR *str
;{ long int i;
Q_CHAR *ch;
ch = str; i = 0;
while( (*ch>= ’0’) && (*ch <=’9’) ){
i = 10*i + *(ch++) - ’0’;
}
return i;
}
-_-_-
<..defines..>+
#define m_alloc(typ,n) (typ *) malloc_chk((int) ((n) * sizeof(typ)))
-_-_-
<..header functions..>+
static void* malloc_chk(ARG_I(int));
-_-_-
<..functions..>+
static void* malloc_chk( n ) int n
;{ void* p;
if((p = (void *) malloc( (size_t) n)) == NULL ) bad_mem;
return p;
}
-_-_-
<..header functions..>+
static void* r_alloc(ARG_II(void *, size_t));
-_-_-
<..functions..>+
static void* r_alloc( q, n )
void *q;
size_t n
;{ void* p;
if((p = (void *) realloc( q, (size_t) n)) == NULL) bad_mem;
return p;
}
-_-_-
The ftell() and fseek() are not consistent in ms-windows. The ftell() accounts for <cr> and <lf> in the byte stream, where fseek() ignore the �cr� bytes. A READ_BIN_FLAGS instead of READ_TEXT_FLAGS seems to solve the problem.
<..CopyTo read flags..>
READ_BIN_FLAGS
-_-_-
A possible alternative is to define a private fseek.
When failure (false status) arises, the input line is consumed to its end. The _until functions place in ”match[i]’ the string found.
<..header functions..>+
static BOOL scan_until_end_str( ARG_IV(const C_CHAR *, int, BOOL, FILE *) );
-_-_-
<..functions..>+
static BOOL scan_until_end_str(str,n,flag,file)
const C_CHAR *str;
int n;
BOOL flag;
FILE* file
;{ Q_CHAR *p;
int i;
if( !flag ) { return flag; }
p = match[n]; i = 0;
while( TRUE ){
if( (i+1) >= max_match[n] ){
max_match[n] += 10;
p = match[n] = (Q_CHAR *)
r_alloc((void *) match[n], (size_t) max_match[n]);
}
p[i] = (char) (eoln_ch = getc(file));
if( (eoln_ch == (int) ’\n’) || (eoln_ch == EOF) ){ break; }
i++;
}
p[i] = ’\0’;
i -= (int) strlen(str);
if( i>= 0 ){ return eq_str(p+i,str); }
return FALSE;
}
-_-_-
<..vars..>+
static Q_CHAR* match[10];
static int max_match[10];
-_-_-
<..main’s init..>+
{ int i;
for( i=0; i<=9; i++){
match[i] = (Q_CHAR *) malloc(70);
max_match[i] = 70;
}
}
-_-_-
<..header functions..>+
static BOOL scan_until_str( ARG_IV(const C_CHAR *, int, BOOL, FILE *) );
-_-_-
<..functions..>+
static BOOL scan_until_str(str,n,flag,file)
const C_CHAR *str;
int n;
BOOL flag;
FILE* file
;{ Q_CHAR *p, ch;
int i, j;
if( !flag ) { return flag; }
p = match[n]; i = 0;
while( TRUE ){
ch = (char) (eoln_ch = getc(file));
if( (eoln_ch == (int) ’\n’) || (eoln_ch == EOF) ){ return FALSE; }
if( (i+1) >= max_match[n] ){
max_match[n] += 10;
p = match[n] = (Q_CHAR *)
r_alloc((void *) match[n], (size_t) max_match[n]);
}
p[i++] = ch;
j = i - (int) strlen(str);
if( j>= 0 ){
p[i] = ’\0’;
if( eq_str(p+j,str) ) { return TRUE; }
}
}
}
-_-_-
<..header functions..>+
static BOOL scan_str( ARG_III(const C_CHAR *, BOOL, FILE *) );
-_-_-
<..functions..>+
static BOOL scan_str(str,flag,file)
const C_CHAR *str;
BOOL flag;
FILE* file
;{ const Q_CHAR *p;
int temp_eoln_ch;
if( !flag ) { return flag; }
p = str;
while( *p != ’\0’ ){
if( *(p++) != (temp_eoln_ch = getc(file)) ) {
while( (temp_eoln_ch != (int) ’\n’)
&& (temp_eoln_ch != EOF) ){ temp_eoln_ch = getc(file); }
eoln_ch = temp_eoln_ch; return FALSE;
}
}
return TRUE;
}
-_-_-
<..defines..>+
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef BOOL
#define BOOL int
#endif
-_-_-