home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / jam / part03 < prev    next >
Text File  |  1993-11-14  |  62KB  |  2,657 lines

  1. Newsgroups: comp.sources.unix
  2. From: seiwald@vix.com (Christopher Seiwald)
  3. Subject: v27i083: jam - just another make, Part03/05
  4. References: <1.753385306.22859@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: seiwald@vix.com (Christopher Seiwald)
  9. Posting-Number: Volume 27, Issue 83
  10. Archive-Name: jam/part03
  11.  
  12. Submitted-by: seiwald@vix.com
  13. Archive-name: jam - make(1) redux/part03
  14.  
  15. #!/bin/sh
  16. # This is part 03 of jam - make(1) redux
  17. # ============= lists.c ==============
  18. if test -f 'lists.c' -a X"$1" != X"-c"; then
  19.     echo 'x - skipping lists.c (File already exists)'
  20. else
  21. echo 'x - extracting lists.c (Text)'
  22. sed 's/^X//' << 'SHAR_EOF' > 'lists.c' &&
  23. X/*
  24. X * Copyright 1993 Christopher Seiwald.
  25. X */
  26. X
  27. X# include "jam.h"
  28. X# include "newstr.h"
  29. X# include "lists.h"
  30. X
  31. X/*
  32. X * lists.c - maintain lists of strings
  33. X *
  34. X * The whole of jam relies on lists of strings as a datatype.  This
  35. X * module, in conjunction with newstr.c, handles these relatively
  36. X * efficiently.
  37. X *
  38. X * External routines:
  39. X *
  40. X *    list_new() - tack a string onto the end of a list of strings
  41. X *     list_copy() - copy a whole list of strings
  42. X *    list_sublist() - copy a subset of a list of strings
  43. X *    list_free() - free a list of strings
  44. X *    list_print() - print a list of strings to stdout
  45. X *
  46. X * This implementation essentially uses a singly linked list, but
  47. X * guarantees that the head element of every list has a valid pointer
  48. X * to the tail of the list, so the new elements can efficiently and 
  49. X * properly be appended to the end of a list.
  50. X *
  51. X * To avoid massive allocation, list_free() just tacks the whole freed
  52. X * chain onto freelist and list_new() looks on freelist first for an 
  53. X * available list struct.  list_free() does not free the strings in the 
  54. X * chain: it lazily lets list_new() do so.
  55. X */
  56. X
  57. Xstatic LIST *freelist = 0;    /* junkpile for list_free() */
  58. X
  59. X/*
  60. X * list_new() - tack a string onto the end of a list of strings
  61. X */
  62. X
  63. XLIST *
  64. Xlist_new( head, string )
  65. XLIST    *head;
  66. Xchar    *string;
  67. X{
  68. X    LIST *l;
  69. X
  70. X    if( DEBUG_LISTS )
  71. X        printf( "list > %s <\n", string );
  72. X
  73. X    /* Get list struct from freelist, if one available.  */
  74. X    /* Otherwise allocate. */
  75. X    /* If from freelist, must free string first */
  76. X
  77. X    if( freelist )
  78. X    {
  79. X        l = freelist;
  80. X        freestr( l->string );
  81. X        freelist = freelist->next;
  82. X    }
  83. X    else
  84. X    {
  85. X        l = (LIST *)malloc( sizeof( *l ) );
  86. X    }
  87. X
  88. X    /* If first on chain, head points here. */
  89. X    /* If adding to chain, tack us on. */
  90. X    /* Tail must point to this new, last element. */
  91. X
  92. X    if( !head ) head = l;
  93. X    else head->tail->next = l;
  94. X    head->tail = l;
  95. X    l->next = 0;
  96. X
  97. X    l->string = string;
  98. X
  99. X    return head;
  100. X}
  101. X
  102. X/*
  103. X * list_copy() - copy a whole list of strings
  104. X */
  105. X
  106. XLIST *
  107. Xlist_copy( l, nl )
  108. XLIST    *l;
  109. XLIST     *nl;
  110. X{
  111. X    for( ; nl; nl = list_next( nl ) )
  112. X        l = list_new( l, copystr( nl->string ) );
  113. X
  114. X    return l;
  115. X}
  116. X
  117. X/*
  118. X * list_sublist() - copy a subset of a list of strings
  119. X */
  120. X
  121. XLIST *
  122. Xlist_sublist( l, start, count )
  123. XLIST    *l;
  124. X{
  125. X    LIST    *nl = 0;
  126. X
  127. X    for( ; l && start--; l = list_next( l ) )
  128. X        ;
  129. X
  130. X    for( ; l && count--; l = list_next( l ) )
  131. X        nl = list_new( nl, copystr( l->string ) );
  132. X
  133. X    return nl;
  134. X}
  135. X
  136. X/*
  137. X * list_free() - free a list of strings
  138. X */
  139. X
  140. Xvoid
  141. Xlist_free( head )
  142. XLIST    *head;
  143. X{
  144. X    /* Just tack onto freelist. */
  145. X
  146. X    if( head )
  147. X    {
  148. X        head->tail->next = freelist;
  149. X        freelist = head;
  150. X    }
  151. X}
  152. X
  153. X/*
  154. X * list_print() - print a list of strings to stdout
  155. X */
  156. X
  157. Xvoid
  158. Xlist_print( l )
  159. XLIST    *l;
  160. X{
  161. X    for( ; l; l = list_next( l ) )
  162. X        printf( "%s ", l->string );
  163. X}
  164. SHAR_EOF
  165. chmod 0444 lists.c ||
  166. echo 'restore of lists.c failed'
  167. Wc_c="`wc -c < 'lists.c'`"
  168. test 2752 -eq "$Wc_c" ||
  169.     echo 'lists.c: original size 2752, current size' "$Wc_c"
  170. fi
  171. # ============= lists.h ==============
  172. if test -f 'lists.h' -a X"$1" != X"-c"; then
  173.     echo 'x - skipping lists.h (File already exists)'
  174. else
  175. echo 'x - extracting lists.h (Text)'
  176. sed 's/^X//' << 'SHAR_EOF' > 'lists.h' &&
  177. X/*
  178. X * Copyright 1993 Christopher Seiwald.
  179. X */
  180. X
  181. X/*
  182. X * lists.h - the LIST structure and routines to manipulate them
  183. X */
  184. X
  185. X/*
  186. X * LIST - list of strings
  187. X */
  188. X
  189. Xtypedef struct _list LIST;
  190. X
  191. Xstruct _list {
  192. X    LIST    *next;
  193. X    LIST    *tail;        /* only valid in head node */
  194. X    char    *string;    /* private copy */
  195. X} ;
  196. X
  197. XLIST     *list_copy();
  198. XLIST     *list_new();
  199. Xvoid    list_free();
  200. Xvoid    list_print();
  201. XLIST    *list_sublist();
  202. X
  203. X# define list_next( l ) ((l)->next)
  204. SHAR_EOF
  205. chmod 0444 lists.h ||
  206. echo 'restore of lists.h failed'
  207. Wc_c="`wc -c < 'lists.h'`"
  208. test 427 -eq "$Wc_c" ||
  209.     echo 'lists.h: original size 427, current size' "$Wc_c"
  210. fi
  211. # ============= make.c ==============
  212. if test -f 'make.c' -a X"$1" != X"-c"; then
  213.     echo 'x - skipping make.c (File already exists)'
  214. else
  215. echo 'x - extracting make.c (Text)'
  216. sed 's/^X//' << 'SHAR_EOF' > 'make.c' &&
  217. X/*
  218. X * Copyright 1993 Christopher Seiwald.
  219. X */
  220. X
  221. X/*
  222. X * make.c - bring a target up to date, once rules are in place
  223. X *
  224. X * This modules controls the execution of rules to bring a target and
  225. X * its dependencies up to date.  It is invoked after the targets, rules,
  226. X * et. al. described in rules.h are created by the interpreting of the
  227. X * jam files.
  228. X *
  229. X * External routines:
  230. X *    make() - make a target, given its name
  231. X *
  232. X * Internal routines:
  233. X *     make0() - bind and scan everything to make a TARGET
  234. X *     make1() - execute commands to update a TARGET
  235. X *     make1a() - execute all actions to build a target
  236. X *    make1b() - execute single command to update a target
  237. X *    make1c() - execute a (piecemeal) piece of a command to update a target
  238. X *    make1u() - remove targets after interrupted command
  239. X *    makexlist() - turn a list of targets into a LIST, for $(<) and $(>)
  240. X */
  241. X
  242. X# include "jam.h"
  243. X
  244. X# include "lists.h"
  245. X# include "parse.h"
  246. X# include "variable.h"
  247. X# include "rules.h"
  248. X
  249. X# include "search.h"
  250. X# include "newstr.h"
  251. X# include "make.h"
  252. X# include "headers.h"
  253. X# include "execcmd.h"
  254. X
  255. Xstatic void make0();
  256. Xstatic void make1();
  257. Xstatic int make1a();
  258. Xstatic int make1b();
  259. Xstatic int make1c();
  260. Xstatic int make1chunk();
  261. Xstatic void make1u();
  262. Xstatic LIST *makexlist();
  263. X
  264. X# define max( a,b ) ((a)>(b)?(a):(b))
  265. X
  266. Xtypedef struct {
  267. X    int    temp;
  268. X    int    updating;
  269. X    int    dontknow;
  270. X    int    targets;
  271. X    int    made;
  272. X} COUNTS ;
  273. X
  274. X# define DONTCARE    0
  275. X# define DOCARE        1
  276. X
  277. Xstatic char *target_fate[] = 
  278. X{
  279. X    "init",
  280. X    "making",
  281. X    "ok",
  282. X    "touched",
  283. X    "temp",
  284. X    "missing",
  285. X    "old",
  286. X    "update",
  287. X    "can't"
  288. X} ;
  289. X
  290. X# define spaces(x) ( "                " + 16 - ( x > 16 ? 16 : x ) )
  291. X
  292. X/*
  293. X * make() - make a target, given its name
  294. X */
  295. X
  296. Xvoid
  297. Xmake( n_targets, targets )
  298. Xint    n_targets;
  299. Xchar    **targets;
  300. X{
  301. X    int i;
  302. X    COUNTS counts[1];
  303. X
  304. X    memset( (char *)counts, 0, sizeof( *counts ) );
  305. X
  306. X    for( i = 0; i < n_targets; i++ )
  307. X        make0( bindtarget( targets[i] ), (time_t)0, 0, counts );
  308. X
  309. X    if( DEBUG_MAKEQ )
  310. X    {
  311. X        if( counts->targets )
  312. X        printf( "...found %d target(s)...\n", counts->targets );
  313. X    }
  314. X
  315. X    if( DEBUG_MAKE )
  316. X    {
  317. X        if( counts->temp )
  318. X        printf( "...using %d temp target(s)...\n", counts->temp );
  319. X        if( counts->updating )
  320. X        printf( "...updating %d target(s)...\n", counts->updating );
  321. X        if( counts->dontknow )
  322. X        printf( "...can't make %d target(s)...\n", counts->dontknow );
  323. X    }
  324. X
  325. X    for( i = 0; i < n_targets; i++ )
  326. X        make1( bindtarget( targets[i] ), counts );
  327. X}
  328. X
  329. X/*
  330. X * make0() - bind and scan everything to make a TARGET
  331. X *
  332. X * Make0() recursively binds a target, searches for #included headers,
  333. X * calls itself on those headers, and calls itself on any dependents.
  334. X */
  335. X
  336. Xstatic void
  337. Xmake0( t, parent, depth, counts )
  338. XTARGET    *t;
  339. Xtime_t    parent;
  340. Xint    depth;
  341. XCOUNTS    *counts;
  342. X{
  343. X    TARGETS    *c;
  344. X    int    fate, hfate;
  345. X    time_t    last, hlast;
  346. X    char    *flag = "";
  347. X
  348. X    if( DEBUG_MAKEPROG )
  349. X        printf( "make\t--\t%s%s\n", spaces( depth ), t->name );
  350. X
  351. X    /* 
  352. X     * Step 1: don't remake if already trying or tried 
  353. X     */
  354. X
  355. X    switch( t->fate )
  356. X    {
  357. X    case T_FATE_MAKING:
  358. X        printf( "warning: %s depends on itself\n", t->name );
  359. X        return;
  360. X
  361. X    default:
  362. X        return;
  363. X
  364. X    case T_FATE_INIT:
  365. X        break;
  366. X    }
  367. X
  368. X    t->fate = T_FATE_MAKING;
  369. X
  370. X    /*
  371. X     * Step 2: under the influence of "on target" variables,
  372. X     * bind the target and search for headers.
  373. X     */
  374. X
  375. X    /* Step 2a: set "on target" variables. */
  376. X
  377. X    pushsettings( t->settings );
  378. X
  379. X    /* Step 2b: find and timestamp the target file (if it's a file). */
  380. X
  381. X    if( t->binding == T_BIND_UNBOUND && !( t->flags & T_FLAG_NOTIME ) )
  382. X    {
  383. X        t->boundname = search( t->name, &t->time );
  384. X        t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
  385. X    }
  386. X
  387. X    /* If temp file doesn't exist, use parent */
  388. X
  389. X    if( t->binding == T_BIND_MISSING && t->flags & T_FLAG_TEMP && parent )
  390. X    {
  391. X        t->time = parent;
  392. X        t->binding = t->time ? T_BIND_TEMP : T_BIND_MISSING;
  393. X    }
  394. X
  395. X    /* Step 2c: If its a file, search for headers. */
  396. X
  397. X    if( t->binding == T_BIND_EXISTS )
  398. X        headers( t );
  399. X
  400. X    /* Step 2d: reset "on target" variables */
  401. X
  402. X    popsettings( t->settings );
  403. X
  404. X    /* 
  405. X     * Step 3: recursively make0() dependents 
  406. X     */
  407. X
  408. X    /* Step 3a: recursively make0() dependents */
  409. X
  410. X    last = 0;
  411. X    fate = T_FATE_STABLE;
  412. X
  413. X    for( c = t->deps; c; c = c->next )
  414. X    {
  415. X        make0( c->target, t->time, depth + 1, counts );
  416. X        last = max( last, c->target->time );
  417. X        last = max( last, c->target->htime );
  418. X        fate = max( fate, c->target->fate );
  419. X        fate = max( fate, c->target->hfate );
  420. X    }
  421. X
  422. X    /* Step 3b: recursively make0() headers */
  423. X
  424. X    hlast = 0;
  425. X    hfate = T_FATE_STABLE;
  426. X
  427. X    for( c = t->headers; c; c = c->next )
  428. X    {
  429. X        make0( c->target, parent, depth + 1, counts );
  430. X        hlast = max( hlast, c->target->time );
  431. X        hlast = max( hlast, c->target->htime );
  432. X        hfate = max( hfate, c->target->fate );
  433. X        hfate = max( hfate, c->target->hfate );
  434. X    }
  435. X
  436. X    /* 
  437. X     * Step 4: aftermath: determine fate and propapate dependents time
  438. X     * and fate.
  439. X     */
  440. X
  441. X    /* Step 4a: determine fate: rebuild target or what? */
  442. X    /* If children newer than target or */
  443. X    /* If target doesn't exist, rebuild.  */
  444. X
  445. X    if( fate > T_FATE_STABLE )
  446. X    {
  447. X        fate = T_FATE_UPDATE;
  448. X    }
  449. X    else if( t->binding == T_BIND_MISSING )
  450. X    {
  451. X        fate = T_FATE_MISSING;
  452. X    }
  453. X    else if( t->binding == T_BIND_EXISTS && last > t->time )
  454. X    {
  455. X        fate = T_FATE_OUTDATED;
  456. X    }
  457. X    else if( t->binding == T_BIND_TEMP && last > t->time )
  458. X    {
  459. X        fate = T_FATE_OUTDATED;
  460. X    }
  461. X    else if( t->binding == T_BIND_EXISTS && t->flags & T_FLAG_TEMP )
  462. X    {
  463. X        fate = T_FATE_ISTMP;
  464. X    }
  465. X    else if( t->flags & T_FLAG_TOUCHED )
  466. X    {
  467. X        fate = T_FATE_TOUCHED;
  468. X    }
  469. X
  470. X    /* Step 4b: handle missing files */
  471. X    /* If it's missing and there are no actions to create it, boom. */
  472. X    /* If we can't make a target we don't care about, 'sokay */
  473. X
  474. X    if( fate == T_FATE_MISSING && !t->actions && !t->deps )
  475. X    {
  476. X        if( t->flags & T_FLAG_NOCARE )
  477. X        {
  478. X        fate = T_FATE_STABLE;
  479. X        }
  480. X        else
  481. X        {
  482. X        fate = T_FATE_DONTKNOW;
  483. X        printf( "don't know how to make %s\n", t->name );
  484. X        }
  485. X    }
  486. X
  487. X    /* Step 4c: Step 6: propagate dependents' time & fate. */
  488. X
  489. X    t->time = max( t->time, last );
  490. X    t->fate = fate;
  491. X
  492. X    t->htime = hlast;
  493. X    t->hfate = hfate;
  494. X
  495. X    /* 
  496. X     * Step 5: a little harmless tabulating for tracing purposes 
  497. X     */
  498. X
  499. X    if( !( ++counts->targets % 1000 ) && DEBUG_MAKE )
  500. X        printf( "...patience...\n" );
  501. X
  502. X    if( fate > T_FATE_ISTMP && t->actions )
  503. X        counts->updating++;
  504. X    else if( fate == T_FATE_ISTMP )
  505. X        counts->temp++;
  506. X    else if( fate == T_FATE_DONTKNOW )
  507. X        counts->dontknow++;
  508. X
  509. X    if( t->binding == T_BIND_EXISTS && parent && t->time > parent )
  510. X        flag = "*";
  511. X
  512. X    if( DEBUG_MAKEPROG )
  513. X        printf( "make%s\t%s\t%s%s\n", 
  514. X        flag, target_fate[ t->fate ], 
  515. X        spaces( depth ), t->name );
  516. X}
  517. X
  518. X/*
  519. X * make1() - execute commands to update a TARGET
  520. X */
  521. X
  522. Xstatic void
  523. Xmake1( t, counts )
  524. XTARGET    *t;
  525. XCOUNTS    *counts;
  526. X{
  527. X    TARGETS    *c;
  528. X    char *failed = "dependents";
  529. X
  530. X    /* Don't remake if already trying or tried */
  531. X
  532. X    if( t->progress != T_MAKE_INIT )
  533. X        return;
  534. X
  535. X    t->progress = T_MAKE_STABLE;
  536. X
  537. X    /* recurseively make1() headers */
  538. X
  539. X    for( c = t->headers; c && t->progress != T_MAKE_INTR; c = c->next )
  540. X    {
  541. X        make1( c->target, counts );
  542. X
  543. X        if( c->target->progress > t->progress )
  544. X        {
  545. X            t->progress = c->target->progress;
  546. X        failed = c->target->name;
  547. X        }
  548. X    }
  549. X
  550. X    /* recursively make1() dependents */
  551. X
  552. X    for( c = t->deps; c && t->progress != T_MAKE_INTR; c = c->next )
  553. X    {
  554. X        make1( c->target, counts );
  555. X
  556. X        if( c->target->progress > t->progress )
  557. X        {
  558. X            t->progress = c->target->progress;
  559. X        failed = c->target->name;
  560. X        }
  561. X    }
  562. X
  563. X    /* If it's missing and there are no actions to create it, boom. */
  564. X    /* if reasonable, execute all actions to make target */
  565. X
  566. X    if( t->progress == T_MAKE_FAIL )
  567. X    {
  568. X        printf( "%s skipped for lack of %s\n", t->name, failed );
  569. X    }
  570. X    else if( t->progress == T_MAKE_INTR )
  571. X    {
  572. X        return;
  573. X    }
  574. X    else switch( t->fate )
  575. X    {
  576. X    case T_FATE_INIT:
  577. X    case T_FATE_MAKING:
  578. X        /* shouldn't happen */ ;
  579. X
  580. X    case T_FATE_STABLE:
  581. X        break;
  582. X
  583. X    case T_FATE_ISTMP:
  584. X        if( DEBUG_MAKEQ )
  585. X        printf( "using %s\n", t->name );
  586. X        t->progress = T_MAKE_OK;
  587. X        break;
  588. X
  589. X    case T_FATE_MISSING:
  590. X    case T_FATE_OUTDATED:
  591. X    case T_FATE_UPDATE:
  592. X        /* Set "on target" vars, execute actions, unset vars */
  593. X
  594. X        pushsettings( t->settings );
  595. X        t->progress = make1a( t->name, t->actions );
  596. X        popsettings( t->settings );
  597. X
  598. X        if( !( ++counts->made % 100 ) && DEBUG_MAKE )
  599. X        printf( "...on %dth target...\n", counts->made );
  600. X
  601. X        break;
  602. X
  603. X    case T_FATE_DONTKNOW:
  604. X        t->progress = T_MAKE_FAIL;
  605. X        break;
  606. X    }
  607. X}
  608. X
  609. X/*
  610. X * make1a() - execute all actions to build a target
  611. X *
  612. X * Executes all actions to build a given target, if the actions haven't
  613. X * been executed previously.
  614. X *
  615. X * Returns:
  616. X *    T_MAKE_FAIL    execution of command failed
  617. X *    T_MAKE_OK    execution successful
  618. X */
  619. X
  620. Xstatic int
  621. Xmake1a( name, actions )
  622. Xchar    *name;
  623. XACTIONS *actions;
  624. X{
  625. X    /* Step through actions */
  626. X    /* Actions may be shared with other targets or grouped with */
  627. X    /* RULE_TOGETHER, so actions already executed are expected. */
  628. X
  629. X    for( ; actions; actions = actions->next )
  630. X    {
  631. X        ACTION  *action = actions->action;
  632. X        RULE    *rule = action->rule;
  633. X        LIST    *targets;
  634. X        LIST    *sources;
  635. X        ACTIONS *a1;
  636. X
  637. X        /* Only do rules with commands to execute. */
  638. X        /* If this action has already been executed, use saved progress */
  639. X
  640. X        if( !rule->actions )
  641. X        continue;
  642. X        
  643. X        switch( action->progress )
  644. X        {
  645. X        case T_MAKE_OK:    continue;
  646. X        case T_MAKE_FAIL:    return T_MAKE_FAIL;
  647. X        case T_MAKE_INIT:    /* fall through */;
  648. X        }
  649. X
  650. X        /* Make LISTS of targets and sources */
  651. X        /* If `execute together` has been specified for this rule, tack */
  652. X        /* on sources from each instance of this rule for this target. */
  653. X
  654. X        targets = makexlist( (LIST *)0, action->targets, 0 );
  655. X        sources = makexlist( (LIST *)0, action->sources, 
  656. X                    rule->flags & RULE_NEWSRCS );
  657. X
  658. X        if( rule->flags & RULE_TOGETHER )
  659. X        for( a1 = actions->next; a1; a1 = a1->next )
  660. X            if( a1->action->rule == rule )
  661. X        {
  662. X        sources = makexlist( sources, a1->action->sources, 
  663. X                    rule->flags & RULE_NEWSRCS );
  664. X        }
  665. X
  666. X        /* Execute single command, saving progress */
  667. X        /* If `execute together` has been specified for this rule, */
  668. X        /* distribute progress to each instance of this rule. */
  669. X
  670. X        if( rule->flags & RULE_QUIETLY ? DEBUG_MAKEQ : DEBUG_MAKE )
  671. X        printf( "%s %s\n", rule->name, name );
  672. X
  673. X        action->progress = make1b( rule, targets, sources );
  674. X
  675. X        if( rule->flags & RULE_TOGETHER )
  676. X        for( a1 = actions->next; a1; a1 = a1->next )
  677. X            if( a1->action->rule == rule )
  678. X        {
  679. X        a1->action->progress = action->progress;
  680. X        }
  681. X
  682. X        /* Free target & source lists */
  683. X
  684. X        list_free( targets );
  685. X        list_free( sources );
  686. X
  687. X        /* Abandon target if any rule fails. */
  688. X
  689. X        if( action->progress != T_MAKE_OK )
  690. X        return action->progress;
  691. X    }
  692. X    
  693. X    return T_MAKE_OK;
  694. X}
  695. X
  696. X/*
  697. X * make1b() - execute single command to update a target
  698. X *
  699. X * Returns:
  700. X *    T_MAKE_FAIL    execution of command failed
  701. X *    T_MAKE_OK    execution successful
  702. X */
  703. X
  704. Xstatic int
  705. Xmake1b( rule, targets, sources )
  706. XRULE    *rule;
  707. XLIST    *targets;
  708. XLIST    *sources;
  709. X{
  710. X    int    chunk = 0;
  711. X    LIST    *somes;
  712. X    int    status = T_MAKE_OK;
  713. X
  714. X    /* If rule is to be cut into (at most) MAXCMD pieces, estimate */
  715. X    /* bytes per $(>) element and aim for using MAXCMD minus a two */
  716. X    /* element pad. */
  717. X
  718. X    if( rule->flags & RULE_PIECEMEAL )
  719. X        chunk = make1chunk( rule->actions, targets, sources );
  720. X
  721. X    /* If cutting rule up, make separate invocations of make1c() for */
  722. X    /* each chunk of $(>).  Otherwise, do it 'ole. */
  723. X
  724. X    if( DEBUG_EXEC && chunk )
  725. X        printf( "%d arguments per invocation\n", chunk );
  726. X
  727. X    if( chunk )
  728. X    {
  729. X        int start;
  730. X
  731. X        for( start = 0;
  732. X             somes = list_sublist( sources, start, chunk );
  733. X         start += chunk )
  734. X        {
  735. X        status = make1c( rule, targets, somes );
  736. X        list_free( somes );
  737. X        
  738. X        if( status != T_MAKE_OK )
  739. X            break;
  740. X        }
  741. X    }
  742. X    else
  743. X    {
  744. X        status = make1c( rule, targets, sources );
  745. X    }
  746. X
  747. X    /* If the command was interrupted and the target is not */
  748. X    /* "precious", remove the targets */
  749. X
  750. X    if( status == T_MAKE_INTR && !( rule->flags & RULE_TOGETHER ) )
  751. X        make1u( targets );
  752. X
  753. X    return status;
  754. X}
  755. X
  756. X/* 
  757. X * make1c() - execute a (piecemeal) piece of a command to update a target
  758. X */
  759. X
  760. Xstatic int
  761. Xmake1c( rule, targets, sources )
  762. XRULE    *rule;
  763. XLIST    *targets;
  764. XLIST    *sources;
  765. X{
  766. X    int    len;
  767. X    char    buf[ MAXCMD ];
  768. X
  769. X    len = var_string( rule->actions, buf, targets, sources );
  770. X    
  771. X    if( len > MAXCMD )
  772. X    {
  773. X        /* Can't do much here - we just blew our stack! */
  774. X        printf( "fatal error: command too long\n" );
  775. X        exit( -1 );
  776. X    }
  777. X
  778. X    if( DEBUG_EXEC )
  779. X        printf( "%s\n", buf );
  780. X
  781. X    if( globs.noexec )
  782. X        return T_MAKE_OK;
  783. X
  784. X    if( DEBUG_MAKE )
  785. X        fflush( stdout );
  786. X    
  787. X    switch( execcmd( buf ) )
  788. X    {
  789. X    case EXEC_CMD_OK:
  790. X        return T_MAKE_OK;
  791. X
  792. X    case EXEC_CMD_FAIL:
  793. X        if( rule->flags & RULE_IGNORE )
  794. X        return T_MAKE_OK;
  795. X
  796. X        return T_MAKE_FAIL;
  797. X
  798. X    case EXEC_CMD_INTR: 
  799. X        printf( "...interrupted\n" );
  800. X        return T_MAKE_INTR;
  801. X
  802. X    default:
  803. X        return T_MAKE_FAIL; /* NOTREACHED */
  804. X    }
  805. X}
  806. X
  807. Xstatic int
  808. Xmake1chunk( cmd, targets, sources )
  809. Xchar    *cmd;
  810. XLIST    *targets;
  811. XLIST    *sources;
  812. X{
  813. X    int onesize;
  814. X    int onediff;
  815. X    int chunk = 0;
  816. X    LIST *somes;
  817. X    char buf[ MAXCMD ];
  818. X
  819. X    somes = list_sublist( sources, 0, 1 );
  820. X    onesize = var_string( cmd, buf, targets, somes );
  821. X    list_free( somes );
  822. X
  823. X    somes = list_sublist( sources, 0, 2 );
  824. X    onediff = var_string( cmd, buf, targets, somes ) - onesize;
  825. X    list_free( somes );
  826. X
  827. X    if( onediff > 0 )
  828. X        chunk = 3 * ( MAXCMD - onesize ) / 4 / onediff + 1;
  829. X
  830. X    return chunk;
  831. X}
  832. X
  833. X/*
  834. X * make1u() - remove targets after interrupted command
  835. X */
  836. X
  837. Xstatic void
  838. Xmake1u( targets )
  839. XLIST *targets;
  840. X{
  841. X    for( ; targets; targets = list_next( targets ) )
  842. X    {
  843. X        if( !unlink( targets->string ) )
  844. X        printf( "%s removed\n", targets->string );
  845. X    }
  846. X}
  847. X
  848. X/*
  849. X * makexlist() - turn a list of targets into a LIST, for $(<) and $(>)
  850. X */
  851. X
  852. Xstatic LIST *
  853. Xmakexlist( l, targets, newonly )
  854. XLIST    *l;
  855. XTARGETS    *targets;
  856. Xint    newonly;
  857. X{
  858. X    for( ; targets; targets = targets->next )
  859. X    {
  860. X    TARGET *t = targets->target;
  861. X
  862. X    /*
  863. X     * spot the kludge!  If a target is not in the dependency tree,
  864. X     * it didn't get bound by make0(), so we have to do it here.
  865. X     * Ugly.
  866. X     */
  867. X
  868. X    if( t->binding == T_BIND_UNBOUND && !( t->flags & T_FLAG_NOTIME ) )
  869. X    {
  870. X        printf( "warning: using independent target %s\n", t->name );
  871. X        pushsettings( t->settings );
  872. X        t->boundname = search( t->name, &t->time );
  873. X        t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
  874. X        popsettings( t->settings );
  875. X    }
  876. X
  877. X    if( !newonly || t->fate > T_FATE_STABLE )
  878. X        l = list_new( l, copystr( t->boundname ) );
  879. X    }
  880. X
  881. X    return l;
  882. X}
  883. SHAR_EOF
  884. chmod 0444 make.c ||
  885. echo 'restore of make.c failed'
  886. Wc_c="`wc -c < 'make.c'`"
  887. test 14415 -eq "$Wc_c" ||
  888.     echo 'make.c: original size 14415, current size' "$Wc_c"
  889. fi
  890. # ============= make.h ==============
  891. if test -f 'make.h' -a X"$1" != X"-c"; then
  892.     echo 'x - skipping make.h (File already exists)'
  893. else
  894. echo 'x - extracting make.h (Text)'
  895. sed 's/^X//' << 'SHAR_EOF' > 'make.h' &&
  896. X/*
  897. X * Copyright 1993 Christopher Seiwald.
  898. X */
  899. X
  900. X/*
  901. X * make.h - bring a target up to date, once rules are in place
  902. X */
  903. X
  904. Xvoid make();
  905. SHAR_EOF
  906. chmod 0444 make.h ||
  907. echo 'restore of make.h failed'
  908. Wc_c="`wc -c < 'make.h'`"
  909. test 131 -eq "$Wc_c" ||
  910.     echo 'make.h: original size 131, current size' "$Wc_c"
  911. fi
  912. # ============= newstr.c ==============
  913. if test -f 'newstr.c' -a X"$1" != X"-c"; then
  914.     echo 'x - skipping newstr.c (File already exists)'
  915. else
  916. echo 'x - extracting newstr.c (Text)'
  917. sed 's/^X//' << 'SHAR_EOF' > 'newstr.c' &&
  918. X/*
  919. X * Copyright 1993 Christopher Seiwald.
  920. X */
  921. X
  922. X# include "jam.h"
  923. X# include "newstr.h"
  924. X# include "hash.h"
  925. X
  926. X/*
  927. X * newstr.c - string manipulation routines
  928. X *
  929. X * To minimize string copying, string creation, copying, and freeing
  930. X * is done through newstr.
  931. X *
  932. X * External functions:
  933. X *
  934. X *    newstr() - return a malloc'ed copy of a string
  935. X *    copystr() - return a copy of a string previously returned by newstr()
  936. X *    freestr() - free a string returned by newstr() or copystr()
  937. X *    donestr() - free string tables
  938. X *
  939. X * Once a string is passed to newstr(), the returned string is readonly.
  940. X *
  941. X * This implementation builds a hash table of all strings, so that multiple 
  942. X * calls of newstr() on the same string allocate memory for the string once.
  943. X * Strings are never actually freed.
  944. X */
  945. X
  946. Xtypedef char *STRING;
  947. X
  948. Xstatic struct hash *strhash = 0;
  949. Xstatic int strtotal = 0;
  950. X
  951. X/*
  952. X * newstr() - return a malloc'ed copy of a string
  953. X */
  954. X
  955. Xchar *
  956. Xnewstr( string )
  957. Xchar *string;
  958. X{
  959. X    STRING str, *s = &str;
  960. X
  961. X    if( !strhash )
  962. X        strhash = hashinit( sizeof( STRING ), "strings" );
  963. X
  964. X    *s = string;
  965. X
  966. X    if( hashenter( strhash, (HASHDATA **)&s ) )
  967. X    {
  968. X        int l = strlen( string );
  969. X        char *m = (char *)malloc( l + 1 );
  970. X
  971. X        strtotal += l + 1;
  972. X        memcpy( m, string, l + 1 );
  973. X        *s = m;
  974. X    }
  975. X
  976. X    return *s;
  977. X}
  978. X
  979. X/*
  980. X * copystr() - return a copy of a string previously returned by newstr()
  981. X */
  982. X
  983. Xchar *
  984. Xcopystr( s )
  985. Xchar    *s;
  986. X{
  987. X    return s;
  988. X}
  989. X
  990. X/*
  991. X * freestr() - free a string returned by newstr() or copystr()
  992. X */
  993. X
  994. Xvoid
  995. Xfreestr( s )
  996. Xchar *s;
  997. X{
  998. X}
  999. X
  1000. X/*
  1001. X * donestr() - free string tables
  1002. X */
  1003. X
  1004. Xvoid
  1005. Xdonestr()
  1006. X{
  1007. X    hashdone( strhash );
  1008. X
  1009. X    if( DEBUG_MEM )
  1010. X        printf( "%dK in strings\n", strtotal / 1024 );
  1011. X}
  1012. SHAR_EOF
  1013. chmod 0444 newstr.c ||
  1014. echo 'restore of newstr.c failed'
  1015. Wc_c="`wc -c < 'newstr.c'`"
  1016. test 1671 -eq "$Wc_c" ||
  1017.     echo 'newstr.c: original size 1671, current size' "$Wc_c"
  1018. fi
  1019. # ============= newstr.h ==============
  1020. if test -f 'newstr.h' -a X"$1" != X"-c"; then
  1021.     echo 'x - skipping newstr.h (File already exists)'
  1022. else
  1023. echo 'x - extracting newstr.h (Text)'
  1024. sed 's/^X//' << 'SHAR_EOF' > 'newstr.h' &&
  1025. X/*
  1026. X * Copyright 1993 Christopher Seiwald.
  1027. X */
  1028. X
  1029. X/*
  1030. X * newstr.h - string manipulation routines
  1031. X */
  1032. X
  1033. Xchar *newstr();
  1034. Xchar *copystr();
  1035. Xvoid freestr();
  1036. X
  1037. SHAR_EOF
  1038. chmod 0444 newstr.h ||
  1039. echo 'restore of newstr.h failed'
  1040. Wc_c="`wc -c < 'newstr.h'`"
  1041. test 148 -eq "$Wc_c" ||
  1042.     echo 'newstr.h: original size 148, current size' "$Wc_c"
  1043. fi
  1044. # ============= option.c ==============
  1045. if test -f 'option.c' -a X"$1" != X"-c"; then
  1046.     echo 'x - skipping option.c (File already exists)'
  1047. else
  1048. echo 'x - extracting option.c (Text)'
  1049. sed 's/^X//' << 'SHAR_EOF' > 'option.c' &&
  1050. X/*
  1051. X * Copyright 1993 Christopher Seiwald.
  1052. X */
  1053. X
  1054. X# include "jam.h"
  1055. X# include "option.h"
  1056. X
  1057. X/*
  1058. X * option.c - command line option processing
  1059. X *
  1060. X * {o >o
  1061. X *  \<>) "Process command line options as defined in <option.h>.
  1062. X *          Return the number of argv[] elements used up by options,
  1063. X *          or -1 if an invalid option flag was given or an argument
  1064. X *          was supplied for an option that does not require one."
  1065. X */
  1066. X
  1067. Xint
  1068. Xgetoptions(argc, argv, opts, optv)
  1069. Xchar **argv;
  1070. Xchar *opts;
  1071. Xoption *optv;
  1072. X{
  1073. X    int i;
  1074. X    int optc = N_OPTS;
  1075. X
  1076. X    memset( (char *)optv, '\0', sizeof( *optv ) * N_OPTS );
  1077. X
  1078. X    for( i = 0; i < argc; i++ )
  1079. X    {
  1080. X    char *arg;
  1081. X
  1082. X    if( argv[i][0] != '-' || !isalpha( argv[i][1] ) )
  1083. X        break;
  1084. X
  1085. X    if( !optc-- )
  1086. X    {
  1087. X        printf( "too many options\n" );
  1088. X        return -1;
  1089. X    }
  1090. X
  1091. X    for( arg = &argv[i][1]; *arg; arg++ )
  1092. X    {
  1093. X        char *f;
  1094. X
  1095. X        for( f = opts; *f; f++ )
  1096. X        if( *f == *arg )
  1097. X            break;
  1098. X
  1099. X        if( !*f )
  1100. X        {
  1101. X        printf( "Invalid option: -%c\n", *arg );
  1102. X        return -1;
  1103. X        }
  1104. X
  1105. X        optv->flag = *f;
  1106. X
  1107. X        if( f[1] != ':' )
  1108. X        {
  1109. X        optv++->val = "true";
  1110. X        }
  1111. X        else if( arg[1] )
  1112. X        {
  1113. X        optv++->val = &arg[1];
  1114. X        break;
  1115. X        }
  1116. X        else if( ++i < argc )
  1117. X        {
  1118. X        optv++->val = argv[i];
  1119. X        break;
  1120. X        }
  1121. X        else
  1122. X        {
  1123. X        printf( "option: -%c needs argument\n", *f );
  1124. X        return -1;
  1125. X        }
  1126. X    }
  1127. X    }
  1128. X
  1129. X    return i;
  1130. X}
  1131. X
  1132. X/*
  1133. X * Name: getoptval() - find an option given its character
  1134. X */
  1135. X
  1136. Xchar *
  1137. Xgetoptval( optv, opt, subopt )
  1138. Xoption *optv;
  1139. Xchar opt;
  1140. Xint subopt;
  1141. X{
  1142. X    int i;
  1143. X
  1144. X    for( i = 0; i < N_OPTS; i++, optv++ )
  1145. X        if( optv->flag == opt && !subopt-- )
  1146. X        return optv->val;
  1147. X
  1148. X    return 0;
  1149. X}
  1150. SHAR_EOF
  1151. chmod 0444 option.c ||
  1152. echo 'restore of option.c failed'
  1153. Wc_c="`wc -c < 'option.c'`"
  1154. test 1584 -eq "$Wc_c" ||
  1155.     echo 'option.c: original size 1584, current size' "$Wc_c"
  1156. fi
  1157. # ============= option.h ==============
  1158. if test -f 'option.h' -a X"$1" != X"-c"; then
  1159.     echo 'x - skipping option.h (File already exists)'
  1160. else
  1161. echo 'x - extracting option.h (Text)'
  1162. sed 's/^X//' << 'SHAR_EOF' > 'option.h' &&
  1163. X/*
  1164. X * Copyright 1993 Christopher Seiwald.
  1165. X */
  1166. X
  1167. X/*
  1168. X * option.h - command line option processing
  1169. X *
  1170. X * {o >o
  1171. X *  \ -) "Command line option."
  1172. X */
  1173. X
  1174. Xtypedef struct option
  1175. X{
  1176. X    char    flag;        /* filled in by getoption() */
  1177. X    char    *val;        /* set to random address if true */
  1178. X} option;
  1179. X
  1180. X# define N_OPTS 10
  1181. X
  1182. Xint     getoptions( /* int argc, char **argv, char *opts, option *optv */ );
  1183. Xchar     *getoptval( /* option *optv, char opt, int subopt */ );
  1184. SHAR_EOF
  1185. chmod 0444 option.h ||
  1186. echo 'restore of option.h failed'
  1187. Wc_c="`wc -c < 'option.h'`"
  1188. test 428 -eq "$Wc_c" ||
  1189.     echo 'option.h: original size 428, current size' "$Wc_c"
  1190. fi
  1191. # ============= parse.c ==============
  1192. if test -f 'parse.c' -a X"$1" != X"-c"; then
  1193.     echo 'x - skipping parse.c (File already exists)'
  1194. else
  1195. echo 'x - extracting parse.c (Text)'
  1196. sed 's/^X//' << 'SHAR_EOF' > 'parse.c' &&
  1197. X/*
  1198. X * Copyright 1993 Christopher Seiwald.
  1199. X */
  1200. X
  1201. X# include "jam.h"
  1202. X# include "lists.h"
  1203. X# include "parse.h"
  1204. X# include "newstr.h"
  1205. X
  1206. X/*
  1207. X * parse.c - make and destroy parse trees as driven by the parser
  1208. X */
  1209. X
  1210. XPARSE *
  1211. Xparse_make( func, left, right, string, string1, llist, rlist, num )
  1212. Xvoid    (*func)();
  1213. XPARSE    *left;
  1214. XPARSE    *right;
  1215. Xchar    *string;
  1216. Xchar    *string1;
  1217. XLIST    *llist;
  1218. XLIST    *rlist;
  1219. Xint    num;
  1220. X{
  1221. X    PARSE    *p = (PARSE *)malloc( sizeof( PARSE ) );
  1222. X
  1223. X    p->func = func;
  1224. X    p->left = left;
  1225. X    p->right = right;
  1226. X    p->string = string;
  1227. X    p->string1 = string1;
  1228. X    p->llist = llist;
  1229. X    p->rlist = rlist;
  1230. X    p->num = num;
  1231. X
  1232. X    return p;
  1233. X}
  1234. X
  1235. Xvoid
  1236. Xparse_free( p )
  1237. XPARSE    *p;
  1238. X{
  1239. X    if( p->string )
  1240. X        freestr( p->string );
  1241. X    if( p->string1 )
  1242. X        freestr( p->string1 );
  1243. X    if( p->llist )
  1244. X        list_free( p->llist );
  1245. X    if( p->rlist )
  1246. X        list_free( p->rlist );
  1247. X    if( p->left )
  1248. X        parse_free( p->left );
  1249. X    if( p->right )
  1250. X        parse_free( p->right );
  1251. X    
  1252. X    free( (char *)p );
  1253. X}
  1254. SHAR_EOF
  1255. chmod 0444 parse.c ||
  1256. echo 'restore of parse.c failed'
  1257. Wc_c="`wc -c < 'parse.c'`"
  1258. test 923 -eq "$Wc_c" ||
  1259.     echo 'parse.c: original size 923, current size' "$Wc_c"
  1260. fi
  1261. # ============= parse.h ==============
  1262. if test -f 'parse.h' -a X"$1" != X"-c"; then
  1263.     echo 'x - skipping parse.h (File already exists)'
  1264. else
  1265. echo 'x - extracting parse.h (Text)'
  1266. sed 's/^X//' << 'SHAR_EOF' > 'parse.h' &&
  1267. X/*
  1268. X * Copyright 1993 Christopher Seiwald.
  1269. X */
  1270. X
  1271. X/*
  1272. X * parse.h - make and destroy parse trees as driven by the parser
  1273. X */
  1274. X
  1275. X/*
  1276. X * parse tree node
  1277. X */
  1278. X
  1279. Xtypedef struct _PARSE PARSE;
  1280. X
  1281. Xstruct _PARSE {
  1282. X    void    (*func)();
  1283. X    PARSE    *left;
  1284. X    PARSE    *right;
  1285. X    char    *string;
  1286. X    char    *string1;
  1287. X    LIST    *llist;
  1288. X    LIST    *rlist;
  1289. X    int    num;
  1290. X} ;
  1291. X
  1292. XPARSE    *parse_make();
  1293. Xvoid    parse_free();
  1294. SHAR_EOF
  1295. chmod 0444 parse.h ||
  1296. echo 'restore of parse.h failed'
  1297. Wc_c="`wc -c < 'parse.h'`"
  1298. test 354 -eq "$Wc_c" ||
  1299.     echo 'parse.h: original size 354, current size' "$Wc_c"
  1300. fi
  1301. # ============= patchlevel.h ==============
  1302. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  1303.     echo 'x - skipping patchlevel.h (File already exists)'
  1304. else
  1305. echo 'x - extracting patchlevel.h (Text)'
  1306. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  1307. X#define VERSION 1
  1308. X#define PATCHLEVEL 1
  1309. SHAR_EOF
  1310. chmod 0444 patchlevel.h ||
  1311. echo 'restore of patchlevel.h failed'
  1312. Wc_c="`wc -c < 'patchlevel.h'`"
  1313. test 39 -eq "$Wc_c" ||
  1314.     echo 'patchlevel.h: original size 39, current size' "$Wc_c"
  1315. fi
  1316. # ============= regexp.c ==============
  1317. if test -f 'regexp.c' -a X"$1" != X"-c"; then
  1318.     echo 'x - skipping regexp.c (File already exists)'
  1319. else
  1320. echo 'x - extracting regexp.c (Text)'
  1321. sed 's/^X//' << 'SHAR_EOF' > 'regexp.c' &&
  1322. X/*
  1323. X * regcomp and regexec -- regsub and regerror are elsewhere
  1324. X *
  1325. X *    Copyright (c) 1986 by University of Toronto.
  1326. X *    Written by Henry Spencer.  Not derived from licensed software.
  1327. X *
  1328. X *    Permission is granted to anyone to use this software for any
  1329. X *    purpose on any computer system, and to redistribute it freely,
  1330. X *    subject to the following restrictions:
  1331. X *
  1332. X *    1. The author is not responsible for the consequences of use of
  1333. X *        this software, no matter how awful, even if they arise
  1334. X *        from defects in it.
  1335. X *
  1336. X *    2. The origin of this software must not be misrepresented, either
  1337. X *        by explicit claim or by omission.
  1338. X *
  1339. X *    3. Altered versions must be plainly marked as such, and must not
  1340. X *        be misrepresented as being the original software.
  1341. X *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
  1342. X *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
  1343. X *** to assist in implementing egrep.
  1344. X *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
  1345. X *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
  1346. X *** as in BSD grep and ex.
  1347. X *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
  1348. X *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
  1349. X *** THIS IS AN ALTERED VERSION.  It was altered by James A. Woods,
  1350. X *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
  1351. X *** THIS IS AN ALTERED VERSION.  It was altered by Christopher Seiwald
  1352. X *** seiwald@vix.com, on 28 August 1993, for use in jam.  Regmagic.h
  1353. X *** was moved into regexp.h, and the include of regexp.h now uses "'s
  1354. X *** to avoid conflicting with the system regexp.h.  Const, bless its
  1355. X *** soul, was removed so it can compile everywhere.  The declaration
  1356. X *** of strchr() was in conflict on AIX, so it was removed (as it is
  1357. X *** happily defined in string.h).
  1358. X *
  1359. X * Beware that some of this code is subtly aware of the way operator
  1360. X * precedence is structured in regular expressions.  Serious changes in
  1361. X * regular-expression syntax might require a total rethink.
  1362. X */
  1363. X#include "regexp.h"
  1364. X#include <stdio.h>
  1365. X#include <ctype.h>
  1366. X#ifndef ultrix
  1367. X#include <stdlib.h>
  1368. X#endif
  1369. X#include <string.h>
  1370. X
  1371. X/*
  1372. X * The "internal use only" fields in regexp.h are present to pass info from
  1373. X * compile to execute that permits the execute phase to run lots faster on
  1374. X * simple cases.  They are:
  1375. X *
  1376. X * regstart    char that must begin a match; '\0' if none obvious
  1377. X * reganch    is the match anchored (at beginning-of-line only)?
  1378. X * regmust    string (pointer into program) that match must include, or NULL
  1379. X * regmlen    length of regmust string
  1380. X *
  1381. X * Regstart and reganch permit very fast decisions on suitable starting points
  1382. X * for a match, cutting down the work a lot.  Regmust permits fast rejection
  1383. X * of lines that cannot possibly match.  The regmust tests are costly enough
  1384. X * that regcomp() supplies a regmust only if the r.e. contains something
  1385. X * potentially expensive (at present, the only such thing detected is * or +
  1386. X * at the start of the r.e., which can involve a lot of backup).  Regmlen is
  1387. X * supplied because the test in regexec() needs it and regcomp() is computing
  1388. X * it anyway.
  1389. X */
  1390. X
  1391. X/*
  1392. X * Structure for regexp "program".  This is essentially a linear encoding
  1393. X * of a nondeterministic finite-state machine (aka syntax charts or
  1394. X * "railroad normal form" in parsing technology).  Each node is an opcode
  1395. X * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
  1396. X * all nodes except BRANCH implement concatenation; a "next" pointer with
  1397. X * a BRANCH on both ends of it is connecting two alternatives.  (Here we
  1398. X * have one of the subtle syntax dependencies:  an individual BRANCH (as
  1399. X * opposed to a collection of them) is never concatenated with anything
  1400. X * because of operator precedence.)  The operand of some types of node is
  1401. X * a literal string; for others, it is a node leading into a sub-FSM.  In
  1402. X * particular, the operand of a BRANCH node is the first node of the branch.
  1403. X * (NB this is *not* a tree structure:  the tail of the branch connects
  1404. X * to the thing following the set of BRANCHes.)  The opcodes are:
  1405. X */
  1406. X
  1407. X/* definition    number    opnd?    meaning */
  1408. X#define    END    0    /* no    End of program. */
  1409. X#define    BOL    1    /* no    Match "" at beginning of line. */
  1410. X#define    EOL    2    /* no    Match "" at end of line. */
  1411. X#define    ANY    3    /* no    Match any one character. */
  1412. X#define    ANYOF    4    /* str    Match any character in this string. */
  1413. X#define    ANYBUT    5    /* str    Match any character not in this string. */
  1414. X#define    BRANCH    6    /* node    Match this alternative, or the next... */
  1415. X#define    BACK    7    /* no    Match "", "next" ptr points backward. */
  1416. X#define    EXACTLY    8    /* str    Match this string. */
  1417. X#define    NOTHING    9    /* no    Match empty string. */
  1418. X#define    STAR    10    /* node    Match this (simple) thing 0 or more times. */
  1419. X#define    PLUS    11    /* node    Match this (simple) thing 1 or more times. */
  1420. X#define    WORDA    12    /* no    Match "" at wordchar, where prev is nonword */
  1421. X#define    WORDZ    13    /* no    Match "" at nonwordchar, where prev is word */
  1422. X#define    OPEN    20    /* no    Mark this point in input as start of #n. */
  1423. X            /*    OPEN+1 is number 1, etc. */
  1424. X#define    CLOSE    30    /* no    Analogous to OPEN. */
  1425. X
  1426. X/*
  1427. X * Opcode notes:
  1428. X *
  1429. X * BRANCH    The set of branches constituting a single choice are hooked
  1430. X *        together with their "next" pointers, since precedence prevents
  1431. X *        anything being concatenated to any individual branch.  The
  1432. X *        "next" pointer of the last BRANCH in a choice points to the
  1433. X *        thing following the whole choice.  This is also where the
  1434. X *        final "next" pointer of each individual branch points; each
  1435. X *        branch starts with the operand node of a BRANCH node.
  1436. X *
  1437. X * BACK        Normal "next" pointers all implicitly point forward; BACK
  1438. X *        exists to make loop structures possible.
  1439. X *
  1440. X * STAR,PLUS    '?', and complex '*' and '+', are implemented as circular
  1441. X *        BRANCH structures using BACK.  Simple cases (one character
  1442. X *        per match) are implemented with STAR and PLUS for speed
  1443. X *        and to minimize recursive plunges.
  1444. X *
  1445. X * OPEN,CLOSE    ...are numbered at compile time.
  1446. X */
  1447. X
  1448. X/*
  1449. X * A node is one char of opcode followed by two chars of "next" pointer.
  1450. X * "Next" pointers are stored as two 8-bit pieces, high order first.  The
  1451. X * value is a positive offset from the opcode of the node containing it.
  1452. X * An operand, if any, simply follows the node.  (Note that much of the
  1453. X * code generation knows about this implicit relationship.)
  1454. X *
  1455. X * Using two bytes for the "next" pointer is vast overkill for most things,
  1456. X * but allows patterns to get big without disasters.
  1457. X */
  1458. X#define    OP(p)    (*(p))
  1459. X#define    NEXT(p)    (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
  1460. X#define    OPERAND(p)    ((p) + 3)
  1461. X
  1462. X/*
  1463. X * See regmagic.h for one further detail of program structure.
  1464. X */
  1465. X
  1466. X
  1467. X/*
  1468. X * Utility definitions.
  1469. X */
  1470. X#ifndef CHARBITS
  1471. X#define    UCHARAT(p)    ((int)*(unsigned char *)(p))
  1472. X#else
  1473. X#define    UCHARAT(p)    ((int)*(p)&CHARBITS)
  1474. X#endif
  1475. X
  1476. X#define    FAIL(m)    { regerror(m); return(NULL); }
  1477. X#define    ISMULT(c)    ((c) == '*' || (c) == '+' || (c) == '?')
  1478. X
  1479. X/*
  1480. X * Flags to be passed up and down.
  1481. X */
  1482. X#define    HASWIDTH    01    /* Known never to match null string. */
  1483. X#define    SIMPLE        02    /* Simple enough to be STAR/PLUS operand. */
  1484. X#define    SPSTART        04    /* Starts with * or +. */
  1485. X#define    WORST        0    /* Worst case. */
  1486. X
  1487. X/*
  1488. X * Global work variables for regcomp().
  1489. X */
  1490. Xstatic char *regparse;        /* Input-scan pointer. */
  1491. Xstatic int regnpar;        /* () count. */
  1492. Xstatic char regdummy;
  1493. Xstatic char *regcode;        /* Code-emit pointer; ®dummy = don't. */
  1494. Xstatic long regsize;        /* Code size. */
  1495. X
  1496. X/*
  1497. X * Forward declarations for regcomp()'s friends.
  1498. X */
  1499. X#ifndef STATIC
  1500. X#define    STATIC    static
  1501. X#endif
  1502. XSTATIC char *reg();
  1503. XSTATIC char *regbranch();
  1504. XSTATIC char *regpiece();
  1505. XSTATIC char *regatom();
  1506. XSTATIC char *regnode();
  1507. XSTATIC char *regnext();
  1508. XSTATIC void regc();
  1509. XSTATIC void reginsert();
  1510. XSTATIC void regtail();
  1511. XSTATIC void regoptail();
  1512. X#ifdef STRCSPN
  1513. XSTATIC int strcspn();
  1514. X#endif
  1515. X
  1516. X/*
  1517. X - regcomp - compile a regular expression into internal code
  1518. X *
  1519. X * We can't allocate space until we know how big the compiled form will be,
  1520. X * but we can't compile it (and thus know how big it is) until we've got a
  1521. X * place to put the code.  So we cheat:  we compile it twice, once with code
  1522. X * generation turned off and size counting turned on, and once "for real".
  1523. X * This also means that we don't allocate space until we are sure that the
  1524. X * thing really will compile successfully, and we never have to move the
  1525. X * code and thus invalidate pointers into it.  (Note that it has to be in
  1526. X * one piece because free() must be able to free it all.)
  1527. X *
  1528. X * Beware that the optimization-preparation code in here knows about some
  1529. X * of the structure of the compiled regexp.
  1530. X */
  1531. Xregexp *
  1532. Xregcomp(exp)
  1533. Xchar *exp;
  1534. X{
  1535. X    register regexp *r;
  1536. X    register char *scan;
  1537. X    register char *longest;
  1538. X    register int len;
  1539. X    int flags;
  1540. X
  1541. X    if (exp == NULL)
  1542. X        FAIL("NULL argument");
  1543. X
  1544. X    /* First pass: determine size, legality. */
  1545. X#ifdef notdef
  1546. X    if (exp[0] == '.' && exp[1] == '*') exp += 2;  /* aid grep */
  1547. X#endif
  1548. X    regparse = (char *)exp;
  1549. X    regnpar = 1;
  1550. X    regsize = 0L;
  1551. X    regcode = ®dummy;
  1552. X    regc(MAGIC);
  1553. X    if (reg(0, &flags) == NULL)
  1554. X        return(NULL);
  1555. X
  1556. X    /* Small enough for pointer-storage convention? */
  1557. X    if (regsize >= 32767L)        /* Probably could be 65535L. */
  1558. X        FAIL("regexp too big");
  1559. X
  1560. X    /* Allocate space. */
  1561. X    r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
  1562. X    if (r == NULL)
  1563. X        FAIL("out of space");
  1564. X
  1565. X    /* Second pass: emit code. */
  1566. X    regparse = (char *)exp;
  1567. X    regnpar = 1;
  1568. X    regcode = r->program;
  1569. X    regc(MAGIC);
  1570. X    if (reg(0, &flags) == NULL)
  1571. X        return(NULL);
  1572. X
  1573. X    /* Dig out information for optimizations. */
  1574. X    r->regstart = '\0';    /* Worst-case defaults. */
  1575. X    r->reganch = 0;
  1576. X    r->regmust = NULL;
  1577. X    r->regmlen = 0;
  1578. X    scan = r->program+1;            /* First BRANCH. */
  1579. X    if (OP(regnext(scan)) == END) {        /* Only one top-level choice. */
  1580. X        scan = OPERAND(scan);
  1581. X
  1582. X        /* Starting-point info. */
  1583. X        if (OP(scan) == EXACTLY)
  1584. X            r->regstart = *OPERAND(scan);
  1585. X        else if (OP(scan) == BOL)
  1586. X            r->reganch++;
  1587. X
  1588. X        /*
  1589. X         * If there's something expensive in the r.e., find the
  1590. X         * longest literal string that must appear and make it the
  1591. X         * regmust.  Resolve ties in favor of later strings, since
  1592. X         * the regstart check works with the beginning of the r.e.
  1593. X         * and avoiding duplication strengthens checking.  Not a
  1594. X         * strong reason, but sufficient in the absence of others.
  1595. X         */
  1596. X        if (flags&SPSTART) {
  1597. X            longest = NULL;
  1598. X            len = 0;
  1599. X            for (; scan != NULL; scan = regnext(scan))
  1600. X                if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
  1601. X                    longest = OPERAND(scan);
  1602. X                    len = strlen(OPERAND(scan));
  1603. X                }
  1604. X            r->regmust = longest;
  1605. X            r->regmlen = len;
  1606. X        }
  1607. X    }
  1608. X
  1609. X    return(r);
  1610. X}
  1611. X
  1612. X/*
  1613. X - reg - regular expression, i.e. main body or parenthesized thing
  1614. X *
  1615. X * Caller must absorb opening parenthesis.
  1616. X *
  1617. X * Combining parenthesis handling with the base level of regular expression
  1618. X * is a trifle forced, but the need to tie the tails of the branches to what
  1619. X * follows makes it hard to avoid.
  1620. X */
  1621. Xstatic char *
  1622. Xreg(paren, flagp)
  1623. Xint paren;            /* Parenthesized? */
  1624. Xint *flagp;
  1625. X{
  1626. X    register char *ret;
  1627. X    register char *br;
  1628. X    register char *ender;
  1629. X    register int parno;
  1630. X    int flags;
  1631. X
  1632. X    *flagp = HASWIDTH;    /* Tentatively. */
  1633. X
  1634. X    /* Make an OPEN node, if parenthesized. */
  1635. X    if (paren) {
  1636. X        if (regnpar >= NSUBEXP)
  1637. X            FAIL("too many ()");
  1638. X        parno = regnpar;
  1639. X        regnpar++;
  1640. X        ret = regnode(OPEN+parno);
  1641. X    } else
  1642. X        ret = NULL;
  1643. X
  1644. X    /* Pick up the branches, linking them together. */
  1645. X    br = regbranch(&flags);
  1646. X    if (br == NULL)
  1647. X        return(NULL);
  1648. X    if (ret != NULL)
  1649. X        regtail(ret, br);    /* OPEN -> first. */
  1650. X    else
  1651. X        ret = br;
  1652. X    if (!(flags&HASWIDTH))
  1653. X        *flagp &= ~HASWIDTH;
  1654. X    *flagp |= flags&SPSTART;
  1655. X    while (*regparse == '|' || *regparse == '\n') {
  1656. X        regparse++;
  1657. X        br = regbranch(&flags);
  1658. X        if (br == NULL)
  1659. X            return(NULL);
  1660. X        regtail(ret, br);    /* BRANCH -> BRANCH. */
  1661. X        if (!(flags&HASWIDTH))
  1662. X            *flagp &= ~HASWIDTH;
  1663. X        *flagp |= flags&SPSTART;
  1664. X    }
  1665. X
  1666. X    /* Make a closing node, and hook it on the end. */
  1667. X    ender = regnode((paren) ? CLOSE+parno : END);    
  1668. X    regtail(ret, ender);
  1669. X
  1670. X    /* Hook the tails of the branches to the closing node. */
  1671. X    for (br = ret; br != NULL; br = regnext(br))
  1672. X        regoptail(br, ender);
  1673. X
  1674. X    /* Check for proper termination. */
  1675. X    if (paren && *regparse++ != ')') {
  1676. X        FAIL("unmatched ()");
  1677. X    } else if (!paren && *regparse != '\0') {
  1678. X        if (*regparse == ')') {
  1679. X            FAIL("unmatched ()");
  1680. X        } else
  1681. X            FAIL("junk on end");    /* "Can't happen". */
  1682. X        /* NOTREACHED */
  1683. X    }
  1684. X
  1685. X    return(ret);
  1686. X}
  1687. X
  1688. X/*
  1689. X - regbranch - one alternative of an | operator
  1690. X *
  1691. X * Implements the concatenation operator.
  1692. X */
  1693. Xstatic char *
  1694. Xregbranch(flagp)
  1695. Xint *flagp;
  1696. X{
  1697. X    register char *ret;
  1698. X    register char *chain;
  1699. X    register char *latest;
  1700. X    int flags;
  1701. X
  1702. X    *flagp = WORST;        /* Tentatively. */
  1703. X
  1704. X    ret = regnode(BRANCH);
  1705. X    chain = NULL;
  1706. X    while (*regparse != '\0' && *regparse != ')' &&
  1707. X           *regparse != '\n' && *regparse != '|') {
  1708. X        latest = regpiece(&flags);
  1709. X        if (latest == NULL)
  1710. X            return(NULL);
  1711. X        *flagp |= flags&HASWIDTH;
  1712. X        if (chain == NULL)    /* First piece. */
  1713. X            *flagp |= flags&SPSTART;
  1714. X        else
  1715. X            regtail(chain, latest);
  1716. X        chain = latest;
  1717. X    }
  1718. X    if (chain == NULL)    /* Loop ran zero times. */
  1719. X        (void) regnode(NOTHING);
  1720. X
  1721. X    return(ret);
  1722. X}
  1723. X
  1724. X/*
  1725. X - regpiece - something followed by possible [*+?]
  1726. X *
  1727. X * Note that the branching code sequences used for ? and the general cases
  1728. X * of * and + are somewhat optimized:  they use the same NOTHING node as
  1729. X * both the endmarker for their branch list and the body of the last branch.
  1730. X * It might seem that this node could be dispensed with entirely, but the
  1731. X * endmarker role is not redundant.
  1732. X */
  1733. Xstatic char *
  1734. Xregpiece(flagp)
  1735. Xint *flagp;
  1736. X{
  1737. X    register char *ret;
  1738. X    register char op;
  1739. X    register char *next;
  1740. X    int flags;
  1741. X
  1742. X    ret = regatom(&flags);
  1743. X    if (ret == NULL)
  1744. X        return(NULL);
  1745. X
  1746. X    op = *regparse;
  1747. X    if (!ISMULT(op)) {
  1748. X        *flagp = flags;
  1749. X        return(ret);
  1750. X    }
  1751. X
  1752. X    if (!(flags&HASWIDTH) && op != '?')
  1753. X        FAIL("*+ operand could be empty");
  1754. X    *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
  1755. X
  1756. X    if (op == '*' && (flags&SIMPLE))
  1757. X        reginsert(STAR, ret);
  1758. X    else if (op == '*') {
  1759. X        /* Emit x* as (x&|), where & means "self". */
  1760. X        reginsert(BRANCH, ret);            /* Either x */
  1761. X        regoptail(ret, regnode(BACK));        /* and loop */
  1762. X        regoptail(ret, ret);            /* back */
  1763. X        regtail(ret, regnode(BRANCH));        /* or */
  1764. X        regtail(ret, regnode(NOTHING));        /* null. */
  1765. X    } else if (op == '+' && (flags&SIMPLE))
  1766. X        reginsert(PLUS, ret);
  1767. X    else if (op == '+') {
  1768. X        /* Emit x+ as x(&|), where & means "self". */
  1769. X        next = regnode(BRANCH);            /* Either */
  1770. X        regtail(ret, next);
  1771. X        regtail(regnode(BACK), ret);        /* loop back */
  1772. X        regtail(next, regnode(BRANCH));        /* or */
  1773. X        regtail(ret, regnode(NOTHING));        /* null. */
  1774. X    } else if (op == '?') {
  1775. X        /* Emit x? as (x|) */
  1776. X        reginsert(BRANCH, ret);            /* Either x */
  1777. X        regtail(ret, regnode(BRANCH));        /* or */
  1778. X        next = regnode(NOTHING);        /* null. */
  1779. X        regtail(ret, next);
  1780. X        regoptail(ret, next);
  1781. X    }
  1782. X    regparse++;
  1783. X    if (ISMULT(*regparse))
  1784. X        FAIL("nested *?+");
  1785. X
  1786. X    return(ret);
  1787. X}
  1788. X
  1789. X/*
  1790. X - regatom - the lowest level
  1791. X *
  1792. X * Optimization:  gobbles an entire sequence of ordinary characters so that
  1793. X * it can turn them into a single node, which is smaller to store and
  1794. X * faster to run.  Backslashed characters are exceptions, each becoming a
  1795. X * separate node; the code is simpler that way and it's not worth fixing.
  1796. X */
  1797. Xstatic char *
  1798. Xregatom(flagp)
  1799. Xint *flagp;
  1800. X{
  1801. X    register char *ret;
  1802. X    int flags;
  1803. X
  1804. X    *flagp = WORST;        /* Tentatively. */
  1805. X
  1806. X    switch (*regparse++) {
  1807. X    /* FIXME: these chars only have meaning at beg/end of pat? */
  1808. X    case '^':
  1809. X        ret = regnode(BOL);
  1810. X        break;
  1811. X    case '$':
  1812. X        ret = regnode(EOL);
  1813. X        break;
  1814. X    case '.':
  1815. X        ret = regnode(ANY);
  1816. X        *flagp |= HASWIDTH|SIMPLE;
  1817. X        break;
  1818. X    case '[': {
  1819. X            register int class;
  1820. X            register int classend;
  1821. X
  1822. X            if (*regparse == '^') {    /* Complement of range. */
  1823. X                ret = regnode(ANYBUT);
  1824. X                regparse++;
  1825. X            } else
  1826. X                ret = regnode(ANYOF);
  1827. X            if (*regparse == ']' || *regparse == '-')
  1828. X                regc(*regparse++);
  1829. X            while (*regparse != '\0' && *regparse != ']') {
  1830. X                if (*regparse == '-') {
  1831. X                    regparse++;
  1832. X                    if (*regparse == ']' || *regparse == '\0')
  1833. X                        regc('-');
  1834. X                    else {
  1835. X                        class = UCHARAT(regparse-2)+1;
  1836. X                        classend = UCHARAT(regparse);
  1837. X                        if (class > classend+1)
  1838. X                            FAIL("invalid [] range");
  1839. X                        for (; class <= classend; class++)
  1840. X                            regc(class);
  1841. X                        regparse++;
  1842. X                    }
  1843. X                } else
  1844. X                    regc(*regparse++);
  1845. X            }
  1846. X            regc('\0');
  1847. X            if (*regparse != ']')
  1848. X                FAIL("unmatched []");
  1849. X            regparse++;
  1850. X            *flagp |= HASWIDTH|SIMPLE;
  1851. X        }
  1852. X        break;
  1853. X    case '(':
  1854. X        ret = reg(1, &flags);
  1855. X        if (ret == NULL)
  1856. X            return(NULL);
  1857. X        *flagp |= flags&(HASWIDTH|SPSTART);
  1858. X        break;
  1859. X    case '\0':
  1860. X    case '|':
  1861. X    case '\n':
  1862. X    case ')':
  1863. X        FAIL("internal urp");    /* Supposed to be caught earlier. */
  1864. X        break;
  1865. X    case '?':
  1866. X    case '+':
  1867. X    case '*':
  1868. X        FAIL("?+* follows nothing");
  1869. X        break;
  1870. X    case '\\':
  1871. X        switch (*regparse++) {
  1872. X        case '\0':
  1873. X            FAIL("trailing \\");
  1874. X            break;
  1875. X        case '<':
  1876. X            ret = regnode(WORDA);
  1877. X            break;
  1878. X        case '>':
  1879. X            ret = regnode(WORDZ);
  1880. X            break;
  1881. X        /* FIXME: Someday handle \1, \2, ... */
  1882. X        default:
  1883. X            /* Handle general quoted chars in exact-match routine */
  1884. X            goto de_fault;
  1885. X        }
  1886. X        break;
  1887. X    de_fault:
  1888. X    default:
  1889. X        /*
  1890. X         * Encode a string of characters to be matched exactly.
  1891. X         *
  1892. X         * This is a bit tricky due to quoted chars and due to
  1893. X         * '*', '+', and '?' taking the SINGLE char previous
  1894. X         * as their operand.
  1895. X         *
  1896. X         * On entry, the char at regparse[-1] is going to go
  1897. X         * into the string, no matter what it is.  (It could be
  1898. X         * following a \ if we are entered from the '\' case.)
  1899. X         * 
  1900. X         * Basic idea is to pick up a good char in  ch  and
  1901. X         * examine the next char.  If it's *+? then we twiddle.
  1902. X         * If it's \ then we frozzle.  If it's other magic char
  1903. X         * we push  ch  and terminate the string.  If none of the
  1904. X         * above, we push  ch  on the string and go around again.
  1905. X         *
  1906. X         *  regprev  is used to remember where "the current char"
  1907. X         * starts in the string, if due to a *+? we need to back
  1908. X         * up and put the current char in a separate, 1-char, string.
  1909. X         * When  regprev  is NULL,  ch  is the only char in the
  1910. X         * string; this is used in *+? handling, and in setting
  1911. X         * flags |= SIMPLE at the end.
  1912. X         */
  1913. X        {
  1914. X            char *regprev;
  1915. X            register char ch;
  1916. X
  1917. X            regparse--;            /* Look at cur char */
  1918. X            ret = regnode(EXACTLY);
  1919. X            for ( regprev = 0 ; ; ) {
  1920. X                ch = *regparse++;    /* Get current char */
  1921. X                switch (*regparse) {    /* look at next one */
  1922. X
  1923. X                default:
  1924. X                    regc(ch);    /* Add cur to string */
  1925. X                    break;
  1926. X
  1927. X                case '.': case '[': case '(':
  1928. X                case ')': case '|': case '\n':
  1929. X                case '$': case '^':
  1930. X                case '\0':
  1931. X                /* FIXME, $ and ^ should not always be magic */
  1932. X                magic:
  1933. X                    regc(ch);    /* dump cur char */
  1934. X                    goto done;    /* and we are done */
  1935. X
  1936. X                case '?': case '+': case '*':
  1937. X                    if (!regprev)     /* If just ch in str, */
  1938. X                        goto magic;    /* use it */
  1939. X                    /* End mult-char string one early */
  1940. X                    regparse = regprev; /* Back up parse */
  1941. X                    goto done;
  1942. X
  1943. X                case '\\':
  1944. X                    regc(ch);    /* Cur char OK */
  1945. X                    switch (regparse[1]){ /* Look after \ */
  1946. X                    case '\0':
  1947. X                    case '<':
  1948. X                    case '>':
  1949. X                    /* FIXME: Someday handle \1, \2, ... */
  1950. X                        goto done; /* Not quoted */
  1951. X                    default:
  1952. X                        /* Backup point is \, scan                             * point is after it. */
  1953. X                        regprev = regparse;
  1954. X                        regparse++; 
  1955. X                        continue;    /* NOT break; */
  1956. X                    }
  1957. X                }
  1958. X                regprev = regparse;    /* Set backup point */
  1959. X            }
  1960. X        done:
  1961. X            regc('\0');
  1962. X            *flagp |= HASWIDTH;
  1963. X            if (!regprev)        /* One char? */
  1964. X                *flagp |= SIMPLE;
  1965. X        }
  1966. X        break;
  1967. X    }
  1968. X
  1969. X    return(ret);
  1970. X}
  1971. X
  1972. X/*
  1973. X - regnode - emit a node
  1974. X */
  1975. Xstatic char *            /* Location. */
  1976. Xregnode(op)
  1977. Xchar op;
  1978. X{
  1979. X    register char *ret;
  1980. X    register char *ptr;
  1981. X
  1982. X    ret = regcode;
  1983. X    if (ret == ®dummy) {
  1984. X        regsize += 3;
  1985. X        return(ret);
  1986. X    }
  1987. X
  1988. X    ptr = ret;
  1989. X    *ptr++ = op;
  1990. X    *ptr++ = '\0';        /* Null "next" pointer. */
  1991. X    *ptr++ = '\0';
  1992. X    regcode = ptr;
  1993. X
  1994. X    return(ret);
  1995. X}
  1996. X
  1997. X/*
  1998. X - regc - emit (if appropriate) a byte of code
  1999. X */
  2000. Xstatic void
  2001. Xregc(b)
  2002. Xchar b;
  2003. X{
  2004. X    if (regcode != ®dummy)
  2005. X        *regcode++ = b;
  2006. X    else
  2007. X        regsize++;
  2008. X}
  2009. X
  2010. X/*
  2011. X - reginsert - insert an operator in front of already-emitted operand
  2012. X *
  2013. X * Means relocating the operand.
  2014. X */
  2015. Xstatic void
  2016. Xreginsert(op, opnd)
  2017. Xchar op;
  2018. Xchar *opnd;
  2019. X{
  2020. X    register char *src;
  2021. X    register char *dst;
  2022. X    register char *place;
  2023. X
  2024. X    if (regcode == ®dummy) {
  2025. X        regsize += 3;
  2026. X        return;
  2027. X    }
  2028. X
  2029. X    src = regcode;
  2030. X    regcode += 3;
  2031. X    dst = regcode;
  2032. X    while (src > opnd)
  2033. X        *--dst = *--src;
  2034. X
  2035. X    place = opnd;        /* Op node, where operand used to be. */
  2036. X    *place++ = op;
  2037. X    *place++ = '\0';
  2038. X    *place++ = '\0';
  2039. X}
  2040. X
  2041. X/*
  2042. X - regtail - set the next-pointer at the end of a node chain
  2043. X */
  2044. Xstatic void
  2045. Xregtail(p, val)
  2046. Xchar *p;
  2047. Xchar *val;
  2048. X{
  2049. X    register char *scan;
  2050. X    register char *temp;
  2051. X    register int offset;
  2052. X
  2053. X    if (p == ®dummy)
  2054. X        return;
  2055. X
  2056. X    /* Find last node. */
  2057. X    scan = p;
  2058. X    for (;;) {
  2059. X        temp = regnext(scan);
  2060. X        if (temp == NULL)
  2061. X            break;
  2062. X        scan = temp;
  2063. X    }
  2064. X
  2065. X    if (OP(scan) == BACK)
  2066. X        offset = scan - val;
  2067. X    else
  2068. X        offset = val - scan;
  2069. X    *(scan+1) = (offset>>8)&0377;
  2070. X    *(scan+2) = offset&0377;
  2071. X}
  2072. X
  2073. X/*
  2074. X - regoptail - regtail on operand of first argument; nop if operandless
  2075. X */
  2076. Xstatic void
  2077. Xregoptail(p, val)
  2078. Xchar *p;
  2079. Xchar *val;
  2080. X{
  2081. X    /* "Operandless" and "op != BRANCH" are synonymous in practice. */
  2082. X    if (p == NULL || p == ®dummy || OP(p) != BRANCH)
  2083. X        return;
  2084. X    regtail(OPERAND(p), val);
  2085. X}
  2086. X
  2087. X/*
  2088. X * regexec and friends
  2089. X */
  2090. X
  2091. X/*
  2092. X * Global work variables for regexec().
  2093. X */
  2094. Xstatic char *reginput;        /* String-input pointer. */
  2095. Xstatic char *regbol;        /* Beginning of input, for ^ check. */
  2096. Xstatic char **regstartp;    /* Pointer to startp array. */
  2097. Xstatic char **regendp;        /* Ditto for endp. */
  2098. X
  2099. X/*
  2100. X * Forwards.
  2101. X */
  2102. XSTATIC int regtry();
  2103. XSTATIC int regmatch();
  2104. XSTATIC int regrepeat();
  2105. X
  2106. X#ifdef DEBUG
  2107. Xint regnarrate = 0;
  2108. Xvoid regdump();
  2109. XSTATIC char *regprop();
  2110. X#endif
  2111. X
  2112. X/*
  2113. X - regexec - match a regexp against a string
  2114. X */
  2115. Xint
  2116. Xregexec(prog, string)
  2117. Xregister regexp *prog;
  2118. Xregister char *string;
  2119. X{
  2120. X    register char *s;
  2121. X
  2122. X    /* Be paranoid... */
  2123. X    if (prog == NULL || string == NULL) {
  2124. X        regerror("NULL parameter");
  2125. X        return(0);
  2126. X    }
  2127. X
  2128. X    /* Check validity of program. */
  2129. X    if (UCHARAT(prog->program) != MAGIC) {
  2130. X        regerror("corrupted program");
  2131. X        return(0);
  2132. X    }
  2133. X
  2134. X    /* If there is a "must appear" string, look for it. */
  2135. X    if (prog->regmust != NULL) {
  2136. X        s = (char *)string;
  2137. X        while ((s = strchr(s, prog->regmust[0])) != NULL) {
  2138. X            if (strncmp(s, prog->regmust, prog->regmlen) == 0)
  2139. X                break;    /* Found it. */
  2140. X            s++;
  2141. X        }
  2142. X        if (s == NULL)    /* Not present. */
  2143. X            return(0);
  2144. X    }
  2145. X
  2146. X    /* Mark beginning of line for ^ . */
  2147. X    regbol = (char *)string;
  2148. X
  2149. X    /* Simplest case:  anchored match need be tried only once. */
  2150. X    if (prog->reganch)
  2151. X        return(regtry(prog, string));
  2152. X
  2153. X    /* Messy cases:  unanchored match. */
  2154. X    s = (char *)string;
  2155. X    if (prog->regstart != '\0')
  2156. X        /* We know what char it must start with. */
  2157. X        while ((s = strchr(s, prog->regstart)) != NULL) {
  2158. X            if (regtry(prog, s))
  2159. X                return(1);
  2160. X            s++;
  2161. X        }
  2162. X    else
  2163. X        /* We don't -- general case. */
  2164. X        do {
  2165. X            if (regtry(prog, s))
  2166. X                return(1);
  2167. X        } while (*s++ != '\0');
  2168. X
  2169. X    /* Failure. */
  2170. X    return(0);
  2171. X}
  2172. X
  2173. X/*
  2174. X - regtry - try match at specific point
  2175. X */
  2176. Xstatic int            /* 0 failure, 1 success */
  2177. Xregtry(prog, string)
  2178. Xregexp *prog;
  2179. Xchar *string;
  2180. X{
  2181. X    register int i;
  2182. X    register char **sp;
  2183. X    register char **ep;
  2184. X
  2185. X    reginput = string;
  2186. X    regstartp = prog->startp;
  2187. X    regendp = prog->endp;
  2188. X
  2189. X    sp = prog->startp;
  2190. X    ep = prog->endp;
  2191. X    for (i = NSUBEXP; i > 0; i--) {
  2192. X        *sp++ = NULL;
  2193. X        *ep++ = NULL;
  2194. X    }
  2195. X    if (regmatch(prog->program + 1)) {
  2196. X        prog->startp[0] = string;
  2197. X        prog->endp[0] = reginput;
  2198. X        return(1);
  2199. X    } else
  2200. X        return(0);
  2201. X}
  2202. X
  2203. X/*
  2204. X - regmatch - main matching routine
  2205. X *
  2206. X * Conceptually the strategy is simple:  check to see whether the current
  2207. X * node matches, call self recursively to see whether the rest matches,
  2208. X * and then act accordingly.  In practice we make some effort to avoid
  2209. X * recursion, in particular by going through "ordinary" nodes (that don't
  2210. X * need to know whether the rest of the match failed) by a loop instead of
  2211. X * by recursion.
  2212. X */
  2213. Xstatic int            /* 0 failure, 1 success */
  2214. Xregmatch(prog)
  2215. Xchar *prog;
  2216. X{
  2217. X    register char *scan;    /* Current node. */
  2218. X    char *next;        /* Next node. */
  2219. X
  2220. X    scan = prog;
  2221. X#ifdef DEBUG
  2222. X    if (scan != NULL && regnarrate)
  2223. X        fprintf(stderr, "%s(\n", regprop(scan));
  2224. X#endif
  2225. X    while (scan != NULL) {
  2226. X#ifdef DEBUG
  2227. X        if (regnarrate)
  2228. X            fprintf(stderr, "%s...\n", regprop(scan));
  2229. X#endif
  2230. X        next = regnext(scan);
  2231. X
  2232. X        switch (OP(scan)) {
  2233. X        case BOL:
  2234. X            if (reginput != regbol)
  2235. X                return(0);
  2236. X            break;
  2237. X        case EOL:
  2238. X            if (*reginput != '\0')
  2239. X                return(0);
  2240. X            break;
  2241. X        case WORDA:
  2242. X            /* Must be looking at a letter, digit, or _ */
  2243. X            if ((!isalnum(*reginput)) && *reginput != '_')
  2244. X                return(0);
  2245. X            /* Prev must be BOL or nonword */
  2246. X            if (reginput > regbol &&
  2247. X                (isalnum(reginput[-1]) || reginput[-1] == '_'))
  2248. X                return(0);
  2249. X            break;
  2250. X        case WORDZ:
  2251. X            /* Must be looking at non letter, digit, or _ */
  2252. X            if (isalnum(*reginput) || *reginput == '_')
  2253. X                return(0);
  2254. X            /* We don't care what the previous char was */
  2255. X            break;
  2256. X        case ANY:
  2257. X            if (*reginput == '\0')
  2258. X                return(0);
  2259. X            reginput++;
  2260. X            break;
  2261. X        case EXACTLY: {
  2262. X                register int len;
  2263. X                register char *opnd;
  2264. X
  2265. X                opnd = OPERAND(scan);
  2266. X                /* Inline the first character, for speed. */
  2267. X                if (*opnd != *reginput)
  2268. X                    return(0);
  2269. X                len = strlen(opnd);
  2270. X                if (len > 1 && strncmp(opnd, reginput, len) != 0)
  2271. X                    return(0);
  2272. X                reginput += len;
  2273. X            }
  2274. X            break;
  2275. X        case ANYOF:
  2276. X             if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
  2277. X                return(0);
  2278. X            reginput++;
  2279. X            break;
  2280. X        case ANYBUT:
  2281. X             if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
  2282. X                return(0);
  2283. X            reginput++;
  2284. X            break;
  2285. X        case NOTHING:
  2286. X            break;
  2287. X        case BACK:
  2288. X            break;
  2289. X        case OPEN+1:
  2290. X        case OPEN+2:
  2291. X        case OPEN+3:
  2292. X        case OPEN+4:
  2293. X        case OPEN+5:
  2294. X        case OPEN+6:
  2295. X        case OPEN+7:
  2296. X        case OPEN+8:
  2297. X        case OPEN+9: {
  2298. X                register int no;
  2299. X                register char *save;
  2300. X
  2301. X                no = OP(scan) - OPEN;
  2302. X                save = reginput;
  2303. X
  2304. X                if (regmatch(next)) {
  2305. X                    /*
  2306. X                     * Don't set startp if some later
  2307. X                     * invocation of the same parentheses
  2308. X                     * already has.
  2309. X                     */
  2310. X                    if (regstartp[no] == NULL)
  2311. X                        regstartp[no] = save;
  2312. X                    return(1);
  2313. X                } else
  2314. X                    return(0);
  2315. X            }
  2316. X            break;
  2317. X        case CLOSE+1:
  2318. X        case CLOSE+2:
  2319. X        case CLOSE+3:
  2320. X        case CLOSE+4:
  2321. X        case CLOSE+5:
  2322. X        case CLOSE+6:
  2323. X        case CLOSE+7:
  2324. X        case CLOSE+8:
  2325. X        case CLOSE+9: {
  2326. X                register int no;
  2327. X                register char *save;
  2328. X
  2329. X                no = OP(scan) - CLOSE;
  2330. X                save = reginput;
  2331. X
  2332. X                if (regmatch(next)) {
  2333. X                    /*
  2334. X                     * Don't set endp if some later
  2335. X                     * invocation of the same parentheses
  2336. X                     * already has.
  2337. X                     */
  2338. X                    if (regendp[no] == NULL)
  2339. X                        regendp[no] = save;
  2340. X                    return(1);
  2341. X                } else
  2342. X                    return(0);
  2343. X            }
  2344. X            break;
  2345. X        case BRANCH: {
  2346. X                register char *save;
  2347. X
  2348. X                if (OP(next) != BRANCH)        /* No choice. */
  2349. X                    next = OPERAND(scan);    /* Avoid recursion. */
  2350. X                else {
  2351. X                    do {
  2352. X                        save = reginput;
  2353. X                        if (regmatch(OPERAND(scan)))
  2354. X                            return(1);
  2355. X                        reginput = save;
  2356. X                        scan = regnext(scan);
  2357. X                    } while (scan != NULL && OP(scan) == BRANCH);
  2358. X                    return(0);
  2359. X                    /* NOTREACHED */
  2360. X                }
  2361. X            }
  2362. X            break;
  2363. X        case STAR:
  2364. X        case PLUS: {
  2365. X                register char nextch;
  2366. X                register int no;
  2367. X                register char *save;
  2368. X                register int min;
  2369. X
  2370. X                /*
  2371. X                 * Lookahead to avoid useless match attempts
  2372. X                 * when we know what character comes next.
  2373. X                 */
  2374. X                nextch = '\0';
  2375. X                if (OP(next) == EXACTLY)
  2376. X                    nextch = *OPERAND(next);
  2377. X                min = (OP(scan) == STAR) ? 0 : 1;
  2378. X                save = reginput;
  2379. X                no = regrepeat(OPERAND(scan));
  2380. X                while (no >= min) {
  2381. X                    /* If it could work, try it. */
  2382. X                    if (nextch == '\0' || *reginput == nextch)
  2383. X                        if (regmatch(next))
  2384. X                            return(1);
  2385. X                    /* Couldn't or didn't -- back up. */
  2386. X                    no--;
  2387. X                    reginput = save + no;
  2388. X                }
  2389. X                return(0);
  2390. X            }
  2391. X            break;
  2392. X        case END:
  2393. X            return(1);    /* Success! */
  2394. X            break;
  2395. X        default:
  2396. X            regerror("memory corruption");
  2397. X            return(0);
  2398. X            break;
  2399. X        }
  2400. X
  2401. X        scan = next;
  2402. X    }
  2403. X
  2404. X    /*
  2405. X     * We get here only if there's trouble -- normally "case END" is
  2406. X     * the terminating point.
  2407. X     */
  2408. X    regerror("corrupted pointers");
  2409. X    return(0);
  2410. X}
  2411. X
  2412. X/*
  2413. X - regrepeat - repeatedly match something simple, report how many
  2414. X */
  2415. Xstatic int
  2416. Xregrepeat(p)
  2417. Xchar *p;
  2418. X{
  2419. X    register int count = 0;
  2420. X    register char *scan;
  2421. X    register char *opnd;
  2422. X
  2423. X    scan = reginput;
  2424. X    opnd = OPERAND(p);
  2425. X    switch (OP(p)) {
  2426. X    case ANY:
  2427. X        count = strlen(scan);
  2428. X        scan += count;
  2429. X        break;
  2430. X    case EXACTLY:
  2431. X        while (*opnd == *scan) {
  2432. X            count++;
  2433. X            scan++;
  2434. X        }
  2435. X        break;
  2436. X    case ANYOF:
  2437. X        while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
  2438. X            count++;
  2439. X            scan++;
  2440. X        }
  2441. X        break;
  2442. X    case ANYBUT:
  2443. X        while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
  2444. X            count++;
  2445. X            scan++;
  2446. X        }
  2447. X        break;
  2448. X    default:        /* Oh dear.  Called inappropriately. */
  2449. X        regerror("internal foulup");
  2450. X        count = 0;    /* Best compromise. */
  2451. X        break;
  2452. X    }
  2453. X    reginput = scan;
  2454. X
  2455. X    return(count);
  2456. X}
  2457. X
  2458. X/*
  2459. X - regnext - dig the "next" pointer out of a node
  2460. X */
  2461. Xstatic char *
  2462. Xregnext(p)
  2463. Xregister char *p;
  2464. X{
  2465. X    register int offset;
  2466. X
  2467. X    if (p == ®dummy)
  2468. X        return(NULL);
  2469. X
  2470. X    offset = NEXT(p);
  2471. X    if (offset == 0)
  2472. X        return(NULL);
  2473. X
  2474. X    if (OP(p) == BACK)
  2475. X        return(p-offset);
  2476. X    else
  2477. X        return(p+offset);
  2478. X}
  2479. X
  2480. X#ifdef DEBUG
  2481. X
  2482. XSTATIC char *regprop();
  2483. X
  2484. X/*
  2485. X - regdump - dump a regexp onto stdout in vaguely comprehensible form
  2486. X */
  2487. Xvoid
  2488. Xregdump(r)
  2489. Xregexp *r;
  2490. X{
  2491. X    register char *s;
  2492. X    register char op = EXACTLY;    /* Arbitrary non-END op. */
  2493. X    register char *next;
  2494. X
  2495. X
  2496. X    s = r->program + 1;
  2497. X    while (op != END) {    /* While that wasn't END last time... */
  2498. X        op = OP(s);
  2499. X        printf("%2d%s", s-r->program, regprop(s));    /* Where, what. */
  2500. X        next = regnext(s);
  2501. X        if (next == NULL)        /* Next ptr. */
  2502. X            printf("(0)");
  2503. X        else 
  2504. X            printf("(%d)", (s-r->program)+(next-s));
  2505. X        s += 3;
  2506. X        if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
  2507. X            /* Literal string, where present. */
  2508. X            while (*s != '\0') {
  2509. X                putchar(*s);
  2510. X                s++;
  2511. X            }
  2512. X            s++;
  2513. X        }
  2514. X        putchar('\n');
  2515. X    }
  2516. X
  2517. X    /* Header fields of interest. */
  2518. X    if (r->regstart != '\0')
  2519. X        printf("start `%c' ", r->regstart);
  2520. X    if (r->reganch)
  2521. X        printf("anchored ");
  2522. X    if (r->regmust != NULL)
  2523. X        printf("must have \"%s\"", r->regmust);
  2524. X    printf("\n");
  2525. X}
  2526. X
  2527. X/*
  2528. X - regprop - printable representation of opcode
  2529. X */
  2530. Xstatic char *
  2531. Xregprop(op)
  2532. Xchar *op;
  2533. X{
  2534. X    register char *p;
  2535. X    static char buf[50];
  2536. X
  2537. X    (void) strcpy(buf, ":");
  2538. X
  2539. X    switch (OP(op)) {
  2540. X    case BOL:
  2541. X        p = "BOL";
  2542. X        break;
  2543. X    case EOL:
  2544. X        p = "EOL";
  2545. X        break;
  2546. X    case ANY:
  2547. X        p = "ANY";
  2548. X        break;
  2549. X    case ANYOF:
  2550. X        p = "ANYOF";
  2551. X        break;
  2552. X    case ANYBUT:
  2553. X        p = "ANYBUT";
  2554. X        break;
  2555. X    case BRANCH:
  2556. X        p = "BRANCH";
  2557. X        break;
  2558. X    case EXACTLY:
  2559. X        p = "EXACTLY";
  2560. X        break;
  2561. X    case NOTHING:
  2562. X        p = "NOTHING";
  2563. X        break;
  2564. X    case BACK:
  2565. X        p = "BACK";
  2566. X        break;
  2567. X    case END:
  2568. X        p = "END";
  2569. X        break;
  2570. X    case OPEN+1:
  2571. X    case OPEN+2:
  2572. X    case OPEN+3:
  2573. X    case OPEN+4:
  2574. X    case OPEN+5:
  2575. X    case OPEN+6:
  2576. X    case OPEN+7:
  2577. X    case OPEN+8:
  2578. X    case OPEN+9:
  2579. X        sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
  2580. X        p = NULL;
  2581. X        break;
  2582. X    case CLOSE+1:
  2583. X    case CLOSE+2:
  2584. X    case CLOSE+3:
  2585. X    case CLOSE+4:
  2586. X    case CLOSE+5:
  2587. X    case CLOSE+6:
  2588. X    case CLOSE+7:
  2589. X    case CLOSE+8:
  2590. X    case CLOSE+9:
  2591. X        sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
  2592. X        p = NULL;
  2593. X        break;
  2594. X    case STAR:
  2595. X        p = "STAR";
  2596. X        break;
  2597. X    case PLUS:
  2598. X        p = "PLUS";
  2599. X        break;
  2600. X    case WORDA:
  2601. X        p = "WORDA";
  2602. X        break;
  2603. X    case WORDZ:
  2604. X        p = "WORDZ";
  2605. X        break;
  2606. X    default:
  2607. X        regerror("corrupted opcode");
  2608. X        break;
  2609. X    }
  2610. X    if (p != NULL)
  2611. X        (void) strcat(buf, p);
  2612. X    return(buf);
  2613. X}
  2614. X#endif
  2615. X
  2616. X/*
  2617. X * The following is provided for those people who do not have strcspn() in
  2618. X * their C libraries.  They should get off their butts and do something
  2619. X * about it; at least one public-domain implementation of those (highly
  2620. X * useful) string routines has been published on Usenet.
  2621. X */
  2622. X#ifdef STRCSPN
  2623. X/*
  2624. X * strcspn - find length of initial segment of s1 consisting entirely
  2625. X * of characters not from s2
  2626. X */
  2627. X
  2628. Xstatic int
  2629. Xstrcspn(s1, s2)
  2630. Xchar *s1;
  2631. Xchar *s2;
  2632. X{
  2633. X    register char *scan1;
  2634. X    register char *scan2;
  2635. X    register int count;
  2636. X
  2637. X    count = 0;
  2638. X    for (scan1 = s1; *scan1 != '\0'; scan1++) {
  2639. X        for (scan2 = s2; *scan2 != '\0';)    /* ++ moved down. */
  2640. X            if (*scan1 == *scan2++)
  2641. X                return(count);
  2642. X        count++;
  2643. X    }
  2644. X    return(count);
  2645. X}
  2646. X#endif
  2647. SHAR_EOF
  2648. chmod 0444 regexp.c ||
  2649. echo 'restore of regexp.c failed'
  2650. Wc_c="`wc -c < 'regexp.c'`"
  2651. test 31610 -eq "$Wc_c" ||
  2652.     echo 'regexp.c: original size 31610, current size' "$Wc_c"
  2653. fi
  2654. true || echo 'restore of regexp.h failed'
  2655. echo End of part 3, continue with part 4
  2656. exit 0
  2657.