home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 48
/
Amiga_Dream_48.iso
/
Atari
/
c
/
cpp.zoo
/
src
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-03
|
6KB
|
287 lines
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include "global.h"
#include "ztype.h"
#include "patchlev.h"
FILE *outf = stdout;
FILE *inf = NULL;
char *argv0;
char **I_list;
char date_string[12], time_string[9];
int nerrs;
int sl_style = SL_NORMAL, keep_comments = 0, do_trigraphs = 0, ansi = 0, w_bad_chars = 1, w_nest_cmts = 0, f_cpp_cmts = 0;
static void usage()
{
fprintf(stderr, "usage: %s [-Dname[=value]...] [-Uname] "
"[ infile [ outfile ] ]\n", argv0
);
exit(1);
}
static void dammit(sig)
int sig;
{
fatal("received signal %d", sig);
}
static void setup_signals()
{
signal(SIGHUP, dammit);
signal(SIGINT, dammit);
signal(SIGQUIT, dammit);
signal(SIGILL, dammit);
signal(SIGTRAP, dammit);
signal(SIGABRT, dammit);
signal(SIGEMT, dammit);
signal(SIGFPE, dammit);
signal(SIGBUS, dammit);
signal(SIGSEGV, dammit);
signal(SIGSYS, dammit);
signal(SIGPIPE, dammit);
signal(SIGALRM, dammit);
signal(SIGTERM, dammit);
}
/* add_include() -- adds |path| to the list of include directories */
static void add_include(path)
char *path;
{
static char **cur_I = NULL;
static int n_I;
ptrdiff_t dp;
if (!cur_I)
cur_I = I_list = (char **)mallok((n_I = 3) * sizeof (char *));
if (cur_I - I_list == n_I) {
dp = cur_I - I_list;
I_list = reallok(I_list, (n_I *= 2) * sizeof (char *));
cur_I = I_list + dp;
}
*cur_I++ = path;
}
/* long_option() -- parses long option |s| */
static void long_option(s)
char *s;
{
int yesno = 1;
char *t;
if (*s == 'W' || *s == 'f') {
if (s[1] == 'n' && s[2] == 'o' && s[3] == '-') {
yesno = 0;
t += 4;
} else
t = s + 1;
if (*s == 'W') { /* warnings */
if (streq(t, "bad-chars"))
w_bad_chars = yesno;
else if (streq(t, "nested-comments"))
w_nest_cmts = yesno;
else {
error("unknown -W option: %s", t);
usage();
}
} else { /* actions */
if (streq(t, "c++-comments"))
f_cpp_cmts = yesno;
else {
error("unknown -f option: %s", t);
usage();
}
}
} else if (streq(s, "ansi")) {
ansi = 1;
do_trigraphs ^= 1;
} else {
error("unrecognized option -%s", s);
usage();
}
}
/*
opt_define() -- handle -Dfred. |s| points to the beginning of the token
to #define.
*/
static void opt_define(s)
char *s;
{
Macro *M, *M1;
char *t;
unsigned int hv;
int hmm = 0;
hv = hash_id(s, &t);
if (*t && *t != '=') {
error("malformed -D option \"%s\"", s);
return;
}
if (*t)
*t++ = '\0';
else
t = "1";
M1 = (Macro *)mallok(sizeof (Macro));
M1->nargs = M1->flags = 0;
M1->m_text = tokenize_string(t);
if (M = lookup(s, hv)) {
/*
guard against re-#definition of magic tokens or previously -U'd tokens
*/
if (M->flags & (UNDEF | MAGIC))
hmm = 1;
if (hmm || !macro_eq(M1, M)) {
if (!hmm)
error("non-identical redefinition of \"%s\"", s);
}
free_tlist(M1->m_text);
free(M1);
return;
}
hash_add(s, hv, M1);
}
/*
opt_undefine() -- handle -Ufred. |s| points to the beginning of the token
to #undef.
*/
static void opt_undefine(s)
char *s;
{
Token T;
Macro *M;
int was_there = 0;
unsigned int hv;
hv = hash_id(s, NULL);
if (M = lookup(s, hv)) {
if (M->flags & MAGIC)
return;
if (M->m_text)
free_tlist(M->m_text);
was_there = 1;
} else {
M = (Macro *)mallok(sizeof (Macro));
M->nargs = M->flags = 0;
}
M->m_text = NULL;
M->flags |= UNDEF;
if (!was_there)
hash_add(s, hv, M);
}
/* main() -- guess... */
main(argc, argv)
int argc;
char **argv;
{
int i;
char *infnam;
int num_Is = 3;
char **cur_I, *incdir;
time_t t;
struct tm *T;
argv0 = argv[0];
Z_type_init();
hash_setup();
cond_setup();
setup_signals();
time(&t);
T = localtime(&t);
strftime(date_string, 12, "%b %d %Y", T);
strftime(time_string, 9, "%H:%M:%S", T);
add_include(NULL);
for (i = 1; i < argc && *argv[i] == '-' && argv[i][1] != '\0'; i++) {
switch (argv[i][1]) {
case 'P':
switch (argv[i][2]) {
case '0':
case '\0':
sl_style = SL_NONE;
break;
case '1':
sl_style = SL_NORMAL;
break;
case '2':
sl_style = SL_LINE;
break;
default:
error("bad argument '%c' to -P option", argv[i][2]);
}
break;
case 'C':
keep_comments = 1;
break;
case 'T':
do_trigraphs ^= 1;
break;
case 'I':
add_include(copy_filename(argv[i] + 2, 0), 0);
break;
case 'D':
opt_define(argv[i] + 2);
break;
case 'U':
opt_undefine(argv[i] + 2);
break;
case 'V':
fprintf(stderr, "CPP -- C preprocessor v%d.%d.%d\n"
"(c) 1993 Hacker Ltd., all rights reserved\n",
CPP_VERSION, CPP_RELEASE, CPP_PATCHLEVEL);
break;
default:
long_option(argv[i] + 1);
}
}
hash_clean_undef();
if (incdir = getenv("INCLUDE")) {
char *s = incdir;
size_t len;
while (*s) {
len = strcspn(s, ";,");
add_include(copy_filename(s, len));
s += len;
if (*s)
s++;
}
}
add_include(NULL);
if (argc - i > 2) {
error("too many arguments");
usage();
}
if (i < argc && !streq(argv[i], "-"))
infnam = copy_filename(argv[i], 0);
else
infnam = STDIN_NAME;
if (i + 1 < argc && (streq(argv[i + 1], "-") || !(outf = xfopen(argv[i + 1], "w"))))
fatal("%s: cannot open output file %s", argv0, argv[i + 1]);
process_file(infnam);
free(infnam);
for (cur_I = I_list + 1; *cur_I; cur_I++)
if (*cur_I)
free(*cur_I);
free(I_list);
fclose(outf);
hash_free();
cond_shutdown();
tok_shutdown();
if (nerrs > 0) {
fprintf(stderr, "%d errors\n", nerrs);
return 1;
}
return 0;
}