home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume19 / dmake / part10 < prev    next >
Encoding:
Text File  |  1991-05-11  |  40.1 KB  |  1,316 lines

  1. Newsgroups: comp.sources.misc
  2. From: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  3. Subject:  v19i031:  dmake - dmake version 3.7, Part10/37
  4. Message-ID: <1991May10.185825.22654@sparky.IMD.Sterling.COM>
  5. Date: Fri, 10 May 1991 18:58:25 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7.  
  8. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  9. Posting-number: Volume 19, Issue 31
  10. Archive-name: dmake/part10
  11. Supersedes: dmake-3.6: Volume 15, Issue 52-77
  12.  
  13. ---- Cut Here and feed the following to sh ----
  14. #!/bin/sh
  15. # this is dmake.shar.10 (part 10 of a multipart archive)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file dmake/getinp.c continued
  18. #
  19. if test ! -r _shar_seq_.tmp; then
  20.     echo 'Please unpack part 1 first!'
  21.     exit 1
  22. fi
  23. (read Scheck
  24.  if test "$Scheck" != 10; then
  25.     echo Please unpack part "$Scheck" next!
  26.     exit 1
  27.  else
  28.     exit 0
  29.  fi
  30. ) < _shar_seq_.tmp || exit 1
  31. if test -f _shar_wnt_.tmp; then
  32. sed 's/^X//' << 'SHAR_EOF' >> 'dmake/getinp.c' &&
  33. X                tok-- );
  34. X           tok[1] = '\0';
  35. X        }
  36. X        else
  37. X           lhs = NIL(char);
  38. X
  39. X        op++;
  40. X        rhs = _strspn( op+1, " \t" );
  41. X        if( !*rhs ) rhs = NIL(char);
  42. X
  43. X        if( (rhs == NIL(char)) || (lhs == NIL(char)) )
  44. X           result = (rhs == lhs) ? TRUE : FALSE;
  45. X        else {
  46. X           tok = rhs + strlen( rhs );
  47. X           for( tok=tok-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
  48. X            tok--);
  49. X           tok[1] = '\0';
  50. X
  51. X           result = (strcmp( lhs, rhs ) == 0) ? TRUE : FALSE;
  52. X        }
  53. X
  54. X        if( *op == '!' ) result = !result;
  55. X     }
  56. X
  57. X     if( expr != NIL(char) ) FREE( expr );
  58. X
  59. X     if( opcode == ST_IF ) {
  60. X        Nest_level++;
  61. X        ifcntl[Nest_level] |= SEEN_IF;
  62. X     }
  63. X
  64. X     if( result )
  65. X        action[ Nest_level ] = action[ Nest_level-1 ];
  66. X     else
  67. X        action[ Nest_level ] = 1;
  68. X     break;
  69. X
  70. X      case ST_ELSE:
  71. X     if( Nest_level <= 0 ) Fatal( ".ELSE without .IF" );
  72. X     if( ifcntl[Nest_level] & SEEN_ELSE )
  73. X        Fatal( "Missing .IF or .ELIF before .ELSE" );
  74. X
  75. X     if( action[ Nest_level-1 ] != 1 )
  76. X        action[ Nest_level ] ^= 0x1;    /* flip between 0 and 1    */
  77. X     ifcntl[Nest_level] |= SEEN_ELSE;
  78. X     break;
  79. X
  80. X      case ST_END:
  81. X     ifcntl[Nest_level] = SEEN_END;
  82. X     Nest_level--;
  83. X     if( Nest_level < 0 ) Fatal( "Unmatched .END" );
  84. X     break;
  85. X   }
  86. X
  87. X   DB_RETURN( action[ Nest_level ] );
  88. }
  89. SHAR_EOF
  90. chmod 0640 dmake/getinp.c ||
  91. echo 'restore of dmake/getinp.c failed'
  92. Wc_c="`wc -c < 'dmake/getinp.c'`"
  93. test 13281 -eq "$Wc_c" ||
  94.     echo 'dmake/getinp.c: original size 13281, current size' "$Wc_c"
  95. rm -f _shar_wnt_.tmp
  96. fi
  97. # ============= dmake/hash.c ==============
  98. if test -f 'dmake/hash.c' -a X"$1" != X"-c"; then
  99.     echo 'x - skipping dmake/hash.c (File already exists)'
  100.     rm -f _shar_wnt_.tmp
  101. else
  102. > _shar_wnt_.tmp
  103. sed 's/^X//' << 'SHAR_EOF' > 'dmake/hash.c' &&
  104. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/hash.c,v 1.1 91/05/06 15:23:15 dvadura Exp $
  105. -- SYNOPSIS -- hashing function for hash tables.
  106. -- 
  107. -- DESCRIPTION
  108. --      Hash an identifier.  The hashing function works by computing the sum
  109. --      of each char and the previous hash value multiplied by 129.  Finally the
  110. --      length of the identifier is added in.  This way the hash depends on the
  111. --      chars as well as the length, and appears to be sufficiently unique,
  112. --      and is FAST to COMPUTE, unlike the previous hash function...
  113. -- 
  114. -- AUTHOR
  115. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  116. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  117. --
  118. -- COPYRIGHT
  119. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  120. -- 
  121. --      This program is free software; you can redistribute it and/or
  122. --      modify it under the terms of the GNU General Public License
  123. --      (version 1), as published by the Free Software Foundation, and
  124. --      found in the file 'LICENSE' included with this distribution.
  125. -- 
  126. --      This program is distributed in the hope that it will be useful,
  127. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  128. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  129. --      GNU General Public License for more details.
  130. -- 
  131. --      You should have received a copy of the GNU General Public License
  132. --      along with this program;  if not, write to the Free Software
  133. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  134. --
  135. -- LOG
  136. --     $Log:    hash.c,v $
  137. X * Revision 1.1  91/05/06  15:23:15  dvadura
  138. X * dmake Release Version 3.7
  139. X * 
  140. */
  141. X
  142. #include "extern.h"
  143. X
  144. PUBLIC uint16
  145. Hash( id, phv )/*
  146. =================
  147. X      This function computes the identifier's hash value and returns the hash
  148. X      value modulo the key size as well as the full hash value.  The reason
  149. X      for returning both is so that hash table searches can be sped up.  You
  150. X      compare hash keys instead and compare strings only for those whose 32-bit
  151. X      hash keys match. (not many) */
  152. X
  153. char   *id;
  154. uint32 *phv;
  155. {
  156. X   register char   *p    = id;
  157. X   register uint32 hash  = (uint32) 0;
  158. X
  159. X   while( *p ) hash = (hash << 7) + hash + (uint32) (*p++);
  160. X   *phv = hash = hash + (uint32) (p-id);
  161. X
  162. X   return( (uint16) (hash % HASH_TABLE_SIZE) );
  163. }
  164. X
  165. SHAR_EOF
  166. chmod 0640 dmake/hash.c ||
  167. echo 'restore of dmake/hash.c failed'
  168. Wc_c="`wc -c < 'dmake/hash.c'`"
  169. test 2324 -eq "$Wc_c" ||
  170.     echo 'dmake/hash.c: original size 2324, current size' "$Wc_c"
  171. rm -f _shar_wnt_.tmp
  172. fi
  173. # ============= dmake/imacs.c ==============
  174. if test -f 'dmake/imacs.c' -a X"$1" != X"-c"; then
  175.     echo 'x - skipping dmake/imacs.c (File already exists)'
  176.     rm -f _shar_wnt_.tmp
  177. else
  178. > _shar_wnt_.tmp
  179. sed 's/^X//' << 'SHAR_EOF' > 'dmake/imacs.c' &&
  180. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/imacs.c,v 1.1 91/05/06 15:23:16 dvadura Exp $
  181. -- SYNOPSIS -- define default internal macros.
  182. -- 
  183. -- DESCRIPTION
  184. --    This file adds to the internal macro tables the set of default
  185. --    internal macros, and for those that are accessible internally via
  186. --    variables creates these variables, and initializes them to point
  187. --    at the default values of these macros.
  188. --
  189. -- AUTHOR
  190. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  191. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  192. --
  193. -- COPYRIGHT
  194. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  195. -- 
  196. --      This program is free software; you can redistribute it and/or
  197. --      modify it under the terms of the GNU General Public License
  198. --      (version 1), as published by the Free Software Foundation, and
  199. --      found in the file 'LICENSE' included with this distribution.
  200. -- 
  201. --      This program is distributed in the hope that it will be useful,
  202. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  203. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  204. --      GNU General Public License for more details.
  205. -- 
  206. --      You should have received a copy of the GNU General Public License
  207. --      along with this program;  if not, write to the Free Software
  208. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  209. --
  210. -- LOG
  211. --     $Log:    imacs.c,v $
  212. X * Revision 1.1  91/05/06  15:23:16  dvadura
  213. X * dmake Release Version 3.7
  214. X * 
  215. */
  216. X
  217. #include "extern.h"
  218. X
  219. static    void    _set_int_var ANSI((char *, char *, int, int *));
  220. static    void    _set_string_var ANSI((char *, char *, int, char **));
  221. static    void    _set_bit_var ANSI((char *, char *, int));
  222. X
  223. /*
  224. ** Arrange to parse the strings stored in Rules[]
  225. */
  226. PUBLIC void
  227. Make_rules()
  228. {
  229. X   Parse(NIL(FILE));
  230. }
  231. X
  232. X
  233. #define M_FLAG   M_DEFAULT | M_EXPANDED
  234. X
  235. /*
  236. ** Add to the macro table all of the internal macro variables plus
  237. ** create secondary variables which will give access to their values
  238. ** easily, both when needed and when the macro value is modified.
  239. ** The latter is accomplished by providing a flag in the macro and a field
  240. ** which gives a pointer to the value if it is a char or string macro value
  241. ** and a mask representing the bit of the global flag register that is affected
  242. ** by this macro's value.
  243. */
  244. PUBLIC void
  245. Create_macro_vars()
  246. {
  247. X   static char* switchar;
  248. X   char   swchar[2];
  249. X
  250. X   swchar[0] = Get_switch_char(), swchar[1] = '\0';
  251. X   _set_string_var("SWITCHAR", swchar, M_PRECIOUS, &switchar);
  252. X   _set_string_var("DIRSEPSTR", "/", M_PRECIOUS, &DirSepStr);
  253. X   _set_string_var("DIRBRKSTR", DirBrkStr, M_PRECIOUS, &DirBrkStr);
  254. X
  255. X   _set_bit_var(".SILENT",   "", A_SILENT  );
  256. X   _set_bit_var(".IGNORE",   "", A_IGNORE  );
  257. X   _set_bit_var(".PRECIOUS", "", A_PRECIOUS);
  258. X   _set_bit_var(".EPILOG",   "", A_EPILOG  );
  259. X   _set_bit_var(".PROLOG",   "", A_PROLOG  );
  260. X   _set_bit_var(".NOINFER",  "", A_NOINFER );
  261. X   _set_bit_var(".SEQUENTIAL","",A_SEQ     );
  262. X   _set_bit_var(".USESHELL", "", A_SHELL   );
  263. X   _set_bit_var(".SWAP",     "", A_SWAP    );
  264. X   _set_bit_var(".MKSARGS",  "", A_MKSARGS );
  265. X
  266. X   Glob_attr = A_DEFAULT;        /* set all flags to NULL   */
  267. X
  268. X   _set_string_var("SHELL",        "",  M_DEFAULT, &Shell       );
  269. X   _set_string_var("SHELLFLAGS",   " ", M_DEFAULT, &Shell_flags );
  270. X   _set_string_var("GROUPSHELL",   "",  M_DEFAULT, &GShell      );
  271. X   _set_string_var("GROUPFLAGS",   " ", M_DEFAULT, &GShell_flags);
  272. X   _set_string_var("SHELLMETAS",   "",  M_DEFAULT, &Shell_metas );
  273. X   _set_string_var("GROUPSUFFIX",  "",  M_DEFAULT, &Grp_suff    );
  274. X   _set_string_var("PREP",         "0", M_DEFAULT, &Prep        );
  275. X   _set_string_var("AUGMAKE",NIL(char), M_DEFAULT, &Augmake     );
  276. X   _set_string_var(".SETDIR",      "",  M_DEFAULT, &Start_dir   );
  277. X   _set_string_var(".KEEP_STATE",  "",  M_DEFAULT, &Keep_state  );
  278. X
  279. X   _set_string_var("MAKEDIR", Get_current_dir(), M_PRECIOUS|M_NOEXPORT,
  280. X         &Makedir);
  281. X   _set_string_var("PWD",  Makedir,  M_DEFAULT|M_NOEXPORT, &Pwd);
  282. X   _set_string_var("TMD",  "",       M_DEFAULT|M_NOEXPORT, &Tmd);
  283. X
  284. X   Def_macro("NULL", "", M_PRECIOUS|M_NOEXPORT|M_FLAG);
  285. X   _set_int_var( "MAXLINELENGTH", "0", M_DEFAULT|M_NOEXPORT, &Buffer_size );
  286. X   (void) Def_macro("MAXLINELENGTH", "0", M_FLAG | M_DEFAULT);
  287. X
  288. X   /* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to
  289. X    * change from command line. */
  290. X   _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT, &Max_proclmt );
  291. X   _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
  292. }
  293. X
  294. X
  295. /*
  296. ** Define an integer variable value, and set up the macro.
  297. */
  298. static void
  299. _set_int_var(name, val, flag, var)
  300. char *name;
  301. char *val;
  302. int  flag;
  303. int  *var;
  304. {
  305. X   HASHPTR hp;
  306. X
  307. X   hp = Def_macro(name, val, M_FLAG | flag);
  308. X   hp->ht_flag |= M_VAR_INT | M_MULTI;
  309. X   hp->MV_IVAR  = var;
  310. X   *var         = atoi(val);
  311. }
  312. X
  313. X
  314. /*
  315. ** Define a string variables value, and set up the macro.
  316. */
  317. static void
  318. _set_string_var(name, val, flag, var)
  319. char *name;
  320. char *val;
  321. int  flag;
  322. char **var;
  323. {
  324. X   HASHPTR hp;
  325. X
  326. X   hp = Def_macro(name, val, M_FLAG | flag);
  327. X   hp->ht_flag |= M_VAR_STRING | M_MULTI;
  328. X   hp->MV_SVAR  = var;
  329. X   *var         = hp->ht_value;
  330. }
  331. X
  332. X
  333. /*
  334. ** Define a bit variable value, and set up the macro.
  335. */
  336. static void
  337. _set_bit_var(name, val, mask)
  338. char *name;
  339. char *val;
  340. int  mask;
  341. {
  342. X   HASHPTR hp;
  343. X
  344. X   hp           = Def_macro(name, val, M_FLAG);
  345. X   hp->ht_flag |= M_VAR_BIT | M_MULTI;
  346. X   hp->MV_MASK  = mask;
  347. X   hp->MV_BVAR  = &Glob_attr;
  348. }
  349. SHAR_EOF
  350. chmod 0640 dmake/imacs.c ||
  351. echo 'restore of dmake/imacs.c failed'
  352. Wc_c="`wc -c < 'dmake/imacs.c'`"
  353. test 5479 -eq "$Wc_c" ||
  354.     echo 'dmake/imacs.c: original size 5479, current size' "$Wc_c"
  355. rm -f _shar_wnt_.tmp
  356. fi
  357. # ============= dmake/infer.c ==============
  358. if test -f 'dmake/infer.c' -a X"$1" != X"-c"; then
  359.     echo 'x - skipping dmake/infer.c (File already exists)'
  360.     rm -f _shar_wnt_.tmp
  361. else
  362. > _shar_wnt_.tmp
  363. sed 's/^X//' << 'SHAR_EOF' > 'dmake/infer.c' &&
  364. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/infer.c,v 1.1 91/05/06 15:23:17 dvadura Exp $
  365. -- SYNOPSIS -- infer how to make a target.
  366. -- 
  367. -- DESCRIPTION
  368. --    This file contains the code to infer a recipe, and possibly some new
  369. --    prerequisites for a target which dmake does not know how to make, or
  370. --    has no explicit recipe.
  371. --
  372. --    The inference fails if no path through the inference graph can be
  373. --    found by which we can make the target.
  374. -- 
  375. -- AUTHOR
  376. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  377. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  378. --
  379. -- COPYRIGHT
  380. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  381. -- 
  382. --      This program is free software; you can redistribute it and/or
  383. --      modify it under the terms of the GNU General Public License
  384. --      (version 1), as published by the Free Software Foundation, and
  385. --      found in the file 'LICENSE' included with this distribution.
  386. -- 
  387. --      This program is distributed in the hope that it will be useful,
  388. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  389. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  390. --      GNU General Public License for more details.
  391. -- 
  392. --      You should have received a copy of the GNU General Public License
  393. --      along with this program;  if not, write to the Free Software
  394. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  395. --
  396. -- LOG
  397. --     $Log:    infer.c,v $
  398. X * Revision 1.1  91/05/06  15:23:17  dvadura
  399. X * dmake Release Version 3.7
  400. X * 
  401. */
  402. X
  403. #include "extern.h"
  404. X
  405. /* attributes that get transfered from the % start cell to the inferred
  406. X * cells. */
  407. X
  408. #define A_TRANSFER  (A_EPILOG | A_PRECIOUS | A_SILENT | A_SHELL | A_SETDIR |\
  409. X             A_SEQ | A_LIBRARY | A_IGNORE | A_PROLOG | A_SWAP |\
  410. X             A_NOSTATE )
  411. X
  412. X
  413. /* Define local static functions */
  414. static DFALINKPTR _dfa_subset  ANSI((DFALINKPTR, DFASETPTR));
  415. static void       _free_dfas   ANSI((DFALINKPTR));
  416. static int      _count_dots  ANSI((char *));
  417. static char *      _build_name  ANSI((char *, char *, char *));
  418. static void      _free_icells ANSI(());
  419. static ICELLPTR   _union_iset  ANSI((ICELLPTR, ICELLPTR));
  420. static ICELLPTR   _add_iset    ANSI((ICELLPTR,ICELLPTR,CELLPTR,DFALINKPTR,
  421. X                     CELLPTR,int,int,char *,char *, int));
  422. static ICELLPTR   _derive_prerequisites ANSI((ICELLPTR, ICELLPTR *));
  423. static char *      _dump_inf_chain ANSI((ICELLPTR, int, int));
  424. X
  425. static int _prep = -1;    /* Integer value of Prep variable */
  426. X
  427. X
  428. PUBLIC void
  429. Infer_recipe( cp, setdirroot )/*
  430. ================================
  431. X   Perform a breadth-first search of the inference graph and return if
  432. X   possible an inferred set of prerequisites for making the current target.
  433. */
  434. CELLPTR cp;
  435. CELLPTR setdirroot;
  436. {
  437. X   ICELLPTR nomatch, match;
  438. X
  439. X   DB_ENTER("Infer_recipe");
  440. X
  441. X   if( cp->ce_attr & A_NOINFER ) {DB_VOID_RETURN;}
  442. X   if( _prep == -1 ) _prep = atoi(Prep);  /* _dfa_subset needs _prep */
  443. X
  444. X   match = NIL(ICELL);
  445. X   nomatch = _add_iset( NIL(ICELL), NIL(ICELL), NIL(CELL), NIL(DFALINK),
  446. X            setdirroot, _prep+_count_dots(cp->CE_NAME), 0,
  447. X            _strdup(cp->CE_NAME), NIL(char),
  448. X            cp->ce_time != (time_t)0L);
  449. X
  450. X   /* Make sure we try whole heartedly to infer at least one suffix */
  451. X   if( nomatch->ic_dmax == 0 ) ++nomatch->ic_dmax;
  452. X
  453. X   DB_EXECUTE( "inf", _dump_iset("nomatch",nomatch); );
  454. X
  455. X   while( nomatch != NIL(ICELL) ) {
  456. X      ICELLPTR new_nomatch = NIL(ICELL);
  457. X      ICELLPTR ic, pmatch, mmatch;
  458. X      CELLPTR  prereq;
  459. X      int      first;
  460. X
  461. X      for( ic=nomatch; ic != NIL(ICELL); ic=ic->ic_next ) {
  462. X     int ipush = FALSE;
  463. X
  464. X     if( ic->ic_dir ) ipush = Push_dir(ic->ic_dir, ic->ic_name, FALSE);
  465. X     match = _union_iset(match, _derive_prerequisites(ic, &new_nomatch));
  466. X     if( ipush ) Pop_dir(FALSE);
  467. X      }
  468. X
  469. X      DB_EXECUTE( "inf", _dump_iset("match",match); );
  470. X      DB_EXECUTE( "inf", _dump_iset("nomatch",new_nomatch); );
  471. X
  472. X      /* We have now deduced the two sets MATCH and NOMATCH.  MATCH holds the
  473. X       * set of edges that we encountered that matched.  If this set is empty
  474. X       * then we can apply transitive closure (if enabled) to the elements of
  475. X       * NOMATCH to see if we can find some other method to make the target.
  476. X       *
  477. X       * If MATCH is non-empty, we have found a method for making the target.
  478. X       * It is the shortest method for doing so (ie. uses fewest number of
  479. X       * steps).  If MATCH contains more than one element then we have a
  480. X       * possible ambiguity.
  481. X       */
  482. X      if( match == NIL(ICELL) ) {
  483. X     nomatch = new_nomatch;
  484. X     continue;
  485. X      }
  486. X
  487. X      /* Ok, we have a set of possible matches in MATCH, we should check the
  488. X       * set for ambiguity.  If more than one inference path exists of the
  489. X       * same depth, then we may issue an ambigous inference error message.
  490. X       *
  491. X       * The message is suppressed if MATCH contains two elements and one of
  492. X       * them is the empty-prerequisite-rule.  In this case we ignore the
  493. X       * ambiguity and take the rule that infers the prerequisite.
  494. X       *
  495. X       * Also if there are any chains that rely on a non-existant prerequisite
  496. X       * that may get made because it has a recipe then we prefer any that
  497. X       * rely on existing final prerequisites over those that we have to make.
  498. X       *
  499. X       * NOTE:  May turn this around at some point.
  500. X       */
  501. X
  502. X      /* Split out those that have to be made from those that end in
  503. X       * prerequisites that already exist. */
  504. X      pmatch = mmatch = NIL(ICELL);
  505. X      for(; match; match = ic ) {
  506. X     ic = match->ic_next;
  507. X     match->ic_next = NIL(ICELL);
  508. X
  509. X     if( match->ic_exists )
  510. X        pmatch = _union_iset(pmatch, match);
  511. X     else
  512. X        mmatch = _union_iset(mmatch, match);
  513. X      }
  514. X
  515. X      if( pmatch )
  516. X     match = pmatch;
  517. X      else
  518. X     match = mmatch;
  519. X
  520. X      /* Make sure it is unique */
  521. X      if( match->ic_next != NIL(ICELL) ) {
  522. X     int dump = (match->ic_next->ic_next != NIL(ICELL));
  523. X
  524. X     /* Check for definite ambiguity */
  525. X     if( !dump )
  526. X        if( (match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq) ||
  527. X            (!match->ic_meta->ce_prq && !match->ic_next->ic_meta->ce_prq)  )
  528. X           dump = TRUE;
  529. X        else if(!match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq )
  530. X           match = match->ic_next;
  531. X
  532. X     if( dump ) {
  533. X        int count = 1;
  534. X
  535. X        Continue = TRUE;
  536. X        Error( "Ambiguous inference chains for target '%s'", cp->CE_NAME );
  537. X        for( ic=match; ic; ic=ic->ic_next )
  538. X           (void) _dump_inf_chain(ic, TRUE, count++);
  539. X        Fatal( "resolve ambiguity before proceeding.");
  540. X        /*NOTREACHED*/
  541. X     }
  542. X      }
  543. X
  544. X      /* MATCH now points at the derived recipe.  We must now take cp, and
  545. X       * construct the correct graph so that the make may proceed. */
  546. X
  547. X      if( Verbose & V_INFER ) {
  548. X     char *tmp = _dump_inf_chain(match, TRUE, FALSE);
  549. X     printf("%s:  Inferring prerequistes and recipes using:\n%s:  ... %s\n",
  550. X         Pname, Pname, tmp );
  551. X     FREE(tmp);
  552. X      }
  553. X
  554. X      pmatch = NIL(ICELL);
  555. X      prereq = NIL(CELL);
  556. X      first  = TRUE;
  557. X
  558. X      while( match ) {
  559. X         CELLPTR infcell=NIL(CELL);
  560. X
  561. X     /* Compute the inferred prerequisite first. */
  562. X     if( match->ic_meta && match->ic_name ) {
  563. X        infcell = Def_cell( match->ic_name );
  564. X
  565. X        if( first )
  566. X           infcell->ce_flag |= F_RULES;
  567. X        else
  568. X           infcell->ce_flag |= F_INFER|F_REMOVE|F_TARGET;
  569. X
  570. X        if( !match->ic_flag )
  571. X           infcell->ce_attr |= A_NOINFER;
  572. X     }
  573. X
  574. X     /* Now attach the recipe from the previous MATCH entry and then
  575. X      * add any prerequisites that you might think are required. */
  576. X     if( infcell == NIL(CELL) && match->ic_name )
  577. X        infcell = cp;
  578. X
  579. X     /* Add global prerequisites from previous rule if there are any and
  580. X      * the recipe. */
  581. X     if( pmatch ) {
  582. X        CELLPTR imeta = pmatch->ic_meta;
  583. X        LINKPTR lp;
  584. X
  585. X        infcell->ce_per   = pmatch->ic_dfa->dl_per;
  586. X        infcell->ce_attr |= (imeta->ce_attr & A_TRANSFER);
  587. X
  588. X        if( !(infcell->ce_flag & F_RULES) ) {
  589. X           infcell->ce_flag   |= (imeta->ce_flag & (F_SINGLE|F_GROUP));
  590. X           infcell->ce_recipe  = imeta->ce_recipe;
  591. X        }
  592. X
  593. X        pmatch->ic_dfa->dl_per = NIL(char);
  594. X
  595. X        /* If infcell already had a directory set then modify it based on
  596. X         * whether it was the original cell or some intermediary. */
  597. X        if( imeta->ce_dir )
  598. X           if( infcell->ce_dir && infcell == cp ) {
  599. X          /* cp->ce_dir was set and we have pushed the directory prior
  600. X           * to calling this routine.  We should therefore pop it and
  601. X           * push the new concatenated directory required by the
  602. X           * inference. */
  603. X          infcell->ce_dir=_strdup(Build_path(infcell->ce_dir,
  604. X                             imeta->ce_dir));
  605. X           }
  606. X           else
  607. X          infcell->ce_dir = imeta->ce_dir;
  608. X
  609. X        for( lp=imeta->ce_indprq; lp != NIL(LINK); lp=lp->cl_next ) {
  610. X           char    *name = lp->cl_prq->CE_NAME;
  611. X           CELLPTR tcp;
  612. X
  613. X           name = _build_name( cp->CE_NAME, name, infcell->ce_per );
  614. X           tcp  = Def_cell( name );
  615. X           tcp->ce_flag |= F_REMOVE;
  616. X           Add_prerequisite( infcell, tcp, FALSE, FALSE );
  617. X
  618. X           if( Verbose & V_INFER )
  619. X          printf( "%s:  Inferred indirect prerequisite [%s]\n",
  620. X              Pname, name );
  621. X           FREE(name);
  622. X        }
  623. X     }
  624. X
  625. X     /* Add the previous cell as the prerequisite */
  626. X     if( prereq )
  627. X        (Add_prerequisite(infcell,prereq,FALSE,FALSE))->cl_flag |= F_TARGET;
  628. X
  629. X     pmatch = match;
  630. X     prereq = infcell;
  631. X     match  = match->ic_parent;
  632. X     first  = FALSE;
  633. X      }
  634. X
  635. X      DB_PRINT("inf", ("Terminated due to a match"));
  636. X      break;
  637. X   }
  638. X
  639. X   _free_icells();
  640. X
  641. X   DB_VOID_RETURN;
  642. }
  643. X
  644. X
  645. static ICELLPTR
  646. _derive_prerequisites( ic, nnmp )/*
  647. ===================================
  648. X   Take a cell and derive a set of prerequisites from the cell.  Categorize
  649. X   them into those that MATCH (ie. those that we found in the file system),
  650. X   and those that do not match NOMATCH that we may possibly have a look at
  651. X   later.  When we process the next level of the breadth-first search.
  652. X   
  653. X   Once MATCH is non-empty we will stop inserting elements into NOMATCH
  654. X   since we know that either MATCH is successful and unique or it will
  655. X   issue an ambiguity error.  We will never go on to look at elements
  656. X   in NOMATCH after wards. */
  657. ICELLPTR ic;
  658. ICELLPTR *nnmp;
  659. {
  660. X   ICELLPTR   match = NIL(ICELL);
  661. X   DFALINKPTR pdfa;
  662. X   DFALINKPTR dfas;
  663. X
  664. X   DB_ENTER("_derive_prerequisites");
  665. X
  666. X   /* If none of the inference nodes match then forget about the inference.
  667. X    * The user did not tell us how to make such a target.  We also stop the
  668. X    * Inference if the new set of DFA's is a proper subset of a previous
  669. X    * subset and it's PREP counts exceed the value of Prep.
  670. X    */
  671. X   dfas = _dfa_subset( Match_dfa(ic->ic_name), &ic->ic_dfastack );
  672. X
  673. X   DB_EXECUTE("inf", _dump_dfa_stack(dfas, &ic->ic_dfastack); );
  674. X
  675. X   /* Ok, we have nothing here to work with so return an empty cell. */
  676. X   if( dfas == NIL(DFALINK) ) {
  677. X      DB_PRINT( "mem", ("%s:<- mem %ld",ic->ic_name, (long)coreleft()));
  678. X      DB_PRINT( "inf", ("<<< Exit, no dfas, cp = %04x", NIL(CELL)) );
  679. X      DB_RETURN( NIL(ICELL) );
  680. X   }
  681. X
  682. X   /* Save the dfas, we are going to use on the stack for this cell. */
  683. X   ic->ic_dfastack.df_set = dfas;
  684. X
  685. X   /* Run through the %-meta cells, build the prerequisite cells.  For each
  686. X    * %-meta go through it's list of edges and try to use each in turn to
  687. X    * decuce a likely prerequisite.  We perform a breadth-first search
  688. X    * matching the first path that results in a unique method for making the
  689. X    * target. */
  690. X   for( pdfa = dfas; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next ) {
  691. X      LINK tl;
  692. X      LINKPTR edge;
  693. X      CELLPTR pmeta;
  694. X
  695. X      pmeta = pdfa->dl_meta;
  696. X      DB_PRINT( "inf", ("Using dfa:  [%s]", pmeta->CE_NAME) );
  697. X
  698. X      /* If the %-meta is a singleton meta then deal with it differently from
  699. X       * the case when it is a bunch of %-meta's found on the original entries
  700. X       * prerequisite list. */
  701. X      if( pmeta->ce_flag & F_MULTI )
  702. X     edge = pmeta->ce_prq;
  703. X      else {
  704. X     tl.cl_prq = pmeta;
  705. X     tl.cl_next = NIL(LINK);
  706. X     edge = &tl;
  707. X      }
  708. X
  709. X      /* Now run through the list of prerequisite edge's for the %-meta. */
  710. X      for( ; edge != NIL(LINK); edge = edge->cl_next ) {
  711. X     HASHPTR  thp;        /* temporary hash table pointer        */
  712. X     HASH     iprqh;    /* hash cell for new prerequisite    */
  713. X     CELL     iprq;        /* inferred prerequisite to look for    */
  714. X     CELLPTR  idirroot;    /* Inferred prerequisite root        */
  715. X     CELLPTR  nidirroot;    /* Inferred prerequisite root        */
  716. X     STRINGPTR ircp;    /* Inferred prerequisites recipe    */
  717. X     char     *idir;    /* directory to CD to.            */
  718. X     int      ipush = 0;    /* flag for push on inferred prereq     */
  719. X     char     *name = NIL(char);         /* prerequisite name    */
  720. X     CELLPTR  meta = edge->cl_prq;
  721. X     int      dmax_fix;
  722. X     int      trans;
  723. X     int      noinf;
  724. X     int      exists;
  725. X     
  726. X     if( meta->ce_prq ) name = meta->ce_prq->cl_prq->CE_NAME;
  727. X
  728. X     DB_PRINT( "inf", ("Trying edge from [%s] to [%s] for [%s]",
  729. X           meta->CE_NAME, name?name:"(nil)", ic->ic_name) );
  730. X
  731. X     /* Set the temp CELL used for building prerequisite candidates to
  732. X      * all zero so that we don't have to keep initializing all the
  733. X      * fields. */
  734. X     {
  735. X        register char *s = (char *) &iprq;
  736. X        register int   n = sizeof(CELL);
  737. X        while( n ) { *s++ = '\0'; n--; }
  738. X     }
  739. X
  740. X     nidirroot = idirroot = ic->ic_setdirroot;
  741. X     iprq.ce_name = &iprqh;
  742. X
  743. X     if( name ) {
  744. X        /* Build the prerequisite name from the %-meta prerequisite given
  745. X         * for the %-meta rule. */
  746. X        iprqh.ht_name = _build_name( ic->ic_name, name, pdfa->dl_per );
  747. X        if((dmax_fix = (_count_dots(name)-_count_dots(meta->CE_NAME))) < 0)
  748. X           dmax_fix = 0;
  749. X
  750. X        if( !strcmp(ic->ic_name, iprqh.ht_name) ||
  751. X        (_count_dots(iprqh.ht_name) > ic->ic_dmax + dmax_fix) ) {
  752. X           FREE( iprqh.ht_name );
  753. X           continue;
  754. X        }
  755. X
  756. X        DB_PRINT( "inf", ("Checking prerequisite [%s]", iprqh.ht_name) );
  757. X
  758. X        /* See if the prerequisite CELL has been previously defined.  If
  759. X         * it has, then make a copy of it into iprq, and use it to try
  760. X         * the inference.  We make the copy so that we don't modify the
  761. X         * stat of the inferred cell if the inference fails.
  762. X         */
  763. X        thp = Get_name( iprqh.ht_name, Defs, FALSE );
  764. X        if(thp != NIL(HASH)) {
  765. X           iprq = *thp->CP_OWNR;
  766. X           ircp = iprq.ce_recipe;
  767. X        }
  768. X        else
  769. X           ircp = NIL(STRING);
  770. X     }
  771. X     else
  772. X        iprqh.ht_name = NIL(char);
  773. X
  774. X
  775. X     /* If the %-meta has a .SETDIR set then we change to the new
  776. X      * directory prior to performing the stat of the new prerequisite.
  777. X      * If the change of directory fails then the rule is droped from
  778. X      * further consideration.
  779. X      */
  780. X     if( iprq.ce_dir ) {
  781. X        if( ipush = Push_dir(iprq.ce_dir, iprqh.ht_name, TRUE) ) {
  782. X           nidirroot = thp->CP_OWNR;
  783. X           idir      = Pwd;
  784. X        }
  785. X        else {
  786. X           if( iprqh.ht_name ) FREE( iprqh.ht_name );
  787. X           continue;
  788. X        }
  789. X     }
  790. X     else
  791. X        idir = NIL(char);
  792. X
  793. X
  794. X     /* Stat the inferred prerequisite.
  795. X      */
  796. X     if( name ) {
  797. X        if( Verbose & V_INFER )
  798. X           printf( "%s:  Trying prerequisite [%s] for [%s]\n", Pname,
  799. X               iprqh.ht_name, ic->ic_name );
  800. X
  801. X        if( !(iprq.ce_flag & F_STAT) ) Stat_target(&iprq, FALSE);
  802. X     }
  803. X
  804. X
  805. X     /* If the STAT succeeded or if the prerequisite has a recipe for
  806. X      * making it then it's a match and a candidate for getting infered.
  807. X      * Otherwise it is not a match, and we cannot yet tell if it is
  808. X      * going to be a successful path to follow, so we save it for
  809. X      * later consideration.
  810. X      */
  811. X     noinf = ((Glob_attr)&A_NOINFER);
  812. X     if( meta->ce_prq )
  813. X        noinf |= ((meta->ce_prq->cl_prq->ce_attr)&A_NOINFER);
  814. X     trans = Transitive || !noinf;
  815. X     exists = (iprq.ce_time != (time_t)0L);
  816. X
  817. X     if( exists || (ircp != NIL(STRING)) || !name ) {
  818. X        match = _add_iset( match, ic, meta, pdfa, idirroot, ic->ic_dmax,
  819. X                   trans, iprq.ce_name->ht_name, idir, exists );
  820. X        DB_PRINT("inf",("Added to MATCH %s",iprq.ce_name->ht_name));
  821. X     }
  822. X     else if( !noinf && match == NIL(ICELL) ) {
  823. X        *nnmp = _add_iset( *nnmp, ic, meta, pdfa, nidirroot, ic->ic_dmax,
  824. X                   trans, iprq.ce_name->ht_name, idir, exists );
  825. X        DB_PRINT("inf",("Added to NOMATCH %s",iprq.ce_name->ht_name));
  826. X     }
  827. X
  828. X     /* If we pushed a directory for the inferred prerequisite then
  829. X      * pop it.
  830. X      */
  831. X     if( ipush ) Pop_dir(FALSE);
  832. X     if( iprqh.ht_name ) FREE(iprqh.ht_name);
  833. X      }
  834. X   }
  835. X
  836. X   DB_RETURN(match);
  837. }
  838. X
  839. X
  840. static char *
  841. _build_name( tg, meta, per )
  842. char *tg;
  843. char *meta;
  844. char *per;
  845. {
  846. X   char    *name;
  847. X
  848. X   name = Apply_edit( meta, "%", per, FALSE, FALSE );
  849. X   if( strchr(name, '$') ) {
  850. X      HASHPTR m_at;
  851. X      char *tmp;
  852. X
  853. X      m_at = Def_macro( "@", tg, M_MULTI );
  854. X      tmp = Expand( name );
  855. X
  856. X      if( m_at->ht_value != NIL(char) ) {
  857. X     FREE( m_at->ht_value );
  858. X     m_at->ht_value = NIL(char);
  859. X      }
  860. X
  861. X      if( name != meta ) FREE( name );
  862. X      name = tmp;
  863. X   }
  864. X   else if( name == meta )
  865. X      name = _strdup( name );
  866. X
  867. X   return(name);
  868. }
  869. X
  870. X
  871. static DFALINKPTR
  872. _dfa_subset( pdfa, stack )/*
  873. ============================
  874. X   This is the valid DFA subset computation.  Whenever a CELL has a Match_dfa
  875. X   subset computed this algorithm is run to see if any of the previously
  876. X   computed sets on the DFA stack are proper subsets of the new set.  If they
  877. X   are, then any elements of the matching subset whose Prep counts exceed
  878. X   the allowed maximum given by Prep are removed from the computed DFA set,
  879. X   and hence from consideration, thereby cutting off the cycle in the
  880. X   inference graph. */
  881. DFALINKPTR       pdfa;
  882. register DFASETPTR stack;
  883. {
  884. X   register DFALINKPTR element;
  885. X   DFALINKPTR          nelement;
  886. X
  887. X   DB_ENTER( "_dfa_subset" );
  888. X
  889. X   for(; pdfa != NIL(DFALINK) && stack != NIL(DFASET); stack = stack->df_next) {
  890. X      int subset = TRUE;
  891. X
  892. X      for( element=stack->df_set; subset && element != NIL(DFALINK);
  893. X           element=element->dl_next ) {
  894. X         register DFALINKPTR subel;
  895. X
  896. X     for( subel = pdfa;
  897. X          subel != NIL(DFALINK) && (subel->dl_meta != element->dl_meta);
  898. X          subel = subel->dl_next );
  899. X
  900. X     if( subset = (subel != NIL(DFALINK)) ) element->dl_member = subel;
  901. X      }
  902. X
  903. X      if( subset )
  904. X     for( element=stack->df_set; element != NIL(DFALINK);
  905. X          element=element->dl_next ) {
  906. X        DFALINKPTR mem = element->dl_member;
  907. X        int        npr = element->dl_prep + 1;
  908. X
  909. X        if( npr > _prep )
  910. X           mem->dl_delete++;
  911. X        else
  912. X           mem->dl_prep = npr;
  913. X     }
  914. X   }
  915. X
  916. X   for( element = pdfa; element != NIL(DFALINK); element = nelement ) {
  917. X      nelement = element->dl_next;
  918. X
  919. X      if( element->dl_delete ) {
  920. X     /* A member of the subset has a PREP count equal to PREP, so
  921. X      * it should not be considered further in the inference, hence
  922. X      * we remove it from the doubly linked set list */
  923. X     if( element == pdfa )
  924. X        pdfa = element->dl_next;
  925. X     else
  926. X        element->dl_prev->dl_next = element->dl_next;
  927. X
  928. X     if( element->dl_next != NIL(DFALINK) )
  929. X        element->dl_next->dl_prev = element->dl_prev;
  930. X
  931. X     DB_PRINT("inf", ("deleting dfa [%s]", element->dl_meta->CE_NAME));
  932. X     FREE( element->dl_per );
  933. X     FREE( element );
  934. X      }
  935. X   }
  936. X
  937. X   DB_RETURN( pdfa );
  938. }
  939. X
  940. X
  941. X
  942. static void
  943. _free_dfas( chain )/*
  944. =====================
  945. X   Free the list of DFA's constructed by Match_dfa, and linked together by
  946. X   LINK cells.  FREE the % value as well, as long as it isn't NIL. */
  947. DFALINKPTR chain;
  948. {
  949. X   register DFALINKPTR tl;
  950. X
  951. X   DB_ENTER( "_free_dfas" );
  952. X
  953. X   for( tl=chain; tl != NIL(DFALINK); chain = tl ) {
  954. X      tl = tl->dl_next;
  955. X
  956. X      DB_PRINT( "inf", ("Freeing DFA [%s], %% = [%s]", chain->dl_meta->CE_NAME,
  957. X                chain->dl_per) );
  958. X
  959. X      if( chain->dl_per != NIL(char) ) FREE( chain->dl_per );
  960. X      FREE( chain );
  961. X   }
  962. X
  963. X   DB_VOID_RETURN;
  964. }
  965. X
  966. X
  967. static int
  968. _count_dots( name )/*
  969. =====================*/
  970. char *name;
  971. {
  972. X   register char *p;
  973. X   register int  i = 0;
  974. X
  975. X   for( p = name; *p; p++ ) if(*p == '.') i++;
  976. X
  977. X   return( i );
  978. }
  979. X
  980. X
  981. static ICELLPTR _icells = NIL(ICELL);
  982. #ifdef DBUG
  983. static int _icell_cost = 0;
  984. #endif
  985. X
  986. static ICELLPTR
  987. _add_iset( iset, parent, meta, dfa, setdirroot, dmax, noinf, name, dir, exists)
  988. ICELLPTR   iset;
  989. ICELLPTR   parent;
  990. CELLPTR    meta;
  991. DFALINKPTR dfa;
  992. CELLPTR    setdirroot;
  993. int       dmax;
  994. int       noinf;
  995. char      *name;
  996. char      *dir;
  997. int       exists;
  998. {
  999. X   ICELLPTR icell;
  1000. X
  1001. X   DB_ENTER("_add_iset");
  1002. X   TALLOC(icell, 1, ICELL);
  1003. X
  1004. X   DB_EXECUTE("inf", _icell_cost+=(sizeof(ICELL)+strlen(dir)+strlen(name)+2););
  1005. X
  1006. X   icell->ic_meta = meta;
  1007. X   icell->ic_dfa  = dfa;
  1008. X   icell->ic_setdirroot = setdirroot;
  1009. X
  1010. X   if( parent ) icell->ic_dfastack.df_next = &parent->ic_dfastack;
  1011. X
  1012. X   icell->ic_dmax = dmax;
  1013. X   icell->ic_dir = _strdup(dir);
  1014. X   icell->ic_name = _strdup(name);
  1015. X   icell->ic_parent = parent;
  1016. X   icell->ic_next = iset;
  1017. X   icell->ic_flag = noinf;
  1018. X   icell->ic_exists = exists;
  1019. X
  1020. X   icell->ic_link = _icells;
  1021. X   _icells = icell;
  1022. X
  1023. X   DB_RETURN(icell);
  1024. }
  1025. X
  1026. X
  1027. static void
  1028. _free_icells()
  1029. {
  1030. X   register ICELLPTR ic;
  1031. X
  1032. X   DB_ENTER("_free_icells");
  1033. X
  1034. X   for( ; _icells; _icells = ic ) {
  1035. X      ic = _icells->ic_link;
  1036. X
  1037. X      _free_dfas(_icells->ic_dfastack.df_set);
  1038. X      if( _icells->ic_dir ) FREE(_icells->ic_dir);
  1039. X      if( _icells->ic_name) FREE(_icells->ic_name);
  1040. X      FREE(_icells);
  1041. X   }
  1042. X
  1043. X   DB_PRINT("inf",("Used %d memory for icells",_icell_cost));
  1044. X   DB_EXECUTE("inf", _icell_cost=0; );
  1045. X
  1046. X   DB_VOID_RETURN;
  1047. }
  1048. X
  1049. X
  1050. static ICELLPTR
  1051. _union_iset( iset, uset )
  1052. ICELLPTR iset;
  1053. ICELLPTR uset;
  1054. {
  1055. X   register ICELLPTR ic;
  1056. X
  1057. X   if( iset == NIL(ICELL) ) return(uset);
  1058. X
  1059. X   for( ic=iset; ic->ic_next != NIL(ICELL); ic=ic->ic_next );
  1060. X   ic->ic_next = uset;
  1061. X
  1062. X   return(iset);
  1063. }
  1064. X
  1065. X
  1066. static char *
  1067. _dump_inf_chain( ip, flag, print )/*
  1068. ====================================*/
  1069. ICELLPTR ip;
  1070. int      flag;
  1071. int     print;
  1072. {
  1073. X   char *tmp;
  1074. X
  1075. X   if( ip == NIL(ICELL) ) return(NIL(char));
  1076. X
  1077. X   tmp = _dump_inf_chain(ip->ic_parent, FALSE, FALSE);
  1078. X
  1079. X   if( ip->ic_meta ) {
  1080. X      tmp = _strjoin(tmp, "(", -1, TRUE);
  1081. X      tmp = _strjoin(tmp, ip->ic_meta->CE_NAME, -1, TRUE);
  1082. X
  1083. X      if( ip->ic_dir && !*ip->ic_dir ) {
  1084. X     tmp = _strjoin(tmp, "[", -1, TRUE);
  1085. X     if( strncmp(Makedir,ip->ic_dir, strlen(Makedir)) )
  1086. X        tmp = _strjoin(tmp, ip->ic_dir, -1, TRUE);
  1087. X     else
  1088. X        tmp = _strjoin(tmp, ip->ic_dir+strlen(Makedir)+1, -1, TRUE);
  1089. X     tmp = _strjoin(tmp, "]", -1, TRUE);
  1090. X      }
  1091. X      tmp = _strjoin(tmp, (ip->ic_name)?") -->":")", -1, TRUE);
  1092. X   }
  1093. X   
  1094. X   if( ip->ic_name ) tmp = _strapp( tmp, ip->ic_name );
  1095. X
  1096. X   if( flag && ip->ic_meta->ce_prq) {
  1097. X      tmp = _strjoin(tmp, "(", -1, TRUE);
  1098. X      tmp = _strjoin(tmp, ip->ic_meta->ce_prq->cl_prq->CE_NAME, -1, TRUE);
  1099. X      tmp = _strjoin(tmp, ")", -1, TRUE);
  1100. X   }
  1101. X
  1102. X   if( print ) {
  1103. X      fprintf( stderr, "%s:  %2d. %s\n", Pname, print, tmp );
  1104. X      FREE(tmp);
  1105. X      tmp = NIL(char);
  1106. X   }
  1107. X
  1108. X   return(tmp);
  1109. }
  1110. X
  1111. X
  1112. #ifdef DBUG
  1113. _dump_dfa_stack(dfas, dfa_stack)
  1114. DFALINKPTR dfas;
  1115. DFASETPTR  dfa_stack;
  1116. {
  1117. X   register DFALINKPTR pdfa;
  1118. X   char      *tmp = NIL(char);
  1119. X   DFASETPTR ds;
  1120. X
  1121. X   for( pdfa = dfas; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next )
  1122. X      tmp = _strapp( tmp, pdfa->dl_meta->CE_NAME );
  1123. X
  1124. X   tmp = _strapp( tmp, ":: {" );
  1125. X   for( ds = dfa_stack; ds != NIL(DFASET); ds = ds->df_next ) {
  1126. X      tmp = _strapp( tmp, "[" );
  1127. X      for( pdfa = ds->df_set; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next )
  1128. X     tmp = _strapp( tmp, pdfa->dl_meta->CE_NAME );
  1129. X      tmp = _strapp( tmp, "]" );
  1130. X   }
  1131. X   tmp = _strapp( tmp, "}" );
  1132. X
  1133. X   printf( "DFA set and stack contents:\n%s\n", tmp );
  1134. X   FREE(tmp);
  1135. }
  1136. X
  1137. X
  1138. _dump_iset( name, iset )
  1139. char     *name;
  1140. ICELLPTR iset;
  1141. {
  1142. X   int cell = 0;
  1143. X
  1144. X   printf( "**** ISET for %s\n", name );
  1145. X   for( ; iset != NIL(ICELL); iset = iset->ic_next ){
  1146. X      printf( "cell %d\n", cell++ );
  1147. X      if( iset->ic_meta )
  1148. X     printf( "edge: %s --> %s\n", iset->ic_meta->CE_NAME,
  1149. X         iset->ic_meta->ce_prq ?
  1150. X         iset->ic_meta->ce_prq->cl_prq->CE_NAME :
  1151. X         "(nil)" );
  1152. X      else
  1153. X     printf( "edge: (nil)\n" );
  1154. X
  1155. X      if( iset->ic_dfa )
  1156. X     printf( "dfa: %s\n", iset->ic_dfa->dl_meta->CE_NAME );
  1157. X      else
  1158. X     printf( "dfa: (nil)\n" );
  1159. X
  1160. X      printf( "sdr: %04x\n", iset->ic_setdirroot );
  1161. X      _dump_dfa_stack(iset->ic_dfastack.df_set, &iset->ic_dfastack);
  1162. X
  1163. X      printf( "dmax: %d\n", iset->ic_dmax );
  1164. X      printf( "name: %s\n", iset->ic_name );
  1165. X      printf( "dir:  %s\n", iset->ic_dir?iset->ic_dir:"(nil)" );
  1166. X
  1167. X      printf( "parent: " );
  1168. X      if( iset->ic_parent )
  1169. X    if( iset->ic_parent->ic_meta )
  1170. X       printf( "%s --> %s\n",
  1171. X               iset->ic_parent->ic_meta->CE_NAME,
  1172. X           iset->ic_parent->ic_meta->ce_prq ?
  1173. X           iset->ic_parent->ic_meta->ce_prq->cl_prq->CE_NAME :
  1174. X           "(nil)" );
  1175. X    else
  1176. X       printf( "(nil)\n" );
  1177. X      else
  1178. X     printf( "(nil)\n" );
  1179. X   }
  1180. X   printf( "==================================\n" );
  1181. }
  1182. #endif
  1183. SHAR_EOF
  1184. chmod 0640 dmake/infer.c ||
  1185. echo 'restore of dmake/infer.c failed'
  1186. Wc_c="`wc -c < 'dmake/infer.c'`"
  1187. test 24179 -eq "$Wc_c" ||
  1188.     echo 'dmake/infer.c: original size 24179, current size' "$Wc_c"
  1189. rm -f _shar_wnt_.tmp
  1190. fi
  1191. # ============= dmake/itypes.h ==============
  1192. if test -f 'dmake/itypes.h' -a X"$1" != X"-c"; then
  1193.     echo 'x - skipping dmake/itypes.h (File already exists)'
  1194.     rm -f _shar_wnt_.tmp
  1195. else
  1196. > _shar_wnt_.tmp
  1197. sed 's/^X//' << 'SHAR_EOF' > 'dmake/itypes.h' &&
  1198. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/itypes.h,v 1.1 91/05/06 15:23:18 dvadura Exp $
  1199. -- SYNOPSIS -- type declarations for common types
  1200. -- 
  1201. -- DESCRIPTION
  1202. --     portable type declarations.
  1203. --
  1204. -- AUTHOR
  1205. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1206. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1207. --
  1208. -- COPYRIGHT
  1209. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1210. -- 
  1211. --      This program is free software; you can redistribute it and/or
  1212. --      modify it under the terms of the GNU General Public License
  1213. --      (version 1), as published by the Free Software Foundation, and
  1214. --      found in the file 'LICENSE' included with this distribution.
  1215. -- 
  1216. --      This program is distributed in the hope that it will be useful,
  1217. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1218. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1219. --      GNU General Public License for more details.
  1220. -- 
  1221. --      You should have received a copy of the GNU General Public License
  1222. --      along with this program;  if not, write to the Free Software
  1223. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1224. --
  1225. -- LOG
  1226. --     $Log:    itypes.h,v $
  1227. X * Revision 1.1  91/05/06  15:23:18  dvadura
  1228. X * dmake Release Version 3.7
  1229. X * 
  1230. */
  1231. X
  1232. X
  1233. #ifndef ITYPES_h
  1234. #define    ITYPES_h
  1235. X
  1236. #if defined(M_I86) || defined(MC68000)
  1237. typedef char  int8;               /* typedefs for right size ints */
  1238. typedef int   int16;
  1239. typedef long  int32;
  1240. typedef unsigned char  uint8;
  1241. typedef unsigned int   uint16;
  1242. typedef unsigned long  uint32;
  1243. #else
  1244. typedef char  int8;               /* typedefs for right size ints */
  1245. typedef short int16;
  1246. typedef long  int32;
  1247. typedef unsigned char  uint8;
  1248. typedef unsigned short uint16;
  1249. typedef unsigned long  uint32;
  1250. #endif
  1251. X
  1252. #endif
  1253. X
  1254. SHAR_EOF
  1255. chmod 0640 dmake/itypes.h ||
  1256. echo 'restore of dmake/itypes.h failed'
  1257. Wc_c="`wc -c < 'dmake/itypes.h'`"
  1258. test 1809 -eq "$Wc_c" ||
  1259.     echo 'dmake/itypes.h: original size 1809, current size' "$Wc_c"
  1260. rm -f _shar_wnt_.tmp
  1261. fi
  1262. # ============= dmake/macparse.c ==============
  1263. if test -f 'dmake/macparse.c' -a X"$1" != X"-c"; then
  1264.     echo 'x - skipping dmake/macparse.c (File already exists)'
  1265.     rm -f _shar_wnt_.tmp
  1266. else
  1267. > _shar_wnt_.tmp
  1268. sed 's/^X//' << 'SHAR_EOF' > 'dmake/macparse.c' &&
  1269. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/macparse.c,v 1.1 91/05/06 15:23:18 dvadura Exp $
  1270. -- SYNOPSIS -- parse a macro definition
  1271. -- 
  1272. -- DESCRIPTION
  1273. --    This file contains the code that parses a macro definition
  1274. --    stored in a buffer.  If the string in buffer is not a valid
  1275. --    macro definition the routie Parse_macro returns 0, otherwise it
  1276. --    returns 1 to indicate success.
  1277. -- 
  1278. -- AUTHOR
  1279. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1280. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1281. --
  1282. -- COPYRIGHT
  1283. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1284. -- 
  1285. --      This program is free software; you can redistribute it and/or
  1286. --      modify it under the terms of the GNU General Public License
  1287. --      (version 1), as published by the Free Software Foundation, and
  1288. --      found in the file 'LICENSE' included with this distribution.
  1289. -- 
  1290. --      This program is distributed in the hope that it will be useful,
  1291. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1292. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1293. --      GNU General Public License for more details.
  1294. -- 
  1295. --      You should have received a copy of the GNU General Public License
  1296. --      along with this program;  if not, write to the Free Software
  1297. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1298. --
  1299. -- LOG
  1300. --     $Log:    macparse.c,v $
  1301. X * Revision 1.1  91/05/06  15:23:18  dvadura
  1302. SHAR_EOF
  1303. true || echo 'restore of dmake/macparse.c failed'
  1304. fi
  1305. echo 'End of part 10, continue with part 11'
  1306. echo 11 > _shar_seq_.tmp
  1307. exit 0
  1308.  
  1309. exit 0 # Just in case...
  1310. -- 
  1311. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1312. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1313. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1314. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1315.