1
0
mirror of https://github.com/PDP-10/PCC20.git synced 2026-01-13 15:17:51 +00:00
2018-10-25 11:25:56 +02:00

343 lines
6.7 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# include "cc.h"
/*
C Compiler
Test C Compiler Command Routine (for CMAC Versions)
Command format:
cc {option ...} name1.c name2.c ...
Options:
d=xxx set compiler debugging argument to xxx
k= keep intermediate files around
s= produce listing of symbol table
Meaningful debugging arguments:
a debug code generator
d debug parser
e debug parser error recovery
m debug macro expander
*/
/* renamings to allow long names */
# define construct_output_file_names cnsofn
# define execute_phase execph
# define process_options proopt
# define process_equal_option proeq
# define p_argc phsac
# define p_argv phsav
# define argv_L avl
# define argv_LP avlp
# define argv_P avp
# define argv_C avc
# define argv_M avm
# define argv_E ave
# define argv_S avs
/* intermediate file names */
# define fncs "0.cstore"
# define fner "0.error"
# define fnhm "0.hmac"
# define fnma "0.mac"
# define fnno "0.node"
# define fnst "0.string"
# define fnsy "0.symtab"
# define fnto "0.token"
# define fnty "0.typtab"
/* options */
char debug[40];
int kflag, sflag;
/* phase information */
# define nphase 7
# define p_L 0
# define p_LP 1
# define p_P 2
# define p_C 3
# define p_M 4
# define p_E 5
# define p_S 6
char *p_name[] {"L", "LP", "P", "C", "M", "E", "S"};
char *p_prog[] {"/dsk/c/_l-cm.tbin",
"/dsk/c/_lp-cm.tbin",
"/dsk/c/_p-cm.tbin",
"/dsk/c/_c-cm.tbin",
"/dsk/c/_m-cm.tbin",
"/dsk/c/_e-cm.tbin",
"/dsk/c/_s-cm.tbin"};
char *argv_L[] {debug, 0, fnto, fncs, fner, fnst};
char *argv_LP[] {debug, 0, fnno, fnty, fner, fnma, fncs, fnst, fnhm, fnsy};
char *argv_P[] {debug, fnto, fnno, fnty, fner, fnma, fnhm, fnsy};
char *argv_C[] {debug, fner, fnno, fnty, fnma};
char *argv_M[] {debug, 0, fncs, fner, fnma, fnst, fnhm};
char *argv_E[] {debug, fner, fncs};
char *argv_S[] {fncs, fnty, fnsy, 0};
char *p_argc[] {6, 10, 8, 5, 7, 3, 4};
char **p_argv[] {argv_L, argv_LP, argv_P, argv_C, argv_M,
argv_E, argv_S};
# define file_name_size 30
/**********************************************************************
DESCRIPTION OF EXTERNAL-DEFINED ROUTINES USED
part of C compiler:
perror - error message processor (if CALL_ERROR config)
cprint - formatted output (c96.c)
standard C library:
copen - open file for input/output
cclose - close file
reasonably machine-independent:
execv - execute program passing vector of args
(status returned through exccode)
delete - delete file
apfname - append new suffix to file name
*/
/**********************************************************************
THE MAIN PROGRAM
**********************************************************************/
char *sconcat();
main (argc, argv) int argc; char *argv[];
{int snum, cc, f;
char *source;
char obj_name[file_name_size], sym_name[file_name_size];
--argc;
++argv;
argc = process_options (argc, argv);
for (snum = 0; snum < argc; ++snum)
{source = argv[snum];
/* check that source file exists */
if ((f = copen (source, MREAD, TEXT)) == OPENLOSS)
{cprint ("Can't Find '%s'.\n", source);
continue;
}
cclose (f);
cprint ("%s:\n", source);
/* fix debug arg */
if (sflag) sconcat (debug, 2, debug, "s");
/* construct output file names from source file name */
construct_output_file_names (source, obj_name, sym_name);
/* create empty ERROR file for phases to append to */
cclose (copen (fner, MWRITE, BINARY));
/* set the variable phase arguments */
argv_L[1] = source;
argv_LP[1] = source;
argv_M[1] = obj_name;
argv_S[3] = sym_name;
/* now execute the phases */
# ifdef MERGE_LP
cc = execute_phase (p_LP);
# endif
# ifndef MERGE_LP
cc = execute_phase (p_L);
if (!cc) cc = execute_phase (p_P);
# endif
if (!cc) cc = execute_phase (p_C);
if (!cc) cc = execute_phase (p_M);
# ifdef CALL_ERROR
perror (fner, fncs);
# endif
# ifndef CALL_ERROR
execute_phase (p_E);
# endif
if (sflag) execute_phase (p_S);
if (!kflag)
{delete (fnto);
delete (fncs);
delete (fner);
delete (fnno);
delete (fnsy);
delete (fnma);
delete (fnhm);
delete (fnst);
delete (fnty);
}
}
}
/**********************************************************************
PROCESS_OPTIONS - Process options in command arguments
and remove options from argument list.
**********************************************************************/
int process_options (argc, argv)
char *argv[];
{char *s, **ss, **dd;
int n, opt;
kflag = sflag = FALSE;
dd = ss = argv;
n = 0;
while (--argc >= 0)
{s = *ss++;
if ((opt = s[0]) && s[1] == '=')
process_equal_option (opt, s+2);
else
{*dd++ = s;
++n;
}
}
return (n);
}
/**********************************************************************
PROCESS_EQUAL_OPTION
**********************************************************************/
process_equal_option (opt, s)
char *s;
{char *r;
int c;
switch (opt = lower (opt)) {
case 'd': r = debug;
while (c = *s++) *r++ = lower (c);
*r = 0;
return;
case 'k': kflag = TRUE; return;
case 's': sflag = TRUE; return;
default: cprint ("Unrecognized option: %c=%s\n", opt, s);
}
}
/**********************************************************************
CONSTRUCT_OUTPUT_FILE_NAME
Construct output file names from source file name.
**********************************************************************/
construct_output_file_names (source, obj_name, sym_name)
char *source, *obj_name, *sym_name;
{apfname (obj_name, source, "MIDAS");
apfname (sym_name, source, "SYMTAB");
}
/**********************************************************************
EXECUTE PHASE
**********************************************************************/
int execute_phase (n) int n;
{extern int exccode; /* set by execv to phase return code */
int c;
char *s;
if (execv (p_prog[n], p_argc[n], p_argv[n]))
{cprint ("Unable to execute phase %s\n", p_name[n]);
return (-1);
}
s = p_name[n];
while (c = *s++) cprint ("%c\n", c);
return (exccode);
}
/**********************************************************************
LOWER - Convert Character To Lower Case
**********************************************************************/
int lower (c)
{if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A');
return (c);
}
/**********************************************************************
SCONCAT - String Concatenate
concatenate strings S1 ... Sn into buffer B
return B
**********************************************************************/
char *sconcat (b, n, s1, s2, s3, s4, s5, s6, s7, s8)
char *b, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;
{char **s, *p, *q;
int c;
q = b;
s = &s1;
while (--n >= 0)
{p = *s++;
while (c = *p++) *q++ = c;
}
*q = 0;
return (b);
}