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

  1. Newsgroups: comp.sources.misc
  2. From: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  3. Subject:  v19i029:  dmake - dmake version 3.7, Part08/37
  4. Message-ID: <1991May10.185717.22492@sparky.IMD.Sterling.COM>
  5. Date: Fri, 10 May 1991 18:57:17 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7.  
  8. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  9. Posting-number: Volume 19, Issue 29
  10. Archive-name: dmake/part08
  11. Supersedes: dmake-3.6: Volume 15, Issue 52-77
  12.  
  13. ---- Cut Here and feed the following to sh ----
  14. #!/bin/sh
  15. # this is dmake.shar.08 (part 8 of a multipart archive)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file dmake/dmake.c continued
  18. #
  19. if test ! -r _shar_seq_.tmp; then
  20.     echo 'Please unpack part 1 first!'
  21.     exit 1
  22. fi
  23. (read Scheck
  24.  if test "$Scheck" != 8; then
  25.     echo Please unpack part "$Scheck" next!
  26.     exit 1
  27.  else
  28.     exit 0
  29.  fi
  30. ) < _shar_seq_.tmp || exit 1
  31. if test -f _shar_wnt_.tmp; then
  32. sed 's/^X//' << 'SHAR_EOF' >> 'dmake/dmake.c' &&
  33. X   
  34. X   if( next_file_slot == MAX_INC_DEPTH )
  35. X      Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH);
  36. X
  37. X   DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
  38. X
  39. X   if( strcmp("-", name) == 0 ) {
  40. X      name = "stdin";
  41. X      fil = stdin;
  42. X   }
  43. X   else
  44. X      fil = fopen( name, mode ? "w":"r" );
  45. X
  46. X   if( Verbose & V_FILE_IO )
  47. X      printf( "%s:  Openning [%s] for %s", Pname, name, mode?"write":"read" );
  48. X
  49. X   if( fil == NIL(FILE) ) {
  50. X      if( Verbose & V_FILE_IO ) printf( " (fail)\n" );
  51. X      if( err )
  52. X         Fatal( mode ? "Cannot open file %s for write" : "File %s not found",
  53. X        name );
  54. X   }
  55. X   else {
  56. X      if( Verbose & V_FILE_IO ) printf( " (success)\n" );
  57. X      ftab[next_file_slot].file   = fil;
  58. X      ftab[next_file_slot].numb   = Line_number;
  59. X      ftab[next_file_slot++].name = _strdup(name);
  60. X      Line_number = 0;
  61. X      _set_inc_depth();
  62. X   }
  63. X
  64. X   DB_RETURN(fil);
  65. }
  66. X
  67. X
  68. PUBLIC FILE *
  69. Closefile()/*
  70. =============
  71. X   This routine is used to close the last file opened.  This forces make
  72. X   to open files in a last open first close fashion.  It returns the
  73. X   file pointer to the next file on the stack, and NULL if the stack is empty.*/
  74. {
  75. X   DB_ENTER("Closefile");
  76. X
  77. X   if( !next_file_slot )
  78. X      DB_RETURN( NIL(FILE) );
  79. X
  80. X   if( ftab[--next_file_slot].file != stdin ) {
  81. X      DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
  82. X
  83. X      if( Verbose & V_FILE_IO )
  84. X     printf( "%s:  Closing [%s]\n", Pname, ftab[next_file_slot].name );
  85. X
  86. X      fclose( ftab[next_file_slot].file );
  87. X      FREE( ftab[next_file_slot].name );
  88. X   }
  89. X
  90. X   _set_inc_depth();
  91. X
  92. X   if( next_file_slot > 0 ) {
  93. X      Line_number = ftab[next_file_slot].numb;
  94. X      DB_RETURN( ftab[next_file_slot-1].file );
  95. X   }
  96. X   else
  97. X      Line_number = 0;
  98. X
  99. X   DB_RETURN( NIL(FILE) );
  100. }
  101. X
  102. X
  103. PUBLIC FILE *
  104. Search_file( macname, rname )
  105. char *macname;
  106. char **rname;
  107. {
  108. X   HASHPTR hp;
  109. X   FILE *fil = NIL(FILE);
  110. X   char *fname;
  111. X   char *ename = NIL(char);
  112. X
  113. X   /* order of precedence is:
  114. X    *
  115. X    *   MACNAME  from command line (precious is marked)
  116. X    *         ... via MACNAME:=filename definition.
  117. X    *   MACNAME  from environment
  118. X    *   MACNAME  from builtin rules (not precious)
  119. X    */
  120. X
  121. X   if( (hp = GET_MACRO(macname)) != NIL(HASH) )
  122. X      ename = fname = Expand(hp->ht_value);
  123. X
  124. X   if( hp->ht_flag & M_PRECIOUS ) fil = Openfile(fname, FALSE, FALSE);
  125. X
  126. X   if( fil == NIL(FILE) ) {
  127. X      fname=Expand(Read_env_string(macname));
  128. X      if( fil = Openfile(fname, FALSE, FALSE) ) FREE(ename);
  129. X   }
  130. X
  131. X   if( fil == NIL(FILE) && hp != NIL(HASH) )
  132. X      fil = Openfile(fname=ename, FALSE, FALSE);
  133. X
  134. X   if( rname ) *rname = fname;
  135. X
  136. X   return(fil);
  137. }
  138. X
  139. X
  140. PUBLIC char *
  141. Filename()/*
  142. ============
  143. X   Return name of file on top of stack */
  144. {
  145. X   return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name );
  146. }
  147. X
  148. /*
  149. ** print error message from variable arg list
  150. */
  151. X
  152. static int errflg = TRUE;
  153. static int warnflg = FALSE;
  154. X
  155. static void
  156. errargs(fmt, args)
  157. char    *fmt;
  158. va_list  args;
  159. {
  160. X   int warn = _warn && warnflg && !(Glob_attr & A_SILENT);
  161. X
  162. X   if( errflg || warn ) {
  163. X      char *f = Filename();
  164. X
  165. X      fprintf( stderr, "%s:  ", Pname );
  166. X      if( f != NIL(char) ) fprintf(stderr, "%s:  line %d:  ", f, Line_number);
  167. X
  168. X      if( errflg )
  169. X         fprintf(stderr, "Error -- ");
  170. X      else if( warn )
  171. X         fprintf(stderr, "Warning -- ");
  172. X
  173. X      vfprintf( stderr, fmt, args );
  174. X      putc( '\n', stderr );
  175. X      if( errflg && !Continue ) Quit( NIL(CELL) );
  176. X   }
  177. }
  178. X
  179. /*
  180. ** Print error message and abort
  181. */
  182. int
  183. Fatal(fmt, va_alist)
  184. char *fmt;
  185. va_dcl;
  186. {
  187. X   va_list args;
  188. X
  189. X   va_start(args, fmt);
  190. X   Continue = FALSE;
  191. X   errargs(fmt, args);
  192. X   va_end(args);
  193. }
  194. X
  195. /*
  196. ** error message and exit (unless -k)
  197. */
  198. int
  199. Error(fmt, va_alist)
  200. char*   fmt;
  201. va_dcl;
  202. {
  203. X   va_list args;
  204. X
  205. X   va_start(args, fmt);
  206. X   errargs(fmt, args);
  207. X   va_end(args);
  208. }
  209. X
  210. X
  211. /*
  212. ** non-fatal message
  213. */
  214. int
  215. Warning(fmt, va_alist)
  216. char *fmt;
  217. va_dcl;
  218. {
  219. X   va_list args;
  220. X
  221. X   va_start(args, fmt);
  222. X   warnflg = TRUE;
  223. X   errflg = FALSE;
  224. X   errargs(fmt, args);
  225. X   errflg = TRUE;
  226. X   warnflg = FALSE;
  227. X   va_end(args);
  228. }
  229. X
  230. X
  231. PUBLIC void
  232. No_ram()
  233. {
  234. X   Fatal( "No more memory" );
  235. }
  236. X
  237. X
  238. PUBLIC
  239. X
  240. Usage( eflag )
  241. int eflag;
  242. {
  243. X   if( eflag ) {
  244. X      fprintf(stderr, USAGE, Pname);
  245. X   }
  246. X   else {
  247. X   printf(USAGE, Pname);
  248. X   puts("    -P#        - set max number of child processes for parallel make");
  249. X   puts("    -f file    - use file as the makefile");
  250. #ifdef MSDOS
  251. X   puts("    -C [+]file - duplicate console output to file, ('+' => append)");
  252. #endif
  253. X   puts("    -K file    - use file as the .KEEP_STATE file");
  254. X   puts("    -v{dfimt}  - verbose, indicate what we are doing, (-v => -vdimt)");
  255. X   puts("                   d => dump change of directory info only" );
  256. X   puts("                   f => dump file open/close info only" );
  257. X   puts("                   i => dump inference information only" );
  258. X   puts("                   m => dump make of target information only" );
  259. X   puts("                   t => keep temporary files when done\n" );
  260. X
  261. X   puts("Options: (can be catenated, ie -irn == -i -r -n)");
  262. X   puts("    -A   - enable AUGMAKE special target mapping");
  263. X   puts("    -c   - use non standard comment scanning");
  264. X   puts("    -e   - define environment strings as macros");
  265. X   puts("    -E   - same as -e but done after parsing makefile");
  266. X   puts("    -h   - print out usage info");
  267. X   puts("    -i   - ignore errors");
  268. X   puts("    -k   - make independent targets, even if errors");
  269. X   puts("    -n   - trace and print, do not execute commands");
  270. X   puts("    -p   - print out a version of the makefile");
  271. X   puts("    -q   - check if target is up to date.  Does not do");
  272. X   puts("           anything.  Returns 0 if up to date, 1 otherwise");
  273. X   puts("    -r   - don't use internal rules");
  274. X   puts("    -s   - do your work silently");
  275. X   puts("    -S   - disable parallel (force sequential) make, overrides -P");
  276. X   puts("    -t   - touch, update time stamps without executing commands");
  277. X   puts("    -T   - do not apply transitive closure");
  278. X   puts("    -u   - force unconditional update of target");
  279. X   puts("    -V   - print out version number");
  280. X   puts("    -x   - export macro values to environment");
  281. X   }
  282. X
  283. X   Quit(NIL(CELL));
  284. }
  285. X
  286. X
  287. PUBLIC
  288. Version()
  289. {
  290. X   extern char **Rule_tab;
  291. X   char **p;
  292. X   
  293. X   printf("%s - %s, ", Pname, sccid);
  294. X   printf("Version %s, PL %d\n\n", VERSION, PATCHLEVEL);
  295. X
  296. X   puts("Default Configuration:");
  297. X   for (p=Rule_tab;  *p != NIL(char);  p++)
  298. X      printf("\t%s\n", *p);
  299. }
  300. SHAR_EOF
  301. chmod 0640 dmake/dmake.c ||
  302. echo 'restore of dmake/dmake.c failed'
  303. Wc_c="`wc -c < 'dmake/dmake.c'`"
  304. test 20025 -eq "$Wc_c" ||
  305.     echo 'dmake/dmake.c: original size 20025, current size' "$Wc_c"
  306. rm -f _shar_wnt_.tmp
  307. fi
  308. # ============= dmake/dmake.h ==============
  309. if test -f 'dmake/dmake.h' -a X"$1" != X"-c"; then
  310.     echo 'x - skipping dmake/dmake.h (File already exists)'
  311.     rm -f _shar_wnt_.tmp
  312. else
  313. > _shar_wnt_.tmp
  314. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dmake.h' &&
  315. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.h,v 1.1 91/05/06 15:23:07 dvadura Exp $
  316. -- SYNOPSIS -- global defines for dmake.
  317. -- 
  318. -- DESCRIPTION
  319. --     All the interesting bits and flags that dmake uses are defined here.
  320. --
  321. -- AUTHOR
  322. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  323. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  324. --
  325. -- COPYRIGHT
  326. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  327. -- 
  328. --      This program is free software; you can redistribute it and/or
  329. --      modify it under the terms of the GNU General Public License
  330. --      (version 1), as published by the Free Software Foundation, and
  331. --      found in the file 'LICENSE' included with this distribution.
  332. -- 
  333. --      This program is distributed in the hope that it will be useful,
  334. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  335. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  336. --      GNU General Public License for more details.
  337. -- 
  338. --      You should have received a copy of the GNU General Public License
  339. --      along with this program;  if not, write to the Free Software
  340. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  341. --
  342. -- LOG
  343. --     $Log:    dmake.h,v $
  344. X * Revision 1.1  91/05/06  15:23:07  dvadura
  345. X * dmake Release Version 3.7
  346. X * 
  347. */
  348. X
  349. #ifndef _DMAKE_INCLUDED_
  350. #define _DMAKE_INCLUDED_
  351. X
  352. #define MAX_INC_DEPTH     10     /* max of ten nested include files      */
  353. #define MAX_COND_DEPTH      20     /* max nesting level of conditionals    */
  354. #define ERROR_EXIT_VALUE  255     /* return code of aborted make         */
  355. #define CONTINUATION_CHAR '\\'   /* line continuation \<nl>              */
  356. #define ESCAPE_CHAR       '\\'   /* escape char for used chars           */
  357. #define COMMENT_CHAR      '#'    /* start of comment chars               */
  358. #define TGT_DEP_SEP       ':'    /* separator for targets and dependents */
  359. #define CONDSTART      '.'     /* start of conditional token    eg .IF     */
  360. #define DEF_MAKE_PNAME    "dmake"/* default name to use as name of make  */
  361. X
  362. X
  363. /* ............... Hashing function constants ......................... */
  364. #define HASH_TABLE_SIZE  200            /* See hash.c for description   */
  365. X
  366. X
  367. /* Bit flags for cells and macro definitions. */
  368. #define M_DEFAULT        0x0000         /* default flag value           */
  369. #define M_MARK           0x0001         /* mark for circularity checks  */
  370. #define M_PRECIOUS       0x0002         /* keep macro, same as A_PRE... */
  371. #define M_MULTI          0x0004         /* multiple redefinitions ok!   */
  372. #define M_EXPANDED       0x0008         /* macro has been assigned      */
  373. #define M_USED         0x0010        /* macro has been expanded    */
  374. #define M_LITERAL     0x0020        /* don't strip w/s on macro def */
  375. #define    M_NOEXPORT     0x0040        /* don't export macro for -x    */
  376. #define M_FORCE         0x0080        /* Force a macro redefinition    */
  377. #define M_VAR_BIT        0x1000         /* macro bit variable           */
  378. #define M_VAR_CHAR       0x2000         /* macro char variable          */
  379. #define M_VAR_STRING     0x4000         /* macro string variable        */
  380. #define M_VAR_INT     0x8000        /* macro integer variable    */
  381. X
  382. #define M_VAR_MASK       0xf000         /* macro variable mask          */
  383. X
  384. X
  385. X
  386. /* Global and target attribute flag definitions.
  387. X * If you change the values of these or re-order them make appropriate changes
  388. X * in dump.c so that the output of dmake -p matches the attribute info for a
  389. X * target. */
  390. X
  391. #define A_DEFAULT        0x00000        /* default flag value           */
  392. #define A_PRECIOUS       0x00001        /* object is precious           */
  393. #define A_SILENT         0x00002        /* don't echo commands          */
  394. #define A_LIBRARY        0x00004        /* target is an archive        */
  395. #define A_EPILOG         0x00008        /* insert shell epilog code     */
  396. #define A_PROLOG         0x00010        /* insert shell prolog code     */
  397. #define A_IGNORE         0x00020        /* ignore errors                */
  398. #define A_SYMBOL     0x00040    /* lib member is a symbol    */
  399. #define A_NOINFER     0x00080    /* no trans closure from cell    */
  400. #define A_UPDATEALL     0x00100    /* all targets of rule modified */
  401. #define A_SEQ         0x00200    /* sequential make attribute    */
  402. #define A_SETDIR         0x00400        /* cd to dir when making target */
  403. #define A_SHELL         0x00800    /* run the recipe using a shell */
  404. #define A_SWAP         0x01000    /* swap on exec.        */
  405. #define A_MKSARGS     0x02000    /* use MKS argument swapping    */
  406. #define A_PHONY         0x04000    /* .PHONY attribute        */
  407. #define A_NOSTATE        0x08000    /* don't track state for me     */
  408. #define MAX_ATTR     A_NOSTATE    /* highest valid attribute    */
  409. #define A_LIBRARYM       0x10000        /* target is an archive member  */
  410. #define A_FRINGE     0x20000    /* cell is on the fringe    */
  411. #define A_COMPOSITE     0x40000    /* member of lib(targ) name    */
  412. #define A_FFNAME     0x80000    /* if set, free ce_fname in stat*/
  413. #define A_UPDATED    0x100000    /* Used to mark cell as updated */
  414. #define A_ROOT          0x200000    /* True if it is a root prereq  */
  415. X
  416. X
  417. /* Global and target bit flag definitions */
  418. X
  419. #define F_DEFAULT        0x0000         /* default flag value           */
  420. #define F_MARK         0x0001        /* circularity check mark    */
  421. #define F_MULTI         0x0002        /* multiple rules for target    */
  422. #define F_SINGLE     0x0004        /* exec rules one/prerequisite  */
  423. #define F_TARGET     0x0008        /* marks a target        */
  424. #define F_RULES          0x0010         /* indicates target has rules   */
  425. #define F_GROUP          0x0020         /* indicates that rules are to  */
  426. X                        /* fed to the shell as a group  */
  427. X
  428. #define F_TRANS         0x0040        /* same as F_STAT not used tgthr*/
  429. #define F_STAT         0x0040        /* target already stated    */
  430. #define F_VISITED     0x0080        /* target scheduled for make    */
  431. #define F_USED         0x0080        /* used in releparse.c        */
  432. #define F_SPECIAL     0x0100        /* marks a special target    */
  433. #define F_DFA          0x0200        /* bit for marking added DFA    */
  434. #define F_EXPLICIT     0x0400        /* explicit target in makefile  */
  435. #define F_PERCENT     0x0800        /* marks a target as a % rule    */
  436. #define F_REMOVE     0x1000        /* marks an intermediate target */
  437. #define F_MAGIC         0x2000        /* marks a magic target        */
  438. #define F_INFER         0x4000        /* target is result of inference*/
  439. #define F_MADE         0x8000        /* target is manufactured    */
  440. X
  441. X
  442. /* Definitions for the Parser states */
  443. #define NORMAL_SCAN    0     /* normal processing state */
  444. #define RULE_SCAN      1     /* scan of rule text       */
  445. X
  446. /* definitions for macro operator types */
  447. #define M_OP_EQ  1           /* macro operation is '='  */
  448. #define M_OP_CL  2           /* macro operation is ':=' */
  449. #define M_OP_PL  3           /* macro operation is '+=' */
  450. #define M_OP_PLCL 4          /* macro operation is '+:='*/
  451. #define M_OP_DF  5         /* macro operation is '*=' */
  452. #define M_OP_DFCL 6         /* macro operation is '*:='*/
  453. X
  454. /* definitions for rule operator types */
  455. #define R_OP_CL   1           /* rule operation is ':'   */
  456. #define R_OP_DCL  2           /* rule operation is '::'  */
  457. #define R_OP_BG   4           /* rule operation is ':!'  */
  458. #define R_OP_UP   8           /* rule operation is ':^'  */
  459. #define R_OP_MI  16           /* rule operation is ':-'  */
  460. X
  461. /* definitions for modifier application in Apply_modifiers in expand.c */
  462. #define SUFFIX_FLAG    1        /* defines for macro modifier code */
  463. #define DIRECTORY_FLAG    2
  464. #define FILE_FLAG    4
  465. X
  466. /* special target definitions for use inside dmake */
  467. #define ST_IF        1
  468. #define ST_ELSE        2
  469. #define ST_END        3
  470. #define ST_REST        4    /* remaining special targets */
  471. #define ST_INCLUDE    5
  472. #define ST_SOURCE    7
  473. #define ST_EXPORT    8
  474. #define ST_IMPORT    9
  475. #define ST_ELIF        10
  476. #define ST_KEEP           11
  477. X
  478. /* Flags for controling use of -v switch */
  479. #define V_NONE        0x00
  480. #define V_LEAVE_TMP    0x01
  481. #define V_PRINT_DIR    0x02
  482. #define V_INFER            0x04
  483. #define V_MAKE        0x08
  484. #define V_FILE_IO       0x10
  485. #define V_ALL        (V_LEAVE_TMP | V_PRINT_DIR | V_INFER | V_MAKE |\
  486. X             V_FILE_IO)
  487. X
  488. /* Macro definitions for use inside dmake */
  489. #define SET_TOKEN(A, B)  (A)->tk_str = (B); (A)->tk_cchar = *(B);\
  490. X             (A)->tk_quote = 1;
  491. #define CLEAR_TOKEN(A)   *(A)->tk_str = (A)->tk_cchar
  492. #define GET_MACRO(A)     Get_name(A, Macs, FALSE)
  493. #define iswhite(C)     ((C == ' ') || (C == '\t'))
  494. X
  495. #endif
  496. X
  497. SHAR_EOF
  498. chmod 0640 dmake/dmake.h ||
  499. echo 'restore of dmake/dmake.h failed'
  500. Wc_c="`wc -c < 'dmake/dmake.h'`"
  501. test 8165 -eq "$Wc_c" ||
  502.     echo 'dmake/dmake.h: original size 8165, current size' "$Wc_c"
  503. rm -f _shar_wnt_.tmp
  504. fi
  505. # ============= dmake/dmdump.c ==============
  506. if test -f 'dmake/dmdump.c' -a X"$1" != X"-c"; then
  507.     echo 'x - skipping dmake/dmdump.c (File already exists)'
  508.     rm -f _shar_wnt_.tmp
  509. else
  510. > _shar_wnt_.tmp
  511. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dmdump.c' &&
  512. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmdump.c,v 1.1 91/05/06 15:23:08 dvadura Exp $
  513. -- SYNOPSIS -- dump the internal dag to stdout.
  514. -- 
  515. -- DESCRIPTION
  516. --    This file contains the routine that is called to dump a version of
  517. --    the digested makefile to the standard output.  May be useful perhaps
  518. --    to the ordinary user, and invaluable for debugging make.
  519. -- 
  520. -- AUTHOR
  521. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  522. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  523. --
  524. -- COPYRIGHT
  525. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  526. -- 
  527. --      This program is free software; you can redistribute it and/or
  528. --      modify it under the terms of the GNU General Public License
  529. --      (version 1), as published by the Free Software Foundation, and
  530. --      found in the file 'LICENSE' included with this distribution.
  531. -- 
  532. --      This program is distributed in the hope that it will be useful,
  533. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  534. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  535. --      GNU General Public License for more details.
  536. -- 
  537. --      You should have received a copy of the GNU General Public License
  538. --      along with this program;  if not, write to the Free Software
  539. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  540. --
  541. -- LOG
  542. --     $Log:    dmdump.c,v $
  543. X * Revision 1.1  91/05/06  15:23:08  dvadura
  544. X * dmake Release Version 3.7
  545. X * 
  546. */
  547. X
  548. #include "extern.h"
  549. X
  550. #define M_TEST    (M_PRECIOUS | M_VAR_MASK)
  551. X
  552. static    void    dump_name ANSI((HASHPTR, int));
  553. static    void    dump_normal_target ANSI((CELLPTR, int));
  554. static  void    dump_prerequisites ANSI((LINKPTR, int, int, int));
  555. X
  556. X
  557. PUBLIC void
  558. Dump()/*
  559. ========  Dump onto standard output the digested makefile.  Note that
  560. X      the form of the dump is not representative of the contents
  561. X      of the original makefile contents at all */
  562. {
  563. X   HASHPTR      hp;
  564. X   int          i;
  565. X
  566. X   DB_ENTER( "Dump" );
  567. X
  568. X   puts( "# Dump of dmake macro variables:" );
  569. X   for( i=0; i<HASH_TABLE_SIZE; i++)
  570. X      for( hp=Macs[i]; hp != NIL(HASH); hp = hp->ht_next ) {
  571. X     int flag = hp->ht_flag;
  572. X
  573. X     printf( "%s ", hp->ht_name );
  574. X     if( flag & M_EXPANDED ) putchar( ':' );
  575. X     printf( "= " );
  576. X     if( hp->ht_value != NIL(char) ) printf( hp->ht_value );
  577. X     if( flag & M_PRECIOUS )
  578. X        printf( "\t # PRECIOUS " );
  579. X     putchar( '\n' );
  580. X      }
  581. X
  582. X   puts( "\n#====================================" );
  583. X   puts( "# Dump of targets:\n" );
  584. X
  585. X   for( i=0; i<HASH_TABLE_SIZE; i++ )
  586. X      for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
  587. X         if( !(hp->CP_OWNR->ce_flag & F_PERCENT) ) {
  588. X        if( Root->ce_prq && hp->CP_OWNR == Root->ce_prq->cl_prq )
  589. X           puts( "# ******* FIRST TARGET ********" );
  590. X        dump_normal_target( hp->CP_OWNR, hp->CP_OWNR->ce_flag );
  591. X     }
  592. X
  593. X   puts( "\n#====================================" );
  594. X   puts( "# Dump of inference graph\n" );
  595. X
  596. X   for( i=0; i<HASH_TABLE_SIZE; i++ )
  597. X      for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
  598. X         if( (hp->CP_OWNR->ce_flag & F_PERCENT) &&
  599. X        !(hp->CP_OWNR->ce_flag & F_MAGIC) )
  600. X        dump_normal_target( hp->CP_OWNR, hp->CP_OWNR->ce_flag );
  601. X
  602. X   DB_VOID_RETURN;
  603. }
  604. X
  605. X
  606. X
  607. PUBLIC void
  608. Dump_recipe( sp )/*
  609. ===================
  610. X   Given a string pointer print the recipe line out */
  611. STRINGPTR sp;
  612. {
  613. X   char *st;
  614. X   char *nl;
  615. X
  616. X   if( sp == NIL(STRING) ) return;
  617. X
  618. X   putchar( '\t' );
  619. X   if( sp->st_attr & A_SILENT ) putchar( '@' );
  620. X   if( sp->st_attr & A_IGNORE ) putchar( '-' );
  621. X   if( sp->st_attr & A_SHELL  ) putchar( '+' );
  622. X   if( sp->st_attr & A_SWAP   ) putchar( '%' );
  623. X
  624. X   st = sp->st_string;
  625. X   for( nl=strchr(st,'\n'); nl != NIL( char); nl=strchr(st,'\n') ) {
  626. X      *nl = '\0';
  627. X      printf( "%s\\\n", st );
  628. X      *nl = '\n';
  629. X      st  = nl+1;
  630. X   }
  631. X   printf( "%s\n", st );
  632. }
  633. X
  634. X
  635. static char *_attrs[] = { ".PRECIOUS", ".SILENT", ".LIBRARY",
  636. X   ".EPILOG", ".PROLOG", ".IGNORE", ".SYMBOL", ".NOINFER",
  637. X   ".UPDATEALL", ".SEQUENTIAL", ".SETDIR=", ".USESHELL", ".SWAP", ".MKSARGS",
  638. X   ".PHONY", ".NOSTATE" };
  639. X
  640. static void
  641. dump_normal_target( cp, flag )/*
  642. ================================
  643. X    Dump in makefile like format the dag information */
  644. CELLPTR cp;
  645. int     flag;
  646. {
  647. X   register LINKPTR   lp;
  648. X   register STRINGPTR sp;
  649. X   t_attr          attr;
  650. X   unsigned int          k;
  651. X
  652. X   DB_ENTER( "dump_normal_target" );
  653. X
  654. X   if( !(cp->ce_flag & F_TARGET) && !cp->ce_attr ) { DB_VOID_RETURN; }
  655. X
  656. X   if( cp->ce_flag & F_MULTI ) {
  657. X      int tflag = cp->ce_prq->cl_prq->ce_flag;
  658. X      if( !(cp->ce_flag & F_PERCENT) ) tflag |= F_MULTI;
  659. X      dump_prerequisites(cp->ce_prq, FALSE, TRUE, tflag);
  660. X   }
  661. X   else {
  662. X      dump_name( cp->ce_name, FALSE );
  663. X
  664. X      for( k=0, attr=1; attr <= MAX_ATTR; attr <<= 1, k++ )
  665. X     if( cp->ce_attr & attr ) {
  666. X        printf( "%s%s ", _attrs[k],
  667. X            (attr != A_SETDIR) ? "" : (cp->ce_dir?cp->ce_dir:"") );
  668. X     }
  669. X        
  670. X      putchar( ':' );
  671. X
  672. X      if( flag & F_MULTI )  putchar( ':' );
  673. X      if( flag & F_SINGLE ) putchar( '!' );
  674. X      putchar( ' ' );
  675. X
  676. X      dump_prerequisites( cp->ce_prq, FALSE, FALSE, F_DEFAULT);
  677. X      dump_prerequisites( cp->ce_indprq, TRUE, FALSE, F_DEFAULT);
  678. X
  679. X      putchar( '\n' );
  680. X      if( cp->ce_flag & F_GROUP ) puts( "[" );
  681. X      for( sp = cp->ce_recipe; sp != NIL(STRING); sp = sp->st_next )
  682. X     Dump_recipe( sp );
  683. X      if( cp->ce_flag & F_GROUP ) puts( "]" );
  684. X
  685. X      putchar( '\n' );
  686. X   }
  687. X
  688. X   DB_VOID_RETURN;
  689. }
  690. X
  691. X
  692. static void
  693. dump_prerequisites( lp, quote, recurse, flag )
  694. LINKPTR lp;
  695. int     quote;
  696. int     recurse;
  697. int     flag;
  698. {
  699. X   for( ; lp; lp=lp->cl_next )
  700. X      if( recurse )
  701. X     dump_normal_target(lp->cl_prq, flag);
  702. X      else if( lp->cl_prq )
  703. X     dump_name(lp->cl_prq->ce_name, quote);
  704. }
  705. X
  706. X
  707. static void
  708. dump_name( hp, quote )/*
  709. ========================
  710. X    print out a name */
  711. HASHPTR hp;
  712. int     quote;
  713. {
  714. X   if( quote ) putchar('\'');
  715. X   printf( "%s", hp->ht_name );
  716. X   if( quote ) putchar('\'');
  717. X   putchar(' ');
  718. }
  719. SHAR_EOF
  720. chmod 0640 dmake/dmdump.c ||
  721. echo 'restore of dmake/dmdump.c failed'
  722. Wc_c="`wc -c < 'dmake/dmdump.c'`"
  723. test 5857 -eq "$Wc_c" ||
  724.     echo 'dmake/dmdump.c: original size 5857, current size' "$Wc_c"
  725. rm -f _shar_wnt_.tmp
  726. fi
  727. # ============= dmake/dmstring.c ==============
  728. if test -f 'dmake/dmstring.c' -a X"$1" != X"-c"; then
  729.     echo 'x - skipping dmake/dmstring.c (File already exists)'
  730.     rm -f _shar_wnt_.tmp
  731. else
  732. > _shar_wnt_.tmp
  733. sed 's/^X//' << 'SHAR_EOF' > 'dmake/dmstring.c' &&
  734. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmstring.c,v 1.1 91/05/06 15:23:09 dvadura Exp $
  735. -- SYNOPSIS -- string handling code
  736. -- 
  737. -- DESCRIPTION
  738. --    Routines to handle string manipulation.  This code is not specific
  739. --    to dmake and has/and will be used in other programs.  The string
  740. --    "" is considered the NULL string, if NIL(char) is received instead
  741. --    undefined results may occurr.  (In reality NIL(char) is checked for
  742. --    but in general it is not safe to assume NIL(char) ==  NULL)
  743. -- 
  744. -- AUTHOR
  745. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  746. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  747. --
  748. -- COPYRIGHT
  749. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  750. -- 
  751. --      This program is free software; you can redistribute it and/or
  752. --      modify it under the terms of the GNU General Public License
  753. --      (version 1), as published by the Free Software Foundation, and
  754. --      found in the file 'LICENSE' included with this distribution.
  755. -- 
  756. --      This program is distributed in the hope that it will be useful,
  757. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  758. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  759. --      GNU General Public License for more details.
  760. -- 
  761. --      You should have received a copy of the GNU General Public License
  762. --      along with this program;  if not, write to the Free Software
  763. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  764. --
  765. -- LOG
  766. --     $Log:    dmstring.c,v $
  767. X * Revision 1.1  91/05/06  15:23:09  dvadura
  768. X * dmake Release Version 3.7
  769. X * 
  770. */
  771. X
  772. #include "extern.h"
  773. X
  774. PUBLIC char *
  775. _strjoin( src, data, n, fr )/*
  776. ==============================
  777. X   Join data to src according to value of n.
  778. X
  779. X      n = -1   - return strcat( src, data )
  780. X      n >= 0   - return strncat( src, data, n )
  781. X
  782. X   FREE original src if fr == TRUE, else leave it alone */
  783. X
  784. char *src;
  785. char *data;
  786. int  n;
  787. int  fr;
  788. {
  789. X   char *t;
  790. X   int  l;
  791. X   int  flag = FALSE;
  792. X
  793. X   DB_ENTER( "_strjoin" );
  794. X   
  795. X   if( src  == NIL(char) ) { src = ""; flag = TRUE; }
  796. X   if( data == NIL(char) ) data = "";
  797. X   DB_PRINT( "str", ("Joining [%s] [%s] %d", src, data, n) );
  798. X
  799. X   if( n == -1 )  n = strlen( data );
  800. X
  801. X   l = strlen( src ) + n + 1;
  802. X   if( (t = MALLOC( l, char )) == NIL(char) ) No_ram();
  803. X
  804. X   strcpy( t, src );
  805. X   if (n) strncat( t, data, n );
  806. X   t[ l-1 ] = '\0';
  807. X
  808. X   if( !flag && fr ) FREE( src );
  809. X
  810. X   DB_PRINT( "str", ("Result  [%s]", t) );
  811. X   DB_RETURN( t );
  812. }
  813. X
  814. X
  815. X
  816. X
  817. PUBLIC char *
  818. _stradd( src, data, fr )/*
  819. ==========================
  820. X   append data to src with space in between if src is not NIL(char) or ""
  821. X   and free both src and data if fr == TRUE, otherwise leave them be */
  822. X
  823. char *src;
  824. char *data;
  825. int  fr;
  826. {
  827. X   char *t;
  828. X   int  l;
  829. X   int  sflag;
  830. X   int  dflag;
  831. X
  832. X   DB_ENTER( "_stradd" );
  833. X
  834. X   sflag = dflag = fr;
  835. X
  836. X   if( src  == NIL(char) ) { src  = ""; sflag = FALSE; }
  837. X   if( data == NIL(char) ) { data = ""; dflag = FALSE; }
  838. X   DB_PRINT( "str", ("Adding [%s] [%s] %d", src, data, fr) );
  839. X
  840. X   l = strlen(src) + strlen(data) + 1;
  841. X   if( *src ) l++;
  842. X
  843. X   if( (t = MALLOC( l, char )) == NIL(char) ) No_ram();
  844. X
  845. X   strcpy( t, src );
  846. X   
  847. X   if( *data )
  848. X   {
  849. X      if( *src ) strcat( t,  " " );
  850. X      strcat( t, data );
  851. X   }
  852. X
  853. X   if( sflag )  FREE( src  );
  854. X   if( dflag )  FREE( data );
  855. X
  856. X   DB_PRINT( "str", ("Result  [%s]", t) );
  857. X   DB_RETURN( t );
  858. }
  859. X
  860. X
  861. X
  862. PUBLIC char *
  863. _strapp( src1, src2 )/*
  864. =======================
  865. X   Append two strings together, and return the result with a space between
  866. X   the two strings.  FREE the first string if it is not NIL and always
  867. X   leave the second string be. */
  868. char *src1;
  869. char *src2;
  870. {
  871. X   src2 = _stradd( src1, src2, FALSE );
  872. X   if( src1 != NIL(char) ) FREE( src1 );
  873. X   return( src2 );
  874. }
  875. X
  876. X
  877. X
  878. #ifdef DBUG
  879. #ifdef _strdup
  880. #undef _strdup
  881. #endif
  882. #endif
  883. PUBLIC char *
  884. _strdup( str )/*
  885. ================  Duplicate the contents of a string, by using malloc */
  886. char *str;
  887. {
  888. X   char *t;
  889. X
  890. X   if( str == NIL(char) ) return( NIL(char) );
  891. X   
  892. X   if( (t = MALLOC( strlen( str )+1, char )) == NIL(char) ) No_ram();
  893. X   strcpy( t, str );
  894. X
  895. X   return( t );
  896. }
  897. X
  898. X
  899. X
  900. X
  901. PUBLIC char *
  902. _strpbrk( s1, s2 )/*
  903. ====================
  904. X   find first occurence of char in s2 in string s1.
  905. X   Returns a pointer to the first occurrence.  NOTE '\0' is considered part
  906. X   of s2 and a pointer to it is returned if no other chars match. */
  907. X
  908. char *s1;
  909. char *s2;
  910. {
  911. X   register char *t;
  912. X
  913. X   if( s1 == NIL(char) || s2 == NIL(char) ) return( "" );
  914. X
  915. X   for( t=s1; *t && (strchr( s2, *t ) == NIL(char)); t++ );
  916. X   return( t );
  917. }
  918. X
  919. X
  920. X
  921. X
  922. PUBLIC char *
  923. _strspn( s1, s2 )/*
  924. ===================
  925. X   return pointer to first char in s1 that does not belong to s2.
  926. X   Returns the pointer if match found, else returns pointer to null char
  927. X   in s1. (ie. "" ) */
  928. X   
  929. char *s1;
  930. char *s2;
  931. {
  932. X   register char *t;
  933. X
  934. X   if( s1 == NIL(char) || s2 == NIL(char) ) return( "" );
  935. X
  936. X   for( t=s1; *t && (strchr( s2, *t ) != NIL(char)); t++ );
  937. X   return( t );
  938. }
  939. X
  940. X
  941. X
  942. X
  943. PUBLIC char *
  944. _strstr( s1, s2 )/*
  945. ==================  find first occurrence in s1 of s2 */
  946. char *s1;
  947. char *s2;
  948. {
  949. X   register char *s;
  950. X   register char *p;
  951. X   register char *r;
  952. X
  953. X   if( s1 != NIL(char) && s2 != NIL(char) )
  954. X      for( s=s1; *s; s++ )
  955. X     if( *s == *s2 )
  956. X     {
  957. X        for( r=s+1, p = s2+1; *p && (*r == *p); r++, p++ );
  958. X        if( !*p ) return( s );
  959. X     }
  960. X   
  961. X   return( NIL(char) );
  962. }
  963. X
  964. X
  965. X
  966. PUBLIC char *
  967. _substr( s, e )/*
  968. =================
  969. X      Return the string between the two pointers s and e, not including the
  970. X      char that e points to.  NOTE:  This routine assumes that s and e point
  971. X      into the same string. */
  972. X
  973. char *s;
  974. char *e;
  975. {
  976. X   char save;
  977. X   int  len = e-s;
  978. X
  979. X   if( len < 0 || len > strlen(s) )
  980. X      Fatal( "Internal Error:  _substr fails consistency test" );
  981. X
  982. X   save = *e;
  983. X   *e   = '\0';
  984. X   s    = _strdup( s );
  985. X   *e   = save;
  986. X
  987. X   return( s );
  988. }
  989. SHAR_EOF
  990. chmod 0640 dmake/dmstring.c ||
  991. echo 'restore of dmake/dmstring.c failed'
  992. Wc_c="`wc -c < 'dmake/dmstring.c'`"
  993. test 5809 -eq "$Wc_c" ||
  994.     echo 'dmake/dmstring.c: original size 5809, current size' "$Wc_c"
  995. rm -f _shar_wnt_.tmp
  996. fi
  997. # ============= dmake/expand.c ==============
  998. if test -f 'dmake/expand.c' -a X"$1" != X"-c"; then
  999.     echo 'x - skipping dmake/expand.c (File already exists)'
  1000.     rm -f _shar_wnt_.tmp
  1001. else
  1002. > _shar_wnt_.tmp
  1003. sed 's/^X//' << 'SHAR_EOF' > 'dmake/expand.c' &&
  1004. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/expand.c,v 1.1 91/05/06 15:23:10 dvadura Exp $
  1005. -- SYNOPSIS -- macro expansion code.
  1006. -- 
  1007. -- DESCRIPTION
  1008. --
  1009. --    This routine handles all the necessary junk that deals with macro
  1010. --    expansion.  It understands the following syntax.  If a macro is
  1011. --    not defined it expands to NULL, and {} are synonyms for ().
  1012. --
  1013. --        $$      - expands to $
  1014. --        {{      - expands to {
  1015. --            }}      - expands to }
  1016. --        $A      - expands to whatever the macro A is defined as
  1017. --        $(AA)   - expands to whatever the macro AA is defined as
  1018. --        $($(A)) - represents macro indirection
  1019. --        <+...+> - get mapped to $(mktmp ...)
  1020. --    
  1021. --        following macro is recognized
  1022. --        
  1023. --                string1{ token_list }string2
  1024. --                
  1025. --        and expands to string1 prepended to each element of token_list and
  1026. --        string2 appended to each of the resulting tokens from the first
  1027. --        operation.  If string2 is of the form above then the result is
  1028. --        the cross product of the specified (possibly modified) token_lists.
  1029. --        
  1030. --        The folowing macro modifiers are defined and expanded:
  1031. --        
  1032. --               $(macro:modifier_list:modifier_list:...)
  1033. --               
  1034. --        where modifier_list a combination of:
  1035. --        
  1036. --               D or d      - Directory portion of token including separator
  1037. --               F or f      - File portion of token including suffix
  1038. --               B or b      - basename portion of token not including suffix
  1039. --         T or t      - for tokenization
  1040. --
  1041. --      or a single
  1042. --               S or s      - pattern substitution (simple)
  1043. --               
  1044. --        NOTE:  Modifiers are applied once the macro value has been found.
  1045. --               Thus the construct $($(test):s/joe/mary/) is defined and
  1046. --               modifies the value of $($(test))
  1047. --
  1048. --           Also the construct $(m:d:f) is not the same as $(m:df)
  1049. --           the first applies d to the value of $(m) and then
  1050. --           applies f to the value of that whereas the second form
  1051. --           applies df to the value of $(m).
  1052. --
  1053. -- AUTHOR
  1054. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1055. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1056. --
  1057. -- COPYRIGHT
  1058. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1059. -- 
  1060. --      This program is free software; you can redistribute it and/or
  1061. --      modify it under the terms of the GNU General Public License
  1062. --      (version 1), as published by the Free Software Foundation, and
  1063. --      found in the file 'LICENSE' included with this distribution.
  1064. -- 
  1065. --      This program is distributed in the hope that it will be useful,
  1066. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1067. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1068. --      GNU General Public License for more details.
  1069. -- 
  1070. --      You should have received a copy of the GNU General Public License
  1071. --      along with this program;  if not, write to the Free Software
  1072. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1073. --
  1074. -- LOG
  1075. --     $Log:    expand.c,v $
  1076. X * Revision 1.1  91/05/06  15:23:10  dvadura
  1077. X * dmake Release Version 3.7
  1078. X * 
  1079. */
  1080. X
  1081. #include "extern.h"
  1082. X
  1083. /* Microsoft BRAINDAMAGE ALERT!!!!
  1084. X * This #ifdef is here only to satisfy stupid bugs in MSC5.0 and MSC5.1
  1085. X * it isn't needed for anything else.  It turns loop optimization off. */
  1086. #if defined(_MSC_VER)
  1087. #include "optoff.h"
  1088. #endif
  1089. X
  1090. static    char*    _scan_token ANSI((char*, char**));
  1091. static    char*    _scan_macro ANSI((char*, char**));
  1092. static    char*    _scan_brace ANSI((char*, char**, int*));
  1093. static    char*    _cross_prod ANSI((char*, char*));
  1094. X
  1095. X
  1096. PUBLIC char *
  1097. Expand( src )/*
  1098. ===============
  1099. X      This is the driver routine for the expansion, it identifies non-white
  1100. X      space tokens and gets the _scan_token routine to figure out if they should
  1101. X      be treated in a special way. */
  1102. X
  1103. char *src;                    /* pointer to source string  */
  1104. {
  1105. X   char  *tmp;              /* pointer to temporary str  */
  1106. X   char  *res;                /* pointer to result string  */
  1107. X   char  *start;              /* pointer to start of token */
  1108. X   
  1109. X   DB_ENTER( "Expand" );
  1110. X   DB_PRINT( "exp", ("Expanding [%s]", src) );
  1111. X
  1112. X   res = _strdup( "" );
  1113. X   if( src == NIL(char) ) DB_RETURN( res );
  1114. X
  1115. X   while( *src ) {
  1116. X      char *ks, *ke;
  1117. X
  1118. X      /* Here we find the next non white space token in the string
  1119. X       * and find it's end, with respect to non-significant white space. */
  1120. X      
  1121. X      start = _strspn( src, " \t\n" );
  1122. X      res   = _strjoin( res, src, start-src, TRUE );
  1123. X      if( !(*start) ) break;
  1124. X
  1125. X      /* START <+...+> KLUDGE */
  1126. X      if( (ks=_strstr(start,"<+")) && (ke=_strstr(ks,"+>")) ){
  1127. X     char *t1, *t2;
  1128. X
  1129. X     res = _strjoin( res, t2=Expand(t1=_substr(start,ks)), -1, TRUE);
  1130. X     FREE(t1); FREE(t2);
  1131. X
  1132. X     t1 = _substr(ks+2, ke+1); t1[ke-ks-2] = ')';
  1133. X     t2 = _strjoin( "$(mktmp ", t1, -1,FALSE);
  1134. X     FREE(t1);
  1135. X     res = _strjoin( res, t2=Expand(t2), -1, TRUE);
  1136. X     FREE(t2);
  1137. X     src = ke+2;
  1138. X      }
  1139. X      /* END <+...+> KLUDGE */
  1140. X      else {
  1141. X     res   = _strjoin( res, tmp = _scan_token( start, &src ), -1, TRUE );
  1142. X     FREE( tmp );
  1143. X      }
  1144. X   }
  1145. X   
  1146. X   DB_PRINT( "exp", ("Returning [%s]", res) );
  1147. X   DB_RETURN( res );
  1148. }
  1149. X
  1150. X
  1151. PUBLIC char *
  1152. Apply_edit( src, pat, subst, fr, anchor )/*
  1153. ===========================================
  1154. X   Take the src string and apply the pattern substitution.  ie. look for
  1155. X   occurrences of pat in src and replace each occurrence with subst.  This is
  1156. X   NOT a regular expressions pattern substitution, it's just not worth it.
  1157. X   
  1158. X   if anchor == TRUE then the src pattern match must be at the end of a token.
  1159. X   ie. this is for SYSV compatibility and is only used for substitutions of
  1160. X   the caused by $(macro:pat=sub).  So if src = "fre.o.k june.o" then
  1161. X   $(src:.o=.a) results in "fre.o.k june.a", and $(src:s/.o/.a) results in
  1162. X   "fre.a.k june.a" */
  1163. X
  1164. char *src;            /* the source string */
  1165. char *pat;            /* pattern to find   */
  1166. char *subst;            /* substitute string */
  1167. int   fr;            /* if TRUE free src  */
  1168. int   anchor;            /* if TRUE anchor    */
  1169. {
  1170. X   char *res;
  1171. X   char *p;
  1172. X   char *s;
  1173. X   int   l;
  1174. X
  1175. X   DB_ENTER( "Apply_edit" );
  1176. X   
  1177. X   if( !*pat ) DB_RETURN( src );        /* do nothing if pat is NULL */
  1178. X
  1179. X   DB_PRINT( "mod", ("Source str:  [%s]", src) );
  1180. X   DB_PRINT( "mod", ("Replacing [%s], with [%s]", pat, subst) );
  1181. X
  1182. X   s   = src;
  1183. X   l   = strlen( pat );
  1184. X   if( (p = _strstr( s, pat )) != NIL(char) ) {
  1185. X      res = _strdup( "" );
  1186. X      do {
  1187. X     if( anchor )
  1188. X        if( !*(p+l) || (strchr(" \t", *(p+l)) != NIL(char)) )
  1189. X           res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
  1190. X        else
  1191. X           res = _strjoin( res, s, p+l-s, TRUE );
  1192. X     else
  1193. X        res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
  1194. X
  1195. X     s   = p + l;
  1196. X      }
  1197. X      while( (p = _strstr( s, pat )) != NIL(char) );
  1198. X
  1199. X      res = _strjoin( res, s, -1, TRUE );
  1200. X      if( fr ) FREE( src );
  1201. X   }
  1202. X   else
  1203. X      res = src;
  1204. X
  1205. X
  1206. X   DB_PRINT( "mod", ("Result [%s]", res) );
  1207. X   DB_RETURN( res );
  1208. }
  1209. X
  1210. X
  1211. PUBLIC void
  1212. Map_esc( tok )/*
  1213. ================
  1214. X   Map an escape sequence and replace it by it's corresponding character
  1215. X   value.  It is assumed that tok points at the initial \, the esc
  1216. X   sequence in the original string is replaced and the value of tok
  1217. X   is not modified. */
  1218. char *tok;
  1219. {
  1220. X   if( strchr( "\"\\vantbrf01234567", tok[1] ) ) {
  1221. X      switch( tok[1] ) {
  1222. X     case 'a' : *tok = 0x07; break;
  1223. X     case 'b' : *tok = '\b'; break;
  1224. X     case 'f' : *tok = '\f'; break;
  1225. X     case 'n' : *tok = '\n'; break;
  1226. X     case 'r' : *tok = '\r'; break;
  1227. X     case 't' : *tok = '\t'; break;
  1228. X     case 'v' : *tok = 0x0b; break;
  1229. X     case '\\': *tok = '\\'; break;
  1230. X     case '\"': *tok = '\"'; break;
  1231. X
  1232. X     default: {
  1233. X        register int i = 0;
  1234. X        register int j = 0;
  1235. X        for( ; i<2 && isdigit(tok[2]); i++ ) {
  1236. X           j = (j << 3) + (tok[1] - '0');
  1237. X           strcpy( tok+1, tok+2 );
  1238. X        }
  1239. X        j = (j << 3) + (tok[1] - '0');
  1240. X        *tok = j;
  1241. X     }
  1242. X      }
  1243. X      strcpy( tok+1, tok+2 );
  1244. X   }
  1245. }
  1246. X
  1247. X
  1248. PUBLIC char*
  1249. Apply_modifiers( mod, src )/*
  1250. =============================
  1251. X   This routine applies the appropriate modifiers to the string src
  1252. X   and returns the proper result string */
  1253. X
  1254. int  mod;
  1255. char *src;
  1256. {
  1257. X   char       *s;
  1258. X   char    *e;
  1259. X   TKSTR   str;
  1260. X
  1261. X   DB_ENTER( "Apply_modifiers" );
  1262. X
  1263. X   if( mod == (SUFFIX_FLAG | DIRECTORY_FLAG | FILE_FLAG) )
  1264. X      DB_RETURN( src );
  1265. X
  1266. X   SET_TOKEN( &str, src );
  1267. X   DB_PRINT( "mod", ("Source string [%s]", src) );
  1268. X
  1269. X   while( *(s = Get_token( &str, "", FALSE )) != '\0' ) {
  1270. X      /* search for the directory portion of the filename.  If the
  1271. X       * DIRECTORY_FLAG is set, then we want to keep the directory portion
  1272. X       * othewise throw it away and blank out to the end of the token */
  1273. X
  1274. X      if( (e = basename(s)) != s)
  1275. X     if( !(mod & DIRECTORY_FLAG) ) {
  1276. X        strcpy(s, e);
  1277. X        e = s+(str.tk_str-e);
  1278. X        for(; e != str.tk_str; e++)
  1279. X               *e = ' ';
  1280. X     }
  1281. X     else
  1282. X        s = e;
  1283. X
  1284. X      /* search for the suffix, if there is none, treat it as a NULL suffix.
  1285. X       * if no file name treat it as a NULL file name.  same copy op as
  1286. X       * for directory case above */
  1287. X
  1288. X      e = strrchr( s, '.' );            /* NULL suffix if e=0 */
  1289. X      if( e == NIL(char) ) e = s+strlen(s);
  1290. X
  1291. X      if( !(mod & FILE_FLAG) ) {
  1292. X     strcpy( s, e );
  1293. X     e = s+(str.tk_str-e);
  1294. X     for( ; e != str.tk_str; e++ ) *e = ' ';
  1295. X      }
  1296. X      else
  1297. X     s = e;
  1298. X
  1299. X      /* The last and final part.  This is the suffix case, if we don't want
  1300. X       * it then just erase to the end of the token. */
  1301. X
  1302. X      if( s != NIL(char) )
  1303. X     if( !(mod & SUFFIX_FLAG) )
  1304. X        for( ; s != str.tk_str; s++ ) *s = ' ';
  1305. X   }
  1306. X
  1307. X   /* delete the extra white space, it looks ugly */
  1308. X   for( s = src, e = NIL(char); *s; s++ )
  1309. X      if( *s == ' ' || *s == '\t' || *s == '\n' ) {
  1310. X     if( e == NIL(char) )
  1311. X        e = s;
  1312. X      }
  1313. X      else {
  1314. X     if( e != NIL(char) ) {
  1315. X        if( e+1 < s ) {
  1316. X           strcpy( e+1, s );
  1317. X           s = e+1;
  1318. X           *e = ' ';
  1319. X        }
  1320. X        e = NIL(char);
  1321. X     }
  1322. X      }
  1323. X
  1324. X   if( e != NIL(char) )
  1325. X      if( e < s )
  1326. X     strcpy( e, s );
  1327. X
  1328. X   DB_PRINT( "mod", ("Result string [%s]", src) );
  1329. X   DB_RETURN( src );
  1330. }
  1331. X
  1332. X
  1333. PUBLIC char*
  1334. Tokenize( src, separator )/*
  1335. ============================
  1336. X    Tokenize the input of src and join each token found together with
  1337. X    the next token separated by the separator string.
  1338. X
  1339. X    When doing the tokenization, <sp>, <tab>, <nl>, and \<nl> all
  1340. X    constitute white space. */
  1341. X
  1342. char *src;
  1343. char *separator;
  1344. {
  1345. X   TKSTR    tokens;
  1346. X   char        *tok;
  1347. X   char        *res;
  1348. X   int        first = TRUE;
  1349. X
  1350. X   DB_ENTER( "Tokenize" );
  1351. X
  1352. X   SET_TOKEN( &tokens, src );
  1353. X
  1354. X
  1355. X   /* map the escape codes in the separator string first */
  1356. X
  1357. X   for(tok=separator; (tok = strchr(tok,CONTINUATION_CHAR)) != NIL(char); tok++)
  1358. X      Map_esc( tok );
  1359. X
  1360. X   DB_PRINT( "exp", ("Separator [%s]", separator) );
  1361. X
  1362. X   /* Build the token list */
  1363. X   res = _strdup( "" );
  1364. SHAR_EOF
  1365. true || echo 'restore of dmake/expand.c failed'
  1366. fi
  1367. echo 'End of part 8, continue with part 9'
  1368. echo 9 > _shar_seq_.tmp
  1369. exit 0
  1370.  
  1371. exit 0 # Just in case...
  1372. -- 
  1373. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1374. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1375. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1376. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1377.