home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3583 < prev    next >
Encoding:
Text File  |  1991-07-03  |  19.8 KB  |  654 lines

  1. Newsgroups: alt.sources
  2. From: goer@ellis.uchicago.edu (Richard L. Goerwitz)
  3. Subject: kjv browser, part 5 of 11
  4. Message-ID: <1991Jul3.065108.28132@midway.uchicago.edu>
  5. Date: Wed, 3 Jul 1991 06:51:08 GMT
  6.  
  7. ---- Cut Here and feed the following to sh ----
  8. #!/bin/sh
  9. # this is bibleref.05 (part 5 of a multipart archive)
  10. # do not concatenate these parts, unpack them in order with /bin/sh
  11. # file indexutl.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" != 5; 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 indexutl.icn'
  27. else
  28. echo 'x - continuing file indexutl.icn'
  29. sed 's/^X//' << 'SHAR_EOF' >> 'indexutl.icn' &&
  30. X#
  31. X############################################################################
  32. X
  33. X#
  34. X# All from the IPL.
  35. X#
  36. Xlink radcon, bincvt
  37. X
  38. X#
  39. X# FS = field separator, s_len = string length of fields, len =
  40. X# byte length of fields, no = number of fields, is_case_sensitive =
  41. X# whether to map index entries to lowercase, r_field = rollover
  42. X# field for limits file.
  43. X#
  44. Xrecord is(FS, s_len, len, no, is_case_sensitive, r_field)
  45. Xglobal _slash, _baselen, IS
  46. X
  47. X
  48. Xprocedure base_name(s)
  49. X
  50. X    # If s == "/usr/local/man/man1/icon.1", base_name will return
  51. X    # "icon.1".  Somewhat like the Unix basename system command.
  52. X
  53. X    # global _slash        # _slash = \ for MS-DOS, / for Unix
  54. X    s ? {
  55. X    while tab(find(_slash)+1)
  56. X    return tab(0)
  57. X    }
  58. X
  59. Xend
  60. X
  61. X
  62. X
  63. Xprocedure dir_name(s)
  64. X
  65. X    # If s == "/usr/local/man/man1/icon.1", dir_name will return
  66. X    # "/usr/local/man/man1".  Somewhat like the Unix dirname system
  67. X    # command.
  68. X
  69. X    local s2
  70. X    # global _slash        # _slash = \ for MS-DOS, / for Unix
  71. X
  72. X    s2 := ""
  73. X    s ? {
  74. X    while s2 ||:= tab(find(_slash)+1)
  75. X    return s2
  76. X    }
  77. X
  78. Xend
  79. X
  80. X
  81. X
  82. Xprocedure create_fname(FNAME, EXT)
  83. X
  84. X    #
  85. X    # Discard path component.  Cut basename down to a small enough
  86. X    # size that the OS will be able to handle addition of the ex-
  87. X    # tension, EXT.
  88. X    #
  89. X
  90. X    # global _slash, _baselen
  91. X
  92. X    *EXT > 3 &
  93. X    abort("get_index_fname","extension too long",7)
  94. X
  95. X    return right(
  96. X    stripchars(base_name(FNAME,_slash),'.'), _baselen, "x") ||
  97. X        "." || EXT
  98. X
  99. Xend
  100. X
  101. X
  102. X
  103. Xprocedure stripchars(s,c)
  104. X
  105. X    # Strip chars (c) from string (s).  Return stripped s.
  106. X
  107. X    local s2
  108. X
  109. X    s2 := ""
  110. X    s ? {
  111. X    while s2 ||:= tab(upto(c))
  112. X    do tab(many(c))
  113. X    s2 ||:= tab(0)
  114. X    }
  115. X    return s2
  116. X
  117. Xend
  118. X
  119. X
  120. X
  121. Xprocedure abort(proc_name, message, error_code)
  122. X
  123. X    if not (/proc_name := "") then
  124. X    proc_name := trim(proc_name, ': ') || ":  "
  125. X    /error_code := 1
  126. X    
  127. X    write(&errout, proc_name, \message) # fail if there's no error msg,
  128. X    exit(error_code)         # then abort
  129. X
  130. Xend
  131. X
  132. X
  133. X
  134. Xprocedure write_int(f, i, size)
  135. X
  136. X    # Write out an integer byte-by-byte.
  137. X    #
  138. X    # Important little routine.  I know it looks inelegant and slow.
  139. X    # Feel free to modify it for speed, and send me the results.
  140. X    # Don't knock out the old code, though.  You understood it when
  141. X    # you read it, right?  That's the idea :-).
  142. X
  143. X    local marker, how_many
  144. X
  145. X    marker := ""
  146. X    how_many := 0
  147. X    /size := (*exbase10(i,2) <= seq(0,8))
  148. X
  149. X    # output bytes most significant first; then least significant
  150. X    until (size -:= 8) <= -8 do {
  151. X    how_many +:= 1
  152. X    marker ||:= (f, char(iand(ishift(i, -size), 2r11111111)))
  153. X    }
  154. X
  155. X    writes(f, marker)
  156. X    return how_many        # number of characters written
  157. X
  158. Xend
  159. X
  160. X
  161. X
  162. Xprocedure read_int(f, size)
  163. X
  164. X    local i, _shift
  165. X
  166. X    # collect bytes, putting the first one read into the high
  167. X    # end of an integer, and on down to the last read (into the
  168. X    # low end)
  169. X    i := _shift := 0
  170. X    while (_shift +:= 8) <= size do
  171. X    i +:= ishift(ord(reads(f)), size - _shift) | fail
  172. X    return i
  173. X
  174. Xend
  175. X
  176. X
  177. X
  178. Xprocedure initialize_os_params()
  179. X
  180. X    local os
  181. X    # global _slash, _baselen
  182. X
  183. X    if find("MS-DOS", os := &features) then {
  184. X    _slash := "\\";    _baselen := 8
  185. X    }
  186. X    else if find("UNIX", os := &features) then {
  187. X    _slash := "/"; _baselen := 10
  188. X    }
  189. X    else abort("initialize_os_params","os parameters undefined", 6)
  190. X
  191. X    return os
  192. X
  193. Xend
  194. X
  195. X
  196. Xprocedure are_metas(str)
  197. X
  198. X    local chr, tmp
  199. X
  200. X    str ? {
  201. X
  202. X    # String-initial metacharacters are meaningless.
  203. X    tab(many('*+?|'))
  204. X
  205. X    # Look for metacharacters and backslashes.
  206. X    while tab(upto('\\*+()|?.$^[')) do {
  207. X
  208. X        # If a backslash comes first, then the next character can't
  209. X        # be a meta.  Move past it, and try again.
  210. X        if ="\\" then move(1) |
  211. X        abort("are_metas","malformed \-escape sequence",19)
  212. X        # Otherwise, we have a metacharacter.  Return its position
  213. X        # in str.  Dereference just so as not to have a global var.
  214. X        # on the loose.
  215. X        else return .&pos
  216. X    }
  217. X
  218. X    }
  219. X
  220. X    # If we've gotten this far without returning, then the string is
  221. X    # clean of metacharacters, and (in boolean terms) the procedure
  222. X    # are_metas() returns false.
  223. X    fail
  224. X
  225. Xend
  226. X
  227. X
  228. X#
  229. X# digits_2_bitmap
  230. X#
  231. X# Converts a string representation of a set of bit-fields into an
  232. X# integer.  I.e. 1:1:3 becomes binary 010111 (decimal 23).  This
  233. X# integer is like a map, and is called, in text-processing circles,
  234. X# a bitmap (not to be confused with bit-mapped display techniques).
  235. X# 
  236. Xprocedure digits_2_bitmap(s)
  237. X
  238. X    # s        = location string (e.g. 10:02:03:75)
  239. X    # IS.s_len = the string length of fields in s (3 in the above example)
  240. X    # IS.len   = the number of bits needed to hold an integer
  241. X    #             representation of a single field
  242. X    # IS.no    = number of fields in s (4 in the above example)
  243. X    #
  244. X    # Fixed field lengths make things much simpler, but a whole
  245. X    # helluva lot less economical.  Be sure that (IS.len * IS.no) does
  246. X    # not exceed the register width for your CPU if either a) your
  247. X    # implementation has no limits on the size of integers, or b) you
  248. X    # are really concerned about performance.  Otherwise, never mind.
  249. X
  250. X    local bitmap, field, no
  251. X
  252. X    no       := IS.no
  253. X    bitmap   := 0
  254. X
  255. X    s ? {
  256. X    if upto(~&digits) then {
  257. X        # The bitmap is delineated by field-markers (e.g. 11;23).
  258. X        tab(upto(&digits))
  259. X        while field := tab(many(&digits)) do {
  260. X        no -:= 1
  261. X        tab(upto(&digits))
  262. X        bitmap +:= ishift(field, no * IS.len)
  263. X        }
  264. X    } else {
  265. X        # Yuck!  An un-delineated bitmap (e.g. 23423).
  266. X        while field := integer(move(IS.s_len)) do {
  267. X        no -:= 1
  268. X        tab(upto(&digits))
  269. X        bitmap +:= ishift(field, no * IS.len)
  270. X        }
  271. X    }
  272. X    # If we're not at the end of the line, then we've got a
  273. X    # a problem with the portion of the input file passed
  274. X    # to digits_2_bitmap as s (arg1).
  275. X    pos(0) | abort("digits_2_bitmap",
  276. X               "malformed position marker:  "||s,
  277. X               11)
  278. X    }
  279. X
  280. X    # If the current no is not -1, then we have either too
  281. X    # many or too few fields, i.e. someone wrote, say, 01:02:03 in
  282. X    # a text which he or she declared as having four fields.
  283. X    no = 0 | abort("digits_2_bitmap",
  284. X    no || " fields in "||s||" (expected "||IS.no||")",
  285. X    12)
  286. X    # write(&errout,"bitmap = ",radcon(bitmap,10,2))  # for debugging
  287. X    return bitmap
  288. X
  289. Xend
  290. SHAR_EOF
  291. echo 'File indexutl.icn is complete' &&
  292. true || echo 'restore of indexutl.icn failed'
  293. rm -f _shar_wnt_.tmp
  294. fi
  295. # ============= retrops.icn ==============
  296. if test -f 'retrops.icn' -a X"$1" != X"-c"; then
  297.     echo 'x - skipping retrops.icn (File already exists)'
  298.     rm -f _shar_wnt_.tmp
  299. else
  300. > _shar_wnt_.tmp
  301. echo 'x - extracting retrops.icn (Text)'
  302. sed 's/^X//' << 'SHAR_EOF' > 'retrops.icn' &&
  303. X############################################################################
  304. X#
  305. X#    Name:     retrops.icn
  306. X#
  307. X#    Title:     logical operations for retrievals
  308. X#
  309. X#    Author:     Richard L. Goerwitz
  310. X#
  311. X#    Version: 1.6
  312. X#
  313. X############################################################################
  314. X#
  315. X#  The following collection of procedures implements logical
  316. X#  and/or/and_not operations for the retrieve text-retrieval package.
  317. X#  Their general form is
  318. X#
  319. X#      r_op(set1, set2, filename, field, range)
  320. X#
  321. X#  where op = one of either and, or, or and_not.  The field and range
  322. X#  arguments are optional.
  323. X#
  324. X#  To illustrate how these operations are performed, let me explain
  325. X#  how one of the procedures below, r_and(), works.  Let us assume we
  326. X#  have retrieve()d bitmap sets for two patterns in a single indexed
  327. X#  file.  Call the sets set1 and set2.  Call the file filename.  These
  328. X#  two sets are passed to r_and() as arguments one and two.  R_and()
  329. X#  takes the intersection of these two sets.  The result is a
  330. X#  collection of all bitmaps pointing to blocks in filename containing
  331. X#  words matching *both* of the two patterns used to generate set1 and
  332. X#  set2.  R_and() returns this result to the calling procedure.
  333. X#
  334. X#  Note that, by default, r_and() retrieves co-ocurrences of patterns
  335. X#  within a single block.  If the programmer wishes to find
  336. X#  co-ocurrences within larger units, he or she may supply a field
  337. X#  argument.  Fields are fixed width bit-fields into which location
  338. X#  markers for filename are divided, numbered from the largest and
  339. X#  most general to the smallest and most specific.  See the file
  340. X#  makeind for a discussion of how they are handled.  A range
  341. X#  parameter may also be specified, which makes it possible to look
  342. X#  for coocurrences in collections of more than one unit of the type
  343. X#  specified in the field argument.
  344. X#
  345. X############################################################################
  346. X#
  347. X#  Links: none
  348. X#
  349. X#  See also: retrieve.icn, makeind.icn
  350. X#
  351. X############################################################################
  352. X
  353. X# The following globals contain stats for current file (here, arg 3).
  354. X# global filestats    # declared in initfile.icn
  355. X# global IS           # declared in indexutl.icn
  356. X
  357. Xprocedure r_or(set1, set2, filename, field, range)
  358. X    # field and range are meaningless for this op
  359. X    return set1 ++ set2
  360. Xend
  361. X
  362. Xprocedure r_and(set1, set2, filename, field, range)
  363. X    # set intersection
  364. X    return apply_op("**", set1, set2, filename, field, range)
  365. Xend
  366. X
  367. Xprocedure r_and_not(set1, set2, filename, field, range)
  368. X    # simpler way of saying X and not Y, or Y and not X
  369. X    return apply_op("--", set1, set2, filename, field, range)
  370. Xend
  371. X
  372. X
  373. Xprocedure apply_op(op, set1, set2, filename, field, range)
  374. X
  375. X    local r_shift, tbl, elem, set1a, set2a, shifted_elem
  376. X
  377. X    # globals:
  378. X    #
  379. X    # IS is a global record in which will be stored important stats for
  380. X    # the file named in arg 4 (filename).  We will be using two of IS's
  381. X    # fields:
  382. X    #
  383. X    # IS.len   = the number of bits needed to hold an integer
  384. X    #             representation of a single field in filename
  385. X    # IS.no    = number of fields for filename
  386. X    #
  387. X    # Filestats is a global table which contains various important stats
  388. X    # for every file that's been accessed.  These stats are kept in a
  389. X    # record of type Fs
  390. X    #  
  391. X    #     record Fs(ind_filename, bmp_filename, lim_filename, IS, ofs_table)
  392. X    #
  393. X    # Fs is declared in initfile.icn; here all we need is Fs.IS,
  394. X    # which we access via filestats[filename].IS.  Initfile() sets up
  395. X    # filestats for filename, but we shouldn't call it here.  It has
  396. X    # (or should already have) been called by retrieve().
  397. X    #
  398. X
  399. X    # Check for sloppy programming.
  400. X    /filename & abort("apply_op", "you gotta call me with a filename", 43)
  401. X    type(set1) == ("list"|"set") |
  402. X    abort("apply_op","arg 1 must be a list/set",47)
  403. X    type(set2) == ("list"|"set") |
  404. X    abort("apply_op","arg 2 must be a list/set",48)
  405. X
  406. X    # Initialize important variables.
  407. X    #
  408. X    if /filestats | /filestats[filename]
  409. X    then abort("apply_op", "can't apply_op before retrieve()ing", 44)
  410. X    IS := filestats[filename].IS      # re-initialize IS for current file
  411. X
  412. X    /field := IS.no; field := IS.no - field
  413. X    /range := 0
  414. X    IS.no >= field >= 0 | abort("apply_op", "field out of range", 40)
  415. X    range >= 0 | abort("apply_op", "no negative ranges, please!", 41)
  416. X
  417. X    if field = range = 0 then {
  418. X    type(set1) ~== "set" & set1 := set(set1)
  419. X    type(set2) ~== "set" & set2 := set(set2)
  420. X    # no need to shift anything around
  421. X    return op(set1, set2)
  422. X    } else {
  423. X    set1a := set()
  424. X    if field = 0 then {
  425. X        every elem := !set1 do {
  426. X        every abs(elem - !set2) <= range do
  427. X            insert(set1a, elem)
  428. X        }
  429. X        return set1a
  430. X    } else {
  431. X        # uh oh, we need to knock out some fields
  432. X        tbl := table()
  433. X        set1a := set(); set2a := set()
  434. X        r_shift := -(field * IS.len)
  435. X        every elem := !set1 do {
  436. X        shifted_elem := ishift(elem,r_shift)
  437. X        /tbl[elem] := set()
  438. X        insert(tbl[shifted_elem], elem)
  439. X        insert(set1a, shifted_elem)
  440. X        }
  441. X        every elem := !set2 do {
  442. X        shifted_elem := ishift(elem,r_shift)
  443. X        /tbl[elem] := set()
  444. X        insert(tbl[shifted_elem], elem)
  445. X        insert(set2a, shifted_elem)
  446. X        }
  447. X        set2 := set()
  448. X        if range = 0 then {
  449. X        set1 := op(set1a, set2a)
  450. X        every insert(set2, !tbl[!set1])
  451. X        }
  452. X        else {
  453. X        every elem := !set1a do {
  454. X            every abs(elem - !set2a) <= range do
  455. X            insert(set2, tbl[elem])
  456. X        }
  457. X        }
  458. X        return set2
  459. X    }
  460. X    }
  461. X
  462. Xend
  463. SHAR_EOF
  464. true || echo 'restore of retrops.icn failed'
  465. rm -f _shar_wnt_.tmp
  466. fi
  467. # ============= whatnext.icn ==============
  468. if test -f 'whatnext.icn' -a X"$1" != X"-c"; then
  469.     echo 'x - skipping whatnext.icn (File already exists)'
  470.     rm -f _shar_wnt_.tmp
  471. else
  472. > _shar_wnt_.tmp
  473. echo 'x - extracting whatnext.icn (Text)'
  474. sed 's/^X//' << 'SHAR_EOF' > 'whatnext.icn' &&
  475. X###########################################################################
  476. X#
  477. X#    Name:     whatnext.icn
  478. X#
  479. X#    Title:     return next/previous bitmap in filename
  480. X#
  481. X#    Author:     Richard L. Goerwitz
  482. X#
  483. X#    Version: 1.5
  484. X#
  485. X###########################################################################
  486. X#
  487. X#  Given a bitmap and a filename, NextBitmap() and PrevBitmap() return
  488. X#  either the next or previous bitmap in filename.  Fail if there is no
  489. X#  next or previous bitmap.  Syntax:
  490. X#
  491. X#      {Next,Prev}Bitmap(bitmap, filename, start_no)
  492. X#
  493. X#  start_no specifies the lowest possible field value.  If null, defaults
  494. X#  to 1.  Normally start_no will be either 1 or 0.
  495. X#
  496. X############################################################################
  497. X#
  498. X#  links:  ./indexutl.icn ./initfile.icn
  499. X#
  500. X############################################################################
  501. X
  502. X# For error messages, debugging.
  503. Xlink radcon
  504. X
  505. X# Declared in indexutl.icn.
  506. X# record is(FS, s_len, len, no, is_case_sensitive)
  507. X# global IS
  508. X
  509. X# Declared in initfile.icn.
  510. X# global filestats
  511. X# record Fs(ind_filename, bmp_filename, lim_filename, IS, ofs_table)
  512. X
  513. X# Used here to store limits data in the static table limits_tbl.
  514. Xrecord ldata(limitslst, limitsset)
  515. X
  516. X
  517. Xprocedure PrevBitmap(bitmap, filename, start_no)
  518. X    return PrevNextBitmap(bitmap, filename, "p", start_no)
  519. Xend
  520. X
  521. Xprocedure NextBitmap(bitmap, filename, start_no)
  522. X    return PrevNextBitmap(bitmap, filename, "n", start_no)
  523. Xend
  524. X
  525. X
  526. Xprocedure PrevNextBitmap(bitmap, filename, direction, start_no)
  527. X
  528. X    local limits_file, limit, bitmap_length, limitslst,
  529. X    limitsset, field_mask, shift_bits_out, lowlimit, shift_back, 
  530. X    i, j, newbitmap
  531. X    static limits_tbl
  532. X    initial limits_tbl := table()
  533. X
  534. X    # These verses are missing from the standard Hebrew Bible.  For
  535. X    # English, we can safely ignore them.  See below ("return newbitmap")
  536. X    # for an explanation of how to use a weirdos set.
  537. X    # weirdos := set(["josh 14:8","deut 23:12"])
  538. X
  539. X    # Check for sloppy programming.
  540. X    /filename & abort("PrevNextBitmap", "you called me without a filename",54)
  541. X    /start_no := 1        # default low value for fields is 1
  542. X
  543. X    # If necessary, initialize limits stats for the current file.
  544. X    #
  545. X    if /limits_tbl[filename] then {
  546. X    if /filestats | /filestats[filename] then
  547. X        initfile(filename)           # see initfile.icn
  548. X    limits_file := open(filestats[filename].lim_filename) |
  549. X        abort("PrevBitmap","can't open "||
  550. X          filestats[filename].lim_filename ||
  551. X          ", index with the -l [int] option", 60)
  552. X    IS := filestats[filename].IS
  553. X    # Figure out how many bits we need (has to be divisible by 8).
  554. X    bitmap_length := ((IS.len * IS.no) <= seq(0,8))
  555. X    limitslst := list(); limitsset := set()
  556. X    shift_bits_out := -(((IS.no-IS.r_field)+ 1) * IS.len)
  557. X    while limit := read_int(limits_file, bitmap_length) do {
  558. X        lowlimit :=    ishift(limit, shift_bits_out)
  559. X        # Shift back, filling remaining fields with start_no (usu. 1).
  560. X        # Note that if IS.no - IS.r_field is 0, nothing will happen!
  561. X        every shift_back := IS.len * (1 to (IS.no-IS.r_field)+ 1) do {
  562. X        lowlimit := ior(ishift(lowlimit, shift_back), start_no)
  563. X        }
  564. X        every put(limitslst, lowlimit | limit)
  565. X        insert(limitsset, limit)
  566. X    }
  567. X    close(limits_file)
  568. X    insert(limits_tbl, filename, ldata(limitslst, limitsset))
  569. X    }
  570. X
  571. X    IS := filestats[filename].IS
  572. X    limitslst := limits_tbl[filename].limitslst
  573. X    limitsset := limits_tbl[filename].limitsset
  574. X    #
  575. X    # Used to mask off the least significant field of bitmap.
  576. X    field_mask := 2^(IS.len)-1
  577. X    #
  578. X    # How many bits should we shift to the right?  E.g. in biblical
  579. X    # texts with morphological tags, we want to shift out the morpheme
  580. X    # field, and deal only with book chapter:verse.  The rollover
  581. X    # field (IS.r_field) is the field on which the limits file is
  582. X    # based.  Subtract it from the total number of fields (IS.no), and
  583. X    # then multiply it by the field width in bits (IS.len) and we get
  584. X    # the amount to shift out in order to leave us with the rollover
  585. X    # field in the least position.
  586. X    #
  587. X    shift_bits_out := -((IS.no-IS.r_field) * IS.len)
  588. X
  589. X    if direction == "p" then {
  590. X    #
  591. X    # See if the rollover field has its lowest possible value.  If
  592. X    # so, then use the limits list to get a bitmap for the
  593. X    # preceding section in filename.
  594. X    #
  595. X    if iand(ishift(bitmap, shift_bits_out), field_mask) = start_no then {
  596. X        bitmap = limitslst[j := 1 to *limitslst] | fail
  597. X        newbitmap := limitslst[j - 1] | fail
  598. X    }
  599. X    #
  600. X    # If the rollover field doesn't have its lowest possible
  601. X    # value, then it can simply be decremented; then the remaining
  602. X    # fields must be reset to start_no.
  603. X    #
  604. X    else {
  605. X        # Decrement appropriate field by one; direction is "p".
  606. X        newbitmap := ishift(bitmap, shift_bits_out) - 1
  607. X        # Shift back, filling remaining fields with start_no (usu. 1).
  608. X        # Note that if IS.no - IS.r_field is 0, nothing will happen!
  609. X        every shift_back := IS.len * (1 to (IS.no-IS.r_field)) do {
  610. X        newbitmap := ior(ishift(newbitmap, shift_back), start_no)
  611. X        }
  612. X    }
  613. X    return newbitmap
  614. X        # This is how we'd handle things if we needed a weirdos set
  615. X        # (needed, e.g., for the Hebrew Bible).
  616. X        # if member(weirdos, newbitmap)
  617. X        # then return WhatsNextPrevious(
  618. X    #    newbitmap, filename, direction, start_no)
  619. X        # else return newbitmap
  620. X    }
  621. X    else if direction == "n" then {
  622. X    #
  623. X    # See if the field after the rollover field has its highest
  624. X    # possible value.  We can determine this by checking to see if
  625. X    # bitmap is a member of the limits set.  If so, then use the
  626. X    # limits *list* to get a bitmap for the next section in filename.
  627. X    #
  628. X    if member(limitsset,bitmap) then {
  629. X        bitmap = limitslst[i := 1 to *limitslst] | fail
  630. X        newbitmap := limitslst[i + 1] | fail
  631. X    }
  632. X    #
  633. X    # If the rollover field doesn't have its highest possible
  634. X    # value, then it can simply be incremented; then the remaining
  635. X    # fields must be reset to start_no.
  636. X    #
  637. X    else {
  638. X        # Increment appropriate field by one; direction is "n".
  639. X        newbitmap := ishift(bitmap, shift_bits_out) + 1
  640. X        # Shift back, filling remaining fields with start_no (usu. 1).
  641. X        every shift_back := IS.len * (1 to (IS.no-IS.r_field)) do {
  642. X        newbitmap := ior(ishift(newbitmap, shift_back), start_no)
  643. SHAR_EOF
  644. true || echo 'restore of whatnext.icn failed'
  645. fi
  646. echo 'End of  part 5'
  647. echo 'File whatnext.icn is continued in part 6'
  648. echo 6 > _shar_seq_.tmp
  649. exit 0
  650. -- 
  651.  
  652.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  653.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  654.