home *** CD-ROM | disk | FTP | other *** search
- /****************************************************/
- /* */
- /* Copyright (c) 1993 SAS Institute, Inc. */
- /* */
- /* Support: walker */
- /* Script: mkmkam */
- /* Date: 07/12/93 */
- /* */
- /****************************************************/
- #include "MKMK.h"
- #include "time.h"
-
- #define MAXLINELEN 77 // Maximum line size (not counting backslash)
-
- static const char verstring[] = "$VER: MKMK " TOOLVER TOOLDATE;
-
- /* File types */
- #define FT_UNK -1 // Unknown
- #define FT_C 0 // C source file
- #define FT_CXX 1 // C++ source file
- #define FT_ASM 2 // Assembler source file
- #define FT_H 3 // Header file
-
- static const struct SUFFIXES
- {
- char suffix[5];
- char val;
- } suffixes[] =
- {
- {".a", FT_ASM},
- {".asm", FT_ASM},
- {".c", FT_C},
- {".cc", FT_CXX},
- {".cpp", FT_CXX},
- {".cxx", FT_CXX},
- {".h", FT_H},
- {".s", FT_ASM},
- };
- #define NUMSUFFIXES (sizeof(suffixes)/sizeof(struct SUFFIXES))
-
- /* return the file type (as defined above) for a given source file */
- int filetype(char *name)
- {
- int i, j;
- name = suffix(name);
-
- for(i=0; i<NUMSUFFIXES; i++)
- {
- j = stricmp(name, (char *)suffixes[i].suffix);
- if(j == 0) return suffixes[i].val;
- }
- return FT_UNK;
- }
-
- /* Return the suffix (portion after the '.') for a source file */
- /* Note that no memory is allocated, the return pointer points */
- /* =into= the argument string. */
- char *suffix(char *s)
- {
- char *p;
- for(p=s+strlen(s); p>s && *p != '.'; p--);
- return p;
- }
-
- /* Return the prefix (portion before the '.') for a source file. */
- /* This function DOES allocate memory to copy the prefix into. */
- char *prefix(char *s)
- {
- char c;
- char *p = suffix(s);
- if(p != s)
- {
- c = *p;
- *p = 0;
- s = scopy(s);
- *p = c;
- return s;
- }
- else
- return scopy("");
- }
-
- /* Take a filename as input, and return the object filename */
- /* that would correspond to it. I.E. take "foo.c" as input */
- /* and put "foo.o" out. Note that this functions DOES */
- /* allocate a new copy of the string. */
- char *objout(char *s)
- {
- char *p;
- char *t;
- long l;
- p = suffix(s);
- if(*p != '.') return NULL;
- t = malloc((unsigned long)p-(unsigned long)s+3);
- if(!t) panic("No Memory!");
- l = (unsigned long)p - (unsigned long)s;
- memcpy(t,s,l);
- strcpy(t+l, ".o");
- return t;
- }
-
- /* Expand file dependancies */
- /* We copy the dependancies of all our children into ourself. */
- /* If the dependancy is already there, nothing will be added. */
- /* Otherwise, it gets added onto the end and fd->ndirect gets */
- /* bumped. When we get there, that dependancy will also be */
- /* expanded. The result is that all dependancies, no matter */
- /* how far removed, end up on the list for fd. */
-
- void ExpandDeps(struct FileDesc *fd)
- {
- int i, j;
- for(i=0; i<fd->ndirect; i++)
- {
- for(j=0; j<fd->Direct[i]->ndirect; j++)
- {
- AddDep(fd, fd->Direct[i]->Direct[j]);
- }
- }
- }
-
- #define HEADER_COMMENT \
- "#\n" \
- "# Makefile automatically generated by MKMK V" TOOLVER "\n" \
- "# %s" \
- "#\n\n"
-
- char header_comment[sizeof(HEADER_COMMENT)+26];
-
- /* All data has been accumulated; generate the smakefile */
- void GenSmake(FileList *fl)
- {
- BPTR fp;
- struct FileDesc *fd;
- char *p;
- int i, j, ft;
- int tmplen, curlen, indent;
- char filename[100];
- long t;
- time(&t);
-
- chkabort();
-
- strcpy(filename, makefile);
-
- if(!force)
- {
- for(i=0; i<100; i++)
- {
- fp = Lock(filename, SHARED_LOCK);
- UnLock(fp);
- if(!fp) break;
- mysprintf(filename, "%s.%02.2ld", makefile, i);
- }
- if(fp)
- panic("Can't determine name for output file!\n");
- }
-
- if(!(fp = Open(filename, MODE_NEWFILE)))
- {
- myfprintf(out, "Can't open output file \"%s\"!\n", filename);
- panic(NULL);
- }
-
- myfprintf(out, "Writing file \"%s\"...", filename);
-
- myfprintf(fp, HEADER_COMMENT, asctime(localtime(&t)));
-
- myfprintf(fp, "OBJS=");
- curlen = indent = 5;
-
- // Put out the list of object files
- for(fd=fl->head; fd; fd=fd->next)
- {
- ft = filetype(fd->name);
- if(ft == FT_C || ft == FT_CXX || ft == FT_ASM)
- {
- if(p = objout(fd->name))
- {
- tmplen = strlen(p) + 1;
- if(curlen + tmplen > MAXLINELEN)
- {
- // Over MAXLINELEN bytes, continue on the next line
- myfprintf(fp, " \\\n");
- for(j=0; j<indent; j++) FPutC(fp, ' ');
- curlen = indent + tmplen;
- }
- else
- curlen += tmplen;
- myfprintf(fp, " %s", p);
-
- /* The first file named will name the project */
- if(target == NULL) target = prefix(p);
-
- free(p);
- }
- }
- else if(ft == FT_UNK)
- {
- /* It's not a file that produces an object file. */
- /* we don't really know what it is, but add it */
- /* to the dependancy list anyway. It might be */
- /* a library or .o file, for example. */
- myfprintf(fp, " %s", fd->name);
- }
- }
-
- if(!target) target = "Project";
-
- /* Put out the linker command */
- myfprintf(fp, "\n\n%s: $(OBJS)\n sc link to %s with <<\n$(OBJS)\n<\n\n",
- target, target);
-
- /* Put out the individual file dependancy lists */
- for(fd=fl->head; fd; fd=fd->next)
- {
- ft = filetype(fd->name);
- if(ft == FT_C || ft == FT_CXX || ft == FT_ASM)
- {
- if(!(p = objout(fd->name))) break;
-
- myfprintf(fp, "%s: %s", p, fd->name);
- indent = strlen(p) + 1;
- curlen = indent + strlen(fd->name) + 1;
- free(p);
-
- /* Expand the dependancies of the current file. This will */
- /* copy all second, third, .... nth level dependancies into */
- /* the current file descriptor. */
- ExpandDeps(fd);
-
- for(i=0; i<fd->ndirect; i++)
- {
- tmplen = strlen(fd->Direct[i]->name) + 1;
- if(curlen + tmplen > MAXLINELEN)
- {
- /* Over MAXLINELEN bytes, continue on a new line */
- myfprintf(fp, " \\\n");
- for(j=0; j<indent; j++) FPutC(fp, ' ');
- curlen = indent + tmplen;
- }
- else
- curlen += tmplen;
- myfprintf(fp, " %s", fd->Direct[i]->name);
- }
- myfprintf(fp, "\n");
- }
- myfprintf(fp, "\n");
- }
-
- Close(fp);
-
- myfprintf(out, "Done\n");
-
- makeicon(filename);
- }
-
- #define DEFROOT "sc:icons/def_"
-
- //Copy the correct .info file for a given filename
- void makeicon(char *name)
- {
- int i, len;
- char *xname;
- struct Library *IconBase;
- char data[300];
- struct DiskObject *dobj;
-
- if(!(IconBase = OpenLibrary("icon.library",0)))
- return;
-
- len = strlen(name);
- if(len > sizeof(data)-1) return;
- memcpy(data, name, len+1);
-
- if(iconexists(data)) goto doexit;
-
- for(i=len-1; i>=0; i--)
- if(name[i] == '.' || name[i] == '/' || name[i] == ':')
- break;
-
- /* If no '.', i is -1, which means use the whole name */
-
- xname = name + (i+1);
-
- // xname now points to the extension
- if(!stricmp(xname, "info"))
- goto doexit; // Don't do icons for .info files!
-
- strcpy(data, DEFROOT);
- strcpy(data + strlen(DEFROOT), xname);
-
- if(!iconexists(data))
- strcpy(data, "sc:icons/def_smakefile");
-
- if(!(dobj = GetDiskObject(data))) goto doexit; // hmm... bad icon?
- PutDiskObject(name, dobj);
- FreeDiskObject(dobj);
- doexit:
- CloseLibrary(IconBase);
- return;
- }
-
- // Determine if an icon already exists for the name
- int iconexists(char *name)
- {
- BPTR lock;
- char fullname[256];
- int len;
-
- len = strlen(name);
- if(len>sizeof(fullname)-6) return(-1);
- memcpy(fullname, name, len);
- memcpy(fullname+len, ".info", 6);
-
- if(lock=Lock(fullname, SHARED_LOCK)) UnLock(lock);
-
- return(lock != NULL);
- }
-