home *** CD-ROM | disk | FTP | other *** search
- /*
- * cc -- unix-like compiler driver for amiga lattice c
- *
- * adapted for lattice version 5.0 and extensively modified
- * by Miles Bader, from the original by Fred Fish (copyright
- * follows).
- */
-
- /************************************************************************
- * *
- * Copyright (c) 1985, Fred Fish *
- * All Rights Reserved *
- * *
- * This software and/or documentation is released into the *
- * public domain for personal, non-commercial use only. *
- * Limited rights to use, modify, and redistribute are hereby *
- * granted for non-commercial purposes, provided that all *
- * copyright notices remain intact and all changes are clearly *
- * documented. The author makes no warranty of any kind with *
- * respect to this product and explicitly disclaims any implied *
- * warranties of merchantability or fitness for any particular *
- * purpose. *
- * *
- ************************************************************************
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <dos.h>
- #include <proto/dos.h>
- #include <ios1.h> /* magic */
-
- #include "common.h"
- #include "list.h"
- #include "dstr.h"
- #include "op.h"
- #include "options.h"
-
- #include "config.h"
-
- static char *locate(char *file,struct list *list); /* find a file */
- static void cleanObjects(int mustExist); /* Remove .o for link and go mode */
- static int makeObjs(); /* Reduce to list of object files */
- static int parseCommandLine(); /* Deal with command line */
- static int compile(struct op *op); /* Translate from .c to .o */
- static int assemble(struct op *op); /* Translate from .s to .o */
- static int link(); /* Gather .o's into executable */
- static int runCmd(struct dstr *cmd);
-
- #ifdef amiga
- #define CHECK_ABORT chkabort()
- #else
- #define CHECK_ABORT /* NULL expansion */
- #endif /* amiga */
-
- DBUG_GLOBALS
-
- /*
- * flags set by command line arguments
- */
- static int debugLevel=DEFAULT_DEBUGLEVEL; /* -g (debugging level) */
-
- struct list *libDirs=NULL;
- struct list *incDirs=NULL;
- struct list *binDirs=NULL;
- struct list *defines=NULL;
- struct list *undefines=NULL;
- struct list *libs=NULL;
-
- struct list *pass1PassThrus=NULL;
- struct list *pass2PassThrus=NULL;
- struct list *optPassThrus=NULL;
- struct list *linkPassThrus=NULL;
-
- struct list *ops=NULL;
-
- static char *outfile=DEFAULT_EXEC; /* output file name from linker */
- static char *tempDir=TEMPDIR; /* where to keep quad files */
- static char *sinkFile=SINKFILE; /* where to put output from passes */
-
- struct dstr *cmdLine=NULL;
-
- static int abortmsg()
- {
- if(options_IsSet(OPT_ECHO))
- fprintf(stderr,"cc: aborting\n");
- return 1; /* abort */
- }
-
- static int cleanup(status)
- int status;
- {
- if(cmdLine!=NULL) dstr_Free(cmdLine);
-
- if(libDirs!=NULL) list_Free(libDirs);
- if(incDirs!=NULL) list_Free(incDirs);
- if(binDirs!=NULL) list_Free(binDirs);
- if(defines!=NULL) list_Free(defines);
- if(undefines!=NULL) list_Free(undefines);
- if(libs!=NULL) list_Free(libs);
-
- if(pass1PassThrus!=NULL) list_Free(pass1PassThrus);
- if(pass2PassThrus!=NULL) list_Free(pass2PassThrus);
- if(optPassThrus!=NULL) list_Free(optPassThrus);
- if(linkPassThrus!=NULL) list_Free(linkPassThrus);
-
- if(ops!=NULL) list_Free(ops);
-
- return status;
- }
-
- static void init()
- {
- int *opt;
-
- options_Init();
- for(opt=defaultOptions; *opt!=0; opt++)
- options_Set(*opt);
-
- cmdLine=dstr_Create(30); /* global command buffer */
-
- libDirs=list_Create((void **)libDirsInit);
- incDirs=list_Create((void **)incDirsInit);
- binDirs=list_Create((void **)binDirsInit);
- defines=list_Create((void **)definesInit);
- undefines=list_Create((void **)undefinesInit);
- libs=list_Create((void **)libsInit);
-
- pass1PassThrus=list_Create(NULL);
- pass2PassThrus=list_Create(NULL);
- optPassThrus=list_Create(NULL);
- linkPassThrus=list_Create(NULL);
-
- ops=list_Create(NULL);
- list_SetFree(ops,op_Free);
- }
-
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- int status;
-
- DBUG_ENTER("main");
-
- onexit(cleanup);
- init();
-
- onbreak(abortmsg);
-
- if(parseCommandLine(argc,argv)==0)
- fatal("no files specified");
-
- cleanObjects(FALSE); /* get rid of existing object files if any */
-
- status=makeObjs();
- if(status==0 && options_IsSet(OPT_LINK)){
- status=link();
- if(list_GetLen(ops)==1)
- cleanObjects(TRUE);
- }
-
- exit(status);
- }
-
- /*
- * The following macro is used to allow optional whitespace between
- * an option and it's argument. Argp is left pointing at the option
- * and argv and argc are adjusted accordingly if necessary.
- *
- * Note that there is no check for missing option arguments. In
- * particular, -o -V will blindly take -V as the output file name.
- *
- */
-
- #define XARG(argc,argv,argp) {if(*++argp=='\0'){argp=(*argv++);argc--;}}
-
- static int parseCommandLine(argc,argv)
- int argc;
- char **argv;
- {
- register char *argp;
-
- DBUG_ENTER("parseCommandLine");
-
- argc--;
- argv++;
- while(argc-- > 0){
- CHECK_ABORT;
-
- argp=*argv++;
-
- if(*argp=='+')
- options_SetByName(argp+1);
- else if(*argp!='-')
- list_Add(ops,(void *)op_Create(argp));
- else
- switch(*++argp){
- case 'c':
- options_Clear(OPT_LINK); /* don't link object modules */
- break;
- case 'p': /* pass thru args to a pass */
- switch(*++argp){
- case '1': /* pass 1 */
- XARG(argc,argv,argp);
- list_Add(pass1PassThrus,argp);
- break;
- case '2': /* pass 2 */
- XARG(argc,argv,argp);
- list_Add(pass2PassThrus,argp);
- break;
- case 'o': /* optimizer */
- XARG(argc,argv,argp);
- list_Add(optPassThrus,argp);
- break;
- case 'l': /* linking */
- XARG(argc,argv,argp);
- list_Add(linkPassThrus,argp);
- break;
- default:
- fatal("unknown pass '%c'; must be one of [12ol]",argp[-1]);
- }
- break;
- case 'D':
- XARG(argc,argv,argp);
- list_Add(defines,(void *)argp);
- break;
- case 'E':
- warning("-E unimplemented, converted to -P instead");
- /* fall through */
- case 'P':
- options_Clear(OPT_COMPILE);
- options_Clear(OPT_ASSEMBLE);
- options_Clear(OPT_LINK);
- break;
- case 'g':
- if(*++argp!='\0') /* optional debuggin level */
- debugLevel=atoi(argp);
- options_Set(OPT_DEBUG);
- break;
- case 'I':
- XARG(argc,argv,argp);
- list_Add(incDirs,(void *)argp);
- break;
- case 'l':
- XARG(argc,argv,argp);
- list_Add(libs,(void *)argp);
- break;
- case 'L':
- XARG(argc,argv,argp);
- list_Add(libDirs,(void *)argp);
- break;
- case 'B':
- XARG(argc,argv,argp);
- list_Add(binDirs,(void *)argp);
- break;
- case 'O':
- options_Set(OPT_OPTIMIZE);
- break;
- case 'o':
- XARG(argc,argv,argp);
- outfile=argp;
- break;
- case 't': /* warning, non-standard */
- XARG(argc,argv,argp);
- tempDir=argp;
- break;
- case 'S':
- warning("-S option not yet implemented, ignored");
- options_Clear(OPT_ASSEMBLE);
- break;
- case 'U':
- XARG(argc,argv,argp);
- list_Add(undefines,(void *)argp);
- break;
- default:
- fatal("unknown option '%c'",*argp);
- break;
- }
- }
-
- DBUG_RETURN(int,list_GetLen(ops));
- }
-
- /*
- * For each operand, do compilation or assembly as necessary, to
- * reduce to an object file in the current directory.
- */
- static int makeObjs()
- {
- int n;
- void **els;
- int numOps=list_GetLen(ops);
- int status=0;
-
- DBUG_ENTER("makeObjs");
-
- for(n=numOps,els=list_GetEls(ops); n>0; n--,els++){
- struct op *op=(struct op *)*els;
-
- CHECK_ABORT;
-
- if(numOps>1 && (op_IsC(op) || op_IsS(op)))
- printf("%s.%s:\n",op->rootname,op->suffix);
-
- if(op_IsC(op))
- status=compile(op);
- else if(op_IsS(op))
- status=assemble(op);
- }
-
- DBUG_RETURN(int,status);
- }
-
- /* handy little routine */
- void addfList(ds,fmt,list)
- struct dstr *ds;
- char *fmt;
- struct list *list;
- {
- int n;
- void **els;
-
- for(n=list_GetLen(list),els=list_GetEls(list); n>0; n--,els++)
- dstr_Addf(ds,fmt,(char *)*els);
- }
-
- /*
- * Note that commands to cc of the form "-l<name>" get interpreted
- * to mean use a library called "name.lib" from the library
- * directory.
- * -lm is specially interpreted to be the appropriate math library.
- */
- static int link()
- {
- int n;
- void **els;
-
- DBUG_ENTER("link");
-
- dstr_Clear(cmdLine);
-
- dstr_Addf(cmdLine,"%s ",locate("blink",binDirs));
-
- if(options_IsSet(OPT_DETACH))
- dstr_Append(cmdLine,locate("cback.o",libDirs));
- else if(options_IsSet(OPT_RESIDENT)){
- if(options_IsSet(OPT_CATCH))
- dstr_Append(cmdLine,locate("catchres.o",libDirs));
- else
- dstr_Append(cmdLine,locate("cres.o",libDirs));
- }else if(options_IsSet(OPT_CATCH))
- dstr_Append(cmdLine,locate("catch.o",libDirs));
- else
- dstr_Append(cmdLine,locate("c.o",libDirs));
-
- for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
- struct op *op=(struct op *)*els;
- char *name=(op_IsO(op) ? op->rootname : op->basename);
-
- dstr_Addf(cmdLine,"+%s.o",name);
- }
-
- if(options_IsSet(OPT_TINYMAIN))
- dstr_Addf(cmdLine," define __main=__tinymain ");
-
- dstr_Addf(cmdLine," library ");
- for(n=list_GetLen(libs),els=list_GetEls(libs); n>0; n--,els++){
- char buffer[50];
- char *lib=(char *)*els;
-
- if(strcmp(lib,"m")==0){
- /* map -lm to appropiate library */
-
- strcpy(buffer,"lib:lcm");
-
- if(options_IsSet(OPT_FFP))
- strcat(buffer,"ffp");
- else if(options_IsSet(OPT_IEEE))
- strcat(buffer,"ieee");
- else if(options_IsSet(OPT_881))
- strcat(buffer,"881");
-
- /*
- * there are only r and s libraries for lcm.lib in the lattice
- * distribution; if there is a way to get the lcmieee, lcmffp,
- * & lcm881 libraries to work with reg-args & short-ints, I
- * couldn't find it.
- */
- if(options_IsSet(OPT_SHORTINTS))
- strcat(buffer,"s");
- if(options_IsSet(OPT_REGARGS))
- strcat(buffer,"r");
-
- strcat(buffer,".lib");
- }else if(strcmp(lib,"lc")==0){
- /* do the standard c library */
-
- strcpy(buffer,"lib:lc");
-
- if(options_IsSet(OPT_SHORTINTS))
- strcat(buffer,"s");
- if(options_IsSet(OPT_REGARGS))
- strcat(buffer,"r");
- if(options_IsSet(OPT_ABSDATA))
- strcat(buffer,"nb");
-
- strcat(buffer,".lib");
-
- if(options_IsSet(OPT_REGARGS)){
- /*
- * Now, do it AGAIN, but without registers, to catch any missing refs.
- * I don't think this is exactly the right thing to do, but there seem
- * to be internal functions missing from the register-fied libraries
- */
-
- strcat(buffer,"+lib:lc");
-
- if(options_IsSet(OPT_SHORTINTS))
- strcat(buffer,"s");
- if(options_IsSet(OPT_ABSDATA))
- strcat(buffer,"nb");
-
- strcat(buffer,".lib");
- }
- }else{
- sprintf(buffer,"%s.lib",lib);
- strcpy(buffer,locate(buffer,libDirs));
- }
-
- if(n==1)
- dstr_Append(cmdLine,buffer);
- else
- dstr_Addf(cmdLine,"%s+",buffer);
- }
-
- if(outfile==NULL)
- /* there better be at least one source file! */
- outfile=((struct op *)list_GetEls(ops))->basename;
-
- dstr_Addf(cmdLine," to %s map nil:",outfile);
-
- addfList(cmdLine," %s",linkPassThrus);
-
- DBUG_RETURN(int,runCmd(cmdLine));
- }
-
- /*
- * compile one operand from a C source program to an object module.
- */
- static int compile(op)
- struct op *op;
- {
- int status=0;
-
- DBUG_ENTER("compile");
-
- if(options_IsSet(OPT_ASSEMBLE)){
- status=pass1(op);
- if(status==0 && options_IsSet(OPT_COMPILE)){
- CHECK_ABORT;
- if(options_IsSet(OPT_OPTIMIZE))
- status=optimize(op);
- if(status==0)
- status=pass2(op);
- }
- }
-
- DBUG_RETURN(int,status);
- }
-
- /*
- * Note that because of brain-damage in the fact that -p to lc1 removes
- * all predefined defs, we must add them so replacing -c with -P in the
- * cc command line will result in the same set of predefined symbols.
- * This is rather ugly and leaves a hole for future problems if we
- * get out of sync with respect to what names the compiler predefines.
- */
- static int pass1(op)
- register struct op *op;
- {
- char tmpFile[MAXPATH];
- int status;
- int n;
- void **els;
-
- DBUG_ENTER("pass1");
-
- dstr_Clear(cmdLine);
-
- dstr_Append(cmdLine,locate((options_IsSet(OPT_BIGLC1) ? "lc1b" : "lc1"),binDirs));
-
- if(options_IsSet(OPT_DEBUG)){
- dstr_Addf(cmdLine," -d%d",debugLevel);
- if(options_IsSet(OPT_OPTIMIZE)){
- warning("-g incompatible with -O, -O turned off");
- options_Clear(OPT_OPTIMIZE);
- }
- }
-
- if(options_IsSet(OPT_FFP))
- dstr_Addf(cmdLine," -ff");
- else if(options_IsSet(OPT_881))
- dstr_Addf(cmdLine," -f8");
- else if(options_IsSet(OPT_IEEE))
- dstr_Addf(cmdLine," -fi");
- else
- dstr_Addf(cmdLine," -fl");
-
- if(options_IsSet(OPT_SHORTINTS))
- dstr_Addf(cmdLine," -w");
- if(options_IsSet(OPT_LONGALIGN))
- dstr_Addf(cmdLine," -l");
-
- if(options_IsSet(OPT_020))
- dstr_Addf(cmdLine," -m2");
- else if(options_IsSet(OPT_030))
- dstr_Addf(cmdLine," -m3");
-
- if(options_IsSet(OPT_CATCH) && !options_IsSet(OPT_ABSDATA)){
- warning("+catch implies +abs-data");
- options_Set(OPT_ABSDATA);
- }
-
- dstr_Addf(cmdLine," -b%d",options_IsSet(OPT_ABSDATA) ? 0 : 1);
- dstr_Addf(cmdLine," -r%d",options_IsSet(OPT_ABSCODE) ? 0 : 1);
-
- if(options_IsSet(OPT_REGARGS))
- dstr_Addf(cmdLine,"r"); /* part of -r switch */
-
- {
- char buf[15], *p=buf;
-
- if(options_IsSet(OPT_ANSI)) *p++='a';
- if(options_IsSet(OPT_CPP)) *p++='+';
- if(options_IsSet(OPT_TRAD)) *p++='l', *p++='o';
- if(options_IsSet(OPT_REGARGS)) *p++='r';
- if(options_IsSet(OPT_PURESTRINGS)) *p++='s';
-
- if(p>buf){
- *p='\0';
- dstr_Addf(cmdLine," -c%s",buf);
- }
- }
-
- if(options_IsSet(OPT_COMPILE)){
- strcpy(tmpFile,tempDir);
- strcat(tmpFile,op->basename);
- strcat(tmpFile,".q");
- dstr_Addf(cmdLine," -o%s",tmpFile);
- }else{
- strcpy(tmpFile,op->basename);
- strcat(tmpFile,".pp");
-
- dstr_Addf(cmdLine," -o%s -p",tmpFile);
- }
-
- for(n=list_GetLen(undefines),els=list_GetEls(undefines); n>0; n--,els++){
- /*************************
- dstr_Addf(cmdLine," -u%s",(char *)*els);
- **************************/
- warning("-U%s ignored! (unimplemented)",(char *)*els);
- }
-
- addfList(cmdLine," -d%s",defines);
- addfList(cmdLine," %s",pass1PassThrus);
-
- for(n=list_GetLen(incDirs),els=list_GetEls(incDirs); n>0; n--,els++){
- char *id=(*els);
- int len=strlen(id);
-
- dstr_Addf(cmdLine," -i%s",*els);
-
- if(len>0 && id[len-1]!=':' && id[len-1]!='/')
- dstr_Addf(cmdLine,"/");
- }
-
- dstr_Addf(cmdLine," %s",op->rootname);
-
- status=runCmd(cmdLine);
- if(status==0 && options_IsSet(OPT_EXEC) && !readable(tmpFile))
- status=1;
-
- DBUG_RETURN(int,status);
- }
-
- /* run the optimizer */
- static int optimize(op)
- struct op *op;
- {
- DBUG_ENTER("optimize");
-
- dstr_Clear(cmdLine);
- dstr_Addf(cmdLine,"%s %s%s",locate("go",binDirs),tempDir,op->basename);
-
- addfList(cmdLine," %s",optPassThrus);
-
- DBUG_RETURN(int,runCmd(cmdLine));
- }
-
- /*
- * Run second pass of compiler on a single operand.
- */
- static int pass2(op)
- struct op *op;
- {
- char objFile[MAXPATH];
- int status;
-
- #ifdef DBUG
- fprintf(stderr,"Entering pass2...\n");
- #endif
-
- DBUG_ENTER("pass2");
-
- dstr_Clear(cmdLine);
-
- dstr_Append(cmdLine,locate("lc2",binDirs));
-
- if(!options_IsSet(OPT_STACKCHECK))
- dstr_Addf(cmdLine," -v");
-
- strcpy(objFile,op->basename);
- strcat(objFile,".o");
-
- dstr_Addf(cmdLine," -o%s",objFile);
-
- dstr_Addf(cmdLine," %s%s",tempDir,op->basename);
-
- addfList(cmdLine," %s",pass2PassThrus);
-
- status=runCmd(cmdLine);
- if(status==0 && options_IsSet(OPT_EXEC) && !readable(objFile))
- status=1;
-
- DBUG_RETURN(int,status);
- }
-
- /*
- * I have not yet had occasion to use the macro assembler,so this
- * part is not yet implemented. If anyone wants to send me the
- * appropriate code, I will be glad to install it.
- */
- static int assemble(op)
- struct op *op;
- {
- DBUG_ENTER("assemble");
- warning("assembly pass not yet implemented");
- DBUG_RETURN(int,1);
- }
-
- static void filteredOutputFrom(source,filter)
- FILE *source;
- char **filter;
- {
- char buf[200];
-
- DBUG_ENTER("FilteredOutputFrom");
-
- while(!feof(source)){
- char **ignore;
-
- fgets(buf,sizeof(buf),source);
-
- for(ignore=filter; *ignore!=NULL; ignore++)
- if(strncmp(*ignore,buf,strlen(*ignore))==0)
- break;
-
- if(*ignore==NULL)
- fputs(buf,stdout);
- }
-
- DBUG_VOID_RETURN;
- }
-
- #ifdef AMIGA
-
- static int execToFile(cmd,sink)
- char *cmd;
- FILE *sink;
- {
- /* this is a dopey version that uses Execute, since I can't get fork to work */
- long fh;
-
- DBUG_ENTER("execToFile");
-
- if(sink==NULL)
- fh=0;
- else
- fh=chkufb(fileno(sink))->ufbfh;
-
- DBUG_RETURN(int,Execute(cmd,0L,fh)!=(-1));
-
- #if 0
- char *argv[50],**argp=argv;
- struct ProcID child;
- static struct FORKENV env={0,0,0,0,0,NULL};
- int i;
-
- DBUG_ENTER("execToFile");
-
- if(cmd==NULL)
- DBUG_RETURN(int,1);
-
- /* this is sort of stupid, cause forkv will just put them back together,
- * but oh well...
- */
- *argp=strtok(cmd," \t");
- while(*argp!=NULL)
- *++argp=strtok(NULL," \t");
-
- if(sink==NULL)
- env.std_out=0;
- else{
- struct UFB *ufb=chkufb(fileno(sink));
- int i;
-
- printf("argv[%d]:",argp-argv);
- for(argp=argv;*argp!=NULL;argp++)
- printf(" %s",*argp);
- putchar('\n');
-
- printf("env: %d, %d, %d, %d, %d, %d\n",
- env.priority, env.stack, env.std_in, env.std_out,
- env.console, env.msgport);
-
- printf("ufb==0x%x, fh==0x%x, go? ",ufb,ufb->ufbfh);
-
- fflush(stdout);
-
- env.std_out=ufb->ufbfh; /* magic to get amigados handle from FILE */
- }
-
- if((i=forkv(argv[0],argv,&env,&child))==-1){
- poserr("forkv");
- DBUG_RETURN(int,1);
- }
-
- printf("Fork returns: %d\n",i);
-
- DBUG_RETURN(int,wait(&child));
- #endif
- }
-
- #endif
-
- static int runCmd(cmd)
- struct dstr *cmd;
- {
- int status;
- char *buf=dstr_GetBuf(cmd);
-
- DBUG_ENTER("RunCommand");
-
- DBUG_3("cmd","execute '%s'",buf);
- if(options_IsSet(OPT_ECHO)){
- puts(buf);
- fflush(stdout);
- }
-
- CHECK_ABORT;
-
- if(options_IsSet(OPT_EXEC)){
- FILE *sink;
-
- if(sinkFile!=NULL && options_IsSet(OPT_FILTER)){
- sink=fopen(sinkFile,"w+");
- if(sink==NULL)
- perror(sinkFile);
- }else
- sink=NULL;
-
- status=execToFile(buf,sink);
- DBUG_3("sys","subcommand returns status %d",status);
-
- if(sink!=NULL){
- rewind(sink);
- filteredOutputFrom(sink,filteredPrefixes);
- fclose(sink);
- unlink(sinkFile);
- }
-
- DBUG_RETURN(int,status);
- }else
- DBUG_RETURN(int,0);
- }
-
- /*
- * Look through the list of paths pointed to by "vec" until we find
- * a file with name given pointed to by "namep". If none is found,
- * the name pointed to by namep is returned.
- */
- static char *locate(name,paths)
- char *name;
- struct list *paths;
- {
- static char namebuf[MAXPATH];
- void **els;
- int n;
-
- DBUG_ENTER("locate");
-
- if(strchr(name,':')!=NULL || *name=='/')
- return name; /* absolute */
-
- for(n=list_GetLen(paths),els=list_GetEls(paths); n>0; n--,els++){
- int len=strlen((char *)*els);
-
- strcpy(namebuf,(char *)*els);
- if(len>0 && namebuf[len-1]!=':' && namebuf[len-1]!='/')
- strcat(namebuf,"/");
- strcat(namebuf,name);
-
- DBUG_3("try","look for '%s'",namebuf);
- if(readable(namebuf)){
- name=namebuf;
- break;
- }
- }
-
- DBUG_RETURN(char *,name);
- }
-
- /*
- * Check to see if the file exists and is readable.
- */
- static int readable(name)
- char *name;
- {
- register int status=0;
- register long fildes;
-
- DBUG_ENTER("readable");
-
- #ifdef unix
- fildes=open(name,O_RDONLY);
- if(fildes >= 0){
- (void) close(fildes);
- status=1;
- }
- #else
- fildes=Lock(name,ACCESS_READ);
- if(fildes != 0){
- UnLock(fildes);
- status=1;
- }
- #endif
-
- DBUG_RETURN(int,status);
- }
-
- /*
- * If an executable is made from a single C file, the normal behavior
- * for the unix environment is to treat the .o file as an intermediate
- * file and remove it, so we follow suit.
- */
- static void cleanObjects(mustExist)
- int mustExist;
- {
- int n;
- void **els;
-
- DBUG_ENTER("cleanObjects");
-
- for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
- char buf[MAXPATH];
- struct op *op=(struct op *)*els;
-
- if(!op_IsO(op)){
- strcpy(buf,op->basename);
- strcat(buf,".o");
- if(unlink(buf)!=0 && mustExist)
- warning("can't delete '%s'",buf);
- }
- }
-
- DBUG_VOID_RETURN;
- }
-