home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
icon
/
dos
/
src
/
icont
/
tmain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-10
|
13KB
|
520 lines
/*
* tmain.c - main program for translator and linker.
*/
#include "../h/gsupport.h"
#include "tproto.h"
/*
* Prototypes.
*/
hidden novalue execute Params((char *ofile,char *efile,char * *args));
hidden novalue report Params((char *s));
hidden novalue rmfiles Params((char **p));
hidden novalue usage Params((noargs));
/*
* The following code is operating-system dependent [@tmain.01]. Include
* files and such.
*/
#if PORT
Deliberate syntax error
#endif /* PORT */
#if AMIGA
#include <libraries/dosextens.h>
#endif /* AMIGA */
#if ARM || MSDOS || MVS || UNIX || VM || VMS
/* nothing is needed */
#endif /* ARM || ... */
#if ATARI_ST
char *patharg;
#endif /* ATARI_ST */
#if MACINTOSH
#if MPW
#include <fcntl.h> /* MPW3 - for unlink() */
#include <CursorCtl.h>
void SortOptions();
#endif /* MPW */
#endif /* MACINTOSH */
#if OS2
#include <process.h>
#endif /* OS2 */
/*
* End of operating-system specific code.
*/
#if IntBits == 16
#ifdef strlen
#undef strlen /* pre-defined in some contexts */
#endif /* strlen */
#endif /* Intbits == 16 */
/*
* Define global variables.
*/
#define Global
#define Init(v) = v
#include "globals.h"
char *ofile = NULL; /* linker output file name */
char patchpath[MaxPath+18] = "%PatchStringHere->";
char *refpath = RefPath;
char *iconxloc;
/*
* getopt() variables
*/
extern int optindex; /* index into parent argv vector */
extern int optopt; /* character checked for validity */
extern char *optarg; /* argument associated with option */
/*
* main program
*/
novalue main(argc,argv)
int argc;
char **argv;
{
int nolink = 0; /* suppress linking? */
int errors = 0; /* translator and linker errors */
char **tfiles, **tptr; /* list of files to translate */
char **lfiles, **lptr; /* list of files to link */
char **rfiles, **rptr; /* list of files to remove */
char *efile = NULL; /* stderr file */
char buf[MaxFileName]; /* file name construction buffer */
int c, n;
struct fileparts *fp;
#if AMIGA
#if AZTEC_C
struct Process *FindTask();
struct Process *Process = FindTask(0L);
ULONG stacksize = *((ULONG *)Process->pr_ReturnAddr);
if (stacksize < ICONTMINSTACK) {
fprintf(stderr,"Icont needs \"stack %d\" to run\n",ICONTMINSTACK);
exit(-1);
}
#endif /* AZTEC_C */
#endif /* AMIGA */
#if MACINTOSH
#if MPW
InitCursorCtl(NULL);
SortOptions(argv);
#endif /* MPW */
#endif /* MACINTOSH */
iconxloc = (char *)alloc((unsigned)strlen(refpath) + 6);
strcpy(iconxloc, refpath);
strcat(iconxloc, "iconx");
if (strlen(patchpath)>18)
iconxloc = patchpath+18;
/*
* Process options.
*/
while ((c = getopt(argc,argv,Options)) != EOF)
switch (c) {
case 'C': /* Ignore: compiler only */
break;
case 'L': /* -L: enable linker debugging */
#ifdef DeBugLinker
Dflag = 1;
#endif /* DeBugLinker */
break;
case 'S': /* -Sxnnnn: set a size */
sizearg(optarg,argv);
break;
case 'c': /* -c: compile only (no linking) */
nolink = 1;
break;
case 'e': /* -e file: redirect stderr */
efile = optarg;
break;
case 'f': /* Ignore: compiler only */
break;
case 'm': /* -m: preprocess using m4(1) [UNIX] */
m4pre = 1;
break;
case 'n': /* Ignore: compiler only */
break;
case 'o': /* -o file: name output file */
ofile = optarg;
break;
case 'p': /* -p path: iconx path [ATARI] */
#if ATARI_ST
patharg = optarg;
#endif /* ATARI_ST */
break;
case 'r': /* Ignore: compiler only */
break;
case 's': /* -s: suppress informative messages */
silent = 1;
break;
case 't': /* -t: turn on procedure tracing */
trace = -1;
break;
case 'u': /* -u: warn about undeclared ids */
uwarn = 1;
break;
case 'v': /* Ignore: compiler only */
break;
default:
case 'x': /* -x illegal until after file list */
usage();
}
/*
* Allocate space for lists of file names.
*/
n = argc - optindex + 1;
tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
/*
* Scan file name arguments.
*/
while (optindex < argc) {
if (strcmp(argv[optindex],"-x") == 0) /* stop at -x */
break;
else if (strcmp(argv[optindex],"-") == 0) {
#if ARM
/* Different file naming, so we need a different strategy... */
*tptr++ = "-";
/* Use makename(), pretending we had an input file named "Stdin" */
makename(buf,TargetDir,"Stdin",U1Suffix);
*lptr++ = *rptr++ = salloc(buf); /* link & remove .u1 */
makename(buf,TargetDir,"Stdin",U2Suffix);
*rptr++ = salloc(buf); /* also remove .u2 */
#else /* ARM */
*tptr++ = "-"; /* "-" means standard input */
*lptr++ = *rptr++ = "stdin.u1";
*rptr++ = "stdin.u2";
#endif /* ARM */
}
else {
fp = fparse(argv[optindex]); /* parse file name */
if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
makename(buf,SourceDir,argv[optindex], SourceSuffix);
*tptr++ = salloc(buf); /* translate the .icn file */
makename(buf,TargetDir,argv[optindex],U1Suffix);
*lptr++ = *rptr++ = salloc(buf); /* link & remove .u1 */
makename(buf,TargetDir,argv[optindex],U2Suffix);
*rptr++ = salloc(buf); /* also remove .u2 */
}
else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
|| smatch(fp->ext,USuffix)) {
makename(buf,TargetDir,argv[optindex],U1Suffix);
*lptr++ = salloc(buf);
}
else
quitf("bad argument %s",argv[optindex]);
}
optindex++;
}
*tptr = *lptr = *rptr = NULL; /* terminate filename lists */
if (lptr == lfiles)
usage(); /* error -- no files named */
/*
* Round hash table sizes to next power of two, and set masks for hashing.
*/
chsize = round2(chsize); cmask = chsize - 1;
fhsize = round2(fhsize); fmask = fhsize - 1;
ghsize = round2(ghsize); gmask = ghsize - 1;
ihsize = round2(ihsize); imask = ihsize - 1;
lhsize = round2(lhsize); lmask = lhsize - 1;
/*
* Translate .icn files to make .u1 and .u2 files.
*/
if (tptr > tfiles) {
if (!silent)
report("Translating");
errors = trans(tfiles);
if (errors > 0) /* exit if errors seen */
exit(ErrorExit);
}
/*
* Link .u1 and .u2 files to make an executable.
*/
if (nolink) { /* exit if no linking wanted */
#if MACINTOSH
#if MPW
/*
* Set type of translator output ucode (.u) files
* to 'TEXT', so they can be easily viewed by editors.
*/
{
char **p;
void setfile();
for (p = rfiles; *p; ++p)
setfile(*p,'TEXT','icon');
}
#endif /* MPW */
#endif /* MACINTOSH */
exit(NormalExit);
}
if (ofile == NULL) { /* if no -o file, synthesize a name */
ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
} else { /* add extension in necessary */
fp = fparse(ofile);
if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
ofile = salloc(makename(buf,NULL,ofile,IcodeSuffix));
}
if (!silent)
report("Linking");
errors = ilink(lfiles,ofile); /* link .u files to make icode file */
/*
* Finish by removing intermediate files.
* Execute the linked program if so requested and if there were no errors.
*/
#if MACINTOSH
#if MPW
/* Set file type to TEXT so it will be executable as a script. */
setfile(ofile,'TEXT','icon');
#endif /* MPW */
#endif /* MACINTOSH */
rmfiles(rfiles); /* remove intermediate files */
if (errors > 0) { /* exit if linker errors seen */
unlink(ofile);
exit(ErrorExit);
}
#if !(MACINTOSH && MPW)
if (optindex < argc) {
if (!silent)
report("Executing");
execute (ofile, efile, argv+optindex+1);
}
#endif /* !(MACINTOSH && MPW) */
exit(NormalExit);
}
/*
* execute - execute iconx to run the icon program
*/
static novalue execute(ofile,efile,args)
char *ofile, *efile, **args;
{
#if !(MACINTOSH && MPW)
int n;
char **argv, **p;
for (n = 0; args[n] != NULL; n++) /* count arguments */
;
p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
*p++ = iconxloc; /* set iconx pathname */
if (efile != NULL) { /* if -e given, copy it */
*p++ = "-e";
*p++ = efile;
}
*p++ = ofile; /* pass icode file name */
#if AMIGA && LATTICE
*p = *args;
while (*p++) {
*p = *args;
args++;
}
#else /* AMIGA && LATTICE */
while (*p++ = *args++) /* copy args into argument vector */
;
#endif /* AMIGA && LATTICE */
*p = NULL;
/*
* The following code is operating-system dependent [@tmain.02]. It calls
* iconx on the way out.
*/
#if PORT
/* something is needed */
Deliberate Syntax Error
#endif /* PORT */
#if AMIGA
#if AZTEC_C
execvp(iconxloc,argv);
return;
#endif /* AZTEC_C */
#if LATTICE
{
struct ProcID procid;
if (forkv(iconxloc,argv,NULL,&procid) == 0) {
wait(&procid);
return;
}
}
#endif /* LATTICE */
#endif /* AMIGA */
#if ARM
{
int i = 7 + strlen(iconxloc);
int j;
char *s;
char buffer[255];
extern int armquote(char *, char **);
sprintf(buffer, "Chain:%s ", iconxloc);
for (p = argv + 1; *p; ++p)
{
j = armquote(*p, &s);
if (j == -1 || i + j >= 255)
{
fprintf(stderr, "Cannot execute: command line too long");
fflush(stderr);
return;
}
strcpy(buffer + i, s);
i += j;
buffer[i] = ' ';
}
buffer[i] = '\0';
system(buffer);
}
#endif /* ARM */
#if ATARI_ST || MACINTOSH
fprintf(stderr,"-x not supported\n");
fflush(stderr);
#endif /* ATARI_ST || ... */
#if MSDOS
#if LATTICE || MICROSOFT || TURBO
execvp(iconxloc,argv); /* execute with path search */
#endif /* LATTICE || MICROSOFT || TURBO */
#if MWC || INTEL_386 || ZTC_386 || HIGHC_386
fprintf(stderr,"-x not supported\n");
fflush(stderr);
#endif /* MWC || INTEL_386 || ... */
#endif /* MSDOS */
#if MVS || VM
#if SASC
exit(sysexec(iconxloc, argv));
#endif /* SASC */
fprintf(stderr,"-x not supported\n");
fflush(stderr);
#endif /* MVS || VM */
#if OS2
execvp(iconxloc,argv); /* execute with path search */
#endif /* OS2 */
#if UNIX
/*
* If an ICONX environment variable is defined, use that.
* If not, first try the predefined path, then search $PATH via execvp.
*/
if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
execv(argv[0], argv); /* exec file specified by $ICONX */
quitf("cannot execute $ICONX (%s)", argv[0]);
}
#ifdef HardWiredPaths
#ifdef CRAY
argv[0] = "iconx";
execv(iconxloc, argv);
#else /* CRAY */
argv[0] = iconxloc; /* try predefined file */
execv(argv[0], argv);
#endif /* CRAY */
#endif /* HardWiredPaths */
argv[0] = "iconx";
execvp(argv[0], argv); /* if no iconxloc, search path for "iconx" */
#ifdef HardWiredPaths
quitf("cannot run %s", iconxloc);
#else /* HardWiredPaths */
quitf("cannot find iconx", "");
#endif /* HardWiredPaths */
#endif /* UNIX */
#if VMS
execv(iconxloc,argv);
#endif /* VMS */
/*
* End of operating-system specific code.
*/
quitf("could not run %s",iconxloc);
#else /* !(MACINTOSH && MPW) */
printf("-x not supported\n");
#endif /* !(MACINZTOSH && MPW) */
}
static novalue report(s)
char *s;
{
fprintf(stderr,"%s:\n",s);
}
/*
* rmfiles - remove a list of files
*/
static novalue rmfiles(p)
char **p;
{
for (; *p; p++) {
unlink(*p);
}
}
/*
* Print an error message if called incorrectly. The message depends
* on the legal options for this system.
*/
static novalue usage()
{
fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, TUsage);
exit(ErrorExit);
}