home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / make / MAKE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-11  |  7.5 KB  |  353 lines

  1. /*
  2.  *    Do the actual making for make
  3.  */
  4.  
  5. #include "h.h"
  6.  
  7. /*
  8.  *  Support functions for Windows 95
  9.  */
  10.  
  11. time_t   CnvSystemTime(LPSYSTEMTIME pSysTime)
  12. {
  13.   time_t     result = 0;
  14.   int        MonthDays[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  15.   int       wYear,wMonth;
  16.  
  17.   for (wYear = 1970;wYear < pSysTime->wYear;wYear++)
  18.     result += (((wYear % 4)==0) ? 366 : 365);
  19.  
  20.   for (wMonth = 1;wMonth < pSysTime->wMonth;wMonth++)
  21.     result += MonthDays[wMonth-1];
  22.     
  23.   if ( (wMonth == 2) && ((wYear % 4) == 0) )
  24.     result ++;
  25.   
  26.   result += pSysTime->wDay - 1;
  27.   result *= 24;
  28.   result += pSysTime->wHour;
  29.   result *= 60;
  30.   result += pSysTime->wMinute;
  31.   result *= 60;
  32.   result += pSysTime->wSecond;
  33.  
  34. #ifndef NDEBUG
  35.   printf("%2d %2d %4d , %2d:%02d:%02d = %d\n",
  36.      pSysTime->wDay,pSysTime->wMonth,pSysTime->wYear,
  37.      pSysTime->wHour,pSysTime->wMinute,pSysTime->wSecond,
  38.      result);
  39. #endif
  40.  
  41.   return result;
  42. }
  43.  
  44. time_t time(time_t *buf)
  45. {
  46.   SYSTEMTIME stNow;
  47.   time_t     result;
  48.  
  49.   GetSystemTime(&stNow);
  50.   result = CnvSystemTime(&stNow);
  51.   if (buf)
  52.     *buf = result;
  53.   return result;
  54. }
  55.  
  56. char *strdup(const char *orig)
  57. {
  58.   char *result;
  59.  
  60.   result = (char *)malloc(strlen(orig)+1);
  61.   if (result != NULL)
  62.     strcpy(result,orig);
  63.   return result;
  64. }
  65.  
  66. /*
  67.  * This way, child programs will execute and return the
  68.  * right exit code values.
  69.  */
  70.  
  71. int _system(const char *cmd)
  72. {
  73.   BOOL                bResult;
  74.   STARTUPINFO         si;
  75.   PROCESS_INFORMATION pi;
  76.   DWORD               exitcode;
  77.  
  78.   memset(&si,0,sizeof(STARTUPINFO));
  79.   si.cb = sizeof(STARTUPINFO);
  80.   
  81.   bResult = CreateProcess(NULL,
  82.               cmd,
  83.               NULL,NULL, /* No security */
  84.               TRUE,         /* Inherits handles */
  85.               0,         /* Runs normally  */
  86.               NULL,NULL, /* Inherits env & cwd */
  87.               &si,&pi);
  88.  
  89.   if (bResult == FALSE) 
  90.     return system(cmd);
  91.   /* Modification proposed by Sune Falck, Sune.Falck@swipnet.se */
  92.   WaitForSingleObject(pi.hProcess,INFINITE);
  93.   if (GetExitCodeProcess(pi.hProcess,&exitcode)==FALSE) {
  94.       fprintf(stderr,"Impossible to get the exit status for %s\n",cmd);
  95.       return -1;
  96.    }
  97.  
  98.   return (int)exitcode;
  99. }
  100.  
  101.  
  102. /*
  103.  *    Do commands to make a target
  104.  */
  105. void docmds1(NAME *np,LINE *lp)
  106. {
  107.   bool            ssilent;
  108.   bool            signore;
  109.   int            estat;
  110.   register char *q;
  111.   register CMD  *cp;
  112.   
  113.   for (cp = lp->l_cmd; cp; cp = cp->c_next)
  114.     {
  115.       strcpy(str1, cp->c_cmd);
  116.       expand(str1);
  117.       q = str1;
  118.       ssilent = silent;
  119.       signore = ignore;
  120.       while ((*q == '@') || (*q == '-'))
  121.     {
  122.       if (*q == '@')       /*  Specific silent  */
  123.         ssilent = TRUE;
  124.       else           /*  Specific ignore  */
  125.         signore = TRUE;
  126.       q++;           /*  Not part of the command  */
  127.     }
  128.       
  129.       if (!domake)
  130.     ssilent = 0;
  131.       
  132.       if (!ssilent)
  133.     printf("   %s\n",q);
  134.       
  135.       if (domake)
  136.     {            /*  Get the shell to execute it  */
  137.       estat = _system(q);
  138.       if (estat != 0)
  139.         {
  140.           printf("%s: Error code %d", myname, estat);
  141.           if (signore)
  142.         fputs(" (Ignored)\n", stdout);
  143.           else
  144.         {
  145.           putchar('\n');
  146.           if (!(np->n_flag & N_PREC))
  147.             if (unlink(np->n_name) == 0)
  148.               printf("%s: '%s' removed.\n", myname, np->n_name);
  149.           exit(estat);
  150.         }
  151.         }
  152.     }
  153.     }
  154. }
  155.  
  156.  
  157. void docmds(NAME *np)
  158. {
  159.   register LINE *lp;
  160.   
  161.   
  162.   for (lp = np->n_line; lp; lp = lp->l_next)
  163.     docmds1(np, lp);
  164. }
  165.  
  166.  
  167. /*
  168.  *    Get the modification time of a file.  If the first
  169.  *    doesn't exist, it's modtime is set to 0.
  170.  */
  171. void modtime(struct name *np)
  172. {
  173.   FILETIME LastModifyTime;
  174.   SYSTEMTIME LastModSysTime;
  175.   HANDLE   hFile;
  176.   BOOL     bResult;
  177.  
  178.   np->n_time = 0L;
  179.   hFile = CreateFileA(np->n_name,GENERIC_READ,
  180.               FILE_SHARE_READ, NULL, OPEN_EXISTING,
  181.               FILE_ATTRIBUTE_NORMAL,NULL);
  182.  
  183.   if (hFile == INVALID_HANDLE_VALUE) {
  184.     DWORD LastError = GetLastError();
  185.     if (LastError != ERROR_FILE_NOT_FOUND) 
  186.       fatal ("Couldn't open %s GetLastError() = %d",np->n_name,LastError);
  187.     return;
  188.   }
  189.   bResult = GetFileTime(hFile,NULL,NULL,&LastModifyTime);
  190.   CloseHandle(hFile);
  191.   if (bResult == FALSE)
  192.     fatal ("Couldn't get file time for %s\n",np->n_name);
  193.   FileTimeToSystemTime(&LastModifyTime,&LastModSysTime);
  194.   np->n_time = CnvSystemTime(&LastModSysTime);
  195. }
  196.  
  197.  
  198. /*
  199.  *    Update the mod time of a file to now.
  200.  */
  201. void touch(struct name *np)
  202. {
  203.   SYSTEMTIME stNow;
  204.   FILETIME   ftNow;
  205.   HANDLE     hFile;
  206.  
  207.   if (!domake || !silent)
  208.     printf("    touch(%s)\n", np->n_name);
  209.   
  210.   if (domake)
  211.     {
  212.       hFile = CreateFileA(np->n_name,GENERIC_WRITE,
  213.               0,NULL,OPEN_EXISTING,
  214.               FILE_ATTRIBUTE_NORMAL,NULL);
  215.  
  216.       if (hFile == INVALID_HANDLE_VALUE) {
  217.     fatal("Couldn't touch %s",np->n_name);
  218.       }
  219.       GetSystemTime(&stNow);
  220.       SystemTimeToFileTime(&stNow,&ftNow);
  221.       SetFileTime(hFile,&ftNow,&ftNow,&ftNow);
  222.       CloseHandle(hFile);
  223.     }
  224. }
  225.  
  226.  
  227. /*
  228.  *    Recursive routine to make a target.
  229.  */
  230. int make(NAME *np,int level)
  231. {
  232.   register DEPEND *dp;
  233.   register LINE   *lp;
  234.   register struct depend *qdp;
  235.   time_t         dtime = 1;
  236.   bool             didsomething = 0;
  237.   
  238.   if (np->n_flag & N_DONE)
  239.     return 0;
  240.   
  241.   if (!np->n_time)
  242.     modtime(np);        /*  Gets modtime of this file  */
  243.   
  244.   if (rules)
  245.     {
  246.       for (lp = np->n_line; lp; lp = lp->l_next)
  247.     if (lp->l_cmd)
  248.       break;
  249.       if (!lp)
  250.     dyndep(np);
  251.     }
  252.   
  253.   if ( ((np->n_flag & N_TARG) == 0) && (np->n_time == 0L) )
  254.     fatal("Don't know how to make %s", np->n_name);
  255.   
  256.   for (qdp = (DEPEND *)0, lp = np->n_line; lp; lp = lp->l_next)
  257.     {
  258.       for (dp = lp->l_dep; dp; dp = dp->d_next)
  259.     {
  260.       make(dp->d_name, level+1);
  261.       if (np->n_time < dp->d_name->n_time)
  262.         qdp = newdep(dp->d_name, qdp);
  263.       dtime = max(dtime, dp->d_name->n_time);
  264.     }
  265.       if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
  266.     {
  267.       make1(np, lp, qdp);    /* free()'s qdp */
  268.       dtime = 1;
  269.       qdp = (DEPEND *)0;
  270.       didsomething++;
  271.     }
  272.     }
  273.   
  274.   np->n_flag |= N_DONE;
  275.   
  276.   if (quest)
  277.     {
  278.       long        t;
  279.       
  280.       t = np->n_time;
  281.       time(&np->n_time);
  282.       return t < dtime;
  283.     }
  284.   else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
  285.     {
  286.       make1(np, (LINE *)0, qdp);    /* free()'s qdp */
  287.       time(&np->n_time);
  288.     }
  289.   else if (level == 0 && !didsomething)
  290.     printf("%s: '%s' is up to date\n", myname, np->n_name);
  291.   return 0;
  292. }
  293.  
  294.  
  295. make1(np, lp, qdp)
  296. register DEPEND *    qdp;
  297. LINE *            lp;
  298. NAME *            np;
  299. {
  300.   register DEPEND *    dp;
  301.  
  302.  
  303.   if (dotouch)
  304.     touch(np);
  305.   else
  306.     {
  307.       strcpy(str1, "");
  308.       for (dp = qdp; dp; dp = qdp)
  309.     {
  310.       if (strlen(str1))
  311.         strcat(str1, " ");
  312.       strcat(str1, dp->d_name->n_name);
  313.       qdp = dp->d_next;
  314.       free(dp);
  315.     }
  316.       setmacro("?", str1);
  317.       setmacro("@", np->n_name);
  318.  
  319.       /* R.D. 1987/02/01  add "$*" macro to stand for target minus suffix */
  320.       /* I'm assuming that np->n_name is the full name of the target. */
  321.  
  322.       {
  323. #if 1
  324. #define    MAXNAMSIZ    32        /* allow 32-char names */
  325.     char tmpnam[MAXNAMSIZ];
  326.     char *p;
  327.     strcpy(tmpnam, np->n_name);
  328.     p = tmpnam + strlen(tmpnam);
  329.     while (*p != '.' && p != tmpnam)
  330.       --p;
  331.     /* now p points to dot, or tmpnam, or both */
  332.     if (*p == '.')
  333.       *p = '\0';        /* null out extension */
  334.     
  335.     /* now tmpnam holds target minus suffix */
  336.     setmacro("*", tmpnam);
  337. #else
  338.     char *ntarget = strdup(np->n_name);
  339.     char *p       = strrchr(ntarget,'.');
  340.     if (*p)
  341.       p = '\0';
  342.     setmacro("*",ntarget);
  343. #endif
  344.       }
  345.  
  346.       if (lp)        /* lp set if doing a :: rule */
  347.     docmds1(np, lp);
  348.       else
  349.     docmds(np);
  350.     }
  351. }
  352.  
  353.