mud/fluffos-2.23-ds03/edit_source.c
2020-09-06 05:43:07 -07:00

1745 lines
53 KiB
C

#define CONFIGURE_VERSION 5
#define EDIT_SOURCE
#define NO_MALLOC
#define NO_SOCKETS
#define NO_OPCODES
#include "std.h"
#include "lex.h"
#include "preprocess.h"
#include "make_func.h"
#include "cc.h"
#include "hash.h"
#include <stdlib.h>
#include <unistd.h>
#ifdef WIN32
#include <process.h>
#include <malloc.h>
#endif
#if defined(DEBUG) || defined(WIN32)
#define TO_DEV_NULL ""
#else
#define TO_DEV_NULL ">/dev/null 2>&1"
#endif
/* Using an include file at this point would be bad */
#ifdef PEDANTIC
char *malloc(int);
char *realloc(char *, int);
void free(char *);
#endif
char *outp;
static int buffered = 0;
static int nexpands = 0;
FILE *yyin = 0, *yyout = 0;
#define SYNTAX "edit_source [-process file] [-options] [-malloc] [-build_func_spec 'command'] [-build_efuns] [-configure]\n"
/* The files we fool with. (Actually, there are more. See -process).
*
* TODO: teach this file how to fix bugs in the source code :)
*/
#define OPTIONS_INCL "options_incl.h"
#define PACKAGES "packages/packages"
#define OPTIONS_H "options.h"
#define LOCAL_OPTIONS "local_options"
#define OPTION_DEFINES "option_defs.c"
#define FUNC_SPEC "func_spec.c"
#define FUNC_SPEC_CPP "func_spec.cpp"
#define EFUN_TABLE "efunctions.h"
#define OPC_PROF "opc.h"
#define OPCODES "opcodes.h"
#define EFUN_PROTO "efun_protos.h"
#define EFUN_DEFS "efun_defs.c"
#define PRAGMA_NOTE_CASE_START 1
int num_packages = 0;
char *packages[100];
char ppchar;
char *current_file = 0;
int current_line;
int grammar_mode = 0; /* which section we're in for .y files */
int in_c_case, cquote, pragmas, block_nest;
char yytext[MAXLINE];
static char defbuf[DEFMAX];
typedef struct incstate_t {
struct incstate_t *next;
FILE *yyin;
int line;
char *file;
} incstate;
static incstate *inctop = 0;
#define CHAR_QUOTE 1
#define STRING_QUOTE 2
static void add_define (const char *, int, const char *);
#ifdef WIN32
#include <io.h>
int compile(char *command) {
FILE *tf = fopen("trash_me.bat","wt+");
fprintf(tf,"%s%s\n%s",
"@echo off\n",
command,
"if errorlevel == 1 goto error\n"
"del trash_me.err >nul\n"
"goto ok\n"
":error\n"
"echo ERROR > trash_me.err\n"
":ok\n");
fclose(tf);
if (!system("trash_me.bat > nul")) return 1;
if (_access("trash_me.err",0) ) return 1;
return 0;
}
#else
int compile (char * str) {
return system(str);
}
#endif
#if defined(WIN32)
int dos_style_link (char * x, char * y) {
char link_cmd[100];
sprintf(link_cmd, "copy %s %s", x, y);
return system(link_cmd);
}
#endif
void yyerror (const char * str)
{
fprintf(stderr, "%s:%d: %s\n", current_file, current_line, str);
exit(1);
}
void mf_fatal (const char * str)
{
yyerror(str);
}
void yywarn (char * str)
{
/* ignore errors :) local_options generates redefinition warnings,
which we don't want to see */
}
void yyerrorp (const char * str)
{
char buff[200];
sprintf(buff, str, ppchar);
fprintf(stderr, "%s:%d: %s\n", current_file, current_line, buff);
exit(1);
}
static void add_input (const char * p)
{
int l = strlen(p);
if (outp - l < defbuf) yyerror("Macro expansion buffer overflow.\n");
strncpy(outp - l, p, l);
outp -= l;
}
#define SKIPW(foo) while (isspace(*foo)) foo++;
static char *skip_comment(char *tmp, int flag)
{
int c;
for (;;) {
while ((c = *++tmp) != '*') {
if (c == EOF) yyerror("End of file in a comment");
if (c == '\n') {
nexpands = 0;
current_line++;
if (!fgets(yytext, MAXLINE - 1, yyin)) yyerror("End of file in a comment");
if (flag && yyout) fputs(yytext, yyout);
tmp = yytext - 1;
}
}
do {
if ((c = *++tmp) == '/')
return tmp + 1;
if (c == '\n') {
nexpands = 0;
current_line++;
if (!fgets(yytext, MAXLINE - 1, yyin)) yyerror("End of file in a comment");
if (flag && yyout) fputs(yytext, yyout);
tmp = yytext - 1;
}
} while (c == '*');
}
}
static void refill()
{
register char *p, *yyp;
int c;
if (fgets(p = yyp = defbuf + (DEFMAX >> 1), MAXLINE - 1, yyin)) {
while (((c = *yyp++) != '\n') && (c != EOF)) {
if (c == '/') {
if ((c = *yyp) == '*') {
yyp = skip_comment(yyp, 0);
continue;
}
else if (c == '/') break;
}
*p++ = c;
}
}
else yyerror("End of macro definition in \\");
nexpands = 0;
current_line++;
*p = 0;
return;
}
static void handle_define()
{
char namebuf[NSIZE];
char args[NARGS][NSIZE];
char mtext[MLEN];
char *end;
register char *tmp = outp, *q;
q = namebuf;
end = q + NSIZE - 1;
while (isalunum(*tmp)) {
if (q < end) *q++ = *tmp++;
else yyerror("Name too long.\n");
}
if (q == namebuf) yyerror("Macro name missing.\n");
if (*namebuf != '_' && !isalpha(*namebuf)) yyerror("Invalid macro name.\n");
*q = 0;
if (*tmp == '(') { /* if "function macro" */
int arg;
int inid;
char *ids = (char *) NULL;
tmp++; /* skip '(' */
SKIPW(tmp);
if (*tmp == ')') {
arg = 0;
} else {
for (arg = 0; arg < NARGS;) {
end = (q = args[arg]) + NSIZE - 1;
while (isalunum(*tmp) || (*tmp == '#')) {
if (q < end) *q++ = *tmp++;
else yyerror("Name too long.\n");
}
if (q == args[arg]) {
char buff[200];
sprintf(buff, "Missing argument %d in #define parameter list", arg + 1);
yyerror(buff);
}
arg++;
SKIPW(tmp);
if (*tmp == ')')
break;
if (*tmp++ != ',') {
yyerror("Missing ',' in #define parameter list");
}
SKIPW(tmp);
}
if (arg == NARGS) yyerror("Too many macro arguments");
}
tmp++; /* skip ')' */
end = mtext + MLEN - 2;
for (inid = 0, q = mtext; *tmp;) {
if (isalunum(*tmp)) {
if (!inid) {
inid++;
ids = tmp;
}
} else {
if (inid) {
int idlen = tmp - ids;
int n, l;
for (n = 0; n < arg; n++) {
l = strlen(args[n]);
if (l == idlen && strncmp(args[n], ids, l) == 0) {
q -= idlen;
*q++ = MARKS;
*q++ = n + MARKS + 1;
break;
}
}
inid = 0;
}
}
if ((*q = *tmp++) == MARKS) *++q = MARKS;
if (q < end) q++;
else yyerror("Macro text too long");
if (!*tmp && tmp[-2] == '\\') {
q -= 2;
refill();
tmp = defbuf + (DEFMAX >> 1);
}
}
*--q = 0;
add_define(namebuf, arg, mtext);
} else if (isspace(*tmp) || (!*tmp && (*(tmp+1) = '\0', *tmp = ' '))) {
end = mtext + MLEN - 2;
for (q = mtext; *tmp;) {
*q = *tmp++;
if (q < end) q++;
else yyerror("Macro text too long");
if (!*tmp && tmp[-2] == '\\') {
q -= 2;
refill();
tmp = defbuf + (DEFMAX >> 1);
}
}
*q = 0;
add_define(namebuf, -1, mtext);
} else {
yyerror("Illegal macro symbol");
}
return;
}
#define SKPW while (isspace(*outp)) outp++
static int cmygetc() {
int c;
for (;;) {
if ((c = *outp++) == '/') {
if ((c = *outp) == '*') outp = skip_comment(outp, 0);
else if (c == '/') return -1;
else return c;
} else return c;
}
}
/* Check if yytext is a macro and expand if it is. */
static int expand_define()
{
defn_t *p;
char expbuf[DEFMAX];
char *args[NARGS];
char buf[DEFMAX];
char *q, *e, *b;
if (nexpands++ > EXPANDMAX) yyerror("Too many macro expansions");
if (!(p = lookup_define(yytext))) return 0;
if (p->nargs == -1) {
add_input(p->exps);
} else {
int c, parcnt = 0, dquote = 0, squote = 0;
int n;
SKPW;
if (*outp++ != '(') yyerror("Missing '(' in macro call");
SKPW;
if ((c = *outp++) == ')')
n = 0;
else {
q = expbuf;
args[0] = q;
for (n = 0; n < NARGS;) {
switch (c) {
case '"':
if (!squote)
dquote ^= 1;
break;
case '\'':
if (!dquote)
squote ^= 1;
break;
case '(':
if (!squote && !dquote)
parcnt++;
break;
case ')':
if (!squote && !dquote)
parcnt--;
break;
case '#':
if (!squote && !dquote) {
*q++ = c;
if (*outp++ != '#') yyerror("'#' expected");
}
break;
case '\\':
if (squote || dquote) {
*q++ = c;
c = *outp++;
} break;
case '\n':
if (squote || dquote) yyerror("Newline in string");
break;
}
if (c == ',' && !parcnt && !dquote && !squote) {
*q++ = 0;
args[++n] = q;
} else if (parcnt < 0) {
*q++ = 0;
n++;
break;
} else {
if (c == EOF) yyerror("Unexpected end of file");
if (q >= expbuf + DEFMAX - 5) {
yyerror("Macro argument overflow");
} else {
*q++ = c;
}
}
if (!squote && !dquote) {
if ((c = cmygetc()) < 0) yyerror("End of macro in // comment");
}
else c = *outp++;
}
if (n == NARGS) {
yyerror("Maximum macro argument count exceeded");
return 0;
}
}
if (n != p->nargs) {
yyerror("Wrong number of macro arguments");
return 0;
}
/* Do expansion */
b = buf;
e = p->exps;
while (*e) {
if (*e == '#' && *(e + 1) == '#')
e += 2;
if (*e == MARKS) {
if (*++e == MARKS)
*b++ = *e++;
else {
for (q = args[*e++ - MARKS - 1]; *q;) {
*b++ = *q++;
if (b >= buf + DEFMAX) yyerror("Macro expansion overflow");
}
}
} else {
*b++ = *e++;
if (b >= buf + DEFMAX) yyerror("Macro expansion overflow");
}
}
*b++ = 0;
add_input(buf);
}
return 1;
}
static int exgetc()
{
register char c, *yyp;
SKPW;
while (isalpha(c = *outp) || c == '_') {
yyp = yytext;
do {
*yyp++ = c;
} while (isalnum(c = *++outp) || (c == '_'));
*yyp = '\0';
if (!strcmp(yytext, "defined")) {
/* handle the defined "function" in #/%if */
SKPW;
if (*outp++ != '(') yyerror("Missing ( after 'defined'");
SKPW;
yyp = yytext;
if (isalpha(c = *outp) || c == '_') {
do {
*yyp++ = c;
} while (isalnum(c = *++outp) || (c == '_'));
*yyp = '\0';
}
else yyerror("Incorrect definition macro after defined(\n");
SKPW;
if (*outp != ')') yyerror("Missing ) in defined");
if (lookup_define(yytext))
add_input("1 ");
else
add_input("0 ");
} else {
if (!expand_define())
add_input("0 ");
else SKPW;
}
}
return c;
}
static int skip_to(const char *token, const char *atoken)
{
char b[20], *p, *end;
int c;
int nest;
for (nest = 0;;) {
if (!fgets(outp = defbuf + (DEFMAX >> 1), MAXLINE-1,yyin)) {
yyerror("Unexpected end of file while skipping");
}
current_line++;
if ((c = *outp++) == ppchar) {
while (isspace(*outp)) outp++;
end = b + sizeof b - 1;
for (p = b; (c = *outp++) != '\n' && !isspace(c) && c != EOF;) {
if (p < end) *p++ = c;
}
*p = 0;
if (!strcmp(b, "if") || !strcmp(b, "ifdef") || !strcmp(b, "ifndef")) {
nest++;
} else if (nest > 0) {
if (!strcmp(b, "endif"))
nest--;
} else {
if (!strcmp(b, token)) {
*--outp = c;
add_input(b);
*--outp = ppchar;
buffered = 1;
return 1;
} else if (atoken && !strcmp(b, atoken)) {
*--outp = c;
add_input(b);
*--outp = ppchar;
buffered = 1;
return 0;
} else if (!strcmp(b, "elif")) {
*--outp = c;
add_input(b);
*--outp = ppchar;
buffered = 1;
return !atoken;
}
}
}
}
}
#include "preprocess.c"
static int maybe_open_input_file (const char * fn) {
if ((yyin = fopen(fn, "r")) == NULL) {
return 0;
}
if (current_file) free((char *)current_file);
current_file = (char *)malloc(strlen(fn) + 1);
current_line = 0;
strcpy(current_file, fn);
return 1;
}
static void open_input_file (const char * fn) {
if (!maybe_open_input_file(fn)) {
perror(fn);
exit(-1);
}
}
static void open_output_file (const char * fn) {
if ((yyout = fopen(fn, "w")) == NULL) {
perror(fn);
exit(-1);
}
}
static void close_output_file() {
fclose(yyout);
yyout = 0;
}
static char *protect (const char * p) {
static char buf[1024];
char *bufp = buf;
while (*p) {
if (*p=='"' || *p == '\\') *bufp++ = '\\';
*bufp++ = *p++;
}
*bufp = 0;
return buf;
}
static void
create_option_defines() {
defn_t *p;
int count = 0;
int i;
fprintf(stderr, "Writing build options to %s ...\n", OPTION_DEFINES);
open_output_file(OPTION_DEFINES);
fprintf(yyout, "{\n");
for (i = 0; i < DEFHASH; i++) {
for (p = defns[i]; p; p = p->next)
if (!(p->flags & DEF_IS_UNDEFINED)) {
count++;
fprintf(yyout, " \"__%s__\", \"%s\",\n",
p->name, protect(p->exps));
if (strncmp(p->name, "PACKAGE_", 8)==0) {
int len;
char *tmp, *t;
len = strlen(p->name + 8);
t = tmp = (char *)malloc(len + 1);
strcpy(tmp, p->name + 8);
while (*t) {
if (isupper(*t))
*t = tolower(*t);
t++;
}
if (num_packages == 100) {
fprintf(stderr, "Too many packages.\n");
exit(-1);
}
packages[num_packages++] = tmp;
}
}
}
fprintf(yyout,"};\n\n#define NUM_OPTION_DEFS %d\n\n", count);
close_output_file();
}
static void deltrail() {
register char *p;
p = outp;
while (*p && !isspace(*p) && *p != '\n') {
p++;
}
*p = 0;
}
static void
handle_include (char * name)
{
char *p;
static char buf[1024];
FILE *f;
incstate *is;
if (*name != '"') {
defn_t *d;
if ((d = lookup_define(name)) && d->nargs == -1) {
char *q;
q = d->exps;
while (isspace(*q))
q++;
handle_include(q);
} else {
yyerrorp("Missing leading \" in %cinclude");
}
return;
}
for (p = ++name; *p && *p != '"'; p++);
if (!*p) yyerrorp("Missing trailing \" in %cinclude");
*p = 0;
if ((f = fopen(name, "r")) != NULL) {
is = (incstate *)
malloc(sizeof(incstate) /*, 61, "handle_include: 1" */);
is->yyin = yyin;
is->line = current_line;
is->file = current_file;
is->next = inctop;
inctop = is;
current_line = 0;
current_file = (char *)malloc(strlen(name) + 1 /*, 62, "handle_include: 2" */);
strcpy(current_file, name);
yyin = f;
} else {
sprintf(buf, "Cannot %cinclude %s", ppchar, name);
yyerror(buf);
}
}
static void
handle_pragma (char * name)
{
if (!strcmp(name, "auto_note_compiler_case_start"))
pragmas |= PRAGMA_NOTE_CASE_START;
else if (!strcmp(name, "no_auto_note_compiler_case_start"))
pragmas &= ~PRAGMA_NOTE_CASE_START;
else if (!strncmp(name, "ppchar:", 7) && *(name + 8))
ppchar = *(name + 8);
else yyerrorp("Unidentified %cpragma");
}
static void
preprocess() {
register char *yyp, *yyp2;
int c;
int cond;
while (buffered ? (yyp = yyp2 = outp) : fgets(yyp = yyp2 = defbuf + (DEFMAX >> 1), MAXLINE-1, yyin)) {
if (!buffered) current_line++;
else buffered = 0;
while (isspace(*yyp2)) yyp2++;
if ((c = *yyp2) == ppchar) {
int quote = 0;
char sp_buf = 0, *oldoutp;
if (c == '%' && yyp2[1] == '%')
grammar_mode++;
outp = 0;
if (yyp != yyp2) yyerrorp("Misplaced '%c'.\n");
while (isspace(*++yyp2));
yyp++;
for (;;) {
if ((c = *yyp2++) == '"') quote ^= 1;
else{
if (!quote && c == '/') {
if (*yyp2 == '*') {
yyp2 = skip_comment(yyp2, 0);
continue;
}
else if (*yyp2 == '/') break;
}
if (!outp && isspace(c)) outp = yyp;
if (c == '\n' || c == EOF) break;
}
*yyp++ = c;
}
if (outp) {
if (yyout) sp_buf = *(oldoutp = outp);
*outp++ = 0;
while (isspace(*outp)) outp++;
}
else outp = yyp;
*yyp = 0;
yyp = defbuf + (DEFMAX >> 1) + 1;
if (!strcmp("define", yyp)) {
handle_define();
} else if (!strcmp("if", yyp)) {
cond = cond_get_exp(0);
if (*outp != '\n') yyerrorp("Condition too complex in %cif");
else handle_cond(cond);
} else if (!strcmp("ifdef", yyp)) {
deltrail();
handle_cond(lookup_define(outp) != 0);
} else if (!strcmp("ifndef", yyp)) {
deltrail();
handle_cond(!lookup_define(outp));
} else if (!strcmp("elif", yyp)) {
handle_elif();
} else if (!strcmp("else", yyp)) {
handle_else();
} else if (!strcmp("endif", yyp)) {
handle_endif();
} else if (!strcmp("undef", yyp)) {
defn_t *d;
deltrail();
if ((d = lookup_definition(outp))) {
d->flags |= DEF_IS_UNDEFINED;
d->flags &= ~DEF_IS_NOT_LOCAL;
} else {
add_define(outp, -1, " ");
d = lookup_definition(outp);
d->flags |= DEF_IS_UNDEFINED;
d->flags &= ~DEF_IS_NOT_LOCAL;
}
} else if (!strcmp("echo", yyp)) {
fprintf(stderr, "echo at line %d of %s: %s\n", current_line, current_file, outp);
} else if (!strcmp("include", yyp)) {
handle_include(outp);
} else if (!strcmp("pragma", yyp)) {
handle_pragma(outp);
} else if (yyout) {
if (!strcmp("line", yyp)) {
fprintf(yyout, "#line %d \"%s\"\n", current_line,
current_file);
} else {
if (sp_buf) *oldoutp = sp_buf;
if (pragmas & PRAGMA_NOTE_CASE_START) {
if (*yyp == '%') pragmas &= ~PRAGMA_NOTE_CASE_START;
}
fprintf(yyout, "%s\n", yyp-1);
}
} else {
char buff[200];
sprintf(buff, "Unrecognised %c directive : %s\n", ppchar, yyp);
yyerror(buff);
}
}
else if (c == '/') {
if ((c = *++yyp2) == '*') {
if (yyout) fputs(yyp, yyout);
yyp2 = skip_comment(yyp2, 1);
} else if (c == '/' && !yyout) continue;
else if (yyout) {
fprintf(yyout, "%s", yyp);
}
}
else if (yyout) {
fprintf(yyout, "%s", yyp);
if (pragmas & PRAGMA_NOTE_CASE_START) {
static int line_to_print;
line_to_print = 0;
if (!in_c_case) {
while (isalunum(*yyp2)) yyp2++;
while (isspace(*yyp2)) yyp2++;
if (*yyp2 == ':') {
in_c_case = 1;
yyp2++;
}
}
if (in_c_case) {
while ((c = *yyp2++)) {
switch(c) {
case '{':
{
if (!cquote && (++block_nest == 1))
line_to_print = 1;
break;
}
case '}':
{
if (!cquote) {
if (--block_nest < 0) yyerror("Too many }'s");
}
break;
}
case '"':
if (!(cquote & CHAR_QUOTE)) cquote ^= STRING_QUOTE;
break;
case '\'':
if (!(cquote & STRING_QUOTE)) cquote ^= CHAR_QUOTE;
break;
case '\\':
if (cquote && *yyp2) yyp2++;
break;
case '/':
if (!cquote) {
if ((c = *yyp2) == '*') {
yyp2 = skip_comment(yyp2, 1);
} else if (c == '/') {
*(yyp2-1) = '\n';
*yyp2 = '\0';
}
}
break;
case ':':
if (!cquote && !block_nest)
yyerror("Case started before ending previous case with ;");
break;
case ';':
if (!cquote && !block_nest) in_c_case = 0;
}
}
}
if (line_to_print)
fprintf(yyout, "#line %d \"%s\"\n", current_line + 1,current_file);
}
}
}
if (iftop) {
ifstate_t *p = iftop;
while (iftop) {
p = iftop;
iftop = p->next;
free((char *)p);
}
yyerrorp("Missing %cendif");
}
fclose(yyin);
free(current_file);
current_file = 0;
nexpands = 0;
if (inctop) {
incstate *p = inctop;
current_file = p->file;
current_line = p->line;
yyin = p->yyin;
inctop = p->next;
free((char *) p);
preprocess();
} else yyin = 0;
}
void make_efun_tables()
{
#define NUM_FILES 5
static const char* outfiles[NUM_FILES] = {
EFUN_TABLE, OPC_PROF, OPCODES, EFUN_PROTO, EFUN_DEFS
};
FILE *files[NUM_FILES];
int i;
fprintf(stderr, "Building efun tables ...\n");
for (i = 0; i < NUM_FILES; i++) {
files[i] = fopen(outfiles[i], "w");
if (!files[i]) {
fprintf(stderr, "make_func: unable to open %s\n", outfiles[i]);
exit(-1);
}
fprintf(files[i],
"/*\n\tThis file is automatically generated by make_func.\n");
fprintf(files[i],
"\tdo not make any manual changes to this file.\n*/\n\n");
}
fprintf(files[0],"\n#include \"efun_protos.h\"\n\n");
fprintf(files[0],"\ntypedef void (*func_t) (void);\n\n");
fprintf(files[0],"func_t efun_table[] = {\n");
fprintf(files[1],"\ntypedef struct opc_s { char *name; int count; } opc_t;\n\n");
fprintf(files[1],"opc_t opc_efun[] = {\n");
fprintf(files[2], "\n/* operators */\n\n");
for (i = 0; i < op_code; i++) {
fprintf(files[2],"#define %-30s %d\n", oper_codes[i], i+1);
}
fprintf(files[2],"\n/* 1 arg efuns */\n#define BASE %d\n\n", op_code+1);
for (i = 0; i < efun1_code; i++) {
fprintf(files[0],"\tf_%s,\n", efun1_names[i]);
fprintf(files[1],"{\"%s\", 0},\n", efun1_names[i]);
fprintf(files[2],"#define %-30s %d\n", efun1_codes[i], i+op_code+1);
fprintf(files[3],"void f_%s (void);\n", efun1_names[i]);
}
fprintf(files[2],"\n/* efuns */\n#define ONEARG_MAX %d\n\n", efun1_code + op_code+1);
for (i = 0; i < efun_code; i++) {
fprintf(files[0],"\tf_%s,\n", efun_names[i]);
fprintf(files[1],"{\"%s\", 0},\n", efun_names[i]);
fprintf(files[2],"#define %-30s %d\n", efun_codes[i], i+op_code+efun1_code+1);
fprintf(files[3],"void f_%s (void);\n", efun_names[i]);
}
fprintf(files[0], "};\n");
fprintf(files[1], "};\n");
if (efun1_code + op_code >= 256) {
fprintf(stderr, "You have way too many efuns. Contact the MudOS developers if you really need this many.\n");
}
if (efun_code >= 256) {
fprintf(stderr, "You have way too many efuns. Contact the MudOS developers if you really need this many.\n");
}
fprintf(files[2],"\n/* efuns */\n#define NUM_OPCODES %d\n\n", efun_code + efun1_code + op_code);
/* Now sort the main_list */
for (i = 0; i < num_buff; i++) {
int j;
for (j = 0; j < i; j++)
if (strcmp(key[i], key[j]) < 0) {
const char *tmp;
tmp = key[i]; key[i] = key[j]; key[j] = tmp;
tmp = buf[i]; buf[i] = buf[j]; buf[j] = tmp;
}
}
/* Now display it... */
fprintf(files[4], "{\n");
for (i = 0; i < num_buff; i++)
fprintf(files[4], "%s", buf[i]);
fprintf(files[4], "\n};\nint efun_arg_types[] = {\n");
for (i=0; i < last_current_type; i++) {
if (arg_types[i] == 0)
fprintf(files[4], "0,\n");
else
fprintf(files[4], "%s,", ctype(arg_types[i]));
}
fprintf(files[4],"};\n");
for (i=0; i < NUM_FILES; i++)
fclose(files[i]);
}
static void handle_local_defines(int check) {
defn_t *p;
int i;
int problem = 0;
for (i = 0; i < DEFHASH; i++)
for (p = defns[i]; p; p = p->next)
p->flags |= DEF_IS_NOT_LOCAL;
/* undefine _OPTIONS_H_ so it doesn't get propagated to the mudlib
or interfere with copies of options.h */
if ((p = lookup_define("_OPTIONS_H_"))) {
p->flags |= DEF_IS_UNDEFINED;
p->flags &= ~DEF_IS_NOT_LOCAL;
}
if ((p = lookup_define("DEBUG")))
p->flags &= ~DEF_IS_NOT_LOCAL;
ppchar = '#';
preprocess();
if ((p = lookup_define("_OPTIONS_H_")))
p->flags |= DEF_IS_UNDEFINED;
if (!check)
return;
for (i = 0; i < DEFHASH; i++)
for (p = defns[i]; p; p = p->next)
if (p->flags & DEF_IS_NOT_LOCAL) {
fprintf(stderr, "No setting for %s in '%s'.\n",
p->name, LOCAL_OPTIONS);
problem = 1;
}
if (problem) {
fprintf(stderr, "\
***This local_options file appears to have been written for an\n\
***earlier version of the MudOS driver. Please lookup the new options\n\
***(mentioned above) in the options.h file, decide how you would like them\n\
***set, and add those settings to the local_options file.\n");
exit(-1);
}
}
static void write_options_incl (int local) {
open_output_file(OPTIONS_INCL);
if (local) {
fprintf(yyout, "#include \"%s\"\n", LOCAL_OPTIONS);
} else {
fprintf(yyout, "#include \"%s\"\n", OPTIONS_H);
}
close_output_file();
}
static void handle_options(int full) {
open_input_file(OPTIONS_H);
ppchar = '#';
preprocess();
if (!full) {
/* don't do any checking, just find out what is defined */
if (maybe_open_input_file(LOCAL_OPTIONS))
handle_local_defines(0);
return;
}
if (maybe_open_input_file(LOCAL_OPTIONS)) {
fprintf(stdout, "Using '%s' file ...\n", LOCAL_OPTIONS);
handle_local_defines(1);
write_options_incl(1);
} else {
fprintf(stderr, "No \"%s\" file present. If you create one from \"%s\",\nyou can use it when you get a new driver, and you will be warned if there are\nchanges to the real %s which you should include in your local file.\n",
LOCAL_OPTIONS, OPTIONS_H, OPTIONS_H);
write_options_incl(0);
}
create_option_defines();
}
static void handle_build_func_spec (char * command) {
char buf[1024];
int i;
fprintf(stderr, "Building compiler files ...\n");
sprintf(buf, "%s %s >%s", command, FUNC_SPEC, FUNC_SPEC_CPP);
system(buf);
for (i = 0; i < num_packages; i++) {
sprintf(buf, "%s -I. packages/%s_spec.c >>%s",
command, packages[i], FUNC_SPEC_CPP);
system(buf);
}
open_output_file(PACKAGES);
fprintf(yyout, "SRC=");
for (i=0; i < num_packages; i++)
fprintf(yyout, "%s.c ", packages[i]);
fprintf(yyout, "\nOBJ=");
for (i=0; i < num_packages; i++)
fprintf(yyout, "%s.$(O) ", packages[i]);
fprintf(yyout, "\n");
close_output_file();
}
static void handle_process (char * file) {
char buf[1024];
int l;
strcpy(buf, file);
l = strlen(buf);
if (strcmp(buf + l - 4, ".pre")) {
fprintf(stderr, "Filename for -process must end in .pre\n");
exit(-1);
}
*(buf + l - 4) = 0;
fprintf(stderr, "Creating '%s' from '%s' ...\n", buf, file);
#ifdef DEBUG
/* pass down the DEBUG define from CFLAGS */
add_define("DEBUG", -1, " ");
#endif
open_input_file(file);
open_output_file(buf);
ppchar = '%';
preprocess();
close_output_file();
}
static void handle_build_efuns() {
void yyparse();
num_buff = op_code = efun_code = efun1_code = 0;
open_input_file(FUNC_SPEC_CPP);
yyparse();
make_efun_tables();
}
static void handle_applies() {
FILE *f = fopen("applies", "r");
FILE *out = fopen("applies.h", "w");
FILE *table = fopen("applies_table.c", "w");
char buf[8192];
char *colon;
char *p;
int apply_number = 0;
fprintf(out, "/* autogenerated from 'applies' */\n#ifndef APPLIES_H\n#define APPLIES_H\n\nextern const char *applies_table[];\n\n/* the folowing must be the first character of __INIT */\n#define APPLY___INIT_SPECIAL_CHAR\t\t'#'\n");
fprintf(table, "/* autogenerated from 'applies' */\n\nconst char *applies_table[] = {\n");
while (fgets(buf, 8192, f)) {
buf[strlen(buf)-1] = 0;
if (buf[0] == '#') break;
if ((colon = strchr(buf, ':'))) {
*colon++ = 0;
fprintf(out, "#define APPLY_%-30s\t\"%s\"\n", buf, colon);
} else {
fprintf(out, "#define APPLY_%-30s\t", buf);
p = buf;
while (*p) {
*p = tolower(*p);
p++;
}
fprintf(out, "\"%s\"\n", buf);
}
}
while (fgets(buf, 8192, f)) {
buf[strlen(buf)-1] = 0;
if ((colon = strchr(buf, ':'))) {
*colon++ = 0;
fprintf(table, "\t\"%s\",\n", colon);
fprintf(out, "#define APPLY_%-30s\t%i\n", buf, apply_number++);
} else {
fprintf(out, "#define APPLY_%-30s\t%i\n", buf, apply_number++);
p = buf;
while (*p) {
*p = tolower(*p);
p++;
}
fprintf(table, "\t\"%s\",\n", buf);
}
}
fprintf(table, "};\n");
fprintf(out, "\n#define NUM_MASTER_APPLIES\t%i\n\n#endif\n", apply_number);
fclose(out);
fclose(table);
fclose(f);
}
static void handle_malloc() {
#ifdef PEDANTIC
int unlink(char *);
int link(char *, char *);
#endif
const char *the_malloc = 0, *the_wrapper = 0;
if (lookup_define("SYSMALLOC"))
the_malloc = "sysmalloc.c";
if (lookup_define("SMALLOC"))
the_malloc = "smalloc.c";
if (lookup_define("BSDMALLOC"))
the_malloc = "bsdmalloc.c";
if (lookup_define("MMALLOC"))
the_malloc = "mmalloc.c";
if(lookup_define("MALLOC64"))
the_malloc = "64bitmalloc.c";
if(lookup_define("MALLOC32"))
the_malloc = "32bitmalloc.c";
if (lookup_define("GNUMALLOC"))
the_malloc = "gnumalloc.c";
if (lookup_define("WRAPPEDMALLOC"))
the_wrapper = "wrappedmalloc.c";
if (lookup_define("DEBUGMALLOC"))
the_wrapper = "debugmalloc.c";
if (!the_malloc && !the_wrapper) {
fprintf(stderr, "Memory package and/or malloc wrapper incorrectly specified in options.h\n");
exit(-1);
}
if (unlink("malloc.c") == -1 && errno != ENOENT)
perror("unlink malloc.c");
if (unlink("mallocwrapper.c") == -1 && errno != ENOENT)
perror("unlink mallocwrapper.c");
if (the_wrapper) {
printf("Using memory allocation package: %s\n\t\tWrapped with: %s\n",
the_malloc, the_wrapper);
if (link(the_wrapper, "mallocwrapper.c") == -1)
perror("link mallocwrapper.c");
} else {
printf("Using memory allocation package: %s\n", the_malloc);
}
if (link(the_malloc, "malloc.c") == -1)
perror("link malloc.c");
}
static int check_include2 (const char * tag, const char * file,
const char * before, const char * after) {
char buf[1024];
FILE *ct;
printf("Checking for include file <%s> ... ", file);
ct = fopen("comptest.c", "w");
fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n%s\n#include <%s>\n%s\n",
before, file, after);
fclose(ct);
sprintf(buf, "%s %s -c comptest.c " TO_DEV_NULL, COMPILER, CFLAGS);
if (!compile(buf)) {
fprintf(yyout, "#define %s\n", tag);
/* Make sure the define exists for later checks */
fflush(yyout);
printf("exists\n");
return 1;
}
printf("does not exist or is unusable\n");
return 0;
}
static int check_include (const char * tag, const char * file) {
char buf[1024];
FILE *ct;
printf("Checking for include file <%s> ... ", file);
ct = fopen("comptest.c", "w");
fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n#include \"file_incl.h\"\n#include <%s>\n", file);
fclose(ct);
sprintf(buf, "%s %s -c comptest.c " TO_DEV_NULL, COMPILER, CFLAGS);
if (!compile(buf)) {
fprintf(yyout, "#define %s\n", tag);
/* Make sure the define exists for later checks */
fflush(yyout);
printf("exists\n");
return 1;
}
printf("does not exist\n");
return 0;
}
static int check_library (const char * lib) {
char buf[1024];
FILE *ct;
printf("Checking for library %s ... ", lib);
ct = fopen("comptest.c", "w");
fprintf(ct, "int main() { return 0; }\n");
fclose(ct);
sprintf(buf, "%s %s comptest.c %s" TO_DEV_NULL, COMPILER, CFLAGS, lib);
if (!compile(buf)) {
fprintf(yyout, " %s", lib);
printf("exists\n");
return 1;
}
printf("does not exist\n");
return 0;
}
#if 0 /* not used any more */
static int check_ret_type (char * tag, char * pre,
char * type, char * func) {
char buf[1024];
FILE *ct;
printf("Checking return type of %s() ...", func);
ct = fopen("comptest.c", "w");
fprintf(ct, "%s\n\n%s%s();\n", pre, type, func);
fclose(ct);
sprintf(buf, "%s %s -c comptest.c >/dev/null 2>&1", COMPILER, CFLAGS);
if (!system(buf)) {
fprintf(yyout, "#define %s\n", tag);
printf("returns %s\n", type);
return 1;
}
printf("does not return %s\n", type);
return 0;
}
#endif
/* This should check a.out existence, not exit value */
static int check_prog (const char * tag, const char * pre, const char * code, int andrun) {
char buf[1024];
FILE *ct;
ct = fopen("comptest.c", "w");
fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n%s\n\nint main() {%s}\n", (pre ? pre : ""), code);
fclose(ct);
sprintf(buf, "%s %s comptest.c -o comptest" TO_DEV_NULL, COMPILER, CFLAGS);
if (!compile(buf) && (!andrun || !system("./comptest"))) {
if (tag) {
fprintf(yyout, "#define %s\n", tag);
fflush(yyout);
}
return 1;
}
return 0;
}
static int check_code (const char * pre, const char * code) {
char buf[1024];
FILE *ct;
int rc;
ct = fopen("comptest.c", "w");
fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n%s\n\nint main() {%s}\n", (pre ? pre : ""), code);
fclose(ct);
sprintf(buf, "%s %s comptest.c -o comptest" TO_DEV_NULL, COMPILER, CFLAGS);
if (compile(buf) || (rc = system("./comptest")) == 127 || rc == -1) {
return -1;
}
return rc;
}
static void check_linux_libc() {
char buf[1024];
FILE *ct;
ct = fopen("comptest.c", "w");
fprintf(ct, "int main() { }\n");
fclose(ct);
sprintf(buf, "%s -g comptest.c -o comptest >/dev/null 2>&1", COMPILER);
if (system(buf)) {
fprintf(stderr, " libg.a/so installed wrong, trying workaround ...\n");
sprintf(buf, "%s -g comptest.c -lc -o comptest >/dev/null 2>&1", COMPILER);
if (system(buf)) {
fprintf(stderr, "*** FAILED.\n");
exit(-1);
}
fprintf(yyout, " -lc");
}
}
static const char *memmove_prog = "\
char buf[80];\n\
strcpy(buf,\"0123456789ABCDEF\");\n\
memmove(&buf[1],&buf[4],13);\n\
if(strcmp(buf,\"0456789ABCDEF\")) exit(-1);\n\
memmove(&buf[8],&buf[6],9);\n\
if(strcmp(buf,\"0456789A9ABCDEF\")) exit(-1);\n\
return 0;\n";
static int check_memmove (const char * tag, const char * str) {
return check_prog(tag, str, memmove_prog, 1);
}
static void find_memmove() {
printf("Checking for memmove() ...");
if (check_memmove(0, "")) {
printf(" exists\n");
return;
}
if (check_memmove("USE_BCOPY", "#define memmove(a,b,c) bcopy(b,a,c)")) {
printf(" simulating via bcopy()\n");
return;
}
printf(" missing; using MudOS's version\n");
fprintf(yyout, "#define MEMMOVE_MISSING\n");
}
static void verbose_check_prog (const char * msg, const char * def, const char * pre,
const char * prog, int andrun) {
printf("%s ...", msg);
if (check_prog(def, pre, prog, andrun))
printf(" exists\n");
else printf(" does not exist\n");
}
static int check_configure_version() {
char buf[1024];
FILE *ct;
ct = fopen("comptest.c", "w");
fprintf(ct, "#include \"configure.h\"\n\n#if CONFIGURE_VERSION < %i\nthrash and die\n#endif\n\nint main() { }\n", CONFIGURE_VERSION);
fclose(ct);
sprintf(buf, "%s %s comptest.c -o comptest " TO_DEV_NULL, COMPILER, CFLAGS);
return !compile(buf);
}
static void handle_configure() {
if (check_configure_version()) return;
open_output_file("configure.h");
#ifndef WIN32
check_include("INCL_STDLIB_H", "stdlib.h");
check_include("INCL_UNISTD_H", "unistd.h");
if (check_include("INCL_TIME_H", "time.h")) {
if (!check_prog(0, "#include <time.h>", "tzset();", 0)) {
if (check_prog(0, 0, "void tzset(); tzset();", 0))
fprintf(yyout, "#define PROTO_TZSET\n#define USE_TZSET\n");
}
else
fprintf(yyout, "#define USE_TZSET\n");
} else {
if (check_prog(0, 0, "void tzset(); tzset();", 0))
fprintf(yyout, "#define PROTO_TZSET\n#define USE_TZSET\n");
}
check_include("INCL_SYS_TIMES_H", "sys/times.h");
check_include("INCL_FCNTL_H", "fcntl.h");
check_include("INCL_SYS_TIME_H", "sys/time.h");
check_include("INCL_DOS_H", "dos.h");
check_include("INCL_USCLKC_H", "usclkc.h");
check_include("INCL_LIMITS_H", "limits.h");
check_include("INCL_LOCALE_H", "locale.h");
if (!check_prog(0, 0, "int x = USHRT_MAX;", 0)) {
if (!check_prog(0, 0, "int x = MAXSHORT;", 0))
check_include("INCL_VALUES_H", "values.h");
fprintf(yyout, "#define USHRT_MAX (MAXSHORT)\n");
}
check_include("INCL_NETINET_IN_H", "netinet/in.h");
check_include("INCL_ARPA_INET_H", "arpa/inet.h");
check_include("INCL_SYS_TYPES_H", "sys/types.h");
check_include("INCL_SYS_IOCTL_H", "sys/ioctl.h");
check_include("INCL_SYS_SOCKET_H", "sys/socket.h");
check_include("INCL_NETDB_H", "netdb.h");
/* TELOPT_NAWS is missing from <arpa/telnet.h> on some systems */
check_include2("INCL_ARPA_TELNET_H", "arpa/telnet.h", "", "int i=TELOPT_NAWS;");
check_include("INCL_SYS_SEMA_H", "sys/sema.h");
check_include("INCL_SYS_SOCKETVAR_H", "sys/socketvar.h");
check_include("INCL_SOCKET_H", "socket.h");
check_include("INCL_RESOLVE_H", "resolve.h");
check_include("INCL_SYS_STAT_H", "sys/stat.h");
/* sys/dir.h is BSD, dirent is sys V. Try to do it the BSD way first. */
/* If that fails, fall back to sys V */
if (check_prog("BSD_READDIR", "#include <sys/dir.h>", "struct direct *d; d->d_namlen;", 0)) {
check_include("INCL_SYS_DIR_H", "sys/dir.h");
} else {
/* could be either of these */
check_include("INCL_DIRENT_H", "dirent.h");
check_include("INCL_SYS_DIRENT_H", "sys/dirent.h");
fprintf(yyout, "#define USE_STRUCT_DIRENT\n");
}
check_include("INCL_SYS_FILIO_H", "sys/filio.h");
check_include("INCL_SYS_SOCKIO_H", "sys/sockio.h");
check_include("INCL_SYS_MKDEV_H", "sys/mkdev.h");
check_include("INCL_SYS_RESOURCE_H", "sys/resource.h");
check_include("INCL_SYS_RUSAGE_H", "sys/rusage.h");
check_include("INCL_SYS_WAIT_H", "sys/wait.h");
check_include("INCL_SYS_CRYPT_H", "sys/crypt.h");
check_include("INCL_CRYPT_H", "crypt.h");
check_include("INCL_MALLOC_H", "my_malloc.h");
/* for NeXT */
if (!check_include("INCL_MACH_MACH_H", "mach/mach.h"))
check_include("INCL_MACH_H", "mach.h");
/* figure out what we need to do to get major()/minor() */
check_include("INCL_SYS_SYSMACROS_H", "sys/sysmacros.h");
#ifdef DEBUG
/* includes just to shut up gcc's warnings on some systems */
check_include("INCL_BSTRING_H", "bstring.h");
#endif
/* Runtime loading support */
if (check_include("INCL_DLFCN_H", "dlfcn.h")) {
if (!check_prog(0, "#include <dlfcn.h>", "int x = RTLD_LAZY;", 0))
fprintf(yyout, "#define RTLD_LAZY 1\n");
} else {
if (!check_prog(0, 0, "int x = RTLD_LAZY;", 0))
fprintf(yyout, "#define RTLD_LAZY 1\n");
}
/* SunOS is missing definition for INADDR_NONE */
printf("Checking for missing INADDR_NONE ... ");
if (!check_prog(0, "#include <netinet/in.h>", "int x = INADDR_NONE;", 0)) {
printf("missing\n");
fprintf(yyout, "#define INADDR_NONE (unsigned int)0xffffffff\n");
} else printf("ok\n");
printf("Checking for random number generator ...");
if (check_prog("DRAND48", 0, "srand48(0);", 0)) {
printf(" using drand48()\n");
} else
if (check_prog("RAND", 0, "srand(0);", 0)) {
printf(" using rand()\n");
} else
if (check_prog("RANDOM", 0, "srandom(0);", 0)) {
printf("using random()\n");
} else {
printf("WARNING: did not find a random number generator\n");
exit(-1);
}
if (check_prog("USE_BSD_SIGNALS", 0, "SIGCHLD; wait3(0, 0, 0);", 0)) {
printf("Using BSD signals.\n");
} else {
printf("Using System V signals.\n");
}
printf("Checking if signal() returns SIG_ERR on error ...");
if (check_prog("SIGNAL_ERROR SIG_ERR", 0, "if (signal(0, 0) == SIG_ERR) ;", 0)) {
printf(" yes\n");
} else {
fprintf(yyout, "#define SIGNAL_ERROR BADSIG\n");
printf(" no\n");
}
printf("Not Checking for inline ...(usage in driver code all broken anyway)");
//if (!check_prog("INLINE inline", "inline void foo() { }", "foo();", 0)) {
//printf(" __inline ...");
//if (!check_prog("INLINE __inline", "__inline void foo() {}", "foo();", 0)) {
fprintf(yyout, "#define INLINE\n");
//}
//}
printf(" const ...\n");
if (!check_prog("CONST const", "int foo(const int *, const int *);", "", 0))
fprintf(yyout, "#define CONST\n");
verbose_check_prog("Checking for strerror()", "HAS_STRERROR",
"", "strerror(12);", 0);
verbose_check_prog("Checking for POSIX getcwd()", "HAS_GETCWD",
"", "getcwd(\"\", 1000);", 0);
verbose_check_prog("Checking for getrusage()", "RUSAGE",
"", "getrusage(0, 0);", 0);
verbose_check_prog("Checking for times()", "TIMES",
"", "times(0);", 0);
verbose_check_prog("Checking for gettimeofday()", "HAS_GETTIMEOFDAY",
"", "gettimeofday(0, 0);", 0);
verbose_check_prog("Checking for fchmod()", "HAS_FCHMOD",
"", "fchmod(0, 0);", 0);
printf("Checking for big or little endian ... ");
if (!check_code("char num[] = { 0x11, 0x22, 0x33, 0x44 }; int *foo = (int *)num;",
"return (*foo == 0x44332211);")) {
printf("big\n");
fprintf(yyout, "#define BIGENDIAN 1\n");
fflush(yyout);
} else printf("little\n");
find_memmove();
#endif
fprintf(yyout, "#define SIZEOF_INT %i\n", sizeof(int));
fprintf(yyout, "#define SIZEOF_PTR %i\n", sizeof(char *));
fprintf(yyout, "#define SIZEOF_SHORT %i\n", sizeof(short));
fprintf(yyout, "#define SIZEOF_FLOAT %i\n", sizeof(float));
fprintf(yyout, "#define SIZEOF_LONG %i\n", sizeof(long));
if (sizeof(unsigned long) == 4)
fprintf(yyout, "#define UINT32 unsigned long\n");
else if (sizeof(unsigned int) == 4)
fprintf(yyout, "#define UINT32 unsigned int\n");
else {
printf("WARNING: could not find a 32 bit integral type.\n");
exit(-1);
}
/* PACKAGE_DB stuff */
if (lookup_define("PACKAGE_DB")) {
/* -I would be nicer for added include paths, but we don't have an easy way to
* set -I paths right now
*/
if (lookup_define("USE_MSQL")) {
if (!(check_include("INCL_LOCAL_MSQL_H", "/usr/local/include/msql.h")
|| check_include("INCL_LOCAL_MSQL_MSQL_H", "/usr/local/msql/include/msql.h")
|| check_include("INCL_LOCAL_MINERVA_MSQL_H", "/usr/local/Minerva/include/msql.h")
|| check_include("INCL_LIB_HUGHES_MSQL_H", "/usr/lib/Hughes/include/msql.h"))) {
fprintf(stderr, "Cannot find msql.h, compilation is going to fail miserably.\n");
}
}
if (lookup_define("USE_MYSQL")) {
if (!(check_include("INCL_LOCAL_MYSQL_H", "/usr/local/include/mysql.h")
|| check_include("INCL_LOCAL_INCLUDE_MYSQL_MYSQL_H", "/usr/local/include/mysql/mysql.h")
|| check_include("INCL_LOCAL_MYSQL_MYSQL_H", "/usr/local/mysql/include/mysql.h")
|| check_include("INCL_MYSQL_MYSQL_H", "/usr/include/mysql/mysql.h")
|| check_include("INCL_MYSQL_INCLUDE_MYSQL_H", "/usr/mysql/include/mysql/mysql.h"))) {
fprintf(stderr, "Cannot find mysql.h, compilation is going to fail miserably.\n");
}
}
if (lookup_define("USE_POSTGRES")) {
if (!(check_include("USE_POSTGRES", "/usr/include/postgresql/libpq-fe.h"))) {
fprintf(stderr,
"Cannot find libpq-fe.h, compilation is going to fail miserably.\n");
}
}
}
fprintf(yyout, "#define CONFIGURE_VERSION %i\n\n", CONFIGURE_VERSION);
close_output_file();
#ifdef WIN32
system("echo Windows detected. Applying libs.");
if (lookup_define("HAVE_ZLIB")){
system("echo -lwsock32 -lws2_32 -lz> system_libs");
}
else system("echo -lwsock32 -lws2_32 > system_libs");
system("copy windows\\configure.h tmp.config.h");
system("type configure.h >> tmp.config.h");
system("del configure.h");
system("rename tmp.config.h configure.h");
#else
open_output_file("system_libs");
check_library("-lresolv");
check_library("-lbsd");
check_library("-lBSD");
check_library("-ly");
/* don't add -lcrypt if crypt() is in libc.a */
if (!check_prog(0, "#include \"lint.h\"",
"char *x = crypt(\"foo\", \"bar\");", 0))
check_library("-lcrypt");
/* don't add -lmalloc if malloc() works */
if (!check_prog(0, "", "char *x = malloc(100);", 0))
check_library("-lmalloc");
/* we don't currently use it anywhere
if (!check_prog(0, "", "void *x = dlopen(0, 0);", 0))
check_library("-ldl");
*/
check_library("-lsocket");
check_library("-linet");
check_library("-lnsl");
check_library("-lnsl_s");
check_library("-lseq");
check_library("-lm");
if (lookup_define("CYGWIN"))
check_library("-liconv");
if (lookup_define("MINGW")){
check_library("-lwsock32");
check_library("-lws2_32");
}
if (lookup_define("HAVE_ZLIB"))
check_library("-lz");
if (lookup_define("PACKAGE_ASYNC"))
check_library("-lpthread");
if (lookup_define("PACKAGE_HASH"))
check_library("-lssl");
if (lookup_define("PACKAGE_PCRE"))
check_library("-lpcre");
fprintf(stderr, "Checking for flaky Linux systems ...\n");
check_linux_libc();
/* PACKAGE_DB stuff */
if (lookup_define("PACKAGE_DB") && lookup_define("USE_MSQL")) {
if (!(check_library("-lmsql") ||
check_library("-L/usr/local/lib -lmsql") ||
check_library("-L/usr/local/msql/lib -lmsql") ||
check_library("-L/usr/local/Minerva/lib -lmsql") ||
check_library("-L/usr/lib/Hughes/lib -lmsql"))) {
fprintf(stderr, "Cannot find libmsql.a, compilation is going to fail miserably\n");
}
}
if (lookup_define("PACKAGE_DB") && lookup_define("USE_MYSQL")) {
if (!(check_library("-lmysqlclient") ||
check_library("-L/usr/local/lib -lmysqlclient") ||
check_library("-L/usr/local/lib/mysql -lmysqlclient") ||
check_library("-L/usr/local/mysql/lib -lmysqlclient") ||
check_library("-L/usr/lib64/mysql -lmysqlclient") ||
check_library("-L/usr/lib/mysql -lmysqlclient") ||
check_library("-L/usr/mysql/lib/64/mysql -lmysqlclient"))) {
fprintf(stderr, "Cannot find libmysqlclient.a, compilation is going to fail miserably\n");
}
}
if (lookup_define("PACKAGE_DB") && lookup_define("USE_POSTGRES")) {
if (!(check_library("-lpq"))) {
fprintf(stderr, "Cannot find libpq.a, compilation is going to fail miserably\n");
}
}
fprintf(yyout, "\n\n");
close_output_file();
#endif
}
int main (int argc, char ** argv) {
int idx = 1;
while (idx < argc) {
if (argv[idx][0] != '-') {
fprintf(stderr, SYNTAX);
exit(-1);
}
if (strcmp(argv[idx], "-configure")==0) {
handle_options(0);
handle_configure();
} else
if (strcmp(argv[idx], "-process")==0) {
handle_process(argv[++idx]);
} else
if (strcmp(argv[idx], "-options")==0) {
handle_options(1);
} else
if (strcmp(argv[idx], "-malloc")==0) {
handle_malloc();
} else
if (strcmp(argv[idx], "-build_applies")==0) {
handle_applies();
} else
if (strcmp(argv[idx], "-build_func_spec")==0) {
handle_build_func_spec(argv[++idx]);
} else
if (strcmp(argv[idx], "-build_efuns")==0) {
handle_build_efuns();
} else {
fprintf(stderr, "Unrecognized flag %s\n", argv[idx]);
exit(-1);
}
idx++;
}
printf("\n");
return 0;
}