home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tools / make / make_pd / make.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-01  |  9.1 KB  |  508 lines

  1. /*
  2.  *    Do the actual making for make
  3.  */
  4.  
  5. #include <stdio.h>
  6. #ifdef unix
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <sys/errno.h>
  10. #endif
  11. #ifdef MSC
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <errno.h>
  15. #endif
  16. #ifdef eon
  17. #include <sys/stat.h>
  18. #include <sys/err.h>
  19. #endif
  20. #ifdef os9
  21. #include <time.h>
  22. #include <os9.h>
  23. #include <modes.h>
  24. #include <direct.h>
  25. #include <errno.h>
  26. #endif
  27. #include "h.h"
  28.  
  29.  
  30.  
  31. /*
  32.  *    Exec a shell that returns exit status correctly (/bin/esh).
  33.  *    The standard EON shell returns the process number of the last
  34.  *    async command, used by the debugger (ugg).
  35.  *    [exec on eon is like a fork+exec on unix]
  36.  */
  37. int
  38. dosh(string, shell)
  39. char *            string;
  40. char *            shell;
  41. {
  42.     int    number;
  43.  
  44. #ifdef MSC
  45.     return system(string);
  46. #endif
  47. #ifdef unix
  48.     return system(string);
  49. #endif
  50. #ifdef eon
  51.     return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
  52.         -1:    /* couldn't start the shell */
  53.         wait(number);    /* return its exit status */
  54. #endif
  55. #ifdef os9
  56.     int    status, pid;
  57.  
  58.     strcat(string, "\n");
  59.     if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
  60.         return -1;        /* Couldn't start a shell */
  61.     do
  62.     {
  63.         if ((pid = wait(&status)) == -1)
  64.             return -1;    /* child already died!?!? */
  65.     } while (pid != number);
  66.  
  67.     return status;
  68. #endif
  69. }
  70.  
  71.  
  72. /*
  73.  *    Do commands to make a target
  74.  */
  75. void
  76. docmds1(np, lp)
  77. struct name *        np;
  78. struct line *        lp;
  79. {
  80.     bool            ssilent;
  81.     bool            signore;
  82.     int            estat;
  83.     register char *        q;
  84.     register char *        p;
  85.     char *            shell;
  86.     register struct cmd *    cp;
  87.  
  88.  
  89.     if (*(shell = getmacro("SHELL")) == '\0')
  90. #ifdef eon
  91.         shell = ":bin/esh";
  92. #endif
  93. #ifdef MCS
  94.         shell = "";
  95. #endif
  96. #ifdef unix
  97.         shell = "/bin/sh";
  98. #endif
  99. #ifdef os9
  100.         shell = "shell";
  101. #endif
  102.  
  103.     for (cp = lp->l_cmd; cp; cp = cp->c_next)
  104.     {
  105.         strcpy(str1, cp->c_cmd);
  106.         expand(str1);
  107.         q = str1;
  108.         ssilent = silent;
  109.         signore = ignore;
  110.         while ((*q == '@') || (*q == '-'))
  111.         {
  112.             if (*q == '@')       /*  Specific silent  */
  113.                 ssilent = TRUE;
  114.             else           /*  Specific ignore  */
  115.                 signore = TRUE;
  116.             q++;           /*  Not part of the command  */
  117.         }
  118.  
  119.         if (!domake)
  120.             ssilent = 0;
  121.  
  122.         if (!ssilent)
  123.             fputs("    ", stdout);
  124.  
  125.         for (p=q; *p; p++)
  126.         {
  127.             if (*p == '\n' && p[1] != '\0')
  128.             {
  129.                 *p = ' ';
  130.                 if (!ssilent)
  131.                     fputs("\\\n", stdout);
  132.             }
  133.             else if (!ssilent)
  134.                 putchar(*p);
  135.         }
  136.         if (!ssilent)
  137.             putchar('\n');
  138.  
  139.         if (domake)
  140.         {            /*  Get the shell to execute it  */
  141.             if ((estat = dosh(q, shell)) != 0)
  142.             {
  143.                 if (estat == -1)
  144.                     fatal("Couldn't execute %s", shell);
  145.                 else
  146.                 {
  147.                     printf("%s: Error code %d", myname, estat);
  148.                     if (signore)
  149.                         fputs(" (Ignored)\n", stdout);
  150.                     else
  151.                     {
  152.                         putchar('\n');
  153.                         if (!(np->n_flag & N_PREC))
  154.                             if (unlink(np->n_name) == 0)
  155.                                 printf("%s: '%s' removed.\n", myname, np->n_name);
  156.                         exit(estat);
  157.                     }
  158.                 }
  159.             }
  160.         }
  161.     }
  162. }
  163.  
  164.  
  165. docmds(np)
  166. struct name *        np;
  167. {
  168.     register struct line *    lp;
  169.  
  170.  
  171.     for (lp = np->n_line; lp; lp = lp->l_next)
  172.         docmds1(np, lp);
  173. }
  174.  
  175.  
  176. #ifdef os9
  177. /*
  178.  *    Some stuffing around to get the modified time of a file
  179.  *    in an os9 file system
  180.  */
  181. getmdate(fd, tbp)
  182. struct sgtbuf *        tbp;
  183. {
  184.     struct registers    regs;
  185.     static struct fildes    fdbuf;
  186.  
  187.  
  188.     regs.rg_a = fd;
  189.     regs.rg_b = SS_FD;
  190.     regs.rg_x = &fdbuf;
  191.     regs.rg_y = sizeof (fdbuf);
  192.  
  193.     if (_os9(I_GETSTT, ®s) == -1)
  194.     {
  195.         errno = regs.rg_b & 0xff;
  196.         return -1;
  197.     }
  198.     if (tbp)
  199.     {
  200.         _strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date));
  201.         tbp->t_second = 0;    /* Files are only acurate to mins */
  202.     }
  203.     return 0;
  204. }
  205.  
  206.  
  207. /*
  208.  *    Kludge routine to return an aproximation of how many
  209.  *    seconds since 1980.  Dates will be in order, but will not
  210.  *    be lineer
  211.  */
  212. time_t
  213. cnvtime(tbp)
  214. struct sgtbuf        *tbp;
  215. {
  216.     long            acc;
  217.  
  218.  
  219.     acc = tbp->t_year - 80;        /* Baseyear is 1980 */
  220.     acc = acc * 12 + tbp->t_month;
  221.     acc = acc * 31 + tbp->t_day;
  222.     acc = acc * 24 + tbp->t_hour;
  223.     acc = acc * 60 + tbp->t_minute;
  224.     acc = acc * 60 + tbp->t_second;
  225.  
  226.     return acc;
  227. }
  228.  
  229.  
  230. /*
  231.  *    Get the current time in the internal format
  232.  */
  233. time(tp)
  234. time_t *        tp;
  235. {
  236.     struct sgtbuf        tbuf;
  237.  
  238.  
  239.     if (getime(&tbuf) < 0)
  240.         return -1;
  241.  
  242.     if (tp)
  243.         *tp = cnvtime(&tbuf);
  244.  
  245.     return 0;
  246. }
  247. #endif
  248.  
  249.  
  250. /*
  251.  *    Get the modification time of a file.  If the first
  252.  *    doesn't exist, it's modtime is set to 0.
  253.  */
  254. void
  255. modtime(np)
  256. struct name *        np;
  257. {
  258. #ifdef MSC
  259.     struct stat        info;
  260.     int            fd;
  261.  
  262.  
  263.     if (stat(np->n_name, &info) < 0)
  264.     {
  265.         if (errno != ENOENT)
  266.             fatal("Can't open %s; error %d", np->n_name, errno);
  267.  
  268.         np->n_time = 0L;
  269.     }
  270.     else
  271.         np->n_time = info.st_mtime;
  272. #endif
  273. #ifdef unix
  274.     struct stat        info;
  275.     int            fd;
  276.  
  277.  
  278.     if (stat(np->n_name, &info) < 0)
  279.     {
  280.         if (errno != ENOENT)
  281.             fatal("Can't open %s; error %d", np->n_name, errno);
  282.  
  283.         np->n_time = 0L;
  284.     }
  285.     else
  286.         np->n_time = info.st_mtime;
  287. #endif
  288. #ifdef eon
  289.     struct stat        info;
  290.     int            fd;
  291.  
  292.  
  293.     if ((fd = open(np->n_name, 0)) < 0)
  294.     {
  295.         if (errno != ER_NOTF)
  296.             fatal("Can't open %s; error %02x", np->n_name, errno);
  297.  
  298.         np->n_time = 0L;
  299.     }
  300.     else if (getstat(fd, &info) < 0)
  301.         fatal("Can't getstat %s; error %02x", np->n_name, errno);
  302.     else
  303.         np->n_time = info.st_mod;
  304.  
  305.     close(fd);
  306. #endif
  307. #ifdef os9
  308.     struct sgtbuf        info;
  309.     int            fd;
  310.  
  311.  
  312.     if ((fd = open(np->n_name, 0)) < 0)
  313.     {
  314.         if (errno != E_PNNF)
  315.             fatal("Can't open %s; error %02x", np->n_name, errno);
  316.  
  317.         np->n_time = 0L;
  318.     }
  319.     else if (getmdate(fd, &info) < 0)
  320.         fatal("Can't getstat %s; error %02x", np->n_name, errno);
  321.     else
  322.         np->n_time = cnvtime(&info);
  323.  
  324.     close(fd);
  325. #endif
  326. }
  327.  
  328.  
  329. /*
  330.  *    Update the mod time of a file to now.
  331.  */
  332. void
  333. touch(np)
  334. struct name *        np;
  335. {
  336.     char            c;
  337.     int            fd;
  338.  
  339.  
  340.     if (!domake || !silent)
  341.         printf("    touch(%s)\n", np->n_name);
  342.  
  343.     if (domake)
  344.     {
  345. #ifdef MSC
  346.         long        a[2];
  347.  
  348.         (void) time(&a[0]);
  349.         a[1] = a[0];
  350.         if (utime(np->n_name, &a[0]) < 0)
  351.             printf("%s: '%s' not touched - non-existant\n",
  352.                     myname, np->n_name);
  353. #endif
  354. #ifdef unix
  355.         long        a[2];
  356.  
  357.         a[0] = a[1] = time(0);
  358.         if (utime(np->n_name, &a[0]) < 0)
  359.             printf("%s: '%s' not touched - non-existant\n",
  360.                     myname, np->n_name);
  361. #endif
  362. #ifdef eon
  363.         if ((fd = open(np->n_name, 0)) < 0)
  364.             printf("%s: '%s' not touched - non-existant\n",
  365.                     myname, np->n_name);
  366.         else
  367.         {
  368.             uread(fd, &c, 1, 0);
  369.             uwrite(fd, &c, 1);
  370.         }
  371.         close(fd);
  372. #endif
  373. #ifdef os9
  374.         /*
  375.          *    Strange that something almost as totally useless
  376.          *    as this is easy to do in os9!
  377.          */
  378.         if ((fd = open(np->n_name, S_IWRITE)) < 0)
  379.             printf("%s: '%s' not touched - non-existant\n",
  380.                     myname, np->n_name);
  381.         close(fd);
  382. #endif
  383.     }
  384. }
  385.  
  386.  
  387. /*
  388.  *    Recursive routine to make a target.
  389.  */
  390. int
  391. make(np, level)
  392. struct name *        np;
  393. int            level;
  394. {
  395.     register struct depend *    dp;
  396.     register struct line *        lp;
  397.     register struct depend *    qdp;
  398.     time_t                dtime = 1;
  399.     bool                didsomething = 0;
  400.  
  401.  
  402.     if (np->n_flag & N_DONE)
  403.         return 0;
  404.  
  405.     if (!np->n_time)
  406.         modtime(np);        /*  Gets modtime of this file  */
  407.  
  408.     if (rules)
  409.     {
  410.         for (lp = np->n_line; lp; lp = lp->l_next)
  411.             if (lp->l_cmd)
  412.                 break;
  413.         if (!lp)
  414.             dyndep(np);
  415.     }
  416.  
  417.     if (!(np->n_flag & N_TARG) && np->n_time == 0L)
  418.         fatal("Don't know how to make %s", np->n_name);
  419.  
  420.     for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
  421.     {
  422.         for (dp = lp->l_dep; dp; dp = dp->d_next)
  423.         {
  424.             make(dp->d_name, level+1);
  425.             if (np->n_time < dp->d_name->n_time)
  426.                 qdp = newdep(dp->d_name, qdp);
  427.             dtime = max(dtime, dp->d_name->n_time);
  428.         }
  429.         if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
  430.         {
  431.             make1(np, lp, qdp);    /* free()'s qdp */
  432.             dtime = 1;
  433.             qdp = (struct depend *)0;
  434.             didsomething++;
  435.         }
  436.     }
  437.  
  438.     np->n_flag |= N_DONE;
  439.  
  440.     if (quest)
  441.     {
  442.         long        t;
  443.  
  444.         t = np->n_time;
  445.         time(&np->n_time);
  446.         return t < dtime;
  447.     }
  448.     else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
  449.     {
  450.         make1(np, (struct line *)0, qdp);    /* free()'s qdp */
  451.         time(&np->n_time);
  452.     }
  453.     else if (level == 0 && !didsomething)
  454.         printf("%s: '%s' is up to date\n", myname, np->n_name);
  455.     return 0;
  456. }
  457.  
  458.  
  459. make1(np, lp, qdp)
  460. register struct depend *    qdp;
  461. struct line *            lp;
  462. struct name *            np;
  463. {
  464.     register struct depend *    dp;
  465.  
  466.  
  467.     if (dotouch)
  468.         touch(np);
  469.     else
  470.     {
  471.         strcpy(str1, "");
  472.         for (dp = qdp; dp; dp = qdp)
  473.         {
  474.             if (strlen(str1))
  475.                 strcat(str1, " ");
  476.             strcat(str1, dp->d_name->n_name);
  477.             qdp = dp->d_next;
  478.             free(dp);
  479.         }
  480.         setmacro("?", str1);
  481.         setmacro("@", np->n_name);
  482.  
  483.         /* R.D. 1987/02/01  add "$*" macro to stand for target minus suffix */
  484.         /* I'm assuming that np->n_name is the full name of the target. */
  485.  
  486. #define    MAXNAMSIZ    32        /* allow 32-char names */
  487.         {
  488.             char tmpnam[MAXNAMSIZ];
  489.             char *p;
  490.             strcpy(tmpnam, np->n_name);
  491.             p = tmpnam + strlen(tmpnam);            /* point p to end of tmpnam */
  492.             while (*p != '.' && p != tmpnam)
  493.                 --p;
  494.             /* now p points to dot, or tmpnam, or both */
  495.             if (*p == '.')
  496.                 *p = '\0';                                /* null out extension */
  497.  
  498.             /* now tmpnam holds target minus suffix */
  499.             setmacro("*", tmpnam);
  500.         }
  501.  
  502.         if (lp)        /* lp set if doing a :: rule */
  503.             docmds1(np, lp);
  504.         else
  505.             docmds(np);
  506.     }
  507. }
  508.