home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3587 < prev    next >
Text File  |  1991-07-02  |  20KB  |  656 lines

  1. Newsgroups: alt.sources
  2. From: goer@ellis.uchicago.edu (Richard L. Goerwitz)
  3. Subject: kjv browser, part 7 of 11
  4. Message-ID: <1991Jul3.065159.28268@midway.uchicago.edu>
  5. Date: Wed, 3 Jul 1991 06:51:59 GMT
  6.  
  7. ---- Cut Here and feed the following to sh ----
  8. #!/bin/sh
  9. # this is bibleref.07 (part 7 of a multipart archive)
  10. # do not concatenate these parts, unpack them in order with /bin/sh
  11. # file iscreen.icn continued
  12. #
  13. if test ! -r _shar_seq_.tmp; then
  14.     echo 'Please unpack part 1 first!'
  15.     exit 1
  16. fi
  17. (read Scheck
  18.  if test "$Scheck" != 7; then
  19.     echo Please unpack part "$Scheck" next!
  20.     exit 1
  21.  else
  22.     exit 0
  23.  fi
  24. ) < _shar_seq_.tmp || exit 1
  25. if test ! -f _shar_wnt_.tmp; then
  26.     echo 'x - still skipping iscreen.icn'
  27. else
  28. echo 'x - continuing file iscreen.icn'
  29. sed 's/^X//' << 'SHAR_EOF' >> 'iscreen.icn' &&
  30. X#
  31. X#    Author:     Richard L. Goerwitz
  32. X#
  33. X#    Version: 1.26
  34. X#
  35. X############################################################################
  36. X#
  37. X#  This and future version of iscreen are placed in the public domain - RLG
  38. X#
  39. X############################################################################
  40. X#  
  41. X#      This file contains some rudimentary screen functions for use with
  42. X#  itlib.icn (termlib-like routines for Icon).
  43. X#
  44. X#      clear()              - clears the screen (tries several methods)
  45. X#      emphasize()          - initiates emphasized mode
  46. X#      boldface()           - initiates bold mode
  47. X#      blink()              - initiates blinking mode
  48. X#      normal()             - resets to normal mode
  49. X#      message(s)           - displays message s on 2nd-to-last line
  50. X#      underline()          - initiates underline mode
  51. X#      status_line(s,s2,p)  - draws status line s on the 3rd-to-last
  52. X#        screen line; if s is too short for the terminal, s2 is used;
  53. X#        if p is nonnull then it either centers, left-, or right-justi-
  54. X#        fies, depending on the value, "c," "l," or "r."
  55. X#      clear_emphasize()    - horrible way of clearing the screen to all-
  56. X#        emphasize mode; necessary for many terminals
  57. X#
  58. X############################################################################
  59. X#
  60. X#  Requires: UNIX
  61. X#
  62. X#  Links: itlib.icn (or your OS-specific port of itlib)
  63. X#
  64. X#  See also: boldface.icn
  65. X#
  66. X############################################################################
  67. X
  68. X
  69. Xprocedure clear()
  70. X
  71. X    # Clears the screen.  Tries several methods.
  72. X    local i
  73. X
  74. X    normal()
  75. X    if not iputs(getval("cl"))
  76. X    then iputs(igoto(getval("cm"),1,1) | getval("ho"))
  77. X    if not iputs(getval("cd"))
  78. X    then {
  79. X    every i := 1 to getval("li") do {
  80. X        iputs(igoto(getval("cm"),1,i))
  81. X        iputs(getval("ce"))
  82. X    }
  83. X    iputs(igoto(getval("cm"),1,1))
  84. X    }
  85. X    return
  86. X
  87. Xend
  88. X
  89. X
  90. X
  91. Xprocedure boldface()
  92. X    
  93. X    static bold_str, cookie_str
  94. X    initial {
  95. X    if bold_str := getval("md")
  96. X    then cookie_str := repl(getval("le"|"bc") | "\b", getval("mg"))
  97. X    else {
  98. X        # One global procedure value substituted for another.
  99. X        boldface := emphasize
  100. X        return emphasize()
  101. X    }
  102. X    }        
  103. X    normal()
  104. X    iputs(\bold_str)
  105. X    iputs(\cookie_str)
  106. X    return
  107. X
  108. Xend
  109. X
  110. X
  111. X
  112. Xprocedure blink()
  113. X    
  114. X    static blink_str, cookie_str
  115. X    initial {
  116. X    if blink_str := getval("mb")
  117. X    then cookie_str :=
  118. X         repl(getval("le"|"bc") | "\b", getval("mg"))
  119. X    else {
  120. X        # One global procedure value substituted for another.
  121. X        blink := emphasize
  122. X        return emphasize()
  123. X    }
  124. X    }        
  125. X    normal()
  126. X    iputs(\blink_str)
  127. X    iputs(\cookie_str)
  128. X    return
  129. X
  130. Xend
  131. X
  132. X
  133. X
  134. Xprocedure emphasize()
  135. X    
  136. X    static emph_str, cookie_str
  137. X    initial {
  138. X    if emph_str := getval("so")
  139. X    then cookie_str := repl(getval("le"|"bc") | "\b", getval("sg"))
  140. X    else {
  141. X        if emph_str := getval("us")
  142. X        then cookie_str := repl(getval("le"|"bc") | "\b", getval("ug"))
  143. X    }
  144. X    }        
  145. X    normal()
  146. X    iputs(\emph_str)
  147. X    iputs(\cookie_str)
  148. X    return
  149. X
  150. Xend
  151. X
  152. X
  153. X
  154. Xprocedure underline()
  155. X    
  156. X    static underline_str, cookie_str
  157. X    initial {
  158. X    if underline_str := getval("us")
  159. X    then cookie_str := repl(getval("le"|"bc") | "\b", getval("ug"))
  160. X    }
  161. X
  162. X    normal()
  163. X    iputs(\underline_str)
  164. X    iputs(\cookie_str)
  165. X    return
  166. X
  167. Xend
  168. X
  169. X
  170. X
  171. Xprocedure normal(mode)
  172. X
  173. X    static UN_emph_str, emph_cookie_str,
  174. X    UN_underline_str, underline_cookie_str,
  175. X    UN_bold_str, bold_cookie_str
  176. X
  177. X    initial {
  178. X
  179. X    # Find out code to turn off emphasize (reverse video) mode.
  180. X    if UN_emph_str := getval("se") then
  181. X        # Figure out how many backspaces we need to erase cookies.
  182. X        emph_cookie_str := repl(getval("le"|"bc") | "\b", getval("sg"))
  183. X
  184. X    # Finally, figure out how to turn off underline mode.
  185. X    if UN_underline_str := (UN_emph_str ~== getval("ue")) then
  186. X        underline_cookie_str := repl(getval("le"|"bc")|"\b", getval("ug"))
  187. X
  188. X    # Figure out how to turn off boldface mode.
  189. X    if UN_bold_str := 
  190. X        (UN_underline_str ~== (UN_emph_str ~== getval("me"))) then
  191. X        # Figure out how many backspaces we need to erase cookies.
  192. X        bold_cookie_str := repl(getval("le"|"bc") | "\b", getval("mg"))
  193. X
  194. X    }        
  195. X    
  196. X    iputs(\UN_emph_str) &
  197. X    iputs(\emph_cookie_str)
  198. X
  199. X    iputs(\UN_underline_str) &
  200. X    iputs(\underline_cookie_str)
  201. X
  202. X    iputs(\UN_bold_str) &
  203. X    iputs(\bold_cookie_str)
  204. X
  205. X    return
  206. X
  207. Xend
  208. X
  209. X
  210. X
  211. Xprocedure status_line(s,s2,p)
  212. X
  213. X    # Writes a status line on the terminal's third-to-last line
  214. X    # The only necessary argument is s.  S2 (optional) is used
  215. X    # for extra narrow screens.  In other words, by specifying
  216. X    # s2 you give status_line an alternate, shorter status string
  217. X    # to display, in case the terminal isn't wide enough to sup-
  218. X    # port s.  If p is nonnull, then the status line is either
  219. X    # centered (if equal to "c"), left justified ("l"), or right
  220. X    # justified ("r").
  221. X
  222. X    local width
  223. X
  224. X    /s := ""; /s2 := ""; /p := "c"
  225. X    width := getval("co")
  226. X    if *s > width then {
  227. X    (*s2 < width, s := s2) |
  228. X        er("status_line","Your terminal is too narrow.",4)
  229. X    }
  230. X
  231. X    case p of {
  232. X    "c"    : s := center(s,width)
  233. X    "l"    : s := left(s,width)
  234. X    "r"    : s := right(s,width)
  235. X    default: stop("status_line:  Unknown option "||string(p),4)
  236. X    }
  237. X
  238. X    iputs(igoto(getval("cm"), 1, getval("li")-2))
  239. X    emphasize(); writes(s)
  240. X    normal()
  241. X    return
  242. X
  243. Xend
  244. X
  245. X
  246. X
  247. Xprocedure message(s)
  248. X
  249. X    # Display prompt s on the second-to-last line of the screen.
  250. X    # I hate to use the last line, due to all the problems with
  251. X    # automatic scrolling.
  252. X
  253. X    /s := ""
  254. X    normal()
  255. X    iputs(igoto(getval("cm"), 1, getval("li")))
  256. X    iputs(getval("ce"))
  257. X    normal()
  258. X    iputs(igoto(getval("cm"), 1, getval("li")-1))
  259. X    iputs(getval("ce"))
  260. X    writes(s[1:getval("co")] | s)
  261. X    return
  262. X
  263. Xend
  264. X
  265. X
  266. X
  267. Xprocedure clear_underline()
  268. X
  269. X    # Horrible way of clearing the screen to all underline mode, but
  270. X    # the only apparent way we can do it "portably" using the termcap
  271. X    # capability database.
  272. X
  273. X    local i
  274. X
  275. X    underline()
  276. X    iputs(igoto(getval("cm"),1,1))
  277. X    if getval("am") then {
  278. X    underline()
  279. X        every 1 to (getval("li")-1) * getval("co") do
  280. X        writes(" ")
  281. X    }
  282. X    else {
  283. X    every i := 1 to getval("li")-1 do {
  284. X        iputs(igoto(getval("cm"), 1, i))
  285. X        underline()
  286. X        writes(repl(" ",getval("co")))
  287. X    }
  288. X    }
  289. X    iputs(igoto(getval("cm"),1,1))
  290. X
  291. Xend
  292. X
  293. X
  294. X
  295. Xprocedure clear_emphasize()
  296. X
  297. X    # Horrible way of clearing the screen to all reverse-video, but
  298. X    # the only apparent way we can do it "portably" using the termcap
  299. X    # capability database.
  300. X
  301. X    local i
  302. X
  303. X    emphasize()
  304. X    iputs(igoto(getval("cm"),1,1))
  305. X    if getval("am") then {
  306. X    emphasize()
  307. X        every 1 to (getval("li")-1) * getval("co") do
  308. X        writes(" ")
  309. X    }
  310. X    else {
  311. X    every i := 1 to getval("li")-1 do {
  312. X        iputs(igoto(getval("cm"), 1, i))
  313. X        emphasize()
  314. X        writes(repl(" ",getval("co")))
  315. X    }
  316. X    }
  317. X    iputs(igoto(getval("cm"),1,1))
  318. X
  319. Xend
  320. SHAR_EOF
  321. echo 'File iscreen.icn is complete' &&
  322. true || echo 'restore of iscreen.icn failed'
  323. rm -f _shar_wnt_.tmp
  324. fi
  325. # ============= findre.icn ==============
  326. if test -f 'findre.icn' -a X"$1" != X"-c"; then
  327.     echo 'x - skipping findre.icn (File already exists)'
  328.     rm -f _shar_wnt_.tmp
  329. else
  330. > _shar_wnt_.tmp
  331. echo 'x - extracting findre.icn (Text)'
  332. sed 's/^X//' << 'SHAR_EOF' > 'findre.icn' &&
  333. X########################################################################
  334. X#    
  335. X#    Name:    findre.icn
  336. X#    
  337. X#    Title:    "Find" Regular Expression
  338. X#    
  339. X#    Author:    Richard L. Goerwitz
  340. X#
  341. X#    Version: 1.15
  342. X#
  343. X########################################################################
  344. X#
  345. X#  I place this and any later versions in the public domain - RLG.
  346. X#
  347. X########################################################################
  348. X#
  349. X#  DESCRIPTION:  findre() is like the Icon builtin function find(),
  350. X#  except that it takes, as its first argument, a regular expression
  351. X#  pretty much like the ones the Unix egrep command uses (the few
  352. X#  minor differences are listed below).  Its syntax is the same as
  353. X#  find's (i.e. findre(s1,s2,i,j)), with the exception that a no-
  354. X#  argument invocation wipes out all static structures utilized by
  355. X#  findre, and then forces a garbage collection.
  356. X#
  357. X#  (For those not familiar with regular expressions and the Unix egrep
  358. X#  command: findre() offers a simple and compact wildcard-based search
  359. X#  system.  If you do a lot of searches through text files, or write
  360. X#  programs which do searches based on user input, then findre is a
  361. X#  utility you might want to look over.)
  362. X#
  363. X#  IMPORTANT DIFFERENCES between find and findre:  As noted above,
  364. X#  findre() is just a find() function that takes a regular expression
  365. X#  as its first argument.  One major problem with this setup is that
  366. X#  it leaves the user with no easy way to tab past a matched
  367. X#  substring, as with
  368. X# 
  369. X#    s ? write(tab(find("hello")+5))
  370. X#
  371. X#  In order to remedy this intrinsic deficiency, findre() sets the
  372. X#  global variable __endpoint to the first position after any given
  373. X#  match occurs.  Use this variable with great care, preferably
  374. X#  assigning its value to some other variable immediately after the
  375. X#  match (for example, findre("hello [.?!]*",s) & tmp := __endpoint).
  376. X#  Otherwise, you will certainly run into trouble.  (See the example
  377. X#  below for an illustration of how __endpoint is used).
  378. X#
  379. X#  IMPORTANT DIFFERENCES between egrep and findre:  findre utilizes
  380. X#  the same basic language as egrep.  The only big difference is that
  381. X#  findre uses intrinsic Icon data structures and escaping conven-
  382. X#  tions rather than those of any particular Unix variant.  Be care-
  383. X#  ful!  If you put findre("\(hello\)",s) into your source file,
  384. X#  findre will treat it just like findre("(hello)",s).  If, however,
  385. X#  you enter '\(hello\)' at run-time (via, say, findre(!&input,s)),
  386. X#  what Icon receives will depend on your operating system (most
  387. X#  likely, a trace will show "\\(hello\\)").
  388. X#
  389. X#  BUGS:  Space has essentially been conserved at the expense of time
  390. X#  in the automata produced by findre().  The algorithm, in other
  391. X#  words, will produce the equivalent of a pushdown automaton under
  392. X#  certain circumstances, rather than strive (at the expense of space)
  393. X#  for full determinism.  I tried to make up a nfa -> dfa converter
  394. X#  that would only create that portion of the dfa it needed to accept
  395. X#  or reject a string, but the resulting automaton was actually quite
  396. X#  slow (if anyone can think of a way to do this in Icon, and keep it
  397. X#  small and fast, please let us all know about it).  Note that under
  398. X#  version 8 of Icon, findre takes up negligible storage space, due to
  399. X#  the much improved hashing algorithm.  I have not tested it under
  400. X#  version 7, but I would expect it to use up quite a bit more space
  401. X#  in that environment.
  402. X#
  403. X#  IMPORTANT NOTE:  Findre takes a shortest-possible-match approach
  404. X#  to regular expressions.  In other words, if you look for "a*",
  405. X#  findre will not even bother looking for an "a."  It will just match
  406. X#  the empty string.  Without this feature, findre would perform a bit
  407. X#  more slowly.  The problem with such an approach is that often the
  408. X#  user will want to tab past the longest possible string of matched
  409. X#  characters (say tab((findre("a*|b*"), __endpoint)).  In circumstan-
  410. X#  ces like this, please just use something like:
  411. X#
  412. X#      s ? {
  413. X#          tab(find("a")) &  # or use Arb() from the IPL (patterns.icn)
  414. X#          tab(many('a'))
  415. X#          tab(many('b'))
  416. X#      }
  417. X#
  418. X#  or else use some combination of findre and the above.
  419. X#    
  420. X########################################################################
  421. X#
  422. X#  REGULAR EXPRESSION SYNTAX: Regular expression syntax is complex,
  423. X#  and yet simple.  It is simple in the sense that most of its power
  424. X#  is concentrated in about a dozen easy-to-learn symbols.  It is
  425. X#  complex in the sense that, by combining these symbols with
  426. X#  characters, you can represent very intricate patterns.
  427. X#
  428. X#  I make no pretense here of offering a full explanation of regular
  429. X#  expressions, their usage, and the deeper nuances of their syntax.
  430. X#  As noted above, this should be gleaned from a Unix manual.  For
  431. X#  quick reference, however, I have included a brief summary of all
  432. X#  the special symbols used, accompanied by an explanation of what
  433. X#  they mean, and, in some cases, of how they are used (most of this
  434. X#  is taken from the comments prepended to Jerry Nowlin's Icon-grep
  435. X#  command, as posted a couple of years ago):
  436. X#
  437. X#     ^   -  matches if the following pattern is at the beginning
  438. X#            of a line (i.e. ^# matches lines beginning with "#")
  439. X#     $   -  matches if the preceding pattern is at the end of a line
  440. X#     .   -  matches any single character
  441. X#     +   -  matches from 1 to any number of occurrences of the
  442. X#            previous expression (i.e. a character, or set of paren-
  443. X#            thesized/bracketed characters)
  444. X#     *   -  matches from 0 to any number of occurrences of the previous
  445. X#            expression
  446. X#     \   -  removes the special meaning of any special characters
  447. X#            recognized by this program (i.e if you want to match lines
  448. X#            beginning with a "[", write ^\[, and not ^[)
  449. X#     |   -  matches either the pattern before it, or the one after
  450. X#            it (i.e. abc|cde matches either abc or cde)
  451. X#     []  -  matches any member of the enclosed character set, or,
  452. X#            if ^ is the first character, any nonmember of the
  453. X#            enclosed character set (i.e. [^ab] matches any character
  454. X#         _except_ a and b).
  455. X#     ()  -  used for grouping (e.g. ^(abc|cde)$ matches lines consist-
  456. X#            ing of either "abc" or "cde," while ^abc|cde$ matches
  457. X#            lines either beginning with "abc" or ending in "cde")
  458. X#
  459. X#########################################################################
  460. X#
  461. X#  EXAMPLE program:
  462. X#
  463. X#  procedure main(a)
  464. X#      while line := !&input do {
  465. X#          token_list := tokenize_line(line,a[1])
  466. X#          every write(!token_list)
  467. X#      }
  468. X#  end
  469. X#
  470. X#  procedure tokenize_line(s,sep)
  471. X#      tmp_lst := []
  472. X#      s ? {
  473. X#          while field := tab(findre(sep)|0) &
  474. X#          mark := __endpoint
  475. X#          do {
  476. X#              put(tmp_lst,"" ~== field)
  477. X#              if pos(0) then break
  478. X#              else tab(mark)
  479. X#          }
  480. X#      }
  481. X#      return tmp_lst
  482. X#  end
  483. X#
  484. X#  The above program would be compiled with findre (e.g. "icont
  485. X#  test_prg.icn findre.icn") to produce a single executable which
  486. X#  tokenizes each line of input based on a user-specified delimiter.
  487. X#  Note how __endpoint is set soon after findre() succeeds.  Note
  488. X#  also how empty fields are excluded with "" ~==, etc.  Finally, note
  489. X#  that the temporary list, tmp_lst, is not needed.  It is included
  490. X#  here merely to illustrate one way in which tokens might be stored.
  491. X#
  492. X#  Tokenizing is, of course, only one of many uses one might put
  493. X#  findre to.  It is very helpful in allowing the user to construct
  494. X#  automata at run-time.  If, say, you want to write a program that
  495. X#  searches text files for patterns given by the user, findre would be
  496. X#  a perfect utility to use.  Findre in general permits more compact
  497. X#  expression of patterns than one can obtain using intrinsic Icon
  498. X#  scanning facilities.  Its near complete compatibility with the Unix
  499. X#  regexp library, moreover, makes for greater ease of porting,
  500. X#  especially in cases where Icon is being used to prototype C code.
  501. X#
  502. X#########################################################################
  503. X
  504. X
  505. Xglobal state_table, parends_present, slash_present
  506. Xglobal biggest_nonmeta_str, __endpoint
  507. Xrecord o_a_s(op,arg,state)
  508. X
  509. X
  510. Xprocedure findre(re, s, i, j)
  511. X
  512. X    local p, x, nonmeta_len, tokenized_re, tmp
  513. X    static FSTN_table, STRING_table
  514. X    initial {
  515. X    FSTN_table := table()
  516. X    STRING_table := table()
  517. X    }
  518. X
  519. X    if /re then {
  520. X    FSTN_table := table()
  521. X    STRING_table := table()
  522. X    collect()  # do it *now*
  523. X    return
  524. X    }
  525. X
  526. X    /s := &subject
  527. X    if \i then {
  528. X    if i < 1 then
  529. X        i := *s + (i+1)
  530. X    }
  531. X    else i := \&pos | 1
  532. X    if \j then {
  533. X    if j < 1 then
  534. X        j := *s + (j+1)
  535. X    }
  536. X
  537. X    else j := *s+1
  538. X    if /FSTN_table[re] then {
  539. X    # If we haven't seen this re before, then...
  540. X    if \STRING_table[re] then {
  541. X        # ...if it's in the STRING_table, use plain find()
  542. X        every p := find(STRING_table[re],s,i,j)
  543. X        do { __endpoint := p + *STRING_table[re]; suspend p }
  544. X        fail
  545. X    }
  546. X    else {
  547. X        # However, if it's not in the string table, we have to
  548. X        # tokenize it and check for metacharacters.  If it has
  549. X        # metas, we create an FSTN, and put that into FSTN_table;
  550. X        # otherwise, we just put it into the STRING_table.
  551. X        tokenized_re := tokenize(re)
  552. X        if 0 > !tokenized_re then {
  553. X        # if at least one element is < 0, re has metas
  554. X        MakeFSTN(tokenized_re) | err_out(re,2)
  555. X        # both biggest_nonmeta_str and state_table are global
  556. X        /FSTN_table[re] := [.biggest_nonmeta_str, copy(state_table)]
  557. X        }
  558. X        else {
  559. X        # re has no metas; put the input string into STRING_table
  560. X        # for future reference, and execute find() at once
  561. X        tmp := ""; every tmp ||:= char(!tokenized_re)
  562. X        insert(STRING_table,re,tmp)
  563. X        every p := find(STRING_table[re],s,i,j)
  564. X        do { __endpoint := p + *STRING_table[re]; suspend p }
  565. X        fail
  566. X        }
  567. X    }
  568. X    }
  569. X
  570. X
  571. X    if nonmeta_len := (1 < *FSTN_table[re][1]) then {
  572. X    # If the biggest non-meta string in the original re
  573. X    # was more than 1, then put in a check for it...
  574. X    s[1:j] ? {
  575. X        tab(x := i to j - nonmeta_len) &
  576. X        (find(FSTN_table[re][1]) | fail) \ 1 &
  577. X        (__endpoint := apply_FSTN(&null,FSTN_table[re][2])) &
  578. X        (suspend x)
  579. X    }
  580. X    }
  581. X    else {
  582. X    #...otherwise it's not worth worrying about the biggest nonmeta str
  583. X    s[1:j] ? {
  584. X        tab(x := i to j) &
  585. X        (__endpoint := apply_FSTN(&null,FSTN_table[re][2])) &
  586. X        (suspend x)
  587. X    }
  588. X    }
  589. X
  590. Xend
  591. X
  592. X
  593. X
  594. Xprocedure apply_FSTN(ini,tbl)
  595. X
  596. X    local biggest_pos, POS, tmp, fin
  597. X    static s_tbl
  598. X
  599. X    /ini := 1 & s_tbl := tbl & biggest_pos := 1
  600. X    if ini = 0 then {
  601. X    return &pos
  602. X    }
  603. X    POS := &pos
  604. X    fin := 0
  605. X
  606. X    repeat {
  607. X    if tmp := !s_tbl[ini] &
  608. X        tab(tmp.op(tmp.arg))
  609. X    then {
  610. X        if tmp.state = fin
  611. X        then return &pos
  612. X        else ini := tmp.state
  613. X    }
  614. X    else (&pos := POS, fail)
  615. X    }
  616. X
  617. Xend
  618. X    
  619. X
  620. X
  621. Xprocedure tokenize(s)
  622. X
  623. X    local token_list, chr, tmp, b_loc, next_one, fixed_length_token_list, i
  624. X
  625. X    token_list := list()
  626. X    s ? {
  627. X    tab(many('*+?|'))
  628. X    while chr := move(1) do {
  629. X        if chr == "\\"
  630. X        # it can't be a metacharacter; remove the \ and "put"
  631. X        # the integer value of the next chr into token_list
  632. X        then put(token_list,ord(move(1))) | err_out(s,2,chr)
  633. X        else if any('*+()|?.$^',chr)
  634. X        then {
  635. X        # Yuck!  Egrep compatibility stuff.
  636. X        case chr of {
  637. X            "*"    : {
  638. X            tab(many('*+?'))
  639. X            put(token_list,-ord("*"))
  640. X            }
  641. X            "+"    : {
  642. SHAR_EOF
  643. true || echo 'restore of findre.icn failed'
  644. fi
  645. echo 'End of  part 7'
  646. echo 'File findre.icn is continued in part 8'
  647. echo 8 > _shar_seq_.tmp
  648. exit 0
  649. -- 
  650.  
  651.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  652.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  653.