home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / SASC6571.LZX / extras / mkmk / mkmk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-24  |  5.4 KB  |  202 lines

  1. /****************************************************/
  2. /*                                                  */
  3. /* Copyright (c) 1993 SAS Institute, Inc.           */
  4. /*                                                  */
  5. /* Support: walker                                  */
  6. /* Script:  splatam                                 */
  7. /* Date:    07/12/93                                */
  8. /*                                                  */
  9. /****************************************************/
  10.  
  11. #include "MKMK.h"
  12.  
  13. #define TEMPLATE "TARGET/K,FORCE/S,MAKEFILE/K,PATTERN/M"
  14.  
  15. #define OPT_TARGET   0
  16. #define OPT_FORCE    1
  17. #define OPT_MAKEFILE 2
  18. #define OPT_PATTERN  3
  19.  
  20. #define OPT_COUNT    4
  21.  
  22. BPTR out;         // Location for output messages to go to
  23. char *makefile;   // Name of makefile to generate
  24. char *target;     // Name of program generated by the makefile
  25. int force;        // Overwrite existing makefile?
  26.  
  27. // This routine is called when we have an emergency exit for some reason
  28. // It simply prints a message and terminates the program
  29. void panic(char *msg)
  30. {
  31.    if(msg && out)
  32.    {
  33.       Write(out, msg, strlen(msg));
  34.       Write(out, "\n", 1);
  35.    }
  36.    if(out && Output() == NULL) Close(out);
  37.    out = NULL;
  38.    __exit(20);
  39. }
  40.  
  41. // This routine is called after parsing the arguments.  If optional parameters
  42. // were omitted, it fills them in with default values.
  43. static void GetDefaultArgs(long *opts)
  44. {
  45.    static const char *statargv[] = 
  46.    {"#?.c", "#?.cxx", "#?.cpp", "#?.cc", "#?.a", NULL};
  47.    makefile = (opts[OPT_MAKEFILE] ? (char *)opts[OPT_MAKEFILE] : "smakefile");
  48.    target   = (char *)opts[OPT_TARGET];
  49.    force    = opts[OPT_FORCE];
  50.    if(opts[OPT_PATTERN] == NULL)
  51.       opts[OPT_PATTERN]  = (long)statargv;
  52. }
  53.  
  54. // Add all files matching the pattern "pattern" to the FileList "fl"
  55. void AddPattern(FileList *fl, char *pattern)
  56. {
  57.    struct FileInfoBlock __aligned fib;
  58.  
  59.    if(dfind(&fib, pattern, 0)) return;
  60.  
  61.    do
  62.    {
  63.       AddFile(fl, scopy(fib.fib_FileName));
  64.    }
  65.    while(!dnext(&fib));
  66. }
  67.  
  68. // Find a file in a FileList
  69. struct FileDesc *FindFile(FileList *fl, char *file)
  70. {
  71.    struct FileDesc *fd;
  72.    for(fd=fl->head; fd && stricmp(file, fd->name); fd=fd->next);
  73.    return fd;
  74. }
  75.  
  76. // Add a single file (not a pattern) to a FileList
  77. struct FileDesc *AddFile(FileList *fl, char *file)
  78. {
  79.    struct FileDesc *fd;
  80.  
  81.    // Check to make sure it's not already on the list
  82.    if(fd = FindFile(fl, file)) return fd;
  83.  
  84.    if(!(fd = malloc(sizeof(*fd)))) panic("No memory!\n");
  85.  
  86.    memset(fd, 0, sizeof(*fd));
  87.  
  88.    // Link the new FileDesc structure into the FileList
  89.    fd->prev = fl->tail;
  90.    if(fl->tail) fl->tail->next = fd;
  91.    else         fl->head = fd;
  92.    fl->tail = fd;
  93.  
  94.    fd->name = file;
  95.  
  96.    return fd;
  97. }
  98.  
  99. // Return the descriptor for the next file in the FileList
  100. struct FileDesc *NextFile(FileList *fl)
  101. {
  102.    if(fl->cur == NULL) return fl->cur = fl->head;
  103.    else return fl->cur = fl->cur->next;
  104. }
  105.  
  106. int main(void)
  107. {
  108.    struct FileList fl;
  109.    struct FileDesc *file;
  110.    long opts[OPT_COUNT];
  111.    char **argptr;
  112.    struct RDArgs *rdargs;
  113.  
  114.    memset(&fl, 0, sizeof(fl));
  115.    memset(opts, 0, sizeof(opts));
  116.  
  117.    if(!(out=Output()))
  118.    {
  119.       // No default Output() window;  open one
  120.       if(!(out = Open("CON:0/0/500/100/GENSMAKE/AUTO/CLOSE/WAIT", MODE_NEWFILE)))
  121.          panic(NULL);
  122.    }
  123.  
  124.    if(SysBase->LibNode.lib_Version < 37)
  125.    {
  126.       panic("Requires AmigaDOS version 2.04 or higher\n");
  127.    }
  128.    
  129.    if(!(rdargs = ReadArgs(TEMPLATE, opts, NULL)))
  130.    {
  131.       // rdargs failed for some reason.  Use PrintFault to print the
  132.       // reason, then quit.
  133.       PrintFault(IoErr(), NULL);
  134.       panic(NULL);
  135.    }
  136.  
  137.    // If the user omitted some arguments, fill them in with default values
  138.    GetDefaultArgs(opts);
  139.  
  140.    // Add all the files specified by the user's patterns
  141.    for(argptr=(char **)opts[OPT_PATTERN]; *argptr; argptr++)
  142.    {
  143.       AddPattern(&fl, *argptr);
  144.    }
  145.  
  146.    // Walk the file list, processing each file.  Note that during file processing, it is
  147.    // possible that other files will be added to the end of the list.  (For example, if a
  148.    // .c file on the list includes a .h file, we add the .h file to the end of the FileList).
  149.    // Since they are added to the end, we stay in this loop until ALL files have been
  150.    // processed, even the ones that weren't on the list when the loop started.
  151.    for(file=NextFile(&fl); file; file=NextFile(&fl))
  152.       DoFile(&fl, file);
  153.  
  154.    // We have now processed all source files, all files included by the source files, all
  155.    // files included by those files, etc.  We have all the information we need to generate
  156.    // the smakefile.
  157.    GenSmake(&fl);
  158.  
  159.    // If we opened our own window previously, close it now.  It was opened with /WAIT, so
  160.    // it won't actually close until the user selects the close gadget.
  161.    if(out != Output()) Close(out);
  162.  
  163.    return 0;
  164. }
  165.  
  166. // Use RawDoFmt to simulate fprintf()
  167. int myfprintf(BPTR file, char *ctl, ...)
  168. {
  169.    char buffer[256];
  170.    va_list args;
  171.  
  172.    va_start(args, ctl);
  173.  
  174.    // The string constant below is actually the hexadecimal value for two 
  175.    // assembly-language instructions.  The two instructions implement the
  176.    // necessary callback routine to copy the format characters into the buffer
  177.    RawDoFmt(ctl, args, (void (*))"\x16\xc0\x4e\x75", buffer);
  178.  
  179.    va_end(args);
  180.  
  181.    FWrite(file, buffer, strlen(buffer), 1);
  182.  
  183.    return 0;
  184. }
  185.  
  186.  
  187. // Simulate sprintf using RawDoFmt
  188. int mysprintf(char *buffer, char *ctl, ...)
  189. {
  190.    va_list args;
  191.  
  192.    va_start(args, ctl);
  193.  
  194.    RawDoFmt(ctl, args, (void (*))"\x16\xc0\x4e\x75", buffer);
  195.  
  196.    va_end(args);
  197.  
  198.    return 0;
  199. }
  200.  
  201.  
  202.