home *** CD-ROM | disk | FTP | other *** search
- From: decvax!minow
- Date: Tue, 8 Jan 85 00:05:20 est
- Subject: cpp1.arc
-
- -h- readme.txt Mon Jan 7 23:59:27 1985 readme.txt
-
- Decus cpp is a public-domain implementation of the C preprocessor.
- It runs on VMS native (Vax C), VMS compatibilty mode (Decus C),
- RSX-11M, RSTS/E, P/OS, and RT11, as well as on several varieties
- of Unix, including Ultrix. Decus cpp attempts to implement features
- in the Draft ANSI Standard for the C language. It should be noted,
- however, that this standard is under active development: the current
- draft of the standard explicitly states that "readers are requested
- not to specify or claim conformance to this draft." Thus readers
- and users of Decus cpp should not assume that it conforms to the
- draft standard, or that it will conform to the actual C language
- standard.
-
- These notes describe how to extract the cpp source files, configure it
- for your needs, and mention a few design decisions that may be of interest
- to maintainers.
-
- Installation
-
- Because the primary development of cpp was not on Unix, it
- is distributed using the Decus C archive program (quite similar
- to the archiver published in Kernighan and Plauger's Software
- Tools). To extract the files from the net.sources distribution,
- save this message as cpp1.arc and the other two distribution
- files as cpp2.arc and cpp3.arc. Then, using your favorite editor,
- locate the archx.c program, just following the line beginning with
- "-h- archx.c" -- the format of the distribution is just:
-
- -h- readme.txt
- ... this file
- -h- cpp.mem
- ... description of cpp
- -h- archx.c
- ... archx.c program -- extracts archives
- -h- archc.c
- ... archc.c program -- creates archives
-
- Compile archx.c -- it shouldn't require any special editing.
- Then run it as follows:
-
- archx *.arc
-
- You do not need to remove mail headers from the saved messages.
-
- You should then read through cppdef.h to make sure the HOST and
- TARGET (and other implementation-specific) definitions are set
- correctly for your machine, editing them as needed.
-
- You may then copy makefile.txt to Makefile, editing it as needed
- for your particular system. On Unix, cpp should be compiled
- by make without further difficulty. On other operating systems,
- you should compile the six source modules, linking them together.
- Note that, on Decus C based systems, you must extend the default
- stack allocation. The Decus C build utility will create the
- appropriate command file.
-
- Support Notes
-
- The USENET distribution kit was designed to keep all submissions around
- 50,000 bytes:
-
- cpp1.arc:
- readme.txt This file
- cpp.mem Documentation page (see below)
- archx.c Archive extraction program
- archc.c Archive construction program
- cpp.rno Source for cpp.mem (see below)
- makefile.txt Unix makefile -- copy to Makefile
- cpp.h Main header file (structure def's and globals)
- cppdef.h Configuration file (host and target definitions)
-
- cpp2.arc:
- cpp1.c Mainline code, documentation master sources
- cpp2.c most #control processing
- cpp3.c filename stuff and command line parsing
- cpp3.arc:
- cpp4.c #define processor
- cpp5.c #if <expr> processor
- cpp6.c Support code (symbol table and I/O routines)
-
- Cpp intentionally does not rely on the presence of a full-scale
- macro preprocessor, it does require the simple parameter substitution
- preprocessor capabilities of Unix V6 and Decus C. If your C
- language lacks full preprocessing, you should make sure "nomacargs"
- is #define'd in cpp.h. (This is done automatically by the Decus C
- compiler.)
-
- The documentation (manual page) for cpp is included as cpp.mem
- and cpp.rno. Cpp.rno is in Dec Runoff format, built by a Decus C
- utility (getrno) from original source which is embedded in cpp1.c.
- To my knowledge, there is no equivalent program that creates
- the nroff source appropriate for Unix.
-
- I would be happy to receive fixes to any problems you encounter.
- As I do not maintain distribution kit base-levels, bare-bones
- diff listings without sufficient context are not very useful.
- It is unlikely that I can find time to help you with other
- difficulties.
-
- Acknowledgements
-
- I received a great deal of help from many people in debugging cpp.
- Alan Feuer and Sam Kendall used "state of the art" run-time code
- checkers to locate several errors. Ed Keiser found problems when
- cpp was used on machines with different int and pointer sizes.
- Dave Conroy helped with the initial debugging, while Arthur Olsen
- and George Rosenberg found (and solved) several problems in the
- first USENET release.
-
- Martin Minow
- decvax!minow
-
- -h- cpp.mem Mon Jan 7 23:59:27 1985 cpp.mem
-
-
-
-
- 1.0 C Pre-Processor
-
-
-
- *******
- * cpp *
- *******
-
-
-
- NAME: cpp -- C Pre-Processor
-
- SYNOPSIS:
-
- cpp [-options] [infile [outfile]]
-
- DESCRIPTION:
-
- CPP reads a C source file, expands macros and include
- files, and writes an input file for the C compiler. If
- no file arguments are given, CPP reads from stdin and
- writes to stdout. If one file argument is given, it
- will define the input file, while two file arguments
- define both input and output files. The file name "-"
- is a synonym for stdin or stdout as appropriate.
-
- The following options are supported. Options may be
- given in either case.
-
- -C If set, source-file comments are written
- to the output file. This allows the
- output of CPP to be used as the input to
- a program, such as lint, that expects
- commands embedded in specially-formatted
- comments.
-
- -Dname=value Define the name as if the programmer
- wrote
-
- #define name value
-
- at the start of the first file. If
- "=value" is not given, a value of "1"
- will be used.
-
- On non-unix systems, all alphabetic text
- will be forced to upper-case.
-
- -E Always return "success" to the operating
- system, even if errors were detected.
- Note that some fatal errors, such as a
- missing #include file, will terminate
- CPP, returning "failure" even if the -E
- option is given.
- Page 2
- cpp C Pre-Processor
-
-
- -Idirectory Add this directory to the list of
- directories searched for #include "..."
- and #include <...> commands. Note that
- there is no space between the "-I" and
- the directory string. More than one -I
- command is permitted. On non-Unix
- systems "directory" is forced to
- upper-case.
-
- -N CPP normally predefines some symbols
- defining the target computer and
- operating system. If -N is specified,
- no symbols will be predefined. If -N -N
- is specified, the "always present"
- symbols, __LINE__, __FILE__, and
- __DATE__ are not defined.
-
- -Stext CPP normally assumes that the size of
- the target computer's basic variable
- types is the same as the size of these
- types of the host computer. (This can
- be overridden when CPP is compiled,
- however.) The -S option allows dynamic
- respecification of these values. "text"
- is a string of numbers, separated by
- commas, that specifies correct sizes.
- The sizes must be specified in the exact
- order:
-
- char short int long float double
-
- If you specify the option as "-S*text",
- pointers to these types will be
- specified. -S* takes one additional
- argument for pointer to function (e.g.
- int (*)())
-
- For example, to specify sizes
- appropriate for a PDP-11, you would
- write:
-
- c s i l f d func
- -S1,2,2,2,4,8,
- -S*2,2,2,2,2,2,2
-
- Note that all values must be specified.
-
- -Uname Undefine the name as if
-
- #undef name
-
- were given. On non-Unix systems, "name"
- will be forced to upper-case.
- Page 3
- cpp C Pre-Processor
-
-
- -Xnumber Enable debugging code. If no value is
- given, a value of 1 will be used. (For
- maintenence of CPP only.)
-
-
- PRE-DEFINED VARIABLES:
-
- When CPP begins processing, the following variables will
- have been defined (unless the -N option is specified):
-
- Target computer (as appropriate):
-
- pdp11, vax, M68000 m68000 m68k
-
- Target operating system (as appropriate):
-
- rsx, rt11, vms, unix
-
- Target compiler (as appropriate):
-
- decus, vax11c
-
- The implementor may add definitions to this list. The
- default definitions match the definition of the host
- computer, operating system, and C compiler.
-
- The following are always available unless undefined (or
- -N was specified twice):
-
- __FILE__ The input (or #include) file being
- compiled (as a quoted string).
-
- __LINE__ The line number being compiled.
-
- __DATE__ The date and time of compilation as a
- Unix ctime quoted string (the trailing
- newline is removed). Thus,
-
- printf("Bug at line %s,", __LINE__);
- printf(" source file %s", __FILE__);
- printf(" compiled on %s", __DATE__);
-
-
- DRAFT PROPOSED ANSI STANDARD CONSIDERATIONS:
-
- The current version of the Draft Proposed Standard
- explicitly states that "readers are requested not to
- specify or claim conformance to this draft." Readers and
- users of Decus CPP should not assume that Decus CPP
- conforms to the standard, or that it will conform to the
- actual C Language Standard.
-
- When CPP is itself compiled, many features of the Draft
- Proposed Standard that are incompatible with existing
- Page 4
- cpp C Pre-Processor
-
-
- preprocessors may be disabled. See the comments in
- CPP's source for details.
-
- The latest version of the Draft Proposed Standard (as
- reflected in Decus CPP) is dated November 12, 1984.
-
- Comments are removed from the input text. The comment
- is replaced by a single space character. The -C option
- preserves comments, writing them to the output file.
-
- The '$' character is considered to be a letter. This is
- a permitted extension.
-
- The following new features of C are processed by CPP:
-
- #elif expression (#else #if)
- '\xNNN' (Hexadecimal constant)
- '\a' (Ascii BELL)
- '\v' (Ascii Vertical Tab)
- #if defined NAME 1 if defined, 0 if not
- #if defined (NAME) 1 if defined, 0 if not
- #if sizeof (basic type)
- unary +
- 123U, 123LU Unsigned ints and longs.
- 12.3L Long double numbers
- token#token Token concatenation
- #include token Expands to filename
-
- The Draft Proposed Standard has extended C, adding a
- constant string concatenation operator, where
-
- "foo" "bar"
-
- is regarded as the single string "foobar". (This does
- not affect CPP's processing but does permit a limited
- form of macro argument substitution into strings as will
- be discussed.)
-
- The Standard Committee plans to add token concatenation
- to #define command lines. One suggested implementation
- is as follows: the sequence "Token1#Token2" is treated
- as if the programmer wrote "Token1Token2". This could
- be used as follows:
-
- #line 123
- #define ATLINE foo#__LINE__
-
- ATLINE would be defined as foo123.
-
- Note that "Token2" must either have the format of an
- identifier or be a string of digits. Thus, the string
-
- #define ATLINE foo#1x3
- Page 5
- cpp C Pre-Processor
-
-
- generates two tokens: "foo1" and "x3".
-
- If the tokens T1 and T2 are concatenated into T3, this
- implementation operates as follows:
-
- 1. Expand T1 if it is a macro.
- 2. Expand T2 if it is a macro.
- 3. Join the tokens, forming T3.
- 4. Expand T3 if it is a macro.
-
- A macro formal parameter will be substituted into a
- string or character constant if it is the only component
- of that constant:
-
- #define VECSIZE 123
- #define vprint(name, size) \
- printf("name" "[" "size" "] = {\n")
- ... vprint(vector, VECSIZE);
-
- expands (effectively) to
-
- vprint("vector[123] = {\n");
-
- Note that this will be useful if your C compiler
- supports the new string concatenation operation noted
- above. As implemented here, if you write
-
- #define string(arg) "arg"
- ... string("foo") ...
-
- This implementation generates "foo", rather than the
- strictly correct ""foo"" (which will probably generate
- an error message). This is, strictly speaking, an error
- in CPP and may be removed from future releases.
-
- ERROR MESSAGES:
-
- Many. CPP prints warning or error messages if you try
- to use multiple-byte character constants
- (non-transportable) if you #undef a symbol that was not
- defined, or if your program has potentially nested
- comments.
-
- AUTHOR:
-
- Martin Minow
-
- BUGS:
-
- The #if expression processor uses signed integers only.
- I.e, #if 0xFFFFu < 0 may be TRUE.
-
- -h- archx.c Mon Jan 7 23:59:27 1985 archx.c
- /*
- * A R C H X
- *
- * Archive extraction
- *
- */
-
- /*)BUILD $(TKBOPTIONS) = {
- TASK = ...ARX
- }
- */
-
- #ifdef DOCUMENTATION
-
- title archx text file archiver extraction
- index text file archiver extraction
-
- synopsis
- arch archive_files
-
- description
-
- Archx manages archives (libraries) of source files, allowing
- a large number of small files to be stored without using
- excessive system resources. Archx extracts all files from
- an archive.
-
- If no archive_name file is given, the standard input is read.
- Archive header records are echoed to the standard output.
-
- archive file format
-
- Archive files are standard text files. Each archive element is
- preceeded by a line of the format:
- .s.nf
- -h- file.name date true_name
- .s.f
- Note that there is no line or byte count. To prevent problems,
- a '-' at the beginning of a record within a user file or embedded
- archive will be "quoted" by doubling it. The date and true filename
- fields are ignored. On some operating systems, file.name is
- forced to lowercase.
-
- If the first non-blank line of an input file does not
- begin with "-h", the text will be appended to "archx.tmp"
- This is needed if archives are distributed by mail
- and arrive with initial routing and subject information.
-
- diagnostics
-
- Diagnostic messages should be self-explanatory
-
- author
-
- Martin Minow
-
- bugs
-
- #endif
-
- #include <stdio.h>
- #include <ctype.h>
- #define EOS 0
- #define FALSE 0
- #define TRUE 1
- #ifdef vms
- #include <ssdef.h>
- extern int errno;
- #define IO_ERROR errno
- #define IO_NORMAL SS$_NORMAL
- #endif
- #ifndef IO_NORMAL
- #define IO_NORMAL 0
- #endif
- #ifndef IO_ERROR
- #define IO_ERROR 1
- #endif
-
- /*
- * The following status codes are returned by gethdr()
- */
- #define DONE 0
- #define GOTCHA 1
- #define NOGOOD 2
-
- char text[513]; /* Working text line */
- char name[81]; /* Current archive member name */
- char filename[81]; /* Working file name */
- char arfilename[81]; /* Archive file name */
- char fullname[81]; /* Output for argetname() */
- int verbose = TRUE; /* TRUE for verbosity */
- int first_archive; /* For mail header skipping */
-
- main(argc, argv)
- int argc; /* Arg count */
- char *argv[]; /* Arg vector */
- {
- register int i; /* Random counter */
- int status; /* Exit status */
-
- #ifdef vms
- argc = getredirection(argc, argv);
- #endif
- status = IO_NORMAL;
- if (argc == 1)
- process();
- else {
- for (i = 1; i < argc; i++) {
- if (freopen(argv[i], "r", stdin) != NULL)
- process();
- else {
- perror(argv[i]);
- status = IO_ERROR;
- }
- }
- }
- exit(status);
- }
-
- process()
- /*
- * Process archive open on stdin
- */
- {
- register char *fn; /* File name pointer */
- register FILE *outfd;
- register int i;
-
- text[0] = EOS;
- while ((i = gethdr()) != DONE) {
- switch (i) {
- case GOTCHA:
- if ((outfd = fopen(name, "w")) == NULL) {
- perror(name);
- fprintf(stderr, "Can't create \"%s\"\n", name);
- arskip();
- continue;
- }
- break;
-
- case NOGOOD:
- fprintf(stderr, "Missing -h-, writing to archx.tmp\n");
- fprintf(stderr, "Current text line: %s", text);
- strcpy(name, "archx.tmp");
- if ((outfd = fopen(name, "a")) == NULL) {
- perror(name);
- fprintf(stderr, "Cannot append to %s\n", name);
- arskip();
- continue;
- }
- break;
- }
- arexport(outfd);
- fclose(outfd);
- }
- }
-
- int
- gethdr()
- /*
- * If text is null, read a record, returning to signal input state:
- * DONE Eof read
- * NOGOOD -h- wasn't first non-blank line. Line is in text[]
- * GOTCHA -h- found, parsed into name.
- */
- {
- register char *tp;
- register char *np;
-
- again: if (text[0] == EOS
- && fgets(text, sizeof text, stdin) == NULL)
- return (DONE);
- if (text[0] == '\n' && text[1] == EOS) {
- text[0] = EOS;
- goto again;
- }
- if (text[0] != '-'
- || text[1] != 'h'
- || text[2] != '-')
- return (NOGOOD);
- for (tp = &text[3]; isspace(*tp); tp++)
- ;
- for (np = name; !isspace(*tp); *np++ = *tp++)
- ;
- *np = EOS;
- return (GOTCHA);
- }
-
- arskip()
- /*
- * Skip to next header
- */
- {
- while (fgets(text, sizeof text, stdin) != NULL) {
- if (text[0] == '-' && text[1] != '-')
- return;
- }
- text[0] = EOS; /* EOF signal */
- }
-
- arexport(outfd)
- register FILE *outfd;
- /*
- * Read secret archive format, writing archived data to outfd.
- * Clean out extraneous <cr>,<lf>'s
- */
- {
- register char *tp;
- unsigned int nrecords;
-
- printf("Creating \"%s\", ", name);
- nrecords = 0;
- while (fgets(text, sizeof text, stdin) != NULL) {
- tp = &text[strlen(text)];
- if (tp > &text[1] && *--tp == '\n' && *--tp == '\r') {
- *tp++ = '\n';
- *tp = EOS;
- }
- if (text[0] == '-') {
- if (text[1] != '-')
- goto gotcha;
- fputs(text+1, outfd);
- }
- else {
- fputs(text, outfd);
- }
- nrecords++;
- }
- text[0] = EOS;
- gotcha: printf("%u records\n", nrecords);
- if (ferror(stdin) || ferror(outfd))
- printf("Creation of \"%s\" completed with error\n", name);
- }
-
- /*
- * getredirection() is intended to aid in porting C programs
- * to VMS (Vax-11 C) which does not support '>' and '<'
- * I/O redirection. With suitable modification, it may
- * useful for other portability problems as well.
- */
-
- #ifdef vms
- static int
- getredirection(argc, argv)
- int argc;
- char **argv;
- /*
- * Process vms redirection arg's. Exit if any error is seen.
- * If getredirection() processes an argument, it is erased
- * from the vector. getredirection() returns a new argc value.
- *
- * Warning: do not try to simplify the code for vms. The code
- * presupposes that getredirection() is called before any data is
- * read from stdin or written to stdout.
- *
- * Normal usage is as follows:
- *
- * main(argc, argv)
- * int argc;
- * char *argv[];
- * {
- * argc = getredirection(argc, argv);
- * }
- */
- {
- register char *ap; /* Argument pointer */
- int i; /* argv[] index */
- int j; /* Output index */
- int file; /* File_descriptor */
- extern int errno; /* Last vms i/o error */
-
- for (j = i = 1; i < argc; i++) { /* Do all arguments */
- switch (*(ap = argv[i])) {
- case '<': /* <file */
- if (freopen(++ap, "r", stdin) == NULL) {
- perror(ap); /* Can't find file */
- exit(errno); /* Is a fatal error */
- }
-
- case '>': /* >file or >>file */
- if (*++ap == '>') { /* >>file */
- /*
- * If the file exists, and is writable by us,
- * call freopen to append to the file (using the
- * file's current attributes). Otherwise, create
- * a new file with "vanilla" attributes as if
- * the argument was given as ">filename".
- * access(name, 2) is TRUE if we can write on
- * the specified file.
- */
- if (access(++ap, 2) == 0) {
- if (freopen(ap, "a", stdout) != NULL)
- break; /* Exit case statement */
- perror(ap); /* Error, can't append */
- exit(errno); /* After access test */
- } /* If file accessable */
- }
- /*
- * On vms, we want to create the file using "standard"
- * record attributes. create(...) creates the file
- * using the caller's default protection mask and
- * "variable length, implied carriage return"
- * attributes. dup2() associates the file with stdout.
- */
- if ((file = creat(ap, 0, "rat=cr", "rfm=var")) == -1
- || dup2(file, fileno(stdout)) == -1) {
- perror(ap); /* Can't create file */
- exit(errno); /* is a fatal error */
- } /* If '>' creation */
- break; /* Exit case test */
-
- default:
- argv[j++] = ap; /* Not a redirector */
- break; /* Exit case test */
- }
- } /* For all arguments */
- return (j);
- }
- #endif
-
- -h- archc.c Mon Jan 7 23:59:27 1985 archc.c
- /*
- * A R C H I V E
- *
- * Create an archive
- *
- */
-
- /*)BUILD $(TKBOPTIONS) = {
- TASK = ...ARC
- }
- */
-
- #ifdef DOCUMENTATION
-
- title archc text file archive creation
- index text file archive creation
-
- synopsis
-
- archc file[s] >archive
-
- description
-
- Archc manages archives (libraries) of source files, allowing
- a large number of small files to be stored without using
- excessive system resources. It copies the set of named
- files to standard output in archive format.
-
- The archx program will recreate the files from an archive.
-
- Note: there are no checks against the same file appearing
- twice in an archive.
-
- archive file format
-
- Archive files are standard text files. Each archive element is
- preceeded by a line of the format:
- .s.nf
- -h- file.name date true_path_name
- .s.f
- Note that there is no line or byte count. To prevent problems,
- a '-' at the beginning of a record within a user file or embedded
- archive will be "quoted" by doubling it. The date and true filename
- fields are ignored. On Dec operating systems, file.name is
- forced to lowercase.
-
- diagnostics
-
- Diagnostic messages should be self-explanatory
-
- author
-
- Martin Minow
-
- #endif
-
- #include <stdio.h>
- #include <ctype.h>
- #define EOS 0
- #define FALSE 0
- #define TRUE 1
-
- char text[513]; /* Working text */
- char name[81]; /* Current archive member name */
- char pathname[81]; /* Output for argetname() */
- char *timetext; /* Time of day text */
- int verbose = TRUE; /* TRUE for verbosity */
- FILE *infd; /* Input file */
-
- main(argc, argv)
- int argc; /* Arg count */
- char *argv[]; /* Arg vector */
- {
- register int i; /* Random counter */
- register char *fn; /* File name pointer */
- register char *argp; /* Arg pointer */
- int nfiles;
- extern char *ctime();
- extern long time();
- long timval;
-
- time(&timval);
- timetext = ctime(&timval);
- timetext[24] = EOS;
- argc = getredirection(argc, argv);
- if (argc <= 1)
- fprintf(stderr, "No files to archive?\n");
- #ifdef unix
- for (i = 1; i < argc; i++) {
- if ((infd = fopen(argv[i], "r")) == NULL)
- perror(argv[i]);
- else {
- strcpy(pathname, argv[i]);
- import();
- fclose(infd);
- }
- }
- #else
- for (i = 1; i < argc; i++) {
- if ((infd = fwild(argv[i], "r")) == NULL)
- perror(argv[i]);
- else {
- for (nfiles = 0; fnext(infd) != NULL; nfiles++) {
- fgetname(infd, pathname);
- import();
- }
- fclose(infd);
- if (nfiles == 0)
- fprintf(stderr, "No files match \"%s\"\n", argv[i]);
- }
- }
- #endif
- }
-
- import()
- /*
- * Add the file open on infd (with file name in pathname) to
- * the archive.
- */
- {
- unsigned int nrecords;
-
- fixname();
- nrecords = 0;
- printf("-h- %s\t%s\t%s\n", name, timetext, pathname);
- while (fgets(text, sizeof text, infd) != NULL) {
- if (text[0] == '-')
- putchar('-'); /* Quote */
- fputs(text, stdout);
- nrecords++;
- }
- if (ferror(infd)) {
- perror(name);
- fprintf(stderr, "Error when importing a file\n");
- }
- if (verbose) {
- fprintf(stderr, "%u records read from %s\n",
- nrecords, pathname);
- }
- }
-
- fixname()
- /*
- * Get file name (in pathname), stripping off device:[directory]
- * and ;version. The archive name ("file.ext") is written to name[].
- * On a dec operating system, name is forced to lowercase.
- */
- {
- register char *tp;
- register char *ip;
- char bracket;
- extern char *strrchr();
-
- #ifdef unix
- /*
- * name is after all directory information
- */
- if ((tp = strrchr(pathname, '/')) != NULL)
- tp++;
- else
- tp = pathname;
- strcpy(name, tp);
- #else
- strcpy(name, pathname);
- if ((tp = strrchr(name, ';')) != NULL)
- *tp = EOS;
- while ((tp = strchr(name, ':')) != NULL)
- strcpy(name, tp + 1);
- switch (name[0]) {
- case '[': bracket = ']';
- break;
- case '<': bracket = '>';
- break;
- case '(': bracket = ')';
- break;
- default: bracket = EOS;
- break;
- }
- if (bracket != EOS) {
- if ((tp = strchr(name, bracket)) == NULL) {
- fprintf(stderr, "? Illegal file name \"%s\"\n",
- pathname);
- }
- else {
- strcpy(name, tp + 1);
- }
- }
- for (tp = name; *tp != EOS; tp++) {
- if (isupper(*tp))
- *tp = tolower(*tp);
- }
- #endif
- }
-
- #ifdef unix
- char *
- strrchr(stng, chr)
- register char *stng;
- register char chr;
- /*
- * Return rightmost instance of chr in stng.
- * This has the wrong name on some Unix systems.
- */
- {
- register char *result;
-
- result = NULL;
-
- do {
- if (*stng == chr)
- result = stng;
- } while (*stng++ != EOS);
- return (result);
- }
- #endif
-
- /*
- * getredirection() is intended to aid in porting C programs
- * to VMS (Vax-11 C) which does not support '>' and '<'
- * I/O redirection. With suitable modification, it may
- * useful for other portability problems as well.
- */
-
- static int
- getredirection(argc, argv)
- int argc;
- char **argv;
- /*
- * Process vms redirection arg's. Exit if any error is seen.
- * If getredirection() processes an argument, it is erased
- * from the vector. getredirection() returns a new argc value.
- *
- * Warning: do not try to simplify the code for vms. The code
- * presupposes that getredirection() is called before any data is
- * read from stdin or written to stdout.
- *
- * Normal usage is as follows:
- *
- * main(argc, argv)
- * int argc;
- * char *argv[];
- * {
- * argc = getredirection(argc, argv);
- * }
- */
- {
- #ifdef vms
- register char *ap; /* Argument pointer */
- int i; /* argv[] index */
- int j; /* Output index */
- int file; /* File_descriptor */
- extern int errno; /* Last vms i/o error */
-
- for (j = i = 1; i < argc; i++) { /* Do all arguments */
- switch (*(ap = argv[i])) {
- case '<': /* <file */
- if (freopen(++ap, "r", stdin) == NULL) {
- perror(ap); /* Can't find file */
- exit(errno); /* Is a fatal error */
- }
-
- case '>': /* >file or >>file */
- if (*++ap == '>') { /* >>file */
- /*
- * If the file exists, and is writable by us,
- * call freopen to append to the file (using the
- * file's current attributes). Otherwise, create
- * a new file with "vanilla" attributes as if
- * the argument was given as ">filename".
- * access(name, 2) is TRUE if we can write on
- * the specified file.
- */
- if (access(++ap, 2) == 0) {
- if (freopen(ap, "a", stdout) != NULL)
- break; /* Exit case statement */
- perror(ap); /* Error, can't append */
- exit(errno); /* After access test */
- } /* If file accessable */
- }
- /*
- * On vms, we want to create the file using "standard"
- * record attributes. create(...) creates the file
- * using the caller's default protection mask and
- * "variable length, implied carriage return"
- * attributes. dup2() associates the file with stdout.
- */
- if ((file = creat(ap, 0, "rat=cr", "rfm=var")) == -1
- || dup2(file, fileno(stdout)) == -1) {
- perror(ap); /* Can't create file */
- exit(errno); /* is a fatal error */
- } /* If '>' creation */
- break; /* Exit case test */
-
- default:
- argv[j++] = ap; /* Not a redirector */
- break; /* Exit case test */
- }
- } /* For all arguments */
- return (j);
- #else
- /*
- * Note: argv[] is referenced to fool the Decus C
- * syntax analyser, supressing an unneeded warning
- * message.
- */
- return (argv[0], argc); /* Just return as seen */
- #endif
- }
-
- -h- cpp.rno Mon Jan 7 23:59:27 1985 cpp.rno
- .lm 8.rm 72.nhy
-
- .no autosubtitle .style headers 3,0,0
- .pg.uc.ps 58,80.lm 8.rm 72
- .hd
- .hd mixed
- .head mixed
-
- .st ########cpp#####C Pre-Processor
- .pg
- .hl 1 ^&C Pre-Processor\&
- .s 2
- .c ;*******
- .c ;* cpp *
- .c ;*******
- .s 2
- .lm +8
- .s.i -8;NAME: cpp -- C Pre-Processor
- .s.f
- .i -8;SYNOPSIS:
- .s.nf
- cpp [-options] [infile [outfile]]
- .s.f
- .i -8;DESCRIPTION:
- .s
- CPP reads a C source file, expands macros and include
- files, and writes an input file for the C compiler.
- If no file arguments are given, CPP reads from stdin
- and writes to stdout. If one file argument is given,
- it will define the input file, while two file arguments
- define both input and output files. The file name "-"
- is a synonym for stdin or stdout as appropriate.
- .s
- The following options are supported. Options may
- be given in either case.
- .lm +16
- .p -16
- --C If set, source-file comments are written
- to the output file. This allows the output of CPP to be
- used as the input to a program, such as lint, that expects
- commands embedded in specially-formatted comments.
- .p -16
- --Dname=value Define the name as if the programmer wrote
- .s
- .nf
- _#define name value
- .s
- .fill
- at the start of the first file. If "=value" is not
- given, a value of "1" will be used.
- .s
- On non-unix systems, all alphabetic text will be forced
- to upper-case.
- .p -16
- --E Always return "success" to the operating
- system, even if errors were detected. Note that some fatal
- errors, such as a missing _#include file, will terminate
- CPP, returning "failure" even if the -E option is given.
- .p -16
- --Idirectory Add this directory to the list of
- directories searched for _#include "..." and _#include <...>
- commands. Note that there is no space between the
- "-I" and the directory string. More than one -I command
- is permitted. On non-Unix systems "directory" is forced
- to upper-case.
- .p -16
- --N CPP normally predefines some symbols defining
- the target computer and operating system. If -N is specified,
- no symbols will be predefined. If -N -N is specified, the
- "always present" symbols, ____LINE____, ____FILE____, and ____DATE____
- are not defined.
- .p -16
- --Stext CPP normally assumes that the size of
- the target computer's basic variable types is the same as the size
- of these types of the host computer. (This can be overridden
- when CPP is compiled, however.) The -S option allows dynamic
- respecification of these values. "text" is a string of
- numbers, separated by commas, that specifies correct sizes.
- The sizes must be specified in the exact order:
- .s
- .nf
- char short int long float double
- .s
- .fill
- If you specify the option as "-S*text", pointers to these
- types will be specified. -S* takes one additional argument
- for pointer to function (e.g. int (*)())
- .s
- For example, to specify sizes appropriate for a PDP-11,
- you would write:
- .s
- .nf
- c s i l f d func
- -S1,2,2,2,4,8,
- -S*2,2,2,2,2,2,2
- .s
- .fill
- Note that all values must be specified.
- .p -16
- --Uname Undefine the name as if
- .s
- .nf
- _#undef name
- .s
- .fill
- were given. On non-Unix systems, "name" will be forced to
- upper-case.
- .p -16
- --Xnumber Enable debugging code. If no value is
- given, a value of 1 will be used. (For maintenence of
- CPP only.)
- .s.lm -16
- .s
- .i -8;PRE-DEFINED VARIABLES:
- .s
- When CPP begins processing, the following variables will
- have been defined (unless the -N option is specified):
- .s
- Target computer (as appropriate):
- .s
- .nf
- pdp11, vax, M68000 m68000 m68k
- .fill
- .s
- Target operating system (as appropriate):
- .s
- .nf
- rsx, rt11, vms, unix
- .fill
- .s
- Target compiler (as appropriate):
- .s
- .nf
- decus, vax11c
- .fill
- .s
- The implementor may add definitions to this list.
- The default definitions match the definition of the
- host computer, operating system, and C compiler.
- .s
- The following are always available unless undefined (or
- --N was specified twice):
- .lm +16
- .p -12
- ____FILE____ The input (or _#include) file being compiled
- (as a quoted string).
- .p -12
- ____LINE____ The line number being compiled.
- .p -12
- ____DATE____ The date and time of compilation as
- a Unix ctime quoted string (the trailing newline is removed).
- Thus,
- .s
- .nf
- printf("Bug at line _%s,", ____LINE____);
- printf(" source file _%s", ____FILE____);
- printf(" compiled on _%s", ____DATE____);
- .fill
- .s.lm -16
- .s
- .i -8;DRAFT PROPOSED ANSI STANDARD CONSIDERATIONS:
- .s
- The current version of the Draft Proposed Standard
- explicitly states that "readers are requested not to specify
- or claim conformance to this draft." Readers and users
- of Decus CPP should not assume that Decus CPP conforms
- to the standard, or that it will conform to the actual
- C Language Standard.
- .s
- When CPP is itself compiled, many features of the Draft
- Proposed Standard that are incompatible with existing
- preprocessors may be disabled. See the comments in CPP's
- source for details.
- .s
- The latest version of the Draft Proposed Standard (as reflected
- in Decus CPP) is dated November 12, 1984.
- .s
- Comments are removed from the input text. The comment
- is replaced by a single space character. The -C option
- preserves comments, writing them to the output file.
- .s
- The '$' character is considered to be a letter. This is
- a permitted extension.
- .s
- The following new features of C are processed by CPP:
- .s.comment Note: significant spaces, not tabs, .br quotes #if, #elif
- .br;####_#elif expression (_#else _#if)
- .br;####'_\xNNN' (Hexadecimal constant)
- .br;####'_\a' (Ascii BELL)
- .br;####'_\v' (Ascii Vertical Tab)
- .br;####_#if defined NAME 1 if defined, 0 if not
- .br;####_#if defined (NAME) 1 if defined, 0 if not
- .br;####_#if sizeof (basic type)
- .br;####unary +
- .br;####123U, 123LU Unsigned ints and longs.
- .br;####12.3L Long double numbers
- .br;####token_#token Token concatenation
- .br;####_#include token Expands to filename
- .s
- The Draft Proposed Standard has extended C, adding a constant
- string concatenation operator, where
- .s
- .nf
- "foo" "bar"
- .s
- .fill
- is regarded as the single string "foobar". (This does not
- affect CPP's processing but does permit a limited form of
- macro argument substitution into strings as will be discussed.)
- .s
- The Standard Committee plans to add token concatenation
- to _#define command lines. One suggested implementation
- is as follows: the sequence "Token1_#Token2" is treated
- as if the programmer wrote "Token1Token2". This could
- be used as follows:
- .s
- .nf
- _#line 123
- _#define ATLINE foo_#____LINE____
- .s
- .fill
- ATLINE would be defined as foo123.
- .s
- Note that "Token2" must either have the format of an
- identifier or be a string of digits. Thus, the string
- .s
- .nf
- _#define ATLINE foo_#1x3
- .s
- .fill
- generates two tokens: "foo1" and "x3".
- .s
- If the tokens T1 and T2 are concatenated into T3,
- this implementation operates as follows:
- .s
- .nf
- 1. Expand T1 if it is a macro.
- 2. Expand T2 if it is a macro.
- 3. Join the tokens, forming T3.
- 4. Expand T3 if it is a macro.
- .s
- .fill
- A macro formal parameter will be substituted into a string
- or character constant if it is the only component of that
- constant:
- .s
- .nf
- _#define VECSIZE 123
- _#define vprint(name, size) _\
- printf("name" "[" "size" "] = {_\n")
- ... vprint(vector, VECSIZE);
- .s
- .fill
- expands (effectively) to
- .s
- .nf
- vprint("vector[123] = {_\n");
- .s
- .fill
- Note that this will be useful if your C compiler supports
- the new string concatenation operation noted above.
- As implemented here, if you write
- .s
- .nf
- _#define string(arg) "arg"
- ... string("foo") ...
- .s
- .fill
- This implementation generates "foo", rather than the strictly
- correct ""foo"" (which will probably generate an error message).
- This is, strictly speaking, an error in CPP and may be removed
- from future releases.
- .s
- .i -8;ERROR MESSAGES:
- .s
- Many. CPP prints warning or error messages if you try to
- use multiple-byte character constants (non-transportable)
- if you _#undef a symbol that was not defined, or if your
- program has potentially nested comments.
- .s
- .i -8;AUTHOR:
- .s
- Martin Minow
- .s
- .i -8;BUGS:
- .s
- The _#if expression processor uses signed integers only.
- I.e, _#if 0xFFFFu < 0 may be TRUE.
- .s
- .lm 8.rm 72.nhy
-
- -h- makefile.txt Mon Jan 7 23:59:27 1985 makefile.txt
- # Unix makefile for cpp
- #
- # The redefinition of strchr() and strrchr() are needed for
- # Ultrix-32, Unix 4.2 bsd (and maybe some other Unices).
- #
- BSDDEFINE = -Dstrchr=index -Dstrrchr=rindex
- #
- # On certain systems, such as Unix System III, you may need to define
- # $(LINTFLAGS) in the make command line to set system-specific lint flags.
- #
- # This Makefile assumes cpp will replace the "standard" preprocessor.
- # Delete the reference to -DLINE_PREFIX=\"\" if cpp is used stand-alone.
- # LINEFIX is a sed script filter that reinserts #line -- used for testing
- # if LINE_PREFIX is set to "". Note that we must stand on our heads to
- # match the # and a line had better not begin with $. By the way, what
- # we really want is
- # LINEFIX = | sed "s/^#/#line/"
- #
- CPPDEFINE = -DLINE_PREFIX=\"\"
- LINEFIX = | sed "s/^[^ !\"%-~]/&line/"
- #
- # Define OLD_PREPROCESSOR non-zero to make a preprocessor which is
- # "as compatible as possible" with the standard Unix V7 or Ultrix
- # preprocessors. This is needed to rebuild 4.2bsd, for example, as
- # the preprocessor is used to modify assembler code, rather than C.
- # This is not recommended for current development. OLD_PREPROCESSOR
- # forces the following definitions:
- # OK_DOLLAR FALSE $ is not allowed in variables
- # OK_CONCAT FALSE # cannot concatenate tokens
- # COMMENT_INVISIBLE TRUE old-style comment concatenation
- # STRING_FORMAL TRUE old-style string expansion
- #
- OLDDEFINE = -DOLD_PREPROCESSOR=1
- #
- # DEFINES collects all -D arguments for cc and lint:
- # Change DEFINES = $(BSDDEFINE) $(CPPDEFINE) $(OLDDEFINE)
- # for an old-style preprocessor.
- #
- DEFINES = $(BSDDEFINE) $(CPPDEFINE)
-
- CFLAGS = -O $(DEFINES)
-
- #
- # ** compile cpp
- #
- SRCS = cpp1.c cpp2.c cpp3.c cpp4.c cpp5.c cpp6.c
- OBJS = cpp1.o cpp2.o cpp3.o cpp4.o cpp5.o cpp6.o
- cpp: $(OBJS)
- $(CC) $(CFLAGS) $(OBJS) -o cpp
-
- #
- # ** Test cpp by preprocessing itself, compiling the result,
- # ** repeating the process and diff'ing the result. Note: this
- # ** is not a good test of cpp, but a simple verification.
- # ** The diff's should not report any changes.
- # ** Note that a sed script may be executed for each compile
- #
- test:
- cpp cpp1.c $(LINEFIX) >old.tmp1.c
- cpp cpp2.c $(LINEFIX) >old.tmp2.c
- cpp cpp3.c $(LINEFIX) >old.tmp3.c
- cpp cpp4.c $(LINEFIX) >old.tmp4.c
- cpp cpp5.c $(LINEFIX) >old.tmp5.c
- cpp cpp6.c $(LINEFIX) >old.tmp6.c
- $(CC) $(CFLAGS) old.tmp[123456].c
- a.out cpp1.c >new.tmp1.c
- a.out cpp2.c >new.tmp2.c
- a.out cpp3.c >new.tmp3.c
- a.out cpp4.c >new.tmp4.c
- a.out cpp5.c >new.tmp5.c
- a.out cpp6.c >new.tmp6.c
- diff old.tmp1.c new.tmp1.c
- diff old.tmp2.c new.tmp2.c
- diff old.tmp3.c new.tmp3.c
- diff old.tmp4.c new.tmp4.c
- diff old.tmp5.c new.tmp5.c
- diff old.tmp6.c new.tmp6.c
- rm a.out old.tmp[123456].* new.tmp[123456].*
-
- #
- # A somewhat more extensive test is provided by the "clock"
- # program (which is not distributed). Substitute your favorite
- # macro-rich program here.
- #
- clock: clock.c cpp
- cpp clock.c $(LINEFIX) >temp.cpp.c
- cc temp.cpp.c -lcurses -ltermcap -o clock
- rm temp.cpp.c
-
- #
- # ** Lint the code
- #
-
- lint: $(SRCS)
- lint $(LINTFLAGS) $(DEFINES) $(SRCS)
-
- #
- # ** Remove unneeded files
- #
- clean:
- rm -f $(OBJS) cpp
-
- #
- # ** Rebuild the archive files needed to distribute cpp
- # ** Uses the Decus C archive utility.
- #
-
- archc: archc.c
- $(CC) $(CFLAGS) archc.c -o archc
-
- archx: archx.c
- $(CC) $(CFLAGS) archx.c -o archx
-
- archive: archc
- archc readme.txt cpp.mem archx.c archc.c cpp.rno makefile.txt \
- cpp*.h >cpp1.arc
- archc cpp1.c cpp2.c cpp3.c >cpp2.arc
- archc cpp4.c cpp5.c cpp6.c >cpp3.arc
-
- #
- # Object module dependencies
- #
-
- cpp1.o : cpp1.c cpp.h cppdef.h
-
- cpp2.o : cpp2.c cpp.h cppdef.h
-
- cpp3.o : cpp3.c cpp.h cppdef.h
-
- cpp4.o : cpp4.c cpp.h cppdef.h
-
- cpp5.o : cpp5.c cpp.h cppdef.h
-
- cpp6.o : cpp6.c cpp.h cppdef.h
-
-
- -h- cpp.h Mon Jan 7 23:59:27 1985 cpp.h
-
- /*
- * I n t e r n a l D e f i n i t i o n s f o r C P P
- *
- * In general, definitions in this file should not be changed.
- */
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
- #ifndef EOS
- /*
- * This is predefined in Decus C
- */
- #define EOS '\0' /* End of string */
- #endif
- #define EOF_CHAR 0 /* Returned by get() on eof */
- #define NULLST ((char *) NULL) /* Pointer to nowhere (linted) */
- #define DEF_NOARGS (-1) /* #define foo vs #define foo() */
-
- /*
- * The following may need to change if the host system doesn't use ASCII.
- */
- #define DEF_MAGIC 0x1D /* Magic for #defines */
- #define TOK_SEP 0x1E /* Token concatenation delim. */
- #define COM_SEP 0x1F /* Magic comment separator */
-
- /*
- * Note -- in Ascii, the following will map macro formals onto DEL + the
- * C1 control character region (decimal 128 .. (128 + PAR_MAC)) which will
- * be ok as long as PAR_MAC is less than 33). Note that the last PAR_MAC
- * value is reserved for string substitution.
- */
-
- #define MAC_PARM 0x7F /* Macro formals start here */
- #if PAR_MAC >= 33
- assertion fails -- PAR_MAC isn't less than 33
- #endif
- #define LASTPARM (PAR_MAC - 1)
-
- /*
- * Character type codes.
- */
-
- #define INV 0 /* Invalid, must be zero */
- #define OP_EOE INV /* End of expression */
- #define DIG 1 /* Digit */
- #define LET 2 /* Identifier start */
- #define FIRST_BINOP OP_ADD
- #define OP_ADD 3
- #define OP_SUB 4
- #define OP_MUL 5
- #define OP_DIV 6
- #define OP_MOD 7
- #define OP_ASL 8
- #define OP_ASR 9
- #define OP_AND 10 /* &, not && */
- #define OP_OR 11 /* |, not || */
- #define OP_XOR 12
- #define OP_EQ 13
- #define OP_NE 14
- #define OP_LT 15
- #define OP_LE 16
- #define OP_GE 17
- #define OP_GT 18
- #define OP_ANA 19 /* && */
- #define OP_ORO 20 /* || */
- #define OP_QUE 21 /* ? */
- #define OP_COL 22 /* : */
- #define OP_CMA 23 /* , (relevant?) */
- #define LAST_BINOP OP_CMA /* Last binary operand */
- /*
- * The following are unary.
- */
- #define FIRST_UNOP OP_PLU /* First Unary operand */
- #define OP_PLU 24 /* + (draft ANSI standard) */
- #define OP_NEG 25 /* - */
- #define OP_COM 26 /* ~ */
- #define OP_NOT 27 /* ! */
- #define LAST_UNOP OP_NOT
- #define OP_LPA 28 /* ( */
- #define OP_RPA 29 /* ) */
- #define OP_END 30 /* End of expression marker */
- #define OP_MAX (OP_END + 1) /* Number of operators */
- #define OP_FAIL (OP_END + 1) /* For error returns */
-
- /*
- * The following are for lexical scanning only.
- */
-
- #define QUO 65 /* Both flavors of quotation */
- #define DOT 66 /* . might start a number */
- #define SPA 67 /* Space and tab */
- #define BSH 68 /* Just a backslash */
- #define END 69 /* EOF */
-
- /*
- * These bits are set in ifstack[]
- */
- #define WAS_COMPILING 1 /* TRUE if compile set at entry */
- #define ELSE_SEEN 2 /* TRUE when #else processed */
- #define TRUE_SEEN 4 /* TRUE when #if TRUE processed */
-
- /*
- * Define bits for the basic types and their adjectives
- */
-
- #define T_CHAR 1
- #define T_INT 2
- #define T_FLOAT 4
- #define T_DOUBLE 8
- #define T_SHORT 16
- #define T_LONG 32
- #define T_SIGNED 64
- #define T_UNSIGNED 128
- #define T_PTR 256 /* Pointer */
- #define T_FPTR 512 /* Pointer to functions */
-
- /*
- * The DEFBUF structure stores information about #defined
- * macros. Note that the defbuf->repl information is always
- * in malloc storage.
- */
-
- typedef struct defbuf {
- struct defbuf *link; /* Next define in chain */
- char *repl; /* -> replacement */
- int hash; /* Symbol table hash */
- int nargs; /* For define(args) */
- char name[1]; /* #define name */
- } DEFBUF;
-
- /*
- * The FILEINFO structure stores information about open files
- * and macros being expanded.
- */
-
- typedef struct fileinfo {
- char *bptr; /* Buffer pointer */
- int line; /* for include or macro */
- FILE *fp; /* File if non-null */
- struct fileinfo *parent; /* Link to includer */
- char *filename; /* File/macro name */
- char *progname; /* From #line statement */
- unsigned int unrecur; /* For macro recursion */
- char buffer[1]; /* current input line */
- } FILEINFO;
-
- /*
- * The SIZES structure is used to store the values for #if sizeof
- */
-
- typedef struct sizes {
- short bits; /* If this bit is set, */
- short size; /* this is the datum size value */
- short psize; /* this is the pointer size */
- } SIZES;
- /*
- * nomacarg is a built-in #define on Decus C.
- */
-
- #ifdef nomacarg
- #define cput output /* cput concatenates tokens */
- #else
- #if COMMENT_INVISIBLE
- #define cput(c) { if (c != TOK_SEP && c != COM_SEP) putchar(c); }
- #else
- #define cput(c) { if (c != TOK_SEP) putchar(c); }
- #endif
- #endif
-
- #ifndef nomacarg
- #define streq(s1, s2) (strcmp(s1, s2) == 0)
- #endif
-
- /*
- * Error codes. VMS uses system definitions.
- * Decus C codes are defined in stdio.h.
- * Others are cooked to order.
- */
-
- #if HOST == SYS_VMS
- #include <ssdef.h>
- #include <stsdef.h>
- #define IO_NORMAL (SS$_NORMAL | STS$M_INHIB_MSG)
- #define IO_ERROR SS$_ABORT
- #endif
- /*
- * Note: IO_NORMAL and IO_ERROR are defined in the Decus C stdio.h file
- */
- #ifndef IO_NORMAL
- #define IO_NORMAL 0
- #endif
- #ifndef IO_ERROR
- #define IO_ERROR 1
- #endif
-
- /*
- * Externs
- */
-
- extern int line; /* Current line number */
- extern int wrongline; /* Force #line to cc pass 1 */
- extern char type[]; /* Character classifier */
- extern char token[IDMAX + 1]; /* Current input token */
- extern int instring; /* TRUE if scanning string */
- extern int inmacro; /* TRUE if scanning #define */
- extern int errors; /* Error counter */
- extern int recursion; /* Macro depth counter */
- extern char ifstack[BLK_NEST]; /* #if information */
- #define compiling ifstack[0]
- extern char *ifptr; /* -> current ifstack item */
- extern char *incdir[NINCLUDE]; /* -i directories */
- extern char **incend; /* -> active end of incdir */
- extern int cflag; /* -C option (keep comments) */
- extern int eflag; /* -E option (ignore errors) */
- extern int nflag; /* -N option (no pre-defines) */
- extern int rec_recover; /* unwind recursive macros */
- extern char *preset[]; /* Standard predefined symbols */
- extern char *magic[]; /* Magic predefined symbols */
- extern FILEINFO *infile; /* Current input file */
- extern char work[NWORK + 1]; /* #define scratch */
- extern char *workp; /* Free space in work */
- #if DEBUG
- extern int debug; /* Debug level */
- #endif
- extern int keepcomments; /* Don't remove comments if set */
- extern SIZES size_table[]; /* For #if sizeof sizes */
- extern char *getmem(); /* Get memory or die. */
- extern DEFBUF *lookid(); /* Look for a #define'd thing */
- extern DEFBUF *defendel(); /* Symbol table enter/delete */
- extern char *savestring(); /* Stuff string in malloc mem. */
- extern char *strcpy();
- extern char *strcat();
- extern char *strrchr();
- extern char *strchr();
- extern long time();
- extern char *sprintf(); /* Lint needs this */
- -h- cppdef.h Mon Jan 7 23:59:27 1985 cppdef.h
- /*
- * S y s t e m D e p e n d e n t
- * D e f i n i t i o n s f o r C P P
- *
- * Definitions in this file may be edited to configure CPP for particular
- * host operating systems and target configurations.
- *
- * NOTE: cpp assumes it is compiled by a compiler that supports macros
- * with arguments. If this is not the case (as for Decus C), #define
- * nomacarg -- and provide function equivalents for all macros.
- *
- * cpp also assumes the host and target implement the Ascii character set.
- * If this is not the case, you will have to do some editing here and there.
- */
-
- /*
- * This redundant definition of TRUE and FALSE works around
- * a limitation of Decus C.
- */
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- /*
- * Define the HOST operating system. This is needed so that
- * cpp can use appropriate filename conventions.
- */
- #define SYS_UNKNOWN 0
- #define SYS_UNIX 1
- #define SYS_VMS 2
- #define SYS_RSX 3
- #define SYS_RT11 4
- #define SYS_LATTICE 5
- #define SYS_ONYX 6
- #define SYS_68000 7
-
- #ifndef HOST
- #ifdef unix
- #define HOST SYS_UNIX
- #else
- #ifdef vms
- #define HOST SYS_VMS
- #else
- #ifdef rsx
- #define HOST SYS_RSX
- #else
- #ifdef rt11
- #define HOST SYS_RT11
- #endif
- #endif
- #endif
- #endif
- #endif
-
- #ifndef HOST
- #define HOST SYS_UNKNOWN
- #endif
-
- /*
- * We assume that the target is the same as the host system
- */
- #ifndef TARGET
- #define TARGET HOST
- #endif
-
- /*
- * In order to predefine machine-dependent constants,
- * several strings are defined here:
- *
- * MACHINE defines the target cpu (by name)
- * SYSTEM defines the target operating system
- * COMPILER defines the target compiler
- *
- * The above may be #defined as "" if they are not wanted.
- * They should not be #defined as NULL.
- *
- * LINE_PREFIX defines the # output line prefix, if not "line"
- * This should be defined as "" if cpp is to replace
- * the "standard" C pre-processor.
- *
- * FILE_LOCAL marks functions which are referenced only in the
- * file they reside. Some C compilers allow these
- * to be marked "static" even though they are referenced
- * by "extern" statements elsewhere.
- *
- * OK_DOLLAR Should be set TRUE if $ is a valid alphabetic character
- * in identifiers (default), or zero if $ is invalid.
- * Default is TRUE.
- *
- * OK_CONCAT Should be set TRUE if # may be used to concatenate
- * tokens in macros (per the Ansi Draft Standard) or
- * FALSE for old-style # processing (needed if cpp is
- * to process assembler source code).
- *
- * OK_DATE Predefines the compilation date if set TRUE.
- * Not permitted by the Nov. 12, 1984 Draft Standard.
- *
- * S_CHAR etc. Define the sizeof the basic TARGET machine word types.
- * By default, sizes are set to the values for the HOST
- * computer. If this is inappropriate, see the code in
- * cpp3.c for details on what to change. Also, if you
- * have a machine where sizeof (signed int) differs from
- * sizeof (unsigned int), you will have to edit code and
- * tables in cpp3.c (and extend the -S option definition.)
- *
- * CPP_LIBRARY May be defined if you have a site-specific include directory
- * which is to be searched *before* the operating-system
- * specific directories.
- */
-
- #if TARGET == SYS_LATTICE
- /*
- * We assume the operating system is pcdos for the IBM-PC.
- * We also assume the small model (just like the PDP-11)
- */
- #define MACHINE "i8086"
- #define SYSTEM "pcdos"
- #endif
-
- #if TARGET == SYS_ONYX
- #define MACHINE "z8000"
- #define SYSTEM "unix"
- #endif
-
- #if TARGET == SYS_VMS
- #define MACHINE "vax"
- #define SYSTEM "vms"
- #define COMPILER "vax11c"
- #endif
-
- #if TARGET == SYS_RSX
- #define MACHINE "pdp11"
- #define SYSTEM "rsx"
- #define COMPILER "decus"
- #endif
-
- #if TARGET == SYS_RT11
- #define MACHINE "pdp11"
- #define SYSTEM "rt11"
- #define COMPILER "decus"
- #endif
-
- #if TARGET == SYS_68000
- /*
- * All three machine designators have been seen in various systems.
- * Warning -- compilers differ as to sizeof (int). cpp3 assumes that
- * sizeof (int) == 2
- */
- #define MACHINE "M68000", "m68000", "m68k"
- #define SYSTEM "unix"
- #endif
-
- #if TARGET == SYS_UNIX
- #define SYSTEM "unix"
- #ifdef pdp11
- #define MACHINE "pdp11"
- #endif
- #ifdef vax
- #define MACHINE "vax"
- #endif
- #endif
-
- /*
- * defaults
- */
-
- #ifndef MSG_PREFIX
- #define MSG_PREFIX "cpp: "
- #endif
-
- #ifndef LINE_PREFIX
- #ifdef decus
- #define LINE_PREFIX ""
- #else
- #define LINE_PREFIX "line"
- #endif
- #endif
-
- /*
- * OLD_PREPROCESSOR forces the definition of OK_DOLLAR, OK_CONCAT,
- * COMMENT_INVISIBLE, and STRING_FORMAL to values appropriate for
- * an old-style preprocessor.
- */
-
- #ifndef OLD_PREPROCESSOR
- #define OLD_PREPROCESSOR FALSE
- #endif
-
- #if OLD_PREPROCESSOR
- #define OK_DOLLAR FALSE
- #define OK_CONCAT FALSE
- #define COMMENT_INVISIBLE TRUE
- #define STRING_FORMAL TRUE
- #endif
-
- /*
- * RECURSION_LIMIT may be set to -1 to disable the macro recursion test.
- */
- #ifndef RECURSION_LIMIT
- #define RECURSION_LIMIT 1000
- #endif
-
- /*
- * BITS_CHAR may be defined to set the number of bits per character.
- * it is needed only for multi-byte character constants.
- */
- #ifndef BITS_CHAR
- #define BITS_CHAR 8
- #endif
-
- /*
- * BIG_ENDIAN is set TRUE on machines (such as the IBM 360 series)
- * where 'ab' stores 'a' in the high-bits and 'b' in the low-bits.
- * It is set FALSE on machines (such as the PDP-11 and Vax-11)
- * where 'ab' stores 'a' in the low-bits and 'b' in the high-bits.
- * (Or is it the other way around?) -- Warning: BIG_ENDIAN code is untested.
- */
- #ifndef BIG_ENDIAN
- #define BIG_ENDIAN FALSE
- #endif
-
- /*
- * COMMENT_INVISIBLE may be defined to allow "old-style" comment
- * processing, whereby the comment becomes a zero-length token
- * delimiter. This permitted tokens to be concatenated in macro
- * expansions. This was removed from the Draft Ansi Standard.
- */
- #ifndef COMMENT_INVISIBLE
- #define COMMENT_INVISIBLE FALSE
- #endif
-
- /*
- * STRING_FORMAL may be defined to allow recognition of macro parameters
- * anywhere in replacement strings. This was removed from the Draft Ansi
- * Standard and a limited recognition capability added.
- */
- #ifndef STRING_FORMAL
- #define STRING_FORMAL FALSE
- #endif
-
- /*
- * OK_DOLLAR enables use of $ as a valid "letter" in identifiers.
- * This is a permitted extension to the Ansi Standard and is required
- * for e.g., VMS, RSX-11M, etc. It should be set FALSE if cpp is
- * used to preprocess assembler source on Unix systems. OLD_PREPROCESSOR
- * sets OK_DOLLAR FALSE for that reason.
- */
- #ifndef OK_DOLLAR
- #define OK_DOLLAR TRUE
- #endif
-
- /*
- * OK_CONCAT enables (one possible implementation of) token concatenation.
- * If cpp is used to preprocess Unix assembler source, this should be
- * set FALSE as the concatenation character, #, is used by the assembler.
- */
- #ifndef OK_CONCAT
- #define OK_CONCAT TRUE
- #endif
-
- /*
- * OK_DATE may be enabled to predefine today's date as a string
- * at the start of each compilation. This is apparently not permitted
- * by the Draft Ansi Standard.
- */
- #ifndef OK_DATE
- #define OK_DATE TRUE
- #endif
-
- /*
- * Some common definitions.
- */
-
- #ifndef DEBUG
- #define DEBUG FALSE
- #endif
-
- /*
- * The following definitions are used to allocate memory for
- * work buffers. In general, they should not be modified
- * by implementors.
- *
- * PAR_MAC The maximum number of #define parameters (31 per Standard)
- * Note: we need another one for strings.
- * IDMAX The longest identifier, 31 per Ansi Standard
- * NBUFF Input buffer size
- * NWORK Work buffer size -- the longest macro
- * must fit here after expansion.
- * NEXP The nesting depth of #if expressions
- * NINCLUDE The number of directories that may be specified
- * on a per-system basis, or by the -I option.
- * BLK_NEST The number of nested #if's permitted.
- */
-
- #define IDMAX 31
- #define PAR_MAC (31 + 1)
- #define NBUFF 512
- #define NWORK 512
- #define NEXP 128
- #define NINCLUDE 7
- #define NPARMWORK (NWORK * 2)
- #define BLK_NEST 32
-
- /*
- * Some special constants. These may need to be changed if cpp
- * is ported to a wierd machine.
- *
- * NOTE: if cpp is run on a non-ascii machine, ALERT and VT may
- * need to be changed. They are used to implement the proposed
- * ANSI standard C control characters '\a' and '\v' only.
- * DEL is used to tag macro tokens to prevent #define foo foo
- * from looping. Note that we don't try to prevent more elaborate
- * #define loops from occurring.
- */
-
- #ifndef ALERT
- #define ALERT '\007' /* '\a' is "Bell" */
- #endif
-
- #ifndef VT
- #define VT '\013' /* Vertical Tab CTRL/K */
- #endif
-
-
- #ifndef FILE_LOCAL
- #ifdef decus
- #define FILE_LOCAL static
- #else
- #ifdef vax11c
- #define FILE_LOCAL static
- #else
- #define FILE_LOCAL /* Others are global */
- #endif
- #endif
- #endif
-
-