home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume15 / dmake-3.6 / part06 < prev    next >
Text File  |  1990-10-14  |  41KB  |  1,213 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: dvadura@watdragon.waterloo.edu
  3. subject: v15i058: dmake version 3.6 (part 06/25)
  4. from: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 58
  8. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  9. Archive-name: dmake-3.6/part06
  10.  
  11. #!/bin/sh
  12. # this is part 6 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file rulparse.c continued
  15. #
  16. CurArch=6
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file rulparse.c"
  27. sed 's/^X//' << 'SHAR_EOF' >> rulparse.c
  28. X      * get marked as having rules and being a target if appropriate. */
  29. X     do {
  30. X        tcp->ce_flag |= tg->ce_flag & (F_RULES|F_TARGET);
  31. X        tcp = tcp->ce_all;
  32. X     }
  33. X     while( tcp != tg );
  34. X     break;
  35. X      }
  36. X   }
  37. X
  38. X   if( tflag ) Target = TRUE;
  39. X   _sv_rules   = NIL(STRING);
  40. X   _sv_crule   = NIL(STRING);
  41. X   _sv_targets = NIL(CELL);
  42. X   _sv_glb_prq = NIL(LINK);
  43. X   _sv_edgel   = NIL(EDGE);
  44. X   _sp_target  = FALSE;
  45. X   _sv_globprq_only = 0;
  46. X
  47. X   DB_VOID_RETURN;
  48. X}
  49. X
  50. X
  51. X
  52. Xint
  53. XSet_group_attributes( list )/*
  54. X==============================
  55. X    Scan list looking for the standard @ and - (as in recipe line defs)
  56. X    and set the flags accordingly so that they apply when we bind the
  57. X    rules to the appropriate targets. */
  58. Xchar *list;
  59. X{
  60. X   t_attr attr = 0;
  61. X   int done = FALSE;
  62. X   int res  = FALSE;
  63. X
  64. X   DB_ENTER( "Set_group_attributes" );
  65. X
  66. X   while( !done )
  67. X      switch( *list++ ) {
  68. X     case '@' : attr |= A_SILENT; ;break;
  69. X     case '-' : attr |= A_IGNORE; ;break;
  70. X     case '%' : attr |= A_SWAP;   ;break;
  71. X
  72. X         case ' ' :
  73. X     case '+' :
  74. X     case '\t': break;
  75. X
  76. X     case '\0': done = TRUE; break;
  77. X     case '[' : res = TRUE; break;
  78. X
  79. X     default  : done = TRUE; res = FALSE; break;
  80. X      }
  81. X
  82. X   if( res ) _sv_attr |= attr;
  83. X   DB_RETURN( res );
  84. X}
  85. X
  86. X
  87. X
  88. Xstatic void
  89. X_do_special( special, op, attr, set_dir, target, prereq, state )/*
  90. X==================================================================
  91. X   Process a special target.  So far the only special targets we have
  92. X   are those recognized by the _is_special function.
  93. X
  94. X   target is always only a single special target.
  95. X   
  96. X   NOTE:  For the cases of .IMPORT, and .INCLUDE, the cells created by the
  97. X         parser are never freed.  This is due to the fact that it is too much
  98. X      trouble to get them out of the hash table once they are defined, and
  99. X      if they are per chance used again it will be ok, anyway, since the
  100. X      cell is not really used by the code below.  */
  101. X
  102. Xint    special;
  103. Xint    op;
  104. Xt_attr    attr;
  105. Xchar    *set_dir;
  106. XCELLPTR target;
  107. XCELLPTR prereq;
  108. Xint     *state;
  109. X{
  110. X   HASHPTR    hp;        /* pointer to macro def cell        */
  111. X   CELLPTR    cp;        /* temporary pointer into cells list    */
  112. X   CELLPTR     dp;        /* pointer to directory dir cell    */
  113. X   LINKPTR     lp;        /* pointer at prerequisite list     */
  114. X   char        *dir;        /* current dir to prepend        */
  115. X   char        *path;        /* resulting path to try to read    */
  116. X   char     *name;        /* File name for processing a .INCLUDE    */
  117. X   char        *tmp;        /* temporary string pointer        */
  118. X   FILE     *fil;        /* File descriptor returned by Openfile    */
  119. X
  120. X   DB_ENTER( "_do_special" );
  121. X
  122. X   target->ce_flag = F_SPECIAL;    /* mark the target as special */
  123. X
  124. X   switch( special ) {
  125. X      case ST_EXPORT:
  126. X     for( ; prereq != NIL(CELL); prereq = prereq->ce_link ) {
  127. X        DB_PRINT( "par", ("Exporting [%s]", prereq->CE_NAME) );
  128. X        hp = GET_MACRO( prereq->CE_NAME );
  129. X
  130. X        if( hp != NIL(HASH) ) {
  131. X           char *tmpstr = hp->ht_value;
  132. X
  133. X           if( tmpstr == NIL(char) ) tmpstr = "";
  134. X
  135. X           if( Write_env_string( prereq->CE_NAME, tmpstr ) != 0 )
  136. X          Warning( "Could not export %s", prereq->CE_NAME );
  137. X        }
  138. X     }
  139. X     break;
  140. X
  141. X      case ST_IMPORT:
  142. X     if( prereq != NIL(CELL) && prereq->ce_link == NIL(CELL) &&
  143. X         strcmp(prereq->CE_NAME, ".EVERYTHING") == 0 )
  144. X     {
  145. X        ReadEnvironment();
  146. X     }
  147. X     else {
  148. X        char *tmpstr;
  149. X
  150. X        for( ; prereq != NIL(CELL); prereq = prereq->ce_link ) {
  151. X           DB_PRINT( "par", ("Importing [%s]", prereq->CE_NAME) );
  152. X
  153. X           tmpstr = Read_env_string( prereq->CE_NAME );
  154. X
  155. X           if( tmpstr != NIL(char) )
  156. X          Def_macro( prereq->CE_NAME, tmpstr, M_EXPANDED | M_LITERAL );
  157. X           else
  158. X              if( !((Glob_attr | attr) & A_IGNORE) )
  159. X             Fatal( "Imported macro `%s' not found", prereq->CE_NAME );
  160. X        }
  161. X
  162. X        attr &= ~A_IGNORE;
  163. X     }
  164. X     break;
  165. X
  166. X      case ST_INCLUDE:
  167. X      {
  168. X     int ignore = (((Glob_attr | attr) & A_IGNORE) != 0);
  169. X     int pushed = FALSE;
  170. X     CELL inc;
  171. X     HASH hcell;
  172. X
  173. X     if( prereq == NIL(CELL) )  Fatal( "No .INCLUDE file(s) specified" );
  174. X
  175. X     dp = Def_cell( ".INCLUDEDIRS", NIL(CELL) );
  176. X
  177. X     if( (attr & A_SETDIR) && *(dir = strchr(set_dir, '=')+1) ) {
  178. X        hcell.ht_name = ".INCLUDE";
  179. X        inc.ce_name   = &hcell;
  180. X        inc.ce_dir    = dir;
  181. X        pushed = Push_dir( &inc, ignore );
  182. X     }
  183. X
  184. X     for( cp=prereq; cp != NIL(CELL); cp = cp->ce_link ) {
  185. X        name = cp->CE_NAME;
  186. X        
  187. X        if( *name == '<' ) {
  188. X           /* We have a file name enclosed in <....>
  189. X            * so get rid of the <> arround the file name */
  190. X
  191. X           name++;
  192. X           if( (tmp = strrchr( name, '>' )) != NIL( char ) )
  193. X          *tmp = 0;
  194. X
  195. X           if( If_root_path( name ) )
  196. X              fil = Openfile( name, FALSE );
  197. X           else
  198. X          fil = NIL(FILE);
  199. X        }
  200. X        else
  201. X           fil = Openfile( name, FALSE );
  202. X           
  203. X        if( fil == NIL(FILE) ) {    /*if true ==> not found in current dir*/
  204. X           /* Now we must scan the list of prerequisites for .INCLUDEDIRS
  205. X            * looking for the file in each of the specified directories.
  206. X        * if we don't find it then we issue an error.  The error
  207. X        * message is suppressed if the .IGNORE attribute of attr is
  208. X        * set.  If a file is found we call Parse on the file to
  209. X        * perform the parse and then continue on from where we left
  210. X        * off.  */
  211. X
  212. X           if( (dp->CE_HOW != NIL(HOW)) &&
  213. X           ((lp = dp->CE_HOW->hw_prq) != NIL(LINK)) )
  214. X          for(; lp != NIL(LINK) && fil == NIL(FILE); lp=lp->cl_next) {
  215. X             dir  = lp->cl_prq->CE_NAME;
  216. X             if( strchr(dir, '$') ) dir = Expand(dir);
  217. X             path = Build_path( dir, name );
  218. X
  219. X             DB_PRINT( "par", ("Trying to include [%s]", path) );
  220. X
  221. X             fil = Openfile( path, FALSE );
  222. X             if( dir != lp->cl_prq->CE_NAME ) FREE(dir);
  223. X          }
  224. X        }
  225. X
  226. X        if( fil != NIL(FILE) )
  227. X           Parse( fil );
  228. X        else if( !((Glob_attr | attr) & A_IGNORE) )
  229. X           Fatal( "Include file %s, not found", name );
  230. X     }
  231. X
  232. X     if( pushed ) Pop_dir(FALSE);
  233. X     attr &= ~(A_IGNORE|A_SETDIR);
  234. X      }
  235. X      break;
  236. X     
  237. X      case ST_SOURCE:
  238. X      /* case ST_SUFFIXES: */
  239. X           if( prereq != NIL(CELL) )
  240. X        _do_targets( op & (R_OP_CL | R_OP_MI | R_OP_UP), attr, set_dir,
  241. X             target, prereq );
  242. X     else {
  243. X        /* The old semantics of .SOURCE were that an empty list of
  244. X         * prerequisites clears the .SOURCE list.  So we must implement
  245. X         * that here as a clearout prerequisite operation.  Since this is
  246. X         * a standard operation with the :- opcode we can simply call the
  247. X         * proper routine with the target cell and it should do the trick
  248. X         */
  249. X
  250. X        if( op == R_OP_CL || (op & R_OP_MI) )
  251. X           Clear_prerequisites( target->CE_HOW );
  252. X     }
  253. X
  254. X     op &= ~(R_OP_MI | R_OP_UP);
  255. X     break;
  256. X
  257. X      case ST_REST:
  258. X         /* The rest of the special targets can all take rules, as such they
  259. X      * must be able to affect the state of the parser. */
  260. X
  261. X     {
  262. X        int s_targ = Target;
  263. X
  264. X        Target     = TRUE;
  265. X        _sp_target = TRUE;
  266. X        *state     = _do_targets( op, attr, set_dir, target, prereq );
  267. X        Target     = s_targ;
  268. X
  269. X        set_dir = NIL( char );
  270. X        attr    = A_DEFAULT;
  271. X        op      = R_OP_CL;
  272. X     }
  273. X     break;
  274. X
  275. X      default:break;
  276. X   }
  277. X      
  278. X   if( set_dir != NIL(char) ) FREE( set_dir );
  279. X   if( op   != R_OP_CL   ) Warning( "Modifier(s) for operator ignored" );
  280. X   if( attr != A_DEFAULT ) Warning( "Extra attributes ignored" );
  281. X
  282. X   DB_VOID_RETURN;
  283. X}
  284. X
  285. X
  286. X
  287. Xstatic int
  288. X_do_targets( op, attr, set_dir, targets, prereq )/*
  289. X================================================= */
  290. Xint    op;
  291. Xt_attr    attr;
  292. Xchar    *set_dir;
  293. XCELLPTR targets;
  294. XCELLPTR prereq;
  295. X{
  296. X   CELLPTR    tg1;        /* temporary target pointer        */
  297. X   CELLPTR    tp1;        /* temporary prerequisite pointer    */
  298. X   char        *p;        /* temporary char pointer        */
  299. X   CELLPTR      prev_cell;    /* pointer for .UPDATEALL processing    */
  300. X   int        update;        /* A_UPDATEALL attribute flag        */
  301. X   int        smagic = 0;    /* collective amount of magic :-)    */
  302. X
  303. X   DB_ENTER( "_do_targets" );
  304. X
  305. X   if( update = ((attr & A_UPDATEALL) != 0) )
  306. X      if( targets == NIL(CELL) )
  307. X        Fatal( ".UPDATEALL attribute requires non-empty list of targets" );
  308. X
  309. X   prev_cell = NIL(CELL);
  310. X   for( tg1 = targets; tg1 != NIL(CELL); tg1 = tg1->ce_link ) {
  311. X      /* Check each target.  Check for inconsistencies between :: and : rule
  312. X       * sets.  :: may follow either : or :: but not the reverse.  We allocate
  313. X       * a HOW cell for each target that we see, if it already does not have
  314. X       * one.  If it has a HOW cell then we use it, unless the current
  315. X       * operator is ::, in which case we must allocate a new one. */
  316. X
  317. X      int magic  = (tg1->ce_flag & F_PERCENT) && !(tg1->ce_flag & F_MAGIC);
  318. X      smagic |= magic;
  319. X
  320. X      if( !(op & R_OP_DCL ) && (tg1->ce_flag & F_MULTI) && !magic )
  321. X     Fatal( "Inconsistency in inference rules for %s", tg1->CE_NAME );
  322. X
  323. X      if( magic )
  324. X         do {
  325. X        _build_graph( op, tg1, prereq );
  326. X        if( prereq != NIL(CELL) ) prereq = prereq->ce_link;
  327. X     } while( prereq != NIL(CELL) );
  328. X      else if( !(tg1->ce_flag & F_SPECIAL) && 
  329. X        (p = _is_magic( tg1->CE_NAME )) != NIL(char) )
  330. X         smagic |= _do_magic( op, p, tg1, prereq, attr, set_dir );
  331. X      else if( op & R_OP_DCL ) {
  332. X     HOWPTR hp;
  333. X
  334. X     TALLOC( hp, 1, HOW );
  335. X
  336. X     hp->hw_next   = tg1->CE_HOW;
  337. X     tg1->CE_HOW   = hp;
  338. X     tg1->ce_flag |= F_MULTI;
  339. X      }
  340. X      else if( tg1->CE_HOW == NIL(HOW) )
  341. X     TALLOC( tg1->CE_HOW, 1, HOW );
  342. X
  343. X      if( !magic ) _set_attributes( attr, set_dir, tg1 );
  344. X
  345. X      if( update ) {
  346. X     if( smagic ) Fatal( ".UPDATEALL attribute not legal in meta rule" );
  347. X
  348. X     /* Check this as it would break another cirlcular .UPATEALL list if
  349. X      * we blindly assign it and it is part of another list already. */
  350. X     if( tg1->ce_all != NIL(CELL) )
  351. X        Fatal( "Target [%s] appears on multiple .UPDATEALL lists" );
  352. X
  353. X     tg1->ce_all = prev_cell;
  354. X     prev_cell = tg1;
  355. X      }
  356. X
  357. X      /* Build the proper prerequisite list of the target.  If the `-',
  358. X       * modifier was used clear the prerequisite list before adding any
  359. X       * new prerequisites.  Else add them to the head/tail as appropriate.
  360. X       *
  361. X       * If the target has F_PERCENT set then no prerequisites are used. */
  362. X
  363. X      if( !(tg1->ce_flag & F_PERCENT) )
  364. X     if( tg1 == targets || !update ) {
  365. X        register HOWPTR  how  = tg1->CE_HOW;
  366. X
  367. X        if( op & R_OP_MI ) Clear_prerequisites( how );
  368. X
  369. X        if( (op & R_OP_UP) && (how->hw_prq != NIL(LINK)) )
  370. X           _stick_at_head( how, prereq );
  371. X        else
  372. X           for( tp1=prereq; tp1 != NIL(CELL); tp1 = tp1->ce_link )
  373. X          Add_prerequisite( how, tp1, FALSE );
  374. X     }
  375. X      else
  376. X         if( op & (R_OP_MI | R_OP_UP) )
  377. X        Warning( "Modifier(s) `^!' for ':' operator ignored" );
  378. X   }
  379. X
  380. X   if( targets != NIL(CELL) ) targets->ce_all = prev_cell;
  381. X
  382. X
  383. X   /* Check to see if we have NO targets but some attributes.  IF so then
  384. X    * apply all of the attributes to the complete list of prerequisites.
  385. X    * Cannot happen for F_PERCENT targets. (ie. in that case targets is always
  386. X    * not NIL) */
  387. X
  388. X   if( (targets == NIL(CELL)) && attr )
  389. X      if( prereq != NIL(CELL) )
  390. X     for( tp1=prereq; tp1 != NIL(CELL); tp1 = tp1->ce_link ) {
  391. X        if( tp1->CE_HOW == NIL(HOW) ) TALLOC( tp1->CE_HOW, 1, HOW );
  392. X        _set_attributes( attr, set_dir, tp1 );
  393. X     }
  394. X      else
  395. X     _set_global_attr( attr, set_dir );
  396. X
  397. X   /* Fix up the HOW pointers for the A_UPDATEALL case, they should all point
  398. X    * to the same cell (targets->CE_HOW), if the .UPDATEALL attribute is given
  399. X    */
  400. X   if( update && targets != NIL(CELL) )
  401. X      for( tg1=targets->ce_link; tg1 != NIL(CELL); tg1 = tg1->ce_link ) {
  402. X     FREE(tg1->CE_HOW);
  403. X     tg1->CE_HOW = targets->CE_HOW;
  404. X      }
  405. X
  406. X   /* Now that we have built the lists of targets, the parser must parse the
  407. X    * rules if there are any.  However we must start the rule list with the
  408. X    * rule specified as via the ; kludge, if there is one */
  409. X
  410. X   _sv_targets = targets;
  411. X   _sv_attr    = _sv_attro = attr;
  412. X   _sv_flag    = ((op & R_OP_BG) ? F_SINGLE : F_DEFAULT);
  413. X      
  414. X   DB_RETURN( RULE_SCAN );
  415. X}
  416. X
  417. X
  418. Xstatic int
  419. X_do_magic( op, dot, target, prereq, attr, set_dir )/*
  420. X=====================================================
  421. X   This function takes a magic target of the form .<chars>.<chars> or
  422. X   .<chars> and builds the appropriate % rules for that target.
  423. X   
  424. X   The function builds the % rule, `%.o : %.c'  from .c.o, and
  425. X   `%.a :' from .a */
  426. X
  427. Xint    op;
  428. Xchar    *dot;
  429. XCELLPTR target;
  430. XCELLPTR prereq;
  431. Xt_attr  attr;
  432. Xchar    *set_dir;
  433. X{
  434. X   CELLPTR tg;
  435. X   CELLPTR prq;
  436. X   char    *tmp, *tmp2;
  437. X
  438. X   DB_ENTER( "_do_magic" );
  439. X
  440. X   if( prereq != NIL(CELL) )
  441. X      Warning( "Ignoring prerequisites of old style meta-target" );
  442. X
  443. X   op &= (R_OP_CL | R_OP_DCL);
  444. X
  445. X   if( dot == target->CE_NAME )    {        /* its of the form .a    */
  446. X      tg  = Def_cell( "%", NIL(CELL) );        /* ==> no prerequisite  */
  447. X      tmp = _build_meta( target->CE_NAME );
  448. X      prq = Def_cell( tmp, NIL(CELL) );
  449. X      FREE( tmp );
  450. X
  451. X      _build_graph( op, tg, prq );
  452. X   }
  453. X   else {
  454. X      tmp = _build_meta( dot );
  455. X      tg  = Def_cell( tmp, NIL(CELL) );
  456. X      FREE( tmp );
  457. X
  458. X      tmp = _build_meta( tmp2 = _substr( target->CE_NAME, dot ) );
  459. X      prq = Def_cell( tmp, NIL(CELL) );
  460. X      FREE( tmp  );
  461. X      FREE( tmp2 );
  462. X
  463. X      _build_graph( op, tg, prq );
  464. X   }
  465. X
  466. X   tg->ce_flag      |= F_PERCENT;
  467. X   target->ce_flag  |= (tg->ce_flag & (F_MULTI | F_PERCENT)) | F_MAGIC;
  468. X   target->CE_EDGES  = tg->CE_EDGES;
  469. X
  470. X   _set_attributes( attr, set_dir, tg );
  471. X
  472. X   DB_RETURN(1);
  473. X}
  474. X
  475. X
  476. X
  477. Xstatic char *
  478. X_build_meta( name )/*
  479. X=====================
  480. X   Check to see if the name is of the form .c~ if so and if Augmake
  481. X   translation is enabled then return s.%.c, else return %.suff, where if the
  482. X   suffix ends in '~' then leave it be.*/
  483. Xchar *name;
  484. X{
  485. X   char *tmp;
  486. X   int  test = Augmake ? name[strlen(name)-1] == '~' : 0;
  487. X
  488. X   tmp = _strjoin( test ? "s.%" : "%", name, -1, FALSE);
  489. X   if( test ) tmp[ strlen(tmp)-1 ] = '\0';
  490. X
  491. X   return(tmp);
  492. X}
  493. X
  494. X
  495. X
  496. Xstatic void
  497. X_build_graph( op, target, prereq )/*
  498. X====================================
  499. X   This function is called to build the graph for the % rule given by
  500. X   target : prereq cell combination.  This function assumes that target
  501. X   is a % target and that prereq is a single % prerequisite.  op can be
  502. X   either R_OP_CL or R_OP_DCL, all other operations are ignored.
  503. X   
  504. X   It also assumes that target cell has F_PERCENT set already. */
  505. Xint op;
  506. XCELLPTR target;
  507. XCELLPTR prereq;
  508. X{
  509. X   int      match;
  510. X   EDGEPTR  edge;
  511. X
  512. X   DB_ENTER( "_build_graph" );
  513. X   DB_PRINT( "%", ("Building graph for [%s : %s]", target->CE_NAME,
  514. X            (prereq == NIL(CELL)) ? "" : prereq->CE_NAME) );
  515. X
  516. X   if( prereq != NIL(CELL) ) {
  517. X      char *name = prereq->CE_NAME;
  518. X      int   len  = strlen(name);
  519. X
  520. X      if( *name == '\'' && name[len-1]=='\'' ){
  521. X     _add_global_prereq( prereq );
  522. X     name[len-1] = '\0';
  523. X     strcpy(name, name+1);
  524. X     DB_VOID_RETURN;
  525. X      }
  526. X   }
  527. X
  528. X   /* The list of edges is kept as a circular list.  Thus we must find the
  529. X    * last edge if we are to add a new edge.  Also we must check the list to
  530. X    * find out if a new edge needs to be added. */
  531. X
  532. X   match = FALSE;
  533. X   if( (edge = target->CE_EDGES) != NIL(EDGE) ) {
  534. X      EDGEPTR start;
  535. X
  536. X      start = edge;
  537. X      do {
  538. X     DB_PRINT( "%", ("Trying to match [%s]", edge->ed_prq->CE_NAME) );
  539. X
  540. X         if( edge->ed_prq == prereq )
  541. X        match = TRUE;
  542. X     else
  543. X        edge  = edge->ed_next;
  544. X      }
  545. X      while ( !match && start != edge );
  546. X   }
  547. X
  548. X   if( match ) {
  549. X      /* match is TRUE hence, we found an edge joining the target and the
  550. X       * prerequisite so set the current target's CE_EDGES pointer to point
  551. X       * at the edge we found and make sure the new edge has a valid HOW
  552. X       * pointer. */
  553. X
  554. X      DB_PRINT( "%", ("It's an old edge") );
  555. X
  556. X      target->CE_EDGES = edge;
  557. X
  558. X      if( op & R_OP_DCL ) {
  559. X         HOWPTR hp;
  560. X
  561. X     TALLOC( hp, 1, HOW );
  562. X
  563. X     hp->hw_next   = edge->ed_how;
  564. X     edge->ed_how  = hp;
  565. X      }
  566. X      else {
  567. X     HOWPTR hp = edge->ed_how;
  568. X
  569. X     hp->hw_flag = F_DEFAULT;
  570. X     hp->hw_attr = A_DEFAULT;
  571. X     target->ce_dir    = NIL(char);
  572. X     target->ce_flag  &= (F_PERCENT|F_MAGIC);
  573. X     target->ce_attr  &= A_NOINFER;
  574. X      }
  575. X    
  576. X   }
  577. X   else {
  578. X      EDGEPTR tedge;
  579. X
  580. X      TALLOC( tedge, 1, EDGE );
  581. X
  582. X      if( edge == NIL(EDGE) ) {
  583. X     DB_PRINT( "%", ("It's a new edge") );
  584. X     edge = tedge;
  585. X     target->CE_EDGES = edge->ed_next = edge;
  586. X      }
  587. X      else {
  588. X     DB_PRINT( "%", ("It's a new edge (non-empty edge list)") );
  589. X     tedge->ed_next   = edge->ed_next;
  590. X     edge->ed_next    = tedge;
  591. X     target->CE_EDGES = edge = tedge;
  592. X      }
  593. X
  594. X      /* This was a new edge so we must point it's prerequisite pointer at the
  595. X       * prerequisite, and add the first HOW cell.
  596. X       * Since this is also the first time we have seen the % target we
  597. X       * add it to the NFA we are building of % rule targets. */
  598. X
  599. X      TALLOC( edge->ed_how, 1, HOW );
  600. X
  601. X      edge->ed_prq = prereq;
  602. X      edge->ed_tg  = target;
  603. X
  604. X      if( !(target->ce_flag & F_DFA) ) {
  605. X     Add_nfa( target->CE_NAME );
  606. X     target->ce_flag |= F_DFA;
  607. X      }
  608. X
  609. X      if( op & R_OP_DCL ) target->ce_flag |= F_MULTI;
  610. X   }
  611. X
  612. X   edge->ed_link = _sv_edgel;
  613. X   _sv_edgel = edge;
  614. X   _sv_globprq_only = 0;
  615. X
  616. X   DB_VOID_RETURN;
  617. X}
  618. X
  619. X
  620. X
  621. Xstatic void
  622. X_add_global_prereq( pq )/*
  623. X==========================
  624. X    Prerequisite is a non-% prerequisite for a %-rule target, add it to
  625. X    the target's list of global prerequsites to add on match */
  626. XCELLPTR pq;
  627. X{
  628. X   register LINKPTR ln;
  629. X
  630. X   TALLOC( ln, 1, LINK );
  631. X   ln->cl_next = _sv_glb_prq;
  632. X   ln->cl_prq  = pq;
  633. X   _sv_glb_prq = ln;
  634. X}
  635. X
  636. X
  637. X
  638. Xstatic void
  639. X_set_attributes( attr, set_dir, cell )/*
  640. X=============================================
  641. X    Set the appropriate attributes for a cell */
  642. Xt_attr    attr;
  643. Xchar    *set_dir;
  644. XCELLPTR cell;
  645. X{
  646. X   char   *dir;
  647. X
  648. X   DB_ENTER( "_set_attributes" );
  649. X
  650. X   /* If .SETDIR attribute is set then we have at least .SETDIR= in the
  651. X    * set_dir string.  So go and fishout what is at the end of the =.
  652. X    * If not set and not NULL then propagate it to the target cell. */
  653. X
  654. X   if( attr & A_SETDIR ) {
  655. X      dir = strchr( set_dir, '=' ) + 1;
  656. X
  657. X      if( cell->ce_attr & A_SETDIR )
  658. X     Warning( "Multiple .SETDIR for %s ignored", cell->CE_NAME );
  659. X      else
  660. X     if( *dir ) cell->ce_dir = dir;
  661. X   }
  662. X   cell->ce_attr |= attr;        /* set rest of attributes for target */
  663. X
  664. X   DB_VOID_RETURN;
  665. X}
  666. X
  667. X
  668. X
  669. Xstatic void
  670. X_set_global_attr( attr, dir )/*
  671. X===============================
  672. X    Handle the setting of the global attribute functions based on
  673. X    The attribute flags set in attr.  Note we set the dir path name
  674. X    to be the value of Start_dir.  If Start_dir is initially set
  675. X    Make will CD to that directory before making any targets. */
  676. Xt_attr attr;
  677. Xchar   *dir;
  678. X{
  679. X   int flag;
  680. X
  681. X   /* Some compilers can't handle a switch on a long, and t_attr is now a long
  682. X    * integer on some systems.  foey! */
  683. X   for( flag = MAX_ATTR; flag; flag >>= 1 )
  684. X      if( flag & attr )
  685. X     if( flag == A_PRECIOUS)      Def_macro(".PRECIOUS",  "y", M_EXPANDED);
  686. X     else if( flag == A_SILENT)   Def_macro(".SILENT",    "y", M_EXPANDED);
  687. X     else if( flag == A_IGNORE )  Def_macro(".IGNORE",    "y", M_EXPANDED);
  688. X     else if( flag == A_EPILOG )  Def_macro(".EPILOG",    "y", M_EXPANDED);
  689. X     else if( flag == A_PROLOG )  Def_macro(".PROLOG",    "y", M_EXPANDED);
  690. X     else if( flag == A_NOINFER ) Def_macro(".NOINFER",   "y", M_EXPANDED);
  691. X     else if( flag == A_SEQ )     Def_macro(".SEQUENTIAL","y", M_EXPANDED);
  692. X     else if( flag == A_SHELL )   Def_macro(".USESHELL",  "y", M_EXPANDED);
  693. X     else if( flag == A_MKSARGS ) Def_macro(".MKSARGS",   "y", M_EXPANDED);
  694. X     else if( flag == A_SWAP )    Def_macro(".SWAP",      "y", M_EXPANDED);
  695. X     else if( flag == A_SETDIR ) {
  696. X        dir = strchr( dir, '=' ) + 1;
  697. X        if( *dir ) Start_dir.ce_dir = dir;
  698. X     }
  699. X   
  700. X   attr &= ~A_GLOB;
  701. X   if( attr ) Warning( "Non global attribute(s) ignored" );
  702. X}
  703. X
  704. X
  705. X
  706. Xstatic void
  707. X_stick_at_head( how, pq )/*
  708. X===========================
  709. X    Add the prerequisite list to the head of the existing prerequisite
  710. X    list */
  711. X
  712. XHOWPTR  how;        /* HOW cell for target node    */
  713. XCELLPTR pq;        /* list of prerequisites to add */
  714. X{
  715. X   DB_ENTER( "_stick_at_head" );
  716. X
  717. X   if( pq->ce_link != NIL(CELL) ) _stick_at_head( how, pq->ce_link );
  718. X   Add_prerequisite( how, pq, TRUE );
  719. X
  720. X   DB_VOID_RETURN;
  721. X}
  722. X
  723. X
  724. X
  725. Xstatic t_attr
  726. X_is_attribute( name )/*
  727. X=======================
  728. X   Check the passed name against the list of valid attributes and return the
  729. X   attribute index if it is, else return 0, indicating the name is not a valid
  730. X   attribute.  The present attributes are defined in dmake.h as A_xxx #defines,
  731. X   with the corresponding makefile specification:  (note they must be named
  732. X   exactly as defined below)
  733. X   
  734. X   Valid attributes are:  .IGNORE, .SETDIR=, .SILENT, .PRECIOUS, .LIBRARY,
  735. X                          .EPILOG, .PROLOG,  .LIBRARYM, .SYMBOL, .UPDATEALL,
  736. X              .USESHELL, .NOINFER
  737. X
  738. X   NOTE:  The strcmp's are OK since at most three are ever executed for any
  739. X          one attribute check, and that happens only when we can be fairly
  740. X          certain we have an attribute.  */
  741. Xchar *name;
  742. X{
  743. X   t_attr attr = 0;
  744. X   
  745. X   DB_ENTER( "_is_attribute" );
  746. X   
  747. X   if( *name++ == '.' )
  748. X      switch( *name )
  749. X      {
  750. X         case 'E': attr = (strcmp(name, "EPILOG"))   ? 0 : A_EPILOG;  break;
  751. X         case 'I': attr = (strcmp(name, "IGNORE"))   ? 0 : A_IGNORE;  break;
  752. X         case 'L': attr = (strcmp(name, "LIBRARY"))  ? 0 : A_LIBRARY; break;
  753. X         case 'M': attr = (strcmp(name, "MKSARGS"))  ? 0 : A_MKSARGS; break;
  754. X         case 'N': attr = (strcmp(name, "NOINFER"))  ? 0 : A_NOINFER; break;
  755. X
  756. X         case 'U':
  757. X        if( !strcmp(name, "UPDATEALL") )    attr = A_UPDATEALL;
  758. X        else if( !strcmp(name, "USESHELL")) attr = A_SHELL;
  759. X        else attr = 0;
  760. X        break;
  761. X
  762. X         case 'P':
  763. X            if( !strcmp(name, "PRECIOUS") )     attr = A_PRECIOUS;
  764. X            else if( !strcmp(name, "PROLOG") )  attr = A_PROLOG;
  765. X            else attr = 0;
  766. X            break;
  767. X
  768. X         case 'S':
  769. X            if( !strncmp(name, "SETDIR=", 7) )    attr = A_SETDIR;
  770. X            else if( !strcmp(name, "SILENT") )    attr = A_SILENT;
  771. X            else if( !strcmp(name, "SYMBOL") )    attr = A_SYMBOL;
  772. X            else if( !strcmp(name, "SEQUENTIAL")) attr = A_SEQ;
  773. X            else if( !strcmp(name, "SWAP"))       attr = A_SWAP;
  774. X            else attr = 0;
  775. X            break;
  776. X      }
  777. X
  778. X   DB_RETURN( attr );
  779. X}
  780. X
  781. X
  782. X
  783. Xstatic int
  784. X_is_special( tg )/*
  785. X===================
  786. X   This function returns TRUE if the name passed in represents a special
  787. X   target, otherwise it returns false.  A special target is one that has
  788. X   a special meaning to dmake, and may require processing at the time that
  789. X   it is parsed.
  790. X   
  791. X   Current Special targets are:
  792. X    .GROUPPROLOG    .GROUPEPILOG    .INCLUDE    .IMPORT
  793. X    .EXPORT        .SOURCE     .SUFFIXES    .ERROR
  794. X    .INCLUDEDIRS    .MAKEFILES    .REMOVE
  795. X*/
  796. Xchar *tg;
  797. X{
  798. X   DB_ENTER( "_is_special" );
  799. X   
  800. X   if( *tg++ != '.' ) DB_RETURN( 0 );
  801. X   
  802. X   switch( *tg )
  803. X   {
  804. X      case 'I':
  805. X         if( !strcmp( tg, "IMPORT" ) )        DB_RETURN( ST_IMPORT   );
  806. X         else if( !strcmp( tg, "INCLUDE" ) )    DB_RETURN( ST_INCLUDE  );
  807. X     else if( !strcmp( tg, "INCLUDEDIRS" )) DB_RETURN( ST_REST     );
  808. X     break;
  809. X      
  810. X      case 'M':
  811. X         if( !strcmp( tg, "MAKEFILES" ) )    DB_RETURN( ST_REST     );
  812. X     break;
  813. X
  814. X      case 'E':
  815. X         if( !strcmp( tg, "ERROR" ) )        DB_RETURN( ST_REST     );
  816. X         else if( !strcmp( tg, "EXPORT" ) )    DB_RETURN( ST_EXPORT   );
  817. X     break;
  818. X
  819. X      case 'G':
  820. X     if( !strcmp( tg, "GROUPPROLOG" ))      DB_RETURN( ST_REST     );
  821. X     else if( !strcmp( tg, "GROUPEPILOG" )) DB_RETURN( ST_REST     );
  822. X     break;
  823. X
  824. X      case 'R':
  825. X         if( !strcmp( tg, "REMOVE" ) )        DB_RETURN( ST_REST     );
  826. X     break;
  827. X
  828. X      case 'S':
  829. X         if( !strncmp( tg, "SOURCE", 6 ) )    DB_RETURN( ST_SOURCE   );
  830. X         else if( !strncmp(tg, "SUFFIXES", 8 )) DB_RETURN( ST_SOURCE   );
  831. X     break;
  832. X   }
  833. X   
  834. X   DB_RETURN( 0 );
  835. X}
  836. X
  837. X
  838. X
  839. Xstatic int
  840. X_is_percent( np )/*
  841. X===================
  842. X    return TRUE if np points at a string containing a % sign */
  843. Xchar *np;
  844. X{
  845. X   return( (strchr(np,'%') && (*np != '\'' && np[strlen(np)-1] != '\'')) ?
  846. X       TRUE : FALSE );
  847. X}
  848. X
  849. X
  850. Xstatic char *
  851. X_is_magic( np )/*
  852. X=================
  853. X    return TRUE if np points at a string of the form
  854. X          .<chars>.<chars>  or  .<chars>
  855. X    where chars are only alpha characters.
  856. X
  857. X        NOTE:  reject target if it begins with ./ or ../ */
  858. Xchar *np;
  859. X{
  860. X   register char *n;
  861. X
  862. X   n = np;
  863. X   if( *n != '.' ) return( NIL(char) );
  864. X   if (strchr(DirBrkStr, *(n+1))!=NULL || *(n+1) == '.' )
  865. X      return (NIL(char));
  866. X
  867. X   for( n++; isgraph(*n) && (*n != '.'); n++ );
  868. X
  869. X   if( *n != '\0' ) {
  870. X      if( *n != '.' )  return( NIL(char) );
  871. X      for( np = n++; isgraph( *n ) && (*n != '.'); n++ );
  872. X      if( *n != '\0' ) return( NIL(char) );
  873. X   }
  874. X   else if( !Augmake )
  875. X      return( NIL(char) );
  876. X
  877. X   /* np points at the second . of .<chars>.<chars> string.
  878. X    * if the special target is of the form .<chars> then np points at the
  879. X    * first . in the token. */
  880. X
  881. X   return( np );
  882. X}
  883. X
  884. SHAR_EOF
  885. echo "File rulparse.c is complete"
  886. chmod 0440 rulparse.c || echo "restore of rulparse.c fails"
  887. echo mkdir - readme
  888. mkdir readme
  889. echo "x - extracting readme/release (Text)"
  890. sed 's/^X//' << 'SHAR_EOF' > readme/release &&
  891. Xdmake Version 3.6
  892. X=================
  893. X
  894. XMANDATORY REPLACEMENT FOR VERSION 3.5 PATCH LEVEL 1 and PATCH LEVEL 2
  895. X
  896. XNature:   This version of dmake MUST replace all versions of dmake 3.5 patch
  897. X-------   levels 1 and 2, and all versions of dmake 3.5 patch level 1 and 2
  898. X      must then be DELETED.  This release addresses several issues.
  899. X
  900. X        1. Copyright infringement claim made by MKS, of Waterloo.
  901. X        2. Modifications to text diversion processing.
  902. X        3. Support for DOS Swapping, and MKS argument passing.
  903. X        4. Other minor nits and tweaks.
  904. X
  905. X      This distribution advances dmake to Version 3.6, patch level 1.  This
  906. X      version is certified free of MKS copyrighted code.  See below for
  907. X      details.
  908. X          
  909. XAvailability:
  910. X-------------
  911. X      dmake is available via anonymous ftp from watmsg.uwaterloo.edu
  912. X      (129.97.129.9) as:
  913. X
  914. X         pub/src/dmake-3.6.tar.Z
  915. X         pub/src/dmake-3.6.zoo 
  916. X
  917. X      and comes in either a compressed tar or zoo archive take your pick.
  918. X
  919. XAcknowledgements:
  920. X-----------------
  921. X      Thanks to all who submitted code for new features, suggestions for
  922. X      improvements, and bug fixes.  Special thanks to those who helped
  923. X      test this version of dmake on the many platforms that the
  924. X      distribution now supports.  I have tried to make sure no gotchas
  925. X      remain, if you encounter problems installing or running dmake please
  926. X      let me know.  As always, I am always happy to receive e-mail.
  927. X
  928. X
  929. XDETAILS OF CHANGES:
  930. X===================
  931. X
  932. XMKS Copyright Infringement:
  933. X---------------------------
  934. X   Due to a misunderstanding over past contractual obligations between
  935. X   myself and Mortice Kern Systems of Waterloo, Ontario, Canada (MKS),
  936. X   the original posting of dmake unitentionally contains some code
  937. X   derived from MKS proprietary code.
  938. X
  939. X   This version rectifies that situation and MUST replace all versions
  940. X   of DMAKE and DMAKE patches that have been previously distributed.
  941. X   Please delete from any archive site versions of DMAKE source code
  942. X   labeled 3.5 patch level 1 or patch level 2 and dmake 3.5 patch 1.
  943. X
  944. X   Version 3.6 of the dmake source replaces *ALL* MKS proprietary code.
  945. X   In particular, putenv.c in the bsd43 and sysvr1 directories is new.
  946. X   Three routines in percent.c;  Add_dfa, Construct_dfa, and Advance_dfa
  947. X   have been replaced.  Lastly, TEXT DIVERSION processing has been removed
  948. X   from make.c and <+...+> constructions are replaced by the $(mktmp ...)
  949. X   construct (see below for more details).  The changes relating to the
  950. X   above mentioned modifications have been reviewed by MKS and certified by
  951. X   MKS to be free of MKS proprietary code.  The note below is from MKS
  952. X   and releases dmake version 3.6 patch level 1 from any MKS copyright
  953. X   infringement claims.
  954. X
  955. X    "MKS has reviewed the latest sources, as of 90.09.20,
  956. X     for the files make.c, putenv.c, and percent.c, which
  957. X     are part of the program dmake version 3.6, and found
  958. X     these files to be free of MKS proprietary source code."
  959. X
  960. X   No functionality is lost as a result of these changes, however
  961. X   certain constructs may have to be expressed using a new syntax.  See
  962. X   the documentation and the comments below for details.
  963. X
  964. X
  965. XText Diversion Processing:
  966. X--------------------------
  967. X   As alluded to above, the <+...+> text diversion facility has been
  968. X   officially replaced by a new facility of the form $(mktmp ...) details of
  969. X   which may be found in the TEXT DIVERSION section of the documentation.
  970. X   Briefly, the construct:
  971. X
  972. X        exe:; link @<+$(OBJFILES:t"+\n")+>
  973. X
  974. X   is replaced by:
  975. X
  976. X        exe:; link @$(mktmp $(OBJFILES:t"+\n"))
  977. X
  978. X   similarly the construct:
  979. X
  980. X        all :
  981. X                echo hi <+
  982. X                line1
  983. X                line2 +>
  984. X
  985. X   is replaced by:
  986. X
  987. X        all :
  988. X                echo hi $(mktmp\
  989. X                line1\n\
  990. X                line2)
  991. X
  992. X   where the \n\ is added to the end of each line within the data portion of
  993. X   the $(mktmp ...) construction.  For a number of reasons it is my belief
  994. X   that this new construct is a better implementation of text diversions than
  995. X   the previous <+...+> as it can be used in macro expressions that appear
  996. X   anywhere in the makefile.
  997. X
  998. X   Compatibility is retained for previous versions of dmake that utilize
  999. X   a simple form of the <+...+> construct.  If your <+...+> constructs do not
  1000. X   span multiple lines (cf second example above), then the new version of
  1001. X   dmke will recognize these and will map them to the appropriate
  1002. X   $(mktmp ...) construct.  Thus, If you use <+...+> and you do not allow the
  1003. X   interior data to span multiple lines and both <+ and +> appear as clear
  1004. X   text in the same recipe line or macro value, then dmake will process these
  1005. X   correctly and the output is 100% compatible to version 3.5 patch level 2.
  1006. X   Any other use of <+...+> must be converted to the new $(mktmp ...) form.
  1007. X
  1008. X   The new form also provides for massaging the name of the temporary file
  1009. X   which replaces the text in the recipe.  See the documentation regarding
  1010. X   the special macros USESHELL, TMPFILE, and DIVSHELL.  This is of most use
  1011. X   in an MSDOS environment.
  1012. X
  1013. X
  1014. XDOS Swapping, and MKS argument passing:
  1015. X---------------------------------------
  1016. X   dmake now supports swapping the executable image to secondary storage when
  1017. X   it executes a child.  Swapping is enabled by setting the new attribute
  1018. X   .SWAP to on, either for a target or globally, or by specifying the '%'
  1019. X   modifier to a recipe line.  So for example:
  1020. X
  1021. X    xx .SWAP :; recipe
  1022. X
  1023. X   and
  1024. X
  1025. X    xx :;% recipe
  1026. X
  1027. X   are equivalent.
  1028. X
  1029. X   The MKS DOS argument passing conventions are now supported, and dmake is
  1030. X   able to communicate with programs that understand those conventions.  The
  1031. X   global variable .MKSARGS is used to enable/disable this facility.  With
  1032. X   these modifications, dmake now supports long command lines for running
  1033. X   commands that understand the MKS argument passing convention, and it does
  1034. X   not run into memory limitations when executing child processes in most
  1035. X   situations.
  1036. X
  1037. X   Both .SWAP and .MKSARGS are ignored by non-MSDOS versions of dmake.
  1038. X   See the manual page for further details.
  1039. X
  1040. X
  1041. XOther tweaks modifications and BUG FIXES:
  1042. X-----------------------------------------
  1043. X-- Slight modifications to msdos/startup.mk files.  Set DIRSEPSTR to \
  1044. X   if using command.com as the shell, otherwise set internaly to /.
  1045. X   Removed -o $@ from MSC startup.mk, and added $(ASFLAGS) to %$O : %$S
  1046. X   rule, in all default DOS startup.mk files.
  1047. X
  1048. X-- Added POSIX '+' character to start of recipe lines.  You can use this
  1049. X   to force the recipe line to be executed by a shell, in addition to the
  1050. X   test used for .SHELLMETAS.
  1051. X
  1052. X   To make the '+' fit into the dmake mold, a new attribute has been created.
  1053. X   the .USESHELL attribute forces the use of a shell for the target or
  1054. X   recipe group for which it is specified.  If it is specified as a global
  1055. X   attribute then all recipes executed will use a shell.  The macro variable
  1056. X   .USESHELL corresponds to the special target '.USESHELL :' in the same way
  1057. X   that .IGNORE corresponds to '.IGNORE :'.
  1058. X
  1059. X-- Added *= and *:= macro assignmen operator, patches from 
  1060. X   Piercarlo Grandi <pcg@compsci.aberystwyth.ac.uk>, see the documentation
  1061. X   for more details.
  1062. X
  1063. X-- Changed makefile.mk to force use of a shell (via '+') to make OBJDIR,
  1064. X   doesn't break on baren DOS systems that way :-).  Many other small changes
  1065. X   to msdos and unix versions of various config.mk files.
  1066. X
  1067. X-- Added two new macros related to diversion file processing.
  1068. X   See the TEXT DIVERSIONS section of the man page for an explanation of this
  1069. X   functionality.
  1070. X
  1071. X        TMPFILE - is set to the name of the temporary file whenever
  1072. X                  a temporary file is opened by dmake.
  1073. X        USESHELL- It's value is 'no' if the current recipe line is not forced
  1074. X          to use a shell via a '+' or .USESHELL directive.  It's
  1075. X          value is 'yes' if such a directive is given.
  1076. X    DIVFILE - is defined in startup.mk and gives a macro to use to set
  1077. X          name of the diversion file, (under UNIX, DIVFILE defaults to
  1078. X          $(TMPFILE), under MSDOS it is the value of $(TMPFILE) with
  1079. X          any / replaced by the appropriate number of \ depending, on
  1080. X          if a shell is used or not).
  1081. X
  1082. X-- \\ appearing at the end of a line does not cause a continuation to the next
  1083. X   line.
  1084. X
  1085. X-- Modified the definition of macro supplied from the command line to allow
  1086. X   macros defined using += or +:= to be modified further from within the
  1087. X   makefile.
  1088. X
  1089. X-- Added MAKETARGETS macro which contains the name of the target(s), if any,
  1090. X   specified on the command line.
  1091. X
  1092. X-- Modified Pack_argv in sysintf.c to use dynamic memory allocation rather
  1093. X   than limit it to a fixed number of arguments.
  1094. X
  1095. X-- BIG BUG FIX:
  1096. X   This one is cute.  It turns out that all individual recipe line
  1097. X   attributes supplied via '@', '-', and now '+' and '%' characters were
  1098. X   getting or'ed together and applied to ALL recipe lines of the recipe, yulk!
  1099. X
  1100. X-- BUG FIX:
  1101. X   Fixed off by one error in make.c:_print_cmnd when remapping \n after
  1102. X   printing the text.
  1103. X
  1104. X-- BUG FIX:  Bug reported by holos0!lbr@gatech.edu
  1105. X   Inferred prerequisites were not getting made when a target was found to
  1106. X   be out of date relative to a non-inferred prerequisite, and the inferred
  1107. X   prerequisite did not exist but the file it could be made from did and was
  1108. X   not out of date relative to the target.  This was a problem with the
  1109. X   following setup.
  1110. X
  1111. X        file.o : header.h
  1112. X
  1113. X   File system contains file.o, header.h and RCS/file.c,v, If file.o is newer
  1114. X   than RCS/file.c,v and older than header.h, then dmake didn't check out
  1115. X   file.c prior to doing the compile.
  1116. X
  1117. X-- BUG FIX: Applied patch from UUCP: twc@legal or ...sun!ys2!legal!twc
  1118. X   to msdos/_chdir.c to fix changing of directory in OS/2 protected mode
  1119. X
  1120. X-- BUG FIX: Applied patch from UUCP: twc@legal or ...sun!ys2!legal!twc
  1121. X   to msdos/switchar.c to read environment variable SWITCHAR instead of using
  1122. X   unsupported call in DOS.  OS/2 doesn't have _get_switchar call!  (It damn
  1123. X   well should though!  Microsoft is really dumb in this respect!)
  1124. X
  1125. X   Extended this patch to use SWITCHAR environment variable in all DOS
  1126. X   versions.  This ensures that DOS 4.0 can selectively change SWITCHAR by
  1127. X   using the environment variable.
  1128. X
  1129. X   Dmake now first gets SWITCHAR from the environment and if that fails it
  1130. X   tries the unsupported MSDOS call.  Under UNIX getswitchar returns '-'
  1131. X   as before.
  1132. X
  1133. X-- BUG FIX: Changed the line _ar.ar_size = atol(arhdr.ar_size) found in
  1134. X   ar_scan() in arlib.c to not use atol() if ASCARCH is FALSE.  I forget who
  1135. X   reported this one :-)
  1136. SHAR_EOF
  1137. chmod 0640 readme/release || echo "restore of readme/release fails"
  1138. echo "x - extracting readme/os2 (Text)"
  1139. sed 's/^X//' << 'SHAR_EOF' > readme/os2 &&
  1140. XAs shipped the DOS versions of dmake will run under OS/2 protected mode.
  1141. XI have a port that works in real mode but it was based on the DOS version.
  1142. XI would like to produce an independent OS/2 directory (cf unix) that contains
  1143. Xall necessary files to make an OS/2 version, and to boot strap it with a
  1144. Xcommand shell.  If anyone is willing to do this I will send them the OS/2
  1145. Xmods that need to be made.
  1146. SHAR_EOF
  1147. chmod 0640 readme/os2 || echo "restore of readme/os2 fails"
  1148. echo "x - extracting readme/msdos (Text)"
  1149. sed 's/^X//' << 'SHAR_EOF' > readme/msdos &&
  1150. XSome notes on the MSDOS implementation of dmake.
  1151. X
  1152. XMaking the binary:
  1153. X------------------
  1154. X
  1155. X   Turbo-C:  By default the turbo-C (make tcc) script will make a version
  1156. X         of the binary that is compiled for an 8088 and up cpu.  Once made
  1157. X         you can make a version for a 186 or 286 by modifying
  1158. X         msdos/tccdos/config.mk and setting CFLAGS to contain the right
  1159. X         flags, comments are supplied in the makefile to do so.
  1160. X
  1161. X         The contents of the default response files
  1162. X         (named in msdos/tccdos/mk*.bat) assume specific locations for
  1163. X         your turbo-C libraries, you may need to edit these before actually
  1164. X         getting a successful binary linked.
  1165. X
  1166. X   Microsoft-C 4.0 to 5.1:
  1167. X         Is straight forward, just type 'make msc' and the compile will
  1168. X         chunk along.
  1169. X
  1170. X   Microsoft-C 6.0:
  1171. X         Is equally easy, just type 'make msc60' and the compile will
  1172. X         chunk along.  Once made, if you want to use dmake to compile
  1173. X         itself then set the environment variable MSC_VER=6.0, otherwise
  1174. X         the compile flags will not be correct.  You may also supply this
  1175. X         as an option on the dmake command line.
  1176. X
  1177. X   Memory Requirements and Swapping:
  1178. X         dmake requires quite a bit of memory to run.  As a result
  1179. X         a swapping version of dmake is made if you issue the command
  1180. X         'make tccswp', 'make mscswp' or 'make msc60swp'.  If you leave
  1181. X         the 'swp' off then corresponding (as described above) non-swapping
  1182. X         versions are made.
  1183. X
  1184. X         The swapping code currently only swaps to DISK, I have left hooks
  1185. X         in to accomodate XMS and EMS, I have some code that performs the
  1186. X         necessary XMS/EMS accesses but have not incorporated it in yet.
  1187. X         It appears that a ramdisk seems to work just fine.  If anyone
  1188. X         wishes to fill in the hooks please do and I'll be happy to include
  1189. X         them in future distributions.
  1190. X
  1191. X   dmake 'makefile.mk' control variables:
  1192. X         Initially dmake is compiled for the compact memory model.
  1193. X         Setting MODEL={s,c,m,l} on the command line will select a different
  1194. X         memory model.  Setting NOSWAP:=1 on the command line
  1195. X         will disable the compile and linking of the swap code.
  1196. X         A summary of the available configuration variables follows:
  1197. X
  1198. X              MODEL={s,c,m,l}  - Select {small, compact, medium, large}
  1199. X                       memory model respectively.
  1200. X          NOSWAP:=y       - If set, do not compile the dmake
  1201. X                       swapping version of spawnvpe.
  1202. X          MSC_VER:=6.0       - Must be set if using MSC 6.0 and dmake
  1203. X                       is used to make a new version of dmake.
  1204. X
  1205. X   ^C and stopping a make:
  1206. X         Handling of ^C in the swapping version seems to be somewhat
  1207. SHAR_EOF
  1208. echo "End of part 6"
  1209. echo "File readme/msdos is continued in part 7"
  1210. echo "7" > s2_seq_.tmp
  1211. exit 0
  1212.  
  1213.