home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume14 / dmake / part16 < prev    next >
Encoding:
Text File  |  1990-07-26  |  39.3 KB  |  1,272 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v14i026: dmake version 3.5 part 16/21
  3. From: dvadura@watdragon.waterloo.edu (Dennis Vadura)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 14, Issue 26
  7. Submitted-by: dvadura@watdragon.waterloo.edu (Dennis Vadura)
  8. Archive-name: dmake/part16
  9.  
  10. #!/bin/sh
  11. # this is part 16 of a multipart archive
  12. # do not concatenate these parts, unpack them in order with /bin/sh
  13. # file infer.c continued
  14. #
  15. CurArch=16
  16. if test ! -r s2_seq_.tmp
  17. then echo "Please unpack part 1 first!"
  18.      exit 1; fi
  19. ( read Scheck
  20.   if test "$Scheck" != $CurArch
  21.   then echo "Please unpack part $Scheck next!"
  22.        exit 1;
  23.   else exit 0; fi
  24. ) < s2_seq_.tmp || exit 1
  25. echo "x - Continuing file infer.c"
  26. sed 's/^X//' << 'SHAR_EOF' >> infer.c
  27. X       * these circumstances the CELL is marked as a MULTI cell.
  28. X       */
  29. X      nhow = how->hw_next;
  30. X      for( ihow=meta->CE_EDGES->ed_how; ihow != NIL(HOW); ihow=ihow->hw_next ) {
  31. X     how->hw_per     = pdfa->dl_per;
  32. X     how->hw_flag   |= (ihow->hw_flag & (F_SINGLE | F_GROUP)) | F_INFER;
  33. X     how->hw_attr   |= ihow->hw_attr & (A_SILENT | A_IGNORE);
  34. X     how->hw_recipe  = ihow->hw_recipe;
  35. X
  36. X     /* If infcell is not NIL then we have inferred a prerequisite, so
  37. X      * add it to the first HOW cell as well.
  38. X      */
  39. X     if( infcell != NIL(CELL) ) {
  40. X        (Add_prerequisite( how, infcell, TRUE))->cl_flag |= F_TARGET;
  41. X
  42. X        if( Verbose )
  43. X           printf( "%s:  Inferred prerequisite [%s]\n",
  44. X                   Pname, infcell->CE_NAME );
  45. X     }
  46. X
  47. X     /* Add global prerequisites to the first HOW cell
  48. X      */
  49. X     for( lp=ihow->hw_indprq; lp != NIL(LINK); lp=lp->cl_next ) {
  50. X        char    *name = lp->cl_prq->CE_NAME;
  51. X        CELLPTR tcp;
  52. X
  53. X        name = _build_name( cp->CE_NAME, name, pdfa->dl_per );
  54. X        tcp  = Def_cell( name, setdirroot );
  55. X        tcp->ce_flag |= F_REMOVE;
  56. X        Add_prerequisite( how, tcp, FALSE );
  57. X
  58. X        if( Verbose )
  59. X           printf( "%s:  Inferred indirect prerequisite [%s]\n",
  60. X                   Pname, name );
  61. X        FREE(name);
  62. X     }
  63. X
  64. X     /* If the recipe is a :: recipe then Insert a new HOW node after
  65. X      * the inferred recipe HOW node and prior to any previous
  66. X      * :: nodes.
  67. X      */
  68. X     if( ihow->hw_next != NIL(HOW) ) {
  69. X        cp->ce_flag |= F_MULTI;
  70. X        TALLOC( how->hw_next, 1, HOW );
  71. X        how = how->hw_next;
  72. X     }
  73. X      }
  74. X      how->hw_next = nhow;
  75. X      pdfa->dl_per = NIL(char);        /* We used it, so don't FREE it */
  76. X
  77. X      /* Make sure to set the FLAGS, and ATTRIBUTES of the CELL so that it
  78. X       * gets made correctly.
  79. X       */
  80. X      cp->ce_flag |= F_RULES | F_TARGET | F_INFER;
  81. X
  82. X      if( !(cp->ce_attr & A_SETDIR) ) {
  83. X         cp->ce_attr |= (meta->ce_attr & A_SETDIR);
  84. X     cp->ce_dir   = meta->ce_dir;
  85. X      }
  86. X   }
  87. X   else
  88. X      cp = NIL(CELL);
  89. X
  90. X   _free_dfas( dfas );
  91. X
  92. X   DB_PRINT( "mem", ("%s:-< mem %ld", (cp!=NIL(CELL)) ? cp->CE_NAME : "(none)",
  93. X         (long)coreleft()));
  94. X   DB_PRINT( "inf", ("<<< Exit, cp = %04x", cp) );
  95. X   DB_RETURN( cp );
  96. X}
  97. X
  98. X
  99. Xstatic char *
  100. X_build_name( tg, meta, per )
  101. Xchar *tg;
  102. Xchar *meta;
  103. Xchar *per;
  104. X{
  105. X   char    *name;
  106. X
  107. X   name = Apply_edit( meta, "%", per, FALSE, FALSE );
  108. X   if( strchr(name, '$') ) {
  109. X      HASHPTR m_at;
  110. X      char *tmp;
  111. X
  112. X      m_at = Def_macro( "@", tg, M_MULTI );
  113. X      tmp = Expand( name );
  114. X
  115. X      if( m_at->ht_value != NIL(char) ) {
  116. X     FREE( m_at->ht_value );
  117. X     m_at->ht_value = NIL(char);
  118. X      }
  119. X
  120. X      if( name != meta ) FREE( name );
  121. X      name = tmp;
  122. X   }
  123. X   else if( name == meta )
  124. X      name = _strdup( name );
  125. X
  126. X   return(name);
  127. X}
  128. X
  129. X
  130. Xstatic DFALINKPTR
  131. X_dfa_subset( pdfa, stack )/*
  132. X============================
  133. X   This is the valid DFA subset computation.  Whenever a CELL has a Match_dfa
  134. X   subset computed this algorithm is run to see if any of the previously
  135. X   computed sets on the DFA stack are proper subsets of the new set.  If they
  136. X   are, then any elements of the matching subset whose Prep counts exceed
  137. X   the allowed maximum given by Prep are removed from the computed DFA set,
  138. X   and hence from consideration, thereby cutting off the cycle in the
  139. X   inference graph. */
  140. XDFALINKPTR       pdfa;
  141. Xregister DFASETPTR stack;
  142. X{
  143. X   register DFALINKPTR element;
  144. X   DFALINKPTR          nelement;
  145. X
  146. X   DB_ENTER( "_dfa_subset" );
  147. X
  148. X   for(; pdfa != NIL(DFALINK) && stack != NIL(DFASET); stack = stack->df_next) {
  149. X      int subset = TRUE;
  150. X
  151. X      for( element=stack->df_set; subset && element != NIL(DFALINK);
  152. X           element=element->dl_next ) {
  153. X         register DFALINKPTR subel;
  154. X
  155. X     for( subel = pdfa;
  156. X          subel != NIL(DFALINK) && (subel->dl_meta != element->dl_meta);
  157. X          subel = subel->dl_next );
  158. X
  159. X     if( subset = (subel != NIL(DFALINK)) ) element->dl_member = subel;
  160. X      }
  161. X
  162. X      if( subset )
  163. X     for( element=stack->df_set; element != NIL(DFALINK);
  164. X          element=element->dl_next ) {
  165. X        DFALINKPTR mem = element->dl_member;
  166. X        int        npr = element->dl_prep + 1;
  167. X
  168. X        if( npr > _prep )
  169. X           mem->dl_delete++;
  170. X        else
  171. X           mem->dl_prep = npr;
  172. X     }
  173. X   }
  174. X
  175. X   for( element = pdfa; element != NIL(DFALINK); element = nelement ) {
  176. X      nelement = element->dl_next;
  177. X
  178. X      if( element->dl_delete ) {
  179. X     /* A member of the subset has a PREP count equal to PREP, so
  180. X      * it should not be considered further in the inference, hence
  181. X      * we remove it from the doubly linked set list */
  182. X     if( element == pdfa )
  183. X        pdfa = element->dl_next;
  184. X     else
  185. X        element->dl_prev->dl_next = element->dl_next;
  186. X
  187. X     if( element->dl_next != NIL(DFALINK) )
  188. X        element->dl_next->dl_prev = element->dl_prev;
  189. X
  190. X     DB_PRINT("inf", ("deleting dfa [%s]", element->dl_meta->CE_NAME));
  191. X     FREE( element->dl_per );
  192. X     FREE( element );
  193. X      }
  194. X   }
  195. X
  196. X   DB_RETURN( pdfa );
  197. X}
  198. X
  199. X
  200. X
  201. Xstatic void
  202. X_free_dfas( chain )/*
  203. X=====================
  204. X   Free the list of DFA's constructed by Match_dfa, and linked together by
  205. X   LINK cells.  FREE the % value as well, as long as it isn't NIL. */
  206. XDFALINKPTR chain;
  207. X{
  208. X   register DFALINKPTR tl;
  209. X
  210. X   DB_ENTER( "_free_dfas" );
  211. X
  212. X   for( tl=chain; tl != NIL(DFALINK); chain = tl ) {
  213. X      tl = tl->dl_next;
  214. X
  215. X      DB_PRINT( "inf", ("Freeing DFA [%s], %% = [%s]", chain->dl_meta->CE_NAME,
  216. X                chain->dl_per) );
  217. X
  218. X      if( chain->dl_per != NIL(char) ) FREE( chain->dl_per );
  219. X      FREE( chain );
  220. X   }
  221. X
  222. X   DB_VOID_RETURN;
  223. X}
  224. X
  225. X
  226. Xstatic int
  227. X_count_dots( name )/*
  228. X=====================*/
  229. Xchar *name;
  230. X{
  231. X   register char *p;
  232. X   register int  i = 0;
  233. X
  234. X   for( p = name; *p; p++ ) if(*p == '.') i++;
  235. X
  236. X   return( i );
  237. X}
  238. SHAR_EOF
  239. echo "File infer.c is complete"
  240. chmod 0440 infer.c || echo "restore of infer.c fails"
  241. echo "x - extracting imacs.c (Text)"
  242. sed 's/^X//' << 'SHAR_EOF' > imacs.c &&
  243. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/imacs.c,v 1.1 90/07/19 13:53:17 dvadura Exp $
  244. X-- SYNOPSIS -- define default internal macros.
  245. X-- 
  246. X-- DESCRIPTION
  247. X--    This file adds to the internal macro tables the set of default
  248. X--    internal macros, and for those that are accessible internally via
  249. X--    variables creates these variables, and initializes them to point
  250. X--    at the default values of these macros.
  251. X--
  252. X-- AUTHOR
  253. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  254. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  255. X--
  256. X-- COPYRIGHT
  257. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  258. X-- 
  259. X--      This program is free software; you can redistribute it and/or
  260. X--      modify it under the terms of the GNU General Public License
  261. X--      (version 1), as published by the Free Software Foundation, and
  262. X--      found in the file 'LICENSE' included with this distribution.
  263. X-- 
  264. X--      This program is distributed in the hope that it will be useful,
  265. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  266. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  267. X--      GNU General Public License for more details.
  268. X-- 
  269. X--      You should have received a copy of the GNU General Public License
  270. X--      along with this program;  if not, write to the Free Software
  271. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  272. X--
  273. X-- LOG
  274. X--     $Log:    imacs.c,v $
  275. X * Revision 1.1  90/07/19  13:53:17  dvadura
  276. X * Initial Revision of Version 3.5
  277. X * 
  278. X*/
  279. X
  280. X#include "extern.h"
  281. X
  282. Xstatic    void    _set_int_var ANSI((char *, char *, int, int *));
  283. Xstatic    void    _set_string_var ANSI((char *, char *, int, char **));
  284. Xstatic    void    _set_bit_var ANSI((char *, char *, int));
  285. X
  286. X/*
  287. X** Arrange to parse the strings stored in Rules[]
  288. X*/
  289. Xvoid
  290. XMake_rules()
  291. X{
  292. X   Parse(NIL(FILE));
  293. X}
  294. X
  295. X
  296. X#define M_FLAG   M_DEFAULT | M_EXPANDED
  297. X
  298. X/*
  299. X** Add to the macro table all of the internal macro variables plus
  300. X** create secondary variables which will give access to their values
  301. X** easily, both when needed and when the macro value is modified.
  302. X** The latter is accomplished by providing a flag in the macro and a field
  303. X** which gives a pointer to the value if it is a char or string macro value
  304. X** and a mask representing the bit of the global flag register that is affected
  305. X** by this macro's value.
  306. X*/
  307. Xvoid
  308. XCreate_macro_vars()
  309. X{
  310. X   static   char*   switChar;
  311. X   char   swchar[2];
  312. X
  313. X   swchar[0] = Get_switch_char(), swchar[1] = '\0';
  314. X   _set_string_var("SWITCHAR", swchar, M_PRECIOUS, &switChar);
  315. X   _set_string_var("DIRSEPSTR", "/", M_PRECIOUS, &DirSepStr);
  316. X   _set_string_var("DIRBRKSTR", DirBrkStr, M_PRECIOUS, &DirBrkStr);
  317. X   
  318. X   _set_bit_var(".SILENT",   "", A_SILENT  );
  319. X   _set_bit_var(".IGNORE",   "", A_IGNORE  );
  320. X   _set_bit_var(".PRECIOUS", "", A_PRECIOUS);
  321. X   _set_bit_var(".EPILOG",   "", A_EPILOG  );
  322. X   _set_bit_var(".PROLOG",   "", A_PROLOG  );
  323. X   _set_bit_var(".NOINFER",  "", A_NOINFER );
  324. X   _set_bit_var(".SEQUENTIAL","",A_SEQ     );
  325. X
  326. X   Glob_attr    = A_DEFAULT;        /* set all flags to NULL   */
  327. X   
  328. X   _set_string_var("SHELL",        "",  M_DEFAULT, &Shell       );
  329. X   _set_string_var("SHELLFLAGS",   " ", M_DEFAULT, &Shell_flags );
  330. X   _set_string_var("GROUPSHELL",   "",  M_DEFAULT, &GShell      );
  331. X   _set_string_var("GROUPFLAGS",   " ", M_DEFAULT, &GShell_flags);
  332. X   _set_string_var("SHELLMETAS",   "",  M_DEFAULT, &Shell_metas );
  333. X   _set_string_var("GROUPSUFFIX",  "",  M_DEFAULT, &Grp_suff    );
  334. X   _set_string_var("PREP",         "0", M_DEFAULT, &Prep        );
  335. X   _set_string_var("AUGMAKE",      NIL(char), M_DEFAULT, &Augmake );
  336. X
  337. X   _set_string_var("MAKEDIR", Get_current_dir(), M_PRECIOUS|M_NOEXPORT,
  338. X         &Makedir);
  339. X   _set_string_var("PWD",  Makedir, M_DEFAULT|M_NOEXPORT, &Pwd);
  340. X
  341. X   Def_macro("NULL", "", M_PRECIOUS|M_NOEXPORT|M_FLAG);
  342. X   _set_int_var( "MAXLINELENGTH", "0", M_DEFAULT|M_NOEXPORT, &Buffer_size );
  343. X   (void) Def_macro("MAXLINELENGTH", "0", M_FLAG | M_DEFAULT);
  344. X
  345. X   /* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to
  346. X    * change from command line. */
  347. X   _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT, &Max_proclmt );
  348. X   _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
  349. X}
  350. X
  351. X/*
  352. X** Define a string variable value, and set up the macro.
  353. X*/
  354. Xstatic void
  355. X_set_int_var(name, val, flag, var)
  356. Xchar *name;
  357. Xchar *val;
  358. Xint  flag;
  359. Xint  *var;
  360. X{
  361. X   HASHPTR hp;
  362. X
  363. X   hp = Def_macro(name, val, M_FLAG | flag);
  364. X   hp->ht_flag |= M_VAR_INT | M_MULTI;
  365. X   hp->MV_IVAR  = var;
  366. X   *var         = atoi(val);
  367. X}
  368. X
  369. X/*
  370. X** Define a string variables value, and set up the macro.
  371. X*/
  372. Xstatic void
  373. X_set_string_var(name, val, flag, var)
  374. Xchar *name;
  375. Xchar *val;
  376. Xint  flag;
  377. Xchar **var;
  378. X{
  379. X   HASHPTR hp;
  380. X
  381. X   hp = Def_macro(name, val, M_FLAG | flag);
  382. X   hp->ht_flag |= M_VAR_STRING | M_MULTI;
  383. X   hp->MV_SVAR  = var;
  384. X   *var         = hp->ht_value;
  385. X}
  386. X
  387. X/*
  388. X** Define a string variables value, and set up the macro.
  389. X*/
  390. Xstatic void
  391. X_set_bit_var(name, val, mask)
  392. Xchar *name;
  393. Xchar *val;
  394. Xint  mask;
  395. X{
  396. X   HASHPTR hp;
  397. X
  398. X   hp           = Def_macro(name, val, M_FLAG);
  399. X   hp->ht_flag |= M_VAR_BIT | M_MULTI;
  400. X   hp->MV_MASK  = mask;
  401. X   hp->MV_BVAR  = &Glob_attr;
  402. X}
  403. X
  404. SHAR_EOF
  405. chmod 0440 imacs.c || echo "restore of imacs.c fails"
  406. echo "x - extracting hash.c (Text)"
  407. sed 's/^X//' << 'SHAR_EOF' > hash.c &&
  408. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/hash.c,v 1.1 90/07/19 13:53:14 dvadura Exp $
  409. X-- SYNOPSIS -- hashing function for hash tables.
  410. X-- 
  411. X-- DESCRIPTION
  412. X--      Hash an identifier.  The hashing function works by computing the sum
  413. X--      of each char and the previous hash value multiplied by 129.  Finally the
  414. X--      length of the identifier is added in.  This way the hash depends on the
  415. X--      chars as well as the length, and appears to be sufficiently unique,
  416. X--      and is FAST to COMPUTE, unlike the previous hash function...
  417. X-- 
  418. X-- AUTHOR
  419. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  420. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  421. X--
  422. X-- COPYRIGHT
  423. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  424. X-- 
  425. X--      This program is free software; you can redistribute it and/or
  426. X--      modify it under the terms of the GNU General Public License
  427. X--      (version 1), as published by the Free Software Foundation, and
  428. X--      found in the file 'LICENSE' included with this distribution.
  429. X-- 
  430. X--      This program is distributed in the hope that it will be useful,
  431. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  432. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  433. X--      GNU General Public License for more details.
  434. X-- 
  435. X--      You should have received a copy of the GNU General Public License
  436. X--      along with this program;  if not, write to the Free Software
  437. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  438. X--
  439. X-- LOG
  440. X--     $Log:    hash.c,v $
  441. X * Revision 1.1  90/07/19  13:53:14  dvadura
  442. X * Initial Revision of Version 3.5
  443. X * 
  444. X*/
  445. X
  446. X#include "extern.h"
  447. X
  448. Xuint16
  449. XHash( id, phv )/*
  450. X=================
  451. X      This function computes the identifier's hash value and returns the hash
  452. X      value modulo the key size as well as the full hash value.  The reason
  453. X      for returning both is so that hash table searches can be sped up.  You
  454. X      compare hash keys instead and compare strings only for those whose 32-bit
  455. X      hash keys match. (not many) */
  456. X
  457. Xchar   *id;
  458. Xuint32 *phv;
  459. X{
  460. X   register char   *p    = id;
  461. X   register uint32 hash  = (uint32) 0;
  462. X
  463. X   while( *p ) hash = (hash << 7) + hash + (uint32) (*p++);
  464. X   *phv = hash = hash + (uint32) (p-id);
  465. X
  466. X   return( (uint16) (hash % HASH_TABLE_SIZE) );
  467. X}
  468. X
  469. SHAR_EOF
  470. chmod 0440 hash.c || echo "restore of hash.c fails"
  471. echo "x - extracting getinp.c (Text)"
  472. sed 's/^X//' << 'SHAR_EOF' > getinp.c &&
  473. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/getinp.c,v 1.1 90/07/19 13:53:12 dvadura Exp $
  474. X-- SYNOPSIS -- handle reading of input.
  475. X-- 
  476. X-- DESCRIPTION
  477. X--    The code in this file reads the input from the specified stream
  478. X--    into the provided buffer of size Buffer_size.  In doing so it deletes
  479. X--    comments.  Comments are delimited by the #, and
  480. X--    <nl> character sequences.  An exception is \# which
  481. X--    is replaced by # in the input.  Line continuations are signalled
  482. X--    at the end of a line and are recognized inside comments.
  483. X--    The line continuation is always  <\><nl>.
  484. X--
  485. X--    If the file to read is NIL(FILE) then the Get_line routine returns the
  486. X--    next rule from the builtin rule table if there is one.
  487. X--
  488. X-- AUTHOR
  489. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  490. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  491. X--
  492. X-- COPYRIGHT
  493. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  494. X-- 
  495. X--      This program is free software; you can redistribute it and/or
  496. X--      modify it under the terms of the GNU General Public License
  497. X--      (version 1), as published by the Free Software Foundation, and
  498. X--      found in the file 'LICENSE' included with this distribution.
  499. X-- 
  500. X--      This program is distributed in the hope that it will be useful,
  501. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  502. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  503. X--      GNU General Public License for more details.
  504. X-- 
  505. X--      You should have received a copy of the GNU General Public License
  506. X--      along with this program;  if not, write to the Free Software
  507. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  508. X--
  509. X-- LOG
  510. X--     $Log:    getinp.c,v $
  511. X * Revision 1.1  90/07/19  13:53:12  dvadura
  512. X * Initial Revision of Version 3.5
  513. X * 
  514. X*/
  515. X
  516. X#include "extern.h"
  517. X#include "alloc.h"
  518. X#include "db.h"
  519. X
  520. X#define IS_WHITE(A)  ((A == ' ') || (A == '\t') || (A == '\n'))
  521. X#define SCAN_WHITE(A) \
  522. X    while( IS_WHITE(*A) ) A++;
  523. X
  524. Xstatic    int    _is_conditional ANSI((char*));
  525. Xstatic    int    _handle_conditional ANSI((int, TKSTRPTR));
  526. X
  527. Xstatic int  rule_ind = 0;    /* index of rule when reading Rule_tab     */
  528. Xstatic int  skip = FALSE;    /* if true the skip input         */
  529. X
  530. X
  531. Xint
  532. XGet_line( buf, fil )/*
  533. X======================
  534. X        Read a line of input from the file stripping
  535. X        off comments.  The routine returns TRUE if EOF */
  536. Xchar *buf;
  537. XFILE *fil;
  538. X{
  539. X   extern   char **Rule_tab;
  540. X   register char *p;
  541. X   register char *q;
  542. X   register char *c;
  543. X   char             *buf_org;
  544. X   static   int     ignore = FALSE;
  545. X   int          cont   = FALSE;
  546. X   int          pos    = 0;
  547. X   int         res;
  548. X
  549. X   DB_ENTER( "Get_line" );
  550. X
  551. X   if( fil == NIL(FILE) ) {
  552. X      /* Reading the internal rule table.  Set the rule_index to zero.
  553. X       * This way ReadEnvironment works as expected every time. */
  554. X
  555. X      while( (p = Rule_tab[ rule_ind++ ]) != NIL(char) )
  556. X     /* The last test in this if '*p != '~', handles the environment
  557. X      * passing conventions used by MKS to pass arguments.  We want to
  558. X      * skip those environment entries. */
  559. X     if( !Readenv || (Readenv && (strchr(p,'=') != NIL(char)) && *p!='~')){
  560. X        strcpy( buf, p );
  561. X
  562. X        DB_PRINT( "io", ("Returning [%s]", buf) );
  563. X        DB_RETURN( FALSE );
  564. X     }
  565. X
  566. X      rule_ind = 0;
  567. X
  568. X      DB_PRINT( "io", ("Done Ruletab") );
  569. X      DB_RETURN( TRUE );
  570. X   }
  571. X
  572. X   buf_org = buf;
  573. X
  574. Xdo_again:
  575. X   do {
  576. X      p = buf+pos;
  577. X      if(feof( fil ) || (fgets( p, Buffer_size-pos, fil ) == NIL(char)))
  578. X     DB_RETURN( TRUE );
  579. X
  580. X      Line_number++;
  581. X
  582. X      /* ignore input if ignore flag set and line ends in a continuation
  583. X     character. */
  584. X
  585. X      q = p+strlen(p)-2;
  586. X      if( ignore ) {
  587. X     if( q[0] != CONTINUATION_CHAR || q[1] != '\n' )  ignore = FALSE;
  588. X     *p = '\0';
  589. X     continue;
  590. X      }
  591. X
  592. X      /* Search the input string looking for comment chars.  If it contains
  593. X       * comment chars then NUKE the remainder of the line, if the comment
  594. X       * char is preceeded by \ then shift the remainder of the line left
  595. X       * by one char. */
  596. X
  597. X      c = p;
  598. X
  599. X      while( (c = strchr(c, COMMENT_CHAR)) != NIL(char) ) {
  600. X     if( c != p && c[-1] == ESCAPE_CHAR ) {
  601. X        strcpy( c-1, c );             /* copy it left, due to \# */
  602. X        q--;              /* shift tail pointer left */
  603. X     }
  604. X     else {
  605. X        *c = '\0';                    /* a true comment so break */
  606. X        break;
  607. X     }
  608. X      }
  609. X      
  610. X      /* Does the end of the line end in a continuation sequence? */
  611. X      
  612. X      if( (q[0] == CONTINUATION_CHAR) && (q[1] == '\n')) {
  613. X     /* If the continuation was at the end of a comment then ignore the
  614. X        next input line, (or lines until we get one ending in just <nl>)
  615. X        else it's a continuation, so build the input line from several
  616. X        text lines on input.  The maximum size of this is governened by
  617. X        Buffer_size */
  618. X
  619. X     if( c != NIL(char) )
  620. X        ignore = TRUE;
  621. X     else
  622. X        cont   = TRUE;
  623. X      }
  624. X      else {
  625. X     cont = FALSE;
  626. X      }
  627. X
  628. X      q    = ( c == NIL(char) ) ? q+2 : c;
  629. X      pos += q-p;
  630. X   }
  631. X   while( (cont || !*buf) && (pos <= Buffer_size) );
  632. X
  633. X   if( buf[ pos-1 ] == '\n' )
  634. X      buf[ --pos ] = '\0';
  635. X   else
  636. X      if( pos == Buffer_size-1 )
  637. X     Fatal( "Input line too long, increase MAXLINELENGTH" );
  638. X
  639. X
  640. X   /* Now that we have the next line of input to make, we should check to
  641. X    * see if it is a conditional expression.  If it is then process it,
  642. X    * otherwise pass it on to the parser. */
  643. X
  644. X   if( *(p = _strspn(buf, " \t")) == CONDSTART ) {
  645. X      TKSTR token;
  646. X
  647. X      SET_TOKEN( &token, p );
  648. X
  649. X      p = Get_token( &token, "", FALSE );
  650. X
  651. X      if( (res = _is_conditional( p )) )    /* ignore non control special */
  652. X      {                        /* targets               */
  653. X     res  = _handle_conditional( res, &token );
  654. X     skip = TRUE;
  655. X      }
  656. X      else {
  657. X     CLEAR_TOKEN( &token );
  658. X     res  = TRUE;
  659. X      }
  660. X   }
  661. X
  662. X   if( skip ) {
  663. X      buf  = buf_org;        /* ignore line just read in */
  664. X      pos  = 0;
  665. X      skip = res;
  666. X      goto do_again;
  667. X   }
  668. X
  669. X   DB_PRINT( "io", ("Returning [%s]", buf) );
  670. X   DB_RETURN( FALSE );
  671. X}
  672. X
  673. X
  674. X
  675. Xchar *
  676. XGet_token( string, brk, anchor )/*
  677. X==================================
  678. X    Return the next token in string.
  679. X    Returns empty string when no more tokens in string.
  680. X    brk is a list of chars that also cause breaks in addition to space and
  681. X    tab, but are themselves returned as tokens.  if brk is NULL then the
  682. X    remainder of the line is returned as a single token.
  683. X    
  684. X    anchor if TRUE, says break on chars in the brk list, but only if
  685. X    the entire token begins with the first char of the brk list, if
  686. X    FALSE then any char of brk will cause a break to occurr. */
  687. X
  688. XTKSTRPTR  string;
  689. Xchar      *brk;
  690. Xint      anchor;
  691. X{
  692. X   register char *s;
  693. X   register char *curp;
  694. X   register char *t;
  695. X   int           done = FALSE;
  696. X   char          space[10];
  697. X
  698. X   DB_ENTER( "Get_token" );
  699. X
  700. X   s  = string->tk_str;              /* Get string parameters    */
  701. X   *s = string->tk_cchar;          /* ... and strip leading w/s    */
  702. X
  703. X   SCAN_WHITE( s );
  704. X
  705. X   DB_PRINT( "tok", ("What's left [%s]", s) );
  706. X
  707. X   if( !*s ) {
  708. X      DB_PRINT( "tok", ("Returning NULL token") );
  709. X      DB_RETURN( "" );
  710. X   }
  711. X
  712. X
  713. X   /* Build the space list.  space contains all those chars that may possibly
  714. X    * cause breaks.  This includes the brk list as well as white space. */
  715. X
  716. X   if( brk != NIL(char) ) {
  717. X      strcpy( space, " \t\n" );
  718. X      strcat( space, brk   );
  719. X   }
  720. X   else {
  721. X      space[0] = 0xff;            /* a char we know will not show up      */
  722. X      space[1] = 0;
  723. X   }
  724. X
  725. X
  726. X   /* Handle processing of quoted tokens.  Note that this is disabled if
  727. X    * brk is equal to NIL */
  728. X
  729. X   while( *s == '\"' && ((brk != NIL(char)) || !string->tk_quote) ) {
  730. X      s++;
  731. X      if( string->tk_quote ) {
  732. X     curp = s-1;
  733. X     do { curp = strchr( curp+1, '\"' ); }
  734. X     while( (curp != NIL(char)) && (*(curp+1) == '\"'));
  735. X
  736. X         if( curp == NIL(char) ) Fatal( "Unmatched quote in token" );
  737. X     string->tk_quote = !string->tk_quote;
  738. X
  739. X     /* Check for "" case, and if found ignore it */
  740. X     if( curp == s ) continue;
  741. X     goto found_token;
  742. X      }
  743. X      else
  744. X     SCAN_WHITE( s );
  745. X
  746. X      string->tk_quote = !string->tk_quote;
  747. X   }
  748. X   
  749. X
  750. X   /* Check for a token break character at the beginning of the token.
  751. X    * If found return the next set of break chars as a token. */
  752. X
  753. X   if( (brk != NIL(char)) && (strchr( brk, *s ) != NIL(char)) ) {
  754. X      curp = _strspn( s, brk );
  755. X      done = anchor ? (*s == *brk) : TRUE;
  756. X   }
  757. X
  758. X
  759. X   /* Scan for the next token in the list and return it less the break char
  760. X    * that was used to terminate the token.  It will possibly be returned in
  761. X    * the next call to Get_token */
  762. X
  763. X   if( !done ) {
  764. X      SCAN_WHITE( s );
  765. X
  766. X      t = s;
  767. X      do {
  768. X     done = TRUE;
  769. X     curp = _strpbrk( t, space);
  770. X     
  771. X     if( anchor && *curp && !IS_WHITE( *curp ) )
  772. X        if( *curp != *brk ) {
  773. X           t++;
  774. X           done = FALSE;
  775. X        }
  776. X      }
  777. X      while( !done );
  778. X
  779. X      if( (curp == s) && (strchr(brk, *curp) != NIL(char)) ) curp++;
  780. X   }
  781. X
  782. Xfound_token:
  783. X   string->tk_str   = curp;
  784. X   string->tk_cchar = *curp;
  785. X   *curp = '\0';
  786. X
  787. X   DB_PRINT( "tok", ("Returning [%s]", s) );
  788. X   DB_RETURN( s );
  789. X}
  790. X
  791. X
  792. X
  793. Xstatic int
  794. X_is_conditional( tg )/*
  795. X=======================
  796. X    Look at tg and return it's value if it is a conditional identifier
  797. X    otherwise return 0. */
  798. Xchar *tg;
  799. X{
  800. X   DB_ENTER( "_is_conditional" );
  801. X   
  802. X   tg++;
  803. X   switch( *tg ) {
  804. X      case 'I': if( !strcmp( tg, "IF" )) DB_RETURN( ST_IF   ); break;
  805. X      
  806. X      case 'E':
  807. X         if( !strcmp( tg, "END" ))     DB_RETURN( ST_END  );
  808. X         else if( !strcmp( tg, "ELSE" )) DB_RETURN( ST_ELSE );
  809. X     break;
  810. X   }
  811. X   
  812. X   DB_RETURN( 0 );
  813. X}
  814. X
  815. X
  816. X
  817. Xstatic int
  818. X_handle_conditional( opcode, tg )/*
  819. X===================================
  820. X    Perform the necessary processing for .IF conditinal targets.
  821. X    Someday this should be modified to do bracketted expressions ala
  822. X    CPP... sigh */
  823. Xint      opcode;
  824. XTKSTRPTR tg;
  825. X{
  826. X   static short    action[MAX_COND_DEPTH];
  827. X   char     *tok, *lhs, *rhs, *op, *expr;
  828. X   int      result;
  829. X
  830. X   DB_ENTER( "_handle_conditional" );
  831. X
  832. X   switch( opcode ) {
  833. X      case ST_IF:
  834. X     if( Nest_level+1 == MAX_COND_DEPTH )
  835. X        Fatal( ".IF .ELSE ... .END nesting too deep" );
  836. X
  837. X     If_expand = TRUE;
  838. X     expr = Expand( Get_token( tg, NIL(char), FALSE ));
  839. X     If_expand = FALSE;
  840. X     lhs = _strspn( expr, " \t" );
  841. X     if( !*lhs ) lhs = NIL(char);
  842. X
  843. X     if( (op = _strstr( lhs, "==" )) == NIL(char) )
  844. X        op = _strstr( lhs, "!=" );
  845. X
  846. X     if( op == NIL(char) )
  847. X        result = (lhs != NIL(char));
  848. X     else {
  849. X        op[1] = op[0];
  850. X        if( lhs != op ) {
  851. X           for( tok = op-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
  852. X                tok-- );
  853. X           tok[1] = '\0';
  854. X        }
  855. X        else
  856. X           lhs = NIL(char);
  857. X
  858. X        op++;
  859. X        rhs = _strspn( op+1, " \t" );
  860. X        if( !*rhs ) rhs = NIL(char);
  861. X
  862. X        if( (rhs == NIL(char)) || (lhs == NIL(char)) )
  863. X           result = (rhs == lhs) ? TRUE : FALSE;
  864. X        else {
  865. X           tok = rhs + strlen( rhs );
  866. X           for( tok=tok-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
  867. X            tok--);
  868. X           tok[1] = '\0';
  869. X
  870. X           result = (strcmp( lhs, rhs ) == 0) ? TRUE : FALSE;
  871. X        }
  872. X
  873. X        if( *op == '!' ) result = !result;
  874. X     }
  875. X
  876. X     if( expr != NIL(char) ) FREE( expr );
  877. X     Nest_level++;
  878. X
  879. X     if( result )
  880. X        action[ Nest_level ] = action[ Nest_level-1 ];
  881. X     else
  882. X        action[ Nest_level ] = 1;
  883. X     break;
  884. X
  885. X      case ST_ELSE:
  886. X     if( Nest_level <= 0 ) Fatal( ".ELSE without .IF" );
  887. X     if( action[ Nest_level-1 ] != 1 )
  888. X        action[ Nest_level ] ^=  0x1;    /* flip between 0 and 1    */
  889. X     break;
  890. X
  891. X      case ST_END:
  892. X     Nest_level--;
  893. X     if( Nest_level < 0 ) Fatal( "Unmatched .END" );
  894. X     break;
  895. X   }
  896. X
  897. X   DB_RETURN( action[ Nest_level ] );
  898. X}
  899. X
  900. SHAR_EOF
  901. chmod 0440 getinp.c || echo "restore of getinp.c fails"
  902. echo "x - extracting extern.h (Text)"
  903. sed 's/^X//' << 'SHAR_EOF' > extern.h &&
  904. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/extern.h,v 1.1 90/07/19 13:55:31 dvadura Exp $
  905. X-- SYNOPSIS -- external declarations for dmake functions.
  906. X-- 
  907. X-- DESCRIPTION
  908. X--    ANSI is a macro that allows the proper handling of ANSI style
  909. X--    function declarations.
  910. X-- 
  911. X-- AUTHOR
  912. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  913. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  914. X--
  915. X-- COPYRIGHT
  916. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  917. X-- 
  918. X--      This program is free software; you can redistribute it and/or
  919. X--      modify it under the terms of the GNU General Public License
  920. X--      (version 1), as published by the Free Software Foundation, and
  921. X--      found in the file 'LICENSE' included with this distribution.
  922. X-- 
  923. X--      This program is distributed in the hope that it will be useful,
  924. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  925. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  926. X--      GNU General Public License for more details.
  927. X-- 
  928. X--      You should have received a copy of the GNU General Public License
  929. X--      along with this program;  if not, write to the Free Software
  930. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  931. X--
  932. X-- LOG
  933. X--     $Log:    extern.h,v $
  934. X * Revision 1.1  90/07/19  13:55:31  dvadura
  935. X * Initial Revision of Version 3.5
  936. X * 
  937. X*/
  938. X
  939. X#ifndef EXTERN_h
  940. X#define EXTERN_h
  941. X
  942. X#include "vextern.h"
  943. X#include "config.h"
  944. X#include <stdlib.h>
  945. X#include <string.h>
  946. X
  947. Xextern    void    Add_dfa ANSI((char *));
  948. Xextern    void    Add_fringe ANSI((CELLPTR));
  949. Xextern    void    Add_recipe_to_list ANSI((char *, int, int));
  950. Xextern    LINKPTR    Add_prerequisite ANSI((HOWPTR, CELLPTR, int));
  951. Xextern    char*    Apply_edit ANSI((char *, char *, char *, int, int));
  952. Xextern    char*    basename ANSI((char*));
  953. Xextern    void    Bind_rules_to_targets ANSI((int));
  954. Xextern    char*    Build_path ANSI((char *, char *));
  955. Xextern    void     Catch_signals ANSI((void (*)()));
  956. Xextern    void    Check_circle ANSI((LINKPTR));
  957. Xextern    void    Check_circle_dfa ANSI(());
  958. Xextern    void    Clear_prerequisites ANSI((HOWPTR));
  959. Xextern    void    Clear_signals ANSI(());
  960. Xextern  void    Clean_up_processes ANSI(());
  961. Xextern    FILE*    Closefile ANSI(());
  962. Xextern  void    Close_temp ANSI((HOWPTR, FILE *));
  963. Xextern    void    Create_macro_vars ANSI(());
  964. Xextern    DFAPTR    Construct_dfa ANSI((char *));
  965. Xextern    CELLPTR    Def_cell ANSI((char *, CELLPTR));
  966. Xextern    HASHPTR    Def_macro ANSI((char *, char *, int));
  967. Xextern    STRINGPTR    Def_recipe ANSI((char *, STRINGPTR, int, int));
  968. Xextern    int     Do_cmnd ANSI((char *, int, int, CELLPTR, HOWPTR, int, int));
  969. Xextern    time_t    Do_stat ANSI((char *, char *, char **));
  970. Xextern    time_t    Do_time ANSI(());
  971. Xextern    int    Do_touch ANSI((char *, char *, char **));
  972. Xextern    void    Dump ANSI(());
  973. Xextern    void    Dump_recipe ANSI((STRINGPTR));
  974. Xextern    void     Epilog ANSI((int));
  975. Xextern    char*    Expand ANSI((char *));
  976. Xextern  CELLPTR Explode_cell ANSI((CELLPTR, CELLPTR));
  977. Xextern  HOWPTR  Explode_how ANSI((HOWPTR, CELLPTR, int));
  978. Xextern  LINKPTR Explode_prq ANSI((LINKPTR, CELLPTR, int));
  979. Xextern  char*   Filename ANSI(());
  980. Xextern    char*    Get_current_dir ANSI(());
  981. Xextern    int    Get_line ANSI((char *, FILE *));
  982. Xextern    HASHPTR    Get_name ANSI((char *, HASHPTR *, int, CELLPTR));
  983. Xextern    char*    Get_suffix ANSI((char *));
  984. Xextern    char    Get_switch_char ANSI(());
  985. Xextern    char*    Get_token ANSI((TKSTRPTR, char *, int));
  986. Xextern    uint16    Hash ANSI((char *,uint32 *));
  987. Xextern  void    Handle_result ANSI((int, int, int, CELLPTR));
  988. Xextern    int    If_root_path ANSI((char *));
  989. Xextern    CELLPTR    Infer_recipe ANSI((CELLPTR, HOWPTR, DFASETPTR, CELLPTR));
  990. Xextern    int    Macro_op ANSI((char *));
  991. Xextern    int    Make ANSI((CELLPTR, HOWPTR, CELLPTR));
  992. Xextern    void    Make_rules ANSI(());
  993. Xextern  void    Map_esc ANSI((char *));
  994. Xextern    DFALINKPTR    Match_dfa ANSI((char *));
  995. Xextern    char*    My_malloc ANSI((unsigned int, char *, int));
  996. Xextern    char*    My_calloc ANSI((unsigned int, unsigned int, char *, int));
  997. Xextern    void    My_free ANSI((char *, char *, int));
  998. Xextern  void    No_ram ANSI(());
  999. Xextern    FILE*    Open_temp ANSI((char **, char *));
  1000. Xextern    FILE*    Openfile ANSI((char *, int));
  1001. Xextern  void    Pack_argv ANSI((char **, int, int, char *));
  1002. Xextern    void    Parse ANSI((FILE *));
  1003. Xextern    int    Parse_macro ANSI((char *, int));
  1004. Xextern    int    Parse_rule_def ANSI((int *));
  1005. Xextern    void    Pop_dir ANSI((int));
  1006. Xextern    void    Prolog ANSI((int, char **));
  1007. Xextern    int    Push_dir ANSI((CELLPTR, int));
  1008. Xextern    void    Quit ANSI(());
  1009. Xextern    char*    Read_env_string ANSI((char *));
  1010. Xextern    void    ReadEnvironment ANSI(());
  1011. Xextern  void    Remove_prq ANSI((CELLPTR));
  1012. Xextern    int    Rule_op ANSI((char *));
  1013. Xextern    int    runargv ANSI((CELLPTR, HOWPTR, int, int, int, char *));
  1014. Xextern    time_t    seek_arch ANSI((char*, char*));
  1015. Xextern    int    Set_dir ANSI((char *));
  1016. Xextern    int    Set_group_attributes ANSI((char *));
  1017. Xextern    void    Stat_target ANSI((CELLPTR, int));
  1018. Xextern  FILE*   Start_temp ANSI((char *, CELLPTR, HOWPTR, char **));
  1019. Xextern    int    Test_circle ANSI((CELLPTR, int));
  1020. Xextern    int    touch_arch ANSI((char*, char*));
  1021. Xextern  void    Unlink_temp_files ANSI((HOWPTR));
  1022. Xextern  void    Update_time_stamp ANSI((CELLPTR, HOWPTR));
  1023. Xextern  void    Void_lib_cache ANSI((char *, char *));
  1024. Xextern  int    Wait_for_child ANSI((int, int));
  1025. Xextern    int    Write_env_string ANSI((char *, char *));
  1026. X
  1027. Xextern    char*    _stradd ANSI((char *,char *, int));
  1028. Xextern    char*    _strapp ANSI((char *,char *));
  1029. Xextern    char*    _strjoin ANSI((char *,char *,int, int));
  1030. Xextern    char*    _strdup ANSI((char *));
  1031. Xextern    char*    _strpbrk ANSI((char *,char *));
  1032. Xextern    char*    _strspn ANSI((char *,char *));
  1033. Xextern    char*    _strstr ANSI((char *,char *));
  1034. Xextern    char*    _substr ANSI((char *,char *));
  1035. X
  1036. X#endif
  1037. X
  1038. SHAR_EOF
  1039. chmod 0440 extern.h || echo "restore of extern.h fails"
  1040. echo "x - extracting expand.c (Text)"
  1041. sed 's/^X//' << 'SHAR_EOF' > expand.c &&
  1042. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/expand.c,v 1.1 90/07/19 13:53:10 dvadura Exp $
  1043. X-- SYNOPSIS -- macro expansion code.
  1044. X-- 
  1045. X-- DESCRIPTION
  1046. X--
  1047. X--    This routine handles all the necessary junk that deals with macro
  1048. X--    expansion.  It understands the following syntax.  If a macro is
  1049. X--    not defined it expands to NULL, and {} are synonyms for ().
  1050. X--
  1051. X--        $$      - expands to $
  1052. X--        {{      - expands to {
  1053. X--            }}      - expands to }
  1054. X--        $A      - expands to whatever the macro A is defined as
  1055. X--        $(AA)   - expands to whatever the macro AA is defined as
  1056. X--        $($(A)) - represents macro indirection
  1057. X--    
  1058. X--        following macro is recognized
  1059. X--        
  1060. X--                string1{ token_list }string2
  1061. X--                
  1062. X--        and expands to string1 prepended to each element of token_list and
  1063. X--        string2 appended to each of the resulting tokens from the first
  1064. X--        operation.  If string2 is of the form above then the result is
  1065. X--        the cross product of the specified (possibly modified) token_lists.
  1066. X--        
  1067. X--        The folowing macro modifiers are defined and expanded:
  1068. X--        
  1069. X--               $(macro:modifier_list:modifier_list:...)
  1070. X--               
  1071. X--        where modifier_list a combination of:
  1072. X--        
  1073. X--               D or d      - Directory portion of token including separator
  1074. X--               F or f      - File portion of token including suffix
  1075. X--               B or b      - basename portion of token not including suffix
  1076. X--         T or t      - for tokenization
  1077. X--
  1078. X--      or a single
  1079. X--               S or s      - pattern substitution (simple)
  1080. X--               
  1081. X--        NOTE:  Modifiers are applied once the macro value has been found.
  1082. X--               Thus the construct $($(test):s/joe/mary/) is defined and
  1083. X--               modifies the value of $($(test))
  1084. X--
  1085. X--           Also the construct $(m:d:f) is not the same as $(m:df)
  1086. X--           the first applies d to the value of $(m) and then
  1087. X--           applies f to the value of that whereas the second form
  1088. X--           applies df to the value of $(m).
  1089. X--
  1090. X-- AUTHOR
  1091. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1092. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1093. X--
  1094. X-- COPYRIGHT
  1095. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1096. X-- 
  1097. X--      This program is free software; you can redistribute it and/or
  1098. X--      modify it under the terms of the GNU General Public License
  1099. X--      (version 1), as published by the Free Software Foundation, and
  1100. X--      found in the file 'LICENSE' included with this distribution.
  1101. X-- 
  1102. X--      This program is distributed in the hope that it will be useful,
  1103. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1104. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1105. X--      GNU General Public License for more details.
  1106. X-- 
  1107. X--      You should have received a copy of the GNU General Public License
  1108. X--      along with this program;  if not, write to the Free Software
  1109. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1110. X--
  1111. X-- LOG
  1112. X--     $Log:    expand.c,v $
  1113. X * Revision 1.1  90/07/19  13:53:10  dvadura
  1114. X * Initial Revision of Version 3.5
  1115. X * 
  1116. X*/
  1117. X
  1118. X#include <ctype.h>
  1119. X#include "extern.h"
  1120. X#include "alloc.h"
  1121. X#include "db.h"
  1122. X
  1123. Xstatic    char*    _scan_token ANSI((char*, char**));
  1124. Xstatic    char*    _scan_macro ANSI((char*, char**));
  1125. Xstatic    char*    _scan_brace ANSI((char*, char**, int*));
  1126. Xstatic    char*    _cross_prod ANSI((char*, char*));
  1127. Xstatic    char*    _apply_modifiers ANSI((int, char*));
  1128. Xstatic    char*    _tokenize ANSI((char*, char*));
  1129. X
  1130. X#define SUFFIX_FLAG    1        /* defines for macro modifier code */
  1131. X#define DIRECTORY_FLAG    2
  1132. X#define FILE_FLAG    4
  1133. X
  1134. X
  1135. Xchar *
  1136. XExpand( src )/*
  1137. X===============
  1138. X      This is the driver routine for the expansion, it identifies non-white
  1139. X      space tokens and gets the _scan_token routine to figure out if they should
  1140. X      be treated in a special way. */
  1141. X
  1142. Xchar *src;                    /* pointer to source string  */
  1143. X{
  1144. X   char  *tmp;              /* pointer to temporary str  */
  1145. X   char  *res;                /* pointer to result string  */
  1146. X   char  *start;              /* pointer to start of token */
  1147. X   
  1148. X   DB_ENTER( "Expand" );
  1149. X   DB_PRINT( "exp", ("Expanding [%s]", src) );
  1150. X
  1151. X   res = _strdup( "" );
  1152. X   if( src == NIL(char) ) DB_RETURN( res );
  1153. X
  1154. X   while( *src ) {
  1155. X      /* Here we find the next non white space token in the string
  1156. X       * and find it's end, with respect to non-significant white space. */
  1157. X      
  1158. X      start = _strspn( src, " \t\n" );
  1159. X      res   = _strjoin( res, src, start-src, TRUE );
  1160. X      if( !(*start) ) break;
  1161. X      res   = _strjoin( res, tmp = _scan_token( start, &src ), -1, TRUE );
  1162. X      FREE( tmp );
  1163. X   }
  1164. X   
  1165. X   DB_PRINT( "exp", ("Returning [%s]", res) );
  1166. X   DB_RETURN( res );
  1167. X}
  1168. X
  1169. X
  1170. X
  1171. Xchar *
  1172. XApply_edit( src, pat, subst, fr, anchor )/*
  1173. X===========================================
  1174. X   Take the src string and apply the pattern substitution.  ie. look for
  1175. X   occurrences of pat in src and replace each occurrence with subst.  This is
  1176. X   NOT a regular expressions pattern substitution, it's just not worth it.
  1177. X   
  1178. X   if anchor == TRUE then the src pattern match must be at the end of a token.
  1179. X   ie. this is for SYSV compatibility and is only used for substitutions of
  1180. X   the caused by $(macro:pat=sub).  So if src = "fre.o.k june.o" then
  1181. X   $(src:.o=.a) results in "fre.o.k june.a", and $(src:s/.o/.a) results in
  1182. X   "fre.a.k june.a" */
  1183. X
  1184. Xchar *src;            /* the source string */
  1185. Xchar *pat;            /* pattern to find   */
  1186. Xchar *subst;            /* substitute string */
  1187. Xint   fr;            /* if TRUE free src  */
  1188. Xint   anchor;            /* if TRUE anchor    */
  1189. X{
  1190. X   char *res;
  1191. X   char *p;
  1192. X   char *s;
  1193. X   int   l;
  1194. X
  1195. X   DB_ENTER( "Apply_edit" );
  1196. X   
  1197. X   if( !*pat ) DB_RETURN( src );        /* do nothing if pat is NULL */
  1198. X
  1199. X   DB_PRINT( "mod", ("Source str:  [%s]", src) );
  1200. X   DB_PRINT( "mod", ("Replacing [%s], with [%s]", pat, subst) );
  1201. X
  1202. X   s   = src;
  1203. X   l   = strlen( pat );
  1204. X   if( (p = _strstr( s, pat )) != NIL(char) ) {
  1205. X      res = _strdup( "" );
  1206. X      do {
  1207. X     if( anchor )
  1208. X        if( !*(p+l) || (strchr(" \t", *(p+l)) != NIL(char)) )
  1209. X           res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
  1210. X        else
  1211. X           res = _strjoin( res, s, p+l-s, TRUE );
  1212. X     else
  1213. X        res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
  1214. X
  1215. X     s   = p + l;
  1216. X      }
  1217. X      while( (p = _strstr( s, pat )) != NIL(char) );
  1218. X
  1219. X      res = _strjoin( res, s, -1, TRUE );
  1220. X      if( fr ) FREE( src );
  1221. X   }
  1222. X   else
  1223. X      res = src;
  1224. X
  1225. X
  1226. X   DB_PRINT( "mod", ("Result [%s]", res) );
  1227. X   DB_RETURN( res );
  1228. X}
  1229. X
  1230. X
  1231. X
  1232. Xvoid
  1233. XMap_esc( tok )/*
  1234. X================
  1235. X   Map an escape sequence and replace it by it's corresponding character
  1236. X   value.  It is assumed that tok points at the initial \, the esc
  1237. X   sequence in the original string is replaced and the value of tok
  1238. X   is not modified. */
  1239. Xchar *tok;
  1240. X{
  1241. X   if( strchr( "\"\\vantbrf01234567", tok[1] ) ) {
  1242. X      switch( tok[1] ) {
  1243. X     case 'a' : *tok = 0x07; break;
  1244. X     case 'b' : *tok = '\b'; break;
  1245. X     case 'f' : *tok = '\f'; break;
  1246. X     case 'n' : *tok = '\n'; break;
  1247. X     case 'r' : *tok = '\r'; break;
  1248. X     case 't' : *tok = '\t'; break;
  1249. X     case 'v' : *tok = 0x0b; break;
  1250. X     case '\\': *tok = '\\'; break;
  1251. X     case '\"': *tok = '\"'; break;
  1252. X
  1253. X     default: {
  1254. X        register int i = 0;
  1255. X        register int j = 0;
  1256. X        for( ; i<2 && isdigit(tok[2]); i++ ) {
  1257. X           j = (j << 3) + (tok[1] - '0');
  1258. X           strcpy( tok+1, tok+2 );
  1259. X        }
  1260. X        j = (j << 3) + (tok[1] - '0');
  1261. X        *tok = j;
  1262. X     }
  1263. X      }
  1264. X      strcpy( tok+1, tok+2 );
  1265. SHAR_EOF
  1266. echo "End of part 16"
  1267. echo "File expand.c is continued in part 17"
  1268. echo "17" > s2_seq_.tmp
  1269. exit 0
  1270.  
  1271.