home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume12 / cake / part02 / entry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-10-14  |  11.1 KB  |  560 lines

  1. /*
  2. **    Module to record and process Cake dependency entries.
  3. */
  4.  
  5. static    char
  6. rcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/entry.c,v 1.14 86/07/19 12:22:52 zs Exp $";
  7.  
  8. #include    "cake.h"
  9. #include    <ctype.h>
  10.  
  11. List    *entries;
  12. Entry    *main_entry;
  13.  
  14. extern    Test    *ground_test();
  15.  
  16. #define    ground_pat(env, pat)    make_pat(ground(env, pat->p_str), pat->p_cmd, pat->p_flag);
  17. #define    ground_act(env, act)    make_act(ground(env, act->a_str), act->a_flag);
  18.  
  19. /*
  20. **    Initialise ALL data structures about entries.
  21. */
  22.  
  23. init_entry()
  24. {
  25.     entries = makelist0();
  26.     main_entry = (Entry *) NULL;
  27. }
  28.  
  29. /*
  30. **    Deposit an entry just read in.
  31. */
  32.  
  33. new_entry(deps, acts)
  34. reg    List    *deps;                /* of Entry    */
  35. reg    List    *acts;                /* of Pat    */
  36. {
  37.     reg    List    *ptr;
  38.     reg    Entry    *entry;
  39.  
  40.     for_list (ptr, deps)
  41.     {
  42.         entry = (Entry *) ldata(ptr);
  43.         entry->e_act  = acts;
  44.         addtail(entries, entry);    /* no assignment */
  45.     }
  46. }
  47.  
  48. /*
  49. **    Prepare entries for matches against their left hand sides.
  50. **    This essentially means dereferencing any command patterns.
  51. **    Another minor correction is also done here: if -n is given
  52. **    then we set nf_PRECIOUS so no file is deleted.
  53. */
  54.  
  55. prep_entries()
  56. {
  57.     extern    List    *break_pat();
  58.     reg    List    *ptr, *ptr1;
  59.     reg    Entry    *entry;
  60.     reg    Pat    *pat;
  61.     reg    List    *newnew;
  62.  
  63.     for_list (ptr, entries)
  64.     {
  65.         entry = (Entry *) ldata(ptr);
  66.  
  67.         newnew = makelist0();
  68.         for_list (ptr1, entry->e_new)
  69.         {
  70.             pat = (Pat *) ldata(ptr1);
  71.             if (on_pat(pat, nf_WHEN))
  72.             {
  73.                 printf("cake: inappropriate flag '*' after target %s ignored\n",
  74.                     pat->p_str);
  75.                 reset_pat(pat, nf_WHEN);
  76.             }
  77.  
  78.             if (nflag)
  79.                 set_pat(pat, nf_PRECIOUS);
  80.  
  81.             if (! pat->p_cmd)
  82.                 addtail(newnew, pat);        /* na */
  83.             else
  84.             {
  85.                 deref(pat, TRUE);
  86.                 addlist(newnew, break_pat(pat));/* na */
  87.             }
  88.         }
  89.  
  90.         entry->e_new = newnew;
  91.  
  92.         for_list (ptr1, entry->e_old)
  93.         {
  94.             pat = (Pat *) ldata(ptr1);
  95.             if (pat->p_cmd && on_pat(pat, nf_WHEN))
  96.             {
  97.                 printf("cake: inappropriate flag '*' after command source %s ignored\n",
  98.                     pat->p_str);
  99.                 reset_pat(pat, nf_WHEN);
  100.             }
  101.         }
  102.  
  103. #ifdef    CAKEDEBUG
  104.         if (entrydebug)
  105.         {
  106.             printf("prepared entry:\n");
  107.             print_entry(entry);
  108.         }
  109. #endif
  110.     }
  111. }
  112.  
  113. /*
  114. **    Enter the last (main) entry. This entry has a distinguished
  115. **    left hand side consisting of the sole pattern CHASEROOT.
  116. **    This is the pattern which cake tries to make up-to-date.
  117. **    If there were nonoption arguments on the command line,
  118. **    CHASEROOT is made to depend on them; otherwise the left hand
  119. **    side of the first concrete entry is used, as in make.
  120. **    However, if the first concrete entry is in an included file,
  121. **    we keep looking, unless it had a double colon.
  122. */
  123.  
  124. final_entry(argc, argv)
  125. reg    int    argc;
  126. reg    char    *argv[];
  127. {
  128.     extern    bool    hasvars();
  129.     reg    List    *ptr, *ptr1;
  130.     reg    Entry    *entry, *foundentry;
  131.     reg    Pat    *pat;
  132.     reg    bool    found_main, found_incl;
  133.     reg    int    i;
  134.  
  135.     main_entry = make(Entry);
  136.     main_entry->e_new  = makelist(make_pat(CHASEROOT, FALSE, nf_PSEUDO|nf_NODELETE));
  137.     main_entry->e_old  = makelist0();
  138.     main_entry->e_cond = (Test *) NULL;
  139.     main_entry->e_act  = makelist0();
  140.  
  141.     cdebug("target count %d\n", argc-1);
  142.  
  143.     if (argc > 1)
  144.     {
  145.         for (i = 1; i < argc; i++)
  146.         {
  147.             cdebug("target %s\n", argv[i]);
  148.             addtail(main_entry->e_old, make_pat(argv[i], FALSE, 0));    /* na */
  149.         }
  150.     }
  151.     else
  152.     {
  153.         /* find the first entry without variables */
  154.         found_main = FALSE;
  155.         found_incl = FALSE;
  156.         for_list (ptr, entries)
  157.         {
  158.             entry = (Entry *) ldata(ptr);
  159.             for_list (ptr1, entry->e_new)
  160.             {
  161.                 pat = (Pat *) ldata(ptr1);
  162.                 if (hasvars(pat->p_str))
  163.                     goto nextentry;
  164.             }
  165.  
  166.             if (streq(entry->e_file, cakefile) || entry->e_dblc)
  167.             {
  168.                 found_main = TRUE;
  169.                 foundentry = entry;
  170.                 break;
  171.             }
  172.             or (! found_incl)
  173.             {
  174.                 found_incl = TRUE;
  175.                 foundentry = entry;
  176.             }
  177.  
  178.         nextentry:    ;
  179.         }
  180.  
  181.         if (! found_main && ! found_incl)
  182.         {
  183.             printf("cake: no entries without variables\n");
  184.             printf("cake: don't know what cake to bake\n");
  185.             exit(1);
  186.         }
  187.  
  188.         /* update everything on its left side */
  189.         for_list (ptr, foundentry->e_new)
  190.         {
  191.             pat = (Pat *) ldata(ptr);
  192.             addtail(main_entry->e_old, pat);    /* na */
  193.         }
  194.     }
  195.  
  196.     addtail(entries, main_entry);    /* no assigment */
  197. }
  198.  
  199.  
  200. /*
  201. **    Return a new entry which is a ground version of the one passed.
  202. **    Process '*' flags and set up e_when accordingly.
  203. */
  204.  
  205. Entry *
  206. ground_entry(env, entry)
  207. Env        env;
  208. reg    Entry    *entry;
  209. {
  210.     extern        do_when();
  211.     extern    List    *break_pat();
  212.     extern    char    *ground();
  213.     reg    List    *ptr;
  214.     reg    Entry    *newentry;
  215.     reg    Pat    *pat, *newpat;
  216.     reg    Act    *act, *newact;
  217.  
  218.     put_trail("ground_entry", "start");
  219.     newentry = make(Entry);
  220.     newentry->e_new  = makelist0();
  221.     newentry->e_old  = makelist0();
  222.     newentry->e_act  = makelist0();
  223.     newentry->e_when = makelist0();
  224.  
  225.     for_list (ptr, entry->e_new)
  226.     {
  227.         /* prep_entries made these patterns command free */
  228.         pat = (Pat *) ldata(ptr);
  229.         newpat = ground_pat(env, pat);
  230.         do_when(newentry, newpat);
  231.         addtail(newentry->e_new, newpat);    /* na */
  232.     }
  233.  
  234.     for_list (ptr, entry->e_old)
  235.     {
  236.         pat = (Pat *) ldata(ptr);
  237.         newpat = ground_pat(env, pat);
  238.         do_when(newentry, newpat);
  239.         addtail(newentry->e_old, newpat);    /* na */
  240.     }
  241.  
  242.     for_list (ptr, entry->e_act)
  243.     {
  244.         act = (Act *) ldata(ptr);
  245.         newact = ground_act(env, act);
  246.         addtail(newentry->e_act, newact);    /* na */
  247.     }
  248.  
  249.     newentry->e_cond = ground_test(env, entry->e_cond);
  250.  
  251.     put_trail("ground_entry", "finish");
  252.     return newentry;
  253. }
  254.  
  255. /*
  256. **    Look after '*' (when) flags.
  257. */
  258.  
  259. do_when(entry, pat)
  260. reg    Entry    *entry;
  261. reg    Pat    *pat;
  262. {
  263.     if (on_pat(pat, nf_WHEN))
  264.     {
  265.         reset_pat(pat, nf_WHEN);
  266.         entry->e_when = addtail(entry->e_when, pat);
  267.     }
  268. }
  269.  
  270. /*
  271. **    Ground a test.
  272. */
  273.  
  274. Test *
  275. ground_test(env, test)
  276. Env        env;
  277. reg    Test    *test;
  278. {
  279.     extern    char    *ground();
  280.     reg    List    *ptr;
  281.     reg    Pat    *pat, *newpat;
  282.     reg    Test    *newtest;
  283.  
  284.     if (test == (Test *) NULL)
  285.         return test;
  286.  
  287.     put_trail("ground_test", "start");
  288.     switch (test->t_kind)
  289.     {
  290.  
  291. when t_TRUE:
  292. case t_FALSE:    put_trail("ground_test", "finish");
  293.         return test;
  294.  
  295. when t_AND:
  296. case t_OR:    put_trail("ground_test", "finish");
  297.         return make_test_b(test->t_kind,
  298.             ground_test(env, test->t_left), ground_test(env, test->t_right));
  299.  
  300. when t_NOT:    put_trail("ground_test", "finish");
  301.         return make_test_u(test->t_kind, ground_test(env, test->t_left));
  302.  
  303. when t_CMD:    put_trail("ground_test", "finish");
  304.         return make_test_c(ground(env, test->t_cmd));
  305.  
  306. when t_MATCH:    pat = ground_pat(env, test->t_pat);
  307.         newtest = make_test_mm(pat);
  308.         for_list (ptr, test->t_list)
  309.         {
  310.             pat = (Pat *) ldata(ptr);
  311.             newpat = ground_pat(env, pat);
  312.             addtail(newtest->t_list, newpat);    /* na */
  313.         }
  314.  
  315.         put_trail("ground_test", "finish");
  316.         return newtest;
  317.  
  318. when t_LIST:    pat = ground_pat(env, test->t_pat);
  319.         newtest = make_test_l(pat, makelist0());
  320.         for_list (ptr, test->t_list)
  321.         {
  322.             pat = (Pat *) ldata(ptr);
  323.             newpat = ground_pat(env, pat);
  324.             addtail(newtest->t_list, newpat);    /* na */
  325.         }
  326.  
  327.         put_trail("ground_test", "finish");
  328.         return newtest;
  329.  
  330. when t_EXIST:    newpat = ground_pat(env, test->t_pat);
  331.         put_trail("ground_test", "finish");
  332.         return make_test_s(t_EXIST, newpat);
  333.  
  334. when t_CANDO:    newpat = ground_pat(env, test->t_pat);
  335.         put_trail("ground_test", "finish");
  336.         return make_test_s(t_CANDO, newpat);
  337.  
  338. when t_OK:    newpat = ground_pat(env, test->t_pat);
  339.         put_trail("ground_test", "finish");
  340.         return make_test_s(t_OK, newpat);
  341.  
  342. otherwise:    printf("cake internal error: bad test type %x in ground_test\n", test->t_kind);
  343.         put_trail("ground_test", "finish");
  344.         return (Test *) NULL;
  345.     }
  346.  
  347.     put_trail("ground_test", "finish");
  348.     return (Test *) NULL;
  349. }
  350.  
  351. /*
  352. **    Dereference all command patterns in the given entry.
  353. */
  354.  
  355. deref_entry(env, entry)
  356. Env        env;
  357. reg    Entry    *entry;
  358. {
  359.     reg    List    *ptr, *ptr1;
  360.     reg    List    *newlist;
  361.     reg    List    *patlist;
  362.     reg    Pat    *pat, *oldpat, *newpat;
  363.  
  364.     newlist = makelist0();
  365.     for_list (ptr, entry->e_old)
  366.     {
  367.         pat = (Pat *) ldata(ptr);
  368.         if (! pat->p_cmd)
  369.             addtail(newlist, pat);    /* na */
  370.         else
  371.         {
  372.             deref(pat, TRUE);
  373.             patlist = break_pat(pat);
  374.             for_list (ptr1, patlist)
  375.             {
  376.                 oldpat = (Pat *) ldata(ptr1);
  377.                 newpat = make_pat(ground(env, oldpat->p_str), FALSE, 0);
  378.                 do_when(entry, newpat);
  379.                 addtail(newlist, newpat);    /* na */
  380.             }
  381.         }
  382.     }
  383.  
  384.     entry->e_old  = newlist;
  385. }
  386.  
  387. /*
  388. **    Dereference a test.
  389. */
  390.  
  391. Test *
  392. deref_test(test)
  393. reg    Test    *test;
  394. {
  395.     extern    char    *expand_cmds();
  396.     reg    List    *ptr;
  397.     reg    List    *newlist;
  398.     reg    Pat    *pat;
  399.  
  400.     if (test == (Test *) NULL)
  401.         return test;
  402.  
  403.     put_trail("deref_test", "start");
  404.     switch (test->t_kind)
  405.     {
  406.  
  407. when t_TRUE:
  408. case t_FALSE:    put_trail("deref_test", "finish");
  409.         return test;
  410.  
  411. when t_AND:
  412. case t_OR:    test->t_left  = deref_test(test->t_left);
  413.         test->t_right = deref_test(test->t_right);
  414.         put_trail("deref_test", "finish");
  415.         return test;
  416.  
  417. when t_NOT:    test->t_left  = deref_test(test->t_left);
  418.         put_trail("deref_test", "finish");
  419.         return test;
  420.  
  421. when t_CMD:    test->t_cmd = expand_cmds(test->t_cmd);
  422.         put_trail("deref_test", "finish");
  423.         return test;
  424.  
  425. when t_MATCH:    deref(test->t_pat, FALSE);
  426.         for_list (ptr, test->t_list)
  427.         {
  428.             pat = (Pat *) ldata(ptr);
  429.             deref(pat, FALSE);
  430.         }
  431.  
  432.         put_trail("deref_test", "finish");
  433.         return test;
  434.  
  435. when t_LIST:    deref(test->t_pat, FALSE);
  436.         newlist = makelist0();
  437.         for_list (ptr, test->t_list)
  438.         {
  439.             pat = (Pat *) ldata(ptr);
  440.             if (! pat->p_cmd)
  441.                 addtail(newlist, pat);            /* na */
  442.             else
  443.             {
  444.                 deref(pat, TRUE);
  445.                 addlist(newlist, break_pat(pat));    /* na */
  446.             }
  447.         }
  448.  
  449.         test->t_list = newlist;
  450.         put_trail("deref_test", "finish");
  451.         return test;
  452.  
  453. when t_EXIST:    deref(test->t_pat, FALSE);
  454.         put_trail("deref_test", "finish");
  455.         return test;
  456.  
  457. when t_CANDO:    deref(test->t_pat, FALSE);
  458.         put_trail("deref_test", "finish");
  459.         return test;
  460.  
  461. when t_OK:    deref(test->t_pat, FALSE);
  462.         put_trail("deref_test", "finish");
  463.         return test;
  464.  
  465. otherwise:    printf("cake internal error: bad test type %x in deref_test\n", test->t_kind);
  466.         put_trail("deref_test", "finish");
  467.         return (Test *) NULL;
  468.     }
  469.  
  470.     put_trail("deref_test", "finish");
  471.     return (Test *) NULL;
  472. }
  473.  
  474. Act *
  475. prep_act(text)
  476. reg    char    *text;
  477. {
  478.     reg    Act    *act;
  479.     reg    char    *s;
  480.  
  481.     act = make(Act);
  482.     act->a_flag = 0;
  483.  
  484.     /* strip trailing space - there is at least the newline */
  485.     for (s = text+strlen(text)-1; isspace(*s); s--)
  486.         *s = '\0';
  487.  
  488.     /* put just the newline back */
  489.     strcat(s, "\n");
  490.  
  491.     /* strip spaces before flags */
  492.     for (s = text; isspace(*s); s++)
  493.         ;
  494.  
  495.     /* process the flags */
  496.     for (; *s != '\0'; s++)
  497.         if (*s == '@')
  498.             set_act(act, af_SILENT);
  499.         or (*s == '!')
  500.             set_act(act, af_SYSTEM);
  501.         or (*s == '-')
  502.             set_act(act, af_IGNORE);
  503.         or (*s == '+')
  504.             set_act(act, af_MINUSN);
  505.         else
  506.             break;
  507.  
  508.     /* strip spaces after flags */
  509.     for (; isspace(*s); s++)
  510.         ;
  511.  
  512.     act->a_str = new_name(s);
  513.     return act;
  514. }
  515.  
  516. Act *
  517. prep_script(first_act, middle_act, last_act)
  518. reg    Act    *first_act, *last_act;
  519. reg    List    *middle_act;
  520. {
  521.     reg    List    *ptr;
  522.     reg    Act    *act;
  523.     reg    char    *s;
  524.     char        buf[MAXSCRIPT];
  525.  
  526.     buf[0] = '\0';
  527.     /* handle the first action */
  528.     for (s = first_act->a_str+1; *s == ' ' || *s == '\t'; s++)
  529.         ;
  530.  
  531.     if (strdiff(s, "\n"))
  532.         strcat(buf, s);
  533.  
  534.     /* handle the middle actions, if any */
  535.     for_list (ptr, middle_act)
  536.     {
  537.         act = (Act *) ldata(ptr);
  538.         strcat(buf, act->a_str);
  539.     }
  540.  
  541.     /* handle the last action as the first */
  542.     for (s = last_act->a_str+1; *s == ' ' || *s == '\t'; s++)
  543.         ;
  544.  
  545.     if (strdiff(s, "\n"))
  546.         strcat(buf, s);
  547.  
  548.     /* check for overflow */
  549.     if (strlen(buf) > MAXSCRIPT)
  550.     {
  551.         printf("cake: script too long\n");
  552.         printf("%s", buf);
  553.         exit_cake(FALSE);
  554.     }
  555.  
  556.     first_act->a_str = new_name(buf);
  557.     set_act(first_act, af_SCRIPT);
  558.     return first_act;
  559. }
  560.