home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume27 / dmake / part09 < prev    next >
Encoding:
Text File  |  1992-01-29  |  39.9 KB  |  1,397 lines

  1. Newsgroups: comp.sources.misc
  2. From: dvadura@plg.waterloo.edu (Dennis Vadura)
  3. Subject:  v27i110:  dmake - dmake Version 3.8, Part09/41
  4. Message-ID: <1992Jan28.031437.7292@sparky.imd.sterling.com>
  5. X-Md4-Signature: d5d694b8295ed87a300e28b128e87dbf
  6. Date: Tue, 28 Jan 1992 03:14:37 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: dvadura@plg.waterloo.edu (Dennis Vadura)
  10. Posting-number: Volume 27, Issue 110
  11. Archive-name: dmake/part09
  12. Environment: Atari-ST, Coherent, Mac, MSDOS, OS/2, UNIX
  13. Supersedes: dmake: Volume 19, Issue 22-58
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. # this is dmake.shar.09 (part 9 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file dmake/expand.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" != 9; 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/expand.c' &&
  34. X        if (brky-cy > 0) strncat( buf, cy, brky-cy );
  35. X        buf[i+(brky-cy)] = '\0';
  36. X        strcat( buf, " " );
  37. X        res = _strjoin( res, buf, -1, TRUE );
  38. X        cy = _strspn( brky, " \t\n" );
  39. X     }
  40. X     cx = _strspn( brkx, " \t\n" );
  41. X      }
  42. X
  43. X      FREE( x );
  44. X      res[ strlen(res)-1 ] = '\0';
  45. X   }
  46. X   else
  47. X      res = _strjoin( x, y, -1, TRUE );
  48. X
  49. X   FREE( y );
  50. X   return( res );
  51. }
  52. SHAR_EOF
  53. chmod 0640 dmake/expand.c ||
  54. echo 'restore of dmake/expand.c failed'
  55. Wc_c="`wc -c < 'dmake/expand.c'`"
  56. test 25463 -eq "$Wc_c" ||
  57.     echo 'dmake/expand.c: original size 25463, current size' "$Wc_c"
  58. rm -f _shar_wnt_.tmp
  59. fi
  60. # ============= dmake/extern.h ==============
  61. if test -f 'dmake/extern.h' -a X"$1" != X"-c"; then
  62.     echo 'x - skipping dmake/extern.h (File already exists)'
  63.     rm -f _shar_wnt_.tmp
  64. else
  65. > _shar_wnt_.tmp
  66. sed 's/^X//' << 'SHAR_EOF' > 'dmake/extern.h' &&
  67. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/extern.h,v 1.1 1992/01/24 03:26:52 dvadura Exp $
  68. -- SYNOPSIS -- external declarations for dmake functions.
  69. -- 
  70. -- DESCRIPTION
  71. --    ANSI is a macro that allows the proper handling of ANSI style
  72. --    function declarations.
  73. -- 
  74. -- AUTHOR
  75. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  76. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  77. --
  78. -- COPYRIGHT
  79. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  80. -- 
  81. --      This program is free software; you can redistribute it and/or
  82. --      modify it under the terms of the GNU General Public License
  83. --      (version 1), as published by the Free Software Foundation, and
  84. --      found in the file 'LICENSE' included with this distribution.
  85. -- 
  86. --      This program is distributed in the hope that it will be useful,
  87. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  88. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  89. --      GNU General Public License for more details.
  90. -- 
  91. --      You should have received a copy of the GNU General Public License
  92. --      along with this program;  if not, write to the Free Software
  93. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  94. --
  95. -- LOG
  96. --     $Log: extern.h,v $
  97. X * Revision 1.1  1992/01/24  03:26:52  dvadura
  98. X * dmake Version 3.8, Initial revision
  99. X *
  100. */
  101. X
  102. #ifndef EXTERN_h
  103. #define EXTERN_h
  104. X
  105. /* Define this for the RS/6000 if it breaks something then we have to put a
  106. X * #ifdef around it. */
  107. #if defined(rs6000)
  108. #define _POSIX_SOURCE
  109. #endif
  110. X
  111. #include <limits.h>
  112. #include <stdio.h>
  113. #include <string.h>
  114. #include <ctype.h>
  115. #include <stdlib.h>
  116. #include <stdarg.h>
  117. #if defined (_MPW)
  118. # include <types.h>
  119. # include <time.h>
  120. #else
  121. # include <sys/types.h>
  122. # include <sys/stat.h>
  123. #endif
  124. #include <signal.h>
  125. #include "itypes.h"
  126. #include "stdmacs.h"
  127. #include "alloc.h"
  128. #include "db.h"
  129. #include "dmake.h"
  130. #include "struct.h"
  131. #include "vextern.h"
  132. #include "public.h"
  133. X
  134. /* Include this last as it invalidates some functions that are defined
  135. X * externally above and turns them into no-ops.  Have to do this after
  136. X * the extern declarations however. */
  137. #include "config.h"
  138. #include "namemax.h"
  139. X
  140. #endif
  141. X
  142. SHAR_EOF
  143. chmod 0640 dmake/extern.h ||
  144. echo 'restore of dmake/extern.h failed'
  145. Wc_c="`wc -c < 'dmake/extern.h'`"
  146. test 2216 -eq "$Wc_c" ||
  147.     echo 'dmake/extern.h: original size 2216, current size' "$Wc_c"
  148. rm -f _shar_wnt_.tmp
  149. fi
  150. # ============= dmake/function.c ==============
  151. if test -f 'dmake/function.c' -a X"$1" != X"-c"; then
  152.     echo 'x - skipping dmake/function.c (File already exists)'
  153.     rm -f _shar_wnt_.tmp
  154. else
  155. > _shar_wnt_.tmp
  156. sed 's/^X//' << 'SHAR_EOF' > 'dmake/function.c' &&
  157. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/function.c,v 1.1 1992/01/24 03:27:00 dvadura Exp $
  158. -- SYNOPSIS -- GNU style functions for dmake.
  159. -- 
  160. -- DESCRIPTION
  161. --     All GNU stule functions understood by dmake are implemented in this
  162. --    file.  Currently the only such function is $(mktmp ...) which is
  163. --    not part of GNU-make is an extension provided by dmake.
  164. --
  165. -- AUTHOR
  166. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  167. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  168. --
  169. -- COPYRIGHT
  170. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  171. -- 
  172. --      This program is free software; you can redistribute it and/or
  173. --      modify it under the terms of the GNU General Public License
  174. --      (version 1), as published by the Free Software Foundation, and
  175. --      found in the file 'LICENSE' included with this distribution.
  176. -- 
  177. --      This program is distributed in the hope that it will be useful,
  178. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  179. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  180. --      GNU General Public License for more details.
  181. -- 
  182. --      You should have received a copy of the GNU General Public License
  183. --      along with this program;  if not, write to the Free Software
  184. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  185. --
  186. -- LOG
  187. --     $Log: function.c,v $
  188. X * Revision 1.1  1992/01/24  03:27:00  dvadura
  189. X * dmake Version 3.8, Initial revision
  190. X *
  191. */
  192. X
  193. #include "extern.h"
  194. X
  195. static char *_exec_mktmp  ANSI((char *, char *, char *));
  196. static char *_exec_subst  ANSI((char *, char *, char *));
  197. static char *_exec_iseq   ANSI((char *, char *, char *, int));
  198. static char *_exec_sort   ANSI((char *));
  199. static char *_exec_shell  ANSI((char *));
  200. static int   _mystrcmp    ANSI((CONST PVOID, CONST PVOID));
  201. X
  202. X
  203. PUBLIC char *
  204. Exec_function(buf)/*
  205. ====================
  206. X   Execute the function given by the value of args.
  207. X
  208. X   So far mktmp is the only valid function, anything else elicits and error
  209. X   message.  It is my hope to support the GNU style functions in this portion
  210. X   of the code at some time in the future. */
  211. char *buf;
  212. {
  213. X   char *fname;
  214. X   char *args;
  215. X   char *mod1;
  216. X   char *mod2 = NIL(char);
  217. X   char *res  = NIL(char);
  218. X
  219. X   /* This must succeed since the presence of ' ', \t or \n is what
  220. X    * determines if this functions is called in the first place. */
  221. X   fname = _substr(buf, args=_strpbrk(buf," \t\n"));
  222. X
  223. X   if( (mod1 = strchr(fname,',')) != NIL(char) ){
  224. X      *mod1 = '\0';
  225. X      mod1++;
  226. X
  227. X      if( (mod2 = strchr(mod1,',')) != NIL(char) ){
  228. X     *mod2 = '\0';
  229. X     mod2++;
  230. X      }
  231. X   }
  232. X
  233. X   switch( *fname ) {
  234. X      case 'e':
  235. X     if(strncmp(fname,"eq",2) == 0) res = _exec_iseq(mod1,mod2,args,TRUE);
  236. X     break;
  237. X
  238. X      case 'm':
  239. X     if( strncmp(fname,"mktmp", 5) == 0 ) res = _exec_mktmp(mod1,mod2,args);
  240. X     break;
  241. X
  242. X      case 'n':
  243. X     if( strncmp(fname,"null", 4) == 0 )
  244. X        res = _exec_iseq(mod1,NIL(char),args,TRUE);
  245. X     break;
  246. X
  247. X      case '!':
  248. X     if(strncmp(fname,"!null",5) == 0)
  249. X        res = _exec_iseq(mod1,NIL(char),args,FALSE);
  250. X     if(strncmp(fname,"!eq",3) == 0) res = _exec_iseq(mod1,mod2,args,FALSE);
  251. X     break;
  252. X
  253. X      case 's':
  254. X     if(strncmp(fname,"sort",4) == 0) res = _exec_sort(args);
  255. X     else if(strncmp(fname,"shell",5)==0) res = _exec_shell(args);
  256. X     else if(strncmp(fname,"strip",5)==0) res = Tokenize(Expand(args)," ");
  257. X     else if(strncmp(fname,"subst",5)==0) res = _exec_subst(mod1,mod2,args);
  258. X     break;
  259. X
  260. X      default:
  261. X     Warning( "Function '%s' not implemented at this time", fname );
  262. X   }
  263. X
  264. X   if( res == NIL(char) ) res = _strdup("");
  265. X
  266. X   FREE(fname);
  267. X   return(res);
  268. }
  269. X
  270. X
  271. static char *
  272. _exec_mktmp( file, text, data )
  273. char *file;
  274. char *text;
  275. char *data;
  276. {
  277. X   register char *p;
  278. X   char *tmpname;
  279. X   char *name;
  280. X   FILE *tmpfile = NIL(FILE);
  281. X
  282. X   /* This is only a test of the recipe line so prevent the tempfile side
  283. X    * effects. */
  284. X   if( Suppress_temp_file ) return(NIL(char));
  285. X
  286. X   name = Current_target ? Current_target->CE_NAME:"makefile text";
  287. X
  288. X   if( file && *file ) {
  289. X      char *newtmp;
  290. X
  291. X      /* This call to Get_temp sets TMPFILE for subsequent expansion of file.
  292. X       * DO NOT DELETE IT! */
  293. X      Get_temp( &newtmp, "", FALSE ); FREE(newtmp);
  294. X      tmpname = Expand(file);
  295. X
  296. X      if( *tmpname ) {
  297. X     if( (tmpfile = fopen(tmpname, "w")) == NIL(FILE) )
  298. X        Open_temp_error( tmpname, name );
  299. X
  300. X     Def_macro("TMPFILE", tmpname, M_EXPANDED|M_MULTI);
  301. X     Link_temp( Current_target, tmpfile, tmpname );
  302. X      }
  303. X      else
  304. X     FREE(tmpname);
  305. X   }
  306. X
  307. X   if( !tmpfile )
  308. X      tmpfile = Start_temp( "", Current_target, &tmpname );
  309. X
  310. X   if( !text || !*text ) text = tmpname;
  311. X   data = Expand(_strspn(data, " \t\n"));
  312. X
  313. X   for(p=strchr(data,'\n'); p; p=strchr(p,'\n')) {
  314. X      char *q = _strspn(++p," \t");
  315. X      strcpy(p,q);
  316. X   }
  317. X
  318. X   Append_line( data, FALSE, tmpfile, name, FALSE, TRUE );
  319. X   Close_temp( Current_target, tmpfile );
  320. X   FREE(data);
  321. X
  322. X   return( Expand(text) );
  323. }
  324. X
  325. X
  326. static char *
  327. _exec_iseq( lhs, rhs, data, eq )
  328. char *lhs;
  329. char *rhs;
  330. char *data;
  331. int  eq;
  332. {
  333. X   char *l = Expand(lhs);
  334. X   char *r = Expand(rhs);
  335. X   char *i = _strspn(data, " \t\n");
  336. X   char *e = strchr(i, ' ');
  337. X   char *res = NIL(char);
  338. X   int  val = strcmp(l,r);
  339. X
  340. X   if( (!val && eq) || (val && !eq) ) {
  341. X      if( e != NIL(char) ) *e = '\0';
  342. X      res = Expand(i);
  343. X   }
  344. X   else if( e != NIL(char) ) {
  345. X      e = _strspn(e," \t\n");
  346. X      if( *e ) res = Expand(e);
  347. X   }
  348. X
  349. X   FREE(l);
  350. X   FREE(r);
  351. X   return(res);
  352. }
  353. X
  354. X
  355. static char *
  356. _exec_sort( args )
  357. char *args;
  358. {
  359. X   char *res  = NIL(char);
  360. X   char *data = Expand(args);
  361. X   char **tokens = NIL(char *);
  362. X   char *p;
  363. X   char *white = " \t\n";
  364. X   int  j;
  365. X   int  i = 0;
  366. X
  367. X   for( i=0,p=_strspn(data,white); *p; p=_strspn(_strpbrk(p,white),white),i++); 
  368. X
  369. X   if( i != 0 ) {
  370. X      TALLOC(tokens, i, char *);
  371. X
  372. X      for( i=0,p=_strspn(data,white); *p; p=_strspn(p,white),i++){
  373. X     tokens[i] = p;
  374. X     p = _strpbrk(p,white);
  375. X     if( *p ) *p++ = '\0';
  376. X      }
  377. X
  378. X      qsort( tokens, i, sizeof(char *), _mystrcmp );
  379. X
  380. X      for( j=0; j<i; j++ ) res = _strapp(res, tokens[j]);
  381. X      FREE(data);
  382. X      FREE(tokens);
  383. X   }
  384. X
  385. X   return(res);
  386. }
  387. X
  388. X
  389. static int
  390. _mystrcmp( p, q )
  391. CONST PVOID p;
  392. CONST PVOID q;
  393. {
  394. X   return(strcmp(*((CONST char **)p),*((CONST char **)q)));
  395. }
  396. X
  397. X
  398. static char *
  399. _exec_subst( pat, subst, data )
  400. char *pat;
  401. char *subst;
  402. char *data;
  403. {
  404. X   char *res;
  405. X
  406. X   pat = Expand(pat);
  407. X   subst = Expand(subst);
  408. X   res = Apply_edit( Expand(data), pat, subst, TRUE, FALSE );
  409. X   FREE(pat);
  410. X   FREE(subst);
  411. X
  412. X   return(res);
  413. }
  414. X
  415. X
  416. static char *
  417. _exec_shell( data )
  418. char *data;
  419. {
  420. X   extern char *tempnam();
  421. X   static int  nestlevel = 0;
  422. X   static int  org_out;
  423. X   static int  bsize;
  424. X   static char *buffer;
  425. X   static char *tmpnm;
  426. X   static FILE *tmp;
  427. X
  428. X   int wait     = Wait_for_completion;
  429. X   uint16 vflag = Verbose;
  430. X   int tflag    = Trace;
  431. X   char *res    = NIL(char);
  432. X   CELL cell;
  433. X   STRING rcp;
  434. X   HASH   cname;
  435. X
  436. X   if( Suppress_temp_file ) return(NIL(char));
  437. X
  438. X   /* Set the temp CELL used for building prerequisite candidates to
  439. X    * all zero so that we don't have to keep initializing all the
  440. X    * fields. */
  441. X   {
  442. X      register char *s = (char *) &cell;
  443. X      register int   n = sizeof(CELL);
  444. X      while( n ) { *s++ = '\0'; n--; }
  445. X   }
  446. X   rcp.st_string  = _strspn(data, " \t+-%@");
  447. X   rcp.st_attr    = Rcp_attribute( data );
  448. X   rcp.st_next    = NIL(STRING);
  449. X   cname.ht_name  = "Shell escape";
  450. X   cell.ce_name   = &cname;
  451. X   cell.ce_fname  = cname.ht_name;
  452. X   cell.ce_recipe = &rcp;
  453. X   cell.ce_flag   = F_TARGET|F_RULES;
  454. X   cell.ce_attr   = A_PHONY|A_SILENT;
  455. X
  456. X   if( nestlevel == 0 ) {
  457. X      tmpnm   = tempnam(NIL(char),"mk");
  458. X      org_out = dup(1);
  459. X
  460. X      if( (tmp = fopen(tmpnm, "w+")) == NIL(FILE) )
  461. X     Open_temp_error( tmpnm, cname.ht_name );
  462. X
  463. X      close(1);
  464. X      dup( fileno(tmp) );
  465. X
  466. X      bsize  = (Buffer_size < BUFSIZ)?BUFSIZ:Buffer_size;
  467. X      buffer = MALLOC(bsize,char);
  468. X   }
  469. X
  470. X   Wait_for_completion = TRUE;
  471. X   Verbose = V_NONE;
  472. X   Trace   = FALSE;
  473. X   nestlevel++;
  474. X   Exec_commands( &cell );
  475. X   nestlevel--;
  476. X   Trace   = tflag;
  477. X   Verbose = vflag;
  478. X   Wait_for_completion = wait;
  479. X
  480. X   /* Now we have to read the temporary file, get the tokens and return them
  481. X    * as a string. */
  482. X   rewind(tmp);
  483. X   while( fgets(buffer, bsize, tmp) ) {
  484. X      char *p = strchr(buffer, '\n');
  485. X
  486. X      if( p == NIL(char) )
  487. X     res = _strjoin(res,buffer,-1,TRUE);
  488. X      else {
  489. X     *p = '\0';
  490. X         res = _strapp(res,buffer);
  491. X      }
  492. X   }
  493. X
  494. X   fclose(tmp);
  495. X   if( nestlevel == 0 ) {
  496. X      Remove_file(tmpnm);
  497. X      close(1);
  498. X      dup(org_out);
  499. X      close(org_out);
  500. X      FREE(tmpnm);
  501. X      FREE(buffer);
  502. X   }
  503. X   else {
  504. X      if( (tmp = fopen(tmpnm, "w+")) == NIL(FILE) )
  505. X     Open_temp_error( tmpnm, cname.ht_name );
  506. X
  507. X      close(1);
  508. X      dup( fileno(tmp) );
  509. X   }
  510. X
  511. X   return(res);
  512. }
  513. SHAR_EOF
  514. chmod 0640 dmake/function.c ||
  515. echo 'restore of dmake/function.c failed'
  516. Wc_c="`wc -c < 'dmake/function.c'`"
  517. test 8705 -eq "$Wc_c" ||
  518.     echo 'dmake/function.c: original size 8705, current size' "$Wc_c"
  519. rm -f _shar_wnt_.tmp
  520. fi
  521. # ============= dmake/getinp.c ==============
  522. if test -f 'dmake/getinp.c' -a X"$1" != X"-c"; then
  523.     echo 'x - skipping dmake/getinp.c (File already exists)'
  524.     rm -f _shar_wnt_.tmp
  525. else
  526. > _shar_wnt_.tmp
  527. sed 's/^X//' << 'SHAR_EOF' > 'dmake/getinp.c' &&
  528. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/getinp.c,v 1.1 1992/01/24 03:27:56 dvadura Exp $
  529. -- SYNOPSIS -- handle reading of input.
  530. -- 
  531. -- DESCRIPTION
  532. --    The code in this file reads the input from the specified stream
  533. --    into the provided buffer of size Buffer_size.  In doing so it deletes
  534. --    comments.  Comments are delimited by the #, and
  535. --    <nl> character sequences.  An exception is \# which
  536. --    is replaced by # in the input.  Line continuations are signalled
  537. --    at the end of a line and are recognized inside comments.
  538. --    The line continuation is always  <\><nl>.
  539. --
  540. --    If the file to read is NIL(FILE) then the Get_line routine returns the
  541. --    next rule from the builtin rule table if there is one.
  542. --
  543. -- AUTHOR
  544. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  545. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  546. --
  547. -- COPYRIGHT
  548. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  549. -- 
  550. --      This program is free software; you can redistribute it and/or
  551. --      modify it under the terms of the GNU General Public License
  552. --      (version 1), as published by the Free Software Foundation, and
  553. --      found in the file 'LICENSE' included with this distribution.
  554. -- 
  555. --      This program is distributed in the hope that it will be useful,
  556. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  557. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  558. --      GNU General Public License for more details.
  559. -- 
  560. --      You should have received a copy of the GNU General Public License
  561. --      along with this program;  if not, write to the Free Software
  562. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  563. --
  564. -- LOG
  565. --     $Log: getinp.c,v $
  566. X * Revision 1.1  1992/01/24  03:27:56  dvadura
  567. X * dmake Version 3.8, Initial revision
  568. X *
  569. */
  570. X
  571. #include "extern.h"
  572. X
  573. #define IS_WHITE(A)  ((A == ' ') || (A == '\t') || (A == '\n') || (A == '\r'))
  574. #define SCAN_WHITE(A) \
  575. X    while( IS_WHITE(*A) ) A++;
  576. X
  577. static    int    _is_conditional ANSI((char*));
  578. static    int    _handle_conditional ANSI((int, TKSTRPTR));
  579. X
  580. static int  rule_ind = 0;    /* index of rule when reading Rule_tab     */
  581. static int  skip = FALSE;    /* if true the skip input         */
  582. X
  583. X
  584. PUBLIC int
  585. Get_line( buf, fil )/*
  586. ======================
  587. X        Read a line of input from the file stripping
  588. X        off comments.  The routine returns TRUE if EOF */
  589. char *buf;
  590. FILE *fil;
  591. {
  592. X   extern   char **Rule_tab;
  593. X   register char *p;
  594. X   register char *c;
  595. X   char      *q;
  596. X   char             *buf_org;
  597. X   static   int     ignore = FALSE;
  598. X   int          cont   = FALSE;
  599. X   int          pos    = 0;
  600. X   int         res;
  601. X
  602. X   DB_ENTER( "Get_line" );
  603. X
  604. X   if( fil == NIL(FILE) ) {
  605. X      /* Reading the internal rule table.  Set the rule_index to zero.
  606. X       * This way ReadEnvironment works as expected every time. */
  607. X
  608. X      while( (p = Rule_tab[ rule_ind++ ]) != NIL(char) )
  609. X     /* The last test in this if '*p != '~', handles the environment
  610. X      * passing conventions used by MKS to pass arguments.  We want to
  611. X      * skip those environment entries. */
  612. X     if( !Readenv || (Readenv && (strchr(p,'=') != NIL(char)) && *p!='~')){
  613. X        strcpy( buf, p );
  614. X
  615. X        DB_PRINT( "io", ("Returning [%s]", buf) );
  616. X        DB_RETURN( FALSE );
  617. X     }
  618. X
  619. X      rule_ind = 0;
  620. X
  621. X      DB_PRINT( "io", ("Done Ruletab") );
  622. X      DB_RETURN( TRUE );
  623. X   }
  624. X
  625. X   buf_org = buf;
  626. X
  627. do_again:
  628. X   do {
  629. X      p = buf+pos;
  630. X      if(feof( fil ) || (fgets( p, Buffer_size-pos, fil ) == NIL(char)))
  631. X     DB_RETURN( TRUE );
  632. X
  633. X      Line_number++;
  634. X
  635. X      /* ignore input if ignore flag set and line ends in a continuation
  636. X     character. */
  637. X
  638. X      q = p+strlen(p)-2;
  639. X      /* ignore each RETURN at the end of a line before any further
  640. X       * processing */
  641. X      if( q[0] == '\r' && q[1] == '\n' ) {
  642. X     q[0] = '\n';
  643. X     q[1] = '\0';
  644. X     q--;
  645. X      }
  646. X      /* you also have to deal with END_OF_FILE chars to process raw
  647. X       * DOS-Files. Normally they are the last chars in file, but after
  648. X       * working on these file with vi, there is an additional NEWLINE
  649. X       * after the last END_OF_FILE. So if the second last char in the
  650. X       * actual line is END_OF_FILE, you can skip the last char. Then
  651. X       * you can search the line back until you find no more END_OF_FILE
  652. X       * and nuke each you found by string termination. */
  653. X      if( q[0] == '\032' )
  654. X     q--;
  655. X      while( q[1] == '\032' ) {
  656. X     q[1] = '\0';
  657. X     q--;
  658. X      }
  659. X
  660. X      if( ignore ) {
  661. X     if( q[0] != CONTINUATION_CHAR || q[1] != '\n' )  ignore = FALSE;
  662. X     *p = '\0';
  663. X     continue;
  664. X      }
  665. X
  666. X      c = Do_comment(p, &q, Group || (*buf == '\t'));
  667. X      
  668. X      /* Does the end of the line end in a continuation sequence? */
  669. X      
  670. X      if( (q[0] == CONTINUATION_CHAR) && (q[1] == '\n')) {
  671. X     /* If the continuation was at the end of a comment then ignore the
  672. X      * next input line, (or lines until we get one ending in just <nl>)
  673. X      * else it's a continuation, so build the input line from several
  674. X      * text lines on input.  The maximum size of this is governened by
  675. X      * Buffer_size */
  676. X     if( q != p && q[-1] == CONTINUATION_CHAR ) {
  677. X        strcpy( q, q+1 );
  678. X        q--;
  679. X        cont = FALSE;
  680. X     }
  681. X     else if( c != NIL(char) )
  682. X        ignore = TRUE;
  683. X     else
  684. X        cont   = TRUE;
  685. X      }
  686. X      else {
  687. X     cont = FALSE;
  688. X      }
  689. X
  690. X      q    = ( c == NIL(char) ) ? q+2 : c;
  691. X      pos += q-p;
  692. X   }
  693. X   while( (cont || !*buf) && (pos <= Buffer_size) );
  694. X
  695. X   if( buf[ pos-1 ] == '\n' )
  696. X      buf[ --pos ] = '\0';
  697. X   else
  698. X      if( pos == Buffer_size-1 )
  699. X     Fatal( "Input line too long, increase MAXLINELENGTH" );
  700. X
  701. X
  702. X   /* Now that we have the next line of input to make, we should check to
  703. X    * see if it is a conditional expression.  If it is then process it,
  704. X    * otherwise pass it on to the parser. */
  705. X
  706. X   if( *(p = _strspn(buf, " \t\r\n")) == CONDSTART ) {
  707. X      TKSTR token;
  708. X
  709. X      SET_TOKEN( &token, p );
  710. X
  711. X      p = Get_token( &token, "", FALSE );
  712. X
  713. X      if( (res = _is_conditional( p )) )    /* ignore non control special */
  714. X      {                        /* targets               */
  715. X     res  = _handle_conditional( res, &token );
  716. X     skip = TRUE;
  717. X      }
  718. X      else {
  719. X     CLEAR_TOKEN( &token );
  720. X     res  = TRUE;
  721. X      }
  722. X   }
  723. X
  724. X   if( skip ) {
  725. X      buf  = buf_org;        /* ignore line just read in */
  726. X      pos  = 0;
  727. X      skip = res;
  728. X      goto do_again;
  729. X   }
  730. X
  731. X   DB_PRINT( "io", ("Returning [%s]", buf) );
  732. X   DB_RETURN( FALSE );
  733. }
  734. X
  735. X
  736. PUBLIC char *
  737. Do_comment(str, pend, keep)/*
  738. =============================
  739. X   Search the input string looking for comment chars.  If it contains
  740. X   comment chars then NUKE the remainder of the line, if the comment
  741. X   char is preceeded by \ then shift the remainder of the line left
  742. X   by one char. */
  743. char *str;
  744. char **pend;
  745. int  keep;
  746. {
  747. X   char *c = str;
  748. X
  749. X   while( (c = strchr(c, COMMENT_CHAR)) != NIL(char) ) {
  750. X      if( Comment || State == NORMAL_SCAN )
  751. X     if( c != str && c[-1] == ESCAPE_CHAR ) {
  752. X        strcpy( c-1, c );        /* copy it left, due to \# */
  753. X        if( pend ) (*pend)--;    /* shift tail pointer left */
  754. X     }
  755. X     else {
  756. X        if(    c == str
  757. X            && c[1] == '!'
  758. X            && Line_number == 1
  759. X        && Nestlevel() == 1 ) {
  760. X           int res;
  761. X           char *cmnd;
  762. X         
  763. X           cmnd = Expand(c+2);
  764. X           cmnd[strlen(cmnd)-1] = '\0';    /* strip last newline */
  765. X           Current_target = Root;
  766. X           Swap_on_exec = TRUE;
  767. X           Wait_for_completion = TRUE;
  768. X           Do_cmnd(cmnd, FALSE, TRUE, Current_target, FALSE, FALSE, TRUE);
  769. X        }
  770. X
  771. X        *c = '\0';               /* a true comment so break */
  772. X        break;
  773. X     }
  774. X      else {
  775. X         if( keep )
  776. X        c = NIL(char);
  777. X     else
  778. X        *c = '\0';
  779. X
  780. X     break;
  781. X      }
  782. X   }
  783. X
  784. X   return(c);
  785. }
  786. X      
  787. X
  788. PUBLIC char *
  789. Get_token( string, brk, anchor )/*
  790. ==================================
  791. X    Return the next token in string.
  792. X    Returns empty string when no more tokens in string.
  793. X    brk is a list of chars that also cause breaks in addition to space and
  794. X    tab, but are themselves returned as tokens.  if brk is NULL then the
  795. X    remainder of the line is returned as a single token.
  796. X    
  797. X    anchor if 1, says break on chars in the brk list, but only if
  798. X    the entire token begins with the first char of the brk list, if
  799. X    0 then any char of brk will cause a break to occurr.
  800. X    
  801. X    If anchor is 2, then break only seeing the first char in the break
  802. X    list allowing only chars in the break list to form the prefix. */
  803. X
  804. TKSTRPTR  string;
  805. char      *brk;
  806. int      anchor;
  807. {
  808. X   register char *s;
  809. X   register char *curp;
  810. X   register char *t;
  811. X   int           done = FALSE;
  812. X   char          space[10];
  813. X
  814. X   DB_ENTER( "Get_token" );
  815. X
  816. X   s  = string->tk_str;              /* Get string parameters    */
  817. X   *s = string->tk_cchar;          /* ... and strip leading w/s    */
  818. X
  819. X   SCAN_WHITE( s );
  820. X
  821. X   DB_PRINT( "tok", ("What's left [%s]", s) );
  822. X
  823. X   if( !*s ) {
  824. X      DB_PRINT( "tok", ("Returning NULL token") );
  825. X      DB_RETURN( "" );
  826. X   }
  827. X
  828. X
  829. X   /* Build the space list.  space contains all those chars that may possibly
  830. X    * cause breaks.  This includes the brk list as well as white space. */
  831. X
  832. X   if( brk != NIL(char) ) {
  833. X      strcpy( space, " \t\r\n" );
  834. X      strcat( space, brk   );
  835. X   }
  836. X   else {
  837. X      space[0] = 0xff;            /* a char we know will not show up      */
  838. X      space[1] = 0;
  839. X   }
  840. X
  841. X
  842. X   /* Handle processing of quoted tokens.  Note that this is disabled if
  843. X    * brk is equal to NIL */
  844. X
  845. X   while( *s == '\"' && ((brk != NIL(char)) || !string->tk_quote) ) {
  846. X      s++;
  847. X      if( string->tk_quote ) {
  848. X     curp = s-1;
  849. X     do { curp = strchr( curp+1, '\"' ); }
  850. X     while( (curp != NIL(char)) && (*(curp+1) == '\"'));
  851. X
  852. X         if( curp == NIL(char) ) Fatal( "Unmatched quote in token" );
  853. X     string->tk_quote = !string->tk_quote;
  854. X
  855. X     /* Check for "" case, and if found ignore it */
  856. X     if( curp == s ) continue;
  857. X     goto found_token;
  858. X      }
  859. X      else
  860. X     SCAN_WHITE( s );
  861. X
  862. X      string->tk_quote = !string->tk_quote;
  863. X   }
  864. X   
  865. X
  866. X   /* Check for a token break character at the beginning of the token.
  867. X    * If found return the next set of break chars as a token. */
  868. X
  869. X   if( anchor == 2 && brk != NIL(char) ) {
  870. X      curp = s;
  871. X      while( *curp && (strchr(brk,*curp)!=NIL(char)) && (*curp!=*brk) ) curp++;
  872. X      done = (*brk == *curp++);
  873. X   }
  874. X   else if( (brk != NIL(char)) && (strchr( brk, *s ) != NIL(char)) ) {
  875. X      curp = _strspn( s, brk );
  876. X      done = (anchor == 0) ? TRUE :
  877. X         ((anchor == 1)?(*s == *brk) : (*brk == curp[-1]));
  878. X   }
  879. X
  880. X
  881. X   /* Scan for the next token in the list and return it less the break char
  882. X    * that was used to terminate the token.  It will possibly be returned in
  883. X    * the next call to Get_token */
  884. X
  885. X   if( !done ) {
  886. X      SCAN_WHITE( s );
  887. X
  888. X      t = s;
  889. X      do {
  890. X     done = TRUE;
  891. X     curp = _strpbrk(t, space);
  892. X     
  893. X     if( anchor && *curp && !IS_WHITE( *curp ) )
  894. X        if( ((anchor == 1)?*curp:_strspn(curp,brk)[-1]) != *brk ) {
  895. X           t++;
  896. X           done = FALSE;
  897. X        }
  898. X      }
  899. X      while( !done );
  900. X
  901. X      if( (curp == s) && (strchr(brk, *curp) != NIL(char)) ) curp++;
  902. X   }
  903. X
  904. found_token:
  905. X   string->tk_str   = curp;
  906. X   string->tk_cchar = *curp;
  907. X   *curp = '\0';
  908. X
  909. X   DB_PRINT( "tok", ("Returning [%s]", s) );
  910. X   DB_RETURN( s );
  911. }
  912. X
  913. X
  914. static int
  915. _is_conditional( tg )/*
  916. =======================
  917. X    Look at tg and return it's value if it is a conditional identifier
  918. X    otherwise return 0. */
  919. char *tg;
  920. {
  921. X   DB_ENTER( "_is_conditional" );
  922. X   
  923. X   tg++;
  924. X   switch( *tg ) {
  925. X      case 'I': if( !strcmp( tg, "IF" )) DB_RETURN( ST_IF   ); break;
  926. X      
  927. X      case 'E':
  928. X         if( !strcmp( tg, "END" ))     DB_RETURN( ST_END  );
  929. X         else if( !strcmp( tg, "ENDIF")) DB_RETURN( ST_END  );
  930. X         else if( !strcmp( tg, "ELSE" )) DB_RETURN( ST_ELSE );
  931. X         else if( !strcmp( tg, "ELIF" )) DB_RETURN( ST_ELIF );
  932. X     break;
  933. X   }
  934. X   
  935. X   DB_RETURN( 0 );
  936. }
  937. X
  938. X
  939. X
  940. #define SEEN_END  0x00
  941. #define SEEN_IF   0x01
  942. #define SEEN_ELSE 0x02
  943. #define SEEN_ELIF 0x04
  944. X
  945. #define ACCEPT_IF   0x10
  946. #define ACCEPT_ELIF 0x20
  947. X
  948. static int
  949. _handle_conditional( opcode, tg )/*
  950. ===================================
  951. X    Perform the necessary processing for .IF conditinal targets.
  952. X    Someday this should be modified to do bracketted expressions ala
  953. X    CPP... sigh */
  954. int      opcode;
  955. TKSTRPTR tg;
  956. {
  957. X   static short    action[MAX_COND_DEPTH];
  958. X   static char  ifcntl[MAX_COND_DEPTH];
  959. X   char     *tok, *lhs, *rhs, *op, *expr;
  960. X   int      result;
  961. X
  962. X   DB_ENTER( "_handle_conditional" );
  963. X
  964. X   switch( opcode ) {
  965. X      case ST_ELIF:
  966. X         if( !(ifcntl[Nest_level] & SEEN_IF) || (ifcntl[Nest_level]&SEEN_ELSE) )
  967. X        Fatal(".ELIF without a preceeding .IF" );
  968. X     /* FALLTHROUGH */
  969. X
  970. X      case ST_IF:
  971. X     if( opcode == ST_IF && (Nest_level+1) == MAX_COND_DEPTH )
  972. X        Fatal( ".IF .ELSE ... .END nesting too deep" );
  973. X
  974. X     If_expand = TRUE;
  975. X     expr = Expand( Get_token( tg, NIL(char), FALSE ));
  976. X     If_expand = FALSE;
  977. X     lhs = _strspn( expr, " \t" );
  978. X     if( !*lhs ) lhs = NIL(char);
  979. X
  980. X     if( (op = _strstr( lhs, "==" )) == NIL(char) )
  981. X        op = _strstr( lhs, "!=" );
  982. X
  983. X     if( op == NIL(char) )
  984. X        result = (lhs != NIL(char));
  985. X     else {
  986. X        op[1] = op[0];
  987. X        if( lhs != op ) {
  988. X           for( tok = op-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
  989. X                tok-- );
  990. X           tok[1] = '\0';
  991. X        }
  992. X        else
  993. X           lhs = NIL(char);
  994. X
  995. X        op++;
  996. X        rhs = _strspn( op+1, " \t" );
  997. X        if( !*rhs ) rhs = NIL(char);
  998. X
  999. X        if( (rhs == NIL(char)) || (lhs == NIL(char)) )
  1000. X           result = (rhs == lhs) ? TRUE : FALSE;
  1001. X        else {
  1002. X           tok = rhs + strlen( rhs );
  1003. X           for( tok=tok-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
  1004. X            tok--);
  1005. X           tok[1] = '\0';
  1006. X
  1007. X           result = (strcmp( lhs, rhs ) == 0) ? TRUE : FALSE;
  1008. X        }
  1009. X
  1010. X        if( *op == '!' ) result = !result;
  1011. X     }
  1012. X
  1013. X     if( expr != NIL(char) ) FREE( expr );
  1014. X
  1015. X     if( opcode == ST_IF ) {
  1016. X        Nest_level++;
  1017. X        action[Nest_level] = 1;
  1018. X     }
  1019. X     ifcntl[Nest_level] |= (opcode==ST_IF)?SEEN_IF:SEEN_ELIF;
  1020. X
  1021. X     if( result ) {
  1022. X        if( !(ifcntl[Nest_level] & (ACCEPT_IF|ACCEPT_ELIF)) ) {
  1023. X           action[ Nest_level ] = action[ Nest_level-1 ];
  1024. X           ifcntl[Nest_level] |= (opcode==ST_IF)?ACCEPT_IF:ACCEPT_ELIF;
  1025. X        }
  1026. X        else
  1027. X           action[Nest_level] = 1;
  1028. X     }
  1029. X     else
  1030. X        action[Nest_level] = 1;
  1031. X     break;
  1032. X
  1033. X      case ST_ELSE:
  1034. X     if( Nest_level <= 0 ) Fatal( ".ELSE without .IF" );
  1035. X     if( ifcntl[Nest_level] & SEEN_ELSE )
  1036. X        Fatal( "Missing .IF or .ELIF before .ELSE" );
  1037. X
  1038. X     if( ifcntl[Nest_level] & (ACCEPT_IF|ACCEPT_ELIF) )
  1039. X        action[Nest_level] = 1;
  1040. X     else if( action[ Nest_level-1 ] != 1 )
  1041. X        action[ Nest_level ] ^= 0x1;    /* flip between 0 and 1    */
  1042. X
  1043. X     ifcntl[Nest_level] |= SEEN_ELSE;
  1044. X     break;
  1045. X
  1046. X      case ST_END:
  1047. X     ifcntl[Nest_level] = SEEN_END;
  1048. X     Nest_level--;
  1049. X     if( Nest_level < 0 ) Fatal( "Unmatched .END[IF]" );
  1050. X     break;
  1051. X   }
  1052. X
  1053. X   DB_RETURN( action[ Nest_level ] );
  1054. }
  1055. SHAR_EOF
  1056. chmod 0640 dmake/getinp.c ||
  1057. echo 'restore of dmake/getinp.c failed'
  1058. Wc_c="`wc -c < 'dmake/getinp.c'`"
  1059. test 14416 -eq "$Wc_c" ||
  1060.     echo 'dmake/getinp.c: original size 14416, current size' "$Wc_c"
  1061. rm -f _shar_wnt_.tmp
  1062. fi
  1063. # ============= dmake/hash.c ==============
  1064. if test -f 'dmake/hash.c' -a X"$1" != X"-c"; then
  1065.     echo 'x - skipping dmake/hash.c (File already exists)'
  1066.     rm -f _shar_wnt_.tmp
  1067. else
  1068. > _shar_wnt_.tmp
  1069. sed 's/^X//' << 'SHAR_EOF' > 'dmake/hash.c' &&
  1070. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/hash.c,v 1.1 1992/01/24 03:27:06 dvadura Exp $
  1071. -- SYNOPSIS -- hashing function for hash tables.
  1072. -- 
  1073. -- DESCRIPTION
  1074. --      Hash an identifier.  The hashing function works by computing the sum
  1075. --      of each char and the previous hash value multiplied by 129.  Finally the
  1076. --      length of the identifier is added in.  This way the hash depends on the
  1077. --      chars as well as the length, and appears to be sufficiently unique,
  1078. --      and is FAST to COMPUTE, unlike the previous hash function...
  1079. -- 
  1080. -- AUTHOR
  1081. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1082. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1083. --
  1084. -- COPYRIGHT
  1085. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1086. -- 
  1087. --      This program is free software; you can redistribute it and/or
  1088. --      modify it under the terms of the GNU General Public License
  1089. --      (version 1), as published by the Free Software Foundation, and
  1090. --      found in the file 'LICENSE' included with this distribution.
  1091. -- 
  1092. --      This program is distributed in the hope that it will be useful,
  1093. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1094. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1095. --      GNU General Public License for more details.
  1096. -- 
  1097. --      You should have received a copy of the GNU General Public License
  1098. --      along with this program;  if not, write to the Free Software
  1099. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1100. --
  1101. -- LOG
  1102. --     $Log: hash.c,v $
  1103. X * Revision 1.1  1992/01/24  03:27:06  dvadura
  1104. X * dmake Version 3.8, Initial revision
  1105. X *
  1106. */
  1107. X
  1108. #include "extern.h"
  1109. X
  1110. PUBLIC uint16
  1111. Hash( id, phv )/*
  1112. =================
  1113. X      This function computes the identifier's hash value and returns the hash
  1114. X      value modulo the key size as well as the full hash value.  The reason
  1115. X      for returning both is so that hash table searches can be sped up.  You
  1116. X      compare hash keys instead and compare strings only for those whose 32-bit
  1117. X      hash keys match. (not many) */
  1118. X
  1119. char   *id;
  1120. uint32 *phv;
  1121. {
  1122. X   register char   *p    = id;
  1123. X   register uint32 hash  = (uint32) 0;
  1124. X
  1125. X   while( *p ) hash = (hash << 7) + hash + (uint32) (*p++);
  1126. X   *phv = hash = hash + (uint32) (p-id);
  1127. X
  1128. X   return( (uint16) (hash % HASH_TABLE_SIZE) );
  1129. }
  1130. X
  1131. SHAR_EOF
  1132. chmod 0640 dmake/hash.c ||
  1133. echo 'restore of dmake/hash.c failed'
  1134. Wc_c="`wc -c < 'dmake/hash.c'`"
  1135. test 2337 -eq "$Wc_c" ||
  1136.     echo 'dmake/hash.c: original size 2337, current size' "$Wc_c"
  1137. rm -f _shar_wnt_.tmp
  1138. fi
  1139. # ============= dmake/imacs.c ==============
  1140. if test -f 'dmake/imacs.c' -a X"$1" != X"-c"; then
  1141.     echo 'x - skipping dmake/imacs.c (File already exists)'
  1142.     rm -f _shar_wnt_.tmp
  1143. else
  1144. > _shar_wnt_.tmp
  1145. sed 's/^X//' << 'SHAR_EOF' > 'dmake/imacs.c' &&
  1146. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/imacs.c,v 1.1 1992/01/24 03:29:55 dvadura Exp $
  1147. -- SYNOPSIS -- define default internal macros.
  1148. -- 
  1149. -- DESCRIPTION
  1150. --    This file adds to the internal macro tables the set of default
  1151. --    internal macros, and for those that are accessible internally via
  1152. --    variables creates these variables, and initializes them to point
  1153. --    at the default values of these macros.
  1154. --
  1155. -- AUTHOR
  1156. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1157. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1158. --
  1159. -- COPYRIGHT
  1160. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1161. -- 
  1162. --      This program is free software; you can redistribute it and/or
  1163. --      modify it under the terms of the GNU General Public License
  1164. --      (version 1), as published by the Free Software Foundation, and
  1165. --      found in the file 'LICENSE' included with this distribution.
  1166. -- 
  1167. --      This program is distributed in the hope that it will be useful,
  1168. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1169. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1170. --      GNU General Public License for more details.
  1171. -- 
  1172. --      You should have received a copy of the GNU General Public License
  1173. --      along with this program;  if not, write to the Free Software
  1174. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1175. --
  1176. -- LOG
  1177. --     $Log: imacs.c,v $
  1178. X * Revision 1.1  1992/01/24  03:29:55  dvadura
  1179. X * dmake Version 3.8, Initial revision
  1180. X *
  1181. */
  1182. X
  1183. #include "extern.h"
  1184. X
  1185. static    void    _set_int_var ANSI((char *, char *, int, int *));
  1186. static    void    _set_string_var ANSI((char *, char *, int, char **));
  1187. static    void    _set_bit_var ANSI((char *, char *, int));
  1188. X
  1189. /*
  1190. ** Arrange to parse the strings stored in Rules[]
  1191. */
  1192. PUBLIC void
  1193. Make_rules()
  1194. {
  1195. X   Parse(NIL(FILE));
  1196. }
  1197. X
  1198. X
  1199. #define M_FLAG   M_DEFAULT | M_EXPANDED
  1200. X
  1201. /*
  1202. ** Add to the macro table all of the internal macro variables plus
  1203. ** create secondary variables which will give access to their values
  1204. ** easily, both when needed and when the macro value is modified.
  1205. ** The latter is accomplished by providing a flag in the macro and a field
  1206. ** which gives a pointer to the value if it is a char or string macro value
  1207. ** and a mask representing the bit of the global flag register that is affected
  1208. ** by this macro's value.
  1209. */
  1210. PUBLIC void
  1211. Create_macro_vars()
  1212. {
  1213. X   static char* switchar;
  1214. X   char   swchar[2];
  1215. X
  1216. X   swchar[0] = Get_switch_char(), swchar[1] = '\0';
  1217. X   _set_string_var("SWITCHAR", swchar, M_PRECIOUS, &switchar);
  1218. X   _set_string_var("DIRSEPSTR", (*swchar=='/')?"\\":"/",M_PRECIOUS,&DirSepStr);
  1219. X   _set_string_var("DIRBRKSTR", DirBrkStr, M_PRECIOUS, &DirBrkStr);
  1220. X   swchar[0] = DEF_ESCAPE_CHAR, swchar[1] = '\0';
  1221. X   _set_string_var(".ESCAPE_PREFIX", swchar, M_FLAG, &Escape_char);
  1222. X
  1223. X   _set_bit_var(".SILENT",   "", A_SILENT  );
  1224. X   _set_bit_var(".IGNORE",   "", A_IGNORE  );
  1225. X   _set_bit_var(".PRECIOUS", "", A_PRECIOUS);
  1226. X   _set_bit_var(".EPILOG",   "", A_EPILOG  );
  1227. X   _set_bit_var(".PROLOG",   "", A_PROLOG  );
  1228. X   _set_bit_var(".NOINFER",  "", A_NOINFER );
  1229. X   _set_bit_var(".SEQUENTIAL","",A_SEQ     );
  1230. X   _set_bit_var(".USESHELL", "", A_SHELL   );
  1231. X   _set_bit_var(".SWAP",     "", A_SWAP    );
  1232. X   _set_bit_var(".MKSARGS",  "", A_MKSARGS );
  1233. X
  1234. X   Glob_attr = A_DEFAULT;        /* set all flags to NULL   */
  1235. X
  1236. X   _set_string_var("SHELL",        "",  M_DEFAULT, &Shell       );
  1237. X   _set_string_var("SHELLFLAGS",   " ", M_DEFAULT, &Shell_flags );
  1238. X   _set_string_var("GROUPSHELL",   "",  M_DEFAULT, &GShell      );
  1239. X   _set_string_var("GROUPFLAGS",   " ", M_DEFAULT, &GShell_flags);
  1240. X   _set_string_var("SHELLMETAS",   "",  M_DEFAULT, &Shell_metas );
  1241. X   _set_string_var("GROUPSUFFIX",  "",  M_DEFAULT, &Grp_suff    );
  1242. X   _set_string_var("PREP",         "0", M_DEFAULT, &Prep        );
  1243. X   _set_string_var("AUGMAKE",NIL(char), M_DEFAULT, &Augmake     );
  1244. X   _set_string_var(".KEEP_STATE",  "",  M_DEFAULT, &Keep_state  );
  1245. X   _set_string_var(".NOTABS",      "",  M_MULTI,   &Notabs      );
  1246. X
  1247. X   _set_string_var(".SETDIR", "", M_DEFAULT|M_NOEXPORT, &Start_dir );
  1248. X   _set_string_var("MAKEDIR",Get_current_dir(),M_PRECIOUS|M_NOEXPORT,&Makedir);
  1249. X   _set_string_var("PWD",  Makedir,  M_DEFAULT|M_NOEXPORT, &Pwd);
  1250. X   _set_string_var("TMD",  "",       M_DEFAULT|M_NOEXPORT, &Tmd);
  1251. X
  1252. X   Def_macro("NULL", "", M_PRECIOUS|M_NOEXPORT|M_FLAG);
  1253. X   _set_int_var( "MAXLINELENGTH", "0", M_DEFAULT|M_NOEXPORT, &Buffer_size );
  1254. X   (void) Def_macro("MAXLINELENGTH", "0", M_FLAG | M_DEFAULT);
  1255. X
  1256. X   /* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to
  1257. X    * change from command line. */
  1258. X   _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT, &Max_proclmt );
  1259. X   _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
  1260. }
  1261. X
  1262. X
  1263. /*
  1264. ** Define an integer variable value, and set up the macro.
  1265. */
  1266. static void
  1267. _set_int_var(name, val, flag, var)
  1268. char *name;
  1269. char *val;
  1270. int  flag;
  1271. int  *var;
  1272. {
  1273. X   HASHPTR hp;
  1274. X
  1275. X   hp = Def_macro(name, val, M_FLAG | flag);
  1276. X   hp->ht_flag |= M_VAR_INT | M_MULTI;
  1277. X   hp->MV_IVAR  = var;
  1278. X   *var         = atoi(val);
  1279. }
  1280. X
  1281. X
  1282. /*
  1283. ** Define a string variables value, and set up the macro.
  1284. */
  1285. static void
  1286. _set_string_var(name, val, flag, var)
  1287. char *name;
  1288. char *val;
  1289. int  flag;
  1290. char **var;
  1291. {
  1292. X   HASHPTR hp;
  1293. X
  1294. X   hp = Def_macro(name, val, M_FLAG | flag);
  1295. X   hp->ht_flag |= M_VAR_STRING | M_MULTI;
  1296. X   hp->MV_SVAR  = var;
  1297. X   *var         = hp->ht_value;
  1298. }
  1299. X
  1300. X
  1301. /*
  1302. ** Define a bit variable value, and set up the macro.
  1303. */
  1304. static void
  1305. _set_bit_var(name, val, mask)
  1306. char *name;
  1307. char *val;
  1308. int  mask;
  1309. {
  1310. X   HASHPTR hp;
  1311. X
  1312. X   hp           = Def_macro(name, val, M_FLAG);
  1313. X   hp->ht_flag |= M_VAR_BIT | M_MULTI;
  1314. X   hp->MV_MASK  = mask;
  1315. X   hp->MV_BVAR  = &Glob_attr;
  1316. }
  1317. SHAR_EOF
  1318. chmod 0640 dmake/imacs.c ||
  1319. echo 'restore of dmake/imacs.c failed'
  1320. Wc_c="`wc -c < 'dmake/imacs.c'`"
  1321. test 5686 -eq "$Wc_c" ||
  1322.     echo 'dmake/imacs.c: original size 5686, current size' "$Wc_c"
  1323. rm -f _shar_wnt_.tmp
  1324. fi
  1325. # ============= dmake/infer.c ==============
  1326. if test -f 'dmake/infer.c' -a X"$1" != X"-c"; then
  1327.     echo 'x - skipping dmake/infer.c (File already exists)'
  1328.     rm -f _shar_wnt_.tmp
  1329. else
  1330. > _shar_wnt_.tmp
  1331. sed 's/^X//' << 'SHAR_EOF' > 'dmake/infer.c' &&
  1332. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/infer.c,v 1.1 1992/01/24 03:27:21 dvadura Exp $
  1333. -- SYNOPSIS -- infer how to make a target.
  1334. -- 
  1335. -- DESCRIPTION
  1336. --    This file contains the code to infer a recipe, and possibly some new
  1337. --    prerequisites for a target which dmake does not know how to make, or
  1338. --    has no explicit recipe.
  1339. --
  1340. --    The inference fails if no path through the inference graph can be
  1341. --    found by which we can make the target.
  1342. -- 
  1343. -- AUTHOR
  1344. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1345. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1346. --
  1347. -- COPYRIGHT
  1348. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1349. -- 
  1350. --      This program is free software; you can redistribute it and/or
  1351. --      modify it under the terms of the GNU General Public License
  1352. --      (version 1), as published by the Free Software Foundation, and
  1353. --      found in the file 'LICENSE' included with this distribution.
  1354. -- 
  1355. --      This program is distributed in the hope that it will be useful,
  1356. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1357. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1358. --      GNU General Public License for more details.
  1359. -- 
  1360. --      You should have received a copy of the GNU General Public License
  1361. --      along with this program;  if not, write to the Free Software
  1362. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1363. --
  1364. -- LOG
  1365. --     $Log: infer.c,v $
  1366. X * Revision 1.1  1992/01/24  03:27:21  dvadura
  1367. X * dmake Version 3.8, Initial revision
  1368. X *
  1369. */
  1370. X
  1371. #include "extern.h"
  1372. X
  1373. /* attributes that get transfered from the % start cell to the inferred
  1374. X * cells. */
  1375. X
  1376. #define A_TRANSFER  (A_EPILOG | A_PRECIOUS | A_SILENT | A_SHELL | A_SETDIR |\
  1377. X             A_SEQ | A_LIBRARY | A_IGNORE | A_PROLOG | A_SWAP |\
  1378. X             A_NOSTATE )
  1379. X
  1380. X
  1381. /* Define local static functions */
  1382. static DFALINKPTR _dfa_subset  ANSI((DFALINKPTR, DFASETPTR));
  1383. static void       _free_dfas   ANSI((DFALINKPTR));
  1384. static int      _count_dots  ANSI((char *));
  1385. static char *      _build_name  ANSI((char *, char *, char *));
  1386. static void      _free_icells ANSI(());
  1387. static ICELLPTR   _union_iset  ANSI((ICELLPTR, ICELLPTR));
  1388. static ICELLPTR   _add_iset    ANSI((ICELLPTR,ICELLPTR,CELLPTR,DFALINKPTR,
  1389. SHAR_EOF
  1390. true || echo 'restore of dmake/infer.c failed'
  1391. fi
  1392. echo 'End of part 9, continue with part 10'
  1393. echo 10 > _shar_seq_.tmp
  1394. exit 0
  1395. exit 0 # Just in case...
  1396.