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

  1. Newsgroups: comp.sources.misc
  2. From: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  3. Subject:  v19i051:  dmake - dmake version 3.7, Part30/37
  4. Message-ID: <1991May13.145257.9543@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 4b5cc2e58ab802d51fec2a27153fe838
  6. Date: Mon, 13 May 1991 14:52:57 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  10. Posting-number: Volume 19, Issue 51
  11. Archive-name: dmake/part30
  12. Supersedes: dmake-3.6: Volume 15, Issue 52-77
  13.  
  14. ---- Cut Here and feed the following to sh ----
  15. #!/bin/sh
  16. # this is dmake.shar.30 (part 30 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file dmake/stat.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 30; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test -f _shar_wnt_.tmp; then
  33. sed 's/^X//' << 'SHAR_EOF' >> 'dmake/stat.c' &&
  34. X
  35. PUBLIC void
  36. Stat_target( cp, setfname )/*
  37. =============================
  38. X    Stat a target.  When doing so follow the following rules, suppose
  39. X    that cp->CE_NAME points at a target called fred.o:
  40. X
  41. X        0.      If A_SYMBOL attribute set look into the library
  42. X            then do the steps 1 thru 4 on the resulting name.
  43. X        1.    Try path's obtained by prepending any dirs found as
  44. X            prerequisites for .SOURCE.o.
  45. X        2.    If not found, do same as 2 but use .SOURCE
  46. X        3.    If not found and .LIBRARYM attribute for the target is
  47. X            set then look for it in the corresponding library.
  48. X            4.    If found in step 0 thru 3, then ce_fname points at
  49. X            file name associate with target, else ce_fname points
  50. X            at a file name built by the first .SOURCE* dir that
  51. X            applied. */
  52. X
  53. CELLPTR cp;
  54. int     setfname;
  55. {
  56. X   register HASHPTR hp;
  57. X   static   HASHPTR srchp = NIL(HASH);
  58. X   char            *name;
  59. X   char            *tmp;
  60. X   int            res = 0;
  61. X
  62. X   DB_ENTER( "Stat_target" );
  63. X
  64. X   name = cp->CE_NAME;
  65. X   if( srchp == NIL(HASH) ) srchp = Get_name(".SOURCE",Defs,FALSE);
  66. X
  67. X   /* Look for a symbol of the form lib((symbol)) the name of the symbol
  68. X    * as entered in the hash table is (symbol) so pull out symbol and try
  69. X    * to find it's module.  If successful DO_STAT will return the module
  70. X    * as well as the archive member name (pointed at by tmp).  We then
  71. X    * replace the symbol name with the archive member name so that we
  72. X    * have the proper name for any future refrences. */
  73. X
  74. X   if( cp->ce_attr & A_SYMBOL ) {
  75. X      DB_PRINT( "stat", ("Binding lib symbol [%s]", name) );
  76. X
  77. X      cp->ce_time = DO_STAT( name, cp->ce_lib, &tmp );
  78. X
  79. X      if( cp->ce_time != (time_t) 0L ) {
  80. X     /* stat the new member name below  note tmp must point at a string
  81. X      * returned by MALLOC... ie. the Do_stat code should use _strdup */
  82. X
  83. X     if( Verbose & V_MAKE )
  84. X        printf( "%s:  Mapped ((%s)) to %s(%s)\n", Pname,
  85. X             name, cp->ce_lib, tmp );
  86. X
  87. X         FREE( name );        
  88. X     name = cp->CE_NAME = tmp;        
  89. X     cp->ce_attr &= ~(A_FFNAME | A_SYMBOL);
  90. X      }
  91. X      else
  92. X         { DB_VOID_RETURN; }
  93. X   }
  94. X
  95. X   _first = NIL(char);
  96. X   tmp = _strjoin( ".SOURCE", Get_suffix( name ), -1, FALSE);
  97. X
  98. X   /* Check .SOURCE.xxx target */
  99. X   if( (hp = Get_name(tmp, Defs, FALSE)) != NIL(HASH) )
  100. X      res = _check_dir_list( cp, hp->CP_OWNR, setfname );
  101. X
  102. X   /* Check just .SOURCE */
  103. X   if( !res && (srchp != NIL(HASH)) )
  104. X      res = _check_dir_list( cp, srchp->CP_OWNR, setfname );
  105. X
  106. X   /* If libmember and we haven't found it check the library */
  107. X   if( !res && (cp->ce_attr & A_LIBRARYM) ) {
  108. X      cp->ce_time = DO_STAT(name, cp->ce_lib, NIL(char *));
  109. X
  110. X      if( !cp->ce_time && Tmd && *Tmd && cp->ce_lib ) {
  111. X     cp->ce_lib=Build_path(Tmd,cp->ce_lib);
  112. X     cp->ce_time = DO_STAT(name, cp->ce_lib, NIL(char *));
  113. X      }
  114. X
  115. X      if( Verbose & V_MAKE )
  116. X     printf( "%s:  Checking library '%s' for member [%s], time %ld\n",
  117. X         Pname, cp->ce_lib, name, cp->ce_time );
  118. X   }
  119. X
  120. X   FREE( tmp );
  121. X
  122. X   if( setfname == 1 || (setfname == -1 && cp->ce_time != (time_t)0L) ) {
  123. X      if( (cp->ce_attr & A_FFNAME) && (cp->ce_fname != NIL(char)) )
  124. X     FREE( cp->ce_fname );
  125. X
  126. X      if( _first != NIL(char) ) {
  127. X     cp->ce_fname = _first;
  128. X     cp->ce_attr |= A_FFNAME;
  129. X      }
  130. X      else {
  131. X     cp->ce_fname = cp->CE_NAME;
  132. X     cp->ce_attr &= ~A_FFNAME;
  133. X      }
  134. X   }
  135. X   else if( _first )
  136. X      FREE( _first );
  137. X
  138. X   /* set it as stated only if successful, this way, we shall try again
  139. X    * later. */
  140. X   if( cp->ce_time != (time_t)0L ) cp->ce_flag |= F_STAT;
  141. X
  142. X   DB_VOID_RETURN;
  143. }
  144. X
  145. X
  146. X
  147. static int
  148. _check_dir_list( cp, sp, setfname )/*
  149. =====================================
  150. X    Check the list of dir's given by the prerequisite list of sp, for a
  151. X    file pointed at by cp.  Returns 0 if path not bound, else returns
  152. X    1 and replaces old name for cell with new cell name. */
  153. X
  154. CELLPTR cp;
  155. CELLPTR sp;
  156. int     setfname;
  157. {
  158. X   register LINKPTR lp;
  159. X   char *dir;
  160. X   char *path;
  161. X   char *name;
  162. X   int  res  = 0;
  163. X   int  fset = 0;
  164. X
  165. X   DB_ENTER( "_check_dir_list" );
  166. X   DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) );
  167. X
  168. X   if( sp->ce_prq != NIL(LINK) )    /* check prerequisites if any */
  169. X   {
  170. X      /* Use the real name instead of basename, this prevents silly
  171. X       * loops in inference code, and is consistent with man page */
  172. X      name = cp->CE_NAME;
  173. X
  174. X      /* Here we loop through each directory on the list, and try to stat
  175. X       * the target.  We always save the first pathname we try and stat in
  176. X       * _first.  If we subsequently get a match we then replace the value of
  177. X       * _first by the matched path name.  */
  178. X
  179. X      for( lp=sp->CE_PRQ; lp != NIL(LINK) && !res; lp=lp->cl_next ) {
  180. X     int  nodup = 0;
  181. X     dir  = lp->cl_prq->CE_NAME;
  182. X
  183. X     if( strchr( dir, '$' ) ) dir = Expand(dir);
  184. X     if( strcmp( dir, ".NULL" ) == 0 ) {
  185. X        nodup = 1;
  186. X        path = cp->CE_NAME;
  187. X     }
  188. X     else
  189. X        path = Build_path( dir, name );
  190. X
  191. X     res = ((cp->ce_time = DO_STAT(path,NIL(char),NIL(char *))) != (time_t)0L);
  192. #if 0
  193. I think this will break a lot of things!
  194. X     /* It didn't work and TMD macro has a value so try to stat it
  195. X      * relative to the original MAKEDIR directory. */
  196. X     if( Tmd && !*Tmd && !res ) {
  197. X        char *p = _strdup(path);
  198. X        path = Build_path(Tmd,p); FREE(p);
  199. X        res = ((cp->ce_time = DO_STAT(path,NIL(char),NIL(char *))) != (time_t)0L);
  200. X     }
  201. #endif
  202. X
  203. X     /* Have to use _strdup to set _first since Build_path, builds it's
  204. X      * path names inside a static buffer. */
  205. X     if( setfname )
  206. X        if( (_first == NIL(char) && !fset) || res ) {
  207. X           if( _first != NIL(char) ) FREE( _first );
  208. X           _first = nodup ? NIL(char) : _strdup(path);
  209. X           fset = 1;
  210. X        }
  211. X
  212. X     DB_PRINT( "stat", ("_first [%s], path [%s]", _first, path) );
  213. X     if( dir != lp->cl_prq->CE_NAME )  FREE(dir);
  214. X      }
  215. X   }
  216. X
  217. X   DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) );
  218. X   DB_RETURN( res );
  219. }
  220. SHAR_EOF
  221. chmod 0640 dmake/stat.c ||
  222. echo 'restore of dmake/stat.c failed'
  223. Wc_c="`wc -c < 'dmake/stat.c'`"
  224. test 7761 -eq "$Wc_c" ||
  225.     echo 'dmake/stat.c: original size 7761, current size' "$Wc_c"
  226. rm -f _shar_wnt_.tmp
  227. fi
  228. # ============= dmake/state.c ==============
  229. if test -f 'dmake/state.c' -a X"$1" != X"-c"; then
  230.     echo 'x - skipping dmake/state.c (File already exists)'
  231.     rm -f _shar_wnt_.tmp
  232. else
  233. > _shar_wnt_.tmp
  234. sed 's/^X//' << 'SHAR_EOF' > 'dmake/state.c' &&
  235. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/state.c,v 1.1 91/05/06 15:23:31 dvadura Exp $
  236. -- SYNOPSIS -- .KEEP_STATE state file management
  237. -- 
  238. -- DESCRIPTION
  239. --     Three routines to interface to the .KEEP_STATE state file.
  240. --
  241. --        Read_state()    - reads the state file if any.
  242. --        Write_state()    - writes the state file.
  243. --
  244. --        Check_state(cp,how) - checks an entry returns 0 or 1
  245. --                      and updates the entry.
  246. --
  247. -- AUTHOR
  248. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  249. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  250. --
  251. -- COPYRIGHT
  252. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  253. -- 
  254. --      This program is free software; you can redistribute it and/or
  255. --      modify it under the terms of the GNU General Public License
  256. --      (version 1), as published by the Free Software Foundation, and
  257. --      found in the file 'LICENSE' included with this distribution.
  258. -- 
  259. --      This program is distributed in the hope that it will be useful,
  260. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  261. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  262. --      GNU General Public License for more details.
  263. -- 
  264. --      You should have received a copy of the GNU General Public License
  265. --      along with this program;  if not, write to the Free Software
  266. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  267. --
  268. -- LOG
  269. --     $Log:    state.c,v $
  270. X * Revision 1.1  91/05/06  15:23:31  dvadura
  271. X * dmake Release Version 3.7
  272. X * 
  273. */
  274. X
  275. #include "extern.h"
  276. X
  277. typedef struct se {
  278. X   char        *st_name;        /* name of cell        */
  279. X   uint32    st_nkey;        /* name hash key    */
  280. X   int        st_count;        /* how count for how    */
  281. X   uint32    st_dkey;        /* directory hash key    */
  282. X   uint32    st_key;            /* hash key        */
  283. X   struct se    *st_next;
  284. } KSTATE, *KSTATEPTR;
  285. X
  286. static KSTATEPTR _st_head  = NIL(KSTATE);
  287. static KSTATEPTR _st_tail  = NIL(KSTATE);
  288. static int       _st_upd   = FALSE;
  289. static char     *_st_file  = NIL(char);
  290. X
  291. static int  _my_fgets ANSI((char *, int, FILE *));
  292. X
  293. PUBLIC void
  294. Read_state()
  295. {
  296. X   char *buf;
  297. X   char sizeb[20];
  298. X   int  size;
  299. X   FILE *fp;
  300. X   KSTATEPTR sp;
  301. X
  302. X   if( (fp = Search_file(".KEEP_STATE", &_st_file)) != NIL(FILE) ) {
  303. X      if( _my_fgets( sizeb, 20, fp ) ) {
  304. X     size = atol(sizeb);
  305. X     buf = MALLOC(size+2, char);
  306. X
  307. X     while( _my_fgets(buf, size, fp) != NULL ) {
  308. X        TALLOC(sp, 1, KSTATE);
  309. X        sp->st_name = _strdup(buf);
  310. X        (void) Hash(buf, &sp->st_nkey);
  311. X
  312. X        if( _my_fgets(buf, size, fp) ) sp->st_count = atoi(buf);
  313. X        if( _my_fgets(buf, size, fp) ) sp->st_dkey   = (uint32) atol(buf);
  314. X
  315. X        if( _my_fgets(buf, size, fp) )
  316. X           sp->st_key = (uint32) atol(buf);
  317. X        else {
  318. X           FREE(sp);
  319. X           break;
  320. X        }
  321. X
  322. X        if( _st_head == NIL(KSTATE) )
  323. X           _st_head = sp;
  324. X        else
  325. X           _st_tail->st_next = sp;
  326. X
  327. X        _st_tail = sp;
  328. X     }
  329. X
  330. X     FREE(buf);
  331. X      }
  332. X
  333. X      Closefile(fp);
  334. X   }
  335. }
  336. X
  337. X
  338. PUBLIC void
  339. Write_state()
  340. {
  341. X   static int in_write = 0;
  342. X   register KSTATEPTR sp;
  343. X   FILE *fp;
  344. X
  345. X   if( !_st_upd || !_st_file || (_st_file && !*_st_file) ||
  346. X       Trace || in_write ) return;
  347. X
  348. X   in_write++;
  349. X   if( (fp = Openfile(_st_file, TRUE, TRUE)) != NIL(FILE) ) {
  350. X      int maxlen = 0;
  351. X      int tmplen;
  352. X
  353. X      for( sp = _st_head; sp; sp=sp->st_next )
  354. X     if( (tmplen = strlen(sp->st_name)) > maxlen )
  355. X        maxlen = tmplen;
  356. X
  357. X      /* A nice arbitrary minimum size */
  358. X      if( maxlen < 20 ) maxlen = 20;
  359. X      fprintf( fp, "%d\n", maxlen );
  360. X
  361. X      for( sp = _st_head; sp; sp=sp->st_next ) {
  362. X     uint16 hv;
  363. X     uint32 hk;
  364. X
  365. X     if( Search_table(Defs, sp->st_name, &hv, &hk) ) {
  366. X        fprintf( fp, "%s\n",  sp->st_name   );
  367. X        fprintf( fp, "%d\n",  sp->st_count );
  368. X        fprintf( fp, "%lu\n", sp->st_dkey   );
  369. X        fprintf( fp, "%lu\n", sp->st_key    );
  370. X     }
  371. X      }
  372. X
  373. X      Closefile();
  374. X   }
  375. X   else
  376. X      Fatal("Cannot open STATE file %s", _st_file);
  377. X
  378. X   in_write = 0;
  379. }
  380. X
  381. X
  382. PUBLIC int
  383. Check_state( cp, recipes, maxrcp )
  384. CELLPTR cp;
  385. STRINGPTR *recipes;
  386. int  maxrcp;
  387. {
  388. X   KSTATEPTR  st;
  389. X   STRINGPTR sp;
  390. X   int    i;
  391. X   uint32 thkey;
  392. X   uint32 hkey;
  393. X   uint32 nkey;
  394. X   uint32 dkey;
  395. X   int    update = FALSE;
  396. X
  397. X   if(    strcmp(cp->CE_NAME,".REMOVE") == 0
  398. X       || (cp->ce_attr & (A_PHONY|A_NOSTATE)) )
  399. X      return(FALSE);
  400. X
  401. X   (void) Hash( cp->CE_NAME, &nkey ); thkey = nkey + (uint32) cp->ce_count;
  402. X   (void) Hash( Pwd,  &dkey ); thkey += dkey;
  403. X
  404. X   Suppress_temp_file = TRUE;
  405. X   for( i=0 ; i<maxrcp; i++ )
  406. X      for(sp=recipes[i]; sp != NIL(STRING); sp=sp->st_next ) {
  407. X     char *cmnd = Expand(sp->st_string);
  408. X
  409. X     (void) Hash(cmnd, &hkey); thkey += hkey;
  410. X     FREE(cmnd);
  411. X      }
  412. X   Suppress_temp_file = FALSE;
  413. X
  414. X   for( st=_st_head; st != NIL(KSTATE); st=st->st_next ) {
  415. X      if(    st->st_nkey   == nkey
  416. X      && st->st_dkey   == dkey
  417. X      && st->st_count  == cp->ce_count
  418. X      && !strcmp(cp->CE_NAME, st->st_name) )
  419. X     break;
  420. X   }
  421. X
  422. X   if( st == NIL(KSTATE) ) {
  423. X      KSTATEPTR nst;
  424. X
  425. X      TALLOC(nst, 1, KSTATE);
  426. X      nst->st_name = cp->CE_NAME;
  427. X      nst->st_nkey = nkey;
  428. X      nst->st_dkey = dkey;
  429. X      nst->st_key  = thkey;
  430. X      nst->st_count = cp->ce_count;
  431. X
  432. X      if( _st_head == NIL(KSTATE) )
  433. X     _st_head = nst;
  434. X      else
  435. X     _st_tail->st_next = nst;
  436. X
  437. X      _st_tail = nst;
  438. X      _st_upd  = TRUE;
  439. X   }
  440. X   else if( st->st_key != thkey ) {
  441. X      st->st_key = thkey;
  442. X      _st_upd = update = TRUE;
  443. X   }
  444. X
  445. X   return(st != NIL(KSTATE) && update);
  446. }
  447. X
  448. X
  449. static int
  450. _my_fgets(buf, size, fp)
  451. char *buf;
  452. int  size;
  453. FILE *fp;
  454. {
  455. X   char *p;
  456. X
  457. X   if( fgets(buf, size, fp) == NULL ) return(0);
  458. X
  459. X   if( (p=strrchr(buf,'\n')) != NIL(char) ) *p='\0';
  460. X   return(1);
  461. }
  462. SHAR_EOF
  463. chmod 0640 dmake/state.c ||
  464. echo 'restore of dmake/state.c failed'
  465. Wc_c="`wc -c < 'dmake/state.c'`"
  466. test 5520 -eq "$Wc_c" ||
  467.     echo 'dmake/state.c: original size 5520, current size' "$Wc_c"
  468. rm -f _shar_wnt_.tmp
  469. fi
  470. # ============= dmake/stdmacs.h ==============
  471. if test -f 'dmake/stdmacs.h' -a X"$1" != X"-c"; then
  472.     echo 'x - skipping dmake/stdmacs.h (File already exists)'
  473.     rm -f _shar_wnt_.tmp
  474. else
  475. > _shar_wnt_.tmp
  476. sed 's/^X//' << 'SHAR_EOF' > 'dmake/stdmacs.h' &&
  477. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/stdmacs.h,v 1.1 91/05/06 15:23:32 dvadura Exp $
  478. -- SYNOPSIS -- general use macros.
  479. -- 
  480. -- DESCRIPTION
  481. --     ANSI macro relies on the fact that it can be replaced by (), or by
  482. --    its value, where the value is one value due to the preprocessors
  483. --    handling of arguments that are surrounded by ()'s as a single
  484. --    argument.
  485. --
  486. -- AUTHOR
  487. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  488. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  489. --
  490. -- COPYRIGHT
  491. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  492. -- 
  493. --      This program is free software; you can redistribute it and/or
  494. --      modify it under the terms of the GNU General Public License
  495. --      (version 1), as published by the Free Software Foundation, and
  496. --      found in the file 'LICENSE' included with this distribution.
  497. -- 
  498. --      This program is distributed in the hope that it will be useful,
  499. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  500. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  501. --      GNU General Public License for more details.
  502. -- 
  503. --      You should have received a copy of the GNU General Public License
  504. --      along with this program;  if not, write to the Free Software
  505. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  506. --
  507. -- LOG
  508. --     $Log:    stdmacs.h,v $
  509. X * Revision 1.1  91/05/06  15:23:32  dvadura
  510. X * dmake Release Version 3.7
  511. X * 
  512. */
  513. X
  514. #ifndef    MACROS_h
  515. #define    MACROS_h
  516. X
  517. /* stupid AIX defines __STDC__ as special, but defined(__STDC__) is false, and
  518. X * it's value is nothing */
  519. #if !defined(__STDC__) && !defined(_AIX)
  520. #define __STDC__ 0
  521. #endif
  522. X
  523. #if __STDC__ || defined(__TURBOC__)
  524. #define    ANSI(x)    x
  525. #else
  526. #define    ANSI(x)    ()
  527. #endif
  528. X
  529. #define    NIL(p)    ((p*)NULL)
  530. X
  531. #if !defined(atarist)
  532. #define    offsetof(type,id) ((size_t)&((type*)NULL)->id)
  533. #endif
  534. X
  535. #define    FALSE    0
  536. #define    TRUE    1
  537. X
  538. #define PUBLIC
  539. X
  540. #endif
  541. X
  542. SHAR_EOF
  543. chmod 0640 dmake/stdmacs.h ||
  544. echo 'restore of dmake/stdmacs.h failed'
  545. Wc_c="`wc -c < 'dmake/stdmacs.h'`"
  546. test 1943 -eq "$Wc_c" ||
  547.     echo 'dmake/stdmacs.h: original size 1943, current size' "$Wc_c"
  548. rm -f _shar_wnt_.tmp
  549. fi
  550. # ============= dmake/struct.h ==============
  551. if test -f 'dmake/struct.h' -a X"$1" != X"-c"; then
  552.     echo 'x - skipping dmake/struct.h (File already exists)'
  553.     rm -f _shar_wnt_.tmp
  554. else
  555. > _shar_wnt_.tmp
  556. sed 's/^X//' << 'SHAR_EOF' > 'dmake/struct.h' &&
  557. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/struct.h,v 1.1 91/05/06 15:23:33 dvadura Exp $
  558. -- SYNOPSIS -- structure definitions
  559. -- 
  560. -- DESCRIPTION
  561. --    dmake main data structure definitions.  See each of the individual
  562. --    struct declarations for more detailed information on the defined
  563. --    fields and their use.
  564. -- 
  565. -- AUTHOR
  566. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  567. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  568. --
  569. -- COPYRIGHT
  570. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  571. -- 
  572. --      This program is free software; you can redistribute it and/or
  573. --      modify it under the terms of the GNU General Public License
  574. --      (version 1), as published by the Free Software Foundation, and
  575. --      found in the file 'LICENSE' included with this distribution.
  576. -- 
  577. --      This program is distributed in the hope that it will be useful,
  578. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  579. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  580. --      GNU General Public License for more details.
  581. -- 
  582. --      You should have received a copy of the GNU General Public License
  583. --      along with this program;  if not, write to the Free Software
  584. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  585. --
  586. -- LOG
  587. --     $Log:    struct.h,v $
  588. X * Revision 1.1  91/05/06  15:23:33  dvadura
  589. X * dmake Release Version 3.7
  590. X * 
  591. */
  592. X
  593. #ifndef _STRUCT_INCLUDED_
  594. #define _STRUCT_INCLUDED_
  595. X
  596. typedef uint32 t_attr;
  597. X
  598. /* The following struct is the cell used in the hash table.
  599. X * NOTE:  It contains the actual hash value.  This allows the hash table
  600. X *        insertion to compare hash values and to do a string compare only
  601. X *        for entries that have matching hash_key values.  This elliminates
  602. X *        99.9999% of all extraneous string compare operations when searching
  603. X *        a hash table chain for matching entries.  */
  604. X
  605. typedef struct hcell {
  606. X    struct hcell    *ht_next;    /* next entry in the hash table */
  607. X    char        *ht_name;    /* name of this cell */
  608. X    char        *ht_value;    /* cell value if and */
  609. X    uint32        ht_hash;    /* actual hash_value of cell */
  610. X    int        ht_flag;    /* flags belonging to hash entry */
  611. X
  612. X    /* NOTE: some macros have corresponding variables defined
  613. X     * that control program behaviour.  For these macros a
  614. X     * bit of ht_flag indicates the variable value will be set, and the
  615. X     * type of the value that will be set.
  616. X     *
  617. X     * The struct below contains a mask for bit variables, and a
  618. X     * pointer to the global STATIC location for that variable.
  619. X     * String and char variables point to the same place as ht_value
  620. X     * and must be updated when ht_value changes, bit variables must
  621. X     * have their value recomputed. See Def_macro code for more
  622. X     * details.
  623. X     *
  624. X     * NOTE:  Macro variables and Targets are always distinct.  Thus
  625. X     * the value union contains pointers back at cells that own
  626. X     * a particular name entry.  A conflict in this can never
  627. X     * arise, ie pointers at cells will never be used as
  628. X     * values for a macro variable, since the cell and macro
  629. X     * name spaces are completely distinct. */
  630. X
  631. X    struct {
  632. X        int    mv_mask;    /* bit mask for bit variable      */
  633. X        union {
  634. X             char**    mv_svar;/* ptr to string valued glob var  */
  635. X            char*    mv_cvar;/* ptr to char   valued glob var */
  636. X            t_attr*    mv_bvar;/* ptr to bit    valued glob var */
  637. X             int*    mv_ivar;/* ptr to int    valued glob var  */
  638. X
  639. X            struct {
  640. X               struct tcell*  ht_owner;/* ptr to CELL owning name */
  641. X               struct tcell*  ht_root; /* root ptr for explode */
  642. X            } ht;
  643. X        } val;
  644. X    } var;                /* variable's static equivalent */
  645. } HASH, *HASHPTR;
  646. X
  647. #define MV_MASK        var.mv_mask
  648. #define MV_SVAR     var.val.mv_svar
  649. #define MV_CVAR     var.val.mv_cvar
  650. #define MV_BVAR     var.val.mv_bvar
  651. #define MV_IVAR     var.val.mv_ivar
  652. #define CP_OWNR         var.val.ht.ht_owner
  653. #define CP_ROOT         var.val.ht.ht_root
  654. X
  655. X
  656. X
  657. /* This struct holds the list of temporary files that have been created.
  658. X * It gets unlinked when Quit is called due to an execution error */
  659. typedef struct flst {
  660. X   char        *fl_name;    /* file name         */
  661. X   FILE        *fl_file;    /* the open file    */
  662. X   struct flst  *fl_next;    /* pointer to next file */
  663. } FILELIST, *FILELISTPTR;
  664. X
  665. X
  666. X
  667. /* This is the structure of a target cell in the dag which represents the
  668. X * graph of dependencies.  Each possible target is represented as a cell.
  669. X * 
  670. X * Each cell contains a pointer to the hash table entry for this cell.
  671. X * The hash table entry records the name of the cell. */
  672. X
  673. typedef struct tcell {
  674. X    struct hcell    *ce_name;    /* name of this cell                */
  675. X
  676. X    struct tcell    *ce_all;    /* link for grouping UPDATEALL cells*/
  677. X    struct tcell    *ce_setdir;    /* SETDIR ROOT pointer for this cell*/
  678. X    struct tcell    *ce_link;    /* link for temporary list making   */
  679. X
  680. X    struct lcell    *ce_prq;    /* list of prerequisites for cell   */
  681. X    struct lcell    *ce_indprq;    /* indirect prerequisites for % cell*/
  682. X
  683. X    struct str      *ce_recipe;    /* recipe for making this cell      */
  684. X    FILELISTPTR     ce_files;    /* list of temporary files for cell */
  685. X
  686. X    char         *ce_per;    /* value of % in %-meta expansion   */
  687. X    char        *ce_fname;    /* file name associated with target */
  688. X    char        *ce_lib;    /* archive name, if A_LIBRARYM      */
  689. X    char        *ce_dir;    /* value for .SETDIR attribute      */
  690. X
  691. X    int        ce_count;    /* value for :: recipe set          */
  692. X    int        ce_index;    /* value of count for next :: child */
  693. X    int           ce_flag;    /* all kinds of goodies            */
  694. X    t_attr        ce_attr;    /* attributes for this target        */
  695. X    time_t        ce_time;    /* time stamp value of target if any*/
  696. } CELL, *CELLPTR;
  697. X
  698. #define CE_NAME        ce_name->ht_name
  699. #define CE_RECIPE       ce_recipe
  700. #define CE_PRQ          ce_prq
  701. X
  702. X
  703. /* This struct represents that used by Get_token to return and control
  704. X * access to a token list inside a particular string.  This gives the
  705. X * ability to access non overlapping tokens simultaneously from
  706. X * multiple strings. */
  707. X    
  708. typedef struct {
  709. X    char *tk_str;              /* the string to search for tokens  */
  710. X    char tk_cchar;             /* current char under *str          */
  711. X    int  tk_quote;               /* if we are scanning a quoted str  */
  712. }  TKSTR, *TKSTRPTR;
  713. X
  714. X
  715. X
  716. /* Below is the struct used to represent a string.  It points at possibly
  717. X * another string, since the set of rules for making a target is a collection
  718. X * of strings. */
  719. X
  720. X
  721. typedef struct str {
  722. X    char        *st_string;    /* the string value */
  723. X    struct str    *st_next;    /* pointer to the next string */
  724. X    t_attr        st_attr;    /* attr for rule operations */
  725. } STRING, *STRINGPTR;
  726. X
  727. X
  728. /* The next struct is used to link together prerequisite lists */
  729. X
  730. typedef struct lcell {
  731. X    struct tcell    *cl_prq;    /* link to a prerequisite     */
  732. X    struct lcell    *cl_next;    /* next cell on dependency list */
  733. X    int        cl_flag;    /* flags for link cell        */
  734. } LINK, *LINKPTR;
  735. X
  736. X
  737. X
  738. /* These structs are used in processing of the % rules, and in building
  739. X * the NFA machine that is used to match an arbitrary target string to
  740. X * one of the % rules that is represented by each DFA */
  741. X
  742. typedef int16 statecnt;        /* limits the max number of dfa states    */
  743. X
  744. X
  745. /* Each state of the DFA contains four pieces of information. */
  746. typedef struct st {
  747. X    struct st    *no_match;    /* state to go to if no match */
  748. X    struct st    *match;        /* state to go to if we do match */
  749. X    char        symbol;        /* symbol on which we transit */
  750. X    char        action;        /* action to perform if match */
  751. } STATE, *STATEPTR;
  752. X
  753. X
  754. /* Each DFA machine looks like this.  It must have two pointers that represent
  755. X * the value of % in the matched string, and it contains a pointer into the
  756. X * current state, as well as the array of all states. */
  757. typedef struct {
  758. X    char        *pstart;    /* start of % string match */
  759. X    char        *pend;        /* end of % string match */
  760. X    STATEPTR    c_state;    /* current DFA state */
  761. X    CELLPTR        node;        /* % target represented by this DFA */
  762. X    STATEPTR    states;        /* table of states for the DFA */
  763. } DFA, *DFAPTR;
  764. X
  765. X
  766. /* An NFA is a collection of DFA's.  For each DFA we must know it's current
  767. X * state and where the next NFA is. */
  768. typedef struct nfa_machine {
  769. X    DFAPTR        dfa;        /* The DFA for this eps transition */
  770. X    char        status;        /* DFA state */
  771. X    struct nfa_machine *next;     /* the next DFA in NFA */
  772. } NFA, *NFAPTR;
  773. X
  774. X
  775. X
  776. /* The next struct is used to link together DFA nodes for inference. */
  777. X
  778. typedef struct dfal {
  779. X    struct tcell    *dl_meta;    /* link to %-meta cell        */
  780. X    struct dfal    *dl_next;    /* next cell on matched DFA list*/
  781. X    struct dfal    *dl_prev;    /* prev cell on matched DFA list*/
  782. X    struct dfal    *dl_member;    /* used during subset calc    */
  783. X    char        dl_delete;    /* used during subset calc    */
  784. X    char           *dl_per;    /* value of % for matched DFA   */
  785. X    statecnt        dl_state;    /* matched state of the DFA    */
  786. X    int        dl_prep;    /* repetion count for the cell    */
  787. } DFALINK, *DFALINKPTR;
  788. X
  789. X
  790. /* This struct is used to store the stack of DFA sets during inference */
  791. typedef struct dfst {
  792. X   DFALINKPTR    df_set;            /* pointer to the set        */
  793. X   struct dfst *df_next;        /* next element in the stack    */
  794. } DFASET, *DFASETPTR;
  795. X
  796. X
  797. /* We need sets of items during inference, here is the item, we form sets
  798. X * by linking them together. */
  799. X
  800. typedef struct ic {
  801. X   CELLPTR    ic_meta;        /* Edge we used to make this cell*/
  802. X   DFALINKPTR   ic_dfa;            /* Dfa that we matched against     */
  803. X   CELLPTR    ic_setdirroot;        /* setdir root pointer for cell     */
  804. X   DFASET       ic_dfastack;        /* set of dfas we're working with*/
  805. X   int        ic_dmax;        /* max depth of cycles in graph  */
  806. X   char           *ic_name;        /* name of the cell to insert    */
  807. X   char        *ic_dir;            /* dir to CD to prior to recurse */
  808. X   struct ic   *ic_next;        /* next pointer to link         */
  809. X   struct ic   *ic_link;        /* link all ICELL'S together     */
  810. X   struct ic   *ic_parent;        /* pointer to post-requisite     */
  811. X   char        ic_flag;        /* flag, used for NOINFER only     */
  812. X   char         ic_exists;        /* TRUE if prerequisite exists     */
  813. } ICELL, *ICELLPTR;
  814. X
  815. #endif
  816. SHAR_EOF
  817. chmod 0640 dmake/struct.h ||
  818. echo 'restore of dmake/struct.h failed'
  819. Wc_c="`wc -c < 'dmake/struct.h'`"
  820. test 9748 -eq "$Wc_c" ||
  821.     echo 'dmake/struct.h: original size 9748, current size' "$Wc_c"
  822. rm -f _shar_wnt_.tmp
  823. fi
  824. # ============= dmake/sysintf.c ==============
  825. if test -f 'dmake/sysintf.c' -a X"$1" != X"-c"; then
  826.     echo 'x - skipping dmake/sysintf.c (File already exists)'
  827.     rm -f _shar_wnt_.tmp
  828. else
  829. > _shar_wnt_.tmp
  830. sed 's/^X//' << 'SHAR_EOF' > 'dmake/sysintf.c' &&
  831. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/sysintf.c,v 1.1 91/05/06 15:23:35 dvadura Exp $
  832. -- SYNOPSIS -- system independent interface
  833. -- 
  834. -- DESCRIPTION
  835. --    These are the routines constituting the system interface.
  836. --    The system is taken to be essentially POSIX conformant.
  837. --    The original code was extensively revised by T J Thompson at MKS,
  838. --    and the library cacheing was added by Eric Gisin at MKS.  I then
  839. --    revised the code yet again, to improve the lib cacheing, and to
  840. --    make it more portable.
  841. --
  842. --    The following is a list of routines that are required by this file
  843. --    in order to work.  These routines are provided as functions by the
  844. --    standard C lib of the target system or as #defines in system/sysintf.h
  845. --    or via appropriate C code in the system/ directory for the given
  846. --    system.
  847. --
  848. --    The first group must be provided by a file in the system/ directory
  849. --    the second group is ideally provided by the C lib.  However, there
  850. --    are instances where the C lib implementation of the specified routine
  851. --    does not exist, or is incorrect.  In these instances the routine
  852. --    must be provided by the the user in the system/ directory of dmake.
  853. --    (For example, the bsd/ dir contains code for putenv(), and tempnam())
  854. --
  855. --    DMAKE SPECIFIC:
  856. --        seek_arch()
  857. --        touch_arch()
  858. --        void_lcache()
  859. --        runargv()
  860. --        STAT()
  861. --        Remove_prq()
  862. --
  863. --    C-LIB SPECIFIC:  (should be present in your C-lib)
  864. --        utime()
  865. --        time()
  866. --        getenv()
  867. --        putenv()
  868. --        getcwd()
  869. --        signal()
  870. --        chdir()
  871. --        tempnam()
  872. -- 
  873. -- AUTHOR
  874. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  875. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  876. --
  877. -- COPYRIGHT
  878. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  879. -- 
  880. --      This program is free software; you can redistribute it and/or
  881. --      modify it under the terms of the GNU General Public License
  882. --      (version 1), as published by the Free Software Foundation, and
  883. --      found in the file 'LICENSE' included with this distribution.
  884. -- 
  885. --      This program is distributed in the hope that it will be useful,
  886. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  887. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  888. --      GNU General Public License for more details.
  889. -- 
  890. --      You should have received a copy of the GNU General Public License
  891. --      along with this program;  if not, write to the Free Software
  892. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  893. --
  894. -- LOG
  895. --     $Log:    sysintf.c,v $
  896. X * Revision 1.1  91/05/06  15:23:35  dvadura
  897. X * dmake Release Version 3.7
  898. X * 
  899. */
  900. X
  901. #include "extern.h"
  902. #include "sysintf.h"
  903. X
  904. /*
  905. ** Tries to stat the file name.  Returns 0 if the file
  906. ** does not exist.  Note that if lib is not null it tries to stat
  907. ** the name found inside lib.
  908. **
  909. ** If member is NOT nil then look for the library object which defines the
  910. ** symbol given by name.  If found _strdup the name and return make the
  911. ** pointer pointed at by sym point at it.  Not handled for now!
  912. */
  913. PUBLIC time_t
  914. Do_stat(name, lib, member)
  915. char *name;
  916. char *lib;
  917. char **member;
  918. {
  919. X   struct stat buf;
  920. X   time_t seek_arch();
  921. X
  922. X   if( member != NIL(char *) )
  923. X      Fatal("Library symbol names not supported");
  924. X
  925. X   buf.st_mtime = (time_t)0L;
  926. X   if( lib != NIL(char) )
  927. X      return( seek_arch(basename(name), lib) );
  928. X   else
  929. X      return( (STAT(name,&buf)==-1 || (Augmake && (buf.st_mode & S_IFDIR)))
  930. X          ? (time_t)0L
  931. X          : (time_t) buf.st_mtime
  932. X        );
  933. }
  934. X
  935. X
  936. X
  937. /* Touch existing file to force modify time to present.
  938. X */
  939. PUBLIC int
  940. Do_touch(name, lib, member)
  941. char *name;
  942. char *lib;
  943. char **member;
  944. {
  945. X   if( member != NIL(char *) )
  946. X      Fatal("Library symbol names not supported");
  947. X
  948. X   if (lib != NIL(char))
  949. X      return( touch_arch(basename(name), lib) );
  950. X   else
  951. X      return( utime(name, NIL(time_t)) );
  952. }
  953. X
  954. X
  955. X
  956. PUBLIC void
  957. Void_lib_cache( lib_name, member_name )/*
  958. =========================================
  959. X   Void the library cache for lib lib_name, and member member_name. */
  960. char *lib_name;
  961. char *member_name;
  962. {
  963. X   VOID_LCACHE( lib_name, member_name );
  964. }
  965. X
  966. X
  967. X
  968. /*
  969. ** return the current time
  970. */
  971. PUBLIC time_t
  972. Do_time()
  973. {
  974. X   extern time_t time();
  975. X   return (time((time_t*)0));
  976. }
  977. X
  978. X
  979. X
  980. /*
  981. ** Execute the string passed in as a command and return
  982. ** the return code. The command line arguments are
  983. ** assumed to be separated by spaces or tabs.  The first
  984. ** such argument is assumed to be the command.
  985. **
  986. ** If group is true then this is a group of commands to be fed to the
  987. ** the shell as a single unit.  In this case cmd is of the form
  988. ** "file" indicating the file that should be read by the shell
  989. ** in order to execute the command group.
  990. */
  991. PUBLIC int
  992. Do_cmnd(cmd, group, do_it, target, ignore, shell, last)
  993. char   *cmd;
  994. int     group;
  995. int    do_it;
  996. CELLPTR target;
  997. int     ignore;
  998. int     shell;
  999. int    last;
  1000. {
  1001. X   int  i;
  1002. X
  1003. X   if( !do_it ) {
  1004. X      if( last && !Doing_bang ) {
  1005. X         Update_time_stamp( target );
  1006. X      }
  1007. X      return(0);
  1008. X   }
  1009. X
  1010. X   if( Max_proc == 1 ) Wait_for_completion = TRUE;
  1011. X
  1012. X   if( (i = runargv(target, ignore, group, last, shell, cmd)) == -1 )
  1013. X      Quit();
  1014. X
  1015. X   /* NOTE:  runargv must return either 0 or 1, 0 ==> command executed, and
  1016. X    * we waited for it to return, 1 ==> command started and is running
  1017. X    * concurrently with make process. */
  1018. X   return(i);
  1019. }
  1020. X
  1021. X
  1022. #define MINARGV 64
  1023. /* Take a command and pack it into an argument vector to be executed. */
  1024. PUBLIC char **
  1025. Pack_argv( group, shell, cmd )
  1026. int    group;
  1027. int    shell;
  1028. char  *cmd;
  1029. {
  1030. X   static char **av = NIL(char *);
  1031. X   static int   avs = 0;
  1032. X   int i = 0;
  1033. X
  1034. X   if( av == NIL(char *) ) {
  1035. X      TALLOC(av, MINARGV, char*);
  1036. X      avs = MINARGV;
  1037. X   }
  1038. X
  1039. X   if( (Packed_shell = shell||group||(*_strpbrk(cmd, Shell_metas)!='\0')) ) {
  1040. X      char* sh = group ? GShell : Shell;
  1041. X
  1042. X      if( sh != NIL(char) ) {
  1043. X         av[i++] = sh;
  1044. X         if( (av[i] = (group?GShell_flags:Shell_flags)) != NIL(char) ) i++;
  1045. X
  1046. X     av[i++] = cmd;
  1047. X     av[i]   = NIL(char);
  1048. X      }
  1049. X      else
  1050. X     Fatal("%sSHELL macro not defined", group?"GROUP":"");
  1051. X   }
  1052. X   else {
  1053. X      do {
  1054. X         while( iswhite(*cmd) ) ++cmd;
  1055. X         if( *cmd ) av[i++] = cmd;
  1056. X
  1057. X         while( *cmd != '\0' && !iswhite(*cmd) ) ++cmd;
  1058. X         if( *cmd ) *cmd++ = '\0';
  1059. X
  1060. X     if( i == avs ) {
  1061. X        avs += MINARGV;
  1062. X        av = (char **) realloc( av, avs*sizeof(char *) );
  1063. X     }
  1064. X      } while( *cmd );
  1065. X
  1066. X      av[i] = NIL(char);
  1067. X   }
  1068. X
  1069. X   return(av);
  1070. }
  1071. X
  1072. X
  1073. /*
  1074. ** Return the value of ename from the environment
  1075. ** if ename is not defined in the environment then
  1076. ** NIL(char) should be returned
  1077. */
  1078. PUBLIC char *
  1079. Read_env_string(ename)
  1080. char *ename;
  1081. {
  1082. #if !defined(_MSC_VER) || _MSC_VER < 600
  1083. X   extern char *getenv();
  1084. #endif
  1085. X   return( getenv(ename) );
  1086. }
  1087. X
  1088. X
  1089. X
  1090. /*
  1091. ** Set the value of the environment string ename to value.
  1092. **  Returns 0 if success, non-zero if failure
  1093. */
  1094. PUBLIC int
  1095. Write_env_string(ename, value)
  1096. char *ename;
  1097. char *value;
  1098. {
  1099. X   extern int putenv();
  1100. X   char*   p;
  1101. X   char*   envstr = _stradd(ename, value, FALSE);
  1102. X
  1103. X   p = envstr+strlen(ename);    /* Don't change this code, _stradd does not */
  1104. X   *p++ = '=';            /* add the space if *value is 0, it does    */
  1105. X   if( !*value ) *p = '\0';    /* allocate enough memory for one though.   */
  1106. X
  1107. X   return( putenv(envstr) );
  1108. }
  1109. X
  1110. X
  1111. X
  1112. PUBLIC void
  1113. ReadEnvironment()
  1114. {
  1115. X   extern char **Rule_tab;
  1116. #if !defined(_MSC_VER)
  1117. X   extern char **environ;
  1118. #endif
  1119. X   char **rsave;
  1120. X
  1121. X   rsave    = Rule_tab;
  1122. X   Rule_tab = environ;
  1123. X   Readenv  = TRUE;
  1124. X
  1125. X   Parse( NIL(FILE) );
  1126. X
  1127. X   Readenv  = FALSE;
  1128. X   Rule_tab = rsave;
  1129. }
  1130. X
  1131. X
  1132. X
  1133. /*
  1134. ** All we have to catch is SIG_INT
  1135. */
  1136. PUBLIC void
  1137. Catch_signals(fn)
  1138. void (*fn)();
  1139. {
  1140. X   if( signal(SIGINT, SIG_IGN) != SIG_IGN )
  1141. X      signal( SIGINT, fn );
  1142. X   if( signal(SIGQUIT, SIG_IGN) != SIG_IGN )
  1143. X      signal( SIGQUIT, fn );
  1144. }
  1145. X
  1146. X
  1147. X
  1148. /*
  1149. ** Clear any previously set signals
  1150. */
  1151. PUBLIC void
  1152. Clear_signals()
  1153. {
  1154. X   if( signal(SIGINT, SIG_IGN) != SIG_IGN )
  1155. X      signal( SIGINT, SIG_DFL );
  1156. X   if( signal(SIGQUIT, SIG_IGN) != SIG_IGN )
  1157. X      signal( SIGQUIT, SIG_DFL );
  1158. }
  1159. X
  1160. X
  1161. X
  1162. /*
  1163. ** Set program name
  1164. */
  1165. PUBLIC void
  1166. Prolog(argc, argv)
  1167. int   argc;
  1168. char* argv[];
  1169. {
  1170. X   char buf[50];
  1171. X
  1172. X   Pname = (argc == 0) ? DEF_MAKE_PNAME : argv[0];
  1173. X   sprintf( buf, "dmake-%d-root", GETPID );
  1174. X   Root = Def_cell( buf );
  1175. X   tzset();
  1176. }
  1177. X
  1178. X
  1179. X
  1180. /*
  1181. ** Do any clean up for exit.
  1182. */
  1183. PUBLIC void
  1184. Epilog(ret_code)
  1185. int ret_code;
  1186. {
  1187. X   Write_state();
  1188. X   Unlink_temp_files(Root);
  1189. X   Hook_std_writes(NIL(char));        /* For MSDOS tee (-F option) */
  1190. X   exit( ret_code );
  1191. }
  1192. X
  1193. X
  1194. X
  1195. /*
  1196. ** Use the built-in functions of the operating system to get the current
  1197. ** working directory.
  1198. */
  1199. PUBLIC char *
  1200. Get_current_dir()
  1201. {
  1202. X   static char buf[MAX_PATH_LEN+1];
  1203. X
  1204. X   return( getcwd(buf, sizeof(buf)) );
  1205. }
  1206. X
  1207. X
  1208. X
  1209. /*
  1210. ** change working directory
  1211. */
  1212. PUBLIC int
  1213. Set_dir(path)
  1214. char*   path;
  1215. {
  1216. X   return( chdir(path) );
  1217. }
  1218. X
  1219. X
  1220. X
  1221. /*
  1222. ** return switch char
  1223. */
  1224. PUBLIC char
  1225. Get_switch_char()
  1226. {
  1227. X   return( getswitchar() );
  1228. }
  1229. X
  1230. X
  1231. X
  1232. /*
  1233. ** Generate a temporary file name and open the file for writing.
  1234. ** If a name cannot be generated or the file cannot be opened
  1235. ** return -1, else return the fileno of the open file.
  1236. ** and update the source file pointer to point at the new file name.
  1237. ** Note that the new name should be freed when the file is removed.
  1238. */
  1239. PUBLIC FILE*
  1240. Get_temp(path, suff, op)
  1241. char **path;
  1242. char *suff;
  1243. int  op;
  1244. {
  1245. X   extern char *tempnam();
  1246. X
  1247. X   *path = _strjoin( tempnam(NIL(char), "mk"), suff, -1, TRUE );
  1248. X   Def_macro( "TMPFILE", *path, M_MULTI|M_EXPANDED );
  1249. X
  1250. X   return( op?fopen(*path, "w"):NIL(FILE) );
  1251. }
  1252. X
  1253. X
  1254. /*
  1255. ** Open a new temporary file and set it up for writing.
  1256. */
  1257. PUBLIC FILE *
  1258. Start_temp( suffix, cp, fname )
  1259. char     *suffix;
  1260. CELLPTR   cp;
  1261. char    **fname;
  1262. {
  1263. X   FILE           *fp;
  1264. X   char        *tmpname;
  1265. X   char           *name;
  1266. X
  1267. X   name = (cp != NIL(CELL))?cp->CE_NAME:"makefile text";
  1268. X
  1269. X   if( (fp = Get_temp(&tmpname, suffix, TRUE)) == NIL(FILE) )
  1270. X      Open_temp_error( tmpname, name );
  1271. X
  1272. X   Link_temp( cp, fp, tmpname );
  1273. X   *fname = tmpname;
  1274. X
  1275. X   return( fp );
  1276. }
  1277. X
  1278. X
  1279. /*
  1280. ** Issue an error on failing to open a temporary file
  1281. */
  1282. PUBLIC void
  1283. Open_temp_error( tmpname, name )
  1284. char *tmpname;
  1285. char *name;
  1286. {
  1287. X   Fatal("Cannot open temp file `%s' while processing `%s'", tmpname, name );
  1288. }
  1289. X
  1290. X
  1291. /*
  1292. ** Link a temp file onto the list of files.
  1293. */
  1294. PUBLIC void
  1295. Link_temp( cp, fp, fname )
  1296. CELLPTR cp;
  1297. FILE   *fp;
  1298. char   *fname;
  1299. {
  1300. X   FILELISTPTR new;
  1301. X
  1302. X   if( cp == NIL(CELL) ) cp = Root;
  1303. X
  1304. X   TALLOC( new, 1, FILELIST );
  1305. X
  1306. X   new->fl_next = cp->ce_files;
  1307. X   new->fl_name = fname;
  1308. X   new->fl_file = fp;        /* indicates temp file is open */
  1309. X
  1310. X   cp->ce_files = new;
  1311. }
  1312. X
  1313. X
  1314. /*
  1315. ** Close a previously used temporary file.
  1316. */
  1317. PUBLIC void
  1318. Close_temp(cp, file)
  1319. CELLPTR cp;
  1320. FILE    *file;
  1321. {
  1322. X   FILELISTPTR fl;
  1323. X   if( cp == NIL(CELL) ) cp = Root;
  1324. X
  1325. X   for( fl=cp->ce_files; fl && fl->fl_file != file; fl=fl->fl_next );
  1326. X   if( fl ) {
  1327. X      fl->fl_file = NIL(FILE);
  1328. X      fclose(file);
  1329. X   }
  1330. }
  1331. X
  1332. X
  1333. /*
  1334. ** Clean-up, and close all temporary files associated with a target.
  1335. */
  1336. PUBLIC void
  1337. Unlink_temp_files( cp )/*
  1338. ==========================
  1339. X   Unlink the tempfiles if any exist.  Make sure you close the files first
  1340. X   though.  This ensures that under DOS there is no disk space lost. */
  1341. CELLPTR cp;
  1342. {
  1343. X   FILELISTPTR cur, next;
  1344. X
  1345. X   if( cp == NIL(CELL) || cp->ce_files == NIL(FILELIST) ) return;
  1346. X
  1347. X   for( cur=cp->ce_files; cur != NIL(FILELIST); cur=next ) {
  1348. X      next = cur->fl_next;
  1349. X
  1350. X      if( cur->fl_file ) fclose( cur->fl_file );
  1351. X
  1352. X      if( Verbose & V_LEAVE_TMP )
  1353. X         printf( "%s:  Left temp file [%s]\n", Pname, cur->fl_name );
  1354. X      else
  1355. X         (void) unlink( cur->fl_name );
  1356. X
  1357. X      FREE(cur->fl_name);
  1358. X      FREE(cur);
  1359. X   }
  1360. X
  1361. X   cp->ce_files = NIL(FILELIST);
  1362. }
  1363. X
  1364. X
  1365. PUBLIC void
  1366. Handle_result(status, ignore, abort_flg, target)
  1367. int    status;
  1368. int    ignore;
  1369. int    abort_flg;
  1370. CELLPTR target;
  1371. {
  1372. X   status = ((status&0xff)==0 ? status>>8
  1373. X        : (status & 0xff)==SIGTERM ? -1
  1374. X        : (status & 0x7f)+128);
  1375. X
  1376. X   if( status )
  1377. X      if( !abort_flg ) {
  1378. X     fprintf( stderr, "%s:  Error code %d, while making '%s'",
  1379. X          Pname, status, target->ce_fname );
  1380. X
  1381. X     if( ignore || Continue ) {
  1382. X        fputs( " (Ignored)\n", stderr );
  1383. X     }
  1384. X     else {
  1385. X        fputc( '\n', stderr );
  1386. X
  1387. X        if( !(target->ce_attr & A_PRECIOUS) )
  1388. X           if( unlink( target->ce_fname ) == 0 )
  1389. X          fprintf(stderr,"%s:  '%s' removed.\n",Pname,target->ce_fname);
  1390. X
  1391. X        Quit();
  1392. X     }
  1393. X      }
  1394. X      else if( !(target->ce_attr & A_PRECIOUS) )
  1395. X     unlink( target->ce_fname );
  1396. }
  1397. X
  1398. X
  1399. PUBLIC void
  1400. Update_time_stamp( cp )
  1401. CELLPTR cp;
  1402. {
  1403. X   HASHPTR hp;
  1404. X   CELLPTR tcp;
  1405. X   int     tmpflg; 
  1406. X   int     phony = ((cp->ce_attr&A_PHONY) != 0);
  1407. X
  1408. X   tcp = cp;
  1409. X   do {
  1410. X      if( tcp->ce_attr & A_LIBRARY )
  1411. X     Void_lib_cache( tcp->ce_fname, NIL(char) );
  1412. X      else if( !Touch && (tcp->ce_attr & A_LIBRARYM) )
  1413. X     Void_lib_cache( tcp->ce_lib, tcp->ce_fname );
  1414. X
  1415. X      if( !phony )
  1416. X     Stat_target(tcp, -1);
  1417. X
  1418. X      if( tcp->ce_time == (time_t) 0L )
  1419. X     tcp->ce_time = Do_time();
  1420. X
  1421. X      if( Trace )
  1422. X     tcp->ce_flag |= F_STAT;        /* pretend we stated ok */
  1423. X
  1424. X      if( Verbose & V_MAKE )
  1425. X     printf( "%s:  <<<< Set [%s] time stamp to %ld\n",
  1426. X         Pname, tcp->CE_NAME, tcp->ce_time );
  1427. X
  1428. X      Unlink_temp_files( tcp );
  1429. X      tcp->ce_flag |= F_MADE;
  1430. X      tcp->ce_attr |= A_UPDATED;
  1431. X      tcp = tcp->ce_all;
  1432. X   }
  1433. X   while( tcp != NIL(CELL) && tcp != cp );
  1434. X
  1435. X
  1436. X   /* Scan the list of prerequisites and if we find one that is
  1437. X    * marked as being removable, (ie. an inferred intermediate node
  1438. X    * then remove it.  We remove a prerequisite by running the recipe
  1439. X    * associated with the special target .REMOVE, with $< set to
  1440. X    * the list of prerequisites to remove. */
  1441. X
  1442. X   /* Make sure we don't try to remove prerequisites for the .REMOVE
  1443. X    * target. */
  1444. X   if( strcmp(cp->CE_NAME,".REMOVE") != 0 &&
  1445. X       (hp = Get_name( ".REMOVE", Defs, FALSE )) != NIL(HASH) ) {
  1446. X      register LINKPTR dp;
  1447. X      int flag = FALSE;
  1448. X      int rem;
  1449. X      t_attr attr;
  1450. X
  1451. X      tcp = hp->CP_OWNR;
  1452. X
  1453. X      tcp->ce_flag |= F_TARGET;
  1454. X      Clear_prerequisites( tcp );
  1455. X
  1456. X      for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next ) {
  1457. X     register CELLPTR prq = dp->cl_prq;
  1458. X
  1459. X     attr = Glob_attr | prq->ce_attr;
  1460. SHAR_EOF
  1461. true || echo 'restore of dmake/sysintf.c failed'
  1462. fi
  1463. echo 'End of part 30, continue with part 31'
  1464. echo 31 > _shar_seq_.tmp
  1465. exit 0
  1466.  
  1467. exit 0 # Just in case...
  1468. -- 
  1469. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1470. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1471. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1472. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1473.