summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2002-07-28 22:10:50 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:47 +0200
commite6248da18100235ae33468d058e5b71fcefeff3b (patch)
tree4e3833ed515d03d2366c27f71ef0fe349a2dee12
parent2060b4f4cc1c13975e495d088344825f7700181b (diff)
downloaddev86-e6248da18100235ae33468d058e5b71fcefeff3b.tar.gz
Import Dev86src-0.16.6.tar.gzv0.16.6
-rw-r--r--Makefile2
-rw-r--r--Mk_dist2
-rw-r--r--bcc/bcc.c76
-rw-r--r--bcc/input.c1
-rw-r--r--bcc/preproc.c51
-rw-r--r--bcc/scan.h1
-rw-r--r--bcc/table.c3
-rw-r--r--cpp/Makefile26
-rw-r--r--cpp/cc.h110
-rwxr-xr-xcpp/cgbin0 -> 27808 bytes
-rw-r--r--cpp/cpp.c1427
-rw-r--r--cpp/hash.c114
-rw-r--r--cpp/log77
-rw-r--r--cpp/main.c390
-rw-r--r--cpp/q.c23
-rw-r--r--cpp/token1.c6
-rw-r--r--cpp/token1.tok26
-rw-r--r--cpp/token2.c6
-rw-r--r--cpp/token2.tok36
-rw-r--r--libc/include/asm/limits.h14
-rw-r--r--libc/include/stdio.h132
-rw-r--r--libc/stdio/Makefile2
-rw-r--r--libc/stdio/printf.c8
-rw-r--r--libc/stdio/scanf.c8
-rw-r--r--makefile.in15
25 files changed, 2364 insertions, 192 deletions
diff --git a/Makefile b/Makefile
index d1ada45..095b6c8 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/Mk_dist b/Mk_dist
index 4c42cc2..a72b9c9 100644
--- a/Mk_dist
+++ b/Mk_dist
@@ -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'
diff --git a/bcc/bcc.c b/bcc/bcc.c
index be59905..f7e7eb6 100644
--- a/bcc/bcc.c
+++ b/bcc/bcc.c
@@ -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;
}
}
diff --git a/bcc/scan.h b/bcc/scan.h
index d1de894..48ff5d2 100644
--- a/bcc/scan.h
+++ b/bcc/scan.h
@@ -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 */
+};
diff --git a/cpp/cg b/cpp/cg
new file mode 100755
index 0000000..9fbf146
--- /dev/null
+++ b/cpp/cg
Binary files differ
diff --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;
+}
diff --git a/cpp/log b/cpp/log
new file mode 100644
index 0000000..1117b3d
--- /dev/null
+++ b/cpp/log
@@ -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;
+ }
+ }
+}
+
diff --git a/cpp/q.c b/cpp/q.c
new file mode 100644
index 0000000..e24592a
--- /dev/null
+++ b/cpp/q.c
@@ -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