diff options
author | Robert de Bath <rdebath@poboxes.com> | 2002-07-28 22:10:50 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:48:47 +0200 |
commit | e6248da18100235ae33468d058e5b71fcefeff3b (patch) | |
tree | 4e3833ed515d03d2366c27f71ef0fe349a2dee12 | |
parent | 2060b4f4cc1c13975e495d088344825f7700181b (diff) | |
download | dev86-e6248da18100235ae33468d058e5b71fcefeff3b.tar.gz |
Import Dev86src-0.16.6.tar.gzv0.16.6
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | Mk_dist | 2 | ||||
-rw-r--r-- | bcc/bcc.c | 76 | ||||
-rw-r--r-- | bcc/input.c | 1 | ||||
-rw-r--r-- | bcc/preproc.c | 51 | ||||
-rw-r--r-- | bcc/scan.h | 1 | ||||
-rw-r--r-- | bcc/table.c | 3 | ||||
-rw-r--r-- | cpp/Makefile | 26 | ||||
-rw-r--r-- | cpp/cc.h | 110 | ||||
-rwxr-xr-x | cpp/cg | bin | 0 -> 27808 bytes | |||
-rw-r--r-- | cpp/cpp.c | 1427 | ||||
-rw-r--r-- | cpp/hash.c | 114 | ||||
-rw-r--r-- | cpp/log | 77 | ||||
-rw-r--r-- | cpp/main.c | 390 | ||||
-rw-r--r-- | cpp/q.c | 23 | ||||
-rw-r--r-- | cpp/token1.c | 6 | ||||
-rw-r--r-- | cpp/token1.tok | 26 | ||||
-rw-r--r-- | cpp/token2.c | 6 | ||||
-rw-r--r-- | cpp/token2.tok | 36 | ||||
-rw-r--r-- | libc/include/asm/limits.h | 14 | ||||
-rw-r--r-- | libc/include/stdio.h | 132 | ||||
-rw-r--r-- | libc/stdio/Makefile | 2 | ||||
-rw-r--r-- | libc/stdio/printf.c | 8 | ||||
-rw-r--r-- | libc/stdio/scanf.c | 8 | ||||
-rw-r--r-- | makefile.in | 15 |
25 files changed, 2364 insertions, 192 deletions
@@ -2,7 +2,7 @@ # This file is part of the Linux-8086 Development environment and is # distributed under the GNU General Public License. -VERSION=0.16.5 +VERSION=0.16.6 TARGETS= \ clean bcc unproto copt as86 ld86 elksemu \ @@ -12,7 +12,7 @@ TMPDIR=/tmp/Linux-86 TMPSRC=linux86 ARCDIR="$DIR"/dev86arc -SRCDIRS='bcc unproto as ar ld copt man elksemu dis88 tests libbsd bin86' +SRCDIRS='bcc cpp unproto as ar ld copt man elksemu dis88 tests libbsd bin86' DISTFILES='Makefile README COPYING Changes Contributors MAGIC mkcompile GNUmakefile libcompat ifdef.c makefile.in Mk_dist' @@ -13,6 +13,7 @@ * -Ml i386 Linux * -M8 CvW's c386 * -M9 MC6809 with bcc + * -M0 A framework for the -B option. */ #include <stdio.h> #ifdef __STDC__ @@ -57,7 +58,7 @@ #define AS09 "as09" EXESUF #define LD09 "ld09" EXESUF -#define CPPBCC "bcc-cc1" EXESUF +#define CPPBCC "bcc-cpp" EXESUF #define CC1BCC "bcc-cc1" EXESUF #define AS86 "as86" EXESUF #define LD86 "ld86" EXESUF @@ -78,11 +79,12 @@ struct command { char * cmd; + char * altcmd; char * fullpath; int numargs; int maxargs; char ** arglist; -} command = { 0,0,0,0,0 }; +} command = { 0,0,0,0,0,0 }; struct file_list { struct file_list * next; @@ -276,8 +278,14 @@ struct file_list * file; { int last_stage = 0;; - if (opt_arch<5) command.cmd = CPPBCC; - else command.cmd = CPP; + if (opt_arch<5 && !opt_e) + command.cmd = CC1BCC; + else if (opt_arch<5) { + command.cmd = CPPBCC; + command.altcmd = CC1BCC; + } + else + command.cmd = CPP; command_reset(); if (!opt_e && !do_optim && !do_as ) last_stage =1; @@ -285,7 +293,10 @@ struct file_list * file; newfilename(file, last_stage, (opt_e?'i':'s'), (opt_arch<5)); - if (opt_e && opt_arch<5) command_opt("-E"); + if (opt_e && opt_arch<5) { + command_opt("-E"); + if (do_unproto) command_opt("-A"); + } command_opts('p'); if (!opt_e) @@ -484,7 +495,7 @@ validate_link_opt(char * option) break; } if (err) - fprintf(stderr, "warning: linker option %s not unrecognised.\n", option); + fprintf(stderr, "warning: linker option %s not recognised.\n", option); } void @@ -532,33 +543,40 @@ command_reset() /* Search for the exe, nb as this will probably be called from 'make' * there's not much point saving this. */ - for(prefix=exec_prefixs; *prefix; prefix++) + for(;;) { - char * p; - if (*prefix == devnull) continue; - - p = strchr(*prefix, '~'); - if (!p) strcpy(buf, *prefix); - else + for(prefix=exec_prefixs; *prefix; prefix++) { - memcpy(buf, *prefix, p-*prefix); - buf[p-*prefix] = 0; + char * p; + if (*prefix == devnull) continue; - strcat(buf, localprefix); - strcat(buf, p+1); - } - strcat(buf, command.cmd); + p = strchr(*prefix, '~'); + if (!p) strcpy(buf, *prefix); + else + { + memcpy(buf, *prefix, p-*prefix); + buf[p-*prefix] = 0; - if (!*command.cmd) - fprintf(stderr, "PATH+=%s\n", buf); - else if (access(buf, X_OK) == 0) - { - command.fullpath = copystr(buf); - break; + strcat(buf, localprefix); + strcat(buf, p+1); + } + strcat(buf, command.cmd); + + if (!*command.cmd) + fprintf(stderr, "PATH+=%s\n", buf); + else if (access(buf, X_OK) == 0) + { + command.fullpath = copystr(buf); + break; + } } + if (command.fullpath || !command.altcmd) break; + command.cmd = command.altcmd; } + if (!command.fullpath) command.fullpath = copystr(command.cmd); + command.altcmd = 0; } void @@ -698,7 +716,7 @@ char ** argv; /* Special case -? is different from -?abcdef */ if(!pflag && argv[ar][2] == 0) switch(argv[ar][1]) { - case 'a': case 'L': case 'M': case 'O': case 'P': case 'Q': + case 'a': case 'L': case 'I': case 'M': case 'O': case 'P': case 'Q': pflag = argv[ar]+1; used_arg = 0; break; @@ -710,8 +728,12 @@ char ** argv; if(strcmp(argv[ar], "-ansi") == 0) { do_unproto = 1; opt_e = 1; - /* NOTE I'm setting this to zero, this isn't a _real_ STDC */ +#if 1 + /* NOTE I'm setting this to zero, this isn't a _real_ Ansi cpp. */ prepend_option("-D__STDC__=0", 'p'); +#else + prepend_option("-D__STDC__", 'p'); +#endif } else Usage(); diff --git a/bcc/input.c b/bcc/input.c index b89eb78..259ae04 100644 --- a/bcc/input.c +++ b/bcc/input.c @@ -511,6 +511,7 @@ char *argv[]; case 't': /* print source code in asm output */ case 'w': /* watch location counter */ case 'O': /* Optimisation. */ + case 'A': /* Ansi mode. */ if (arg[2] == 0) flag[(int)arg[1]] = TRUE; else if (arg[2] == '-' && arg[3] == 0) diff --git a/bcc/preproc.c b/bcc/preproc.c index e292329..1f35013 100644 --- a/bcc/preproc.c +++ b/bcc/preproc.c @@ -53,6 +53,7 @@ PRIVATE struct macroposition macrostack[MAX_MACRO]; FORWARD void asmcontrol P((void)); FORWARD void warningcntl P((void)); +FORWARD void errorcntl P((void)); FORWARD void control P((void)); FORWARD void defineorundefinestring P((char *str, bool_pt defineflag)); FORWARD void elifcontrol P((void)); @@ -157,20 +158,49 @@ PUBLIC void checknotinif() } } +/* warningcntl() - process #warning */ -/* This is a major hack. It doesn't handle continued lines. - * It does let me avoid wrapping warning directives though. */ PRIVATE void warningcntl() { - char *s = lineptr; + char estr[256], *ep = estr; - while (*lineptr && (*lineptr != EOL)) { - ++lineptr; + if (!orig_cppmode) { + *ep++ = '%'; *ep++ = 'w'; + } + while( ch != EOL ) { + if (ep < estr+sizeof(estr)-2 ) + *ep++ = ch; + gch1(); + } + *ep = 0; + + if (!orig_cppmode) + error(estr); + else { + outstr("#warning"); + outnstr(estr); + } +} + +/* errorcntl() - process #error */ + +PRIVATE void errorcntl() +{ + char estr[256], *ep = estr; + + while( ch != EOL ) { + if (ep < estr+sizeof(estr)-2 ) + *ep++ = ch; + gch1(); + } + *ep = 0; + + if (!orig_cppmode) + error(estr); + else { + outstr("#error"); + outnstr(estr); } - write(2, "warning: #warning", 17); - write(2, s, lineptr - s); - write(2, "\n", 1); - ch = *lineptr; } /* control() - select and switch to control statement */ @@ -261,6 +291,9 @@ PRIVATE void control() case WARNINGCNTL: warningcntl(); break; + case ERRORCNTL: + errorcntl(); + break; } } @@ -172,6 +172,7 @@ enum scan_states LINECNTL, UNDEFCNTL, WARNINGCNTL, + ERRORCNTL, ELIFCNTL, /* "IF" controls must be contiguous */ ELSECNTL, diff --git a/bcc/table.c b/bcc/table.c index 203b4fb..79dcf62 100644 --- a/bcc/table.c +++ b/bcc/table.c @@ -30,7 +30,7 @@ #define MAXEXPR 500 #endif #define MAXLOCAL 100 -#define NKEYWORDS 38 +#define NKEYWORDS 39 #ifdef NOFLOAT #define NSCALTYPES 10 #else @@ -128,6 +128,7 @@ PRIVATE struct keywordstruct keywords[NKEYWORDS] = { "#line", LINECNTL, }, { "#undef", UNDEFCNTL, }, { "#warning", WARNINGCNTL, }, + { "#error", ERRORCNTL, }, { "defined", DEFINEDSYM, }, /* should be deactivated except in #if's */ }; diff --git a/cpp/Makefile b/cpp/Makefile new file mode 100644 index 0000000..b5d5322 --- /dev/null +++ b/cpp/Makefile @@ -0,0 +1,26 @@ +CFLAGS=-Wall -Wstrict-prototypes + +all: bcc-cpp + +bcc-cpp: main.o cpp.o hash.o token1.o token2.o + $(CC) $(CFLAGS) -o bcc-cpp main.o cpp.o hash.o token1.o token2.o + +realclean: clean + rm -f bcc-cpp token1.h token2.h + +clean: + rm -f main.o cpp.o hash.o token1.o token2.o + +main.o: cc.h +cpp.o: cc.h +hash.o: cc.h +tree.o: cc.h + +token1.o: token1.h +token2.o: token2.h + +token1.h: token1.tok + gperf -aptTc -N is_ctok -H hash1 token1.tok > token1.h + +token2.h: token2.tok + gperf -aptTc -k1,3 -N is_ckey -H hash2 token2.tok > token2.h diff --git a/cpp/cc.h b/cpp/cc.h new file mode 100644 index 0000000..57dab6c --- /dev/null +++ b/cpp/cc.h @@ -0,0 +1,110 @@ + +#ifndef _P +#if __STDC__ +#define _P(x) x +#else +#define _P(x) () +#endif +#endif + +extern void cfatal _P((char*)); +extern void cerror _P((char*)); +extern void cwarn _P((char*)); +extern FILE * open_include _P((char*, char*, int)); + +extern FILE * curfile; +extern char curword[]; +extern char * c_fname; +extern int c_lineno; +extern int in_asm; +extern int ansi_c; + +extern int gettok _P((void)); + +struct token_trans { char * name; int token; }; +struct token_trans * is_ctok _P((const char *str, unsigned int len)); +struct token_trans * is_ckey _P((const char *str, unsigned int len)); + +#define WORDSIZE 128 +#define TK_WORD 256 +#define TK_NUM 257 +#define TK_FLT 258 +#define TK_QUOT 259 +#define TK_STR 260 +#define TK_FILE 261 +#define TK_LINE 262 +#define TK_COPY 263 + +#define TK_CTOK 0x200 +#define TK_CKEY 0x300 + +#define TK_NE_OP (TK_CTOK+ 0) +#define TK_MOD_ASSIGN (TK_CTOK+ 1) +#define TK_AND_OP (TK_CTOK+ 2) +#define TK_AND_ASSIGN (TK_CTOK+ 3) +#define TK_MUL_ASSIGN (TK_CTOK+ 4) +#define TK_INC_OP (TK_CTOK+ 5) +#define TK_ADD_ASSIGN (TK_CTOK+ 6) +#define TK_DEC_OP (TK_CTOK+ 7) +#define TK_SUB_ASSIGN (TK_CTOK+ 8) +#define TK_PTR_OP (TK_CTOK+ 9) +#define TK_ELLIPSIS (TK_CTOK+10) +#define TK_DIV_ASSIGN (TK_CTOK+11) +#define TK_LEFT_OP (TK_CTOK+12) +#define TK_LEFT_ASSIGN (TK_CTOK+13) +#define TK_LE_OP (TK_CTOK+14) +#define TK_EQ_OP (TK_CTOK+15) +#define TK_GE_OP (TK_CTOK+16) +#define TK_RIGHT_OP (TK_CTOK+17) +#define TK_RIGHT_ASSIGN (TK_CTOK+18) +#define TK_XOR_ASSIGN (TK_CTOK+19) +#define TK_OR_ASSIGN (TK_CTOK+20) +#define TK_OR_OP (TK_CTOK+21) + +#define TK_AUTO (TK_CKEY+ 0) +#define TK_BREAK (TK_CKEY+ 1) +#define TK_CASE (TK_CKEY+ 2) +#define TK_CHAR (TK_CKEY+ 3) +#define TK_CONST (TK_CKEY+ 4) +#define TK_CONTINUE (TK_CKEY+ 5) +#define TK_DEFAULT (TK_CKEY+ 6) +#define TK_DO (TK_CKEY+ 7) +#define TK_DOUBLE (TK_CKEY+ 8) +#define TK_ELSE (TK_CKEY+ 9) +#define TK_ENUM (TK_CKEY+10) +#define TK_EXTERN (TK_CKEY+11) +#define TK_FLOAT (TK_CKEY+12) +#define TK_FOR (TK_CKEY+13) +#define TK_GOTO (TK_CKEY+14) +#define TK_IF (TK_CKEY+15) +#define TK_INT (TK_CKEY+16) +#define TK_LONG (TK_CKEY+17) +#define TK_REGISTER (TK_CKEY+18) +#define TK_RETURN (TK_CKEY+19) +#define TK_SHORT (TK_CKEY+20) +#define TK_SIGNED (TK_CKEY+21) +#define TK_SIZEOF (TK_CKEY+22) +#define TK_STATIC (TK_CKEY+23) +#define TK_STRUCT (TK_CKEY+24) +#define TK_SWITCH (TK_CKEY+25) +#define TK_TYPEDEF (TK_CKEY+26) +#define TK_UNION (TK_CKEY+27) +#define TK_UNSIGNED (TK_CKEY+28) +#define TK_VOID (TK_CKEY+29) +#define TK_VOLATILE (TK_CKEY+30) +#define TK_WHILE (TK_CKEY+31) + +#define MAX_INCLUDE 16 /* Nested includes */ +#define MAX_DEFINE 32 /* Nested defines */ + +extern char * set_entry _P((int,char*,void*)); +extern void * read_entry _P((int,char*)); + +struct define_item +{ + struct define_arg * next; + char * name; + int arg_count; /* -1 = none; >=0 = brackets with N args */ + int in_use; /* Skip this one for looking up #defines */ + char value[1]; /* [arg,]*value */ +}; Binary files differdiff --git a/cpp/cpp.c b/cpp/cpp.c new file mode 100644 index 0000000..542a709 --- /dev/null +++ b/cpp/cpp.c @@ -0,0 +1,1427 @@ + +#include <stdio.h> +#include <string.h> +#include <malloc.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include "cc.h" + +#define CPP_DEBUG 0 /* LOTS of junk to stdout. */ + +/* + * This file comprises the 'guts' of a C preprocessor. + * + * Functions exported from this file: + * gettok() Returns the next token from the source + * curword contains the text of the token + * + * Variables + * curword Contains the text of the last token parsed. + * curfile Currently open primary file + * c_fname Name of file being parsed + * c_lineno Current line number in file being parsed. + * + * in_asm Control flag for the kind of tokens you want (C or assembler) + * ansi_c Control flag to change the preprocessor for Ansi C. + * + */ + +char curword[WORDSIZE]; +int in_asm = 0; +int ansi_c = 0; + +FILE * curfile; +char * c_fname; +int c_lineno = 0; + +typedef int int_type; /* Used for preprocessor expressions */ +static int curtok = 0; /* Used for preprocessor expressions */ + +static int fi_count = 0; +static FILE * saved_files[MAX_INCLUDE]; +static char * saved_fname[MAX_INCLUDE]; +static int saved_lines[MAX_INCLUDE]; + +static char * def_ptr = 0; +static char * def_start = 0; +static struct define_item * def_ref = 0; + +static int def_count =0; +static char * saved_def[MAX_DEFINE]; +static char * saved_start[MAX_DEFINE]; +static long saved_unputc[MAX_DEFINE]; +static struct define_item * saved_ref[MAX_DEFINE]; + +static long unputc = 0; + +static int last_char = '\n'; +static int in_preproc = 0; +static int dont_subst = 0; +static int quoted_str = 0; + +static int if_count = 0; +static int if_false = 0; +static int if_has_else = 0; +static int if_hidden = 0; +static int if_stack = 0; + +struct arg_store { + char * name; + char * value; + int in_define; +}; + +static int chget _P((void)); +static void unchget _P((int)); +static int gettok_nosub _P((void)); +static int get_onetok _P((void)); +static int pgetc _P((void)); +static int do_preproc _P((void)); +static int do_proc_copy_hashline _P((void)); +static int do_proc_if _P((int)); +static void do_proc_include _P((void)); +static void do_proc_define _P((void)); +static void do_proc_undef _P((void)); +static void do_proc_else _P((void)); +static void do_proc_endif _P((void)); +static void do_proc_tail _P((void)); +static int get_if_expression _P((void)); +static int_type get_expression _P((int)); +static int_type get_exp_value _P((void)); +static int gen_substrings _P((char *, char *, int)); +static char * insert_substrings _P((char *, struct arg_store *, int)); + +int +gettok() +{ + int ch; + + for(;;) + { + /* Normal C Preprocessor decoding */ + if (in_asm) { + *curword = 0; + if (quoted_str) ch = chget(); + else ch = pgetc(); + if (ch > 0xFF || ch == EOF) return ch; + + if(!quoted_str && + ( (ch >= 'A' && ch <= 'Z') + || (ch >= 'a' && ch <= 'z') + || ch == '_' || ch == '$' ) ) { + unchget(ch); + } + else + { + curword[0] = ch; + curword[1] = 0; + if (quoted_str==2) + quoted_str=1; + else { + if (ch == '"') { + quoted_str = !quoted_str; + return '"'; + } + if (quoted_str == 1 && ch == '\\') + quoted_str = 2; + else if (quoted_str && ch == '\n') { + quoted_str = 0; + unchget(ch); + return '\n'; + } + } + + if (ch == '\n') continue; + return TK_STR; + } + } + + /* Tokenised C-Preprocessing */ + if (!quoted_str) + { + ch = get_onetok(); + + /* Erase meaningless backslashes */ + if( ch == '\\' ) { + int ch1 = chget(); + if (ch1 == '\n') continue; + unchget(ch1); + } + + if( ch == '"' ) + quoted_str = 1; + return ch; + } + + /* Special for quoted strings */ + *curword = 0; + ch = chget(); + if( ch == EOF ) return ch; + + *curword = ch; + curword[1] = '\0'; + + if( quoted_str == 2 ) { + quoted_str = 1; + return TK_STR; + } + + if( ch == '"' ) + { + /* Found a terminator '"' check for ansi continuation */ + while( (ch = pgetc()) <= ' ' && ch != EOF) ; + if( ch == '"' ) continue; + quoted_str = 0; + unchget(ch); + + *curword = '"'; + curword[1] = '\0'; + return '"'; + } + if( ch == '\n' ) { + quoted_str = 0; + unchget(ch); + return ch; + } + if( ch != '\\' ) return TK_STR; + + /* Deal with backslash; NB this could interpret all the \X codes */ + ch = chget(); + + if( ch != '\n' ) { quoted_str++; unchget(ch); return TK_STR; } + } +} + +static int +gettok_nosub() +{ int rv; dont_subst++; rv=get_onetok(); dont_subst--; return rv; } + +static int +get_onetok() +{ + char * p; + int state; + int ch, cc; + +Try_again: + *(p=curword) = '\0'; + state=cc=ch=0; + + while( (ch = pgetc()) != EOF) + { + if( ch > ' ' ) break; + if( in_preproc && ch == '\n') break; + if( (!in_preproc) && in_asm && (ch == ' ' || ch == '\t') ) break; + } + if( ch > 0xFF ) return ch; + for(;;) + { + switch(state) + { + case 0: if( (ch >= 'A' && ch <= 'Z') + || (ch >= 'a' && ch <= 'z') + || ch == '_' || ch == '$' ) + state = 1; + else if(ch == '0') + state = 2; + else if(ch >= '1' && ch <= '9') + state = 5; + else + goto break_break; + break; + case 1: if( (ch >= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'Z') + || (ch >= 'a' && ch <= 'z') + || ch == '_' || ch == '$' ) + break; + else + goto break_break; + case 2: if( ch >= '0' && ch <= '7') + state = 3; + else if( ch == 'x' || ch == 'X' ) + state = 4; + else + goto break_break; + break; + case 3: if( ch >= '0' && ch <= '7') + break; + else + goto break_break; + case 4: if( (ch >= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'F') + || (ch >= 'a' && ch <= 'f') ) + break; + else + goto break_break; + case 5: + case 6: if( ch >= '0' && ch <= '9') + ; + else if( ch == '.' && state != 6 ) + state = 6; + else if( ch == 'e' || ch == 'E' ) + state = 7; + else + goto break_break; + break; + case 7: if( ch == '+' || ch == '-' ) + break; + state = 8; + /* FALLTHROUGH */ + case 8: if( ch >= '0' && ch <= '9') + break; + else + goto break_break; + } + if( cc < WORDSIZE-1 ) *p++ = ch; /* Clip to WORDSIZE */ + *p = '\0'; cc++; + ch = pgetc(); + } +break_break: + if( state == 1 ) + { + struct define_item * ptr; + unchget(ch); + if( !dont_subst + && (ptr = read_entry(0, curword)) != 0 + && !ptr->in_use + ) + { + if ( def_count >= MAX_DEFINE ) { + cerror("Preprocessor recursion overflow"); + goto oops_keep_going; + } else + /* Add in the arguments if they're there */ + if( ptr->arg_count >= 0 ) + { + /* We have arguments to process so lets do so. */ + if( !gen_substrings(ptr->name, ptr->value, ptr->arg_count) ) + goto oops_keep_going; + def_ref = ptr; + ptr->in_use = 1; + } + else if (ptr->value[0]) + { + saved_ref[def_count] = def_ref; + saved_def[def_count] = def_ptr; + saved_start[def_count] = def_start; + saved_unputc[def_count] = unputc; + def_count++; + unputc = 0; + def_ref = ptr; + def_ptr = ptr->value; + def_start = 0; + ptr->in_use = 1; + } + goto Try_again; + } +oops_keep_going: + if( !in_preproc ) + { + struct token_trans *p; + if( p=is_ckey(curword, cc) ) + return p->token; + } + return TK_WORD; + } + if( state >= 2 ) + { + if( state < 6 ) + { + if( ch == 'l' || ch == 'L' ) + { + if( cc < WORDSIZE-1 ) *p++ = ch; /* Clip to WORDSIZE */ + *p = '\0'; cc++; + } + else unchget(ch); + return TK_NUM; + } + unchget(ch); + return TK_FLT; + } + + /* More tokeniser for C like stuff */ + if(!in_asm || in_preproc) + { + /* Quoted char (NOT strings!) */ + if (ch == '\'' ) + { + *p++ = ch; ch = chget(); + for(;;) + { + if( cc < WORDSIZE-1 ) *p++ = ch; /* Clip to WORDSIZE */ + *p = '\0'; cc++; + if( ch == '\'' || ch == '\n' ) break; + + if( ch == '\\' ) + { + ch = chget(); + if( cc < WORDSIZE-1 ) *p++ = ch; /* Clip to WORDSIZE */ + *p = '\0'; cc++; + } + ch = chget(); + } + ch = TK_QUOT; + } + /* Composite tokens */ + if( ch > ' ' && ch <= '~' ) + { + struct token_trans *p; + *curword = cc = ch; + + for(state=1; ; state++) + { + curword[state] = ch = chget(); + if( !(p=is_ctok(curword, state+1)) ) + { + unchget(ch); + curword[state] = '\0'; + return cc; + } + cc=p->token; + } + } + } else { + *curword = ch; + curword[1] = 0; + } + return ch; +} + +static int +pgetc() +{ + int ch, ch1; + + for(;;) + { + /* This loop is repeated if the current char is not suitable + either because of a comment or a false #if condition + */ + + ch = chget(); + + if( ch == EOF ) return ch; + if( in_preproc && ch == '\\' ) + { + ch1 = chget(); + if( ch1 == '\n' ) ch = chget(); + else unchget(ch1); + } + + /* Ansi trigraphs -- Ewww, anyway this doesn't work, it needs lots + * of 'unchget' space too. */ + if (ansi_c && ch == '?') { + ch1 = chget(); + if (ch1 != '?') + unchget(ch1); + else { + static char trig1[] = "()<>/!'-="; + static char trig2[] = "[]{}\\|^~#"; + char * s; + ch1 = chget(); + s = strchr(trig1, ch1); + if (s) ch = trig2[s-trig1]; + else { + unchget(ch1); + unchget('?'); + } + } + } + + if( !in_preproc && last_char == '\n' && ch == '#' ) + { + in_preproc = 1; + ch = do_preproc(); + in_preproc = 0; + last_char = '\n'; + if(if_false) continue; + return ch; + } + if( last_char != '\n' || (ch != ' ' && ch != '\t') ) + last_char = ch; + + /* Remove comments ... */ + if( ch != '/' ) + { if(if_false && !in_preproc) continue; return ch; } + ch1 = chget(); + + if( ch1 == '/' ) /* Double slash style comments */ + { + do + { + ch = chget(); + if( ch == EOF ) return EOF; + if( ch == '\\' ) { + ch1 = chget(); + if( ch1 == EOF ) return EOF; + } + } + while(ch != '\n'); + continue; + } + + if( ch1 != '*' ) + { + unchget(ch1); + if(if_false && !in_preproc) continue; + return ch; + } + + for(;;) + { + if( ch == '*' ) + { + ch = chget(); + if( ch == EOF ) return EOF; + if( ch == '/' ) break; + } + else ch = chget(); + } + if (ansi_c) + return ' '; /* If comments become " " */ + + /* Comments become nulls */ + } +} + +static void +unchget(ch) +{ +#if CPP_DEBUG + fprintf(stderr, "\b", ch); +#endif + if(ch == EOF) ch=26; /* EOF is pushed back as ^Z */ + ch &= 0xFF; + + if(unputc&0xFF000000) + cerror("Internal character pushback stack overflow"); + else unputc = (unputc<<8) + (ch); + if( ch == '\n' ) c_lineno--; +} + +static int +chget() +#if CPP_DEBUG +{ + int ch; +static int last_def = 0; +static int last_fi = 0; + if (last_fi != fi_count) fprintf(stderr, "<INC%d>", fi_count); + if (last_def != def_count) fprintf(stderr, "<DEF%d>", def_count); + last_def = def_count; last_fi = fi_count; + + ch = realchget(); + if (ch == EOF) fprintf(stderr, "<EOF>"); else fprintf(stderr, "%c", ch); + + if (last_def != def_count) fprintf(stderr, "<DEF%d>", def_count); + if (last_fi != fi_count) fprintf(stderr, "<INC%d>", fi_count); + last_def = def_count; last_fi = fi_count; + + return ch; +} + +static int +realchget() +#endif +{ + int ch; + for(;;) + { + if( unputc ) + { + if((unputc&0xFF)==26 && in_preproc) return '\n'; + ch=(unputc&0xFF); unputc>>=8; + if( ch == 26 ) ch = EOF; + if( ch == '\n' ) c_lineno++; + return ch; + } + + if( def_ptr ) + { + ch = *def_ptr++; if(ch) return (unsigned char)ch; + if( def_start ) free(def_start); + if( def_ref ) def_ref->in_use = 0; + + def_count--; + def_ref = saved_ref[def_count]; + def_ptr = saved_def[def_count]; + def_start = saved_start[def_count]; + unputc = saved_unputc[def_count]; + continue; + } + + ch = getc(curfile); + if( ch == EOF && fi_count != 0) + { + fclose(curfile); + fi_count--; + curfile = saved_files[fi_count]; + if(c_fname) free(c_fname); + c_fname = saved_fname[fi_count]; + c_lineno = saved_lines[fi_count]; + ch = '\n'; /* Ensure end of line on end of file */ + } + else if( ch == '\n' ) c_lineno++; + + /* Treat all control characters, except the standard whitespace + * characters of TAB and NL as completely invisible. + */ + if( ch >= 0 && ch < ' ' && ch!='\n' && ch!='\t' && ch!=EOF ) continue; + + if( ch == EOF ) { unchget(ch); return '\n'; } /* Ensure EOL before EOF */ + return (unsigned char)ch; + } +} + +static int +do_preproc() +{ + int val, no_match=0; + + if( (val=get_onetok()) == TK_WORD ) + { + if( strcmp(curword, "ifdef") == 0 ) + do_proc_if(0); + else if( strcmp(curword, "ifndef") == 0 ) + do_proc_if(1); + else if( strcmp(curword, "if") == 0 ) + do_proc_if(2); + else if( strcmp(curword, "elif") == 0 ) + do_proc_if(3); + else if( strcmp(curword, "else") == 0 ) + do_proc_else(); + else if( strcmp(curword, "endif") == 0 ) + do_proc_endif(); + else if(if_false) + no_match=1; + else + { + if( strcmp(curword, "include") == 0 ) + do_proc_include(); + else if( strcmp(curword, "define") == 0 ) + do_proc_define(); + else if( strcmp(curword, "undef") == 0 ) + do_proc_undef(); + else if( strcmp(curword, "error") == 0 ) + return do_proc_copy_hashline(); + else if( strcmp(curword, "warning") == 0 ) + return do_proc_copy_hashline(); + else if( strcmp(curword, "asm") == 0 ) { + in_asm |= 1; + return do_proc_copy_hashline(); + } else if( strcmp(curword, "endasm") == 0 ) { + in_asm &= ~1; + return do_proc_copy_hashline(); + } else + no_match=1; + } + } + else if( val == '#' ) /* This is a comment, it's used as a marker */ + /* for compiler specific header files */ + { + while((val = pgetc()) != '\n'); + } + else no_match=1; + + if( no_match ) + { + if(!if_false) cerror("Unknown preprocessor directive"); + while( val != '\n' ) val = pgetc(); + } + + strcpy(curword, "\n"); + return '\n'; +} + +static int +do_proc_copy_hashline() +{ + int off, ch; + + off = strlen(curword); + + while( (ch=pgetc()) != '\n' ) + { + if( off < WORDSIZE ) curword[off++] = ch; + } + if( off == WORDSIZE ) + { + cerror("Preprocessor directive too long"); + curword[WORDSIZE-1] = '\0'; + } + else + curword[off] = '\0'; + + unchget('\n'); + return TK_COPY; +} + +static void do_proc_include() +{ + int ch, ch1; + char * p; + FILE * fd; + + ch = get_onetok(); + if( ch == '<' || ch == '"' ) + { + if( ch == '"' ) ch1 = ch; else ch1 = '>'; + p = curword; + while(p< curword+sizeof(curword)-1) + { + ch = pgetc(); + if( ch == '\n' ) break; + if( ch == ch1 ) + { + *p = '\0'; + + fd = open_include(curword, "r", (ch=='"')); + if( fd == 0 ) + cerror("Cannot open include file"); + do { ch = pgetc(); } while(ch == ' ' || ch == '\t'); unchget(ch); + do_proc_tail(); + + if( fd ) + { + saved_files[fi_count] = curfile; + saved_fname[fi_count] = c_fname; + saved_lines[fi_count] = c_lineno; + fi_count++; + + curfile = fd; + c_fname = malloc(strlen(curword)+1); + if( c_fname == 0 ) cfatal("Preprocessor out of memory"); + strcpy(c_fname, curword); + c_lineno = 1; + } + return; + } + *p++ = ch; + } + } + cerror("Bad #include command"); + while(ch != '\n') ch = pgetc(); + return; +} + +static void do_proc_define() +{ + int ch, ch1; + struct define_item * ptr, * old_value = 0; + int cc, len; + char name[sizeof(curword)]; + + if( (ch=gettok_nosub()) == TK_WORD ) + { + strcpy(name, curword); + ptr = read_entry(0, name); + if(ptr) + { + set_entry(0, name, (void*)0); /* Unset var */ + if (ptr->in_use) + ; /* Eeeek! This shouldn't happen; so just let it leak. */ + else + old_value = ptr; + } + for(ch=ch1=pgetc(); ch == ' ' || ch == '\t' ; ch=pgetc()) ; + + /* If #define with no substitute */ + if( ch == '\n' ) + { +#if CPP_DEBUG + fprintf(stderr, "\n### Define '%s' as null\n", name); +#endif + ptr = malloc(sizeof(struct define_item)); + if(ptr==0) cfatal("Preprocessor out of memory"); + ptr->name = set_entry(0, name, ptr); + ptr->value[0] = '\0'; + ptr->arg_count = -1; + ptr->in_use = 0; + ptr->next = 0; + if (old_value) { + if (strcmp(old_value->value, ptr->value) != 0) + cwarn("#define redefined macro"); + free(old_value); + } + return; + } + len = WORDSIZE; + ptr = malloc(sizeof(struct define_item) + WORDSIZE); + if(ptr==0) cfatal("Preprocessor out of memory"); + ptr->value[cc=0] = 0; + + /* Add in arguments */ + if( ch1 == '(' ) + { + ptr->arg_count=0; + for(;;) + { + ch=gettok_nosub(); + if( ptr->arg_count==0 && ch == ')' ) break; + if( ch == TK_WORD ) + { + if( cc+strlen(curword)+4 >= len) + { + len = cc + WORDSIZE; + ptr = (struct define_item *) realloc(ptr, sizeof(struct define_item) + len); + if(ptr==0) cfatal("Preprocessor out of memory"); + } + if( cc+strlen(curword) < len) + { + strcpy(ptr->value+cc, curword); + cc+=strlen(curword); + strcpy(ptr->value+cc, ","); + cc++; + ptr->arg_count++; + ch=gettok_nosub(); + if( ch == ')' ) break; + if( ch == ',' ) continue; + } + } + cerror("Bad #define command"); + free(ptr); + while(ch != '\n') ch = pgetc(); + set_entry(0, name, (void*)old_value); /* Return var to old. */ + return; + } + while((ch=pgetc())==' ' || ch=='\t'); + } + else ptr->arg_count = -1; + + /* And the substitution string */ + while(ch != '\n') + { + if( cc+4 > len ) + { + len = cc + WORDSIZE; + ptr = (struct define_item *) realloc(ptr, sizeof(struct define_item) + len); + if(ptr==0) cfatal("Preprocessor out of memory"); + } + ptr->value[cc++] = ch; + ch = pgetc(); + } + ptr->value[cc++] = ' '; /* Byte of lookahead for recursive macros */ + ptr->value[cc++] = 0; + +#if CPP_DEBUG + if (ptr->arg_count<0) + fprintf(stderr, "\n### Define '%s' as '%s'\n", + name, ptr->value); + else + fprintf(stderr, "\n### Define '%s' as %d args '%s'\n", + name, ptr->arg_count, ptr->value); +#endif + + /* Clip to correct size and save */ + ptr = (struct define_item *) realloc(ptr, sizeof(struct define_item) + cc); + ptr->name = set_entry(0, name, ptr); + ptr->in_use = 0; + ptr->next = 0; + + if (old_value) { + if (strcmp(old_value->value, ptr->value) != 0) + cwarn("#define redefined macro"); + free(old_value); + } + } + else cerror("Bad #define command"); + while(ch != '\n') ch = pgetc(); +} + +static void do_proc_undef() +{ + int ch; + struct define_item * ptr; + if( (ch=gettok_nosub()) == TK_WORD ) + { + ptr = read_entry(0, curword); + if(ptr) + { + set_entry(0, curword, (void*)0); /* Unset var */ + if (ptr->in_use) + ; /* Eeeek! This shouldn't happen; so just let it leak. */ + else + free(ptr); + } + do_proc_tail(); + } + else + { + cerror("Bad #undef command"); + while(ch != '\n') ch = pgetc(); + } +} + +static int do_proc_if(type) +int type; +{ + int ch = 0; + if( type == 3 ) + { + if( if_count == 0 ) + cerror("#elif without matching #if"); + else + { + if( if_has_else ) + cerror("#elif following #else for one #if"); + if( if_has_else || if_false != 1 ) + { + if_false=2; + while(ch != '\n') ch = pgetc(); + return 0; + } + if_false=0; + } + if_has_else = 0; + } + if(if_false) + { + if( type != 3 ) if_hidden++; + do_proc_tail(); + } + else + { + if( type != 3 ) + { + if_count++; + if_stack <<= 1; + if_stack |= if_has_else; + if_has_else = 0; + } + if(type > 1) + { + ch = get_if_expression(); + if_false=!ch; + } + else + { + ch = gettok_nosub(); + if( ch == TK_WORD ) + { + do_proc_tail(); + if_false = (read_entry(0, curword) == 0); + if(type == 1) if_false = !if_false; + } + else + { + cerror("Bad #if command"); + if_false = 0; + while(ch != '\n') ch = pgetc(); + } + } + } + return 0; +} + +static void do_proc_else() +{ + if( if_hidden == 0 ) + { + if( if_count == 0 ) + cerror("#else without matching #if"); + else + if_false = (if_false^1); + if( if_has_else ) + cerror("Multiple #else's for one #if"); + if_has_else = 1; + } + do_proc_tail(); +} + +static void do_proc_endif() +{ + if( if_hidden ) + if_hidden--; + else + { + if( if_count == 0 ) + cerror("Unmatched #endif"); + else + { + if_count--; + if_false=0; + if_has_else = (if_stack&1); + if_stack >>=1; + } + } + do_proc_tail(); +} + +static void +do_proc_tail() +{ + int ch, flg=1; + while((ch = pgetc()) != '\n') if(ch > ' ') + { + if (!if_false && flg) + cwarn("Unexpected text following preprocessor command"); + flg=0; + } +} + +static int +get_if_expression() +{ + int value = get_expression(0); + + if (curtok != '\n') + do_proc_tail(); + + return value; +} + +static int_type +get_expression(prio) +int prio; +{ + int_type lvalue; + int_type rvalue; + int no_op = 0; + + curtok = get_onetok(); + lvalue = get_exp_value(); + + do + { + switch(curtok) + { + case '*': case '/': case '%': + if (prio >= 10) return lvalue; + break; + case '+': case '-': + if (prio >= 9) return lvalue; + break; + case TK_RIGHT_OP: case TK_LEFT_OP: + if (prio >= 8) return lvalue; + break; + case '<': case '>': case TK_LE_OP: case TK_GE_OP: + if (prio >= 7) return lvalue; + break; + case TK_EQ_OP: case TK_NE_OP: + if (prio >= 6) return lvalue; + break; + case '&': + if (prio >= 5) return lvalue; + break; + case '^': + if (prio >= 4) return lvalue; + break; + case '|': + if (prio >= 3) return lvalue; + break; + case TK_AND_OP: + if (prio >= 2) return lvalue; + break; + case TK_OR_OP: + if (prio >= 1) return lvalue; + break; + } + switch(curtok) + { + case '*': + rvalue = get_expression(10); + lvalue *= rvalue; + break; + case '/': + rvalue = get_expression(10); + if (rvalue) + lvalue /= rvalue; + break; + case '%': + rvalue = get_expression(10); + if (rvalue) + lvalue %= rvalue; + break; + case '+': + rvalue = get_expression(9); + lvalue += rvalue; + break; + case '-': + rvalue = get_expression(9); + lvalue -= rvalue; + break; + case TK_RIGHT_OP: + rvalue = get_expression(8); + lvalue >>= rvalue; + break; + case TK_LEFT_OP: + rvalue = get_expression(8); + lvalue <<= rvalue; + break; + case '<': + rvalue = get_expression(7); + lvalue = (lvalue < rvalue); + break; + case '>': + rvalue = get_expression(7); + lvalue = (lvalue > rvalue); + break; + case TK_LE_OP: + rvalue = get_expression(7); + lvalue = (lvalue <= rvalue); + break; + case TK_GE_OP: + rvalue = get_expression(7); + lvalue = (lvalue >= rvalue); + break; + case TK_EQ_OP: + rvalue = get_expression(6); + lvalue = (lvalue == rvalue); + break; + case TK_NE_OP: + rvalue = get_expression(6); + lvalue = (lvalue != rvalue); + break; + case '&': + rvalue = get_expression(5); + lvalue = (lvalue & rvalue); + break; + case '^': + rvalue = get_expression(4); + lvalue = (lvalue ^ rvalue); + break; + case '|': + rvalue = get_expression(3); + lvalue = (lvalue | rvalue); + break; + case TK_AND_OP: + rvalue = get_expression(2); + lvalue = (lvalue && rvalue); + break; + case TK_OR_OP: + rvalue = get_expression(1); + lvalue = (lvalue || rvalue); + break; + + case '?': /* XXX: To add */ + + default: + no_op = 1; + } + } + while(prio == 0 && !no_op); + + return lvalue; +} + +static int_type +get_exp_value() +{ + int_type value = 0; + int sign = 1; + + if (curtok == '!') { + curtok = get_onetok(); + return !get_exp_value(); + } + if (curtok == '~') { + curtok = get_onetok(); + return ~get_exp_value(); + } + + while (curtok == '+' || curtok == '-') { + if (curtok == '-') sign = -sign; + curtok = get_onetok(); + } + + if (curtok == TK_NUM) { + value = strtoul(curword, (void*)0, 0); + curtok = get_onetok(); + } else if (curtok == TK_QUOT) { + value = curword[1]; + if (value == '\\') { + if (curword[2] >= '0' && curword[2] <= '7') { + value = curword[2] - '0'; + if (curword[3] >= '0' && curword[3] <= '7') { + value = (value<<3) + curword[3] - '0'; + if (curword[4] >= '0' && curword[4] <= '7') { + value = (value<<3) + curword[4] - '0'; + } + } + } else switch(curword[2]) { + case 'n': value = '\n'; break; + case 'f': value = '\f'; break; + case 't': value = '\t'; break; + default: value = curword[2]; break; + } + } +#ifdef NATIVE_CPP + value = (char) value; /* Fix range */ +#elif SIGNED_CHAR + value = (signed char) value; +#else + value = (unsigned char) value; +#endif + curtok = get_onetok(); + } else if (curtok == TK_WORD) { + value = 0; + if (strcmp("defined", curword) == 0) { + curtok = gettok_nosub(); + if (curtok == '(' && gettok_nosub() != TK_WORD) + cerror("'defined' keyword requires argument"); + else { + value = (read_entry(0, curword) != 0); + if (curtok == '(' && gettok_nosub() != ')') + cerror("'defined' keyword requires closing ')'"); + else + curtok = get_onetok(); + } + } + else + curtok = get_onetok(); + + } else if (curtok == '(') { + value = get_expression(0); + if (curtok == ')') + curtok = get_onetok(); + else + curtok = '$'; + } + + return sign<0 ? -value: value; +} + +static int +gen_substrings(macname, data_str, arg_count) +char * macname; +char * data_str; +int arg_count; +{ + char * mac_text = 0; + struct arg_store *arg_list; + int ac, ch, cc, len; + int args_found = 1; /* An empty arg still counts as one. */ + + int paren_count = 0; + int in_quote = 0; + + arg_list = malloc(sizeof(struct arg_store) * arg_count); + memset(arg_list, 0, sizeof(struct arg_store) * arg_count); + + for(ac=0; *data_str && ac < arg_count; data_str++) { + if( *data_str == ',' ) { ac++; continue; } + + if (arg_list[ac].name == 0) cc = len = 0; + + if (cc+2 >= len) { + len += 20; + arg_list[ac].name = realloc(arg_list[ac].name, len); + } + arg_list[ac].name[cc++] = *data_str; + arg_list[ac].name[cc] = 0; + } + + while((ch = chget()) <= ' ' && ch != EOF ) ; + + if( ch != '(' ) + { + /* Macro name used without arguments, ignore substitution */ + unchget(ch); + /* unchget(' '); .* This is needed incase the next thing is a word */ + /* to stop these two words being stuck together. */ + return 0; + } + + for(;;) { + if ((ch = chget()) == EOF) break; + if(in_quote == 2) { + in_quote = 1; + } else if (in_quote) { + if ( ch == '"' ) in_quote = 0; + if ( ch == '\\') in_quote = 2; + } else { + if ( ch == '(' ) paren_count++; + if ( ch == '"' ) in_quote = 1; + if (paren_count == 0 && ch == ',' ) { + args_found++; continue; + } + if ( ch == ')' ) { + if (paren_count == 0) break; + paren_count--; + } + } + /* Too many args; ignore rest */ + if (args_found > arg_count ) continue; + ac = args_found-1; + if (arg_list[ac].value == 0) { + cc = len = 0; + arg_list[ac].in_define = def_count; + } + + if (cc+2 >= len) { + len += 20; + arg_list[ac].value = realloc(arg_list[ac].value, len); + } + if (ch == '\n' && cc>0 && arg_list[ac].value[cc-1] == '\\' ) { + /* Humm, ok */ + arg_list[ac].value[--cc] = 0; + ch = ' '; + if (!ansi_c) continue; + } + + if (ch == '\n' && cc>0 && arg_list[ac].value[cc-1] == '\n' ) { + cerror("Unquoted newline in macro arguments"); + break; + } + + arg_list[ac].value[cc++] = ch; + arg_list[ac].value[cc] = 0; + } + + if( arg_count != args_found ) + cerror("Incorrect number of macro arguments"); + + mac_text = insert_substrings(data_str, arg_list, arg_count); + + if (arg_list) { + for (ac=0; ac<arg_count; ac++) { + if (arg_list[ac].name) free(arg_list[ac].name); + if (arg_list[ac].value) free(arg_list[ac].value); + } + free(arg_list); + } + + saved_ref[def_count] = def_ref; + saved_def[def_count] = def_ptr; + saved_start[def_count] = def_start; + saved_unputc[def_count] = unputc; + def_count++; + unputc = 0; + def_ptr = mac_text; + def_start = mac_text; +#if CPP_DEBUG + fprintf(stderr, "\n### <DEF%d='%s'>\n", def_count, mac_text); +#endif + return 1; +} + +static char * +insert_substrings(data_str, arg_list, arg_count) +char * data_str; +struct arg_store *arg_list; +int arg_count; +{ + int ac, ch; + char * p, * s; + char * rv = 0; + int len = 0; + int cc = 0; + int in_quote = 0; + int ansi_stringize = 0; + +#if CPP_DEBUG + fprintf(stderr, "\n### Macro substitution in '%s'\n", data_str); + for (ac=0; ac<arg_count; ac++) { + fprintf(stderr, "### Argument %d (%s) = '%s'\n", + ac+1, arg_list[ac].name, arg_list[ac].value); + } +#endif + + rv = malloc(4); *rv = 0; len = 4; + + while(*data_str) { + p = curword; + + if (ansi_c) { + if (in_quote == 2) + in_quote = 1; + else if (in_quote) { + if (*data_str == '"') in_quote = 0; + if (*data_str == '\\') in_quote = 2; + } else { + if (*data_str == '"') in_quote = 1; + } + } + + if (!in_quote) for(;;) { + ch = *data_str; + if( (ch >= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'Z') + || (ch >= 'a' && ch <= 'z') + || ch == '_' || ch == '$' ) + *p++ = *data_str++; + else + break; + } + + if (p == curword) { + /* Ansi Stringize and concat */ + if (*data_str == '#' && ansi_c) { + if (data_str[1] == '#') { + while(cc>0 && (rv[cc-1] == ' ' || rv[cc-1] == '\t')) + cc--; + data_str+=2; + while(*data_str == ' ' || *data_str == '\t') + data_str++; + if (*data_str == 0) { /* Hummm */ + data_str--; + cerror("'##' operator at end of macro"); + } + continue; + } + data_str++; + ansi_stringize = 1; + continue; + } + + if (ansi_stringize) { + ansi_stringize = 0; + cerror("'#' operator should be followed by a macro argument name"); + } + + /* Other characters ... */ + if (cc+2 > len) { len += 20; rv = realloc(rv, len); } + rv[cc++] = *data_str++; + continue; + } + *p = 0; s = curword; + for (ac=0; ac<arg_count; ac++) { + if (*curword == arg_list[ac].name[0] && + strcmp(curword, arg_list[ac].name) == 0) + { + s = arg_list[ac].value; + + /* Ansi stringize operation, this is very messy! */ + if (ansi_stringize) { + if (arg_list[ac].in_define) { + struct define_item * ptr; + if ((ptr = read_entry(0, s)) && + ptr->arg_count == -1) { + s = ptr->value; + } + } + + rv[cc++] = '"'; + while(*s == ' ' || *s == '\t') s++; + while (*s) { + if (cc+4 > len) { len += 20; rv = realloc(rv, len); } + if (*s == '"') rv[cc++] = '\\'; + rv[cc++] = *s++; + } + while(cc>0 && (rv[cc-1] == ' ' || rv[cc-1] == '\t')) + cc--; + rv[cc++] = '"'; + rv[cc++] = 0; + ansi_stringize = 0; + s = ""; + break; + } + + break; + } + } + + if (ansi_stringize) { + ansi_stringize = 0; + cerror("'#' operator should be followed by a macro argument name"); + } + + if (cc+2+strlen(s) > len) { len += strlen(s)+20; rv = realloc(rv, len); } + strcpy(rv+cc, s); + cc = strlen(rv); + } + + rv[cc] = 0; + return rv; +} diff --git a/cpp/hash.c b/cpp/hash.c new file mode 100644 index 0000000..3d340e8 --- /dev/null +++ b/cpp/hash.c @@ -0,0 +1,114 @@ + +#include <stdio.h> +#include <malloc.h> +#include "cc.h" + +/* + * Two functions: + * char * set_entry(int namespace, char * name, void * value); + * returns a pointer to the copy of the name; + * + * void * read_entry(int namespace, char * name); + * returns the value; + */ + +struct hashentry +{ + struct hashentry * next; + void * value; + int namespace; + char word[1]; +}; + +struct hashentry ** hashtable; +int hashsize = 0xFF; /* 2^X -1 */ +int hashcount = 0; +static int hashvalue(); + +void * +read_entry(namespace, word) +int namespace; +char * word; +{ + int hash_val; + struct hashentry * hashline; + if( hashtable == 0 ) return 0; + hash_val = hashvalue(namespace, word); + + hashline = hashtable[hash_val]; + + for(; hashline; hashline = hashline->next) + { + if(namespace != hashline->namespace) continue; + if(word[0] != hashline->word[0]) continue; + if(strcmp(word, hashline->word) ) continue; + return hashline->value; + } + return 0; +} + +char * +set_entry(namespace, word, value) +int namespace; +char * word; +void * value; +{ + int hash_val, i; + struct hashentry * hashline, *prev; + hash_val = hashvalue(namespace, word); + + if( hashtable ) + { + hashline = hashtable[hash_val]; + + for(prev=0; hashline; prev=hashline, hashline = hashline->next) + { + if(namespace != hashline->namespace) continue; + if(word[0] != hashline->word[0]) continue; + if(strcmp(word, hashline->word) ) continue; + if( value ) hashline->value = value; + else + { + if( prev == 0 ) hashtable[hash_val] = hashline->next; + else prev->next = hashline->next; + free(hashline); + return 0; + } + return hashline->word; + } + } + if( value == 0 ) return 0; + if( hashtable == 0 ) + { + hashtable = malloc((hashsize+1)*sizeof(char*)); + if( hashtable == 0 ) cfatal("Out of memory"); + for(i=0; i<=hashsize; i++) hashtable[i] = 0; + } + /* Add record */ + hashline = malloc(sizeof(struct hashentry)+strlen(word)); + if( hashline == 0 ) cfatal("Out of memory"); + else + { + hashline->next = hashtable[hash_val]; + hashline->namespace = namespace; + hashline->value = value; + strcpy(hashline->word, word); + hashtable[hash_val] = hashline; + } + return hashline->word; +} + +static int hashvalue(namespace, word) +int namespace; +char * word; +{ + int val = namespace; + char *p = word; + + while(*p) + { + val = ((val<<4)^((val>>12)&0xF)^((*p++)&0xFF)); + } + val &= hashsize; + return val; +} @@ -0,0 +1,77 @@ + +#define m_size((p)) ((p) [0].size) /* For malloc */ + +### Define 'm_size' as 1 args 'p,((p) [0].size) ' +#define m_next((p)) ((p) [1].next) /* For malloc and alloca */ + +### Define 'm_next' as 1 args 'p,((p) [1].next) ' +#define m_deep((p)) ((p) [0].depth) /* For alloca */ + +### Define 'm_deep' as 1 args 'p,((p) [0].depth) ' + + mm_size((p1) +### Macro substitution in '((p) [0].size) ' +### Argument 1 (p) = 'p1' + +### <DEF1='((p1) [0].size) '> +<DEF1>((pp1)) [0].ssize)) <DEF0>+= mm_size((m_next(p1)) +### Macro substitution in '((p) [0].size) ' +### Argument 1 (p) = 'm_next(p1)' + +### <DEF1='((m_next(p1)) [0].size) '> +<DEF1>((mm_next((p1) +### Macro substitution in '((p) [1].next) ' +### Argument 1 (p) = 'p1' + +### <DEF2='((p1) [1].next) '> +<DEF2>((pp1)) [1].nnext)) )<DEF1> [0].ssize)) ;<DEF0> + mm_next((p1) +### Macro substitution in '((p) [1].next) ' +### Argument 1 (p) = 'p1' + +### <DEF1='((p1) [1].next) '> +<DEF1>((pp1)) [1].nnext)) <DEF0>= mm_next((m_next(p1)) +### Macro substitution in '((p) [1].next) ' +### Argument 1 (p) = 'm_next(p1)' + +### <DEF1='((m_next(p1)) [1].next) '> +<DEF1>((mm_next((pp1))) [1].nnext)) ;<DEF0> + nnoise(("JOIN 2", pp1)); + + hhello/?/??? ? +??=warning oooer + +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ + +### Define 'LOCK_NB' as '4 ' +#define LOCK_UN 8 /* remove lock */ + +### Define 'LOCK_UN' as '8 ' + + +#define comba((x,,yy)) x/**/y + +### Define 'comba' as 2 args 'x,y,x y ' +#define combb((x,,yy)) x ## y + +### Define 'combb' as 2 args 'x,y,x ## y ' + + + ccomba((un,signed) +### Macro substitution in 'x y ' +### Argument 1 (x) = 'un' +### Argument 2 (y) = 'signed' + +### <DEF1='un signed '> +<DEF1>un ssigned ;<DEF0> + ccombb((un,signed) +### Macro substitution in 'x ## y ' +### Argument 1 (x) = 'un' +### Argument 2 (y) = 'signed' + +### <DEF1='unsigned '> +<DEF1>unsigned ;<DEF0> +. + +<EOF>
\ No newline at end of file diff --git a/cpp/main.c b/cpp/main.c new file mode 100644 index 0000000..0ef2cf2 --- /dev/null +++ b/cpp/main.c @@ -0,0 +1,390 @@ + +#include <stdio.h> +#if __STDC__ +#include <stdlib.h> +#endif +#include <ctype.h> +#include <string.h> +#include <malloc.h> + +#include "cc.h" + +#define MAXINCPATH 5 + +void print_toks_cpp _P((void)); +void print_toks_raw _P((void)); +void define_macro _P((char *)); +void undefine_macro _P((char *)); + +char * include_paths[MAXINCPATH]; + +char last_name[512] = ""; +int last_line = -1; +int debug_mode = 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"; + + in_asm = 2; /* Always in assembler mode */ + + for(ar=1; ar<argc; ar++) if( argv[ar][0] == '-') switch(argv[ar][1]) + { + case 'd': debug_mode = 1; break; + case 'T': in_asm = 0; break; + case 'E': /* in_asm = 0; */ break; + case 'A': ansi_c = 1; break; + + /* Some options for 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. */ + cfatal("-C not implemented"); + break; + case 'P': /* Supress #line lines. */ + cfatal("-P not implemented"); + 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; + } else + cfatal(Usage); + + 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(0); +} + +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; + int i; + char buf[256]; + + if( checkrel ) + { + fd=fopen(fname, mode); + if( fd ) return 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 ) return fd; + } + return 0; +} + +/*----------------------------------------------------------------------*/ + +static int outpos = 0; + +void +cmsg(mtype, str) +char * mtype; +char * str; +{ + if (mtype) { + if (c_fname && (*c_fname || c_lineno)) + fprintf(stderr, "%s %s(%d): %s\n", mtype, c_fname, c_lineno, str); + else + 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; +{ + cmsg("CPP error", str); +} + +void +cwarn(str) +char * str; +{ + cmsg("CPP 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 && + c_lineno < last_line+2 && /* XXX: Change to 10 */ + last_line > 0 && + !debug_mode ) + { + fputc('\n', ofd); last_line++; + } + + if( c_lineno != last_line || last_line <= 0 ) + { + fprintf(ofd, "# %d", c_lineno); + if( last_line <= 0 ) fprintf(ofd, " \"%s\"", c_fname); + /* if( last_line > 0 ) fprintf(ofd, " // From line %d", last_line); */ + 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!?"); + break; + + case TK_STR: + outpos += strlen(curword); + 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); + default: ; } + + if (!in_asm) { + 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++; + } + + fprintf(ofd, "%s", curword); + outpos += strlen(curword); + + if ( i == '"' ) + { + while((i=gettok()) == TK_STR) { + outpos += strlen(curword); + fprintf(ofd, "%s", curword); + } + if (i != '\n') { + outpos += strlen(curword); + fprintf(ofd, "%s", curword); + } else { + outpos++; + fputc('"', ofd); + cerror("Unterminated string"); + } + } + 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) + { + default: fprintf(ofd, "%04x: '", i); + { + char *p; + for(p=curword; *p; p++) + if(isprint(*p) && *p != '\'') + fputc(*p, ofd); + else + fprintf(ofd, "\\x%02x", (unsigned char)*p); + } + fprintf(ofd, "'\n"); + break; + case '"': + fprintf(ofd, "QSTR: \""); + while((i=gettok()) == TK_STR) { + if (i == '\n') + fprintf(ofd, "\\N"); + else + fputc(*curword, ofd), outpos++; + } + if ( i == '\n' ) fprintf(ofd, "\" --> No terminator\n"); + else fprintf(ofd, "\"\n"); + break; + case TK_NUM: + val = strtoul(curword, (void*)0, 0); + fprintf(ofd, "NUMB: %s => %ld\n", curword, val); + break; + case TK_COPY: + fprintf(ofd, "AMSG: #%s\n", curword); + break; + } + } +} + @@ -0,0 +1,23 @@ + +#define m_size(p) ((p) [0].size) /* For malloc */ +#define m_next(p) ((p) [1].next) /* For malloc and alloca */ +#define m_deep(p) ((p) [0].depth) /* For alloca */ + + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 2", p1); + + hello/?? +??=warning oooer +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + + +#define comba(x,y) x/**/y +#define combb(x,y) x ## y + + + comba(un,signed); + combb(un,signed); +. diff --git a/cpp/token1.c b/cpp/token1.c new file mode 100644 index 0000000..e53f563 --- /dev/null +++ b/cpp/token1.c @@ -0,0 +1,6 @@ + +#include <stdio.h> +#include <string.h> +#include "cc.h" + +#include "token1.h" diff --git a/cpp/token1.tok b/cpp/token1.tok new file mode 100644 index 0000000..92e6d83 --- /dev/null +++ b/cpp/token1.tok @@ -0,0 +1,26 @@ +struct token_trans { char * name; int token; }; +%% +..., TK_ELLIPSIS +>>=, TK_RIGHT_ASSIGN +<<=, TK_LEFT_ASSIGN ++=, TK_ADD_ASSIGN +-=, TK_SUB_ASSIGN +*=, TK_MUL_ASSIGN +/=, TK_DIV_ASSIGN +%=, TK_MOD_ASSIGN +&=, TK_AND_ASSIGN +^=, TK_XOR_ASSIGN +|=, TK_OR_ASSIGN +>>, TK_RIGHT_OP +<<, TK_LEFT_OP +++, TK_INC_OP +--, TK_DEC_OP +->, TK_PTR_OP +&&, TK_AND_OP +||, TK_OR_OP +<=, TK_LE_OP +>=, TK_GE_OP +==, TK_EQ_OP +!=, TK_NE_OP +.., TK_WORD +//, TK_WORD diff --git a/cpp/token2.c b/cpp/token2.c new file mode 100644 index 0000000..e113fdd --- /dev/null +++ b/cpp/token2.c @@ -0,0 +1,6 @@ + +#include <stdio.h> +#include <string.h> +#include "cc.h" + +#include "token2.h" diff --git a/cpp/token2.tok b/cpp/token2.tok new file mode 100644 index 0000000..d04e6e8 --- /dev/null +++ b/cpp/token2.tok @@ -0,0 +1,36 @@ +struct token_trans { char * name; int token; }; +%% +auto, TK_AUTO +break, TK_BREAK +case, TK_CASE +char, TK_CHAR +const, TK_CONST +continue, TK_CONTINUE +default, TK_DEFAULT +do, TK_DO +double, TK_DOUBLE +else, TK_ELSE +enum, TK_ENUM +extern, TK_EXTERN +float, TK_FLOAT +for, TK_FOR +goto, TK_GOTO +if, TK_IF +int, TK_INT +long, TK_LONG +register, TK_REGISTER +return, TK_RETURN +short, TK_SHORT +signed, TK_SIGNED +sizeof, TK_SIZEOF +static, TK_STATIC +struct, TK_STRUCT +switch, TK_SWITCH +typedef, TK_TYPEDEF +union, TK_UNION +unsigned, TK_UNSIGNED +void, TK_VOID +volatile, TK_VOLATILE +while, TK_WHILE +__FILE__, TK_FILE +__LINE__, TK_LINE diff --git a/libc/include/asm/limits.h b/libc/include/asm/limits.h index 531ea41..25cf8b7 100644 --- a/libc/include/asm/limits.h +++ b/libc/include/asm/limits.h @@ -31,9 +31,9 @@ #define UINT_MAX 0xffff /* maximum unsigned int value */ #endif -/* BCC doesn't have signed char */ -/* #define SCHAR_MAX 127 /* maximum signed char value */ -/* #define SCHAR_MIN (-128) /* minimum signed char value */ +/* BCC does have signed char now. */ +#define SCHAR_MAX 127 /* maximum signed char value */ +#define SCHAR_MIN (-128) /* minimum signed char value */ #endif #if defined(__GNUC__) && defined(__i386__) @@ -46,12 +46,12 @@ #define UINT_MAX 0xffffffff /* maximum unsigned int value */ #endif -#ifndef INT_MAX -#error "Limits.h not fully implemented" -#endif - #ifndef RAND_MAX #define RAND_MAX INT_MAX #endif +#ifndef INT_MAX +#error "Limits.h not fully implemented, INT_MAX undefined!" +#endif + #endif diff --git a/libc/include/stdio.h b/libc/include/stdio.h deleted file mode 100644 index cbdacc3..0000000 --- a/libc/include/stdio.h +++ /dev/null @@ -1,132 +0,0 @@ - -#ifndef __STDIO_H -#define __STDIO_H - -#include <features.h> -#include <sys/types.h> - -#ifndef SEEK_SET -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 -#endif - -#define _IOFBF 0x00 /* full buffering */ -#define _IOLBF 0x01 /* line buffering */ -#define _IONBF 0x02 /* no buffering */ -#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ - -#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ -#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ - -#define __MODE_READ 0x10 /* Opened in read only */ -#define __MODE_WRITE 0x20 /* Opened in write only */ -#define __MODE_RDWR 0x30 /* Opened in read/write */ - -#define __MODE_READING 0x40 /* Buffer has pending read data */ -#define __MODE_WRITING 0x80 /* Buffer has pending write data */ - -#define __MODE_EOF 0x100 /* EOF status */ -#define __MODE_ERR 0x200 /* Error status */ -#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ - -#ifdef __MSDOS__ -#define __MODE_IOTRAN 0x1000 /* MSDOS nl <-> cr,nl translation */ -#else -#define __MODE_IOTRAN 0 -#endif - -/* when you add or change fields here, be sure to change the initialization - * in stdio_init and fopen */ -struct __stdio_file { - unsigned char *bufpos; /* the next byte to write to or read from */ - unsigned char *bufread; /* the end of data returned by last read() */ - unsigned char *bufwrite; /* highest address writable by macro */ - unsigned char *bufstart; /* the start of the buffer */ - unsigned char *bufend; /* the end of the buffer; ie the byte after the last - malloc()ed byte */ - - int fd; /* the file descriptor associated with the stream */ - int mode; - - char unbuf[8]; /* The buffer for 'unbuffered' streams */ - - struct __stdio_file * next; -}; - -#define EOF (-1) -#ifndef NULL -#define NULL ((void*)0) -#endif - -typedef struct __stdio_file FILE; - -#ifdef __AS386_16__ -#define BUFSIZ (256) -#else -#define BUFSIZ (2048) -#endif - -extern FILE stdin[1]; -extern FILE stdout[1]; -extern FILE stderr[1]; - -#ifdef __MSDOS__ -#define putc(c, fp) fputc(c, fp) -#define getc(fp) fgetc(fp) -#else -#define putc(c, stream) \ - (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream)) \ - : (unsigned char) (*(stream)->bufpos++ = (c)) ) - -#define getc(stream) \ - (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \ - (*(stream)->bufpos++)) -#endif - -#define putchar(c) putc((c), stdout) -#define getchar() getc(stdin) - -#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) -#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) -#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0) -#define fileno(fp) ((fp)->fd) - -/* declare functions; not like it makes much difference without ANSI */ -/* RDB: The return values _are_ important, especially if we ever use - 8086 'large' model - */ - -/* These two call malloc */ -#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) -extern int setvbuf __P((FILE*, char*, int, size_t)); - -/* These don't */ -#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) -extern void setbuffer __P((FILE*, char*, int)); - -extern int fgetc __P((FILE*)); -extern int fputc __P((int, FILE*)); - -extern int fclose __P((FILE*)); -extern int fflush __P((FILE*)); -extern char *fgets __P((char*, size_t, FILE*)); - -extern FILE *fopen __P((char*, char*)); -extern FILE *fdopen __P((int, char*)); -extern FILE *freopen __P((char*, char*, FILE*)); - -#ifdef __LIBC__ -extern FILE *__fopen __P((char*, int, FILE*, char*)); -#endif - -extern int fputs __P((char*, FILE*)); -extern int puts __P((char*)); - -extern int printf __P ((__const char*, ...)); -extern int fprintf __P ((FILE*, __const char*, ...)); -extern int sprintf __P ((char*, __const char*, ...)); - -#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos) - -#endif /* __STDIO_H */ diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 9e96427..3c85f40 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -43,7 +43,7 @@ transfer: cp -p stdio.h ../include/. clean: - rm -f *.o libc.a + rm -f *.o libc.a ../include/stdio.h $(LIBC)($(OBJ)): stdio.h diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index e41eca4..6e7b3e1 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -23,7 +23,7 @@ #include <sys/types.h> #include <fcntl.h> -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) #include <stdarg.h> #define va_strt va_start #else @@ -35,7 +35,7 @@ #ifdef L_printf -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) int printf(const char * fmt, ...) #else int printf(fmt, va_alist) @@ -53,7 +53,7 @@ va_dcl #endif #ifdef L_sprintf -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) int sprintf(char * sp, const char * fmt, ...) #else int sprintf(sp, fmt, va_alist) @@ -80,7 +80,7 @@ static FILE string[1] = #endif #ifdef L_fprintf -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) int fprintf(FILE * fp, const char * fmt, ...) #else int fprintf(fp, fmt, va_alist) diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c index 1e0f282..a49174d 100644 --- a/libc/stdio/scanf.c +++ b/libc/stdio/scanf.c @@ -16,7 +16,7 @@ #include <ctype.h> #include <string.h> -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) #include <stdarg.h> #define va_strt va_start #else @@ -25,7 +25,7 @@ #endif #ifdef L_scanf -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) int scanf(const char * fmt, ...) #else int scanf(fmt, va_alist) @@ -43,7 +43,7 @@ va_dcl #endif #ifdef L_sscanf -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) int sscanf(char * sp, const char * fmt, ...) #else int sscanf(sp, fmt, va_alist) @@ -69,7 +69,7 @@ static FILE string[1] = #endif #ifdef L_fscanf -#ifdef __STDC__ +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) int fscanf(FILE * fp, const char * fmt, ...) #else int fscanf(fp, fmt, va_alist) diff --git a/makefile.in b/makefile.in index d921d74..bdfe358 100644 --- a/makefile.in +++ b/makefile.in @@ -79,10 +79,10 @@ INSCR=-o root -g root -m 755 #endif #ifdef GNUMAKE -all: check_config bcc unproto copt as86 ar86 ld86 objdump86 \ +all: check_config bcc cpp unproto copt as86 ar86 ld86 objdump86 \ library lib-bsd alt-libs elksemu #else -all: check_config bcc unproto copt as86 ar86 ld86 objdump86 +all: check_config bcc cpp unproto copt as86 ar86 ld86 objdump86 @echo @echo 'NOTE: To build the libraries you need GNU-Make.' @echo ' They are available precompiled in the Dev86clb-X.X.X.zip file.' @@ -115,7 +115,7 @@ DISTPRE= $(DIST)$(LIBPRE) # Others to install OTHERS= tests dis88 doselks bootblocks -CLEANLIST= bcc as ar ld unproto copt libc elksemu libbsd $(OTHERS) +CLEANLIST= bcc as ar ld cpp unproto copt libc elksemu libbsd $(OTHERS) ############################################################################## @@ -135,6 +135,10 @@ bcc: bindir cp -p bcc/ncc bin/ncc cp -p bcc/bcc-cc1 lib/bcc-cc1 +cpp: bindir + $(MAKEC) cpp $(MAKEARG) bcc-cpp + cp -p cpp/bcc-cpp lib/bcc-cpp + unproto: bindir $(MAKEC) unproto $(MAKEARG) unproto cp -p unproto/unproto lib/unproto @@ -177,7 +181,7 @@ elksemu: bindir cp -p elksemu/elksemu bin/elksemu #endif -install-ln: bcc unproto copt as86 ar86 ld86 elksemu +install-ln: bcc cpp unproto copt as86 ar86 ld86 elksemu install -d $(DISTBIN) ln -fs `pwd`/bin/ncc $(DISTBIN)/bcc ln -fs `pwd`/bin/as86_encap $(DISTBIN)/as86_encap @@ -190,7 +194,7 @@ install-ln: bcc unproto copt as86 ar86 ld86 elksemu -install -d $(DIST)/usr/lib -install $(INDAT) libc/error/liberror.txt $(DIST)/usr/lib/liberror.txt -install-bcc: bcc unproto copt as86 ar86 ld86 objdump86 +install-bcc: bcc cpp unproto copt as86 ar86 ld86 objdump86 install -d $(DISTBIN) $(DISTLIB) $(DISTLIB)/i86 install $(INEXE) bin/Bcc $(DISTBIN)/bcc install $(INSCR) bin/as86_encap $(DISTBIN)/as86_encap @@ -201,6 +205,7 @@ install-bcc: bcc unproto copt as86 ar86 ld86 objdump86 install $(INEXE) bin/objdump86 $(DISTBIN)/nm86 install $(INEXE) bin/objdump86 $(DISTBIN)/size86 install $(INEXE) lib/bcc-cc1 $(DISTLIB)/bcc-cc1 + install $(INEXE) lib/bcc-cpp $(DISTLIB)/bcc-cpp install $(INEXE) lib/unproto $(DISTLIB)/unproto install $(INEXE) lib/copt $(DISTLIB)/copt install $(INDAT) lib/rules.* $(DISTLIB)/i86 |