mirror of
https://github.com/PDP-10/its.git
synced 2026-03-26 02:05:51 +00:00
343 lines
6.7 KiB
C
343 lines
6.7 KiB
C
# 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);
|
|
}
|
|
|