123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- #include <stdio.h>
- #if __STDC__
- #include <stdlib.h>
- #include <locale.h>
- #else
- #include <malloc.h>
- #endif
- #include <ctype.h>
- #include <string.h>
- #include <time.h>
- #include "cc.h"
- #define MAXINCPATH 5
- int main P((int argc, char ** argv));
- void undefine_macro P((char * name));
- void define_macro P((char * name));
- void print_toks_cpp P((void));
- void print_toks_raw P((void));
- void define_macro P((char *));
- void undefine_macro P((char *));
- void cmsg P((char * mtype, char * str));
- char * token_txn P((int));
- void pr_indent P((int));
- void hash_line P((void));
- char * include_paths[MAXINCPATH];
- char last_name[512] = "";
- int last_line = -1;
- int debug_mode = 0;
- int p_flag = 0;
- int exit_code = 0;
- char * outfile = 0;
- FILE * ofd = 0;
- int
- main(argc, argv)
- int argc;
- char ** argv;
- {
- int ar, i;
- char * p;
- static char Usage[] = "Usage: cpp -E -0 -Dxxx -Uxxx -Ixxx infile -o outfile";
- #ifdef LC_CTYPE
- setlocale(LC_CTYPE, "");
- #endif
- alltok = 1; /* Get all tokens from the cpp. */
- for(ar=1; ar<argc; ar++) if( argv[ar][0] == '-') switch(argv[ar][1])
- {
- case 'd': debug_mode++; break;
- case 'T': alltok = 0; break;
- case 'A': dialect = DI_ANSI; break;
- case 'K': dialect = DI_KNR; break;
- /* Some options for describing the code generator. */
- case '0': define_macro("__BCC__");
- define_macro("__AS386_16__");
- define_macro("__8086__");
- break;
- case '3': define_macro("__BCC__");
- define_macro("__AS386_32__");
- define_macro("__i386__");
- break;
- case 'c': define_macro("__CALLER_SAVES__");
- break;
- case 'f': define_macro("__FIRST_ARG_IN_AX__");
- break;
- case 'O': define_macro("__OPTIMISED__");
- break;
- case 'C': /* Keep comments. */
- cwarn("-C not implemented");
- break;
- case 'P': p_flag++;
- break;
- case 'I':
- if (argv[ar][2]) p=argv[ar]+2;
- else {
- ar++;
- if (ar>=argc) cfatal(Usage);
- p = argv[ar];
- }
- for(i=0; i<MAXINCPATH; i++)
- if (!include_paths[i]) {
- include_paths[i] = p;
- break;
- }
- if (i>=MAXINCPATH)
- cfatal("Too many items in include path for CPP");
- break;
- case 'D':
- if (argv[ar][2]) p=argv[ar]+2;
- else {
- ar++;
- if (ar>=argc) cfatal(Usage);
- p = argv[ar];
- }
- define_macro(p);
- break;
- case 'U':
- if (argv[ar][2]) p=argv[ar]+2;
- else {
- ar++;
- if (ar>=argc) cfatal(Usage);
- p = argv[ar];
- }
- undefine_macro(p);
- break;
- case 'o':
- if (argv[ar][2]) p=argv[ar]+2;
- else {
- ar++;
- if (ar>=argc) cfatal(Usage);
- p = argv[ar];
- }
- if (outfile) cfatal(Usage);
- outfile = p;
- break;
- default:
- fprintf(stderr, "CPP Unknown option %s\n", argv[ar]);
- cfatal(Usage);
- } else if (!curfile) {
- /* Input file */
- curfile = fopen(argv[ar], "r");
- c_fname = argv[ar]; c_lineno = 1;
- if (!curfile)
- cfatal("Cannot open input file");
- } else
- cfatal(Usage);
- if (!curfile)
- cfatal(Usage);
- /* Define date and time macros. */
- if (dialect != DI_KNR) {
- time_t now;
- char * timep;
- char buf[128];
- time(&now);
- timep = ctime(&now);
- /* Yes, well */
- sprintf(buf, "__TIME__=\"%.8s\"", timep + 11);
- define_macro(buf);
- /* US order; Seems to be mandated by standard. */
- sprintf(buf, "__DATE__=\"%.3s %.2s %.4s\"", timep + 4, timep + 8, timep + 20);
- define_macro(buf);
- }
- if (outfile) ofd = fopen(outfile, "w");
- else ofd = stdout;
- if (!ofd)
- cfatal("Cannot open output file");
- if (debug_mode)
- print_toks_raw();
- else
- print_toks_cpp();
- if (outfile) fclose(ofd);
- exit(exit_code);
- }
- void
- undefine_macro(name)
- char * name;
- {
- struct define_item * ptr;
- ptr = read_entry(0, name);
- if (ptr) {
- set_entry(0, name, (void*)0);
- if (!ptr->in_use) free(ptr);
- }
- }
- void
- define_macro(name)
- char * name;
- {
- char * p;
- char * value;
- struct define_item * ptr;
- if ((p=strchr(name, '=')) != 0) {
- *p = 0;
- value = p+1;
- } else
- value = "1";
- undefine_macro(name);
- ptr = malloc(sizeof(struct define_item) + strlen(value));
- ptr->name = set_entry(0, name, ptr);
- strcpy(ptr->value, value);
- ptr->arg_count = -1;
- ptr->in_use = 0;
- ptr->next = 0;
- }
- FILE *
- open_include(fname, mode, checkrel)
- char * fname;
- char * mode;
- int checkrel;
- {
- FILE * fd = 0;
- int i;
- char buf[256], *p;
- if( checkrel )
- {
- strcpy(buf, c_fname);
- p = strrchr(buf, '/');
- if (p) *++p = 0; else *(p=buf) = 0;
- strcpy(p, fname);
- fd=fopen(buf, mode);
- }
- if (!fd) {
- for(i=0; i<MAXINCPATH; i++)
- if (include_paths[i]) {
- strcpy(buf, include_paths[i]);
- if (buf[strlen(buf)-1] != '/') strcat(buf, "/");
- strcat(buf, fname);
- fd=fopen(buf, mode);
- if( fd ) break;
- }
- }
- if (!fd) return fd;
- c_fname = strdup(buf);
- c_lineno = 1;
- return fd;
- }
- /*----------------------------------------------------------------------*/
- static int outpos = 0;
- void
- cmsg(mtype, str)
- char * mtype;
- char * str;
- {
- if (c_fname && (*c_fname || c_lineno))
- fprintf(stderr, "%s:%d: ", c_fname, c_lineno);
- if (mtype && *mtype)
- fprintf(stderr, "%s: %s\n", mtype, str);
- else
- fprintf(stderr, "%s\n", str);
- }
- void
- cfatal(str)
- char * str;
- {
- cmsg("CPP-FATAL error", str);
- exit(255);
- }
- void
- cerror(str)
- char * str;
- {
- exit_code = 1;
- cmsg("error", str);
- }
- void
- cwarn(str)
- char * str;
- {
- cmsg("warning", str);
- }
- void
- pr_indent(count)
- int count;
- {
- if(count>10) count=10;
- while(count>0) {fprintf(ofd, "\t"); count--; }
- }
- void
- hash_line()
- {
- if( strcmp(last_name, c_fname) != 0 ) last_line = -1;
- if( c_lineno != last_line || last_line <= 0 )
- {
- if( outpos != 0 ) {
- fputc('\n', ofd); outpos=0;
- if (last_line > 0) last_line++;
- }
- while( c_lineno > last_line &&
- (p_flag || c_lineno < last_line+4) &&
- last_line > 0 &&
- !debug_mode )
- {
- fputc('\n', ofd); last_line++;
- }
- if( !p_flag && (c_lineno != last_line || last_line <= 0 ))
- {
- fprintf(ofd, "# %d", c_lineno);
- if( last_line <= 0 ) fprintf(ofd, " \"%s\"", c_fname);
- fprintf(ofd, "\n");
- }
- strcpy(last_name, c_fname);
- last_line = c_lineno;
- }
- }
- void
- print_toks_cpp()
- {
- int i;
- int indent=0;
- int paren=0;
- hash_line();
- while( (i=gettok()) != EOF )
- {
- hash_line();
- switch(i)
- {
- case '\n':
- cwarn("newline received from tokeniser!");
- break;
- case TK_STR:
- outpos += fprintf(ofd, "%s", curword);
- break;
- case TK_COPY:
- if( outpos ) { fputc('\n', ofd); last_line++; }
- outpos = 0; last_line++;
- fprintf(ofd, "#%s\n", curword);
- break;
- case TK_FILE: sprintf(curword, "\"%s\"", c_fname); if(0) {
- case TK_LINE: sprintf(curword, "%d", c_lineno);
- }
- /*FALLTHROUGH*/
- default:
- if (!alltok) {
- if(i == '}' || i == TK_CASE || i == TK_DEFAULT ) indent--;
- if(i ==')') paren--;
- if(outpos) { fputc(' ', ofd); outpos++; }
- else pr_indent(indent+(paren!=0));
- if(i == '{' || i == TK_CASE || i == TK_DEFAULT ) indent++;
- if(i ==';') paren=0;
- if(i =='(') paren++;
- }
- outpos += fprintf(ofd, "%s", curword);
- if ( i == '"' || i == '\'' )
- {
- while((i=gettok()) == TK_STR) {
- outpos += fprintf(ofd, "%s", curword);
- }
- if (i != '\n')
- outpos += fprintf(ofd, "%s", curword);
- }
- break;
- }
- }
- if( outpos ) fputc('\n', ofd);
- outpos = 0;
- }
- void
- print_toks_raw()
- {
- int i;
- long val;
- hash_line();
- while( (i=gettok()) != EOF )
- {
- hash_line();
- switch(i)
- {
- case '"': case '\'':
- if (debug_mode < 2) {
- fprintf(ofd, "%-16s: %s", "Quoted string", curword);
- while((i=gettok()) == TK_STR)
- outpos+= fprintf(ofd, "%s", curword);
- if ( i == '\n' ) fprintf(ofd, " --> EOL!!\n");
- else outpos+= fprintf(ofd, "%s\n", curword);
- break;
- }
- /*FALLTHROUGH*/
- default: fprintf(ofd, "%-16s: '", token_txn(i));
- {
- char *p;
- for(p=curword; *p; p++)
- if(isprint(*p) && *p != '\'' && *p != '\\')
- fputc(*p, ofd);
- else if (*p == '\n') fprintf(ofd, "\\n");
- else if (*p == '\t') fprintf(ofd, "\\t");
- else if (*p == '\v') fprintf(ofd, "\\v");
- else if (*p == '\b') fprintf(ofd, "\\b");
- else if (*p == '\r') fprintf(ofd, "\\r");
- else if (*p == '\f') fprintf(ofd, "\\f");
- else if (*p == '\a') fprintf(ofd, "\\a");
- else
- fprintf(ofd, "\\x%02x", (unsigned char)*p);
- }
- fprintf(ofd, "'\n");
- break;
- case TK_NUM:
- val = strtoul(curword, (void*)0, 0);
- fprintf(ofd, "%-16s: ", token_txn(i));
- fprintf(ofd, "%s => %ld\n", curword, val);
- break;
- case TK_COPY:
- fprintf(ofd, "%-16s: ", token_txn(i));
- fprintf(ofd, "#%s\n", curword);
- break;
- case '\n':
- fprintf(ofd, "%-16s:\n", "Newline char");
- break;
- }
- }
- }
- char *
- token_txn(token)
- int token;
- {
- char * s = "UNKNOWN";
- static char buf[17];
- if (token> ' ' && token <= '~')
- {
- sprintf(buf, "TK_CHAR('%c')", token);
- return buf;
- }
- if (token >= 0 && token < 0x100)
- {
- sprintf(buf, "TK_CHAR(%d)", token);
- return buf;
- }
- switch(token)
- {
- case TK_WSPACE : s="TK_WSPACE"; break;
- case TK_WORD : s="TK_WORD"; break;
- case TK_NUM : s="TK_NUM"; break;
- case TK_FLT : s="TK_FLT"; break;
- case TK_QUOT : s="TK_QUOT"; break;
- case TK_STR : s="TK_STR"; break;
- case TK_FILE : s="TK_FILE"; break;
- case TK_LINE : s="TK_LINE"; break;
- case TK_COPY : s="TK_COPY"; break;
- case TK_NE_OP : s="TK_NE_OP"; break;
- case TK_MOD_ASSIGN : s="TK_MOD_ASSIGN"; break;
- case TK_AND_OP : s="TK_AND_OP"; break;
- case TK_AND_ASSIGN : s="TK_AND_ASSIGN"; break;
- case TK_MUL_ASSIGN : s="TK_MUL_ASSIGN"; break;
- case TK_INC_OP : s="TK_INC_OP"; break;
- case TK_ADD_ASSIGN : s="TK_ADD_ASSIGN"; break;
- case TK_DEC_OP : s="TK_DEC_OP"; break;
- case TK_SUB_ASSIGN : s="TK_SUB_ASSIGN"; break;
- case TK_PTR_OP : s="TK_PTR_OP"; break;
- case TK_ELLIPSIS : s="TK_ELLIPSIS"; break;
- case TK_DIV_ASSIGN : s="TK_DIV_ASSIGN"; break;
- case TK_LEFT_OP : s="TK_LEFT_OP"; break;
- case TK_LEFT_ASSIGN : s="TK_LEFT_ASSIGN"; break;
- case TK_LE_OP : s="TK_LE_OP"; break;
- case TK_EQ_OP : s="TK_EQ_OP"; break;
- case TK_GE_OP : s="TK_GE_OP"; break;
- case TK_RIGHT_OP : s="TK_RIGHT_OP"; break;
- case TK_RIGHT_ASSIGN : s="TK_RIGHT_ASSIGN"; break;
- case TK_XOR_ASSIGN : s="TK_XOR_ASSIGN"; break;
- case TK_OR_ASSIGN : s="TK_OR_ASSIGN"; break;
- case TK_OR_OP : s="TK_OR_OP"; break;
- case TK_AUTO : s="TK_AUTO"; break;
- case TK_BREAK : s="TK_BREAK"; break;
- case TK_CASE : s="TK_CASE"; break;
- case TK_CHAR : s="TK_CHAR"; break;
- case TK_CONST : s="TK_CONST"; break;
- case TK_CONTINUE : s="TK_CONTINUE"; break;
- case TK_DEFAULT : s="TK_DEFAULT"; break;
- case TK_DO : s="TK_DO"; break;
- case TK_DOUBLE : s="TK_DOUBLE"; break;
- case TK_ELSE : s="TK_ELSE"; break;
- case TK_ENUM : s="TK_ENUM"; break;
- case TK_EXTERN : s="TK_EXTERN"; break;
- case TK_FLOAT : s="TK_FLOAT"; break;
- case TK_FOR : s="TK_FOR"; break;
- case TK_GOTO : s="TK_GOTO"; break;
- case TK_IF : s="TK_IF"; break;
- case TK_INT : s="TK_INT"; break;
- case TK_LONG : s="TK_LONG"; break;
- case TK_REGISTER : s="TK_REGISTER"; break;
- case TK_RETURN : s="TK_RETURN"; break;
- case TK_SHORT : s="TK_SHORT"; break;
- case TK_SIGNED : s="TK_SIGNED"; break;
- case TK_SIZEOF : s="TK_SIZEOF"; break;
- case TK_STATIC : s="TK_STATIC"; break;
- case TK_STRUCT : s="TK_STRUCT"; break;
- case TK_SWITCH : s="TK_SWITCH"; break;
- case TK_TYPEDEF : s="TK_TYPEDEF"; break;
- case TK_UNION : s="TK_UNION"; break;
- case TK_UNSIGNED : s="TK_UNSIGNED"; break;
- case TK_VOID : s="TK_VOID"; break;
- case TK_VOLATILE : s="TK_VOLATILE"; break;
- case TK_WHILE : s="TK_WHILE"; break;
- }
- return s;
- }
|