home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group90b.txt < prev    next >
Internet Message Format  |  1991-01-03  |  482KB

  1. From R@edinburgh.ac.uk  Tue Jun  5 03:02:43 1990
  2. Received: from rvax.ccit.arizona.edu by megaron (5.61/15) via SMTP
  3.     id AA06671; Tue, 5 Jun 90 03:02:43 -0700
  4. Received: from UKACRL.BITNET by rvax.ccit.arizona.edu; Tue, 5 Jun 90 03:02 MST
  5. Received: from RL.IB by UKACRL.BITNET (Mailer X1.25) with BSMTP id 0481; Tue,
  6.  05 Jun 90 10:50:51 BST
  7. Date: 05 Jun 90  10:41:26 bst
  8. From: R.J.Hare@edinburgh.ac.uk
  9. Subject: Icon Book
  10. To: icon-group@cs.arizona.edu
  11. Message-Id: <05 Jun 90  10:41:26 bst  340083@EMAS-A>
  12. Via:        UK.AC.ED.EMAS-A;  5 JUN 90 10:41:03 BST
  13. X-Envelope-To: icon-group@cs.arizona.edu
  14. Status: O
  15.  
  16. Could someone please remind me of the publication details (date, edition
  17. number, isbn, price) of the new edition of the Icon book please - I want to
  18. order a copy and want to make sure that I don't get the first edition...
  19.  
  20. Thanks.
  21.  
  22. RH.
  23.  
  24. From cargo@tardis.cray.com  Tue Jun  5 12:01:53 1990
  25. Received: from timbuk.CRAY.COM by megaron (5.61/15) via SMTP
  26.     id AA00187; Tue, 5 Jun 90 12:01:53 -0700
  27. Received: from hall.cray.com by timbuk.CRAY.COM (4.1/CRI-1.34)
  28.     id AA05899; Tue, 5 Jun 90 14:01:03 CDT
  29. Received: from zk.cray.com by hall.cray.com
  30.     id AA02627; 4.1/CRI-3.12; Tue, 5 Jun 90 14:00:40 CDT
  31. Received: by zk.cray.com
  32.     id AA12356; 3.2/CRI-3.12; Tue, 5 Jun 90 14:00:54 CDT
  33. Date: Tue, 5 Jun 90 14:00:54 CDT
  34. From: cargo@tardis.cray.com (David S. Cargo)
  35. Message-Id: <9006051900.AA12356@zk.cray.com>
  36. To: icon-group@cs.arizona.edu
  37. Subject: BASIC, expression parsing
  38. Status: O
  39.  
  40. As an actual, real-world application I am building an application
  41. that analyzes the memory of a microprocessor.  I'm using Icon to
  42. write it.  I've got some useful parts of it working, but I want
  43. some more, to simplify it for its users.  I'm wondering if anybody
  44. has implemented a general-purpose expression evaluator that can
  45. handles variables and does not use co-expressions.  I'm looking for
  46. something on the order of a BASIC LET statement with more flexibility
  47. for expression types (in need shifts and boolean operations) and
  48. variable types.          o       o
  49.                           \_____/
  50.                           /-o-o-\     _______
  51. DDDD      SSSS   CCCC    /   ^   \   /\\\\\\\\
  52. D   D    S      C        \ \___/ /  /\   ___  \
  53. D   D     SSS   C         \_   _/  /\   /\\\\  \
  54. D   D        S  C           \  \__/\   /\ @_/  /
  55. DDDDavid SSSS.   CCCCargo    \____\____\______/ cargo@tardis.cray.com
  56.  
  57. From icon-group-request@arizona.edu  Tue Jun  5 21:53:45 1990
  58. Resent-From: icon-group-request@arizona.edu
  59. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  60.     id AA02155; Tue, 5 Jun 90 21:53:45 -0700
  61. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Tue, 5 Jun 90 21:55 MST
  62. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA05786; Tue, 5 Jun 90 21:40:54
  63.  -0700
  64. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  65.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  66.  usenet@ucbvax.Berkeley.EDU if you have questions)
  67. Resent-Date: Tue, 5 Jun 90 21:55 MST
  68. Date: 6 Jun 90 04:42:24 GMT
  69. From: iris!wood@ucdavis.ucdavis.EDU
  70. Subject: Compiling icon
  71. Sender: icon-group-request@arizona.edu
  72. Resent-To: icon-group@cs.arizona.edu
  73. To: icon-group@arizona.edu
  74. Resent-Message-Id: <83C8ED3FC45FA00304@Arizona.EDU>
  75. Message-Id: <7432@ucdavis.ucdavis.edu>
  76. Organization: U.C. Davis - Department of Electrical Engineering and Computer
  77.  Science
  78. X-Envelope-To: icon-group@CS.Arizona.EDU
  79. X-Vms-To: icon-group@Arizona.edu
  80. Status: O
  81.  
  82. I'm trying to compile the icon source for research for a class of mine.
  83. However, I can't get the original source to compile.  Is the 'as' opcode
  84. "ADDL3" (from a file called create.c in int/operations) valid?
  85.  
  86. Or did I completely miss something?
  87.  
  88. I know, I know, I should probably ask the 'Icon project', could someone
  89. please send me the address and some guidelines on getting them to answer
  90. questions?  Thanks.
  91.  
  92.     Jeff Wood
  93.     wood@iris.ucdavis.edu
  94.     Univ. of California, Davis
  95.  
  96. From tenaglia@fps.mcw.edu  Wed Jun  6 15:19:26 1990
  97. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  98.     id AA20568; Wed, 6 Jun 90 15:19:26 -0700
  99. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.3/3.06) with UUCP 
  100.     id AA06432; Wed, 6 Jun 90 17:50:15 EDT
  101. Received: by uwm.edu; id AA20935; Wed, 6 Jun 90 16:48:04 -0500
  102. Message-Id: <9006062148.AA20935@uwm.edu>
  103. Received: from mis by fps.mcw.edu (DECUS UUCP w/Smail);
  104.           Wed,  6 Jun 90 15:04:59 CDT
  105. Received: by mis.mcw.edu (DECUS UUCP w/Smail);
  106.           Wed,  6 Jun 90 13:45:15 CDT
  107. Date: Wed,  6 Jun 90 13:45:15 CDT
  108. From: Chris Tenaglia - 257-8765 <tenaglia@mis.mcw.edu>
  109. To: icon-group@cs.arizona.edu
  110. Subject: Anyone want to be adventurous with VMS and C ?
  111. Status: O
  112.  
  113. I've discovered a small bug in Icon Version 8 under VAX/VMS 5.2. I like
  114. mixing VMS and icon (to imitate pipes that are natural under unix. For
  115. example.
  116.  
  117. ###########################################################################
  118. #                                                                         #
  119. # resp.icn          5/29/90          by tenaglia                          #
  120. #                                                                         #
  121. # used in determining what slow response time is                          #
  122. #                                                                         #
  123. ###########################################################################
  124. procedure main()
  125.   out := open("bench.log","w")
  126.   repeat
  127.     {
  128.     bucket := []
  129.     now := edit(&clock,"##$##$##")
  130.     (test:= open("@RESP.COM","pr")) | stop("broken pipe")      # 1
  131.     (log := open("RESP.LOG","w"))   | stop("what's with resp.log?")
  132.     while put(bucket,read(test))
  133.     close(test) | stop("Can't close process")                  # 2
  134.     every write(log,!bucket) ; close(log)
  135.     fin := edit(&clock,"##$##$##")
  136.     write(out,&dateline," --> ",fin - now)
  137.     system("wait 00:01:00")
  138.     }
  139.   end
  140.  
  141. ########################################################################
  142. #                                                                      #
  143. # EXAMPLES :  edit("12/03/89","##$##$##") returns 120389               #
  144. #             edit("120389","##/##/19##") returns 12/03/1989           #
  145. #             edit("12/03/1989","##$")    returns 12                   #
  146. #                                                                      #
  147. ########################################################################
  148. procedure edit(var,mask)       
  149.   text := ""
  150.   var ? {
  151.     every chr := !mask do {
  152.       case chr of {
  153.         "#" : text ||:= move(1)
  154.         "$" : move(1)
  155.         default : text ||:= chr
  156.         }
  157.       }
  158.     }
  159.   return text
  160. end
  161.  
  162. In #1 I open a process for read. Later I read lines out of it. Finally in #2
  163. I close the process to make it go away. It does, but not quite. After it loops
  164. the number of times that equals the PRCLM on my account, it dies. Even if SHOW
  165. SYSTEM shows no such processes.
  166.  
  167. Another similar and related problem is that if I would try to close the process
  168. before reading all the lines. The close() is successful but the processes are
  169. left hanging out there.
  170.  
  171. My question is, is there any VMS/C guru out there in Iconland who might have a
  172. patch? I don't have C on our systems. I do have UUDECODE, in case you'd want to
  173. mail the whole executable. Which exectable? ICONX.EXE. I browsed over the code
  174. briefly. The close is accomplished by FSYS.C in [ICON.SRC.ICONX] around lines
  175. 43 to 54. Thanks in advance. (But I think most users are unix people).
  176.  
  177. Chris Tenaglia (System Manager)
  178. Medical College of Wisconsin
  179. 8701 W. Watertown Plank Rd.
  180. Milwaukee, WI 53226
  181. (414)257-8765
  182. tenaglia@mis.mcw.edu
  183.  
  184.  
  185. From icon-group-request@arizona.edu  Thu Jun  7 07:45:33 1990
  186. Resent-From: icon-group-request@arizona.edu
  187. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  188.     id AA00240; Thu, 7 Jun 90 07:45:33 -0700
  189. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 7 Jun 90 07:47 MST
  190. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA26697; Thu, 7 Jun 90 07:24:12
  191.  -0700
  192. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  193.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  194.  usenet@ucbvax.Berkeley.EDU if you have questions)
  195. Resent-Date: Thu, 7 Jun 90 07:47 MST
  196. Date: 6 Jun 90 23:37:07 GMT
  197. From: amdahl!ntmtv!hildum@apple.COM
  198. Subject: What is the best way to do this?
  199. Sender: icon-group-request@arizona.edu
  200. Resent-To: icon-group@cs.arizona.edu
  201. To: icon-group@arizona.edu
  202. Resent-Message-Id: <82AD14150D5FA00DB3@Arizona.EDU>
  203. Message-Id: <1214@ntmtv.UUCP>
  204. Organization: Northern Telecom (Mountain View, CA)
  205. X-Envelope-To: icon-group@CS.Arizona.EDU
  206. X-Vms-To: icon-group@Arizona.edu
  207. Status: O
  208.  
  209.  
  210. I am writing a procedure which scans a file for the objects that it 
  211. includes, and returns the name of the object. Objects are included
  212. via a line of the form:
  213.  
  214. *=> [chars]* COPY name
  215.  
  216. where name is the name of the object, COPY is a keyword, *=> marks the
  217. beginning of the line, and [chars]* are any characters but the sequence
  218. COPY. White space is ignored, and there are a random number of them on a 
  219. line.
  220.  
  221. I have written the following procedure to open the files and generate
  222. the names of objects included in the file.  The commented out portion is
  223. a previous version of the loop body, and I have created a new loop body
  224. using an if expression.  Which one of these is better, and why? If there 
  225. is a better solution, I would like to see it.
  226.  
  227.                     Thank you,
  228.                         Eric Hildum
  229.  
  230. procedure find_segments(name)
  231.  
  232.     local msource_file
  233.     static segment_chars
  234.  
  235.     initial segment_chars := &ucase ++ &lcase ++ '0123456789'
  236.  
  237.     (msource_file := open(name, "r")) | stop("Unable to open: " || name)
  238.  
  239.     while line := read(msource_file) do 
  240. #new
  241.           line ? if (match("*=>") & tab(find("COPY") + 4)) then
  242.                      { 
  243.                      tab(upto(segment_chars)) 
  244.                      suspend tab(many(segment_chars)) \ 1
  245.                      }
  246. #old
  247. #         suspend( line ? (match("*=>"),
  248. #                  tab(find("COPY") + 4) , 
  249. #                  tab(upto(segment_chars)) , 
  250. #                  tab(many(segment_chars))) ) \ 1
  251.                 
  252.     close(msource_file)
  253.  
  254. end
  255.  
  256. From icon-group-request@arizona.edu  Thu Jun  7 10:16:24 1990
  257. Resent-From: icon-group-request@arizona.edu
  258. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  259.     id AA06958; Thu, 7 Jun 90 10:16:24 -0700
  260. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 7 Jun 90 10:18 MST
  261. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA06539; Thu, 7 Jun 90 10:05:11
  262.  -0700
  263. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  264.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  265.  usenet@ucbvax.Berkeley.EDU if you have questions)
  266. Resent-Date: Thu, 7 Jun 90 10:18 MST
  267. Date: 7 Jun 90 17:04:58 GMT
  268. From: swrinde!cs.utexas.edu!uwm.edu!csd4.csd.uwm.edu!corre@ucsd.EDU
  269. Subject: ProIcon Windows
  270. Sender: icon-group-request@arizona.edu
  271. Resent-To: icon-group@cs.arizona.edu
  272. To: icon-group@arizona.edu
  273. Resent-Message-Id: <8298059F78BFA008C6@Arizona.EDU>
  274. Message-Id: <4356@uwm.edu>
  275. Organization: University of Wisconsin-Milwaukee
  276. X-Envelope-To: icon-group@CS.Arizona.EDU
  277. X-Vms-To: icon-group@Arizona.edu
  278. Status: O
  279.  
  280. I should like to say something about a feature of ProIcon windows which can
  281. potentially cause a bug in programs which may go undetected for some time,
  282. and then cause the program to fail at a distance from the causative event,
  283. leaving the user with a cryptic error message.
  284. A window is opened by the function wopen() which assigns an integer to
  285. identify the window, and returns this integer as its value. In this respect
  286. it is not parallel to open() which returns a file value. The window can be
  287. closed with wclose(). This is where the problem arises. If the user closes
  288. the window by clicking on the box, and then the program attempts to close
  289. the window, there is a "hole" in the roster of windows, and the variable to
  290. which the integer is assigned has the same value, but no longer references a
  291. window. This causes an error.
  292. There are several ways in which this can be handled. One is always to attach
  293. windows to files by opening the window as a file. In this case the window is
  294. hidden rather than dismissed, and no error will be caused. But this changes
  295. the rules of the game, and does not permit the user to dismiss the window,
  296. which under some circumstances might be desirable. An alternative solution
  297. is to routinely use wopen() again before using wclose() or indeed before any
  298. window function. If the window is still open, wopen() will simply return an
  299. integer. If it is not, it will give wclose() something to work with. A final
  300. possibility might be to give &error a positive value, changing the error to
  301. a failure. This is not recommended, since &error is meant as a debugging
  302. aid, allowing programs to limp home if errors are encountered. In such cases
  303. the final value of &error should always be checked and adjustments made. At
  304. this point I add a "tangent" which discusses an essentially different issue.
  305.  
  306. Tangent
  307. The TopSpeed Modula-2 Language Tutorial (p. 27) contains a program to
  308. reverse an integer using arithmetic rather than string methods:
  309. ...
  310. BEGIN
  311.   WrStr("Enter number to be reversed: ");
  312.   number := RdCard();
  313.   WrStr("The reversal is: ");
  314.   REPEAT
  315.     WrCard(number MOD 10, 1);
  316.     number := number DIV 10
  317.   UNTIL number = 0;
  318.   WrLn
  319. END
  320. ...
  321.  
  322. I tried entering a non-integer, A79 for example. The program accepted the
  323. bad data gladly, and gave me a garbage answer. I wrote and asked the company
  324. what was the point of the strict typing of RdCard() which on its face will
  325. only read a cardinal number, if it accepts A79? The answer: It's the job of
  326. the programmer to protect against that. A global variable OK is set to FALSE
  327. in such a case. Fine, but who knows about it?
  328. It's curious how the inventor of a language has fanatically strict typing,
  329. stricter than Pascal, and it is subverted by the implementor. Obviously
  330. programmers dislike such strict rules, and call for modification which is
  331. supplied to them. It seems to me that Icon makes a lot more sense. That
  332. program translated into Icon would fail by default. The arithmetic operator
  333. would take care of it. You would have to TELL &error explicitly that you 
  334. wanted the Modula-2 situation to prevail--and that is how &error should be 
  335. used.
  336. --
  337. Alan D. Corre
  338. Department of Hebrew Studies
  339. University of Wisconsin-Milwaukee                     (414) 229-4245
  340. PO Box 413, Milwaukee, WI 53201               corre@csd4.csd.uwm.edu
  341.  
  342. From utah-cs!boulder!ncar.UCAR.EDU!oddjob!sophist.uchicago.edu.goer!zenu!  Thu Jun  7 10:48:31 1990
  343. Received: from utah-cs.UUCP by megaron.cs.arizona.edu (5.61/15) via UUCP
  344.     id AA08732; Thu, 7 Jun 90 10:48:31 -0700
  345. Received: from boulder.UUCP by cs.utah.edu (5.61/utah-2.11-cs)
  346.     id AA19334; Thu, 7 Jun 90 11:48:05 -0600
  347. Received: by boulder.Colorado.EDU (cu-hub.890824)
  348. Received: by ncar.ucar.EDU (5.61/ NCAR Central Post Office 04/10/90)
  349.     id AA25008; Thu, 7 Jun 90 11:47:19 MDT
  350. Received: from tank.uchicago.edu by oddjob.uchicago.edu Thu, 7 Jun 90 12:14:53 CDT
  351. Received: from sophist.uchicago.edu by tank.uchicago.edu Thu, 7 Jun 90 12:16:28 CDT
  352. Return-Path: <goer@zenu.uucp>
  353. Received:  by sophist.uchicago.edu (3.2/UofC3.0)
  354.     id AA25377; Thu, 7 Jun 90 12:12:10 CDT
  355. Received: by sophist.uchicago.edu (smail2.5)
  356.     id AA02103; 7 Jun 90 09:41:42 PDT (Thu)
  357. Subject: yuck!
  358. To: icon-group@arizona.edu
  359. Date: Thu, 7 Jun 90 9:41:42 PDT
  360. X-Mailer: ELM [version 2.2 PL0]
  361. Message-Id: <9006070941.AA02103@sophist.uchicago.edu>
  362. From: utah-cs!boulder!sophist.uchicago.edu!goer (Richard Goerwitz qua goer.)
  363. Status: O
  364.  
  365. From the pathologically-averse-to-explicit-intermediate-variables devil:
  366. Status: O
  367.  
  368. procedure find_segment(name)
  369.     suspend !((open(name,"r") | stop("can't open "||name)) \ 1) ? {
  370.     trim((="*=>", tab(find("COPY")+4), tab(many('\t ')), tab(0)) \ 1)
  371.     }
  372. end
  373.  
  374. From icon-group-request@arizona.edu  Fri Jun  8 20:28:30 1990
  375. Resent-From: icon-group-request@arizona.edu
  376. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  377.     id AA02710; Fri, 8 Jun 90 20:28:30 -0700
  378. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Fri, 8 Jun 90 20:30 MST
  379. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA00704; Fri, 8 Jun 90 20:11:16
  380.  -0700
  381. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  382.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  383.  usenet@ucbvax.Berkeley.EDU if you have questions)
  384. Resent-Date: Fri, 8 Jun 90 20:30 MST
  385. Date: 8 Jun 90 13:38:08 GMT
  386. From: esquire!yost@nyu.EDU
  387. Subject: RE: ProIcon Windows
  388. Sender: icon-group-request@arizona.edu
  389. Resent-To: icon-group@cs.arizona.edu
  390. To: icon-group@arizona.edu
  391. Resent-Message-Id: <8179592BEDDFA01155@Arizona.EDU>
  392. Message-Id: <2064@esquire.UUCP>
  393. Organization: DP&W, New York, NY
  394. X-Envelope-To: icon-group@CS.Arizona.EDU
  395. X-Vms-To: icon-group@Arizona.edu
  396. References: <4356@uwm.edu>
  397. Status: O
  398.  
  399. In article <4356@uwm.edu> corre@csd4.csd.uwm.edu (Alan D Corre) writes:
  400. >If the user closes
  401. >the window by clicking on the box, and then the program attempts to close
  402. >the window, there is a "hole" in the roster of windows, and the variable to
  403. >which the integer is assigned has the same value, but no longer references a
  404. >window. This causes an error.
  405.  
  406. The right way to handle this, I think, is for an icon procedure
  407. to be called when the user clicks the close box.  Which is to say
  408. that opening a window should do more than return an integer; it
  409. should hook some procedures to be called when the user does
  410. certain things to the window.
  411.  
  412.  --dave yost
  413.    yost@dpw.com or uunet!esquire!yost
  414.    Please ignore the From or Reply-To fields above, if different.
  415.  
  416. From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU  Fri Jun 15 23:46:30 1990
  417. Received: from noao.edu by megaron (5.61/15) via SMTP
  418.     id AA07477; Fri, 15 Jun 90 23:46:30 -0700
  419. Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G40)
  420.     id AA06107; Fri, 15 Jun 90 23:46:24 MST; for icon-group@cs.arizona.edu
  421. Received: by ncar.ucar.EDU (5.61/ NCAR Central Post Office 04/10/90)
  422.     id AA18113; Sat, 16 Jun 90 00:46:27 MDT
  423. Received: from tank.uchicago.edu by oddjob.uchicago.edu Sat, 16 Jun 90 01:45:04 -0500
  424. Received: from sophist.uchicago.edu by tank.uchicago.edu Sat, 16 Jun 90 01:46:51 CDT
  425. Return-Path: <goer@zenu.uucp>
  426. Received:  by sophist.uchicago.edu (3.2/UofC3.0)
  427.     id AA07745; Sat, 16 Jun 90 01:42:48 CDT
  428. Received: by sophist.uchicago.edu (smail2.5)
  429.     id AA00360; 15 Jun 90 18:48:16 PDT (Fri)
  430. Subject: local, static, etc.
  431. To: icon-group@arizona.edu
  432. Date: Fri, 15 Jun 90 18:48:16 PDT
  433. X-Mailer: ELM [version 2.2 PL0]
  434. Message-Id: <9006151848.AA00360@sophist.uchicago.edu>
  435. From: goer@sophist.uchicago.edu (Richard Goerwitz)
  436. Status: O
  437.  
  438. Question for those versed in the underlying implementation, and in
  439. the fine points of Icon syntax:
  440.  
  441. Sure, B is local.  But do we call C local or not? -
  442.  
  443. procedure a(A)
  444.     local B
  445.     use A and B to come up with a value, which is assigned to C
  446.     return C
  447. end
  448.  
  449. (Note that Icon programmers normally recognize that return is not
  450. a function, but a keyword in a control structure.  When can we tell
  451. C programmers the news? :-]).
  452.  
  453. The variable C above is local.  Its value is not.  Do I put it with
  454. B?
  455.  
  456. Actually, I have to wonder about A as well.  When the arguments get
  457. popped off the stack, don't they basically get assigned to variables
  458. in the parameter list, as if by a normal assignment?  Is there any
  459. harm in calling A local?  Any reason *not* to?
  460.  
  461. Haven't tested anything out.  Just an idle curiosity....
  462.  
  463. -- 
  464.  
  465.  -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  466.  goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  467.  
  468. From cfcl!rdm@apple.com  Sun Jun 17 20:50:48 1990
  469. Received: from apple.com by megaron (5.61/15) via SMTP
  470.     id AA04946; Sun, 17 Jun 90 20:50:48 -0700
  471. Received: by apple.com (5.61/25-eef)
  472.     id AA17694; Sun, 17 Jun 90 20:42:45 -0700
  473.     for 
  474. Received: by cfcl.uucp id AA00962; Sun, 17 Jun 90 16:35:11 PDT
  475. Date: Sun, 17 Jun 90 16:35:11 PDT
  476. From: cfcl!rdm@apple.com (Rich Morin)
  477. Message-Id: <9006172335.AA00962@cfcl.uucp>
  478. To: icon-group@cs.arizona.edu
  479. Subject: Permuted indices of V8 pro[cg]s
  480. Status: O
  481.  
  482. Here are some simple scripts for generating and printing permuted indices
  483. of the Icon V8 procs and progs.  For non-UNIXoids, I have included some
  484. printable output.  Hope this is useful (despite its non-Icon nature :-)...
  485.  
  486. This is all in the public domain - use it as you wish...
  487. ::::::::::::::
  488. g_index
  489. ::::::::::::::
  490. :
  491. : g_index - generate index of icon pro[cg]s
  492. :
  493. # Usage:    g_index > list
  494. #
  495. # Written by Rich Morin, CFCL, 1990
  496.  
  497. # IPL=/usr/icon/v8/ipl
  498. IPL=/usr/local/src/icon/v8/ipl
  499.  
  500. for type in procs progs; do
  501.   cd $IPL/$type
  502.   for file in *.icn; do
  503.     base=`basename $file .icn`
  504.     expand                            |
  505.     awk '$2 == "Title:"    {
  506.            printf("'$type'/%s %s\n", "'$base'", substr($0, 17))
  507.            exit
  508.         }'                            |
  509.     sed 's@  *@ @g'
  510.   done
  511. done
  512. ::::::::::::::
  513. n_index
  514. ::::::::::::::
  515. :
  516. : n_index - generate nroffed index of Icon pro[cg]s
  517. :
  518. # Usage:    n_index list > list.nr
  519. #
  520. # Written by Rich Morin, CFCL, 1990
  521.  
  522. ptx -r $1                        |
  523. awk '
  524.   BEGIN {
  525.     print ".de hd"
  526.     print "'\''sp 1i"
  527.     print ".."
  528.     print ".de fo"
  529.     print "'\''bp"
  530.     print ".."
  531.     print ".wh 0 hd"
  532.     print ".wh -1i fo"
  533.   }
  534.   { print $0 }
  535. '                            |
  536. nroff -mptx
  537.  
  538. # The nroff output may have backspace sequences in it for bolding.
  539. # These can be removed by something like: sed 's@.^H@@g;s@^H@@g'
  540. ::::::::::::::
  541. t_index
  542. ::::::::::::::
  543. :
  544. : t_index - generate troffed index of Icon pro[cg]s
  545. :
  546. # Usage:    t_index list
  547. #
  548. # Written by Rich Morin, CFCL, 1990
  549.  
  550. ptx -r -t $1                        |
  551. awk '
  552.   BEGIN {
  553.     print ".de hd"
  554.     print "'\''sp 1i"
  555.     print ".."
  556.     print ".de fo"
  557.     print "'\''bp"
  558.     print ".."
  559.     print ".wh 0 hd"
  560.     print ".wh -1i fo"
  561.   }
  562.   { print $0 }
  563. '                            |
  564. troff -Tpsc -mptx                    |
  565. psdit                            |
  566. lpr
  567. ::::::::::::::
  568. nn
  569. ::::::::::::::
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.                              Animal game ................ progs/animal
  577.                              Arrange data into columns .. procs/colmize
  578.                              Arrange data into columns .. progs/colm
  579.             UNIX-like Wild   Card Pattern Matching Function  procs/wildcard
  580.                              Collate and decollate strings  procs/collate
  581.          Huffman decoding.   Compute state transitions for  progs/hufftab
  582.                Utility LZW   Compression and Decompression  progs/press
  583.                denominator   Compute greatest common ..... procs/gcd
  584.                  Iterative   Conjunction Control Operation  procs/allof
  585.      Iterative Conjunction   Control Operation .......... procs/allof
  586.                              Convert binary data ........ procs/bincvt
  587.                              Convert string to Morse code  procs/morse
  588.                Icon "link"   Cross Reference Utility .... progs/ilnkxref
  589.                              Currency formatting procedure  procs/currency
  590.                              Customizable sort procedure  procs/isort
  591.                              Deal bridge hands .......... progs/deal
  592.        LZW Compression and   Decompression Utility ...... progs/press
  593.                              Delaminate file ............ progs/delam
  594.                 characters   Delaminate file using tab .. progs/delamc
  595.                              Desk calculator ............ progs/calc
  596.                 of strings   Diagram character intersections  progs/kross
  597.                              Diff engine ................ procs/dif
  598.                              Display intersection of words  progs/cross
  599.         characters in file   Display representations of . progs/fileprnt
  600.                    problem   Display solutions to n-queens  progs/vnq
  601.                              Encode and decode Icon values  procs/object
  602.                              Entab an Icon program ...... progs/itab
  603.                  Generator   Expression Measurement Program  progs/empg
  604.                   Generate   Farberisms ................. progs/farb
  605.                      lines   Filter out identical adjacent  progs/unique
  606.                       text   Filter to word wrap a range of  progs/format
  607.                              Format and convert numbers . procs/numbers
  608.                              Format columnar data ....... procs/printcol
  609.                              Format mailing labels ...... progs/labels
  610. Wild Card Pattern Matching   Function UNIX-like ......... procs/wildcard
  611.                              Generate Farberisms ........ progs/farb
  612. from context-sensitive grammars   Generate instances of sentences  progs/csgen
  613.              phone numbers   Generate letter combinations for  procs/phoname
  614.                              Generate miscellaneous sequences  procs/gener
  615.                              Generate n-grams ........... procs/ngrams
  616.                              Generate random text ....... progs/monkeys
  617.   sentences from a grammar   Generate randomly selected . progs/rsg
  618. in a context-free language   Generate recognizer for sentences  progs/recgen
  619.                     system   Generate sentences in Lindenmayer  progs/linden
  620.           n-queens problem   Generate solutions to the .. progs/queens
  621.                     system   Generate strings from the MIU  progs/miu
  622. Expression Measurement Program   Generator .................. progs/empg
  623.                              Generic filter skeleton in Icon  progs/filter
  624.                              Hexadecimal conversion ..... procs/hexcvt
  625. Compute state transitions for   Huffman decoding. .......... progs/hufftab
  626.                      Write   Icon code to write input ... progs/iwriter
  627. Procedures to encode and decode   Icon data .................. procs/codeobj
  628.                    Utility   Icon "link" Cross Reference  progs/ilnkxref
  629.                  Interpret   Icon literal escapes ....... procs/escape
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.                  Summarize   Icon memory management ..... progs/memsum
  643.                              Icon preprocessor .......... progs/ipp
  644.                       Sort   Icon procedures ............ progs/ipsort
  645.                      Split   Icon program into separate files  progs/ipsplit
  646.                      Print   Icon program ............... progs/iprint
  647. Produce cross reference for   Icon program ............... progs/ipxref
  648.                   Entab an   Icon program ............... progs/itab
  649. Generic filter skeleton in   Icon ....................... progs/filter
  650. of different syntactic forms in   Icon Instances ............. progs/proto
  651.    Produce string image of   Icon result sequence ....... procs/seqimage
  652. to find undeclared variables in   Icon source program. Utility  progs/iundecl
  653.           Show snapshot of   Icon string scanning ....... procs/snapshot
  654. Produce generalized image of   Icon value ................. procs/image
  655.          Encode and decode   Icon values ................ procs/object
  656.              forms in Icon   Instances of different syntactic  progs/proto
  657.                              Interpret Icon literal escapes  procs/escape
  658.                  Operation   Iterative Conjunction Control  procs/allof
  659.                    Utility   LZW Compression and Decompression  progs/press
  660.                    Process   LaTeX .idx file ............ progs/latexidx
  661.                              Laminate files ............. progs/lam
  662.                              Large integer arithmetic ... procs/largint
  663.                              Letter patterns in words ... procs/patword
  664.      Generate sentences in   Lindenmayer system ......... progs/linden
  665.                              Lisp interpreter ........... progs/lisp
  666.              roff document   List commands and macros in a  progs/roffcmds
  667.                              List different words ....... progs/diffword
  668.  Generate strings from the   MIU system ................. progs/miu
  669.                              Map list elements .......... procs/lmap
  670.             representation   Map string into bit ........ procs/mapbit
  671. UNIX-like Wild Card Pattern   Matching Function .......... procs/wildcard
  672.                 Expression   Measurement Program Generator  progs/empg
  673.          Convert string to   Morse code ................. procs/morse
  674. Iterative Conjunction Control   Operation .................. procs/allof
  675.                              Package multiple files ..... progs/pack
  676.                              Parse arithmetic expressions  progs/parsex
  677.                              Parse file names ........... procs/filename
  678.                              Parse simple statements .... progs/parse
  679.        UNIX-like Wild Card   Pattern Matching Function .. procs/wildcard
  680.                    SNOBOL4   Pattern matching in the style of  procs/patterns
  681.                    numbers   Perform arithmetic on rational  procs/rational
  682.                              Perform complex arithmetic . procs/complex
  683.                              Perform mathematical computations  procs/math
  684.                       such   Permutations, combinations, and  procs/permute
  685.                              Play kriegspiel ............ progs/krieg
  686.                              Play the game of solitaire . progs/solit
  687.                              Print Icon program ......... progs/iprint
  688.                              Printf-style formatting .... procs/printf
  689.          underscoring test   Procedures for enboldening and  procs/bold
  690.                  Icon data   Procedures to encode and decode  procs/codeobj
  691.                              Process LaTeX .idx file .... progs/latexidx
  692.                              Process n-tuples ........... procs/tuple
  693.              specification   Produce complement of file . progs/gcomp
  694.                              Produce concordance ........ progs/concord
  695.                    program   Produce cross reference for Icon  progs/ipxref
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.                      value   Produce generalized image of Icon  procs/image
  709.                              Produce keywords in context  progs/kwic
  710.                       file   Produce load map of UNIX obect  progs/loadmap
  711. parenthesis-balanced strings   Produce random ............. progs/parens
  712.                              Produce script for the ed editor  progs/edscript
  713.            result sequence   Produce string image of Icon  procs/seqimage
  714.            structured data   Produces complete image of . procs/fullimag
  715.            structured data   Produces "executable" image of  procs/ximage
  716.     Expression Measurement   Program Generator .......... progs/empg
  717.                 operations   Programmer-defined control ... procs/pdco
  718.                 evaluation   Programmer-defined argument  procs/pdae
  719.                              Quote word for shells ...... procs/shquote
  720.                              Radix conversion ........... procs/radcon
  721.          Icon "link" Cross   Reference Utility .......... progs/ilnkxref
  722. Pattern matching in the style of   SNOBOL4 .................... procs/patterns
  723.                              Segment string ............. procs/segment
  724.                              Service procedures ......... procs/usage
  725.                              Show differences files ..... progs/diffn
  726.                   scanning   Show snapshot of Icon string  procs/snapshot
  727.                              Shuffle lines in a file .... progs/shuffile
  728.                              Shuffle values ............. procs/shuffle
  729.                              Simulate a Turing machine .. progs/turing
  730.                              Sort Icon procedures ....... progs/ipsort
  731.                              Sort groups of lines ....... progs/grpsort
  732.                              Sort mailing labels by ZIP code  progs/zipsort
  733.                      files   Split Icon program into separate  progs/ipsplit
  734.                              String utilities ........... procs/strings
  735.                              Structure operations ....... procs/structs
  736.                              Summarize Icon memory management  progs/memsum
  737.                              Tabulate characters in a file  progs/tablc
  738.                              Tabulate properties of text file  progs/textcnt
  739.                              Tabulate words in a file ... progs/tablw
  740.                              Trim lines in a file ....... progs/trim
  741.                 Simulate a   Turing machine ............. progs/turing
  742.        Produce load map of   UNIX obect file ............ progs/loadmap
  743.          Matching Function   UNIX-like Wild Card Pattern  procs/wildcard
  744.                              Unpackage files ............ progs/unpack
  745. Icon "link" Cross Reference   Utility .................... progs/ilnkxref
  746. LZW Compression and Decompression   Utility .................... progs/press
  747.  variables in Icon source/   Utility to find undeclared . progs/iundecl
  748.         Function UNIX-like   Wild Card Pattern Matching . procs/wildcard
  749.                    write()   Wrap lines of output for use with  procs/wrap
  750.                              Write Icon code to write input  progs/iwriter
  751.            standard output   Write a character ruler to . progs/ruler
  752.     Sort mailing labels by   ZIP code ................... progs/zipsort
  753.       Filter out identical   adjacent lines ............. progs/unique
  754.         Programmer-defined   argument evaluation ........ procs/pdae
  755.                      Parse   arithmetic expressions ..... progs/parsex
  756.                    Perform   arithmetic on rational numbers  procs/rational
  757.            Perform complex   arithmetic ................. procs/complex
  758.              Large integer   arithmetic ................. procs/largint
  759.                    Convert   binary data ................ procs/bincvt
  760.            Map string into   bit representation ......... procs/mapbit
  761.                       Deal   bridge hands ............... progs/deal
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.                       Desk   calculator ................. progs/calc
  775.            strings Diagram   character intersections of . progs/kross
  776.             output Write a   character ruler to standard  progs/ruler
  777.                   Tabulate   characters in a file ....... progs/tablc
  778. Display representations of   characters in file ......... progs/fileprnt
  779.  Delaminate file using tab   characters ................. progs/delamc
  780.           Compute greatest   cmmon denominator .......... procs/gcd
  781.                     Format   columnar data .............. procs/printcol
  782.          Arrange data into   columns .................... procs/colmize
  783.          Arrange data into   columns .................... progs/colm
  784.              Permutations,   combinations, and such ..... procs/permute
  785.            Generate letter   combinations for phone numbers  procs/phoname
  786.                        Get   command-line options ....... procs/options
  787.              document List   commands and macros in a roff  progs/roffcmds
  788.                    Produce   complement of file specification  progs/gcomp
  789.                   Produces   complete image of structured data  procs/fullimag
  790.                    Perform   complex arithmetic ......... procs/complex
  791.       Perform mathematical   computations ............... procs/math
  792.                    Produce   concordance ................ progs/concord
  793.        Produce keywords in   context .................... progs/kwic
  794. recognizer for sentences in a   context-free language Generate  progs/recgen
  795. /instances of sentences from   context-sensitive grammars . progs/csgen
  796.         Programmer-defined   control operations ......... procs/pdco
  797.                Hexadecimal   conversion ................. procs/hexcvt
  798.                      Radix   conversion ................. procs/radcon
  799.                 Format and   convert numbers ............ procs/numbers
  800.                    Produce   cross reference for Icon program  progs/ipxref
  801.                    Arrange   data into columns .......... procs/colmize
  802.                    Arrange   data into columns .......... progs/colm
  803.             Convert binary   data ....................... procs/bincvt
  804.  to encode and decode Icon   data Procedures ............ procs/codeobj
  805. complete image of structured   data Produces .............. procs/fullimag
  806.            Format columnar   data ....................... procs/printcol
  807.        image of structured   data Produces "executable" . procs/ximage
  808.   Procedures to encode and   decode Icon data ........... procs/codeobj
  809.                 Encode and   decode Icon values ......... procs/object
  810. state transitions for Huffman   decoding. Compute ......... progs/hufftab
  811.                Collate and   decollate strings .......... procs/collate
  812.     Compute greatest cmmon   denominator ................ procs/gcd
  813.                       Show   differences files .......... progs/diffn
  814.               Instances of   different syntactic forms in Icon  progs/proto
  815.                       List   different words ............ progs/diffword
  816. commands and macros in a roff   document List .............. progs/roffcmds
  817.     Produce script for the   ed editor .................. progs/edscript
  818.  Produce script for the ed   editor ..................... progs/edscript
  819.                   Map list   elements ................... procs/lmap
  820.             Procedures for   enboldening and underscoring test  procs/bold
  821.              Procedures to   encode and decode Icon data  procs/codeobj
  822.                       Diff   engine ..................... procs/dif
  823.     Interpret Icon literal   escapes .................... procs/escape
  824. Programmer-defined argument   evaluation ................. procs/pdae
  825.   structured data Produces   "executable" image of ...... procs/ximage
  826.           Parse arithmetic   expressions ................ progs/parsex
  827.                      Parse   file names ................. procs/filename
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.                 Delaminate   file ....................... progs/delam
  841. representations of characters in   file Display ............... progs/fileprnt
  842.         Process LaTeX .idx   file ....................... progs/latexidx
  843. Produce load map of UNIX obect   file ....................... progs/loadmap
  844.         Shuffle lines in a   file ....................... progs/shuffile
  845.   Tabulate characters in a   file ....................... progs/tablc
  846.        Tabulate words in a   file ....................... progs/tablw
  847. Tabulate properties of text   file ....................... progs/textcnt
  848.            Trim lines in a   file ....................... progs/trim
  849.      Produce complement of   file specification ......... progs/gcomp
  850.                 Delaminate   file using tab characters .. progs/delamc
  851.           Show differences   files ...................... progs/diffn
  852. Split Icon program into separate   files ...................... progs/ipsplit
  853.                   Laminate   files ...................... progs/lam
  854.           Package multiple   files ...................... progs/pack
  855.                  Unpackage   files ...................... progs/unpack
  856.                    Generic   filter skeleton in Icon .... progs/filter
  857. source program. Utility to   find undeclared variables in Icon  progs/iundecl
  858.                   Currency   formatting procedure ....... procs/currency
  859.               Printf-style   formatting ................. procs/printf
  860. Instances of different syntactic   forms in Icon .............. progs/proto
  861.                   Play the   game of solitaire .......... progs/solit
  862.                     Animal   game ....................... progs/animal
  863.                    Produce   generalized image of Icon value  procs/image
  864.  selected sentences from a   grammar Generate randomly .. progs/rsg
  865. sentences from context-sensitive   grammars Generate instances of  progs/csgen
  866.                    Compute   greatest cmmon denominator . procs/gcd
  867.                       Sort   groups of lines ............ progs/grpsort
  868.                Deal bridge   hands ...................... progs/deal
  869.                 Filter out   identical adjacent lines ... progs/unique
  870.              Process LaTeX   .idx file .................. progs/latexidx
  871.             Produce string   image of Icon result sequence  procs/seqimage
  872.        Produce generalized   image of Icon value ........ procs/image
  873.          Produces complete   image of structured data ... procs/fullimag
  874.      Produces "executable"   image of structured data ... procs/ximage
  875.   Write Icon code to write   input ...................... progs/iwriter
  876. context-sensitive/ Generate   instances of sentences from  progs/csgen
  877.                      Large   integer arithmetic ......... procs/largint
  878.                       Lisp   interpreter ................ progs/lisp
  879.                    Display   intersection of words ...... progs/cross
  880.          Diagram character   intersections of strings ... progs/kross
  881.                    Produce   keywords in context ........ progs/kwic
  882.                       Play   kriegspiel ................. progs/krieg
  883.               Sort mailing   labels by ZIP code ......... progs/zipsort
  884.             Format mailing   labels ..................... progs/labels
  885. for sentences in a context-free   language Generate recognizer  progs/recgen
  886.           numbers Generate   letter combinations for phone  procs/phoname
  887.                    Shuffle   lines in a file ............ progs/shuffile
  888.                       Trim   lines in a file ............ progs/trim
  889.               write() Wrap   lines of output for use with  procs/wrap
  890.             Sort groups of   lines ...................... progs/grpsort
  891. Filter out identical adjacent   lines ...................... progs/unique
  892.                       Icon   "link" Cross Reference Utility  progs/ilnkxref
  893.                        Map   list elements .............. procs/lmap
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.             Interpret Icon   literal escapes ............ procs/escape
  907.                    Produce   load map of UNIX obect file  progs/loadmap
  908.          Simulate a Turing   machine .................... progs/turing
  909.          List commands and   macros in a roff document .. progs/roffcmds
  910.                       Sort   mailing labels by ZIP code . progs/zipsort
  911.                     Format   mailing labels ............. progs/labels
  912.      Summarize Icon memory   management ................. progs/memsum
  913.               Produce load   map of UNIX obect file ..... progs/loadmap
  914.                    Pattern   matching in the style of SNOBOL4  procs/patterns
  915.                    Perform   mathematical computations .. procs/math
  916.             Summarize Icon   memory management .......... progs/memsum
  917.                   Generate   miscellaneous sequences .... procs/gener
  918.                    Package   multiple files ............. progs/pack
  919.                 Parse file   names ...................... procs/filename
  920.                   Generate   n-grams .................... procs/ngrams
  921.  Generate solutions to the   n-queens problem ........... progs/queens
  922.       Display solutions to   n-queens problem ........... progs/vnq
  923.                    Process   n-tuples ................... procs/tuple
  924.         Format and convert   numbers .................... procs/numbers
  925. letter combinations for phone   numbers Generate ........... procs/phoname
  926. Perform arithmetic on rational   numbers .................... procs/rational
  927.   Produce load map of UNIX   obect file ................. progs/loadmap
  928. Programmer-defined control   operations ................. procs/pdco
  929.                  Structure   operations ................. procs/structs
  930.           Get command-line   options .................... procs/options
  931.              Wrap lines of   output for use with write()  procs/wrap
  932. a character ruler to standard   output Write ............... progs/ruler
  933.             Produce random   parenthesis-balanced strings  progs/parens
  934.                     Letter   patterns in words .......... procs/patword
  935. Generate letter combinations for   phone numbers .............. procs/phoname
  936.                       Icon   preprocessor ............... progs/ipp
  937.  solutions to the n-queens   problem Generate ........... progs/queens
  938. Display solutions to n-queens   problem .................... progs/vnq
  939.        Currency formatting   procedure .................. procs/currency
  940.          Customizable sort   procedure .................. procs/isort
  941.                    Service   procedures ................. procs/usage
  942.                  Sort Icon   procedures ................. progs/ipsort
  943.                 Split Icon   program into separate files  progs/ipsplit
  944.                 Print Icon   program .................... progs/iprint
  945. Produce cross reference for Icon   program .................... progs/ipxref
  946.              Entab an Icon   program .................... progs/itab
  947.   variables in Icon source   program. /to find undeclared  progs/iundecl
  948.                   Tabulate   properties of text file .... progs/textcnt
  949.            strings Produce   random parenthesis-balanced  progs/parens
  950.                   Generate   random text ................ progs/monkeys
  951.         a grammar Generate   randomly selected sentences from  progs/rsg
  952.      Filter to word wrap a   range of text .............. progs/format
  953.      Perform arithmetic on   rational numbers ........... procs/rational
  954. context-free language Generate   recognizer for sentences in a  progs/recgen
  955.              Produce cross   reference for Icon program . progs/ipxref
  956.        Map string into bit   representation ............. procs/mapbit
  957.               file Display   representations of characters in  progs/fileprnt
  958. Produce string image of Icon   result sequence ............ procs/seqimage
  959. List commands and macros in a   roff document .............. progs/roffcmds
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.          Write a character   ruler to standard output ... progs/ruler
  973. Show snapshot of Icon string   scanning ................... procs/snapshot
  974.                    Produce   script for the ed editor ... progs/edscript
  975.          Generate randomly   selected sentences from a grammar  progs/rsg
  976. Generate randomly selected   sentences from a grammar ... progs/rsg
  977. grammars Generate instances of   sentences from context-sensitive  progs/csgen
  978.                   Generate   sentences in Lindenmayer system  progs/linden
  979. language Generate recognizer for   sentences in a context-free  progs/recgen
  980.    Split Icon program into   separate files ............. progs/ipsplit
  981. string image of Icon result   sequence Produce ........... procs/seqimage
  982.     Generate miscellaneous   sequences .................. procs/gener
  983.             Quote word for   shells ..................... procs/shquote
  984.                      Parse   simple statements .......... progs/parse
  985.             Generic filter   skeleton in Icon ........... progs/filter
  986.                       Show   snapshot of Icon string scanning  procs/snapshot
  987.           Play the game of   solitaire .................. progs/solit
  988.                    Display   solutions to n-queens problem  progs/vnq
  989.                   Generate   solutions to the n-queens problem  progs/queens
  990.               Customizable   sort procedure ............. procs/isort
  991. Produce complement of file   specification .............. progs/gcomp
  992. Write a character ruler to   standard output ............ progs/ruler
  993.               Parse simple   statements ................. progs/parse
  994.           sequence Produce   string image of Icon result  procs/seqimage
  995.                        Map   string into bit representation  procs/mapbit
  996.                    Segment   string ..................... procs/segment
  997.      Show snapshot of Icon   string scanning ............ procs/snapshot
  998.                    Convert   string to Morse code ....... procs/morse
  999.                   Generate   strings from the MIU system  progs/miu
  1000.      Collate and decollate   strings .................... procs/collate
  1001. character intersections of   strings Diagram ............ progs/kross
  1002. random parenthesis-balanced   strings Produce ............ progs/parens
  1003. Produces complete image of   structured data ............ procs/fullimag
  1004. Produces "executable" image of   structured data ............ procs/ximage
  1005.    Pattern matching in the   style of SNOBOL4 ........... procs/patterns
  1006.     Instances of different   syntactic forms in Icon .... progs/proto
  1007. Generate sentences in Lindenmayer   system ..................... progs/linden
  1008. Generate strings from the MIU   system ..................... progs/miu
  1009.      Delaminate file using   tab characters ............. progs/delamc
  1010. for enboldening and underscoring   test Procedures ............ procs/bold
  1011.     Tabulate properties of   text file .................. progs/textcnt
  1012. Filter to word wrap a range of   text ....................... progs/format
  1013.            Generate random   text ....................... progs/monkeys
  1014.             Compute state   transitions for Huffman decoding.  progs/hufftab
  1015. source program. Utility to find   undeclared variables in Icon  progs/iundecl
  1016. Procedures for enboldening and   underscoring test .......... procs/bold
  1017.   Wrap lines of output for   use with write() ........... procs/wrap
  1018.            Delaminate file   using tab characters ....... progs/delamc
  1019.                     String   utilities .................. procs/strings
  1020. Produce generalized image of Icon   value ...................... procs/image
  1021.     Encode and decode Icon   values ..................... procs/object
  1022.                    Shuffle   values ..................... procs/shuffle
  1023. Utility to find undeclared   variables in Icon source program.  progs/iundecl
  1024.                      Quote   word for shells ............ procs/shquote
  1025.                  Filter to   word wrap a range of text .. progs/format
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.                   Tabulate   words in a file ............ progs/tablw
  1039.         Letter patterns in   words ...................... procs/patword
  1040.    Display intersection of   words ...................... progs/cross
  1041.             List different   words ...................... progs/diffword
  1042.             Filter to word   wrap a range of text ....... progs/format
  1043.         Write Icon code to   write input ................ progs/iwriter
  1044. Wrap lines of output for use with   write() .................... procs/wrap
  1045.  
  1046. From tenaglia@fps.mcw.edu  Wed Jun 20 07:50:25 1990
  1047. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  1048.     id AA20919; Wed, 20 Jun 90 07:50:25 -0700
  1049. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.3/3.06) with UUCP 
  1050.     id AA06084; Wed, 20 Jun 90 10:18:14 EDT
  1051. Received: by uwm.edu; id AA12108; Wed, 20 Jun 90 08:43:17 -0500
  1052. Message-Id: <9006201343.AA12108@uwm.edu>
  1053. Received: from mis by fps.mcw.edu (DECUS UUCP w/Smail);
  1054.           Wed, 20 Jun 90 08:20:23 CDT
  1055. Received: by mis.mcw.edu (DECUS UUCP w/Smail);
  1056.           Wed, 20 Jun 90 08:11:31 CDT
  1057. Date: Wed, 20 Jun 90 08:11:31 CDT
  1058. From: Chris Tenaglia - 257-8765 <tenaglia@mis.mcw.edu>
  1059. To: icon-group@cs.arizona.edu
  1060. Subject: Generators with tables
  1061. Status: O
  1062.  
  1063. Icon has these wonderful generator things. They work well with strings and
  1064. numbers, and lists, and perhaps even sets. But it doesn't lend itself to
  1065. tables. I wonder if there isn't a better way to generate the contents of
  1066. a table other than sort(). What about some amper variables like &first,
  1067. &next, &prior, &last, and &pointer that one could use to peruse the
  1068. entries and assignments in a table structure. For example :
  1069.  
  1070.                     # initialization
  1071.                     tank := table("")
  1072.                     while line := read() do
  1073.                       {
  1074.                       entry := parse(line,1)
  1075.                       asgn  := parse(line,2)
  1076.                       tank[entry] := asgn
  1077.                       }
  1078.                     # and now the main loop
  1079.                       first_entry := tank[&first]
  1080.                       last_asgn  := member(tank,&last)
  1081.                     repeat               # this code really doesn't do
  1082.                       {                  # anything except illustrate
  1083.                       &pointer := &first              # a possibility
  1084.                       while asgn := tank[&next] do
  1085.                         if asgn == tank[&prior] then handle_dupe()
  1086.                       }
  1087.  
  1088. Perhaps a ?? operator might be envisioned for structure scanning? These
  1089. amper variables could be used like &pos, and &subject. Any ideas? Are these
  1090. concepts compatible with the destiny of icon? Would anyone else think they're
  1091. useful? Hmmm.
  1092.  
  1093. Chris Tenaglia (System Manager)
  1094. Medical College of Wisconsin
  1095. 8701 W. Watertown Plank Rd.
  1096. Milwaukee, WI 53226
  1097. (414)257-8765
  1098. tenaglia@mis.mcw.edu
  1099.  
  1100.  
  1101. From ralph  Wed Jun 20 08:03:47 1990
  1102. Date: Wed, 20 Jun 90 08:03:47 -0700
  1103. From: "Ralph Griswold" <ralph>
  1104. Message-Id: <9006201503.AA21476@megaron.cs.arizona.edu>
  1105. Received: by megaron.cs.arizona.edu (5.61/15)
  1106.     id AA21476; Wed, 20 Jun 90 08:03:47 -0700
  1107. To: icon-group@cs.arizona.edu, tenaglia@mis.mcw.edu
  1108. Subject: Re:  Generators with tables
  1109. In-Reply-To: <9006201343.AA12108@uwm.edu>
  1110. Status: O
  1111.  
  1112. Version 8 of Icon has a generator for tables -- key(T).  It generates
  1113. the keys, and from them you can get to the values, if you wish.
  1114.  
  1115. See pages 74-75 of the second edition of The Icon Programming Language.
  1116.  
  1117.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  1118.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  1119.  
  1120. From esquire!info8!yost@cmcl2.NYU.EDU  Wed Jun 20 09:17:53 1990
  1121. Received: from cmcl2.NYU.EDU (NYU.EDU) by megaron (5.61/15) via SMTP
  1122.     id AA26062; Wed, 20 Jun 90 09:17:53 -0700
  1123. Received: by cmcl2.NYU.EDU (5.61/1.34)
  1124.     id AA09571; Wed, 20 Jun 90 12:19:09 -0400
  1125. Received: from info8 by ESQUIRE.DPW. id aa23235; 20 Jun 90 12:06 EDT
  1126. Received: from localhost by info8. (4.0/SMI-4.0)
  1127.     id AA09048; Wed, 20 Jun 90 12:09:34 EDT
  1128. Message-Id: <9006201609.AA09048@info8.>
  1129. From: yost@DPW.COM (Dave Yost)
  1130. Reply-To: yost@DPW.COM (Dave Yost)
  1131. To: "Ralph Griswold" <ralph@cs.arizona.edu>
  1132. Cc: icon-group@cs.arizona.edu, yost@cmcl2.NYU.EDU
  1133. Subject: Re: Generators with tables 
  1134. In-Reply-To: Your message of Wed, 20 Jun 90 08:03:47 PDT.
  1135.              <9006201503.AA21476@megaron.cs.arizona.edu> 
  1136. Phone: +1 212-266-0796 (Voice Direct Line)
  1137. Fax: +1 212-266-0790
  1138. Organization: Davis Polk & Wardwell
  1139.           1 Chase Manhattan Plaza
  1140.           New York, NY  10005
  1141. Date: Wed, 20 Jun 90 12:09:30 -0400
  1142. Sender: yost@info8.NYU.EDU
  1143. Status: O
  1144.  
  1145. # Version 8 of Icon has a generator for tables -- key(T).  It generates
  1146. # the keys, and from them you can get to the values, if you wish.
  1147.  
  1148. The book doesn't specify the order in which key(T)
  1149. generates the keys.  I assume it is likely not the same
  1150. order you would get from a sort on the table, right?
  1151.  
  1152. While we're on the subject,
  1153.  
  1154. The sort operations on tables generate lists that
  1155. include all the keys and values.  In some (many?)
  1156. circumstances one uses only the values from that sorted
  1157. list.  Wouldn't it be more efficient in those cases if
  1158. there were a table sort operation that generated a list
  1159. of table values only, sorted by key?
  1160.  
  1161.  --dave yost
  1162.    yost@dpw.com or uunet!esquire!yost
  1163.    Please ignore the From or Reply-To fields above, if different.
  1164.  
  1165. From goer@sophist.uchicago.EDU  Wed Jun 20 10:05:46 1990
  1166. Resent-From: goer@sophist.uchicago.EDU
  1167. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1168.     id AA29473; Wed, 20 Jun 90 10:05:46 -0700
  1169. Return-Path: goer@sophist.uchicago.EDU
  1170. Received: from tank.uchicago.edu by Arizona.EDU; Wed, 20 Jun 90 10:07 MST
  1171. Received: from sophist.uchicago.edu by tank.uchicago.edu Wed, 20 Jun 90
  1172.  12:03:25 CDT
  1173. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA12922; Wed, 20 Jun 90
  1174.  11:56:16 CDT
  1175. Resent-Date: Wed, 20 Jun 90 10:07 MST
  1176. Date: Wed, 20 Jun 90 11:56:16 CDT
  1177. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  1178. Subject: followup on tables
  1179. Resent-To: icon-group@cs.arizona.edu
  1180. To: icon-group@arizona.edu
  1181. Resent-Message-Id: <7862590EE75F4009CF@Arizona.EDU>
  1182. Message-Id: <9006201656.AA12922@sophist.uchicago.edu>
  1183. X-Envelope-To: icon-group@CS.Arizona.EDU
  1184. X-Vms-To: icon-group@Arizona.edu
  1185. Status: O
  1186.  
  1187. Dave Yost says:
  1188.  
  1189.     The sort operations on tables generate lists that
  1190.     include all the keys and values.  In some (many?)
  1191.     circumstances one uses only the values from that sorted
  1192.     list.  Wouldn't it be more efficient in those cases if
  1193.     there were a table sort operation that generated a list
  1194.     of table values only, sorted by key?
  1195.  
  1196. I dunno, but Icon seems to be pretty big as it is.  Let's see
  1197. if this can be done using existing facilities.  Hmmm:
  1198.  
  1199. procedure get_values(tbl)
  1200.  
  1201.     # suspends the values of tbl, in order, sorted by the
  1202.     # their respective keys
  1203.  
  1204.     tmp_list := sort(tbl,3)
  1205.     suspend tmp_list[2 to *tmp_list by 2]
  1206.  
  1207. end
  1208.  
  1209. If you want these sorted values in a list, you could say
  1210.  
  1211.     val_list := []
  1212.     every put(val_list,get_values(tbl))
  1213.  
  1214. It's just my personal opinion, but I think that this is easier and
  1215. clearer at it is, without an extra function or operator.  You could
  1216. put a set of little functions like this into a library, and use them
  1217. as if they were built-in.
  1218.  
  1219.  
  1220.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1221.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1222.  
  1223. From icon-group-request@arizona.edu  Wed Jun 20 10:37:51 1990
  1224. Resent-From: icon-group-request@arizona.edu
  1225. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1226.     id AA02600; Wed, 20 Jun 90 10:37:51 -0700
  1227. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Wed, 20 Jun 90 10:39 MST
  1228. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA02376; Wed, 20 Jun 90
  1229.  10:27:20 -0700
  1230. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1231.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1232.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1233. Resent-Date: Wed, 20 Jun 90 10:40 MST
  1234. Date: 20 Jun 90 16:09:40 GMT
  1235. From: midway!sophist!goer@uunet.uu.NET
  1236. Subject: RE: Generators with tables
  1237. Sender: icon-group-request@arizona.edu
  1238. Resent-To: icon-group@cs.arizona.edu
  1239. To: icon-group@arizona.edu
  1240. Resent-Message-Id: <785DDB3506BF400A30@Arizona.EDU>
  1241. Message-Id: <1990Jun20.160940.3058@midway.uchicago.edu>
  1242. Organization: University of Chicago
  1243. X-Envelope-To: icon-group@CS.Arizona.EDU
  1244. X-Vms-To: icon-group@Arizona.edu
  1245. References: <9006201343.AA12108@uwm.edu>
  1246. Status: O
  1247.  
  1248. In article <9006201343.AA12108@uwm.edu> tenaglia@mis.mcw.edu (Chris Tenaglia - 257-8765) writes:
  1249.  
  1250. >Perhaps a ?? operator might be envisioned for structure scanning? These
  1251. >amper variables could be used like &pos, and &subject. Any ideas? Are these
  1252. >concepts compatible with the destiny of icon? Would anyone else think they're
  1253. >useful? Hmmm.
  1254.  
  1255. I don't usually have to scan tables, since any tables I use are usually
  1256. there for dynamic modification and extension, and not for the things one
  1257. normally associates with scanning.  HOWEVER, there are times when I would
  1258. have liked to do things like "scan" lists and "strings" of integers or
  1259. just bits (say when Huffmon encoding, doing BCD, etc).  I'll bet that, at
  1260. least for lists, it wouldn't be too hard to simulate scanning.
  1261.  
  1262.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1263.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1264.  
  1265. From esquire!info8!yost@cmcl2.NYU.EDU  Wed Jun 20 12:03:43 1990
  1266. Received: from cmcl2.NYU.EDU (NYU.EDU) by megaron (5.61/15) via SMTP
  1267.     id AA11359; Wed, 20 Jun 90 12:03:43 -0700
  1268. Received: by cmcl2.NYU.EDU (5.61/1.34)
  1269.     id AA15697; Wed, 20 Jun 90 15:05:18 -0400
  1270. Received: from info8 by ESQUIRE.DPW. id aa25472; 20 Jun 90 14:12 EDT
  1271. Received: from localhost by info8. (4.0/SMI-4.0)
  1272.     id AA09449; Wed, 20 Jun 90 14:15:49 EDT
  1273. Message-Id: <9006201815.AA09449@info8.>
  1274. From: yost@DPW.COM (Dave Yost)
  1275. Reply-To: yost@DPW.COM (Dave Yost)
  1276. To: griswold@cs.arizona.edu
  1277. Subject: The Image(x,style) ipl proc
  1278. Cc: yost@cmcl2.NYU.EDU, icon-group@cs.arizona.edu
  1279. Phone: +1 212-266-0796 (Voice Direct Line)
  1280. Fax: +1 212-266-0790
  1281. Organization: Davis Polk & Wardwell
  1282.           1 Chase Manhattan Plaza
  1283.           New York, NY  10005
  1284. Date: Wed, 20 Jun 90 14:15:47 -0400
  1285. Sender: yost@info8.NYU.EDU
  1286. Status: O
  1287.  
  1288. I was very pleased and honored to see in the v8 release
  1289. that you adopted my 'style' argument enhancement to the
  1290. Image() procedure (practically without change!), and
  1291. credited me at the top of the file.
  1292.  
  1293. Thank you very much.  You made my day (and maybe week).
  1294.  
  1295. And many thanks for the new updated Icon book.  I
  1296. hope somebody will send out press releases to all the
  1297. periodicals that might write it up.  It's a perfect
  1298. opportunity for some articles to start appearing about
  1299. Icon, one of the "best kept secrets" in software.
  1300.  
  1301.  --dave yost
  1302.    yost@dpw.com or uunet!esquire!yost
  1303.    Please ignore the From or Reply-To fields above, if different.
  1304.  
  1305. From icon-group-request@arizona.edu  Wed Jun 20 12:52:23 1990
  1306. Resent-From: icon-group-request@arizona.edu
  1307. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1308.     id AA14250; Wed, 20 Jun 90 12:52:23 -0700
  1309. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Wed, 20 Jun 90 12:54 MST
  1310. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA11759; Wed, 20 Jun 90
  1311.  12:38:53 -0700
  1312. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1313.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1314.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1315. Resent-Date: Wed, 20 Jun 90 12:54 MST
  1316. Date: 19 Jun 90 22:02:52 GMT
  1317. From: amdahl!ntmtv!hildum@apple.COM
  1318. Subject: Excess paging problem. Bug?
  1319. Sender: icon-group-request@arizona.edu
  1320. Resent-To: icon-group@cs.arizona.edu
  1321. To: icon-group@arizona.edu
  1322. Resent-Message-Id: <784B0DA6369F400B2E@Arizona.EDU>
  1323. Message-Id: <1259@ntmtv.UUCP>
  1324. Organization: Northern Telecom (Mountain View, CA)
  1325. X-Envelope-To: icon-group@CS.Arizona.EDU
  1326. X-Vms-To: icon-group@Arizona.edu
  1327. Status: O
  1328.  
  1329. The following program, when run on my Sun workstation, uses about
  1330. 2.5Mbytes of resident and 7Mbytes of virtual address when the -s
  1331. and -m options are specified. The input file contains two tables, the
  1332. first with ~1300 entries, each a set of ~1.2 elements on average. The
  1333. second table contains ~200 entries, each a set of ~7 elements.
  1334.  
  1335. I have noticed that the coexpression processing takes a long time, and
  1336. that a lot of garbage collection is taking place. The program will
  1337. create and delete ~1500 coexpressions, but they are all the same size.
  1338. What is causing the program to grow to a very large size, and is the
  1339. paging caused by garbage collection when the size is ~7Mbytes?
  1340.  
  1341. Is this a bug in Icon?
  1342.  
  1343. System Sun 3/60, 8Mbytes, SunOS 4.0.3, 68881
  1344. Icon version 8, software checking for 68881 (cc -fswitch)
  1345.  
  1346. #
  1347. #
  1348. #    This program reads two tables which store the dependencies
  1349. #    among source files and segments. One table is a list of 
  1350. #    source file (names) and the segments that are included in
  1351. #    file, the other is a list of segment names and the source
  1352. #    files which include them. It then scans the tables for the
  1353. #    source or segments specified on the command line and 
  1354. #    reports the corresponding segments included or sources
  1355. #    including the source or segment.
  1356. #
  1357. #    Invokation:
  1358. #
  1359. #    msl1depend -d dependencies names [-m] [-s]
  1360. #
  1361. #    where
  1362. #
  1363. #    -d dependencies
  1364. #        the name of the file containing the dependencies
  1365. #        tables.
  1366. #
  1367. #    -m    print all the source files and the segments that
  1368. #        that they contain
  1369. #
  1370. #    -s    print all the segments and the files that contain
  1371. #        them
  1372. #
  1373. #
  1374. #
  1375.  
  1376. link colmize, object, options, usage
  1377.  
  1378. global arguments
  1379.  
  1380. procedure main(parameters)
  1381.  
  1382.     static usage_string
  1383.     local dependencies        # The dependencies table
  1384.     local includes        # The includes table
  1385.     local source_names        # The requested source names
  1386.     local segment_names        # The requested segment names
  1387.     local name 
  1388.     local input_file        # The dependencies data file
  1389.  
  1390.     #
  1391.     #    Set the command description string to describe the command
  1392.     #   and all valid options.
  1393.     #
  1394.     initial {
  1395.     usage_string := "msl1depend " || 
  1396.                 "-d dependenciesfile" ||
  1397.             "names [-m] [-s]"
  1398.     }
  1399.  
  1400.     #
  1401.     #    Test the Icon implementation to ensure that all required
  1402.     #    features are implemented.
  1403.     #
  1404.     Requires("UNIX")
  1405.     Requires("co-expressions")
  1406.     Requires("environment variables")
  1407.  
  1408.     #
  1409.     #    Set the name lists to be empty sets
  1410.     #
  1411.     source_names := set()
  1412.     segment_names := set()
  1413.  
  1414.     #
  1415.     #    Process the command line options, obtaining a table of the
  1416.     #    specified options and a list of parameters.
  1417.     #
  1418.     arguments := options(parameters, "d:ms")
  1419.  
  1420.     #
  1421.     #    Make sure some names will be processed.
  1422.     #
  1423.     if /arguments["m"] & /arguments["s"] & *parameters = 0 then
  1424.     Usage(usage_string)
  1425.  
  1426.     #
  1427.     #    Verify that the dependencies file has been specified and may be
  1428.     #    read.
  1429.     #
  1430.     \arguments["d"] | Usage(usage_string)
  1431.     (input_file := open(arguments["d"], "r")) | stop("Unable to open" || 
  1432.                               arguments["d"])
  1433.     #
  1434.     #    Load the dependencies and includes tables.
  1435.     #
  1436.     dependencies := getobj(input_file)
  1437.     includes := getobj(input_file)
  1438.  
  1439.     #
  1440.     #    Close the input file
  1441.     #
  1442.     close(input_file)
  1443.  
  1444.     #
  1445.     #    Determine the type of name requested, and add it to the 
  1446.     #    appropriate list of names for later processing. If a name
  1447.     #    is not in one of the key lists, then print a message.
  1448.     #
  1449.     every name := lowercase(!parameters) do {
  1450.     if name == key(dependencies) then insert(segment_names, name)
  1451.     else if name == key(includes) then insert(source_names, name)
  1452.     else write("Name ", name, " is not a segment or source name")
  1453.         }
  1454.  
  1455.     #
  1456.     #    Process remaining arguments.
  1457.     #
  1458.     /arguments["m"] | every name := key(includes) do
  1459.                     insert(source_names, name)
  1460.     /arguments["s"] | every name := key(dependencies) do
  1461.                     insert(segment_names, name)
  1462.  
  1463.     #
  1464.     #    Print requested information or stop.
  1465.     #
  1466.     if *source_names = *segment_names = 0 then
  1467.     stop("No valid names have been specified")
  1468.     write()
  1469.     if 0 < *source_names then
  1470.     print_source_includes(sort(source_names), includes)
  1471.     write()
  1472.     if 0 < *segment_names then
  1473.     print_segment_dependencies(sort(segment_names), dependencies)
  1474.  
  1475.     return
  1476. end
  1477.  
  1478.  
  1479. procedure lowercase(name)
  1480.  
  1481.     #
  1482.     #    Convert all the uppercase characters in name to lower case.
  1483.     #
  1484.     return map(name, &ucase, &lcase)
  1485.  
  1486. end
  1487.  
  1488.  
  1489. procedure print_source_includes(names, values)
  1490.  
  1491.     local name
  1492.     local line
  1493.     local tag
  1494.  
  1495.     write("Source      Segments included")
  1496.     write("-----------------------------")
  1497.  
  1498.     every name := !names do {
  1499.     tag := create(left(name, 10) | |repl(" ", 10))
  1500.     if 0 < *values[name] then
  1501.         every line := colmize(sort(values[name]), 70, 2, 10) do
  1502.         write(@tag || line)
  1503.     else
  1504.         write(left(name, 10), "-- does not include any segments --")
  1505.     }
  1506.  
  1507. end
  1508.  
  1509. procedure print_segment_dependencies(names, values)
  1510.  
  1511.     local name
  1512.     local line
  1513.     local tag
  1514.  
  1515.     write("Segment     Msource files including segment")
  1516.     write("-------------------------------------------")
  1517.  
  1518.     every name := !names do {
  1519.     tag := create(left(name, 10) | |repl(" ", 10))
  1520.     if 0 < *values[name] then
  1521.         every line := colmize(sort(values[name]), 70, 2, 10) do
  1522.         write(@tag || line)
  1523.     else
  1524.         write(left(name, 10), "-- is not included in any source --")
  1525.     }
  1526.  
  1527. end
  1528.  
  1529. From ralph  Wed Jun 20 13:01:49 1990
  1530. Date: Wed, 20 Jun 90 13:01:49 -0700
  1531. From: "Ralph Griswold" <ralph>
  1532. Message-Id: <9006202001.AA14789@megaron.cs.arizona.edu>
  1533. Received: by megaron.cs.arizona.edu (5.61/15)
  1534.     id AA14789; Wed, 20 Jun 90 13:01:49 -0700
  1535. To: amdahl!ntmtv!hildum@apple.COM
  1536. Subject: Re:  Excess paging problem. Bug?
  1537. Cc: icon-group
  1538. Status: O
  1539.  
  1540. Without looking closely, I'd suspect your problem is that your program
  1541. is never able to collect any co-expression.  When you create a co-expression,
  1542. it clones a copy of all local variables.  In something like
  1543.  
  1544.     every ... do {
  1545.            tab := create ...
  1546.        }
  1547.  
  1548. the newly created co-expression references the identifier tag, and hence
  1549. the last co-expression.  What you get is a long chain of inaccessible, but
  1550. also uncollectable co-expressions.  The thing to do is
  1551.  
  1552.     every ... do {
  1553.        tab := &null
  1554.        tab := create ...
  1555.        }
  1556.  
  1557. This problem is mentioned in TR 90-1, incidentally, but unless you've
  1558. been bitten by it, you'd probably not think to look for it.
  1559.  
  1560.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  1561.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  1562.  
  1563. From cjeffery  Wed Jun 20 14:59:15 1990
  1564. Resent-From: "Clinton Jeffery" <cjeffery>
  1565. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1566.     id AA20763; Wed, 20 Jun 90 14:59:15 -0700
  1567. Received: from megaron (megaron.cs.Arizona.EDU) by Arizona.EDU; Wed, 20 Jun 90
  1568.  15:01 MST
  1569. Received: from cheltenham.cs.arizona.edu by megaron (5.61/15) via SMTP id
  1570.  AA20745; Wed, 20 Jun 90 14:58:33 -0700
  1571. Received: by cheltenham.cs.arizona.edu; Wed, 20 Jun 90 14:58:31 MST
  1572. Resent-Date: Wed, 20 Jun 90 15:01 MST
  1573. Date: Wed, 20 Jun 90 14:58:31 MST
  1574. From: Clinton Jeffery <cjeffery@cs.arizona.edu>
  1575. Subject: Generators with tables
  1576. Resent-To: icon-group@cs.arizona.edu
  1577. To: midway!sophist!goer@uunet.uu.NET
  1578. Cc: icon-group@arizona.edu
  1579. Resent-Message-Id: <78395BCC2F3F40089D@Arizona.EDU>
  1580. Message-Id: <9006202158.AA22477@cheltenham.cs.arizona.edu>
  1581. In-Reply-To: midway!sophist!goer@uunet.uu.NET's message of 20 Jun 90 16:09:40
  1582.  GMT <1990Jun20.160940.3058@midway.uchicago.edu>
  1583. X-Envelope-To: icon-group@CS.Arizona.EDU
  1584. X-Vms-To: midway!sophist!goer@uunet.uu.NET
  1585. X-Vms-Cc: icon-group@Arizona.edu
  1586. Status: O
  1587.  
  1588. On generalizations of Icon's string scanning, Chris Tenaglia writes:
  1589.   >>Perhaps a ?? operator might be envisioned for structure scanning?
  1590. Richard Goerwitz responds:
  1591.   >I don't usually have to scan tables...HOWEVER, there are times when I would
  1592.   >have liked to do things like "scan" lists and "strings" of integers or
  1593.   >just bits (say when Huffmon encoding, doing BCD, etc).  I'll bet that, at
  1594.   >least for lists, it wouldn't be too hard to simulate scanning.
  1595.  
  1596. I don't have a complete implementation for you, but one approach to list
  1597. scanning is suggested in the technical report on Idol, present in the
  1598. Version 8 Icon Program Library.  If anyone extends my class ListScan to
  1599. the point where it is generally useful, I'd appreciate a copy.  List
  1600. scanning is a good example of where Idol can be useful to regular Icon
  1601. programmers who want nothing to do with "object-oriented programming".
  1602.  
  1603. From goer@sophist.uchicago.EDU  Thu Jun 21 10:15:24 1990
  1604. Resent-From: goer@sophist.uchicago.EDU
  1605. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1606.     id AA02553; Thu, 21 Jun 90 10:15:24 -0700
  1607. Return-Path: goer@sophist.uchicago.EDU
  1608. Received: from tank.uchicago.edu by Arizona.EDU; Thu, 21 Jun 90 10:17 MST
  1609. Received: from sophist.uchicago.edu by tank.uchicago.edu Thu, 21 Jun 90
  1610.  12:16:19 CDT
  1611. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA14288; Thu, 21 Jun 90
  1612.  12:12:30 CDT
  1613. Resent-Date: Thu, 21 Jun 90 10:17 MST
  1614. Date: Thu, 21 Jun 90 12:12:30 CDT
  1615. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  1616. Subject: list manipulation
  1617. Resent-To: icon-group@cs.arizona.edu
  1618. To: icon-group@arizona.edu
  1619. Resent-Message-Id: <7797DB36ED7F401056@Arizona.EDU>
  1620. Message-Id: <9006211712.AA14288@sophist.uchicago.edu>
  1621. X-Envelope-To: icon-group@CS.Arizona.EDU
  1622. X-Vms-To: icon-group@Arizona.edu
  1623. Status: O
  1624.  
  1625.  
  1626. Short question for anyone (not just experts):
  1627.  
  1628. What is the most facile way of moving an element from one position
  1629. to another in a list?  Suppose I have ["a","b","c"], and I want
  1630. ["a","c","b"].  Does anyone have any suggestions as to how this
  1631. sort of manipulation might be done in Icon (in a generalized man-
  1632. ner), short of
  1633.  
  1634.     lst := lst[1:i-1] ||| lst[i+1:0] ||| lst[i-1:i+1]
  1635.  
  1636. That looks terrible, and slow to boot.
  1637.  
  1638.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1639.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1640.  
  1641. From ralph  Thu Jun 21 10:30:35 1990
  1642. Date: Thu, 21 Jun 90 10:30:35 -0700
  1643. From: "Ralph Griswold" <ralph>
  1644. Message-Id: <9006211730.AA03365@megaron.cs.arizona.edu>
  1645. Received: by megaron.cs.arizona.edu (5.61/15)
  1646.     id AA03365; Thu, 21 Jun 90 10:30:35 -0700
  1647. To: goer@sophist.uchicago.EDU
  1648. Subject: Re:  list manipulation
  1649. Cc: icon-group
  1650. In-Reply-To: <9006211712.AA14288@sophist.uchicago.edu>
  1651. Status: O
  1652.  
  1653. Try
  1654.  
  1655.     L[i] :=: L[j]
  1656.  
  1657.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  1658.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  1659.  
  1660. From ralph  Thu Jun 21 10:58:14 1990
  1661. Date: Thu, 21 Jun 90 10:58:14 -0700
  1662. From: "Ralph Griswold" <ralph>
  1663. Message-Id: <9006211758.AA05465@megaron.cs.arizona.edu>
  1664. Received: by megaron.cs.arizona.edu (5.61/15)
  1665.     id AA05465; Thu, 21 Jun 90 10:58:14 -0700
  1666. To: icon-group
  1667. Subject: rearranging list elements
  1668. Status: O
  1669.  
  1670.  
  1671. For a general way to *rearrange* the elements in a list, see lmap.icn
  1672. in Version 8 of the Icon program library and the portion of the Icon
  1673. language book that deals with transpositions.
  1674.  
  1675. (This method is overbearing unless you want to do the same rearrangement
  1676. on several lists.)
  1677.  
  1678.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  1679.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  1680.  
  1681. From R@edinburgh.ac.uk  Fri Jun 22 09:06:46 1990
  1682. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1683.     id AA01873; Fri, 22 Jun 90 09:06:46 -0700
  1684. Received: from UKACRL.BITNET by Arizona.EDU; Fri, 22 Jun 90 08:06 MST
  1685. Received: from RL.IB by UKACRL.BITNET (Mailer X1.25) with BSMTP id 0850; Fri,
  1686.  22 Jun 90 15:40:45 BST
  1687. Date: 22 Jun 90  15:41:02 bst
  1688. From: R.J.Hare@edinburgh.ac.uk
  1689. Subject: Constant table space
  1690. To: icon-group@cs.arizona.edu
  1691. Message-Id: <22 Jun 90  15:41:02 bst  340301@EMAS-A>
  1692. Via:        UK.AC.ED.EMAS-A; 22 JUN 90 15:40:36 BST
  1693. X-Envelope-To: icon-group@cs.arizona.EDU
  1694. Status: O
  1695.  
  1696. This may be a dumb question...
  1697.  
  1698. I am getting the message "out of constant table space" from an Icon program I
  1699. am trying to run on our Sequent, running Dynix. I can't see anything in the
  1700. Icon book which tells me which environment variable to set to get round this
  1701. problem (if it can be got round at all) can anyone suggest a way round this
  1702. problem please (It is rather a large table...)?
  1703.  
  1704. Thanks.
  1705.  
  1706. Roger Hare.
  1707.  
  1708. From goer@sophist.uchicago.EDU  Fri Jun 22 11:25:56 1990
  1709. Resent-From: goer@sophist.uchicago.EDU
  1710. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  1711.     id AA09538; Fri, 22 Jun 90 11:25:56 -0700
  1712. Return-Path: goer@sophist.uchicago.EDU
  1713. Received: from tank.uchicago.edu by Arizona.EDU; Fri, 22 Jun 90 11:28 MST
  1714. Received: from sophist.uchicago.edu by tank.uchicago.edu Fri, 22 Jun 90
  1715.  13:27:11 CDT
  1716. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA15827; Fri, 22 Jun 90
  1717.  13:23:20 CDT
  1718. Resent-Date: Fri, 22 Jun 90 11:28 MST
  1719. Date: Fri, 22 Jun 90 13:23:20 CDT
  1720. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  1721. Subject: testers
  1722. Resent-To: icon-group@cs.arizona.edu
  1723. To: icon-group@arizona.edu
  1724. Resent-Message-Id: <76C4CACB1F7F40161D@Arizona.EDU>
  1725. Message-Id: <9006221823.AA15827@sophist.uchicago.edu>
  1726. X-Envelope-To: icon-group@CS.Arizona.EDU
  1727. X-Vms-To: icon-group@Arizona.edu
  1728. Status: O
  1729.  
  1730. I'm writing an icon-termlib and windowing library.  The termlib part
  1731. is done (please, no sniping for not using terminfo :-).  I'm now work-
  1732. ing on the windows part.  So far I can create, foreground, delete,
  1733. etc., and I've gotten things so that you can write to any window at
  1734. any time (whether visible or not).  There is no notion of a "current
  1735. window."  My difficulty is that I don't have anything but ANSI-family
  1736. terminals to work with, and so I don't have the opportunity of testing
  1737. anything out on a broad range of platforms.  I'd really appreciate it
  1738. if some kind unix-using soul could test a sample program out on a non-
  1739. ANSI-ish terminal (wyses, vt100s, etc. are all out).  Though the win-
  1740. dowing part is not done, you'll get a fairly well-tested termlib out
  1741. of it (and a warm feeling in your heart :-).  I just want to be sure
  1742. this thing works, such as it is, before going on much farther.  Thanks.
  1743.  
  1744.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1745.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1746.  
  1747. From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU  Wed Jun 27 00:47:35 1990
  1748. Received: from noao.edu by megaron (5.61/15) via SMTP
  1749.     id AA10270; Wed, 27 Jun 90 00:47:35 -0700
  1750. Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G41)
  1751.     id AA29553; Wed, 27 Jun 90 00:47:29 MST; for icon-group@cs.arizona.edu
  1752. Received: by ncar.ucar.EDU (5.61/ NCAR Central Post Office 04/10/90)
  1753.     id AA21602; Wed, 27 Jun 90 01:47:27 MDT
  1754. Received: from tank.uchicago.edu by oddjob.uchicago.edu Wed, 27 Jun 90 01:47:04 -0500
  1755. Received: from sophist.uchicago.edu by tank.uchicago.edu Wed, 27 Jun 90 01:48:47 CDT
  1756. Return-Path: <goer@zenu.uucp>
  1757. Received:  by sophist.uchicago.edu (3.2/UofC3.0)
  1758.     id AA21090; Wed, 27 Jun 90 01:44:52 CDT
  1759. Received: by sophist.uchicago.edu (smail2.5)
  1760.     id AA00415; 26 Jun 90 23:36:49 PDT (Tue)
  1761. Subject: itermlib
  1762. To: icon-group@arizona.edu
  1763. Date: Tue, 26 Jun 90 23:36:48 PDT
  1764. X-Mailer: ELM [version 2.2 PL0]
  1765. Message-Id: <9006262336.AA00415@sophist.uchicago.edu>
  1766. From: goer@sophist.uchicago.edu (Richard Goerwitz)
  1767. Status: O
  1768.  
  1769. I've been asked by several people to post the following software, des-
  1770. pite its preliminary nature.  That's fine with me.  I've been using it
  1771. for a while now, and there are sections of code I just won't ever have
  1772. the opportunity of testing in my current range of computing environ-
  1773. ments.  I can use all the bug reports I can get.
  1774.  
  1775. Sorry about the annoying disclaimer included below.  Some recent con-
  1776. tacts with the legal staff of an outfit using software posted here
  1777. has led me to think it sensible a) to copyright everything, however
  1778. trivial, b) to make absolutely clear the free and unrestricted nature
  1779. of the code, and c) to disclaim any responsibility for anything that
  1780. might occur in conjunction with its (ab)use.
  1781.  
  1782. Note:   Contrary to my usual practices, I've packed this as a shar
  1783. archive.  It's 400 lines of code, too.  If anyone feels that one of
  1784. the source newsgroups might be a better place, please let me know.
  1785.  
  1786.  
  1787.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1788.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1789.  
  1790.  
  1791. #!/bin/sh
  1792. # This is a shell archive (shar 3.24)
  1793. # made 06/27/1990 06:12 UTC by richard@zenu (goer@sophist.uchicago.edu)
  1794. #
  1795. # existing files WILL be overwritten
  1796. # This format requires very little intelligence at unshar time.
  1797. # "echo" and "sed" will be needed.
  1798. #
  1799. # ============= itlib024.icn ==============
  1800. echo "x - extracting itlib024.icn (Text)"
  1801. sed 's/^X//' << 'SHAR_EOF' > itlib024.icn &&
  1802. X########################################################################
  1803. X#    
  1804. X#    Name:    itermlib.icn
  1805. X#    
  1806. X#    Title:    Icon termlib-type tools
  1807. X#    
  1808. X#    Author:    Richard L. Goerwitz
  1809. X#
  1810. X#    Date:    June 19, 1990 (version 0.24 - beta test)
  1811. X#
  1812. X########################################################################
  1813. X#
  1814. X#  Copyright (c) 1990, Richard L. Goerwitz, III
  1815. X#
  1816. X#  This software is intended for free and unrestricted distribution.
  1817. X#  I place only two conditions on its use:  1) That you clearly mark
  1818. X#  any additions or changes you make to the source code, and 2) that
  1819. X#  you do not delete this message therefrom.  In order to protect
  1820. X#  myself from spurious litigation, it must also be stated here that,
  1821. X#  because this is free software, I, Richard Goerwitz, make no claim
  1822. X#  about the applicability or fitness of this software for any
  1823. X#  purpose, and expressly disclaim any responsibility for any damages
  1824. X#  that might be incurred in conjunction with its use.
  1825. X#
  1826. X########################################################################
  1827. X#
  1828. X#  The following library represents a series of rough functional
  1829. X#  equivalents to the standard Unix low-level termcap routines.  They
  1830. X#  are not meant as exact termlib clones.  Nor are they enhanced to
  1831. X#  take care of magic cookie terminals, terminals that use \D in their
  1832. X#  termcap entries, or, in short, anything I felt would not affect my
  1833. X#  work.  If anyone enhances these routines, I'd deeply appreciate it
  1834. X#  if they would share their changes with me and/or the rest of the
  1835. X#  Icon community.
  1836. X#
  1837. X#  Requires:  A unix platform & co-expressions.  Certainly the
  1838. X#  package could be altered for use with MS-DOS and other systems.
  1839. X#  Please contact me if advice on how to do this is needed.
  1840. X#
  1841. X#  setname(term)
  1842. X#    Use only if you wish to initialize itermlib for a terminal
  1843. X#  other than what your current environment specifies.  "Term" is the
  1844. X#  name of the termcap entry to use.  Normally this initialization is
  1845. X#  done automatically, and need not concern the user.
  1846. X#
  1847. X#  getval(id)
  1848. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  1849. X#  spirit of Icon, all three have been collapsed into one routine.
  1850. X#  Integer valued caps are returned as integers, strings as strings,
  1851. X#  and flags as records (if a flag is set, then type(id) will return
  1852. X#  "true").  Absence of a given capability is signalled by procedure
  1853. X#  failure.
  1854. X#
  1855. X#  igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)!
  1856. X#    Analogous to tgoto.  Make "cm" the cursor movement command for
  1857. X#  the current terminal, as obtained via getval("cm").  Igoto()
  1858. X#  returns a string which, when output via iputs, will cause the
  1859. X#  cursor to move to column "destcol" and line "destline."  Column and
  1860. X#  line are always calculated using a *one* offset.  This is far more
  1861. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  1862. X#  go to the first square on your screen, then input
  1863. X#  "igoto(getval("cm"),1,1).
  1864. X#
  1865. X#  iputs(cp,affcnt)
  1866. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  1867. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  1868. X#  count of affected lines.  It is only relevant for terminals which
  1869. X#  specify proportional (starred) delays in their termcap entries.
  1870. X#
  1871. X##########################################################################
  1872. X
  1873. X
  1874. Xglobal tc_table, tty_speed
  1875. Xrecord true()
  1876. X
  1877. X
  1878. Xprocedure check_features()
  1879. X
  1880. X    local in_params, yes_tabs, line
  1881. X    # global tty_speed
  1882. X
  1883. X    initial {
  1884. X    find("unix",map(&features)) |
  1885. X        er("check_features","unix system required",1)
  1886. X    find("o-expres",&features) |
  1887. X        er("check_features","co-expressions not implemented - &$#!",1)
  1888. X    system("/bin/stty tabs") |
  1889. X        er("check_features","can't set tabs option",1)
  1890. X    }
  1891. X
  1892. X    # clumsy, clumsy, clumsy, and probably won't work on all systems
  1893. X    in_params := open("/bin/stty 2>&1","pr") | 
  1894. X    (ospeed := &null, fail)
  1895. X    every line := !in_params do {
  1896. X    yes_tabs := find("tabs",line) #unused
  1897. X    line ? {
  1898. X        tty_speed := (tab(find("speed")+5), tab(many(' ')),
  1899. X               integer(tab(many(&digits))))
  1900. X    }
  1901. X    }
  1902. X    close(in_params)
  1903. X    return "term characteristics reset; features check out"
  1904. X
  1905. Xend
  1906. X
  1907. X
  1908. X
  1909. Xprocedure setname(name)
  1910. X
  1911. X    # Sets current terminal type to "name" and builds a new termcap
  1912. X    # capability database (residing in tc_table).  Fails if unable to
  1913. X    # find a termcap entry for terminal type "name."  If you want it
  1914. X    # to terminate with an error message under these circumstances,
  1915. X    # comment out "| fail" below, and uncomment the er() line.
  1916. X
  1917. X    #tc_table is global
  1918. X    
  1919. X    check_features()
  1920. X
  1921. X    tc_table := maketc_table(getentry(name)) | fail
  1922. X    # er("setname","no termcap entry found for "||name,3)
  1923. X    return "successfully reset for terminal " || name
  1924. X
  1925. Xend
  1926. X
  1927. X
  1928. X
  1929. Xprocedure getname()
  1930. X
  1931. X    # Getname() first checks to be sure we're running under Unix, and,
  1932. X    # if so, tries to figure out what the current terminal type is,
  1933. X    # checking successively the value of the environment variable
  1934. X    # TERM, and then the output of "tset -".  Terminates with an error
  1935. X    # message if the terminal type cannot be ascertained.
  1936. X
  1937. X    local term, tset_output
  1938. X
  1939. X    check_features()
  1940. X
  1941. X    if not (term := getenv("TERM")) then {
  1942. X    tset_output := open("/bin/tset -","pr") |
  1943. X        er("getname","can't find tset command",1)
  1944. X    term := !tset_output
  1945. X    close(tset_output)
  1946. X    }
  1947. X    return \term |
  1948. X    er("getname","can't seem to determine your terminal type",1)
  1949. X
  1950. Xend
  1951. X
  1952. X
  1953. X
  1954. Xprocedure er(func,msg,errnum)
  1955. X
  1956. X    # short error processing utility
  1957. X    write(&errout,func,":  ",msg)
  1958. X    exit(errnum)
  1959. X
  1960. Xend
  1961. X
  1962. X
  1963. X
  1964. Xprocedure getentry(name)
  1965. X
  1966. X    # "Name" designates the current terminal type.  Getentry() scans
  1967. X    # the current environment for the variable TERMCAP.  If the
  1968. X    # TERMCAP string represents a termcap entry for a terminal of type
  1969. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  1970. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  1971. X    # getentry() will scan that file for an entry corresponding to
  1972. X    # "name."  If the TERMCAP string does not designate a filename,
  1973. X    # getentry() will scan /etc/termcap for the correct entry.
  1974. X    # Whatever the input file, if an entry for terminal "name" is
  1975. X    # found, getentry() returns that entry.  Otherwise, getentry()
  1976. X    # fails.
  1977. X
  1978. X    local termcap_string, f, getline, line
  1979. X
  1980. X    termcap_string := getenv("TERMCAP")
  1981. X
  1982. X    if termcap_string ?    (not match("/"), pos(0) | tab(find("|")+1), =name)
  1983. X    then return termcap_string
  1984. X    else {
  1985. X
  1986. X    if find("/",termcap_string)
  1987. X    then f := open(termcap_string)
  1988. X    /f := open("/etc/termcap") |
  1989. X        er("getentry","I can't access your /etc/termcap file",1)
  1990. X
  1991. X    getline := create read_file(f)
  1992. X    
  1993. X    while line := @getline do {
  1994. X        if line ? (pos(0) | tab(find("|")+1), =name) then {
  1995. X        entry := ""
  1996. X        while (\line | @getline) ? {
  1997. X            if not (entry ||:= 1(tab(find("\\")), pos(-1)))
  1998. X            then close(f) & (return entry || &subject)
  1999. X            \line := &null
  2000. X        }
  2001. X        }
  2002. X    }
  2003. X    }
  2004. X
  2005. X    close(f)
  2006. X    fail
  2007. Xend
  2008. X
  2009. X
  2010. X
  2011. Xprocedure read_file(fname)
  2012. X
  2013. X    # Suspends all non #-initial lines in the file named "fname."
  2014. X    # Removes leading tabs and spaces from lines before suspending
  2015. X    # them.
  2016. X
  2017. X    local intext, line
  2018. X
  2019. X    intext := open(fname) |
  2020. X    er("read_tcap_file","can't open "||fname,3)
  2021. X    while line := read(intext) do {
  2022. X    match("#",line) & next
  2023. X    suspend line ? (tab(many('\t ')), tab(0)) 
  2024. X    }
  2025. X
  2026. X    close(intext)
  2027. X    fail
  2028. X
  2029. Xend
  2030. X
  2031. X
  2032. X
  2033. Xprocedure maketc_table(entry)
  2034. X
  2035. X    # Maketc_table(s) (where s is a valid termcap entry for some
  2036. X    # terminal-type): Returns a table in which the keys are termcap
  2037. X    # capability designators, and the values are the entries in
  2038. X    # "entry" for those designators.
  2039. X
  2040. X    local k, v
  2041. X    
  2042. X    tc_table := table()
  2043. X    entry ? {
  2044. X
  2045. X    tab(find(":")+1)    # tab past initial (name) field
  2046. X    while tab(find(":")+1) ? {
  2047. X
  2048. X        if k := 1(move(2), ="=")
  2049. X        then insert(tc_table, k, decode(tab(find(":"))))
  2050. X        else if k := 1(move(2), ="#")
  2051. X        then insert(tc_table, k, integer(tab(find(":"))))
  2052. X        else if k := 1(tab(find(":")), pos(-1))
  2053. X        then insert(tc_table, k, true())
  2054. X        else er("maketc_table", "your termcap file has a bad entry",3)
  2055. X
  2056. X    }
  2057. X    }
  2058. X
  2059. X    return tc_table
  2060. X
  2061. Xend
  2062. X
  2063. X
  2064. X
  2065. Xprocedure getval(id)
  2066. X
  2067. X    /tc_table := maketc_table(getentry(getname())) |
  2068. X    er("getval","can't make a table for your terminal",4)
  2069. X
  2070. X    return \tc_table[id] | fail
  2071. X    # er("getval","terminal doesn't support "||id,7)
  2072. X
  2073. Xend
  2074. X
  2075. X
  2076. X
  2077. Xprocedure decode(s)
  2078. X
  2079. X    new_s := ""
  2080. X
  2081. X    s ? {
  2082. X    while new_s ||:= tab(upto('\\^')) do {
  2083. X        chr := move(1)
  2084. X        if chr == "\\" then {
  2085. X        new_s ||:= {
  2086. X            case chr2 := move(1) of {
  2087. X            "\\" : "\\"
  2088. X            "^"  : "^"
  2089. X            "E"  : "\e"
  2090. X            "b"  : "\b"
  2091. X            "f"  : "\f"
  2092. X            "n"  : "\n"
  2093. X            "r"  : "\r"
  2094. X            "t"  : "\t"
  2095. X            default : {
  2096. X                if any(&digits,chr)
  2097. X                then char(integer("8r"||chr2||move(2))) |
  2098. X                er("decode","bad termcap entry",3)
  2099. X                else chr2
  2100. X            }
  2101. X            }
  2102. X        }
  2103. X        }
  2104. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  2105. X    }
  2106. X    new_s ||:= tab(0)
  2107. X    }
  2108. X
  2109. X    return new_s
  2110. X
  2111. Xend
  2112. X
  2113. X
  2114. X
  2115. Xprocedure igoto(cm,col,line)
  2116. X
  2117. X    local colline, range, outstr, chr, x, y
  2118. X
  2119. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  2120. X    colline := string(col) || "," || string(line)
  2121. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  2122. X    er("igoto",colline || " out of range " || range,9)
  2123. X    } 
  2124. X
  2125. X    # use iconish 1 offset, rather than C-ish 0
  2126. X    find("%i",cm) | (col +:= 1, line +:= 1)
  2127. X    outstr := ""
  2128. X    
  2129. X    cm ? {
  2130. X    while outstr ||:= tab(find("%")) do {
  2131. X        tab(match("%"))
  2132. X        chr := move(1)
  2133. X        if case chr of {
  2134. X        "." :  outstr ||:= char(line)
  2135. X        "+" :  line +:= ord(move(1))
  2136. X        "d" :  {
  2137. X            outstr ||:= 
  2138. X            right(string(line), integer(tab(any('23'))), "0") |
  2139. X            string(line)
  2140. X        }
  2141. X        }
  2142. X        then line :=: col
  2143. X        else {
  2144. X        case chr of {
  2145. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  2146. X            "i" :  &null
  2147. X            "r" :  line :=: col
  2148. X            "%" :  outstr ||:= "%"
  2149. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  2150. X            ">" :  {
  2151. X            x := move(1); y := move(1)
  2152. X            line > ord(x) & line +:= ord(y)
  2153. X            &null
  2154. X            }
  2155. X        } | er("goto","bad termcap entry",5)
  2156. X        }
  2157. X    }
  2158. X    return outstr || tab(0)
  2159. X    }
  2160. X
  2161. Xend
  2162. X
  2163. X
  2164. X
  2165. Xprocedure iputs(cp, affcnt)
  2166. X
  2167. X    local baud_rates, char_rates, i, delay, PC
  2168. X    static num_chars, char_times
  2169. X    # global tty_speed
  2170. X
  2171. X    initial {
  2172. X    num_chars := &digits ++ '.'
  2173. X    char_times := table()
  2174. X    baud_rates := [0,300,600,1200,1800,2400,4800,9600,19200]
  2175. X    char_rates := [0,333,166,83,55,41,20,10,5]
  2176. X    every i := 1 to *baud_rates do {
  2177. X        char_times[baud_rates[i]] := char_rates[i]
  2178. X    }
  2179. X    }
  2180. X
  2181. X    type(cp) == "string" |
  2182. X    er("iputs","you can't iputs() a non-string value!",10)
  2183. X
  2184. X    cp ? {
  2185. X    delay := tab(many(num_chars))
  2186. X    if ="*" then {
  2187. X        delay *:= \affcnt |
  2188. X        er("iputs","affected line count missing",6)
  2189. X    }
  2190. X    writes(tab(0))
  2191. X    }
  2192. X
  2193. X    if (\delay, tty_speed ~= 0) then {
  2194. X    PC := tc_table["pc"] | "\000"
  2195. X    char_time := char_times[tty_speed] | (return "speed error")
  2196. X    delay := (delay * char_time) + (char_time / 2)
  2197. X    every 1 to delay by 10
  2198. X    do writes(PC)
  2199. X    }
  2200. X
  2201. X    return
  2202. X
  2203. Xend
  2204. SHAR_EOF
  2205. exit 0
  2206.  
  2207. From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU  Thu Jun 28 13:50:01 1990
  2208. Received: from noao.edu by megaron (5.61/15) via SMTP
  2209.     id AA06092; Thu, 28 Jun 90 13:50:01 -0700
  2210. Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G42)
  2211.     id AA04329; Thu, 28 Jun 90 13:49:52 MST; for icon-group@cs.arizona.edu
  2212. Received: by ncar.ucar.EDU (5.64/ NCAR Central Post Office 04/10/90)
  2213.     id AA04634; Thu, 28 Jun 90 14:49:53 MDT
  2214. Received: from tank.uchicago.edu by oddjob.uchicago.edu Thu, 28 Jun 90 14:47:21 -0500
  2215. Received: from sophist.uchicago.edu by tank.uchicago.edu Thu, 28 Jun 90 14:49:07 CDT
  2216. Return-Path: <goer@zenu.uucp>
  2217. Received:  by sophist.uchicago.edu (3.2/UofC3.0)
  2218.     id AA22581; Thu, 28 Jun 90 14:45:09 CDT
  2219. Received: by sophist.uchicago.edu (smail2.5)
  2220.     id AA01422; 28 Jun 90 12:15:23 PDT (Thu)
  2221. Subject: BSD -> SysV filename conversion
  2222. To: icon-group@arizona.edu
  2223. Date: Thu, 28 Jun 90 12:15:22 PDT
  2224. X-Mailer: ELM [version 2.2 PL0]
  2225. Message-Id: <9006281215.AA01422@sophist.uchicago.edu>
  2226. From: goer@sophist.uchicago.edu (Richard Goerwitz)
  2227. Status: O
  2228.  
  2229. Yes, more code.  Isn't this newsgroup fun?
  2230.  
  2231. This is a repost of a now much enlarged and expanded tar archive
  2232. converter.  I frequently find that the main hassle porting BSD things
  2233. to SysV comes down to renaming files, and then weeding through the
  2234. source to find references to the old, overlong filenames.  This soft-
  2235. ware essentially automates the process.
  2236.  
  2237. Note:  This is NOT just a filename re-namer.  Yes, it renames files.
  2238. It also goes through any text files in the archive, and inserts the
  2239. new filenames there as well.  Note also:  The mapping algorithm is
  2240. smart.  It will keep one-letter extensions like .c, and will at the
  2241. user's option, keep any other extensions as well (e.g. .icn, .tex,
  2242. .uu).  With most archives, you should be able to just run this pro-
  2243. gram, pipe it to a file, unarchive this file, and then forget about
  2244. filename-length problems.
  2245.  
  2246. No one complained about the shar archive last time, so I'll shar
  2247. this one as well.  As usual, send me bug reports.
  2248.  
  2249.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  2250.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  2251.  
  2252.  
  2253.  
  2254. #!/bin/sh
  2255. # This is a shell archive (shar 3.24)
  2256. # made 06/28/1990 18:46 UTC by richard@zenu (goer@sophist.uchicago.edu)
  2257. #
  2258. # existing files WILL be overwritten
  2259. # This format requires very little intelligence at unshar time.
  2260. # "echo" and "sed" will be needed.
  2261. #
  2262. # ============= mtf3.icn ==============
  2263. echo "x - extracting mtf3.icn (Text)"
  2264. sed 's/^X//' << 'SHAR_EOF' > mtf3.icn &&
  2265. X#############################################################################
  2266. X#
  2267. X#    NAME:    mtf3.icn
  2268. X#
  2269. X#    TITLE:    map tar file
  2270. X#
  2271. X#    AUTHOR:    Richard Goerwitz
  2272. X#
  2273. X#    DATE:    5/23/90  (version 3.0 - beta)
  2274. X#
  2275. X#############################################################################
  2276. X#
  2277. X#  Copyright (c) 1990, Richard L. Goerwitz, III
  2278. X#
  2279. X#  This software is intended for free and unrestricted distribution.
  2280. X#  I place only two conditions on its use:  1) That you clearly mark
  2281. X#  any additions or changes you make to the source code, and 2) that
  2282. X#  you do not delete this message therefrom.  In order to protect
  2283. X#  myself from spurious litigation, it must also be stated here that,
  2284. X#  because this is free software, I, Richard Goerwitz, make no claim
  2285. X#  about the applicability or fitness of this software for any
  2286. X#  purpose, and expressly disclaim any responsibility for any damages
  2287. X#  that might be incurred in conjunction with its use.
  2288. X#
  2289. X###########################################################################
  2290. X#
  2291. X#  PURPOSE: Maps 15+ char. filenames in a tar archive to 14 chars.
  2292. X#  Handles both header blocks and the archive itself.  Mtf is intended
  2293. X#  to facilitate installation of tar'd archives on systems subject to
  2294. X#  the System V 14-character filename limit.
  2295. X#
  2296. X#  USAGE:  mtf3 inputfile [-r reportfile] [-e .extensions] [-x exceptions]
  2297. X#
  2298. X#  "Inputfile" is a tar archive.  "Reportfile" is file containing a
  2299. X#  list of files already mapped by mtf in a previous run (used to
  2300. X#  avoid clashes with filenames in use outside the current archive).
  2301. X#  The -e switch precedes a list of filename .extensions which mtf is
  2302. X#  supposed to leave unscathed by the mapping process
  2303. X#  (single-character extensions such as .c and .o are automatically
  2304. X#  preserved; -e allows the user to specify additional extensions,
  2305. X#  such as .pxl, .cpi, and .icn).  The final switch, -x, precedes a
  2306. X#  list of strings which should not be mapped at all.  Use this switch
  2307. X#  if, say, you have a C file with a structure.field combination such
  2308. X#  as "thisisveryverybig.hashptr" in an archive that contains a file
  2309. X#  called "thisisveryverybig.h," and you want to avoid mapping that
  2310. X#  portion of the struct name which matches the name of the overlong
  2311. X#  file (to wit, "mtf inputfile -x thisisveryverybig.hashptr").  To
  2312. X#  prevent mapping of any string (including overlong filenames) begin-
  2313. X#  ning, say, with "thisisvery," use "mtf inputfile -x thisisvery."
  2314. X#  Be careful with this option, or you might end up defeating the
  2315. X#  whole point of using mtf in the first place.
  2316. X#
  2317. X#  OUTPUT FORMAT:  Mtf writes a mapped tar archive to the stdout.
  2318. X#  When finished, it leaves a file called "map.report" in the current
  2319. X#  directory which records what filenames were mapped and how.  Rename
  2320. X#  and save this file, and use it as the "reportfile" argument to any
  2321. X#  subsequent runs of mtf in this same directory.  Even if you don't
  2322. X#  plan to run mtf again, this file should still be examined, just to
  2323. X#  be sure that the new filenames are acceptable, and to see if
  2324. X#  perhaps additional .extensions and/or exceptions should be
  2325. X#  specified.
  2326. X#
  2327. X#  BUGS:  Mtf only maps filenames found in the main tar headers.
  2328. X#  Because of this, mtf cannot accept nested tar archives.  If you try
  2329. X#  to map a tar archive within a tar file, mtf will abort with a nasty
  2330. X#  message about screwing up your files.  Please note that, unless you
  2331. X#  give mtf a "reportfile" to consider, it knows nothing about files
  2332. X#  existing outside the archive.  Hence, if an input archive refers to
  2333. X#  an overlong filename in another archive, mtf naturally will not
  2334. X#  know to shorten it.  Mtf will, in fact, have no way of knowing that
  2335. X#  it is a filename, and not, say, an identifier in a C program.
  2336. X#  Final word of caution:  Try not to use mtf on binaries.  It cannot
  2337. X#  possibly preserve the correct format and alignment of strings in an
  2338. X#  executable.  Same goes for compressed files.  Mtf can't map
  2339. X#  filenames that it can't read!
  2340. X#
  2341. X####################################################################
  2342. X
  2343. X
  2344. Xglobal filenametbl, chunkset, short_chunkset   # see procedure mappiece(s)
  2345. Xglobal extensions, no_nos                      # ditto
  2346. X
  2347. Xrecord hblock(name,junk,size,mtime,chksum,     # tar header struct;
  2348. X              linkflag,linkname,therest)       # see readtarhdr(s)
  2349. X
  2350. X
  2351. Xprocedure main(a)
  2352. X
  2353. X    usage := "usage:  mtf3 inputfile [-r reportfile] " ||
  2354. X         "[-e .extensions] [-x exceptions]"
  2355. X
  2356. X    *a = 0 & stop(usage)
  2357. X
  2358. X    intext := open_input_file(a[1]) & pop(a)
  2359. X
  2360. X    i := 0
  2361. X    extensions := []; no_nos := []
  2362. X    while (i +:= 1) <= *a do {
  2363. X    case a[i] of {
  2364. X        "-r"    :    readin_old_map_report(a[i+:=1])
  2365. X        "-e"    :    current_list := extensions
  2366. X        "-x"    :    current_list := no_nos
  2367. X        default :    put(current_list,a[i])
  2368. X    }
  2369. X    }
  2370. X
  2371. X    every !extensions ?:= (=".", tab(0))
  2372. X    
  2373. X    # Run through all the headers in the input file, filling
  2374. X    # (global) filenametbl with the names of overlong files;
  2375. X    # make_table_of_filenames fails if there are no such files.
  2376. X    make_table_of_filenames(intext) | {
  2377. X    write(&errout,"mtf:  no overlong path names to map") 
  2378. X    a[1] ? (tab(find(".tar")+4), pos(0)) |
  2379. X      write(&errout,"(Is ",a[1]," even a tar archive?)")
  2380. X     exit(1)
  2381. X    } 
  2382. X
  2383. X    # Now that a table of overlong filenames exists, go back
  2384. X    # through the text, remapping all occurrences of these names
  2385. X    # to new, 14-char values; also, reset header checksums, and
  2386. X    # reformat text into correctly padded 512-byte blocks.  Ter-
  2387. X    # minate output with 512 nulls.
  2388. X    seek(intext,1)
  2389. X    every writes(output_mapped_headers_and_texts(intext))
  2390. X
  2391. X    close(intext)
  2392. X    write_report()   # Record mapped file and dir names for future ref.
  2393. X    exit(0)
  2394. X    
  2395. Xend
  2396. X
  2397. X
  2398. X
  2399. Xprocedure open_input_file(s)
  2400. X    intext := open("" ~== s,"r") |
  2401. X    stop("mtf:  can't open ",s)
  2402. X    find("UNIX",&features) |
  2403. X    stop("mtf:  I'm not tested on non-Unix systems.")
  2404. X    s[-2:0] == ".Z" &
  2405. X        stop("mtf:  sorry, can't accept compressed files")
  2406. X    return intext
  2407. Xend
  2408. X
  2409. X
  2410. X
  2411. Xprocedure readin_old_map_report(s)
  2412. X
  2413. X    initial {
  2414. X    filenametbl := table()
  2415. X    chunkset := set()
  2416. X    short_chunkset := set()
  2417. X    }
  2418. X
  2419. X    mapfile := open_input_file(s)
  2420. X    while line := read(mapfile) do {
  2421. X    line ? {    
  2422. X        if chunk := tab(many(~' \t')) & tab(upto(~' \t')) &
  2423. X        lchunk := move(14) & pos(0) then {
  2424. X        filenametbl[chunk] := lchunk
  2425. X        insert(chunkset,chunk)
  2426. X        insert(short_chunkset,chunk[1:16])
  2427. X        }
  2428. X    if /chunk | /lchunk
  2429. X    then stop("mtf:  report file, ",s," seems mangled.")
  2430. X    }
  2431. X    }
  2432. X
  2433. Xend
  2434. X
  2435. X
  2436. X
  2437. Xprocedure make_table_of_filenames(intext)
  2438. X
  2439. X    local header # chunkset is global
  2440. X
  2441. X    # search headers for overlong filenames; for now
  2442. X    # ignore everything else
  2443. X    while header := readtarhdr(reads(intext,512)) do {
  2444. X    # tab upto the next header block
  2445. X    tab_nxt_hdr(intext,trim_str(header.size),1)
  2446. X    # record overlong filenames in several global tables, sets
  2447. X    fixpath(trim_str(header.name))
  2448. X    }
  2449. X    *\chunkset ~= 0 | fail
  2450. X    return &null
  2451. X
  2452. Xend
  2453. X
  2454. X
  2455. X
  2456. Xprocedure output_mapped_headers_and_texts(intext)
  2457. X
  2458. X    # Remember that filenametbl, chunkset, and short_chunkset
  2459. X    # (which are used by various procedures below) are global.
  2460. X    local header, newtext, full_block, block, lastblock
  2461. X
  2462. X    # Read in headers, one at a time.
  2463. X    while header := readtarhdr(reads(intext,512)) do {
  2464. X
  2465. X    # Replace overlong filenames with shorter ones, according to
  2466. X    # the conversions specified in the global hash table filenametbl
  2467. X    # (which were generated by fixpath() on the first pass).
  2468. X          header.name := left(map_filenams(header.name),100,"\x00")
  2469. X    header.linkname := left(map_filenams(header.linkname),100,"\x00")
  2470. X
  2471. X    # Use header.size field to determine the size of the subsequent text.
  2472. X    # Read in the text as one string.  Map overlong filenames found in it
  2473. X     # to shorter names as specified in the global hash table filenamtbl.
  2474. X    newtext := map_filenams(tab_nxt_hdr(intext,trim_str(header.size)))
  2475. X
  2476. X    # Now, find the length of newtext, and insert it into the size field.
  2477. X    header.size := right(exbase10(*newtext,8) || " ",12," ")
  2478. X
  2479. X    # Calculate the checksum of the newly retouched header.
  2480. X    header.chksum := right(exbase10(get_checksum(header),8)||"\x00 ",8," ")
  2481. X
  2482. X    # Finally, join all the header fields into a new block and write it out
  2483. X    full_block := ""; every full_block ||:= !header
  2484. X    suspend left(full_block,512,"\x00")
  2485. X
  2486. X    # Now we're ready to write out the text, padding the final block
  2487. X    # out to an even 512 bytes if necessary; the next header must start
  2488. X    # right at the beginning of a 512-byte block.
  2489. X    newtext ? {
  2490. X        while block := move(512)
  2491. X        do suspend block
  2492. X        pos(0) & next
  2493. X            lastblock := left(tab(0),512,"\x00")
  2494. X        suspend lastblock
  2495. X    }
  2496. X    }
  2497. X    # Write out a final null-filled block.  Some tar programs will write
  2498. X    # out 1024 nulls at the end.  Dunno why.
  2499. X    return repl("\x00",512)
  2500. X
  2501. Xend
  2502. X
  2503. X
  2504. X
  2505. Xprocedure trim_str(s)
  2506. X
  2507. X    # Knock out spaces, nulls from those crazy tar header
  2508. X    # block fields (some of which end in a space and a null,
  2509. X    # some just a space, and some just a null [anyone know
  2510. X    # why?]).
  2511. X    return s ? {
  2512. X    (tab(many(' ')) | &null) &
  2513. X        trim(tab(find("\x00")|0))
  2514. X    } \ 1
  2515. X
  2516. Xend 
  2517. X
  2518. X
  2519. X
  2520. Xprocedure tab_nxt_hdr(f,size_str,firstpass)
  2521. X
  2522. X    # Tab upto the next header block.  Return the bypassed text
  2523. X    # as a string if not the first pass.
  2524. X
  2525. X    local hs, next_header_offset
  2526. X
  2527. X    hs := integer("8r" || size_str)
  2528. X    next_header_offset := (hs / 512) * 512
  2529. X    hs % 512 ~= 0 & next_header_offset +:= 512
  2530. X    if 0 = next_header_offset then return ""
  2531. X    else {
  2532. X    # if this is pass no. 1 don't bother returning a value; we're
  2533. X    # just collecting long filenames;
  2534. X    if \firstpass then {
  2535. X        seek(f,where(f)+next_header_offset)
  2536. X        return
  2537. X    }
  2538. X    else {
  2539. X        return reads(f,next_header_offset)[1:hs+1] |
  2540. X        stop("mtf:  error reading in ",
  2541. X             string(next_header_offset)," bytes.")
  2542. X    }
  2543. X    }
  2544. X
  2545. Xend
  2546. X
  2547. X
  2548. X
  2549. Xprocedure fixpath(s)
  2550. X
  2551. X    # Fixpath is a misnomer of sorts, since it is used on
  2552. X    # the first pass only, and merely examines each filename
  2553. X    # in a path, using the procedure mappiece to record any
  2554. X    # overlong ones in the global table filenametbl and in
  2555. X    # the global sets chunkset and short_chunkset; no fixing
  2556. X    # is actually done here.
  2557. X
  2558. X    s2 := ""
  2559. X    s ? {
  2560. X    while piece := tab(find("/")+1)
  2561. X    do s2 ||:= mappiece(piece) 
  2562. X    s2 ||:= mappiece(tab(0))
  2563. X    }
  2564. X    return s2
  2565. X
  2566. Xend
  2567. X
  2568. X
  2569. X
  2570. Xprocedure mappiece(s)
  2571. X
  2572. X    # Check s (the name of a file or dir as recorded in the tar header
  2573. X    # being examined) to see if it is over 14 chars long.  If so,
  2574. X    # generate a unique 14-char version of the name, and store
  2575. X    # both values in the global hashtable filenametbl.  Also store
  2576. X    # the original (overlong) file name in chunkset.  Store the
  2577. X    # first fifteen chars of the original file name in short_chunkset.
  2578. X    # Sorry about all of the tables and sets.  It actually makes for
  2579. X    # a reasonably efficient program.  Doing away with both sets,
  2580. X    # while possible, causes a tenfold drop in execution speed!
  2581. X    
  2582. X    # global filenametbl, chunkset, short_chunkset, extensions
  2583. X    local j, ending
  2584. X
  2585. X    initial {
  2586. X    /filenametbl := table()
  2587. X    /chunkset := set()
  2588. X    /short_chunkset := set()
  2589. X    }
  2590. X   
  2591. X    chunk := trim(s,'/')
  2592. X    if chunk ? (tab(find(".tar")+4), pos(0)) then {
  2593. X    write(&errout, "mtf:  Sorry, I can't let you do this.\n",
  2594. X                   "      You've nested a tar archive within\n",
  2595. X                   "      another tar archive, which makes it\n",
  2596. X                   "      likely I'll f your filenames ubar.")
  2597. X    exit(2)
  2598. X    }
  2599. X    if *chunk > 14 then {
  2600. X    i := 0
  2601. X
  2602. X    if /filenametbl[chunk] then {
  2603. X    # if we have not seen this file, then...
  2604. X        repeat {
  2605. X        # ...find a new unique 14-character name for it;
  2606. X        # preserve important suffixes like ".Z," ".c," etc.
  2607. X        # First, check to see if the original filename (chunk)
  2608. X        # ends in an important extension...
  2609. X        if chunk ?
  2610. X            (tab(find(".")),
  2611. X             ending := move(1) || tab(match(!extensions)|any(&ascii)),
  2612. X             pos(0)
  2613. X             )
  2614. X        # ...If so, then leave the extension alone; mess with the
  2615. X        # middle part of the filename (e.g. file.with.extension.c ->
  2616. X        # file.with001.c).
  2617. X        then {
  2618. X            j := (15 - *ending - 3)
  2619. X            lchunk:= chunk[1:j] || right(string(i+:=1),3,"0") || ending
  2620. X        }
  2621. X        # If no important extension is present, then reformat the
  2622. X        # end of the file (e.g. too.long.file.name -> too.long.fi01).
  2623. X        else lchunk := chunk[1:13] || right(string(i+:=1),2,"0")
  2624. X
  2625. X        # If the resulting shorter file name has already been used...
  2626. X        if lchunk == !filenametbl
  2627. X        # ...then go back and find another (i.e. increment i & try
  2628. X        # again; else break from the repeat loop, and...
  2629. X        then next else break
  2630. X        }
  2631. X            # ...record both the old filename (chunk) and its new,
  2632. X        # mapped name (lchunk) in filenametbl.  Also record the
  2633. X        # mapped names in chunkset and short_chunkset.
  2634. X        filenametbl[chunk] := lchunk
  2635. X        insert(chunkset,chunk)
  2636. X        insert(short_chunkset,chunk[1:16])
  2637. X    }
  2638. X    }
  2639. X
  2640. X    # If the filename is overlong, return lchunk (the shortened
  2641. X    # name), else return the original name (chunk).  If the name,
  2642. X    # as passed to the current function, contained a trailing /
  2643. X    # (i.e. if s[-1]=="/"), then put the / back.  This could be
  2644. X    # done more elegantly.
  2645. X    return (\lchunk | chunk) || ((s[-1] == "/") | "")
  2646. X
  2647. Xend
  2648. X
  2649. X
  2650. X
  2651. Xprocedure readtarhdr(s)
  2652. X
  2653. X    # Read the silly tar header into a record.  Note that, as was
  2654. X    # complained about above, some of the fields end in a null, some
  2655. X    # in a space, and some in a space and a null.  The procedure
  2656. X    # trim_str() may (and in fact often _is_) used to remove this
  2657. X    # extra garbage.
  2658. X
  2659. X    this_block := hblock()
  2660. X    s ? {
  2661. X    this_block.name     := move(100)    # <- to be looked at later
  2662. X    this_block.junk     := move(8+8+8)  # skip the permissions, uid, etc.
  2663. X    this_block.size     := move(12)     # <- to be looked at later
  2664. X    this_block.mtime    := move(12)
  2665. X    this_block.chksum   := move(8)      # <- to be looked at later
  2666. X    this_block.linkflag := move(1)
  2667. X    this_block.linkname := move(100)    # <- to be looked at later
  2668. X    this_block.therest  := tab(0)
  2669. X    }
  2670. X    integer(this_block.size) | fail  # If it's not an integer, we've hit
  2671. X                                     # the final (null-filled) block.
  2672. X    return this_block
  2673. X
  2674. Xend
  2675. X
  2676. X
  2677. X
  2678. Xprocedure map_filenams(s)
  2679. X
  2680. X    # Chunkset is global, and contains all the overlong filenames
  2681. X    # found in the first pass through the input file; here the aim
  2682. X    # is to map these filenames to the shortened variants as stored
  2683. X    # in filenametbl (GLOBAL).
  2684. X
  2685. X    local s2, tmp_chunk_tbl, tmp_lst
  2686. X    static new_chunklist
  2687. X    initial {
  2688. X
  2689. X        # Make sure filenames are sorted, longest first.  Say we
  2690. X        # have a file called long_file_name_here.1 and one called
  2691. X        # long_file_name_here.1a.  We want to check for the longer
  2692. X        # one first.  Otherwise the portion of the second file which
  2693. X        # matches the first file will get remapped.
  2694. X        tmp_chunk_tbl := table()
  2695. X        every el := !chunkset
  2696. X        do insert(tmp_chunk_tbl,el,*el)
  2697. X        tmp_lst := sort(tmp_chunk_tbl,4)
  2698. X        new_chunklist := list()
  2699. X        every put(new_chunklist,tmp_lst[*tmp_lst-1 to 1 by -2])
  2700. X
  2701. X    }
  2702. X
  2703. X    s2 := ""
  2704. X    s ? {
  2705. X    until pos(0) do {
  2706. X        # first narrow the possibilities, using short_chunkset
  2707. X        if member(short_chunkset,&subject[&pos:&pos+15])
  2708. X            # then try to map from a long to a shorter 14-char filename
  2709. X        then {
  2710. X        if match(ch := !new_chunklist) & not match(!no_nos)
  2711. X        then s2 ||:= filenametbl[=ch]
  2712. X        else s2 ||:= move(1)
  2713. X        }
  2714. X        else s2 ||:= move(1)
  2715. X    }
  2716. X    }
  2717. X    return s2
  2718. X
  2719. Xend
  2720. X
  2721. X
  2722. X#  From the IPL.  Thanks, Ralph -
  2723. X#  Author:  Ralph E. Griswold
  2724. X#  Date:  June 10, 1988
  2725. X#  exbase10(i,j) convert base-10 integer i to base j
  2726. X#  The maximum base allowed is 36.
  2727. X
  2728. Xprocedure exbase10(i,j)
  2729. X
  2730. X   static digits
  2731. X   local s, d, sign
  2732. X   initial digits := &digits || &lcase
  2733. X   if i = 0 then return 0
  2734. X   if i < 0 then {
  2735. X      sign := "-"
  2736. X      i := -i
  2737. X      }
  2738. X   else sign := ""
  2739. X   s := ""
  2740. X   while i > 0 do {
  2741. X      d := i % j
  2742. X      if d > 9 then d := digits[d + 1]
  2743. X      s := d || s
  2744. X      i /:= j
  2745. X      }
  2746. X   return sign || s
  2747. X
  2748. Xend
  2749. X
  2750. X# end IPL material
  2751. X
  2752. X
  2753. Xprocedure get_checksum(r)
  2754. X    # Calculates the new value of the checksum field for the
  2755. X    # current header block.  Note that the specification say
  2756. X    # that, when calculating this value, the chksum field must
  2757. X    # be blank-filled.
  2758. X
  2759. X    sum := 0
  2760. X    r.chksum := "        "
  2761. X    every field := !r
  2762. X    do every sum +:= ord(!field)
  2763. X    return sum
  2764. X
  2765. Xend
  2766. X
  2767. X
  2768. X
  2769. Xprocedure write_report()
  2770. X
  2771. X    # This procedure writes out a list of filenames which were
  2772. X    # remapped (because they exceeded the SysV 14-char limit),
  2773. X    # and then notifies the user of the existence of this file.
  2774. X
  2775. X    local outtext, stbl, i, j, mapfile_name
  2776. X
  2777. X    # Get a unique name for the map.report (thereby preventing
  2778. X    # us from overwriting an older one).
  2779. X    mapfile_name := "map.report"; j := 1
  2780. X    until not close(open(mapfile_name,"r"))
  2781. X    do mapfile_name := (mapfile_name[1:11] || string(j+:=1))
  2782. X
  2783. X    (outtext := open(mapfile_name,"w")) |
  2784. X    open(mapfile_name := "/tmp/map.report","w") |
  2785. X         stop("mtf:  Can't find a place to put map.report!")
  2786. X    stbl := sort(filenametbl,3)
  2787. X    every i := 1 to *stbl -1 by 2 do {
  2788. X    match(!no_nos,stbl[i]) |
  2789. X        write(outtext,left(stbl[i],35," ")," ",stbl[i+1])
  2790. X    }
  2791. X    write(&errout,"\nmtf:  ",mapfile_name," contains the list of changes.")
  2792. X    write(&errout,"      Please save this list!")
  2793. X    close(outtext)
  2794. X    return &null
  2795. X
  2796. Xend
  2797. SHAR_EOF
  2798. exit 0
  2799.  
  2800. From icon-group-request@arizona.edu  Mon Jul  2 10:28:13 1990
  2801. Resent-From: icon-group-request@arizona.edu
  2802. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  2803.     id AA13884; Mon, 2 Jul 90 10:28:13 -0700
  2804. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Mon, 2 Jul 90 10:30 MST
  2805. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA19095; Mon, 2 Jul 90 10:22:02
  2806.  -0700
  2807. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2808.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2809.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2810. Resent-Date: Mon, 2 Jul 90 10:30 MST
  2811. Date: 2 Jul 90 12:08:15 GMT
  2812. From: fed!arccs2!m1bjk00@uunet.uu.NET
  2813. Subject: icont
  2814. Sender: icon-group-request@arizona.edu
  2815. Resent-To: icon-group@cs.arizona.edu
  2816. To: icon-group@arizona.edu
  2817. Resent-Message-Id: <6EF12BAC2A9F404DD5@Arizona.EDU>
  2818. Message-Id: <M1BJK00.90Jul2130815@arccs3.fed.frb.gov>
  2819. Organization: Federal Reserve Board
  2820. X-Envelope-To: icon-group@CS.Arizona.EDU
  2821. X-Vms-To: icon-group@Arizona.EDU
  2822. Status: O
  2823.  
  2824.  
  2825. I am new to icon and new to this newsgroup. I have the following 2 problems
  2826. with respect to using icon on a Sun 3/60 for anyone willing to direct or
  2827. correct me:  
  2828.  
  2829.   1. Under v7, the following syntax works:
  2830.  
  2831.               icont fn1 ./mylib/fn2.u1 
  2832.  
  2833.      Under v8, I get:
  2834.  
  2835.             icont: cannot resolve reference to file 'fn2.u1'
  2836.  
  2837.   2. Under v7, the following syntax fails:
  2838.  
  2839.              icont /abc/def/myprog
  2840.  
  2841.      with:
  2842.  
  2843.              Can't resolve reference to file '/arc/fame/icon/myprog.u1'
  2844.  
  2845.     when I am not in the directory /abc/def.
  2846.  
  2847.     Under v8, the preceding works, but the following fails:
  2848.  
  2849.              icont /abc/def/myprog /abc/def/mysub.u1
  2850.  
  2851.     with:
  2852.  
  2853.              icont: cannot resolve reference to file 'mysub.u1'
  2854.  
  2855. From icon-group-request@arizona.edu  Tue Jul  3 21:43:31 1990
  2856. Resent-From: icon-group-request@arizona.edu
  2857. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  2858.     id AA04196; Tue, 3 Jul 90 21:43:31 -0700
  2859. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Tue, 3 Jul 90 21:45 MST
  2860. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA29225; Tue, 3 Jul 90 21:28:07
  2861.  -0700
  2862. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2863.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2864.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2865. Resent-Date: Tue, 3 Jul 90 21:46 MST
  2866. Date: 4 Jul 90 01:46:26 GMT
  2867. From: sumax!amc-gw!thebes!happym!irv@beaver.cs.washington.EDU
  2868. Subject: need icon project email address
  2869. Sender: icon-group-request@arizona.edu
  2870. Resent-To: icon-group@cs.arizona.edu
  2871. To: icon-group@arizona.edu
  2872. Resent-Message-Id: <6DC9A9B3A63F405E47@Arizona.EDU>
  2873. Message-Id: <325@happym.wa.com>
  2874. Organization: Happy Man Corp., Seattle
  2875. X-Envelope-To: icon-group@CS.Arizona.EDU
  2876. X-Vms-To: icon-group@Arizona.EDU
  2877. Status: O
  2878.  
  2879. Since I've moved, I've apparently lost contact with the Icon people.  Does
  2880. someone have their email address handy, so I could let them know my new
  2881. mailing address and get the newsletter once again?
  2882.  
  2883. Thanks!
  2884. -- 
  2885.  Irving Wolfe            irv@happym.wa.com              206/463-9399 ext.101
  2886.  Happy Man Corp.   4410 SW Pt. Robinson Road,  Vashon Island, WA  98070-7399
  2887.  SOLID VALUE, the investment letter for Benj. Graham's intelligent investors
  2888.  
  2889. From ralph  Wed Jul  4 05:49:29 1990
  2890. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2891.     id AA16477; Wed, 4 Jul 90 05:49:29 -0700
  2892. Date: Wed, 4 Jul 90 05:49:25 MST
  2893. From: "Ralph Griswold" <ralph>
  2894. Message-Id: <9007041249.AA29693@cheltenham.cs.arizona.edu>
  2895. Received: by cheltenham.cs.arizona.edu; Wed, 4 Jul 90 05:49:25 MST
  2896. To: icon-group
  2897. Subject: Icon context switch for the Sun4
  2898. Status: O
  2899.  
  2900. An Icon co-expression context switch for the Sun4 folllows. If you use it
  2901. and encounter any problems, please let the Icon project know.
  2902.  
  2903. This context switch was written by Phil Kaslo of our laboratory staff, with
  2904. initial assistance from Dave Bakken.
  2905.  
  2906. +++++++++++CUT HERE+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2907.  
  2908. /*
  2909.  * rswitch.c for Sun-4 Sparc.
  2910.  * 
  2911.  * Compile this with 'cc -c rswitch.c'.  Do not use cc -O.
  2912.  */
  2913.  
  2914. #include <sun4/asm_linkage.h>
  2915. #include <sun4/trap.h>
  2916.  
  2917. int coswitch(old_cs, new_cs, first)
  2918. int *old_cs, *new_cs;
  2919. int first;
  2920. {
  2921.    asm("ta    0x03");            /* ST_FLUSH_WINDOWS in trap.h     */
  2922.    asm("ld    [%fp+0x44], %o0");    /* load old_cs into %o0              */
  2923.    asm("st    %sp,[%o0]");        /* Save user stack pointer        */
  2924.    asm("st    %fp,[%o0+0x4]");    /* Save frame pointer             */
  2925.    asm("st    %i7,[%o0+0x8]");    /* Save return address            */
  2926.  
  2927.    if (first == 0) {            /* this is the first activation   */
  2928.       asm("ld    [%fp+0x48], %o0");    /* load new_cs into %o0           */
  2929.       asm("ld    [%o0], %o1");        /* load %o1 from cstate[0]        */
  2930.  
  2931.       /* Decrement new stack pointer value before loading it into sp.      */
  2932.       /* The top 64 bytes of the stack are reserved for the kernel, to    */
  2933.       /* save the 8 local and 8 in registers into, on context switches,   */
  2934.       /* interrupts, traps, etc.                      */
  2935.  
  2936.       asm("dec  96,%o1");        
  2937.       asm("mov  %o1, %sp");        /* load %sp from %o1              */
  2938.       interp(0,0);
  2939.       syserr("interp() returned in coswitch");
  2940.  
  2941.    } else {
  2942.       asm("ld    [%fp+0x48], %o0");    /* load new_cs into %o0           */
  2943.       asm("ld    [%o0+0x4],%fp");    /* Load frame pointer             */
  2944.       asm("ld    [%o0+0x8],%i7");    /* Load return address            */
  2945.       asm("ld    [%o0],%sp");        /* Load user stack pointer        */
  2946.    }
  2947. }
  2948.  
  2949. +++++++++++CUT HERE+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2950.  
  2951.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  2952.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  2953.  
  2954. From ralph  Wed Jul  4 05:54:23 1990
  2955. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  2956.     id AA16608; Wed, 4 Jul 90 05:54:23 -0700
  2957. Date: Wed, 4 Jul 90 05:54:20 MST
  2958. From: "Ralph Griswold" <ralph>
  2959. Message-Id: <9007041254.AA29743@cheltenham.cs.arizona.edu>
  2960. Received: by cheltenham.cs.arizona.edu; Wed, 4 Jul 90 05:54:20 MST
  2961. To: icon-group
  2962. Subject: Icon program available
  2963. Status: O
  2964.  
  2965. Alan Corre has provided us with an Icon program and some ancillary materials
  2966. for a visually equivalent Jewish/Civil calendar.  The file is rather large
  2967. (about 29K bytes), so we're offering to send copies to individuals rather
  2968. than posting it to the entire group.
  2969.  
  2970. If you'd like a copy, send your request to me (not icon-group or icon-project).
  2971.  
  2972.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  2973.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  2974.  
  2975. From kwalker  Wed Jul  4 14:09:27 1990
  2976. Date: Wed, 4 Jul 90 14:09:27 -0700
  2977. From: "Kenneth Walker" <kwalker>
  2978. Message-Id: <9007042109.AA03875@megaron.cs.arizona.edu>
  2979. Received: by megaron.cs.arizona.edu (5.61/15)
  2980.     id AA03875; Wed, 4 Jul 90 14:09:27 -0700
  2981. To: fed!arccs2!m1bjk00@uunet.uu.NET, icon-group
  2982. Subject: Re: icont
  2983. Status: O
  2984.  
  2985. > Date: 2 Jul 90 12:08:15 GMT
  2986. > From: fed!arccs2!m1bjk00@uunet.uu.NET
  2987.  
  2988. >   1. Under v7, the following syntax works:
  2989.  
  2990. >               icont fn1 ./mylib/fn2.u1 
  2991.  
  2992. >      Under v8, I get:
  2993.  
  2994. >             icont: cannot resolve reference to file 'fn2.u1'
  2995.  
  2996. This is a known bug in V8. The work around is to include the "mylib"
  2997. directory in the search path specified with the IPATH environment
  2998. variable.
  2999.  
  3000.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  3001.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  3002.  
  3003. From esquire!info8!yost@cmcl2.NYU.EDU  Thu Jul  5 09:28:18 1990
  3004. Received: from cmcl2.NYU.EDU (NYU.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  3005.     id AA00410; Thu, 5 Jul 90 09:28:18 -0700
  3006. Received: by cmcl2.NYU.EDU (5.61/1.34)
  3007.     id AA26327; Thu, 5 Jul 90 10:15:58 -0400
  3008. Received: from info8 by ESQUIRE.DPW. id aa01992; 5 Jul 90 10:01 EDT
  3009. Received: from localhost by info8. (4.0/SMI-4.0)
  3010.     id AA24281; Thu, 5 Jul 90 10:02:36 EDT
  3011. Message-Id: <9007051402.AA24281@info8.>
  3012. From: yost@DPW.COM (Dave Yost)
  3013. Reply-To: yost@DPW.COM (Dave Yost)
  3014. To: "Ralph Griswold" <ralph@cs.arizona.edu>
  3015. Cc: icon-group@cs.arizona.edu, yost@cmcl2.NYU.EDU
  3016. Subject: Re: Icon context switch for the Sun4 
  3017. In-Reply-To: Your message of Wed, 04 Jul 90 05:49:25 MST.
  3018.              <9007041249.AA29693@cheltenham.cs.arizona.edu> 
  3019. Phone: +1 212-266-0796 (Voice Direct Line)
  3020. Fax: +1 212-266-0790
  3021. Organization: Davis Polk & Wardwell
  3022.           1 Chase Manhattan Plaza
  3023.           New York, NY  10005
  3024. Date: Thu, 05 Jul 90 10:02:33 -0400
  3025. Sender: yost@info8.NYU.EDU
  3026. Status: O
  3027.  
  3028. > An Icon co-expression context switch for the Sun4 folllows. If you use it
  3029. > and encounter any problems, please let the Icon project know.
  3030.  
  3031. You forgot to mention why we might want this.
  3032. Is the standard v8 rswitch.c buggy?  Too slow?
  3033.  
  3034.  --dave yost
  3035.    yost@dpw.com or uunet!esquire!yost
  3036.    Please ignore the From or Reply-To fields above, if different.
  3037.  
  3038. From icon-group-request@arizona.edu  Thu Jul  5 15:01:10 1990
  3039. Resent-From: icon-group-request@arizona.edu
  3040. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  3041.     id AA19371; Thu, 5 Jul 90 15:01:10 -0700
  3042. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 5 Jul 90 15:03 MST
  3043. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA11996; Thu, 5 Jul 90 14:58:48
  3044.  -0700
  3045. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3046.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3047.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3048. Resent-Date: Thu, 5 Jul 90 15:03 MST
  3049. Date: 5 Jul 90 20:41:35 GMT
  3050. From: bunny!nic!hri!sparc9!rolandi@husc6.harvard.EDU
  3051. Subject: passing variable patterns to egrep
  3052. Sender: icon-group-request@arizona.edu
  3053. Resent-To: icon-group@cs.arizona.edu
  3054. To: icon-group@arizona.edu
  3055. Resent-Message-Id: <6C6F85623B3F4065C9@Arizona.EDU>
  3056. Message-Id: <1990Jul5.204135.13202@hri.com>
  3057. Organization: Horizon Research
  3058. X-Envelope-To: icon-group@CS.Arizona.EDU
  3059. X-Vms-To: icon-group@Arizona.EDU
  3060. Status: O
  3061.  
  3062.  
  3063. can anyone suggest a way to pass variable patterns  to egrep via a
  3064. quoted  argument as in
  3065.  
  3066. system("egrep 'ABC[d.]'")
  3067.  
  3068. i would like to be able to assemble the 'ABC[d.]' type parts on the
  3069. fly and then push  them out to the system.
  3070.  
  3071. any ideas?
  3072.  
  3073.               ***************************************
  3074.               *          Walter G. Rolandi          *
  3075.               *        Horizon Research, Inc.       *
  3076.               *           1432 Main Street          *
  3077.               *       Waltham, MA  02154  USA       *
  3078.               *            (617) 466 8339           *
  3079.               *                                     *
  3080.               *           rolandi@hri.com           *
  3081.               ***************************************
  3082.  
  3083. From goer@sophist.uchicago.EDU  Thu Jul  5 22:11:12 1990
  3084. Resent-From: goer@sophist.uchicago.EDU
  3085. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  3086.     id AA07107; Thu, 5 Jul 90 22:11:12 -0700
  3087. Return-Path: goer@sophist.uchicago.EDU
  3088. Received: from xtank.uchicago.edu by Arizona.EDU; Thu, 5 Jul 90 22:13 MST
  3089. Received: from sophist.uchicago.edu by xtank.uchicago.edu Fri, 6 Jul 90
  3090.  00:12:42 CDT
  3091. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA04804; Fri, 6 Jul 90
  3092.  00:08:34 CDT
  3093. Resent-Date: Thu, 5 Jul 90 22:13 MST
  3094. Date: Fri, 6 Jul 90 00:08:34 CDT
  3095. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  3096. Subject: egrep & variable patterns
  3097. Resent-To: icon-group@cs.arizona.edu
  3098. To: icon-group@arizona.edu
  3099. Resent-Message-Id: <6C337544D4BF4063A1@Arizona.EDU>
  3100. Message-Id: <9007060508.AA04804@sophist.uchicago.edu>
  3101. X-Envelope-To: icon-group@CS.Arizona.EDU
  3102. X-Vms-To: icon-group@Arizona.EDU
  3103. Status: O
  3104.  
  3105. > Can anyone suggest a way to pass variable patterns  to egrep via a
  3106. > quoted argument as in,
  3107. >    system("egrep 'ABC[d.]'")
  3108. > I would like to be able to assemble the 'ABC[d.]' type parts on the
  3109. > fly and then push them out to the system.
  3110. > Any ideas?
  3111.  
  3112. Sure.  I got a lot of ideas.  You judge for yourself which (if any) are
  3113. going to work out.
  3114.  
  3115. First of all, you could try something cute like:
  3116.  
  3117.   while ans := read(&input) do {
  3118.     system("/bin/egrep "||ans||" filename")
  3119.     }
  3120.  
  3121. I don't see what good this will do, because egrep will write to the
  3122. standard output and standard error output, and will not pipe to iconx.
  3123. You might as well write a shell script that does the same thing.
  3124.  
  3125. I might add that, unless you are writing a utility geared specifically
  3126. for the Unix environment, you'd best avoid such heavily OS-dependent
  3127. things as /bin/egrep (I gather the system function itself is not ter-
  3128. ribly portable, too).
  3129.  
  3130. Finally, you'll find that repeated calls to system() are expensive.  They
  3131. take a lot of time.
  3132.  
  3133. So much for my first suggestion.
  3134.  
  3135. A second suggestion might be to do something with
  3136.  
  3137.     open("/bin/egrep "||ans||" filename","pr")
  3138.  
  3139. You could then use egrep's output within Icon.
  3140.  
  3141. The problems here are again OS dependency and slowness.  Many implemen-
  3142. tations don't give you the "p" option with open().  And even if you can
  3143. do it, you'll pay the price of having to open and close pipes repeatedly.
  3144.  
  3145. A third suggestion might be to complain to the Icon Project that an in-
  3146. ternal grep-like command is needed, and try to convince them to create
  3147. one (after all, most C libraries have regex functions).
  3148.  
  3149. My objection to this is that it would be very un-Iconish.  Icon's pat-
  3150. tern-matching facilities are far more powerful than the facilities of-
  3151. fered by egrep, and of a wholly different kind.  You can easily construct
  3152. scanning expressions that will do anything egrep's regular expressions
  3153. will do.  I don't think anyone at the Icon project will be interested
  3154. in adding an igrep(), or whatever, function.
  3155.  
  3156. This leads to yet another solution to your problem:  Why not just use
  3157. Icon's intrinsic pattern-matching facilities?  Your
  3158.  
  3159.     egrep 'ABC[de]' filename
  3160.  
  3161. above can just as easily be expressed in Icon.  The following is very
  3162. inelegant, but suffices to show what can be done:
  3163.  
  3164.     every write(!open("filename") ? (tab(find("ABC")+3), any('de'), &subject))
  3165.  
  3166. You can, of course, use the results by assigning them to an intermediate
  3167. variable.  And you can vary the search pattern yourself simply by changing
  3168. the expression used after the question mark above.  You can vary the file
  3169. ("filename" -> "filename1"|"filename2"|"filename3"), and anything else
  3170. you like.  Easy as pie, once you "get it."
  3171.  
  3172. The only problem likely to crop up in this connection has to do with con-
  3173. structing automata to match patterns at run-time.  You'll likely have some
  3174. trouble getting Icon to do this.
  3175.  
  3176. Lucky for you some nutcase posted a program called find_re, which is inten-
  3177. ded just for this very thing.  It works a bit like find() and a bit like
  3178. egrep, though it's not as fast as the C egrep program.  It's fast enough
  3179. for most purposes, though.  And since it's written in Icon, you don't have
  3180. to worry about piping, system(), and what not.  If you want find_re(),
  3181. please send a note to the following address:
  3182.  
  3183.     Richard L. Goerwitz               goer%sophist@uchicago.bitnet
  3184.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  3185.  
  3186. This person appreciates it very much when people test his software, and
  3187. send back bug reports.
  3188.  
  3189. From alfred@alpha.uni-paderborn.de  Fri Jul  6 07:56:52 1990
  3190. Received: from unido.informatik.uni-dortmund.de by megaron.cs.arizona.edu (5.61/15) via SMTP
  3191.     id AA22421; Fri, 6 Jul 90 07:56:52 -0700
  3192. Received: from pbinfo-n.uni-paderborn.de 
  3193.     by unido.informatik.uni-dortmund.de with SMTP via EUnet (UNIDO-2.0.1.q) via EUnet
  3194.     for cs.arizona.edu
  3195.     id AQ16967; Fri, 6 Jul 90 16:55:00 +0100
  3196. Received: by pbinfo-n.uni-paderborn.de; Fri, 6 Jul 90 11:34:15 +0200 PBINFO2.1
  3197. Received: by pbinfo.uni-paderborn.de; Fri, 6 Jul 90 11:48:23 +0200 PBINFO2.1
  3198. From: Alfred Schmidt <alfred@alpha.uni-paderborn.de>
  3199. Date: Wed, 4 Jul 90 08:34:11 MEZ
  3200. Message-Id: <9007040934.AA00311@alpha.uni-paderborn.de>
  3201. Received: by alpha.uni-paderborn.de; Wed, 4 Jul 90 08:34:11 MEZ
  3202. To: icon-group@cs.arizona.edu
  3203. Status: O
  3204.  
  3205. Dear Sirs:
  3206.  
  3207.   I would like to order 
  3208.  
  3209.   1x (code DE) MS-DOS executables ICON V8 (5 1/4")     $25
  3210.   1x (code NL) Newsletter back issues complete (1-33)  $20
  3211.   1x (code LB) Icon book, 2nd edition                  $43
  3212.   --------------------------------------------------------
  3213.                                                  total $88
  3214.                                                  =========
  3215.  
  3216. Name and address (this is a new address!):
  3217.  
  3218.     Alfred Schmidt
  3219.     Linnebornweg 3
  3220.     D-4790 Paderborn
  3221.     WEST GERMANY 
  3222.     phone: (+49) 5251 603158
  3223.            (+49) 5251 55295
  3224.                   
  3225. Payment:      MasterCard
  3226.  
  3227. I hereby authorize the billing of the above order 
  3228. to my credit card:
  3229.  
  3230.     card number:  5232 5411 1001 2038
  3231.     exp. date:    08/91
  3232.     name on card: Alfred Schmidt
  3233.  
  3234. I would appreciate very much if you could confirm the receipt of 
  3235. this message.
  3236.  
  3237. Yours Sincerely,
  3238.  
  3239.   Alfred Schmidt
  3240.  
  3241. From ralph  Fri Jul  6 09:15:08 1990
  3242. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  3243.     id AA25966; Fri, 6 Jul 90 09:15:08 -0700
  3244. Date: Fri, 6 Jul 90 09:14:54 MST
  3245. From: "Ralph Griswold" <ralph>
  3246. Message-Id: <9007061614.AA22701@cheltenham.cs.arizona.edu>
  3247. Received: by cheltenham.cs.arizona.edu; Fri, 6 Jul 90 09:14:54 MST
  3248. To: icon-group
  3249. Subject: Icon orders
  3250. Status: O
  3251.  
  3252. Orders for Icon material should be sent to icon-project@cs.arizona.edu,
  3253. *not* to icon-group@cs.arizona.edu.  Electronic mail to the icon-project goes
  3254. only to persons affiliated with the Icon Project at the University
  3255. of Arizona, while mail to icon-group goes to hundreds of persons all
  3256. over the world.
  3257.  
  3258. In particular, you should not post credit card information to icon-group.
  3259.  
  3260. For confidential material, send it directly to a person.  If in doubt,
  3261. send credit-card orders directly to me: ralph@cs.arizona.edu.
  3262.  
  3263.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  3264.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  3265.  
  3266. From icon-group-request@arizona.edu  Sun Jul  8 09:35:55 1990
  3267. Resent-From: icon-group-request@arizona.edu
  3268. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  3269.     id AA27371; Sun, 8 Jul 90 09:35:55 -0700
  3270. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Sun, 8 Jul 90 09:38 MST
  3271. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA16743; Sun, 8 Jul 90 09:20:21
  3272.  -0700
  3273. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3274.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3275.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3276. Resent-Date: Sun, 8 Jul 90 09:38 MST
  3277. Date: 6 Jul 90 00:04:23 GMT
  3278. From: att!mcdchg!ddsw1!corpane!disk!stevenw@ucbvax.Berkeley.EDU
  3279. Subject: RE: need icon project email address
  3280. Sender: icon-group-request@arizona.edu
  3281. Resent-To: icon-group@cs.arizona.edu
  3282. To: icon-group@arizona.edu
  3283. Resent-Message-Id: <6A4177C2DA5F4008CA@Arizona.EDU>
  3284. Message-Id: <3314@disk.UUCP>
  3285. Organization: Digital Information Systems of Ky (DISK), Louisville, Ky
  3286. X-Envelope-To: icon-group@CS.Arizona.EDU
  3287. X-Vms-To: icon-group@Arizona.edu
  3288. References: <325@happym.wa.com>
  3289. Status: O
  3290.  
  3291.  
  3292.  
  3293. Re: ICON address.
  3294.  
  3295. Their BBS number is (602) 621-2283  (Arizona).
  3296.  
  3297. I also have the following address for FTP:  cs.arizona.edu  (cd /icon)
  3298.  
  3299. Hope this helps
  3300. -- 
  3301. : Phone: (502) 425 9560   <<  Steven Weller  >>   Fax: (502) 426 3944 :
  3302. :   Windsor Systems, 2407 Lime Kiln Lane, Louisville, KY, 40222 USA   :
  3303. :      "A substance almost, but not quite, entirely unlike tea"       :
  3304. :        stevenw@disk.UUCP or uunet!ukma!corpane!disk!stevenw         :
  3305.  
  3306. From ralph  Wed Jul 11 09:06:34 1990
  3307. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  3308.     id AA06153; Wed, 11 Jul 90 09:06:34 -0700
  3309. Date: Wed, 11 Jul 90 09:06:30 MST
  3310. From: "Ralph Griswold" <ralph>
  3311. Message-Id: <9007111606.AA21919@cheltenham.cs.arizona.edu>
  3312. Received: by cheltenham.cs.arizona.edu; Wed, 11 Jul 90 09:06:30 MST
  3313. To: icon-group
  3314. Subject: electronic mail
  3315. Status: O
  3316.  
  3317. Someone has raised the question of security of electronic mail and
  3318. "confidentiality".
  3319.  
  3320. I assume everyone knows that electronic mail is anything but secure.
  3321. In using it for transmitting sensitive information, you're taking a
  3322. risk.
  3323.  
  3324. My point about e-mail regarding Icon is simply that the fewer persons
  3325. to which you transmit sensitive information, the less the risk is.
  3326. There is no way to eliminate risk completely, but you can minimize
  3327. it by being careful.
  3328.  
  3329. The Icon Project does not encourage orders of Icon material by
  3330. electronic mail. However, many persons find convenience outweighs
  3331. risk. It comes down to an individual decision.
  3332.  
  3333. Another issue is the potential confusion between the e-mail addresses
  3334. icon-project and icon-group. We use icon-group for the electronic news
  3335. function because that's the de facto naming standard on the network.
  3336. The address icon-project predated icon-group and it's been disseminated
  3337. so widely that we couldn't change it now without creating more problems
  3338. than we could hope to solve.
  3339.  
  3340. Do give some thought before addressing e-mail about Icon.  Use icon-project
  3341. for queries about Icon availability, trouble reports, and in general
  3342. for things that are not of significant interest to the Icon community. Use
  3343. icon-group for things you think may have wide interest. Realize that
  3344. e-mail to icon-group is redistributed to hundreds (possibly thousands)
  3345. of individuals.
  3346.  
  3347.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  3348.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  3349.  
  3350. From goer@sophist.uchicago.EDU  Mon Jul 16 10:11:57 1990
  3351. Resent-From: goer@sophist.uchicago.EDU
  3352. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3353.     id AA10081; Mon, 16 Jul 90 10:11:57 -0700
  3354. Return-Path: goer@sophist.uchicago.EDU
  3355. Received: from xtank.uchicago.edu by Arizona.EDU; Mon, 16 Jul 90 10:14 MST
  3356. Received: from sophist.uchicago.edu by xtank.uchicago.edu Mon, 16 Jul 90
  3357.  12:12:24 CDT
  3358. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA21287; Mon, 16 Jul 90
  3359.  12:07:54 CDT
  3360. Resent-Date: Mon, 16 Jul 90 10:14 MST
  3361. Date: Mon, 16 Jul 90 12:07:54 CDT
  3362. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  3363. Subject: Unix port of Alan Corre's prgm.
  3364. Resent-To: icon-group@cs.arizona.edu
  3365. To: icon-group@arizona.edu
  3366. Resent-Message-Id: <63F31AEF0E1F40424C@Arizona.EDU>
  3367. Message-Id: <9007161707.AA21287@sophist.uchicago.edu>
  3368. X-Envelope-To: icon-group@CS.Arizona.EDU
  3369. X-Vms-To: icon-group@Arizona.edu
  3370. Status: O
  3371.  
  3372. I just did a Unix port of Alan Corre's MS-DOS Jewish/Civil calendar
  3373. program.  I'm still in the process of working out the bugs.  Would
  3374. anyone like to volunteer to test it?  I've tried it out under Xenix,
  3375. BSD 4.2, and some others.  Need further input.  NB:  No support yet
  3376. for magic cookie terminals.
  3377.  
  3378.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  3379.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  3380.  
  3381. From goer@sophist.uchicago.EDU  Tue Jul 17 09:24:22 1990
  3382. Resent-From: goer@sophist.uchicago.EDU
  3383. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3384.     id AA14911; Tue, 17 Jul 90 09:24:22 -0700
  3385. Return-Path: goer@sophist.uchicago.EDU
  3386. Received: from xtank.uchicago.edu by Arizona.EDU; Tue, 17 Jul 90 09:26 MST
  3387. Received: from sophist.uchicago.edu by xtank.uchicago.edu Tue, 17 Jul 90
  3388.  11:24:36 CDT
  3389. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA23326; Tue, 17 Jul 90
  3390.  11:20:05 CDT
  3391. Resent-Date: Tue, 17 Jul 90 09:27 MST
  3392. Date: Tue, 17 Jul 90 11:20:05 CDT
  3393. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  3394. Subject: resend requests
  3395. Resent-To: icon-group@cs.arizona.edu
  3396. To: icon-group@arizona.edu
  3397. Resent-Message-Id: <6330949CB19F405636@Arizona.EDU>
  3398. Message-Id: <9007171620.AA23326@sophist.uchicago.edu>
  3399. X-Envelope-To: icon-group@CS.Arizona.EDU
  3400. X-Vms-To: icon-group@Arizona.edu
  3401. Status: O
  3402.  
  3403. I clobbered several requests I had queued for find_re and for the test
  3404. version of the port of Alan Corre's program.  Could those who sent them
  3405. perhaps resend these requests.  I feel terrible.  Sorry.
  3406. -Richard
  3407.  
  3408. From icon-group-request@arizona.edu  Thu Jul 19 09:09:51 1990
  3409. Resent-From: icon-group-request@arizona.edu
  3410. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3411.     id AA13990; Thu, 19 Jul 90 09:09:51 -0700
  3412. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 19 Jul 90 09:12 MST
  3413. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA00445; Thu, 19 Jul 90
  3414.  08:53:01 -0700
  3415. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3416.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3417.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3418. Resent-Date: Thu, 19 Jul 90 09:12 MST
  3419. Date: 18 Jul 90 13:38:23 GMT
  3420. From: amdahl!ntmtv!hildum@sun.COM
  3421. Subject: Enhanced colmize procedure
  3422. Sender: icon-group-request@arizona.edu
  3423. Resent-To: icon-group@cs.arizona.edu
  3424. To: icon-group@arizona.edu
  3425. Resent-Message-Id: <61A0405B267F405BCD@Arizona.EDU>
  3426. Message-Id: <1414@ntmtv.UUCP>
  3427. Organization: Northern Telecom (Mountain View, CA)
  3428. X-Envelope-To: icon-group@CS.Arizona.EDU
  3429. X-Vms-To: icon-group@Arizona.edu
  3430. Status: O
  3431.  
  3432. I have made a modification to colmize to allow a tag field to be added
  3433. to the data. The tag will count against the maxcols in determining the
  3434. arrangement of data. The resulting output will appear as follows:
  3435.  
  3436. tag  data1  data3  data5  data7  data9  data11 data13 data15 data17
  3437.      data2  data4  data6  data8  data10 data12 data14 data16 data18
  3438.  
  3439. ---------------- Cut here------------------------------------------
  3440. ############################################################################
  3441. #
  3442. #    Name:    colmize.icn
  3443. #
  3444. #    Title:    Arrange data into columns
  3445. #
  3446. #    Author:    Robert J. Alexander
  3447. #
  3448. #    Date:    December 5, 1989
  3449. #
  3450. #
  3451. #    Modification History
  3452. #
  3453. #    15-Jun-1990 Eric Hildum        Added tag field.
  3454. ############################################################################
  3455. #
  3456. #  colmize() -- Arrange data into columns.
  3457. #
  3458. #  Procedure to arrange a number of data items into multiple columns.
  3459. #  Items are arranged in column-wise order, that is, the sequence runs
  3460. #  down the first column, then down the second, etc.
  3461. #
  3462. #  This procedure goes to great lengths to print the items in as few
  3463. #  vertical lines as possible.
  3464. #
  3465. ############################################################################
  3466.  
  3467. procedure colmize(entries,maxcols,space,minwidth,tag,tagspace,tagminwidth,rowwise,distribute)
  3468.    local mean,cols,lines,width,i,x,wid,extra,t,j,first_tagfield,tagfield
  3469.    #
  3470.    #  Process arguments -- provide defaults.
  3471.    #
  3472.    # entries: a list of items to be columnized
  3473.    /maxcols := 80                        # max width of output lines
  3474.    /space := 2                           # min nbr of spaces between columns
  3475.    /minwidth := 0                        # min column width
  3476.    # tag: a label to be placed on the first line of output
  3477.    /tagminwidth := 0
  3478.    /tagspace := 2
  3479.    # rowwise: if nonnull, entries are listed in rowwise order rather than
  3480.    # columnwise
  3481.    #
  3482.    #
  3483.    #  Process the tag field information. The tag will appear on the
  3484.    #  first line to the left of the data.
  3485.    #
  3486.    if \tag then {
  3487.       tagminwidth <:= *tag + tagspace
  3488.       maxcols -:= tagminwidth
  3489.       first_tagfield := left(tag, tagminwidth - tagspace) || repl(" ",tagspace)
  3490.       tagfield := repl(" ",tagminwidth)
  3491.    } else 
  3492.       tagfield := first_tagfield := ""
  3493.    #  Starting with a trial number-of-columns that is guaranteed
  3494.    #  to be too wide, successively reduce the number until the
  3495.    #  items can be packed into the allotted width.
  3496.    #
  3497.    mean := 0
  3498.    every mean +:= *!entries
  3499.    mean := mean / (0 ~= *entries) | 1
  3500.    every cols := (maxcols + space) * 2 / (mean + space) to 1 by -1 do {
  3501.       lines := (*entries + cols - 1) / cols
  3502.       width := list(cols,minwidth)
  3503.       i := 0
  3504.       if /rowwise then {                  # if column-wise
  3505.      every x := !entries do {
  3506.         width[i / lines + 1] <:= *x + space
  3507.         i +:= 1
  3508.         }
  3509.      }
  3510.       else {                              # else row-wise
  3511.      every x := !entries do {
  3512.         width[i % cols + 1] <:= *x + space
  3513.         i +:= 1
  3514.         }
  3515.      }
  3516.       wid := 0
  3517.       every x := !width do wid +:= x
  3518.       if wid <= maxcols + space then break
  3519.       }
  3520.    #
  3521.    #  Now output the data in columns.
  3522.    #
  3523.    extra := (\distribute & (maxcols - wid) / (0 < cols - 1)) | 0
  3524.    if /rowwise then {            # if column-wise
  3525.       every i := 1 to lines do {
  3526.          if i = 1 then
  3527.             t := first_tagfield
  3528.          else
  3529.             t := tagfield
  3530.      every j := 0 to cols - 1 do
  3531.            t ||:= left(entries[i + j * lines],width[j + 1] + extra)
  3532.      suspend trim(t)
  3533.      }
  3534.       }
  3535.    else {                                # else row-wise
  3536.       every i := 0 to lines - 1 do {
  3537.          if i = 0 then
  3538.             t := first_tagfield
  3539.          else
  3540.             t := tagfield
  3541.      every j := 1 to cols do
  3542.            t ||:= left(entries[j + i * cols],width[j] + extra)
  3543.      suspend trim(t)
  3544.      }
  3545.       }
  3546. end
  3547.  
  3548. From icon-group-request@arizona.edu  Thu Jul 19 20:09:24 1990
  3549. Resent-From: icon-group-request@arizona.edu
  3550. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3551.     id AA15325; Thu, 19 Jul 90 20:09:24 -0700
  3552. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 19 Jul 90 20:12 MST
  3553. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA13549; Thu, 19 Jul 90
  3554.  20:07:53 -0700
  3555. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3556.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3557.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3558. Resent-Date: Thu, 19 Jul 90 20:12 MST
  3559. Date: 19 Jul 90 12:49:43 GMT
  3560. From: decvax.dec.com!elrond!shodsdon@mcnc.ORG
  3561. Subject: Wanted: latest ICON
  3562. Sender: icon-group-request@arizona.edu
  3563. Resent-To: icon-group@cs.arizona.edu
  3564. To: icon-group@arizona.edu
  3565. Resent-Message-Id: <61441E22F21F405F52@Arizona.EDU>
  3566. Message-Id: <2838@elrond.CalComp.COM>
  3567. Organization: Calcomp Display Products Division, Hudson, NH, USA
  3568. X-Envelope-To: icon-group@CS.Arizona.EDU
  3569. X-Vms-To: icon-group@Arizona.edu
  3570. Status: O
  3571.  
  3572. I'm looking for the latest sources for icon. The only version that I have
  3573. worked with is ver 6 on the mac (MPW).
  3574.  
  3575. Tks.
  3576.  
  3577. -- 
  3578. Steve Hodsdon                          | Keep sane inside insanity.
  3579. shodsdon@elrond.CalComp.COM            | Don't dream it, be it.
  3580. {decvax|harvard}!elrond!shodsdon       |
  3581. (603) 885-8324                         |
  3582.  
  3583. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Sat Jul 21 01:03:37 1990
  3584. Received: from umich.edu by megaron (5.61/15) via SMTP
  3585.     id AA16704; Sat, 21 Jul 90 01:03:37 -0700
  3586. Received: from ummts.cc.umich.edu by umich.edu (5.61/1123-1.0)
  3587.     id AA27857; Sat, 21 Jul 90 04:03:32 -0400
  3588. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 21 Jul 90 04:03:23 EDT
  3589. Date: Fri, 20 Jul 90 23:07:30 EDT
  3590. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  3591. To: icon-group@cs.arizona.edu
  3592. Message-Id: <239208@Wayne-MTS>
  3593. Subject: Semantics of break break
  3594. Status: O
  3595.  
  3596.  
  3597. You can break out of two loops at once by using "break break", which
  3598. can even return a value.  For instance, the program:
  3599.  
  3600. procedure main()
  3601.     write(
  3602.         every i := 10 to 30 by 10 do every j := 1 to 4 do
  3603.             {write(i+j); if i+j=23 then break break "outer"}
  3604.     )
  3605. end
  3606.  
  3607. prints 11 12 13 14 21 22 23 outer (on several lines).
  3608.  
  3609. However, a reading of the new (or old) Icon book does not make it at all clear
  3610. why this should work.  On p. 285 it states that break x produces the outcome
  3611. of x, and on p. it states that outcomes include results (values and variables)
  3612. as well as failure. But if x is "break 2", this is neither a result nor
  3613. failure. 
  3614.  
  3615. I think I understand what break does, but I don't understand how I'm supposed
  3616. to think about it.
  3617.  
  3618. Paul Abrahams
  3619.  
  3620. From sbw@turing  Sat Jul 21 06:49:06 1990
  3621. Received: from turing (turing.cse.nau.edu) by megaron (5.61/15) via SMTP
  3622.     id AA00102; Sat, 21 Jul 90 06:49:06 -0700
  3623. Received: by turing (5.57/1.34)
  3624.     id AA02352; Sat, 21 Jul 90 06:48:02 MST
  3625. Message-Id: <9007211348.AA02352@turing>
  3626. From: sbw@turing (Steve Wampler)
  3627. Date: Sat, 21 Jul 1990 06:48:01 MST
  3628. In-Reply-To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu's mail message of Jul 21,  1:04.
  3629. X-Mailer: Mail User's Shell (7.1.1 5/02/90)
  3630. To: icon-group@cs.arizona.edu
  3631. Subject: Re: Semantics of break break
  3632. Status: O
  3633.  
  3634. I think the easiest way to think about 'break expr' is that it is
  3635. a control structure where first the break is performed and then the
  3636. expression is evaluated.  This has the effect that the expression
  3637. is evaluated in the context surrounding the loop, not within the loop.
  3638.  
  3639. -- 
  3640.     Steve Wampler
  3641.     {....!arizona!naucse!sbw}
  3642.     {sbw@naucse.cse.nau.edu}
  3643.  
  3644. From kwalker  Sat Jul 21 19:32:05 1990
  3645. Date: Sat, 21 Jul 90 19:32:05 -0700
  3646. From: "Kenneth Walker" <kwalker>
  3647. Message-Id: <9007220232.AA24868@megaron.cs.arizona.edu>
  3648. Received: by megaron.cs.arizona.edu (5.61/15)
  3649.     id AA24868; Sat, 21 Jul 90 19:32:05 -0700
  3650. To: icon-group
  3651. Subject: Re: Semantics of break break
  3652. Status: O
  3653.  
  3654. > Date: Fri, 20 Jul 90 23:07:30 EDT
  3655. > From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  3656. >  
  3657. > I think I understand what break does, but I don't understand how I'm supposed
  3658. > to think about it.
  3659.  
  3660. I was told that break is designed to act as if the loop were replaced
  3661. by the expression. That is, that it is supposed to act like textual
  3662. substitution. This applies to the value produced, goal-directed evaluation,
  3663. other breaks, etc. I find this view very helpful.
  3664.  
  3665.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  3666.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  3667.  
  3668. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Sun Jul 22 13:08:01 1990
  3669. Received: from umich.edu by megaron (5.61/15) via SMTP
  3670.     id AA00454; Sun, 22 Jul 90 13:08:01 -0700
  3671. Received: from ummts.cc.umich.edu by umich.edu (5.61/1123-1.0)
  3672.     id AA01175; Sun, 22 Jul 90 16:07:57 -0400
  3673. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sun, 22 Jul 90 16:07:39 EDT
  3674. Date: Sun, 22 Jul 90 12:05:30 EDT
  3675. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  3676. To: icon-group@cs.arizona.edu
  3677. Message-Id: <239317@Wayne-MTS>
  3678. Subject: Semantics of break break
  3679. Status: O
  3680.  
  3681. The interesting thing about
  3682.    break (break 2)
  3683. is that the argument of the first break is returned *unevaluated* as the
  3684. result of the inner loop.  Are there any other places in Icon where
  3685. unevaluated expressions are returned?  I can't think of any.
  3686.  
  3687. Paul Abrahams
  3688.  
  3689. From sbw@turing  Sun Jul 22 13:44:33 1990
  3690. Received: from turing (turing.cse.nau.edu) by megaron (5.61/15) via SMTP
  3691.     id AA01450; Sun, 22 Jul 90 13:44:33 -0700
  3692. Received: by turing (5.57/1.34)
  3693.     id AA03438; Sun, 22 Jul 90 13:43:22 MST
  3694. Message-Id: <9007222043.AA03438@turing>
  3695. From: sbw@turing (Steve Wampler)
  3696. Date: Sun, 22 Jul 1990 13:43:22 MST
  3697. In-Reply-To: Mail Delivery Subsystem's mail message of Jul 22, 13:40.
  3698. X-Mailer: Mail User's Shell (7.1.1 5/02/90)
  3699. To: icon-group@cs.arizona.edu
  3700. Subject: Re: Returned mail: Host unknown
  3701. Status: O
  3702.  
  3703. Subject: Re: Semantics of break break
  3704.  
  3705. Hmmm, maybe it isn't proper to think of break as having an argument.
  3706.  
  3707. That is, one normally doesn't consider the 'then' or 'else' clause
  3708. of an 'if-then-else' as being an argument, per se.
  3709.  
  3710. Break is a control structure that evaluates an expression (its
  3711. 'argument') after performing the loop break.  Is that all that
  3712. different than an if returning the outcome of its else clause?
  3713. In both cases the control flow has occurred before evaluation.
  3714.  
  3715.  
  3716. -- 
  3717.     Steve Wampler
  3718.     {....!arizona!naucse!sbw}
  3719.     {sbw@naucse.cse.nau.edu}
  3720.  
  3721. From goer@sophist.uchicago.EDU  Sun Jul 22 15:14:28 1990
  3722. Resent-From: goer@sophist.uchicago.EDU
  3723. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3724.     id AA04336; Sun, 22 Jul 90 15:14:28 -0700
  3725. Return-Path: goer@sophist.uchicago.EDU
  3726. Received: from xtank.uchicago.edu by Arizona.EDU; Sun, 22 Jul 90 15:15 MST
  3727. Received: from sophist.uchicago.edu by xtank.uchicago.edu Sun, 22 Jul 90
  3728.  17:13:52 CDT
  3729. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA00920; Sun, 22 Jul 90
  3730.  17:09:21 CDT
  3731. Resent-Date: Sun, 22 Jul 90 15:16 MST
  3732. Date: Sun, 22 Jul 90 17:09:21 CDT
  3733. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  3734. Subject: break, goto
  3735. Resent-To: icon-group@cs.arizona.edu
  3736. To: icon-group@arizona.edu
  3737. Resent-Message-Id: <5F11E3F3A05F40730F@Arizona.EDU>
  3738. Message-Id: <9007222209.AA00920@sophist.uchicago.edu>
  3739. X-Envelope-To: icon-group@CS.Arizona.EDU
  3740. X-Vms-To: icon-group@Arizona.edu
  3741. Status: O
  3742.  
  3743. Having break act as a control structure has helped me avoid a helluva
  3744. lot of kludgy constructions (which in C would normally be uncluttered
  3745. with a goto).  E.g. I occasionally have reason to write
  3746.  
  3747.   every i := 1 to 2 do {
  3748.     every j := 1 to 10 do {
  3749.       i+j = 5 & {break next}
  3750.       }
  3751.     }
  3752.  
  3753. Naturally, there are ways to code this without using the break.  It's
  3754. a nice bit of sugar, though, isn't it?
  3755.  
  3756.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  3757.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  3758.  
  3759. From goer@sophist.uchicago.EDU  Mon Jul 23 12:27:13 1990
  3760. Resent-From: goer@sophist.uchicago.EDU
  3761. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3762.     id AA19723; Mon, 23 Jul 90 12:27:13 -0700
  3763. Return-Path: goer@Arizona.edu
  3764. Received: from xtank.uchicago.edu by Arizona.EDU; Mon, 23 Jul 90 12:29 MST
  3765. Received: from sophist.uchicago.edu by xtank.uchicago.edu Mon, 23 Jul 90
  3766.  14:27:43 CDT
  3767. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA01435; Mon, 23 Jul 90
  3768.  01:49:18 CDT
  3769. Resent-Date: Mon, 23 Jul 90 12:30 MST
  3770. Date: Mon, 23 Jul 90 01:49:18 CDT
  3771. From: Richard Goerwitz <goer@sophist.uchicago.EDU>
  3772. Subject: Icon yacc
  3773. Resent-To: icon-group@cs.arizona.edu
  3774. To: icon-group@arizona.edu
  3775. Resent-Message-Id: <5E60031C989FA00B4F@Arizona.EDU>
  3776. Message-Id: <9007230649.AA01435@sophist.uchicago.edu>
  3777. X-Envelope-To: icon-group@CS.Arizona.EDU
  3778. X-Vms-To: icon-group@Arizona.edu
  3779. Status: O
  3780.  
  3781. Has anyone at any point felt a desire to create an Icon yacc
  3782. program?  I'm just curious.  Such a utility could be very
  3783. useful.  Maybe yacc is the wrong term.  Yaicc?  Yuck.
  3784.  
  3785. Anyway, the question is a serious one.
  3786.  
  3787.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  3788.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  3789.  
  3790. From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU  Mon Jul 23 12:47:42 1990
  3791. Received: from noao.edu by megaron (5.61/15) via SMTP
  3792.     id AA20372; Mon, 23 Jul 90 12:47:42 -0700
  3793. Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G43)
  3794.     id AA08435; Mon, 23 Jul 90 12:47:38 MST; for icon-group@cs.arizona.edu
  3795. Received: by ncar.ucar.EDU (5.64/ NCAR Central Post Office 04/10/90)
  3796.     id AA11120; Mon, 23 Jul 90 13:47:38 MDT
  3797. Received: from xtank.uchicago.edu by oddjob.uchicago.edu Mon, 23 Jul 90 14:25:27 -0500
  3798. Received: from sophist.uchicago.edu by xtank.uchicago.edu Mon, 23 Jul 90 14:26:59 CDT
  3799. Return-Path: <goer@zenu.uucp>
  3800. Received:  by sophist.uchicago.edu (3.2/UofC3.0)
  3801.     id AA01963; Mon, 23 Jul 90 12:46:20 CDT
  3802. Received: by sophist.uchicago.edu (smail2.5)
  3803.     id AA00244; 23 Jul 90 10:26:18 PDT (Mon)
  3804. Subject: scanning lists & not just strings
  3805. To: icon-group@arizona.edu
  3806. Date: Mon, 23 Jul 90 10:26:18 PDT
  3807. X-Mailer: ELM [version 2.2 PL0]
  3808. Message-Id: <9007231026.AA00244@sophist.uchicago.edu>
  3809. From: goer@sophist.uchicago.edu (Richard Goerwitz)
  3810. Status: O
  3811.  
  3812. A few months ago, some kind soul send me some examples of generalized
  3813. scanning routines for data types other than strings.  I remember look-
  3814. ing them over, thinking that they looked interesting, and then delet-
  3815. ing them because I felt I wouldn't use them.
  3816.  
  3817. Hmmm.
  3818.  
  3819. Almost as soon as I threw the sample code away, I became embroiled in
  3820. several projects that required me to tokenize strings, and then essen-
  3821. tially "scan" lists.  At first I did this in an ad hoc fashion.  After
  3822. a few weeks of this, however, I realized that a set of generalized list
  3823. scanning routines would be better.
  3824.  
  3825. Anyway, I've written a set of routines, l_tab, l_move, l_match, l_pos,
  3826. etc., which transpose string-like scanning functions to lists.  They
  3827. correctly handle nesting of list scanning, and what not.  I seem to
  3828. recall some discussion of how scanning might be generalized to lists
  3829. a few months back.  If anyone is still interested, I'd be happy to
  3830. send them my library of l_ functions.
  3831.  
  3832. -- 
  3833.  
  3834.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  3835.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  3836.  
  3837. From icon-group-request@arizona.edu  Mon Jul 23 18:57:46 1990
  3838. Resent-From: icon-group-request@arizona.edu
  3839. Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3840.     id AA09302; Mon, 23 Jul 90 18:57:46 -0700
  3841. Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Mon, 23 Jul 90 19:00 MST
  3842. Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA26427; Mon, 23 Jul 90
  3843.  18:42:19 -0700
  3844. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3845.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3846.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3847. Resent-Date: Mon, 23 Jul 90 19:00 MST
  3848. Date: 24 Jul 90 01:07:55 GMT
  3849. From: cca.ucsf.edu!root@cgl.ucsf.EDU
  3850. Subject: RE: Wanted: latest ICON
  3851. Sender: icon-group-request@arizona.edu
  3852. Resent-To: icon-group@cs.arizona.edu
  3853. To: icon-group@arizona.edu
  3854. Resent-Message-Id: <5E2973D7903FA00BA3@Arizona.EDU>
  3855. Message-Id: <3036@ucsfcca.ucsf.edu>
  3856. Organization: Computer Center, UCSF
  3857. X-Envelope-To: icon-group@CS.Arizona.EDU
  3858. X-Vms-To: icon-group@Arizona.edu
  3859. References: <2838@elrond.CalComp.COM>
  3860. Status: O
  3861.  
  3862. In article <2838@elrond.CalComp.COM>, shodsdon@elrond.CalComp.COM (Steve V. Hodsdon) writes:
  3863. > I'm looking for the latest sources for icon. The only version that I have
  3864. > worked with is ver 6 on the mac (MPW).
  3865.  
  3866. Version 8 is now available from cs.arizona.edu [128.196.128.118]
  3867. by anonymous FTP.
  3868.  
  3869.  Thos Sumner       Internet: thos@cca.ucsf.edu
  3870.  (The I.G.)        UUCP: ...ucbvax!ucsfcgl!cca.ucsf!thos
  3871.                    BITNET:  thos@ucsfcca
  3872.  
  3873.  U.S. Mail:  Thos Sumner, Computer Center, Rm U-76, UCSF
  3874.              San Francisco, CA 94143-0704 USA
  3875.  
  3876. I hear nothing in life is certain but death and taxes -- and they're
  3877. working on death.
  3878.  
  3879. #include <disclaimer.std>
  3880.  
  3881. From goer@sophist.uchicago.edu  Tue Jul 24 11:29:30 1990
  3882. Resent-From: goer@sophist.uchicago.edu
  3883. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  3884.     id AA20121; Tue, 24 Jul 90 11:29:30 -0700
  3885. Return-Path: goer@sophist.uchicago.edu
  3886. Received: from xtank.uchicago.edu by Arizona.edu; Tue, 24 Jul 90 11:31 MST
  3887. Received: from sophist.uchicago.edu by xtank.uchicago.edu Tue, 24 Jul 90
  3888.  13:29:46 CDT
  3889. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA03438; Tue, 24 Jul 90
  3890.  13:25:14 CDT
  3891. Resent-Date: Tue, 24 Jul 90 11:32 MST
  3892. Date: Tue, 24 Jul 90 13:25:14 CDT
  3893. From: Richard Goerwitz <goer@sophist.uchicago.edu>
  3894. Subject: list scanning; here it is
  3895. Resent-To: icon-group@cs.arizona.edu
  3896. To: icon-group@arizona.edu
  3897. Resent-Message-Id: <5D9EEE753E9FA0182F@Arizona.edu>
  3898. Message-Id: <9007241825.AA03438@sophist.uchicago.edu>
  3899. X-Envelope-To: icon-group@CS.Arizona.EDU
  3900. X-Vms-To: icon-group@Arizona.EDU
  3901. Status: O
  3902.  
  3903. I've been swamped with requests for my list scanning routines.
  3904. This was quite unexpected.  I sometimes post programs that I
  3905. think will be of great general interest, only to get two or
  3906. three responses.  This last time, I didn't post code because
  3907. I couldn't imagine more than two or three people wanting list
  3908. scanning routines.  The opposite seems to have been the case.
  3909.  
  3910. With a somewhat red face, I'm going to do an about-face, and
  3911. post the list scanning code.
  3912.  
  3913.  
  3914.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  3915.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  3916.  
  3917.  
  3918. ############################################################################
  3919. #
  3920. #    Name:    lscan.icn
  3921. #
  3922. #    Title:    Quasi ? scanning routines for lists.
  3923. #
  3924. #    Author:    Richard L. Goerwitz
  3925. #
  3926. #    Date:    7/24/90 (version 1.10)
  3927. #
  3928. ############################################################################
  3929. #
  3930. #  Copyright (c) 1990, Richard L. Goerwitz, III
  3931. #
  3932. #  This software is intended for free and unrestricted distribution.
  3933. #  I place only two conditions on its use:  1) That you clearly mark
  3934. #  any additions or changes you make to the source code, and 2) that
  3935. #  you do not delete this message from it.  In order to protect
  3936. #  myself from spurious litigation, it must also be stated here that,
  3937. #  because this is free software, I, Richard Goerwitz, make no claim
  3938. #  about the applicability or fitness of this software for any
  3939. #  purpose, and disclaim any responsibility for any damages that
  3940. #  might be incurred in conjunction with its use.
  3941. #
  3942. ############################################################################
  3943. #
  3944. #  PURPOSE: String scanning is terriffic, but often I am forced to
  3945. #  tokenize and work with lists.  So as to make operations on these
  3946. #  lists as close to corresponding string operations as possible, I've
  3947. #  implemented a series of list analogues to any(), find(), many(),
  3948. #  match(), move(), pos(), tab(), and upto().  Their names are just
  3949. #  like corresponding string functions, except with a prepended "l_"
  3950. #  (e.g. l_any()).  Since Icon does not permit me to define new
  3951. #  control structures via infix operators, list scanning must be
  3952. #  initialized via a procedure, namely l_scan(l), where l is the list
  3953. #  to be scanned.  Scanning is ended by calling end_l_scan(l).
  3954. #  Nesting is permitted, but you'd better make sure your indentation
  3955. #  is correct.  Since l_scan() does not represent a real control
  3956. #  structure, you must call end_l_scan() before "breaking" from an
  3957. #  l_scan.  Otherwise l_POS and l_SUBJ will not be handled properly.
  3958. #
  3959. #  If someone can think of a way to do this more elegantly let me
  3960. #  know.  Personally, I'd like p{a,b,c} to be extended to allow
  3961. #  p{a;b;c} (where ; = ; or a newline).  I could then do something
  3962. #  like 
  3963. #
  3964. #      l_scan {
  3965. #          a
  3966. #          b
  3967. #          c
  3968. #      }
  3969. #
  3970. #  Now that's a user-defined control structure.  (How, though, would
  3971. #  we work variable args into this scheme?)
  3972. #
  3973. #  I envision l_scan being used (and in fact use it myself) to parse
  3974. #  trees and compare complicated list structures.  One big time-saver
  3975. #  in parsing natural languages, for instance, is to store partial
  3976. #  trees.  The l_scan routines enable you to take your list structures
  3977. #  and say, "Give me that portion of list 2 which corresponds
  3978. #  structurally to list 1."  Or you can say, "Tell me if the first
  3979. #  portion of x list corresponds structurally to y."  In effect, the
  3980. #  structure of the tree can be checked without necessitating a
  3981. #  reparse.
  3982. #
  3983. #  BUGS:  Can you say slow?  I thought you could.
  3984. #
  3985. ############################################################################
  3986. #
  3987. #  Here's a trivial example of how one might utilize the lscan routines:
  3988. #
  3989. #  procedure main()
  3990. #
  3991. #      l := ["h","e","l","l","o"," ","t","t","t","h","e","r","e"]
  3992. #
  3993. #      l_scan(l)
  3994. #          hello_list := l_tab(l_match(["h","e","l","l","o"]))
  3995. #          every writes(!hello_list)
  3996. #          write()
  3997. #
  3998. #       l_scan(l_tab(0))
  3999. #           l_tab(l_many([[" "],["t"]]) - 1)
  4000. #              every writes(!l_tab(0))
  4001. #           write()
  4002. #          end_l_scan()
  4003. #  
  4004. #      end_l_scan()
  4005. #  
  4006. #  end
  4007. #
  4008. #  The above program simply writes "hello" and "there" on successive
  4009. #  lines to the standard output.
  4010. #
  4011. #  PITFALLS: In general, note that we are comparing lists here instead
  4012. #  of strings, so l_find("h", l), for instance, will yield an error
  4013. #  message (use l_find(["h"], l) instead).  The point at which I
  4014. #  expect this nuance will be most confusing will be in cases where
  4015. #  one is looking for lists within lists.  Suppose we have a list,
  4016. #
  4017. #      l1 := ["junk",[["hello"]," ",["there"]],"!","m","o","r","e","junk"]
  4018. #
  4019. #  and suppose, morover, that we wish to find the position in l1 at
  4020. #  which the list
  4021. #
  4022. #      [["hello"]," ",["there"]]
  4023. #
  4024. #  occurs.  If, say, we assign [["hello"]," ",["there"]] to the
  4025. #  variable l2, then our l_find() expression will need to look like
  4026. #
  4027. #      l_scan(l1)
  4028. #          l_tab(l_find([l2]))
  4029. #      etc.
  4030. #
  4031. #  The reason l2 must be enclosed within a list is that we are
  4032. #  searching for a single element within l1, not a series of three
  4033. #  elements.  Hence, just as l_find("h") would not work correctly
  4034. #  above, so l_find(l2) will not work here (although in this latter
  4035. #  case, no error message is generated; the expression merely fails
  4036. #  when it finds no sequence of elements in l1 corresponding to the
  4037. #  sequence of elements occurring in l2).
  4038. #
  4039. ############################################################################
  4040.  
  4041. global l_POS
  4042. global l_SUBJ
  4043.  
  4044.  
  4045. procedure l_scan(l)
  4046.  
  4047.     if /l_POS then {
  4048.     l_POS  := []
  4049.     l_SUBJ := []
  4050.     }
  4051.  
  4052.     push(l_POS, 1)
  4053.     push(l_SUBJ, l)
  4054.     return
  4055.  
  4056. end
  4057.  
  4058.  
  4059.  
  4060. procedure end_l_scan()
  4061.  
  4062.     every pop(l_POS|l_SUBJ)
  4063.     if *l_POS = 0 then {
  4064.     l_POS  := &null
  4065.     l_SUBJ := &null
  4066.     }
  4067.     return
  4068.  
  4069. end
  4070.  
  4071.  
  4072.  
  4073. procedure l_move(i)
  4074.  
  4075.     /i & stop("l_move:  Null argument.")
  4076.     if /l_POS | /l_SUBJ
  4077.     then stop("l_move:  Call l_scan first.")
  4078.  
  4079.     suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1 >= l_POS[1]+i))]
  4080.  
  4081. end
  4082.  
  4083.  
  4084.  
  4085. procedure l_tab(i)
  4086.  
  4087.     /i & stop("l_tab:  Null argument.")
  4088.     if /l_POS | /l_SUBJ
  4089.     then stop("l_tab:  Call l_scan first.")
  4090.  
  4091.     if i = 0
  4092.     then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- *l_SUBJ[1]+1]
  4093.     else {
  4094.     if i < 0
  4095.     then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1) + i)]
  4096.     else suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (*l_SUBJ[1]+1 >= i)]
  4097.     }
  4098.  
  4099. end
  4100.  
  4101.  
  4102.  
  4103. procedure l_any(l1,l2,i,j)
  4104.  
  4105.     # Like any(c,s2,i,j) except that the string & cset arguments are
  4106.     # replaced by list arguments.  l1 must be a list of one-element
  4107.     # lists, while l2 can be any list (l_SUBJ[1] by default).
  4108.  
  4109.     local sub_l
  4110.  
  4111.     /l1 & stop("l_any:  Null first argument!")
  4112.     if /l_POS | /l_SUBJ
  4113.     then stop("l_any:  Call l_scan first.")
  4114.     if type(l1) == "set" then l1 := sort(l1)
  4115.  
  4116.     /l2 := l_SUBJ[1]
  4117.     /i  := \l_POS[1] | 1
  4118.     /j  := *l_SUBJ[1]+1
  4119.  
  4120.     every sub_l := !l1 do {
  4121.     if not (type(sub_l) == "list", *sub_l = 1) then
  4122.         stop("l_any:  Elements of l1 must be lists of length 1.")
  4123.     if x := l_match(sub_l,l2,i,i+1)
  4124.     then return x
  4125.     }
  4126.     
  4127. end
  4128.  
  4129.  
  4130.  
  4131. procedure l_match(l1,l2,i,j)
  4132.  
  4133.     # Analogous to match(s1,s2,i,j), except that s1 and s2 are lists,
  4134.     # and l_match returns the next position in l2 after that portion
  4135.     # (if any) which is structurally identical to l1.  If a match is not
  4136.     # found, l_match fails.
  4137.  
  4138.     if /l1
  4139.     then stop("l_match:  Null first argument!")
  4140.     if /l_POS | /l_SUBJ
  4141.     then stop("l_match:  Call l_scan first.")
  4142.     if type(l1) ~== "list"
  4143.     then stop("l_match:  Call me with a list as the first arg.")
  4144.  
  4145.     /l2 := l_SUBJ[1]
  4146.     /i  := \l_POS[1] | 1
  4147.     /j  := *l_SUBJ[1]+1
  4148.  
  4149.     if l_comp(l1,l2[i+:*l1])
  4150.     then return i + *l1
  4151.  
  4152. end
  4153.  
  4154.     
  4155.  
  4156. procedure l_comp(l1,l2)
  4157.  
  4158.     # List comparison routine basically taken from Griswold & Griswold
  4159.     # (1st ed.), p. 174.
  4160.  
  4161.     local i
  4162.  
  4163.     /l1 | /l2 & stop("l_comp:  Null argument!")
  4164.     l1 === l2 & return l2
  4165.  
  4166.     if type(l1) == type(l2) == "list" then {
  4167.     *l1 ~= *l2 & fail
  4168.     every i := 1 to *l1
  4169.     do l_comp(l1[i],l2[i]) | fail
  4170.     return l2
  4171.     }
  4172.  
  4173. end
  4174.  
  4175.  
  4176.  
  4177. procedure l_find(l1,l2,i,j)
  4178.  
  4179.     local x
  4180.  
  4181.     /l1 & stop("l_find:  Null first argument!")
  4182.     if /l_POS | /l_SUBJ
  4183.     then stop("l_find:  Call l_scan first.")
  4184.  
  4185.     /l2 := l_SUBJ[1]
  4186.     /i  := \l_POS[1] | 1
  4187.     /j  := *l_SUBJ[1]+1
  4188.  
  4189.     every x := i to ((*l2+1) - *l1) do {
  4190.     if l_match(l1,l2,x,j)
  4191.     then suspend x
  4192.     }
  4193.     
  4194. end
  4195.  
  4196.  
  4197.  
  4198. procedure l_upto(l1,l2,i,j)
  4199.  
  4200.     local x
  4201.  
  4202.     /l1 & stop("l_upto:  Null first argument!")
  4203.     if /l_POS | /l_SUBJ
  4204.     then stop("l_upto:  Call l_scan first.")
  4205.     if type(l1) == "set" then l1 := sort(l1)
  4206.  
  4207.     /l2 := l_SUBJ[1]
  4208.     /i  := \l_POS[1] | 1
  4209.     /j  := *l_SUBJ[1]+1
  4210.  
  4211.     every x := i to ((*l2+1) - *l1) do {
  4212.     if l_any(l1,l2,x,j)
  4213.     then suspend x
  4214.     }
  4215.     
  4216. end
  4217.  
  4218.  
  4219.  
  4220. procedure l_many(l1,l2,i,j)
  4221.  
  4222.     /l1 & stop("l_many:  Null first argument!")
  4223.     if /l_POS | /l_SUBJ
  4224.     then stop("l_many:  Call l_scan first.")
  4225.     if type(l1) == "set" then l1 := sort(l1)
  4226.  
  4227.     /l2 := l_SUBJ[1]
  4228.     /i  := \l_POS[1] | 1
  4229.     /j  := *l_SUBJ[1]+1
  4230.  
  4231.     l_scan(l2)
  4232.     while x := l_any(l1,,,j)
  4233.     do l_tab(x)
  4234.     end_l_scan(l2)
  4235.  
  4236.     return \x
  4237.  
  4238. end
  4239.  
  4240.  
  4241.  
  4242. procedure l_pos(i)
  4243.  
  4244.     local x
  4245.  
  4246.     if /l_POS | /l_SUBJ
  4247.     then stop("l_many:  Call l_scan first.")
  4248.  
  4249.     if i <= 0
  4250.     then x := 0 < (*l_SUBJ[1]+1 >= (*l_SUBJ[1]+1)+i) | fail
  4251.     else x := 0 < (*l_SUBJ[1]+1 >= i) | fail
  4252.  
  4253.     if x = l_POS[1]
  4254.     then return i
  4255.     else fail
  4256.  
  4257. end
  4258.  
  4259. From goer@sophist.uchicago.edu  Tue Jul 24 21:16:32 1990
  4260. Resent-From: goer@sophist.uchicago.edu
  4261. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4262.     id AA17441; Tue, 24 Jul 90 21:16:32 -0700
  4263. Return-Path: goer@sophist.uchicago.edu
  4264. Received: from xtank.uchicago.edu by Arizona.edu; Tue, 24 Jul 90 21:18 MST
  4265. Received: from sophist.uchicago.edu by xtank.uchicago.edu Tue, 24 Jul 90
  4266.  23:17:01 CDT
  4267. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA03991; Tue, 24 Jul 90
  4268.  23:12:27 CDT
  4269. Resent-Date: Tue, 24 Jul 90 21:19 MST
  4270. Date: Tue, 24 Jul 90 23:12:27 CDT
  4271. From: Richard Goerwitz <goer@sophist.uchicago.edu>
  4272. Subject: user-defined control structures; limitation expressions
  4273. Resent-To: icon-group@cs.arizona.edu
  4274. To: icon-group@arizona.edu
  4275. Resent-Message-Id: <5D4CE9E1A5FFA017C1@Arizona.edu>
  4276. Message-Id: <9007250412.AA03991@sophist.uchicago.edu>
  4277. X-Envelope-To: icon-group@CS.Arizona.EDU
  4278. X-Vms-To: icon-group@Arizona.EDU
  4279. Status: O
  4280.  
  4281. Mixed in with a recent posting on another topic, I suggested
  4282. that p{a,b,c...} might possibly be extended to p{a;b;c}, where
  4283. ; is actually intended to represent a comma, semicolon, or new-
  4284. line.  This would permit the creation of user-defined control
  4285. structures that *looked* like control structures.  I.e. instead
  4286. of p{a,b,c} you could just write
  4287.  
  4288.     p {
  4289.         a
  4290.         b
  4291.         c
  4292.         etc.
  4293.     }
  4294.  
  4295. This just looks to me like a control structure.  In the case of
  4296. my list scanning routines, it would permit me to say -
  4297.  
  4298.     l_scan(l) {
  4299.         junk1
  4300.         junk2
  4301.         etc.
  4302.     }
  4303.  
  4304. The procedure l_scan would set up l_POS and l_SUBJ (the list equiva-
  4305. lents to &pos and &subject), and then return a control procedure
  4306. (call it setup_scan).  Setup_scan(lst[]) would then simply execute
  4307. each of its args, noting whether they were a break or next or some
  4308. other control structure that might necessitate ending the scanning
  4309. operation.  If encountered, l_POS and l_SUBJ could be restored cor-
  4310. rectly, and the loop could be terminated, just as with regular
  4311. string scans.
  4312.  
  4313. I've got another idea I'd be interested in hearing ideas about.
  4314. Why not let &null limiters work like no limiters at all?  Just
  4315. curious.  Often I change the amount of backtracking on the fly,
  4316. and I find it rather awkward to use backslashes and what not to
  4317. try to find a way to get a \ expression to do no limitation at
  4318. all.  Is there some easy and elegant way I'm overlooking?
  4319.  
  4320.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  4321.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  4322.  
  4323. From goer@sophist.uchicago.edu  Wed Jul 25 09:14:16 1990
  4324. Resent-From: goer@sophist.uchicago.edu
  4325. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4326.     id AA12518; Wed, 25 Jul 90 09:14:16 -0700
  4327. Return-Path: goer@sophist.uchicago.edu
  4328. Received: from xtank.uchicago.edu by Arizona.edu; Wed, 25 Jul 90 09:16 MST
  4329. Received: from sophist.uchicago.edu by xtank.uchicago.edu Wed, 25 Jul 90
  4330.  11:14:34 CDT
  4331. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA04565; Wed, 25 Jul 90
  4332.  11:10:00 CDT
  4333. Resent-Date: Wed, 25 Jul 90 09:17 MST
  4334. Date: Wed, 25 Jul 90 11:10:00 CDT
  4335. From: Richard Goerwitz <goer@sophist.uchicago.edu>
  4336. Subject: list scanning
  4337. Resent-To: icon-group@cs.arizona.edu
  4338. To: icon-group@arizona.edu
  4339. Resent-Message-Id: <5CE8A4D1BDBFA021B3@Arizona.edu>
  4340. Message-Id: <9007251610.AA04565@sophist.uchicago.edu>
  4341. X-Envelope-To: icon-group@CS.Arizona.EDU
  4342. X-Vms-To: icon-group@Arizona.EDU
  4343. Status: O
  4344.  
  4345. A postscript to the list scanning routines:  They are new and
  4346. largely untested.  Normally, I'd have labeled them as BETA in
  4347. the posting, but I just plain forgot.  In the next couple of
  4348. days, I'll probably add l_bal() and some other things.  Please
  4349. drop me a line any time if you find bugs, or want the latest
  4350. version.  It's the sort of thing I'll eventually submit to the
  4351. IPL, but will play with for some time to see whether they are
  4352. really useful enough to warrant such a drastic step.
  4353.  
  4354. -Richard
  4355.  
  4356. From icon-group-request@arizona.edu  Fri Aug  3 10:58:32 1990
  4357. Resent-From: icon-group-request@arizona.edu
  4358. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4359.     id AA15365; Fri, 3 Aug 90 10:58:32 -0700
  4360. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 3 Aug 90 11:01 MST
  4361. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA12757; Fri, 3 Aug 90 10:42:57
  4362.  -0700
  4363. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  4364.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  4365.  usenet@ucbvax.Berkeley.EDU if you have questions)
  4366. Resent-Date: Fri, 3 Aug 90 11:01 MST
  4367. Date: 3 Aug 90 16:19:17 GMT
  4368. From: ux1.cso.uiuc.edu!midway!sophist!goer@iuvax.cs.indiana.edu
  4369. Subject: fits posting; new l_scan() routines
  4370. Sender: icon-group-request@arizona.edu
  4371. Resent-To: icon-group@cs.arizona.edu
  4372. To: icon-group@arizona.edu
  4373. Resent-Message-Id: <55C79229F8DFA05F1A@Arizona.edu>
  4374. Message-Id: <1990Aug3.161917.28358@midway.uchicago.edu>
  4375. Organization: University of Chicago
  4376. X-Envelope-To: icon-group@CS.Arizona.EDU
  4377. X-Vms-To: icon-group@Arizona.EDU
  4378. Status: O
  4379.  
  4380. I'm having fits posting here because of mail reorganizations at
  4381. the U of Chicago.  I assume nothing I've posted in the last week
  4382. has gotten through.
  4383.  
  4384. Anyway, I've just been trying to post a newer version of the list
  4385. scanning routines I posted a couple of weeks back.  This new ver-
  4386. sion fixes a couple of bugs and provides the "missing" l_bal()
  4387. function.
  4388.  
  4389. I want very much to prototype this new scanning method using user-
  4390. defined control structures, but it's proving very hard.  Let's say
  4391. you want to write -
  4392.  
  4393.     repeat {
  4394.       do something
  4395.       l_scan(l) {
  4396.           expresion1,
  4397.           expression2 & break
  4398.       }
  4399.     }
  4400.  
  4401. Okay, the l_scan(l) routine sets pos and subject for the list, and
  4402. then returns a procedure geared for {}-style invocation.  Expres-
  4403. sion1 and expression2 & break are the arguments to this procedure.
  4404. The trouble is that, even if we could say "create break" (which we
  4405. can't), we end up with a break in an invalid context.
  4406.  
  4407. The user-defined control structures seem not to allow real Iconish
  4408. control.  Is this the case?  If so, no matter.  If not (i.e. if I
  4409. am overlooking something), could someone kindly enlighten me?  Alter-
  4410. natively, if someone has an idea about how to prototype new control
  4411. structures, could they perhaps post a followup?
  4412.  
  4413. I dearly hope that our news software & mail router doesn't barf on
  4414. this one.
  4415.  
  4416. Anyway, here's the code:
  4417.  
  4418.  
  4419.  
  4420. ############################################################################
  4421. #
  4422. #    Name:    lscan.icn
  4423. #
  4424. #    Title:    Quasi ? scanning routines for lists.
  4425. #
  4426. #    Author:    Richard L. Goerwitz
  4427. #
  4428. #    Version: 1.16
  4429. #
  4430. ############################################################################
  4431. #
  4432. #  Copyright (c) 1990, Richard L. Goerwitz, III
  4433. #
  4434. #  This software is intended for free and unrestricted distribution.
  4435. #  I place only two conditions on its use:  1) That you clearly mark
  4436. #  any additions or changes you make to the source code, and 2) that
  4437. #  you do not delete this message from it.  In order to protect
  4438. #  myself from spurious litigation, it must also be stated here that,
  4439. #  because this is free software, I, Richard Goerwitz, make no claim
  4440. #  about the applicability or fitness of this software for any
  4441. #  purpose, and disclaim any responsibility for any damages that
  4442. #  might be incurred in conjunction with its use.
  4443. #
  4444. ############################################################################
  4445. #
  4446. #  PURPOSE: String scanning is terrific, but often I am forced to
  4447. #  tokenize and work with lists.  So as to make operations on these
  4448. #  lists as close to corresponding string operations as possible, I've
  4449. #  implemented a series of list analogues to any(), bal(), find(),
  4450. #  many(), match(), move(), pos(), tab(), and upto().  Their names are
  4451. #  just like corresponding string functions, except with a prepended
  4452. #  "l_" (e.g. l_any()).  Functionally, the list routines parallel the
  4453. #  string ones closely, except that in place of strings, l_find and
  4454. #  l_match accept lists as their first argument.  L_any(), l_many(),
  4455. #  and l_upto() all take either sets or lists of lists (e.g.
  4456. #  l_tab(l_upto([["a"],["b"],["j","u","n","k"]])).  Note that l_bal(),
  4457. #  unlike the builtin bal(), has no defaults for the first four
  4458. #  arguments.  This just seemed appropriate, given that no precise
  4459. #  list analogue to &cset, etc. occurs.
  4460. #
  4461. #  Since Icon does not permit me to define new control structures via
  4462. #  infix operators, list scanning must be initialized via a procedure,
  4463. #  namely l_scan(l), where l is the list to be scanned.  Scanning is
  4464. #  ended by calling end_l_scan(l).  Nesting is permitted, but you'd
  4465. #  better make sure your indentation is correct.  Since l_scan() does
  4466. #  not represent a real control structure, you must call end_l_scan()
  4467. #  before "breaking" from an l_scan.  Otherwise l_POS and l_SUBJ will
  4468. #  not be handled properly.
  4469. #
  4470. #  If someone can think of a way to do this more elegantly let me
  4471. #  know.  Personally, I'd like p{a,b,c} to be extended to allow p{a S
  4472. #  b S c} (where S ::= ; | \n).  I could then do something cute, like
  4473. #  have l_scan initialize l_POS and l_SUBJ for list l, and then return
  4474. #  a control procedure geared for {}-style invocation:
  4475. #
  4476. #      l_scan(l) {
  4477. #          a
  4478. #          b
  4479. #          c
  4480. #      }
  4481. #
  4482. #  I just think this *looks* like a control structure (much more so
  4483. #  than the kludge I give below).  I'd just set up the control pro-
  4484. #  cedure to handle variable-length arguments.
  4485. #
  4486. #  I envision l_scan being used (and in fact use it myself) to parse
  4487. #  trees and compare complicated list structures.  One big time-saver
  4488. #  in parsing natural languages, for instance, is to store partial
  4489. #  trees.  The l_scan routines enable you to take your list structures
  4490. #  and say, "Give me that portion of list 2 which corresponds
  4491. #  structurally to list 1."  Or you can say, "Tell me if the first
  4492. #  portion of x list corresponds structurally to y."  In effect, the
  4493. #  structure of the tree can be checked without necessitating a
  4494. #  reparse.
  4495. #
  4496. #  BUGS:  Can you say slow?  I thought you could.
  4497. #
  4498. ############################################################################
  4499. #
  4500. #  Here's a trivial example of how one might utilize the lscan routines:
  4501. #
  4502. #  procedure main()
  4503. #
  4504. #      l := ["h","e","l","l","o"," ","t","t","t","h","e","r","e"]
  4505. #
  4506. #      l_scan(l)
  4507. #          hello_list := l_tab(l_match(["h","e","l","l","o"]))
  4508. #          every writes(!hello_list)
  4509. #          write()
  4510. #
  4511. #       l_scan(l_tab(0))
  4512. #           l_tab(l_many([[" "],["t"]]) - 1)
  4513. #              every writes(!l_tab(0))
  4514. #           write()
  4515. #          end_l_scan()
  4516. #  
  4517. #      end_l_scan()
  4518. #  
  4519. #  end
  4520. #
  4521. #  The above program simply writes "hello" and "there" on successive
  4522. #  lines to the standard output.
  4523. #
  4524. #  PITFALLS: In general, note that we are comparing lists here instead
  4525. #  of strings, so l_find("h", l), for instance, will yield an error
  4526. #  message (use l_find(["h"], l) instead).  The point at which I
  4527. #  expect this nuance will be most confusing will be in cases where
  4528. #  one is looking for lists within lists.  Suppose we have a list,
  4529. #
  4530. #      l1 := ["junk",[["hello"]," ",["there"]],"!","m","o","r","e","junk"]
  4531. #
  4532. #  and suppose, moreover, that we wish to find the position in l1 at
  4533. #  which the list
  4534. #
  4535. #      [["hello"]," ",["there"]]
  4536. #
  4537. #  occurs.  If, say, we assign [["hello"]," ",["there"]] to the
  4538. #  variable l2, then our l_find() expression will need to look like
  4539. #
  4540. #      l_scan(l1)
  4541. #          l_tab(l_find([l2]))
  4542. #      etc.
  4543. #
  4544. #  The reason l2 must be enclosed within a list is that we are
  4545. #  searching for a single element within l1, not a series of three
  4546. #  elements.  Just as l_find("h") would not work correctly above, so
  4547. #  l_find(l2) will not work here (although in this latter case, no
  4548. #  error message is generated; the expression merely fails when it
  4549. #  finds no sequence of elements in l1 corresponding to the sequence
  4550. #  of elements occurring in l2).
  4551. #
  4552. ############################################################################
  4553.  
  4554. global l_POS
  4555. global l_SUBJ
  4556.  
  4557.  
  4558.  
  4559. procedure l_scan(l)
  4560.  
  4561.     if /l_POS then {
  4562.     l_POS  := []
  4563.     l_SUBJ := []
  4564.     }
  4565.  
  4566.     push(l_POS, 1)
  4567.     push(l_SUBJ, l)
  4568.     return
  4569.  
  4570. end
  4571.  
  4572.  
  4573.  
  4574. procedure end_l_scan()
  4575.  
  4576.     every pop(l_POS|l_SUBJ)
  4577.     if *l_POS = 0 then {
  4578.     l_POS  := &null
  4579.     l_SUBJ := &null
  4580.     }
  4581.     return
  4582.  
  4583. end
  4584.  
  4585.  
  4586.  
  4587. procedure l_move(i)
  4588.  
  4589.     /i & stop("l_move:  Null argument.")
  4590.     if /l_POS | /l_SUBJ
  4591.     then stop("l_move:  Call l_scan first.")
  4592.     suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1 >= l_POS[1]+i))]
  4593.  
  4594. end
  4595.  
  4596.  
  4597.  
  4598. procedure l_tab(i)
  4599.  
  4600.     /i & stop("l_tab:  Null argument.")
  4601.     if /l_POS | /l_SUBJ
  4602.     then stop("l_tab:  Call l_scan first.")
  4603.  
  4604.     if i = 0
  4605.     then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- *l_SUBJ[1]+1]
  4606.     else {
  4607.     if i < 0
  4608.     then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1) + i)]
  4609.     else suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (*l_SUBJ[1]+1 >= i)]
  4610.     }
  4611.  
  4612. end
  4613.  
  4614.  
  4615.  
  4616. procedure l_any(l1,l2,i,j)
  4617.  
  4618.     # Like any(c,s2,i,j) except that the string & cset arguments are
  4619.     # replaced by list arguments.  l1 must be a list of one-element
  4620.     # lists, while l2 can be any list (l_SUBJ[1] by default).
  4621.  
  4622.     local sub_l
  4623.  
  4624.     /l1 & stop("l_any:  Null first argument!")
  4625.     if type(l1) == "set" then l1 := sort(l1)
  4626.  
  4627.     /l2 := l_SUBJ[1]
  4628.     /i  := \l_POS[1] | 1
  4629.     /j  := *l_SUBJ[1]+1
  4630.  
  4631.     (i+1) > j & fail
  4632.     every sub_l := !l1 do {
  4633.     if not (type(sub_l) == "list", *sub_l = 1) then
  4634.         stop("l_any:  Elements of l1 must be lists of length 1.")
  4635.     if x := l_match(sub_l,l2,i,i+1)
  4636.     then return x
  4637.     }
  4638.     
  4639. end
  4640.  
  4641.  
  4642.  
  4643. procedure l_match(l1,l2,i,j)
  4644.  
  4645.     # Analogous to match(s1,s2,i,j), except that s1 and s2 are lists,
  4646.     # and l_match returns the next position in l2 after that portion
  4647.     # (if any) which is structurally identical to l1.  If a match is not
  4648.     # found, l_match fails.
  4649.  
  4650.     if /l1
  4651.     then stop("l_match:  Null first argument!")
  4652.     if type(l1) ~== "list"
  4653.     then stop("l_match:  Call me with a list as the first arg.")
  4654.  
  4655.     /l2 := l_SUBJ[1]
  4656.     /i  := \l_POS[1] | 1
  4657.     /j  := *l_SUBJ[1]+1
  4658.  
  4659.     i + *l1 > j & fail
  4660.     if l_comp(l1,l2[i+:*l1])
  4661.     then return i + *l1
  4662.  
  4663. end
  4664.  
  4665.     
  4666.  
  4667. procedure l_comp(l1,l2)
  4668.  
  4669.     # List comparison routine basically taken from Griswold & Griswold
  4670.     # (1st ed.), p. 174.
  4671.  
  4672.     local i
  4673.  
  4674.     /l1 | /l2 & stop("l_comp:  Null argument!")
  4675.     l1 === l2 & (return l2)
  4676.  
  4677.     if type(l1) == type(l2) == "list" then {
  4678.     *l1 ~= *l2 & fail
  4679.     every i := 1 to *l1
  4680.     do l_comp(l1[i],l2[i]) | fail
  4681.     return l2
  4682.     }
  4683.  
  4684. end
  4685.  
  4686.  
  4687.  
  4688. procedure l_find(l1,l2,i,j)
  4689.  
  4690.     local x
  4691.  
  4692.     /l1 & stop("l_find:  Null first argument!")
  4693.  
  4694.     /l2 := l_SUBJ[1]
  4695.     /i  := \l_POS[1] | 1
  4696.     /j  := *l_SUBJ[1]+1
  4697.  
  4698.     every x := i to ((*l2+1) - *l1) do {
  4699.     if l_match(l1,l2,x,j)
  4700.     then suspend x
  4701.     }
  4702.     
  4703. end
  4704.  
  4705.  
  4706.  
  4707. procedure l_upto(l1,l2,i,j)
  4708.  
  4709.     local x
  4710.  
  4711.     /l1 & stop("l_upto:  Null first argument!")
  4712.     if type(l1) == "set" then l1 := sort(l1)
  4713.  
  4714.     /l2 := l_SUBJ[1]
  4715.     /i  := \l_POS[1] | 1
  4716.     /j  := *l_SUBJ[1]+1
  4717.  
  4718.     every x := i to ((*l2+1) - *l1) do {
  4719.     if l_any(l1,l2,x,j)
  4720.     then suspend x
  4721.     }
  4722.     
  4723. end
  4724.  
  4725.  
  4726.  
  4727. procedure l_many(l1,l2,i,j)
  4728.  
  4729.     /l1 & stop("l_many:  Null first argument!")
  4730.     if type(l1) == "set" then l1 := sort(l1)
  4731.  
  4732.     /l2 := l_SUBJ[1]
  4733.     /i  := \l_POS[1] | 1
  4734.     /j  := *l_SUBJ[1]+1
  4735.  
  4736.     l_scan(l2)
  4737.     while x := l_any(l1,,,j)
  4738.     do l_tab(x)
  4739.     end_l_scan(l2)
  4740.  
  4741.     return \x
  4742.  
  4743. end
  4744.  
  4745.  
  4746.  
  4747. procedure l_pos(i)
  4748.  
  4749.     local x
  4750.  
  4751.     if /l_POS | /l_SUBJ
  4752.     then stop("l_move:  Call l_scan first.")
  4753.  
  4754.     if i <= 0
  4755.     then x := 0 < (*l_SUBJ[1]+1 >= (*l_SUBJ[1]+1)+i) | fail
  4756.     else x := 0 < (*l_SUBJ[1]+1 >= i) | fail
  4757.  
  4758.     if x = l_POS[1]
  4759.     then return x
  4760.     else fail
  4761.  
  4762. end
  4763.  
  4764.  
  4765.  
  4766. procedure l_bal(l1,l2,l3,l,i,j)
  4767.  
  4768.     local l2_count, l3_count, x, position
  4769.  
  4770.     /l1 & stop("l_bal:  Null first argument!")
  4771.     if type(l1) == "set" then l1 := sort(l1)  # convert to a list
  4772.     if type(l2) == "set" then l1 := sort(l2)
  4773.     if type(l3) == "set" then l1 := sort(l3)
  4774.  
  4775.     /l := l_SUBJ[1]
  4776.     /i  := \l_POS[1] | 1
  4777.     /j  := *l_SUBJ[1]+1
  4778.  
  4779.     l2_count := l3_count := 0
  4780.  
  4781.     every x := i to j-1 do {
  4782.  
  4783.     if l_any(l2, l, x, x+1) then {
  4784.         l2_count +:= 1
  4785.     }
  4786.     if l_any(l3, l, x, x+1) then {
  4787.         l3_count +:= 1
  4788.     }
  4789.     if l2_count = l3_count then {
  4790.         if l_any(l1,l,x,x+1)
  4791.         then suspend x
  4792.     }
  4793.     }
  4794.  
  4795. end
  4796.  
  4797.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  4798.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  4799.  
  4800. From kwalker  Fri Aug  3 16:06:05 1990
  4801. Resent-From: "Kenneth Walker" <kwalker>
  4802. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4803.     id AA28424; Fri, 3 Aug 90 16:06:05 -0700
  4804. Received: from megaron.cs.Arizona.EDU by Arizona.edu; Fri, 3 Aug 90 16:05 MST
  4805. Received: by megaron.cs.arizona.edu (5.61/15) id AA28394; Fri, 3 Aug 90
  4806.  16:05:32 -0700
  4807. Resent-Date: Fri, 3 Aug 90 16:05 MST
  4808. Date: Fri, 3 Aug 90 16:05:32 -0700
  4809. From: Kenneth Walker <kwalker@cs.arizona.edu>
  4810. Subject: RE: fits posting; new l_scan() routines
  4811. Resent-To: icon-group@cs.arizona.edu
  4812. To: icon-group@arizona.edu
  4813. Resent-Message-Id: <559D0E62DF9BA05A95@Arizona.edu>
  4814. Message-Id: <9008032305.AA28394@megaron.cs.arizona.edu>
  4815. X-Envelope-To: icon-group@CS.Arizona.EDU
  4816. X-Vms-To: icon-group@Arizona.EDU
  4817. Status: O
  4818.  
  4819. > Date: 3 Aug 90 16:19:17 GMT
  4820. > From: ux1.cso.uiuc.edu!midway!sophist!goer@iuvax.cs.indiana.edu
  4821.  
  4822. > I want very much to prototype this new scanning method using user-
  4823. > defined control structures, but it's proving very hard.
  4824.  
  4825. Emulating regular string scanning using user-defined control structures
  4826. is also awkward. There is a way to emulate string scanning using nested
  4827. procedure calls. It does not correctly handle breaking out of string
  4828. scanning (but then neither did the Icon intepreter until V7!).
  4829.  
  4830. The idea is to translate
  4831.  
  4832.    expr1 ? expr2
  4833.  
  4834. into
  4835.  
  4836.    escan(bscan(expr1), expr2)
  4837.  
  4838. (Of course, expr2 can be a compound expression, if you want it to be.)
  4839. This allows the setup routine, bscan, to comunicate with the termination
  4840. routine, escan. It allows nesting of scanning along with full backtracking
  4841. into and out of scanning. In addition, escan returns the value of the
  4842. scanning expression.
  4843.  
  4844. Saved scanning environments are stored in records
  4845.  
  4846.    record scan_env(subject, pos)
  4847.  
  4848.    procedure bscan(expr1)
  4849.       local outer_env
  4850.  
  4851.       outer_env := scan_env(&subject, &pos)
  4852.       &subject := expr1
  4853.       &pos := 1
  4854.       suspend outer_env   # pass saved environment to escan
  4855.       &subject = outer_env.subject
  4856.       &pos = outer_env.pos
  4857.       fail  # resume expression for expr1
  4858.    end
  4859.  
  4860.    procedure escan(outer_env, expr2)
  4861.       local inner_env
  4862.  
  4863.       inner_env := scan_env(&subject, &pos)
  4864.       &subject = outer_env.subject
  4865.       &pos = outer_env.pos
  4866.       suspend expr2
  4867.       outer_env.subject = &subject
  4868.       outer_env.pos = &pos
  4869.       &subject = inner_env.subject
  4870.       &pos = inner_env.pos
  4871.       fail   # resume expression for expr2
  4872.    end
  4873.  
  4874. (disclaimer: these routines are based on code that works, but I
  4875. typed them in without trying to translate or run them)
  4876.  
  4877. This bscan-escan expression works well if you are using a preprocess
  4878. (for example, one bassed on the variant translator system) to translate
  4879. from a notation that looks like a control structure, but looks
  4880. rather odd if you code it directly. However, it may give you some
  4881. ideas.
  4882.  
  4883. The only way I know of to solve the "break" problem is to use something
  4884. more primative than suspend (break just wipes out suspened generators
  4885. without considering that something more might need to be done), but you
  4886. can only do this in the run-time system routines written in C, not within
  4887. Icon itself.
  4888.  
  4889.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  4890.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  4891.  
  4892. From goer@sophist.uchicago.edu  Thu Aug  9 14:57:17 1990
  4893. Resent-From: goer@sophist.uchicago.edu
  4894. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4895.     id AA14726; Thu, 9 Aug 90 14:57:17 -0700
  4896. Return-Path: goer@sophist.uchicago.edu
  4897. Received: from midway.uchicago.edu by Arizona.edu; Thu, 9 Aug 90 14:56 MST
  4898. Received: from sophist.uchicago.edu by midway.uchicago.edu Thu, 9 Aug 90
  4899.  16:56:23 CDT
  4900. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA24489; Thu, 9 Aug 90
  4901.  16:54:06 CDT
  4902. Resent-Date: Thu, 9 Aug 90 14:56 MST
  4903. Date: Thu, 9 Aug 90 16:54:06 CDT
  4904. From: Richard Goerwitz <goer@sophist.uchicago.edu>
  4905. Subject: Alan Corre's calendar program; Unix port
  4906. Resent-To: icon-group@cs.arizona.edu
  4907. To: icon-group@arizona.edu
  4908. Resent-Message-Id: <50EFB04DB03BA090B0@Arizona.edu>
  4909. Message-Id: <9008092154.AA24489@sophist.uchicago.edu>
  4910. X-Envelope-To: icon-group@CS.Arizona.EDU
  4911. X-Vms-To: icon-group@Arizona.EDU
  4912. Status: O
  4913.  
  4914. This is a blanket response to those who are inquiring about the
  4915. availability of the Unix port of Alan Corre's Jewish/Civil calen-
  4916. dar.  A few weeks ago I had asked for beta testers - i.e. people
  4917. who might be willing to try the program out under various Unix
  4918. versions.  Within a few days, the main bugs had been worked out,
  4919. and the port was sent to cs.arizona.edu and to Alan Corre.
  4920.  
  4921. I am still getting occasional offers to beta test, and I'd just
  4922. like to let everyone who might be inclined to make such an offer
  4923. know that, although I'm happy about the interest, I've really done
  4924. all I'm going to do with the port (unless some really big bugs
  4925. are found).  Those wanting to know more about the program should,
  4926. at this point, mail to Alan Corre, unless the questions are spe-
  4927. cifically related to my port.  I'll be happy to send out shars if
  4928. requested, but I'd suggest that those with good access to cs.
  4929. arizona.edu just get them there (in icon/contrib/hebcalen.*.Z).
  4930.  
  4931. Again, thanks to those who offered their help.  No need for any
  4932. more guinea pigs to volunteer!
  4933.  
  4934.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  4935.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  4936.  
  4937. PS.  Those interested in the latest icon-termlib routines should
  4938. grab the calendar program, since it's got the latest version there.
  4939. It's probably the last anyone will see of it, unless it ends up in
  4940. the IPL.
  4941.  
  4942. From icon-group-request@arizona.edu  Sun Aug 12 13:10:20 1990
  4943. Resent-From: icon-group-request@arizona.edu
  4944. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4945.     id AA28281; Sun, 12 Aug 90 13:10:20 -0700
  4946. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Sun, 12 Aug 90 12:35 MST
  4947. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15354; Sun, 12 Aug 90
  4948.  12:30:37 -0700
  4949. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  4950.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  4951.  usenet@ucbvax.Berkeley.EDU if you have questions)
  4952. Resent-Date: Sun, 12 Aug 90 12:57 MST
  4953. Date: 12 Aug 90 19:14:49 GMT
  4954. From: cs.utexas.edu!wuarchive!brutus.cs.uiuc.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@tut.cis.ohio-state.edu
  4955. Subject: style checkers?
  4956. Sender: icon-group-request@arizona.edu
  4957. Resent-To: icon-group@cs.arizona.edu
  4958. To: icon-group@arizona.edu
  4959. Resent-Message-Id: <4EA4B7795CDBA08184@Arizona.edu>
  4960. Message-Id: <1990Aug12.191449.14458@midway.uchicago.edu>
  4961. Organization: University of Chicago Computing Organizations
  4962. X-Envelope-To: icon-group@CS.Arizona.EDU
  4963. X-Vms-To: icon-group@Arizona.EDU
  4964. Status: O
  4965.  
  4966. Icon seems to me to offer just the sorts of facilities that
  4967. one would need to write a good style checker (hash tables,
  4968. sets, elegant string processing facilities).  Has anyone out
  4969. there done this?  Just curious.
  4970.  
  4971. From goer@sophist.uchicago.edu  Mon Aug 13 11:55:51 1990
  4972. Resent-From: goer@sophist.uchicago.edu
  4973. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  4974.     id AA13980; Mon, 13 Aug 90 11:55:51 -0700
  4975. Return-Path: goer@sophist.uchicago.edu
  4976. Received: from midway.uchicago.edu by Arizona.edu; Mon, 13 Aug 90 11:55 MST
  4977. Received: from sophist.uchicago.edu by midway.uchicago.edu Mon, 13 Aug 90
  4978.  13:55:14 CDT
  4979. Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA27841; Mon, 13 Aug 90
  4980.  13:52:55 CDT
  4981. Resent-Date: Mon, 13 Aug 90 11:55 MST
  4982. Date: Mon, 13 Aug 90 13:52:55 CDT
  4983. From: Richard Goerwitz <goer@sophist.uchicago.edu>
  4984. Subject: snipping out sentences from text files
  4985. Resent-To: icon-group@cs.arizona.edu
  4986. To: icon-group@arizona.edu
  4987. Resent-Message-Id: <4DE45CB598BBA09918@Arizona.edu>
  4988. Message-Id: <9008131852.AA27841@sophist.uchicago.edu>
  4989. X-Envelope-To: icon-group@CS.Arizona.EDU
  4990. X-Vms-To: icon-group@Arizona.EDU
  4991. Status: O
  4992.  
  4993. Recently I have had to do some analysis on my prose (my sentences tend
  4994. to be too long, contain too many polysyllabic words, and to have too
  4995. many subordinate clauses).  To do this I wrote a short Icon program.
  4996. One procedure I needed to write was a sentence-finder, which snips out
  4997. sentences from a given ASCII file.  This seemed to be of general in-
  4998. terest, so I'm posting it here.
  4999.  
  5000. My ulterior motive is that I'll bet a lot of literary types are on
  5001. this mailing list, and could improve the algorithm substantially.
  5002. I'd really like to see any modifications anyone makes to this code.
  5003.  
  5004. -Richard
  5005.  
  5006. ------------------------------ cut here ------------------------------
  5007.  
  5008. procedure main(a)
  5009.  
  5010.     intext := open(\a[1]) | &input
  5011.     every write("\n",sentence(intext))
  5012.  
  5013. end
  5014.  
  5015.  
  5016. ############################################################################
  5017. #
  5018. #    Name:     sentence.icn
  5019. #
  5020. #    Title:     A simple sentence-finder
  5021. #
  5022. #    Author:     Richard Goerwitz
  5023. #
  5024. #    Version: (just a preliminary hack)
  5025. #
  5026. ############################################################################
  5027. #  
  5028. #     This procedure simply reads an ASCII file (or maybe an n/troff file),
  5029. #  and suspends the sentences contained in it.  Sentences are defined as
  5030. #  any string of characters ending in a punctuation-group containing an
  5031. #  exclamation point, period, or question mark, followed by two spaces, or
  5032. #  else by a space, an (optional) string of sentence-initial punctuation,
  5033. #  and finally a capital letter or number.  If I could count on everyone
  5034. #  having a /usr/dict/words file, I'd require that the capital letter be-
  5035. #  gin a word which maps to a lowercase entry in /usr/dict/words (so as to
  5036. #  avoid calling cases like "R. Goerwitz" a sentence-break).  Since not every-
  5037. #  one has such a wordlist, I'll just rest content to leave the algorithm
  5038. #  (imperfect) as it is.  Note that cases where a sentence ends a line are
  5039. #  handled by appending a space to that line, and then appending the next
  5040. #  line from the input file.  This puts the sentence break into a form the
  5041. #  algorithm can recognize as a sentence break.
  5042. #
  5043. ############################################################################
  5044. #
  5045. #  Requires: coexpressions
  5046. #
  5047. #  See also: segment.icn (if you wish to tokenize)
  5048. #
  5049. ############################################################################
  5050.  
  5051.  
  5052. procedure sentence(intext)
  5053.  
  5054.     local sentence, get_line, line, tmp_s, end_part
  5055.     static inits, punct
  5056.     initial {
  5057.     inits := &ucase ++ &digits
  5058.     punct := ".\"'!?)]"
  5059.     }
  5060.     sentence := ""
  5061.     get_line := create read_line(intext)
  5062.  
  5063.     while line := @get_line do {
  5064.  
  5065.     # Go on until you can't find any more sentence-endings in line,
  5066.     # then break and get another line.
  5067.     repeat {
  5068.  
  5069.         # Scan for a sentence break somewhere in line.
  5070.         line ? {
  5071.  
  5072.         # Ugly, but it works.  Look for sequences containing
  5073.         # things like periods and question marks, followed by
  5074.         # a space and another space or a word beginning with
  5075.         # a capital letter.  If we don't have enough context,
  5076.         # append the next line from intext to line & scan again.
  5077.         if tmp_s := tab(upto(punct)) &
  5078.             upto('!?.', end_part := tab(many(punct))) &
  5079.             not (pos(-1), line ||:= @get_line, next) &
  5080.             =" " & (=" " | (tab(many('\'"('))|&null,any(inits)))
  5081.         then {
  5082.             suspend sentence || tmp_s || end_part
  5083.             tab(many(' '))
  5084.             line := tab(0)
  5085.             sentence := ""
  5086.             next
  5087.         }
  5088.         else break
  5089.         }
  5090.     }
  5091.  
  5092.     # Otherwise just tack line onto sentence & try again.
  5093.     sentence ||:= line
  5094.     }
  5095.  
  5096.     return sentence
  5097.  
  5098. end
  5099.  
  5100.  
  5101.  
  5102.  
  5103. procedure read_line(intext)
  5104.  
  5105.     local new_line
  5106.  
  5107.     while line := trim(!intext,'\t ') do {
  5108.     line ? {
  5109.         match(".") & next
  5110.         tab(many('\t #'))
  5111.         pos(0) & next
  5112.         new_line := tab(-1) || (="-" | (move(1) || " "))
  5113.     }
  5114.     suspend new_line
  5115.     }
  5116.  
  5117. end
  5118.  
  5119. From cargo@cherry.cray.com  Fri Aug 17 13:20:29 1990
  5120. Received: from timbuk.CRAY.COM by megaron (5.61/15) via SMTP
  5121.     id AA12741; Fri, 17 Aug 90 13:20:29 -0700
  5122. Received: from cherry04.cray.com by timbuk.CRAY.COM (4.1/SMI4.0 CRAY1.1)
  5123.     id AA24602; Fri, 17 Aug 90 15:20:23 CDT
  5124. Received: by cherry04.cray.com
  5125.     id AA07741; 4.1/CRI-3.20; Fri, 17 Aug 90 15:20:19 CDT
  5126. Date: Fri, 17 Aug 90 15:20:19 CDT
  5127. From: cargo@cherry.cray.com (David S. Cargo)
  5128. Message-Id: <9008172020.AA07741@cherry04.cray.com>
  5129. To: icon-group@cs.arizona.edu
  5130. Subject: new table mechanism
  5131. Status: O
  5132.  
  5133. I was thinking about the new table mechanisms in the latest version
  5134. of Icon.  I think that a change in the way that the tables are
  5135. initially allocated could double the size of tables that can be handled
  5136. effectively as well as improve space and time performance for handling
  5137. small tables.
  5138.  
  5139. As I understand it, minimum size tables are now composed of two parts,
  5140. a table header, and a hash chain header.  The table header contains
  5141. "slots" for pointing to hash chain headers.  The hash chain headers
  5142. are sizes based on powers of two.  The first hash chain header will be
  5143. of size 8 (for example), the second will be of the same size, the
  5144. third will be equal to the sum of the sizes of the first two, the
  5145. fourth will be equal to the sum of the sizes of the first three, etc. 
  5146.  
  5147. I believe the current implementation also has 8 slots for pointing to
  5148. hash chain headers.  Therefore it can point to 8 + 8 + 16 + 32 + 64 +
  5149. 128 + 256 + 512 = 1024 chains.
  5150.  
  5151. An empty table has a table header that points to an empty hash chain
  5152. header.  
  5153.  
  5154. What I think might be worth investigating is using the table header
  5155. slots as hash chain headers for small tables.  This still gives you 8
  5156. hash chain slots.  Then, if the table load factor grows to the point
  5157. where more hash chain slots are needed, allocate a hash chain header
  5158. with 16 slots.  Instead of starting the sizes of hash chain headers at
  5159. 8, this would start them at 16, doubling the number of total slots
  5160. that could be pointed to by the 8 slots in the table header.
  5161.  
  5162. For small tables, this eliminates one level of indirection and reduces
  5163. the space overhead for small and empty tables.  It also reduces the
  5164. time overhead for creating tables, since fewer memory allocations are
  5165. required.  This would be most noticable when many small tables are
  5166. created.  
  5167.  
  5168. For large tables, this doubles the maximum number of potential hash
  5169. chains.  
  5170.  
  5171. Certainly the semantics of tables require that more issues than just
  5172. the space considerations be examined (e.g., element generation), but
  5173. making this implementation change would further improve the benefit of
  5174. dynamic tables.
  5175.  
  5176. David S. Cargo (cargo@cray.com)
  5177.  
  5178. From CELEX@CELEX.KUN.NL  Mon Aug 20 06:29:29 1990
  5179. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5180.     id AA23098; Mon, 20 Aug 90 06:29:29 -0700
  5181. Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Mon, 20 Aug 90 06:29 MST
  5182. Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Mon, 20 Aug 90 15:31 MET
  5183. Date: Mon, 20 Aug 90 15:24 MET
  5184. From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
  5185. Subject: Output to screen.
  5186. To: icon-group@cs.arizona.edu
  5187. Message-Id: <484607C22EDF402586@KUNRC1.URC.KUN.NL>
  5188. X-Envelope-To: icon-group@cs.ARIZONA.EDU
  5189. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  5190. Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
  5191.  SURF/DECNET: celex::celexmail   JANET: celex%earn.hnympi52@uk.ac.earn-relay
  5192. Status: RO
  5193.  
  5194.  
  5195. We have recently installed version 8 of Icon on our micro-VAXes. Compared
  5196. to version 6 the output to the screen is much slower. Can anything be done
  5197. about that?
  5198.  
  5199.                                               Marcel Bingley
  5200.                                               CELEX
  5201.                                               Nijmegen, the Netherlands.
  5202.  
  5203. From CELEX@CELEX.KUN.NL  Mon Aug 20 09:14:59 1990
  5204. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5205.     id AA02148; Mon, 20 Aug 90 09:14:59 -0700
  5206. Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Mon, 20 Aug 90 09:14 MST
  5207. Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Mon, 20 Aug 90 18:07 MET
  5208. Date: Mon, 20 Aug 90 18:00 MET
  5209. From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
  5210. Subject: Output to screen.
  5211. To: icon-group@cs.arizona.edu
  5212. Message-Id: <483042BF825F40152B@KUNRC1.URC.KUN.NL>
  5213. X-Envelope-To: icon-group@cs.ARIZONA.EDU
  5214. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  5215. Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
  5216.  SURF/DECNET: celex::celexmail   JANET: celex%earn.hnympi52@uk.ac.earn-relay
  5217. Status: RO
  5218.  
  5219.  
  5220. Richard,
  5221.  
  5222. We still have version 6 installed, so if your answer will be the only
  5223. solution we can "down-grade" in a minute.
  5224.  
  5225. I don't know what gcc is (must have something to do with C, I guess),
  5226. so I don't know whether it will run. We use the VAX-C compiler.
  5227.  
  5228. -Marcel
  5229.  
  5230. From tenaglia@mis.mcw.edu  Mon Aug 20 10:24:03 1990
  5231. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  5232.     id AA05591; Mon, 20 Aug 90 10:24:03 -0700
  5233. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.3/3.07) with UUCP 
  5234.     id AA10495; Mon, 20 Aug 90 13:11:40 EDT
  5235. Received: by uwm.edu; id AA07857; Mon, 20 Aug 90 11:31:09 -0500
  5236. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  5237.           Mon, 20 Aug 90 11:13:53 CDT
  5238. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  5239.           Mon, 20 Aug 90 10:31:34 CDT
  5240. Date: Mon, 20 Aug 90 10:31:34 CDT
  5241. Message-Id: <0093B790107BF840.2040021F@mis.mcw.edu>
  5242. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  5243. Subject: ICON on VMS
  5244. To: icon-group@cs.arizona.edu
  5245. Status: RO
  5246.  
  5247.  
  5248. Recently someone mentioned something about Icon V8 being slower than V6 on a
  5249. microvax in regards to screen IO. This sounds like a VMS system. I've used
  5250. in primarily on VAX/VMS, but also a little on a VAX 780 running Berkeley Unix
  5251. 4.3 and the screen IO behaviour difference is quite noticable.
  5252.  
  5253. I think it's because the VMS version is trying to emulate the data stream
  5254. concept of unix. This is why the unix redirectors <, >, and >> can be used
  5255. with VMS ICON where VAX FORTRAN doesn't handle them automatically. Therefore,
  5256. I'm not sure that we could or should ever expect speedy screen IO under VMS.
  5257. I really like the redirectors and wouldn't want to loose them. Eventually,
  5258. I'd like to see the PIPE | come to VMS ICON as well. Then we could issue
  5259. commands like ICONX PROG1 <DATA.LIS | PROG2 | PROG3 >FILTERED.LIS where
  5260. PROG1, PROG2, and PROG3 are icon executables.
  5261.  
  5262. There is another problem with screen IO. Here's a little program...
  5263.  
  5264.                         procedure main()
  5265.                           write("Hello there")
  5266.                           end
  5267.  
  5268. If this is run interactively the output is "Hello there". If it's run in a
  5269. batch or in a DCL subprocess window under EVE the output is
  5270. H
  5271. e
  5272. l
  5273. l
  5274. o
  5275.  
  5276. t
  5277. h
  5278. e
  5279. r
  5280. e
  5281. Which can make the batch log or editor buffer pretty long. I wrote a log
  5282. squeezer. Its usage is ICONX LOG <BATCH.LOG >BATCH.LIS
  5283.  
  5284. #######################################################################
  5285. #                                                                     #
  5286. # LOG.ICN          7/5/90          BY TENAGLIA                        #
  5287. #                                                                     #
  5288. # THIS PROGRAM SMOOTHS A BATCH LOG THAT RAN AN ICON PROGRAM           #
  5289. # ICON PROGRAMS IN BATCH TEND TO PUT ONE CHARACTER PER LINE           #
  5290. # IN THE LOG FILES, MAKING THEM HORRIBLE TO PRINT AND READ.           #
  5291. # THIS PROGRAM SENSES THE ICON ENVIRONMENT, AND TRIES TO MAKE         #
  5292. # THE LOG FILE MORE COMPRESSED AND READIBLE.                          #
  5293. # USAGE : ICONX LOG <INPUT_FILE >OUTPUT_FILE WIDTH [132]              #
  5294. #                                                                     #
  5295. #######################################################################
  5296. global tty
  5297. procedure main(param)
  5298.   width := param[1] | 132
  5299.   width := ((-width > width) | width) - 3
  5300.   text := ""
  5301.   while line := read() do
  5302.     {
  5303.     if *line > 2 then
  5304.       {
  5305.       if match("$",line) & (trim(text) ~== "") then line := "\n" || line
  5306.       both := text || line
  5307.       write(unscape(both))
  5308.       text := ""
  5309.       next
  5310.       }
  5311.     text ||:= line
  5312.     if *text > width then
  5313.       {
  5314.       write(unscape(text))
  5315.       text := ""
  5316.       }
  5317.     }
  5318.   end
  5319.  
  5320. #
  5321. # REMOVES MOST UGLY ESCAPE SEQUENCES
  5322. #
  5323. procedure unscape(data)
  5324.   new := "" ; toggle := -1
  5325.   while i := find("\e#"|"\e("|"\e)",data) do data[i+:3] := ""
  5326.   every byte := !data do
  5327.     {
  5328.     if byte == "\e" then
  5329.       {
  5330.       toggle := 1
  5331.       next
  5332.       }
  5333.     if toggle = 1 then
  5334.       {
  5335.       if any(&letters,byte) then toggle := -1
  5336.       next
  5337.       } else new ||:= byte
  5338.     }
  5339.   return new
  5340.   end
  5341.   
  5342. Chris Tenaglia (System Manager)
  5343. Medical College of Wisconsin
  5344. 8701 W. Watertown Plank Rd.
  5345. Milwaukee, WI 53226
  5346. (414)257-8765
  5347. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  5348.  
  5349.  
  5350. From kwalker  Tue Aug 21 15:46:13 1990
  5351. Received: from gacham.cs.arizona.edu by megaron (5.61/15) via SMTP
  5352.     id AA15524; Tue, 21 Aug 90 15:46:13 -0700
  5353. Date: Tue, 21 Aug 90 15:46:11 MST
  5354. From: "Kenneth Walker" <kwalker>
  5355. Message-Id: <9008212246.AA12413@gacham.cs.arizona.edu>
  5356. Received: by gacham.cs.arizona.edu; Tue, 21 Aug 90 15:46:11 MST
  5357. To: icon-group
  5358. Subject: Re:  ICON on VMS
  5359. Status: RO
  5360.  
  5361. > Date: Mon, 20 Aug 90 10:31:34 CDT
  5362. > From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  5363. > Subject: ICON on VMS
  5364.  
  5365. > Recently someone mentioned something about Icon V8 being slower than V6 on a
  5366. > microvax in regards to screen IO. This sounds like a VMS system.    
  5367.  
  5368. > There is another problem with screen IO. Here's a little program...
  5369.  
  5370. The Icon interpreter is a C program that uses C's fwrite() to implement
  5371. the write() function. Do other C programs have these problems under VMS?
  5372.  
  5373. Ken Walker, kwalker@cs.arizona.edu
  5374.  
  5375. From icon-group-request@arizona.edu  Wed Aug 22 06:44:59 1990
  5376. Resent-From: icon-group-request@arizona.edu
  5377. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5378.     id AA13328; Wed, 22 Aug 90 06:44:59 -0700
  5379. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 22 Aug 90 06:44 MST
  5380. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA22123; Wed, 22 Aug 90
  5381.  06:30:12 -0700
  5382. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  5383.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  5384.  usenet@ucbvax.Berkeley.EDU if you have questions)
  5385. Resent-Date: Wed, 22 Aug 90 06:44 MST
  5386. Date: 22 Aug 90 12:25:18 GMT
  5387. From: mcsun!hp4nl!mhres!squirrel!jv@uunet.uu.net
  5388. Subject: Catspaw
  5389. Sender: icon-group-request@arizona.edu
  5390. Resent-To: icon-group@cs.arizona.edu
  5391. To: icon-group@arizona.edu
  5392. Resent-Message-Id: <46FD4904D9FF001618@Arizona.edu>
  5393. Message-Id: <1990Aug22.122518.28178@squirrel.mh.nl>
  5394. Organization: Multihouse Automation, the Netherlands
  5395. X-Envelope-To: icon-group@CS.Arizona.EDU
  5396. X-Vms-To: icon-group@Arizona.EDU
  5397. Status: RO
  5398.  
  5399.  
  5400. Is Catspaw still on the net? Their old address
  5401. <...%cats.uucp@arizona.edu>  bounces.
  5402. I wanted to find out if there is anything
  5403. new on the ProIcon front.
  5404.  
  5405.     Johan
  5406. -- 
  5407. Johan Vromans                       jv@mh.nl via internet backbones
  5408. Multihouse Automatisering bv               uucp: ..!{uunet,hp4nl}!mh.nl!jv
  5409. Doesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62911/62500
  5410. ------------------------ "Arms are made for hugging" -------------------------
  5411.  
  5412. From CELEX@CELEX.KUN.NL  Wed Aug 22 09:17:03 1990
  5413. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5414.     id AA20264; Wed, 22 Aug 90 09:17:03 -0700
  5415. Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Wed, 22 Aug 90 09:16 MST
  5416. Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Wed, 22 Aug 90 18:18 MET
  5417. Date: Wed, 22 Aug 90 18:13 MET
  5418. From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
  5419. Subject: Screen I/O
  5420. To: icon-group@cs.arizona.edu
  5421. Message-Id: <469C508A341F402C33@KUNRC1.URC.KUN.NL>
  5422. X-Envelope-To: icon-group@cs.ARIZONA.EDU
  5423. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  5424. Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
  5425.  SURF/DECNET: celex::celexmail   JANET: celex%earn.hnympi52@uk.ac.earn-relay
  5426. Status: RO
  5427.  
  5428. Thanks to everyone who replied to my problem with the slow screen I/O
  5429. with Icon V8.
  5430.  
  5431. Richard wrote:
  5432. > Gcc is the GNU C compiler, and it produces much better code, in many
  5433. > instances, than the native compilers that come on various systems.
  5434. > I just wondered whether there was a VAX version.
  5435.  
  5436. Sorry Richard, I don't know if one is available.
  5437.  
  5438. > I do not use VMS, but I would be curious to know if anyone sends you
  5439. > a solution to your problem with Icon version 8.  I might be tempted
  5440. > to try version 7.5 to see if it works as fast as 8, since 7.5 is very
  5441. > close syntactically to version 8.  Version 8 mainly represents a change
  5442. > in the internal handling of tables and sets.  Version 8 also allows
  5443. > memory monitoring.
  5444.  
  5445. We had the same problem with v. 7.5, so we stayed with v.6 (I guess
  5446. we should have reported this problem then).
  5447.  
  5448. > You may find that, despite slower I/O, version 8 saves you so much
  5449. > space that it's worth it.  The space savings will show up in programs
  5450. > that use large sets and tables.
  5451. > Please let me know what you do.  I am curious.
  5452.  
  5453. I will.
  5454.  
  5455. Chris wrote:
  5456. > Recently someone mentioned something about Icon V8 being slower than V6 on a
  5457. > microvax in regards to screen IO. This sounds like a VMS system. I've used
  5458. > in primarily on VAX/VMS, but also a little on a VAX 780 running Berkeley Unix
  5459. > 4.3 and the screen IO behaviour difference is quite noticable.
  5460. > I think it's because the VMS version is trying to emulate the data stream
  5461. > concept of unix. This is why the unix redirectors <, >, and >> can be used
  5462. > with VMS ICON where VAX FORTRAN doesn't handle them automatically. Therefore,
  5463. > I'm not sure that we could or should ever expect speedy screen IO under VMS.
  5464. > I really like the redirectors and wouldn't want to loose them. Eventually,
  5465. > I'd like to see the PIPE | come to VMS ICON as well. Then we could issue
  5466. > commands like ICONX PROG1 <DATA.LIS | PROG2 | PROG3 >FILTERED.LIS where
  5467. > PROG1, PROG2, and PROG3 are icon executables.
  5468.  
  5469. From this I conclude that you think that above v6 the fast screen I/O
  5470. is sacrificed for the possibility of using redirectors. I can understand
  5471. you don't want to loose them, but we don't want to loose the fast screen
  5472. I/O. Wouldn't it be great, if your theory is right, to introduce 2 Icon
  5473. versions to keep both of us happy?
  5474.  
  5475. And finally Ken wrote:
  5476.  
  5477. > The Icon interpreter is a C program that uses C's fwrite() to implement
  5478. > the write() function. Do other C programs have these problems under VMS?
  5479.  
  5480. No, other (well, we only tried one) C-programs don't have that problem.
  5481. We compared the screen-output of the following 2 programs:
  5482.  
  5483. The C-version:
  5484.  
  5485. ---
  5486. #include stdio
  5487.  
  5488. main()
  5489.    {
  5490.    int i;
  5491.    char s[20] = "Hello world.\n";
  5492.    FILE term;
  5493.  
  5494.    term = fopen("SYS$OUTPUT","w");
  5495.    for (i=0; i<100; i++)
  5496.       fwrite(s,strlen(s),1,term);
  5497.    }
  5498. ---
  5499.  
  5500. The Icon-version:
  5501.  
  5502. ---
  5503. procedure main()
  5504.    s := "Hello world."
  5505.    every i := 1 to 100 do
  5506.       write(s)
  5507. end
  5508. ---
  5509.  
  5510. The Icon-output was considerably slower. Is the problem somewhere else?
  5511.  
  5512.  Marcel Bingley
  5513.  CELEX
  5514.  Nijmegen University - The Netherlands.
  5515.  
  5516. From CELEX@CELEX.KUN.NL  Wed Aug 22 12:50:54 1990
  5517. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5518.     id AA01353; Wed, 22 Aug 90 12:50:54 -0700
  5519. Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Wed, 22 Aug 90 12:50 MST
  5520. Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Wed, 22 Aug 90 18:23 MET
  5521. Date: Wed, 22 Aug 90 18:17 MET
  5522. From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
  5523. Subject: Screen I/O
  5524. To: icon-group@cs.arizona.edu
  5525. Message-Id: <469BBD46503F4031B6@KUNRC1.URC.KUN.NL>
  5526. X-Envelope-To: icon-group@cs.ARIZONA.EDU
  5527. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  5528. Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
  5529.  SURF/DECNET: celex::celexmail   JANET: celex%earn.hnympi52@uk.ac.earn-relay
  5530. Status: RO
  5531.  
  5532.  
  5533. In addition to my previous message: as Chris already guessed, we run
  5534. indeed VAX/VMS (version 5.1-B).
  5535.  
  5536. Marcel Bingley
  5537. CELEX
  5538. Nijmegen University - The Netherlands
  5539.  
  5540. From CELEX@CELEX.KUN.NL  Wed Aug 22 12:56:00 1990
  5541. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5542.     id AA01530; Wed, 22 Aug 90 12:56:00 -0700
  5543. Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Wed, 22 Aug 90 12:55 MST
  5544. Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Wed, 22 Aug 90 19:58 MET
  5545. Date: Wed, 22 Aug 90 19:51 MET
  5546. From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
  5547. Subject: RE: VMS I/O
  5548. To: icon-group@cs.arizona.edu
  5549. Message-Id: <468E719C6C3F4028D7@KUNRC1.URC.KUN.NL>
  5550. X-Envelope-To: icon-group@cs.ARIZONA.EDU
  5551. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  5552. Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
  5553.  SURF/DECNET: celex::celexmail   JANET: celex%earn.hnympi52@uk.ac.earn-relay
  5554. Status: RO
  5555.  
  5556.  
  5557. Dear Gregg,
  5558.  
  5559.  I tried your alternative C-program and it works fine (i.e. fast output).
  5560. The 2 C-programs and the V6-Icon-program produce fast output (you don't
  5561. see the cursor). With the V8-program you actually see the cursor writing
  5562. a line.
  5563.  
  5564.  Hope this gives you a clue.
  5565.  
  5566.  
  5567.  Marcel Bingley
  5568.  CELEX
  5569.  Nijmegen University - The Netherlands.
  5570.  
  5571. From icon-group-request@arizona.edu  Wed Aug 22 13:30:25 1990
  5572. Resent-From: icon-group-request@arizona.edu
  5573. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5574.     id AA03374; Wed, 22 Aug 90 13:30:25 -0700
  5575. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 22 Aug 90 13:30 MST
  5576. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA20284; Wed, 22 Aug 90
  5577.  13:29:42 -0700
  5578. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  5579.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  5580.  usenet@ucbvax.Berkeley.EDU if you have questions)
  5581. Resent-Date: Wed, 22 Aug 90 13:30 MST
  5582. Date: 22 Aug 90 20:07:02 GMT
  5583. From: news@psuvax1.cs.psu.edu
  5584. Subject: RE: Screen I/O
  5585. Sender: icon-group-request@arizona.edu
  5586. Resent-To: icon-group@cs.arizona.edu
  5587. To: icon-group@arizona.edu
  5588. Resent-Message-Id: <46C4A27228FF001B3F@Arizona.edu>
  5589. Message-Id: <F53rjst1@cs.psu.edu>
  5590. Organization: Pennsylvania State University, computer science
  5591. X-Envelope-To: icon-group@CS.Arizona.EDU
  5592. X-Vms-To: icon-group@Arizona.EDU
  5593. References: <469C508A341F402C33@KUNRC1.URC.KUN.NL>
  5594. Status: RO
  5595.  
  5596.  
  5597. Marcel Bingley writes:    
  5598.    Sorry Richard, I don't know if one is available.
  5599.  
  5600. There is.  prep.ai.mit.edu has gcc-vms.tar in pub/gnu.  
  5601.  
  5602. From icon-group-request@arizona.edu  Tue Aug 28 18:10:20 1990
  5603. Resent-From: icon-group-request@arizona.edu
  5604. Received: from Arizona.edu (hopey.telcom.arizona.edu) by megaron (5.61/15) via SMTP
  5605.     id AA05479; Tue, 28 Aug 90 18:10:20 -0700
  5606. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 28 Aug 90 18:09 MST
  5607. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09685; Tue, 28 Aug 90
  5608.  18:00:36 -0700
  5609. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  5610.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  5611.  usenet@ucbvax.Berkeley.EDU if you have questions)
  5612. Resent-Date: Tue, 28 Aug 90 18:10 MST
  5613. Date: 29 Aug 90 00:30:44 GMT
  5614. From: sdd.hp.com!zaphod.mps.ohio-state.edu!brutus.cs.uiuc.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@ucsd.edu
  5615. Subject: game
  5616. Sender: icon-group-request@arizona.edu
  5617. Resent-To: icon-group@cs.arizona.edu
  5618. To: icon-group@arizona.edu
  5619. Resent-Message-Id: <41E68D3299CB003A39@Arizona.edu>
  5620. Message-Id: <1990Aug29.003044.10129@midway.uchicago.edu>
  5621. Organization: University of Chicago
  5622. X-Envelope-To: icon-group@CS.Arizona.EDU
  5623. X-Vms-To: icon-group@Arizona.EDU
  5624.  
  5625. Would anyone like to try out an idle game I wrote which simply does
  5626. pretty things on the screen?
  5627.  
  5628. I wrote it to test out some utility libraries, so the real reason
  5629. behind my asking is to get feedback on those libraries.
  5630.  
  5631. NB:  To run everything, you'll need to be operating in a Unix envi-
  5632. ronment, or else enjoy hacking.
  5633.  
  5634. -Richard
  5635.  
  5636. From @mirsa.inria.fr:ol@cerisi.cerisi.Fr  Wed Aug 29 00:48:06 1990
  5637. Resent-From: @mirsa.inria.fr:ol@cerisi.cerisi.Fr
  5638. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5639.     id AA17796; Wed, 29 Aug 90 00:48:06 -0700
  5640. Received: from mirsa.inria.fr by Arizona.edu; Wed, 29 Aug 90 00:47 MST
  5641. Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP (5.61+++/IDA-1.2.8)
  5642.  id AA08085; Wed, 29 Aug 90 09:49:14 +0200
  5643. Resent-Date: Wed, 29 Aug 90 00:47 MST
  5644. Date: Wed, 29 Aug 90 09:45:50 -0100
  5645. From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
  5646. Subject: game
  5647. Resent-To: icon-group@cs.arizona.edu
  5648. To: quads.%midway@ux1.cso.uiuc.edu
  5649. Cc: icon-group@arizona.edu
  5650. Resent-Message-Id: <41AEFF3FD06B004B84@Arizona.edu>
  5651. Message-Id: <9008290749.AA08085@mirsa.inria.fr>
  5652. Posted-Date: Wed, 29 Aug 90 09:45:50 -0100
  5653. In-Reply-To: 
  5654.  sdd.hp.com!zaphod.mps.ohio-state.edu!brutus.cs.uiuc.edu!ux1.cso.uiuc.edu!midway!quads.'s message
  5655.  of 29 Aug 90 00:30:44 GMT <1990Aug29.003044.10129@midway.uchicago.edu>
  5656. X-Envelope-To: icon-group@CS.Arizona.EDU
  5657. X-Vms-To: quads.%midway@ux1.cso.uiuc.edu
  5658. X-Vms-Cc: icon-group@Arizona.EDU
  5659.  
  5660. Why not?
  5661.  
  5662.  
  5663.                 Olivier Lecarme
  5664.  
  5665. From MYankowski.BSPO@DOCKMASTER.NCSC.MIL  Tue Sep  4 08:34:13 1990
  5666. Received: from DOCKMASTER.NCSC.MIL by megaron (5.61/15) via SMTP
  5667.     id AA29669; Tue, 4 Sep 90 08:34:13 -0700
  5668. Date:  Tue, 4 Sep 90 11:27 EDT
  5669. From: MYankowski@DOCKMASTER.NCSC.MIL
  5670. Subject:  parsing the backslash character
  5671. To: icon-group@128.196.128.118
  5672. Message-Id:  <900904152756.009633@DOCKMASTER.NCSC.MIL>
  5673.  
  5674. I am trying to parse a string which is a DOS path name.  I cannot pull
  5675. out the directory separators ("\") because ICON recognizes them as an
  5676. escape sequence, if it is valid, or just returns the character that
  5677. follows the backslash.  Can anyone offer any sug- gestions.
  5678.  
  5679.  
  5680.  
  5681. Michael Yankowski Dockmaster.ARPA
  5682.  
  5683.  
  5684. From nowlin@iwtqg.att.com  Tue Sep  4 11:37:19 1990
  5685. Resent-From: nowlin@iwtqg.att.com
  5686. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5687.     id AA11697; Tue, 4 Sep 90 11:37:19 -0700
  5688. Received: from att-in.att.com by Arizona.edu; Tue, 4 Sep 90 11:36 MST
  5689. Resent-Date: Tue, 4 Sep 90 11:37 MST
  5690. Date: Tue, 4 Sep 90 11:23 CDT
  5691. From: nowlin@iwtqg.att.com
  5692. Subject: RE: parsing the backslash character
  5693. Resent-To: icon-group@cs.arizona.edu
  5694. To: att!arizona.edu!icon-group@cs.arizona.edu
  5695. Resent-Message-Id: <3C9D4C53B8A7006AD2@Arizona.edu>
  5696. Message-Id: <3C9D55EB9F972059DB@Arizona.edu>
  5697. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  5698. X-Envelope-To: icon-group@CS.Arizona.EDU
  5699. X-Vms-To: att!arizona.edu!icon-group@cs.Arizona.edu
  5700.  
  5701. > I am trying to parse a string which is a DOS path name.  I cannot pull
  5702. > out the directory separators ("\") because ICON recognizes them as an
  5703. > escape sequence, if it is valid, or just returns the character that
  5704. > follows the backslash.  Can anyone offer any sug- gestions.
  5705. > Michael Yankowski Dockmaster.ARPA
  5706.  
  5707. A backslash is just another character if it's in a string you're
  5708. scanning.  The trick is specifying the backslash as the scanning
  5709. target.  Two backslashes is the way.  For example, if the your
  5710. program reads lines containing DOS pathnames to be scanned you
  5711. could pull off the directory segments of the paths and the command
  5712. names with this simple program:
  5713.  
  5714. procedure main()
  5715.  
  5716.     while line := read() do {
  5717.  
  5718.         line ? {
  5719.             dir := []
  5720.             while put(dir,tab(upto('\\'))) do tab(many('\\'))
  5721.             cmd := tab(0)
  5722.         }
  5723.  
  5724.         every writes(!dir,"\\")
  5725.         write(cmd)
  5726.     }
  5727. end
  5728.  
  5729. This program reconstructs the paths and writes them back out but
  5730. you could do anything with them at that point.
  5731.  
  5732. Jerry Nowlin
  5733. (...!att!iwtqg!nowlin)
  5734.  
  5735. From icon-group-request@arizona.edu  Wed Sep  5 03:25:50 1990
  5736. Resent-From: icon-group-request@arizona.edu
  5737. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  5738.     id AA28854; Wed, 5 Sep 90 03:25:50 -0700
  5739. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 5 Sep 90 03:25 MST
  5740. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29436; Wed, 5 Sep 90 03:14:59
  5741.  -0700
  5742. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  5743.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  5744.  usenet@ucbvax.Berkeley.EDU if you have questions)
  5745. Resent-Date: Wed, 5 Sep 90 03:25 MST
  5746. Date: 4 Sep 90 04:59:25 GMT
  5747. From: cs.utexas.edu!sdd.hp.com!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!mcs.anl.gov!midway!quads.uchicago.edu!goer@tut.cis.ohio-state.edu
  5748. Subject: I/O routines, part 02 of 02
  5749. Sender: icon-group-request@arizona.edu
  5750. Resent-To: icon-group@cs.arizona.edu
  5751. To: icon-group@arizona.edu
  5752. Resent-Message-Id: <3C18CE2794EB006839@Arizona.edu>
  5753. Message-Id: <1990Sep4.045925.26376@midway.uchicago.edu>
  5754. Organization: University of Chicago
  5755. X-Envelope-To: icon-group@CS.Arizona.EDU
  5756. X-Vms-To: icon-group@Arizona.EDU
  5757.  
  5758.  
  5759. ---- Cut Here and unpack ----
  5760. #!/bin/sh
  5761. # this is itlib.02 (part 2 of a multipart archive)
  5762. # do not concatenate these parts, unpack them in order with /bin/sh
  5763. # file itlibdos.icn continued
  5764. #
  5765. if test ! -r shar3_seq_.tmp; then
  5766.     echo "Please unpack part 1 first!"
  5767.     exit 1
  5768. fi
  5769. (read Scheck
  5770.  if test "$Scheck" != 2; then
  5771.     echo "Please unpack part $Scheck next!"
  5772.     exit 1
  5773.  else
  5774.     exit 0
  5775.  fi
  5776. ) < shar3_seq_.tmp || exit 1
  5777. echo "x - Continuing file itlibdos.icn"
  5778. sed 's/^X//' << 'SHAR_EOF' >> itlibdos.icn &&
  5779. X        &subject == "" & next
  5780. X        if k := 1(move(2), ="=")
  5781. X        then /tc_table[k] := decode(tab(find(":")))
  5782. X        else if k := 1(move(2), ="#")
  5783. X        then /tc_table[k] := integer(tab(find(":")))
  5784. X        else if k := 1(tab(find(":")), pos(-1))
  5785. X        then /tc_table[k] := true()
  5786. X        else er("maketc_table", "your termcap file has a bad entry",3)
  5787. X        &null  # in case insertion fails due to duplicate entry
  5788. X    }
  5789. X    }
  5790. X
  5791. X    return tc_table
  5792. X
  5793. Xend
  5794. X
  5795. X
  5796. X
  5797. Xprocedure getval(id)
  5798. X
  5799. X    /tc_table := maketc_table(getentry(getname())) |
  5800. X    er("getval","can't make a table for your terminal",4)
  5801. X
  5802. X    return \tc_table[id] | fail
  5803. X    # er("getval","the current terminal doesn't support "||id,7)
  5804. X
  5805. Xend
  5806. X
  5807. X
  5808. X
  5809. Xprocedure decode(s)
  5810. X
  5811. X    # Does things like turn ^ plus a letter into a genuine control
  5812. X    # character.
  5813. X
  5814. X    new_s := ""
  5815. X
  5816. X    s ? {
  5817. X    while new_s ||:= tab(upto('\\^')) do {
  5818. X        chr := move(1)
  5819. X        if chr == "\\" then {
  5820. X        new_s ||:= {
  5821. X            case chr2 := move(1) of {
  5822. X            "\\" : "\\"
  5823. X            "^"  : "^"
  5824. X            "E"  : "\e"
  5825. X            "b"  : "\b"
  5826. X            "f"  : "\f"
  5827. X            "n"  : "\n"
  5828. X            "r"  : "\r"
  5829. X            "t"  : "\t"
  5830. X            default : {
  5831. X                if any(&digits,chr2) then {
  5832. X                char(integer("8r"||chr2||move(2 to 0 by -1))) |
  5833. X                    er("decode","bad termcap entry",3)
  5834. X                }
  5835. X               else chr2
  5836. X            }
  5837. X            }
  5838. X        }
  5839. X        }
  5840. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  5841. X    }
  5842. X    new_s ||:= tab(0)
  5843. X    }
  5844. X
  5845. X    return new_s
  5846. X
  5847. Xend
  5848. X
  5849. X
  5850. X
  5851. Xprocedure igoto(cm,col,line)
  5852. X
  5853. X    local colline, range, increment, str, outstr, chr, x, y
  5854. X
  5855. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  5856. X    colline := string(\col) || "," || string(\line) | string(\col|line)
  5857. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  5858. X    er("igoto",colline || " out of range " || (\range|""),9)
  5859. X    } 
  5860. X
  5861. X    # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  5862. X    increment := -1
  5863. X    outstr := ""
  5864. X    
  5865. X    cm ? {
  5866. X    while outstr ||:= tab(find("%")) do {
  5867. X        tab(match("%"))
  5868. X        chr := move(1)
  5869. X        if case chr of {
  5870. X        "." :  outstr ||:= char(line + increment)
  5871. X        "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  5872. X        "d" :  {
  5873. X            str := string(line + increment)
  5874. X            outstr ||:= right(str, integer(tab(any('23'))), "0") | str
  5875. X        }
  5876. X        }
  5877. X        then line :=: col
  5878. X        else {
  5879. X        case chr of {
  5880. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  5881. X            "i" :  increment := 0
  5882. X            "r" :  line :=: col
  5883. X            "%" :  outstr ||:= "%"
  5884. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  5885. X            ">" :  {
  5886. X            x := move(1); y := move(1)
  5887. X            line > ord(x) & line +:= ord(y)
  5888. X            &null
  5889. X            }
  5890. X        } | er("goto","bad termcap entry",5)
  5891. X        }
  5892. X    }
  5893. X    return outstr || tab(0)
  5894. X    }
  5895. X
  5896. Xend
  5897. X
  5898. X
  5899. X
  5900. Xprocedure iputs(cp, affcnt)
  5901. X
  5902. X    # Writes cp to the screen.  Use this instead of writes() for
  5903. X    # compatibility with the Unix version (which will need to send
  5904. X    # null padding in some cases).  Iputs() also does a useful type
  5905. X    # check.
  5906. X
  5907. X    static num_chars
  5908. X    initial num_chars := &digits ++ '.'
  5909. X
  5910. X    type(cp) == "string" |
  5911. X    er("iputs","you can't iputs() a non-string value!",10)
  5912. X
  5913. X    cp ? {
  5914. X    if tab(many(num_chars)) & ="*" then
  5915. X        stop("iputs:  MS-DOS termcap files shouldn't specify padding.")
  5916. X    writes(tab(0))
  5917. X    }
  5918. X
  5919. X    return
  5920. X
  5921. Xend
  5922. SHAR_EOF
  5923. echo "File itlibdos.icn is complete" &&
  5924. # ============= termcap.dos ==============
  5925. echo "x - extracting termcap.dos (Text)"
  5926. sed 's/^X//' << 'SHAR_EOF' > termcap.dos &&
  5927. Xansi|color|ansi-color|ibm|ibmpc|ANSI.SYS color:\
  5928. X    :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\
  5929. X    :cl=\E[H\E[2J:ce=\E[K:\
  5930. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  5931. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5932. X    :ti=\E[0;44m:te=\E[0m:\
  5933. X    :so=\E[1;35;44m:se=\E[0;44m:\
  5934. X    :us=\E[1;31;44m:ue=\E[0;44m:\
  5935. X    :mb=\E[5m:md=\E[1m:me=\E[0;44m:
  5936. Xmono|ansi-mono|ANSI.SYS:\
  5937. X    :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\
  5938. X    :cl=\E[H\E[2J:ce=\E[K:\
  5939. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  5940. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5941. X    :so=\E[1m:se=\E[m:us=\E[4m:ue=\E[m:\
  5942. X    :mb=\E[5m:md=\E[1m:me=\E[m:
  5943. Xnnansi-mono|NNANSI.SYS:\
  5944. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  5945. X    :cl=\E[2J:cd=\E[J:ce=\E[K:\
  5946. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  5947. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5948. X    :so=\E[1m:se=\E[2m:\
  5949. X    :us=\E[4m:ue=\E[24m:\
  5950. X    :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[m:\
  5951. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  5952. Xnnansi|nnansi-color|NNANSI.SYS color:\
  5953. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  5954. X    :cl=\E[2J:cd=\E[J:ce=\E[K:\
  5955. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  5956. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5957. X    :ti=\E[0;44m:te=\E[0m:\
  5958. X    :so=\E[1;35;44m:se=\E[2;37m:\
  5959. X    :us=\E[4m:ue=\E[24m:\
  5960. X    :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[0;44m:\
  5961. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  5962. Xnansi-mono|zansi-mono|N/ZANSI.SYS:\
  5963. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  5964. X    :cl=\E[2J:ce=\E[K:\
  5965. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  5966. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5967. X    :ti=\E[0m:te=\E[0m:\
  5968. X    :so=\E[1;35m:se=\E[0m:\
  5969. X    :us=\E[1;31m:ue=\E[0m:\
  5970. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:\
  5971. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  5972. Xnansi|zansi|nansi-color|zansi-color|N/ZANSI.SYS color:\
  5973. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  5974. X    :cl=\E[2J:ce=\E[K:\
  5975. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  5976. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5977. X    :ti=\E[0;44m:te=\E[0m:\
  5978. X    :so=\E[1;35;44m:se=\E[0;44m:\
  5979. X    :us=\E[1;31;44m:ue=\E[0;44m:\
  5980. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[0;44m:\
  5981. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  5982. XAX|ANSI X3.64|full ANSI X3.64 (1977) standard:\
  5983. X    :co#80:li#24:bs:pt:am:mi:bl=^G:le=^H:\
  5984. X    :cl=\E[2J:ce=\E[K:cd=\E[J:\
  5985. X    :ho=\E[H:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\
  5986. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  5987. X    :UP=\E[%dA:DO=\E[%dB:LE=\E[%dC:RI=\E[%dD:\
  5988. X    :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
  5989. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:as=^N:ae=^O:\
  5990. X    :ku=\E[A:kd=\E[B:kl=\E[C:kr=\E[D:kb=^H:\
  5991. X    :kn#4:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\
  5992. X    :im=\E[4h:ei=\E[4l:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:sf=\ED:sr=\EM:
  5993. SHAR_EOF
  5994. rm -f shar3_seq_.tmp
  5995. echo "You have unpacked the last part"
  5996. exit 0
  5997.  
  5998. From icon-group-request@arizona.edu  Wed Sep  5 03:26:14 1990
  5999. Resent-From: icon-group-request@arizona.edu
  6000. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  6001.     id AA28870; Wed, 5 Sep 90 03:26:14 -0700
  6002. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 5 Sep 90 03:25 MST
  6003. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29438; Wed, 5 Sep 90 03:14:59
  6004.  -0700
  6005. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  6006.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  6007.  usenet@ucbvax.Berkeley.EDU if you have questions)
  6008. Resent-Date: Wed, 5 Sep 90 03:25 MST
  6009. Date: 4 Sep 90 04:57:30 GMT
  6010. From: usc!zaphod.mps.ohio-state.edu!maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!mcs.anl.gov!midway!quads.uchicago.edu!goer@ucsd.edu
  6011. Subject: I/O library, part 01 of 02
  6012. Sender: icon-group-request@arizona.edu
  6013. Resent-To: icon-group@cs.arizona.edu
  6014. To: icon-group@arizona.edu
  6015. Resent-Message-Id: <3C18BD78A58B006ABA@Arizona.edu>
  6016. Message-Id: <1990Sep4.045730.26320@midway.uchicago.edu>
  6017. Organization: University of Chicago
  6018. X-Envelope-To: icon-group@CS.Arizona.EDU
  6019. X-Vms-To: icon-group@Arizona.EDU
  6020. References: <1990Aug29.003044.10129@midway.uchicago.edu>,
  6021.  <9008290749.AA08085@mirsa.inria.fr>
  6022.  
  6023. A few months ago, I posted a set of generalized I/O routines for Icon
  6024. running on Unix routines.  Since then, I've used various underhanded
  6025. means of testing them, such as porting Alan Corre's calendar program
  6026. to Unix, and sending out a little snake game.
  6027.  
  6028. The routines are now in fair shape.  What is more, I've ported them to
  6029. MS-DOS, so that people can now write programs for the one environment,
  6030. and expect them to run (and look pretty much the same) in the other.
  6031. I really hope that, by using these generalized routines, people will
  6032. be able to avoid the cardinal sin of hard-coding OS and terminal spe-
  6033. cific I/O routines into their source code.
  6034.  
  6035. This posting is long, but I've received a number of requests for the
  6036. package.  To be sure no one's mailer barf's on it, it's been split
  6037. into two parts.  This is part 1.
  6038.  
  6039. -Richard
  6040.  
  6041. (BTW:  The MS-DOS version is much less well-tested than the Unix ver-
  6042. sion, mainly because I don't use DOS much, and when I do it's usually
  6043. by way of a DOS emulator running as a task under Xenix.)
  6044.  
  6045. ---- Cut Here and unpack ----
  6046. #!/bin/sh
  6047. # This is a shell archive (shar 3.24)
  6048. # made 08/31/1990 05:59 UTC by goer@sophist.uchicago.edu
  6049. # Source directory /u/richard/Itermlib
  6050. #
  6051. # existing files WILL be overwritten
  6052. # This format requires very little intelligence at unshar time.
  6053. # "echo" and "sed" will be needed.
  6054. #
  6055. # This is part 1 of a multipart archive                                    
  6056. # do not concatenate these parts, unpack them in order with /bin/sh        
  6057. #
  6058. # This shar contains:
  6059. # length  mode       name
  6060. # ------ ---------- ------------------------------------------
  6061. #  12054 -r--r--r-- itlib.icn
  6062. #   4980 -r--r--r-- iscreen.icn
  6063. #  15452 -r--r--r-- itlibdos.icn
  6064. #   2391 -r--r--r-- termcap.dos
  6065. #
  6066. if test -r shar3_seq_.tmp; then
  6067.     echo "Must unpack archives in sequence!"
  6068.     next=`cat shar3_seq_.tmp`; echo "Please unpack part $next next"
  6069.     exit 1
  6070. fi
  6071. # ============= itlib.icn ==============
  6072. echo "x - extracting itlib.icn (Text)"
  6073. sed 's/^X//' << 'SHAR_EOF' > itlib.icn &&
  6074. X########################################################################
  6075. X#    
  6076. X#    Name:    itlib.icn
  6077. X#    
  6078. X#    Title:    Icon termlib-type tools
  6079. X#    
  6080. X#    Author:    Richard L. Goerwitz
  6081. X#
  6082. X#    Version: 1.12
  6083. X#
  6084. X########################################################################
  6085. X#
  6086. X#  Copyright (c) 1990, Richard L. Goerwitz, III
  6087. X#
  6088. X#  This software is intended for free and unrestricted distribution.
  6089. X#  I place only two conditions on its use:  1) That you clearly mark
  6090. X#  any additions or changes you make to the source code, and 2) that
  6091. X#  you do not delete this message therefrom.  In order to protect
  6092. X#  myself from spurious litigation, it must also be stated here that,
  6093. X#  because this is free software, I, Richard Goerwitz, make no claim
  6094. X#  about the applicability or fitness of this software for any
  6095. X#  purpose, and expressly disclaim any responsibility for any damages
  6096. X#  that might be incurred in conjunction with its use.
  6097. X#
  6098. X########################################################################
  6099. X#
  6100. X#  The following library represents a series of rough functional
  6101. X#  equivalents to the standard Unix low-level termcap routines.  They
  6102. X#  are not meant as exact termlib clones.  Nor are they enhanced to
  6103. X#  take care of magic cookie terminals, terminals that use \D in their
  6104. X#  termcap entries, or, in short, anything I felt would not affect my
  6105. X#  normal, day-to-day work with ANSI and vt100 terminals.
  6106. X#
  6107. X#  Requires:  A unix platform & co-expressions.  I have diffs for a
  6108. X#  MS-DOS version, if anyone wants them.
  6109. X#
  6110. X#  setname(term)
  6111. X#    Use only if you wish to initialize itermlib for a terminal
  6112. X#  other than what your current environment specifies.  "Term" is the
  6113. X#  name of the termcap entry to use.  Normally this initialization is
  6114. X#  done automatically, and need not concern the user.
  6115. X#
  6116. X#  getval(id)
  6117. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  6118. X#  spirit of Icon, all three have been collapsed into one routine.
  6119. X#  Integer valued caps are returned as integers, strings as strings,
  6120. X#  and flags as records (if a flag is set, then type(flag) will return
  6121. X#  "true").  Absence of a given capability is signalled by procedure
  6122. X#  failure.
  6123. X#
  6124. X#  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  6125. X#    Analogous to tgoto.  "Cm" is the cursor movement command for
  6126. X#  the current terminal, as obtained via getval("cm").  Igoto()
  6127. X#  returns a string which, when output via iputs, will cause the
  6128. X#  cursor to move to column "destcol" and line "destline."  Column and
  6129. X#  line are always calculated using a *one* offset.  This is far more
  6130. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  6131. X#  go to the first square on your screen, then include in your program
  6132. X#  "iputs(igoto(getval("cm"),1,1))."
  6133. X#
  6134. X#  iputs(cp,affcnt)
  6135. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  6136. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  6137. X#  count of affected lines.  It is only relevant for terminals which
  6138. X#  specify proportional (starred) delays in their termcap entries.
  6139. X#
  6140. X#  Bugs:  I have not tested these routines on terminals that require
  6141. X#  padding.
  6142. X#
  6143. X##########################################################################
  6144. X#
  6145. X#  Requires: UNIX, co-expressions
  6146. X#
  6147. X#  See also: iscreen.icn (a set of companion utilities)
  6148. X#
  6149. X##########################################################################
  6150. X
  6151. X
  6152. Xglobal tc_table, tty_speed
  6153. Xrecord true()
  6154. X
  6155. X
  6156. Xprocedure check_features()
  6157. X
  6158. X    local in_params, line
  6159. X    # global tty_speed
  6160. X
  6161. X    initial {
  6162. X    find("unix",map(&features)) |
  6163. X        er("check_features","unix system required",1)
  6164. X    find("o-expres",&features) |
  6165. X        er("check_features","co-expressions not implemented - &$#!",1)
  6166. X    system("/bin/stty tabs") |
  6167. X        er("check_features","can't set tabs option",1)
  6168. X    }
  6169. X
  6170. X    # clumsy, clumsy, clumsy, and probably won't work on all systems
  6171. X    in_params := open("/bin/stty 2>&1","pr") | fail
  6172. X    every line := !in_params do {
  6173. X    line ? {
  6174. X        tab(find("speed")+5) &
  6175. X        tab(many(' ')) &
  6176. X        tty_speed := integer(tab(many(&digits)))
  6177. X    }
  6178. X    }
  6179. X    close(in_params)
  6180. X    return "term characteristics reset; features check out"
  6181. X
  6182. Xend
  6183. X
  6184. X
  6185. X
  6186. Xprocedure setname(name)
  6187. X
  6188. X    # Sets current terminal type to "name" and builds a new termcap
  6189. X    # capability database (residing in tc_table).  Fails if unable to
  6190. X    # find a termcap entry for terminal type "name."  If you want it
  6191. X    # to terminate with an error message under these circumstances,
  6192. X    # comment out "| fail" below, and uncomment the er() line.
  6193. X
  6194. X    #tc_table is global
  6195. X    
  6196. X    check_features()
  6197. X
  6198. X    tc_table := maketc_table(getentry(name)) | fail
  6199. X    # er("setname","no termcap entry found for "||name,3)
  6200. X    return "successfully reset for terminal " || name
  6201. X
  6202. Xend
  6203. X
  6204. X
  6205. X
  6206. Xprocedure getname()
  6207. X
  6208. X    # Getname() first checks to be sure we're running under Unix, and,
  6209. X    # if so, tries to figure out what the current terminal type is,
  6210. X    # checking successively the value of the environment variable
  6211. X    # TERM, and then the output of "tset -".  Terminates with an error
  6212. X    # message if the terminal type cannot be ascertained.
  6213. X
  6214. X    local term, tset_output
  6215. X
  6216. X    check_features()
  6217. X
  6218. X    if not (term := getenv("TERM")) then {
  6219. X    tset_output := open("/bin/tset -","pr") |
  6220. X        er("getname","can't find tset command",1)
  6221. X    term := !tset_output
  6222. X    close(tset_output)
  6223. X    }
  6224. X    return \term |
  6225. X    er("getname","can't seem to determine your terminal type",1)
  6226. X
  6227. Xend
  6228. X
  6229. X
  6230. X
  6231. Xprocedure er(func,msg,errnum)
  6232. X
  6233. X    # short error processing utility
  6234. X    write(&errout,func,":  ",msg)
  6235. X    exit(errnum)
  6236. X
  6237. Xend
  6238. X
  6239. X
  6240. X
  6241. Xprocedure getentry(name)
  6242. X
  6243. X    # "Name" designates the current terminal type.  Getentry() scans
  6244. X    # the current environment for the variable TERMCAP.  If the
  6245. X    # TERMCAP string represents a termcap entry for a terminal of type
  6246. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  6247. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  6248. X    # getentry() will scan that file for an entry corresponding to
  6249. X    # "name."  If the TERMCAP string does not designate a filename,
  6250. X    # getentry() will scan /etc/termcap for the correct entry.
  6251. X    # Whatever the input file, if an entry for terminal "name" is
  6252. X    # found, getentry() returns that entry.  Otherwise, getentry()
  6253. X    # fails.
  6254. X
  6255. X    local termcap_string, f, getline, line, nm, ent1, ent2
  6256. X
  6257. X    termcap_string := getenv("TERMCAP")
  6258. X
  6259. X    if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name)
  6260. X    then return termcap_string
  6261. X    else {
  6262. X
  6263. X    # The logic here probably isn't clear.  The idea is to try to use
  6264. X    # the termcap environment variable successively as 1) a termcap en-
  6265. X    # try and then 2) as a termcap file.  If neither works, 3) go to
  6266. X    # the /etc/termcap file.  The else clause here does 2 and, if ne-
  6267. X    # cessary, 3.  The "\termcap_string ? (not match..." expression
  6268. X    # handles 1.
  6269. X
  6270. X    if find("/",\termcap_string)
  6271. X    then f := open(termcap_string)
  6272. X    /f := open("/etc/termcap") |
  6273. X        er("getentry","I can't access your /etc/termcap file",1)
  6274. X
  6275. X    getline := create read_file(f)
  6276. X    
  6277. X    while line := @getline do {
  6278. X        if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  6279. X        entry := ""
  6280. X        while (\line | @getline) ? {
  6281. X            if entry ||:= 1(tab(find(":")+1), pos(0))
  6282. X            then {
  6283. X            close(f)
  6284. X            # if entry ends in tc= then add in the named tc entry
  6285. X            entry ?:= tab(find("tc=")) ||
  6286. X                # recursively fetch the new termcap entry
  6287. X                (move(3), getentry(tab(find(":"))) ?
  6288. X                    # remove the name field from the new entry
  6289. X                     (tab(find(":")+1), tab(0)))
  6290. X            return entry
  6291. X            }
  6292. X            else {
  6293. X            \line := &null # must precede the next line
  6294. X            entry ||:= tab(-2)
  6295. X            }
  6296. X        }
  6297. X        }
  6298. X    }
  6299. X    }
  6300. X
  6301. X    close(f)
  6302. X    er("getentry","can't find and/or process your termcap entry",3)
  6303. Xend
  6304. X
  6305. X
  6306. X
  6307. Xprocedure read_file(f)
  6308. X
  6309. X    # Suspends all non #-initial lines in the file f.
  6310. X    # Removes leading tabs and spaces from lines before suspending
  6311. X    # them.
  6312. X
  6313. X    local line
  6314. X
  6315. X    \f | er("read_tcap_file","no valid termcap file found",3)
  6316. X    while line := read(f) do {
  6317. X    match("#",line) & next
  6318. X    line ?:= (tab(many('\t ')) | &null, tab(0))
  6319. X    suspend line
  6320. X    }
  6321. X
  6322. X    fail
  6323. X
  6324. Xend
  6325. X
  6326. X
  6327. X
  6328. Xprocedure maketc_table(entry)
  6329. X
  6330. X    # Maketc_table(s) (where s is a valid termcap entry for some
  6331. X    # terminal-type): Returns a table in which the keys are termcap
  6332. X    # capability designators, and the values are the entries in
  6333. X    # "entry" for those designators.
  6334. X
  6335. X    local k, v
  6336. X
  6337. X    /entry & er("maketc_table","no entry given",8)
  6338. X    if entry[-1] ~== ":" then entry ||:= ":"
  6339. X    
  6340. X    tc_table := table()
  6341. X
  6342. X    entry ? {
  6343. X
  6344. X    tab(find(":")+1)    # tab past initial (name) field
  6345. X
  6346. X    while tab((find(":")+1) \ 1) ? {
  6347. X
  6348. X        &subject == "" & next
  6349. X        if k := 1(move(2), ="=")
  6350. X        then /tc_table[k] := decode(tab(find(":")))
  6351. X        else if k := 1(move(2), ="#")
  6352. X        then /tc_table[k] := integer(tab(find(":")))
  6353. X        else if k := 1(tab(find(":")), pos(-1))
  6354. X        then /tc_table[k] := true()
  6355. X        else er("maketc_table", "your termcap file has a bad entry",3)
  6356. X        &null  # in case insertion fails due to duplicate entry
  6357. X    }
  6358. X    }
  6359. X
  6360. X    return tc_table
  6361. X
  6362. Xend
  6363. X
  6364. X
  6365. X
  6366. Xprocedure getval(id)
  6367. X
  6368. X    /tc_table := maketc_table(getentry(getname())) |
  6369. X    er("getval","can't make a table for your terminal",4)
  6370. X
  6371. X    return \tc_table[id] | fail
  6372. X    # er("getval","the current terminal doesn't support "||id,7)
  6373. X
  6374. Xend
  6375. X
  6376. X
  6377. X
  6378. Xprocedure decode(s)
  6379. X
  6380. X    # Does things like turn ^ plus a letter into a genuine control
  6381. X    # character.
  6382. X
  6383. X    new_s := ""
  6384. X
  6385. X    s ? {
  6386. X    while new_s ||:= tab(upto('\\^')) do {
  6387. X        chr := move(1)
  6388. X        if chr == "\\" then {
  6389. X        new_s ||:= {
  6390. X            case chr2 := move(1) of {
  6391. X            "\\" : "\\"
  6392. X            "^"  : "^"
  6393. X            "E"  : "\e"
  6394. X            "b"  : "\b"
  6395. X            "f"  : "\f"
  6396. X            "n"  : "\n"
  6397. X            "r"  : "\r"
  6398. X            "t"  : "\t"
  6399. X            default : {
  6400. X                if any(&digits,chr2) then {
  6401. X                char(integer("8r"||chr2||move(2 to 0 by -1))) |
  6402. X                    er("decode","bad termcap entry",3)
  6403. X                }
  6404. X               else chr2
  6405. X            }
  6406. X            }
  6407. X        }
  6408. X        }
  6409. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  6410. X    }
  6411. X    new_s ||:= tab(0)
  6412. X    }
  6413. X
  6414. X    return new_s
  6415. X
  6416. Xend
  6417. X
  6418. X
  6419. X
  6420. Xprocedure igoto(cm,col,line)
  6421. X
  6422. X    local colline, range, increment, str, outstr, chr, x, y
  6423. X
  6424. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  6425. X    colline := string(\col) || "," || string(\line) | string(\col|line)
  6426. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  6427. X    er("igoto",colline || " out of range " || (\range|""),9)
  6428. X    } 
  6429. X
  6430. X    # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  6431. X    increment := -1
  6432. X    outstr := ""
  6433. X    
  6434. X    cm ? {
  6435. X    while outstr ||:= tab(find("%")) do {
  6436. X        tab(match("%"))
  6437. X        chr := move(1)
  6438. X        if case chr of {
  6439. X        "." :  outstr ||:= char(line + increment)
  6440. X        "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  6441. X        "d" :  {
  6442. X            str := string(line + increment)
  6443. X            outstr ||:= right(str, integer(tab(any('23'))), "0") | str
  6444. X        }
  6445. X        }
  6446. X        then line :=: col
  6447. X        else {
  6448. X        case chr of {
  6449. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  6450. X            "i" :  increment := 0
  6451. X            "r" :  line :=: col
  6452. X            "%" :  outstr ||:= "%"
  6453. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  6454. X            ">" :  {
  6455. X            x := move(1); y := move(1)
  6456. X            line > ord(x) & line +:= ord(y)
  6457. X            &null
  6458. X            }
  6459. X        } | er("goto","bad termcap entry",5)
  6460. X        }
  6461. X    }
  6462. X    return outstr || tab(0)
  6463. X    }
  6464. X
  6465. Xend
  6466. X
  6467. X
  6468. X
  6469. Xprocedure iputs(cp, affcnt)
  6470. X
  6471. X    local baud_rates, char_rates, i, delay, PC
  6472. X    static num_chars, char_times
  6473. X    # global tty_speed
  6474. X
  6475. X    initial {
  6476. X    num_chars := &digits ++ '.'
  6477. X    char_times := table()
  6478. X    baud_rates := [0,300,600,1200,1800,2400,4800,9600,19200]
  6479. X    char_rates := [0,333,166,83,55,41,20,10,5]
  6480. X    every i := 1 to *baud_rates do {
  6481. X        char_times[baud_rates[i]] := char_rates[i]
  6482. X    }
  6483. X    }
  6484. X
  6485. X    type(cp) == "string" |
  6486. X    er("iputs","you can't iputs() a non-string value!",10)
  6487. X
  6488. X    cp ? {
  6489. X    delay := tab(many(num_chars))
  6490. X    if ="*" then {
  6491. X        delay *:= \affcnt |
  6492. X        er("iputs","affected line count missing",6)
  6493. X    }
  6494. X    writes(tab(0))
  6495. X    }
  6496. X
  6497. X    if (\delay, tty_speed ~= 0) then {
  6498. X    PC := tc_table["pc"] | "\000"
  6499. X    char_time := char_times[tty_speed] | (return "speed error")
  6500. X    delay := (delay * char_time) + (char_time / 2)
  6501. X    every 1 to delay by 10
  6502. X    do writes(PC)
  6503. X    }
  6504. X
  6505. X    return
  6506. X
  6507. Xend
  6508. SHAR_EOF
  6509. # ============= iscreen.icn ==============
  6510. echo "x - extracting iscreen.icn (Text)"
  6511. sed 's/^X//' << 'SHAR_EOF' > iscreen.icn &&
  6512. X############################################################################
  6513. X#
  6514. X#    Name:     iscreen.icn
  6515. X#
  6516. X#    Title:     Icon screen functions
  6517. X#
  6518. X#    Author:     Richard L. Goerwitz
  6519. X#
  6520. X#    Version: 1.11
  6521. X#
  6522. X############################################################################
  6523. X#
  6524. X#  Copyright (c) 1990, Richard L. Goerwitz, III
  6525. X#
  6526. X#  This software is intended for free and unrestricted distribution.
  6527. X#  I place only two conditions on its use:  1) That you clearly mark
  6528. X#  any additions or changes you make to the source code, and 2) that
  6529. X#  you do not delete this message from it.  In order to protect
  6530. X#  myself from spurious litigation, it must also be stated here that,
  6531. X#  because this is free software, I, Richard Goerwitz, make no claim
  6532. X#  about the applicability or fitness of this software for any
  6533. X#  purpose, and disclaim any responsibility for any damages that
  6534. X#  might be incurred in conjunction with its use.
  6535. X#
  6536. X############################################################################
  6537. X#  
  6538. X#      This file contains some rudimentary screen functions for use with
  6539. X#  itlib.icn (termlib-like routines for Icon).
  6540. X#
  6541. X#      clear()              - clears the screen (tries several methods)
  6542. X#      emphasize()          - initiates emphasized mode
  6543. X#      normal(mode)         - resets to normal mode; if mode is null,
  6544. X#        or "b," normal() assumes you were in emphasize mode,
  6545. X#        otherwise you are assumed to have been in underline mode
  6546. X#      message(s)           - displays message s on 2nd-to-last line
  6547. X#      underline()          - initiates underline mode
  6548. X#      status_line(s,s2,p)  - draws status line s on the 3rd-to-last
  6549. X#        screen line; if s is too short for the terminal, s2 is used;
  6550. X#        if p is nonnull then it either centers, left-, or right-justi-
  6551. X#        fies, depending on the value, "c," "l," or "r."
  6552. X#
  6553. X############################################################################
  6554. X#
  6555. X#  Requires: UNIX
  6556. X#
  6557. X#  Links: itlib.icn (or your OS-specific port of itlib)
  6558. X#
  6559. X#  See also: boldface.icn
  6560. X#
  6561. X############################################################################
  6562. X
  6563. X
  6564. Xprocedure clear()
  6565. X
  6566. X    # Clears the screen.  Tries several methods.
  6567. X
  6568. X    if not iputs(getval("cl"))
  6569. X    then iputs(igoto(getval("cm"),1,1))
  6570. X    if not iputs(getval("cd"))
  6571. X    then {
  6572. X    every i := 1 to getval("li") do {
  6573. X        iputs(igoto(getval("cm"),1,i))
  6574. X        iputs(getval("ce"))
  6575. X    }
  6576. X    iputs(igoto(getval("cm"),1,1))
  6577. X    }
  6578. X    return
  6579. X
  6580. Xend
  6581. X
  6582. X
  6583. X
  6584. Xprocedure emphasize()
  6585. X    
  6586. X    static bold_str, cookie_str
  6587. X    initial {
  6588. X    if bold_str := getval("so")
  6589. X    then cookie_str := repl(getval("bc") | "\b", getval("sg"))
  6590. X    else {
  6591. X        if bold_str := getval("us")
  6592. X        then cookie_str := repl(getval("bc") | "\b", getval("ug"))
  6593. X    }
  6594. X    }        
  6595. X    
  6596. X    iputs(\bold_str)
  6597. X    iputs(\cookie_str)
  6598. X    return
  6599. X
  6600. Xend
  6601. X
  6602. X
  6603. X
  6604. Xprocedure underline()
  6605. X    
  6606. X    static underline_str, cookie_str
  6607. X    initial {
  6608. X    if underline_str := getval("us")
  6609. X    then cookie_str := repl(getval("bc") | "\b", getval("sg"))
  6610. X    }        
  6611. X    
  6612. X    iputs(\underline_str)
  6613. X    iputs(\cookie_str)
  6614. X    return
  6615. X
  6616. Xend
  6617. X
  6618. X
  6619. X
  6620. Xprocedure normal(mode)
  6621. X
  6622. X    static UN_bold_str, bold_cookie_str,
  6623. X    UN_underline_str, underline_cookie_str
  6624. X    initial {
  6625. X
  6626. X    if UN_bold_str := getval("se") then
  6627. X        bold_cookie_str := repl(getval("bc") | "\b", getval("sg"))
  6628. X    else {
  6629. X        UN_bold_str := getval("ue")
  6630. X        bold_cookie_str := repl(getval("bc")|"\b", getval("ug"))
  6631. X    }
  6632. X    if UN_underline_str := getval("ue") then
  6633. X        underline_cookie_str := repl(getval("bc")|"\b", getval("ug"))
  6634. X    }        
  6635. X    
  6636. X    if /mode | (mode == "b") then {
  6637. X    iputs(\UN_bold_str)
  6638. X    iputs(\bold_cookie_str)
  6639. X    return
  6640. X    }
  6641. X
  6642. X    iputs(\UN_underline_str)
  6643. X    iputs(\underline_cookie_str)
  6644. X    return
  6645. X
  6646. Xend
  6647. X
  6648. X
  6649. X
  6650. Xprocedure status_line(s,s2,p)
  6651. X
  6652. X    # Writes a status line on the terminal's third-to-last line
  6653. X    # The only necessary argument is s.  S2 (optional) is used
  6654. X    # for extra narrow screens.  In other words, by specifying
  6655. X    # s2 you give status_line an alternate, shorter status string
  6656. X    # to display, in case the terminal isn't wide enough to sup-
  6657. X    # port s.  If p is nonnull, then the status line is either
  6658. X    # centered (if equal to "c"), left justified ("l"), or right
  6659. X    # justified ("r").
  6660. X
  6661. X    local width
  6662. X
  6663. X    /s := ""
  6664. X    width := getval("co")
  6665. X    if *s > width then {
  6666. X    (*s2 < width, s := \s2) |
  6667. X        er("status_line","Your terminal is too narrow.",4)
  6668. X    }
  6669. X    case \p of {
  6670. X    "c"    : s := center(s,width-1)
  6671. X    "l"    : s := left(s,width-1)
  6672. X    "r"    : s := right(s,width-1)
  6673. X    default: stop("status_line:  Unknown option "||string(p),4)
  6674. X    }
  6675. X
  6676. X    iputs(igoto(getval("cm"), 1, getval("li")-2))
  6677. X    emphasize(); writes(s); iputs(getval("ce"))
  6678. X    normal()
  6679. X    return
  6680. X
  6681. Xend
  6682. X
  6683. X
  6684. X
  6685. Xprocedure message(s)
  6686. X
  6687. X    # Display prompt s on the second-to-last line of the screen.
  6688. X    # I hate to use the last line, due to all the problems with
  6689. X    # automatic scrolling.
  6690. X
  6691. X    /s := ""
  6692. X    normal()
  6693. X    iputs(igoto(getval("cm"), 1, getval("li")-1))
  6694. X    writes(s[1:getval("co")] | s)
  6695. X    iputs(getval("ce"))
  6696. X    return
  6697. X
  6698. Xend
  6699. SHAR_EOF
  6700. # ============= itlibdos.icn ==============
  6701. echo "x - extracting itlibdos.icn (Text)"
  6702. sed 's/^X//' << 'SHAR_EOF' > itlibdos.icn &&
  6703. X########################################################################
  6704. X#    
  6705. X#    Name:    itlibdos.icn
  6706. X#    
  6707. X#    Title:    Icon termlib-type tools (MS-DOS version)
  6708. X#    
  6709. X#    Author:    Richard L. Goerwitz
  6710. X#
  6711. X#    Version: 1.3
  6712. X#
  6713. X########################################################################
  6714. X#
  6715. X#  Copyright (c) 1990, Richard L. Goerwitz, III
  6716. X#
  6717. X#  This software is intended for free and unrestricted distribution.
  6718. X#  I place only two conditions on its use:  1) That you clearly mark
  6719. X#  any additions or changes you make to the source code, and 2) that
  6720. X#  you do not delete this message therefrom.  In order to protect
  6721. X#  myself from spurious litigation, it must also be stated here that,
  6722. X#  because this is free software, I, Richard Goerwitz, make no claim
  6723. X#  about the applicability or fitness of this software for any
  6724. X#  purpose, and expressly disclaim any responsibility for any damages
  6725. X#  that might be incurred in conjunction with its use.
  6726. X#
  6727. X########################################################################
  6728. X#
  6729. X#  The following library represents a series of rough functional
  6730. X#  equivalents to the standard Unix low-level termcap routines.  They
  6731. X#  are not meant as exact termlib clones.  Nor are they enhanced to
  6732. X#  take care of magic cookie terminals, terminals that use \D in their
  6733. X#  termcap entries, or, in short, anything I felt would not affect my
  6734. X#  normal, day-to-day work with ANSI and vt100 terminals.
  6735. X#
  6736. X#  Requires:  An MS-DOS platform & co-expressions.  The MS-DOS version
  6737. X#  is a port of the Unix version.  Software you write for this library
  6738. X#  can be made to run under Unix simply by substituting the Unix ver-
  6739. X#  sion of this library.  See below for additional notes on how to use
  6740. X#  this MS-DOS port.
  6741. X#
  6742. X#  setname(term)
  6743. X#    Use only if you wish to initialize itermlib for a terminal
  6744. X#  other than what your current environment specifies.  "Term" is the
  6745. X#  name of the termcap entry to use.  Normally this initialization is
  6746. X#  done automatically, and need not concern the user.
  6747. X#
  6748. X#  getval(id)
  6749. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  6750. X#  spirit of Icon, all three have been collapsed into one routine.
  6751. X#  Integer valued caps are returned as integers, strings as strings,
  6752. X#  and flags as records (if a flag is set, then type(flag) will return
  6753. X#  "true").  Absence of a given capability is signalled by procedure
  6754. X#  failure.
  6755. X#
  6756. X#  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  6757. X#    Analogous to tgoto.  "Cm" is the cursor movement command for
  6758. X#  the current terminal, as obtained via getval("cm").  Igoto()
  6759. X#  returns a string which, when output via iputs, will cause the
  6760. X#  cursor to move to column "destcol" and line "destline."  Column and
  6761. X#  line are always calculated using a *one* offset.  This is far more
  6762. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  6763. X#  go to the first square on your screen, then include in your program
  6764. X#  "iputs(igoto(getval("cm"),1,1))."
  6765. X#
  6766. X#  iputs(cp,affcnt)
  6767. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  6768. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  6769. X#  count of affected lines.  It is only relevant for terminals which
  6770. X#  specify proportional (starred) delays in their termcap entries.
  6771. X#
  6772. X#  Notes on the MS-DOS version:
  6773. X#    There are two basic reasons for using the I/O routines
  6774. X#  contained in this package.  First, by using a set of generalized
  6775. X#  routines, your code will become much more readable.  Secondly, by
  6776. X#  using a high level interface, you can avoid the cardinal
  6777. X#  programming error of hard coding things like screen length and
  6778. X#  escape codes into your programs.
  6779. X#    To use this collection of programs, you must do two things.
  6780. X#  First, you must add the line "device=ansi.sys" (or the name of some
  6781. X#  other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new
  6782. X#  nansi.sys]) to your config.sys file.  Secondly, you must add two
  6783. X#  lines to your autoexec.bat file:  1) "set TERM=ansi-mono" and 2)
  6784. X#  "set TERMCAP=\location\termcap."  The purpose of setting the TERM
  6785. X#  variable is to tell this program what driver you are using.  If you
  6786. X#  have a color system, use "ansi-color" instead of "ansi-mono," and
  6787. X#  if you are using nansi or zansi instead of vanilla ansi, use one of
  6788. X#  these names instead of the "ansi" (e.g. "zansi-mono").  The purpose
  6789. X#  of setting TERMCAP is to make it possible to determine where the
  6790. X#  termcap file is located.  The termcap file (which should have been
  6791. X#  packed with this library as termcap.dos) is a short database of all
  6792. X#  the escape sequences used by the various terminal drivers.  Set
  6793. X#  TERMCAP so that it reflects the location of this file (which should
  6794. X#  be renamed as termcap, for the sake of consistency with the Unix
  6795. X#  version).  Naturally, you must change "\location\" above to reflect
  6796. X#  the correct path on your system.
  6797. X#    Although I make no pretense here of providing here a complete
  6798. X#  introduction to the format of the termcap database file, it will be
  6799. X#  useful, I think, to explain a few basic facts about how to use this
  6800. X#  program in conjunction with it.  If, say, you want to clear the
  6801. X#  screen, add the line,
  6802. X#
  6803. X#    iputs(getval("cl"))
  6804. X#
  6805. X#  to your program.  The function iputs() outputs screen control
  6806. X#  sequences.  Getval retrieves a specific sequence from the termcap
  6807. X#  file.  The string "cl" is the symbol used in the termcap file to
  6808. X#  mark the code used to clear the screen.  By executing the
  6809. X#  expression "iputs(getval("cl"))," you are 1) looking up the "cl"
  6810. X#  (clear) code in the termcap database entry for your terminal, and
  6811. X#  the 2) outputting that sequence to the screen.
  6812. X#    Some other useful termcap symbols are "ce" (clear to end of
  6813. X#  line), "ho" (go to the top left square on the screen), "so" (begin
  6814. X#  standout mode), and "se" (end standout mode).  To output a
  6815. X#  boldfaced string, str, to the screen, you would write -
  6816. X#
  6817. X#    iputs(getval("so"))
  6818. X#    writes(str)
  6819. X#    iputs(getval("se"))
  6820. X#
  6821. X#  You could write "iputs(getval("so") || str || getval("se")), but
  6822. X#  this would only work for DOS.  Some Unix terminals require padding,
  6823. X#  and iputs() handles them specially.  Normally you should not worry
  6824. X#  about Unix quirks under DOS.  It is in general wise, though, to
  6825. X#  separate out screen control sequences, and output them via iputs().
  6826. X#    It is also heartily to be recommended that MS-DOS programmers
  6827. X#  try not to assume that everyone will be using a 25-line screen.
  6828. X#  Some terminals are 24-line.  Some 43.  Some have variable window
  6829. X#  sizes.  If you want to put a status line on, say, the 2nd-to-last
  6830. X#  line of the screen, then determine what that line is by executing
  6831. X#  "getval("li")."  The termcap database holds not only string-valued
  6832. X#  sequences, but numeric ones as well.  The value of "li" tells you
  6833. X#  how many lines the terminal has (compare "co," which will tell you
  6834. X#  how many columns).  To go to the beginning of the second-to-last
  6835. X#  line on the screen, type in:
  6836. X#
  6837. X#    iputs(igoto(getval("cm"), 1, getval("li")-1))
  6838. X#
  6839. X#  The "cm" capability is a special capability, and needs to be output
  6840. X#  via igoto(cm,x,y), where cm is the sequence telling your computer
  6841. X#  to move the cursor to a specified spot, x is the column, and y is
  6842. X#  the row.  The expression "getval("li")-1" will return the number of
  6843. X#  the second-to-last line on your screen.
  6844. X#
  6845. X##########################################################################
  6846. X#
  6847. X#  Requires: MS-DOS, coexpressions
  6848. X#
  6849. X#  See also: iscreen.icn (a set of companion utilities) 
  6850. X#
  6851. X##########################################################################
  6852. X
  6853. X
  6854. Xglobal tc_table
  6855. Xrecord true()
  6856. X
  6857. X
  6858. Xprocedure check_features()
  6859. X
  6860. X    local in_params, line
  6861. X    # global tty_speed
  6862. X
  6863. X    initial {
  6864. X    find("ms-dos",map(&features)) |
  6865. X        er("check_features","unix system required",1)
  6866. X    find("o-expres",&features) |
  6867. X        er("check_features","co-expressions not implemented - &$#!",1)
  6868. X    }
  6869. X
  6870. X    return "term characteristics reset; features check out"
  6871. X
  6872. Xend
  6873. X
  6874. X
  6875. X
  6876. Xprocedure setname(name)
  6877. X
  6878. X    # Sets current terminal type to "name" and builds a new termcap
  6879. X    # capability database (residing in tc_table).  Fails if unable to
  6880. X    # find a termcap entry for terminal type "name."  If you want it
  6881. X    # to terminate with an error message under these circumstances,
  6882. X    # comment out "| fail" below, and uncomment the er() line.
  6883. X
  6884. X    #tc_table is global
  6885. X    
  6886. X    check_features()
  6887. X
  6888. X    tc_table := maketc_table(getentry(name)) | fail
  6889. X    # er("setname","no termcap entry found for "||name,3)
  6890. X    return "successfully reset for terminal " || name
  6891. X
  6892. Xend
  6893. X
  6894. X
  6895. X
  6896. Xprocedure getname()
  6897. X
  6898. X    # Getname() first checks to be sure we're running under DOS, and,
  6899. X    # if so, tries to figure out what the current terminal type is,
  6900. X    # checking the value of the environment variable TERM, and if this
  6901. X    # is unsuccessful, defaulting to "mono."
  6902. X
  6903. X    local term, tset_output
  6904. X
  6905. X    check_features()
  6906. X
  6907. X    if not (term := getenv("TERM")) then {
  6908. X    tset_output := open("/bin/tset -","pr") |
  6909. X        er("getname","can't find tset command",1)
  6910. X    term := !tset_output
  6911. X    close(tset_output)
  6912. X    }
  6913. X    return \term |
  6914. X    er("getname","can't seem to determine your terminal type",1)
  6915. X
  6916. Xend
  6917. X
  6918. X
  6919. X
  6920. Xprocedure er(func,msg,errnum)
  6921. X
  6922. X    # short error processing utility
  6923. X    write(&errout,func,":  ",msg)
  6924. X    exit(errnum)
  6925. X
  6926. Xend
  6927. X
  6928. X
  6929. X
  6930. Xprocedure getentry(name)
  6931. X
  6932. X    # "Name" designates the current terminal type.  Getentry() scans
  6933. X    # the current environment for the variable TERMCAP.  If the
  6934. X    # TERMCAP string represents a termcap entry for a terminal of type
  6935. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  6936. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  6937. X    # getentry() will scan that file for an entry corresponding to
  6938. X    # "name."  If the TERMCAP string does not designate a filename,
  6939. X    # getentry() will look through ./termcap for the correct entry.
  6940. X    # Whatever the input file, if an entry for terminal "name" is
  6941. X    # found, getentry() returns that entry.  Otherwise, getentry()
  6942. X    # fails.
  6943. X
  6944. X    local termcap_string, f, getline, line, nm, ent1, ent2
  6945. X
  6946. X    termcap_string := getenv("TERMCAP")
  6947. X
  6948. X    if \termcap_string ? (not match("\\"), pos(0) | tab(find("|")+1), =name)
  6949. X    then return termcap_string
  6950. X    else {
  6951. X
  6952. X    # The logic here probably isn't clear.  The idea is to try to use
  6953. X    # the termcap environment variable successively as 1) a termcap en-
  6954. X    # try and then 2) as a termcap file.  If neither works, 3) go to
  6955. X    # the ./termcap file.  The else clause here does 2 and, if ne-
  6956. X    # cessary, 3.  The "\termcap_string ? (not match..." expression
  6957. X    # handles 1.
  6958. X
  6959. X    if find("\\",\termcap_string)
  6960. X    then f := open(termcap_string)
  6961. X    /f := open("termcap") |
  6962. X        er("getentry","I can't access your termcap file",1)
  6963. X
  6964. X    getline := create read_file(f)
  6965. X    
  6966. X    while line := @getline do {
  6967. X        if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  6968. X        entry := ""
  6969. X        while (\line | @getline) ? {
  6970. X            if entry ||:= 1(tab(find(":")+1), pos(0))
  6971. X            then {
  6972. X            close(f)
  6973. X            # if entry ends in tc= then add in the named tc entry
  6974. X            entry ?:= tab(find("tc=")) ||
  6975. X                # recursively fetch the new termcap entry
  6976. X                (move(3), getentry(tab(find(":"))) ?
  6977. X                    # remove the name field from the new entry
  6978. X                     (tab(find(":")+1), tab(0)))
  6979. X            return entry
  6980. X            }
  6981. X            else {
  6982. X            \line := &null # must precede the next line
  6983. X            entry ||:= tab(-2)
  6984. X            }
  6985. X        }
  6986. X        }
  6987. X    }
  6988. X    }
  6989. X
  6990. X    close(f)
  6991. X    er("getentry","can't find and/or process your termcap entry",3)
  6992. Xend
  6993. X
  6994. X
  6995. X
  6996. Xprocedure read_file(f)
  6997. X
  6998. X    # Suspends all non #-initial lines in the file f.
  6999. X    # Removes leading tabs and spaces from lines before suspending
  7000. X    # them.
  7001. X
  7002. X    local line
  7003. X
  7004. X    \f | er("read_tcap_file","no valid termcap file found",3)
  7005. X    while line := read(f) do {
  7006. X    match("#",line) & next
  7007. X    line ?:= (tab(many('\t ')) | &null, tab(0))
  7008. X    suspend line
  7009. X    }
  7010. X
  7011. X    fail
  7012. X
  7013. Xend
  7014. X
  7015. X
  7016. X
  7017. Xprocedure maketc_table(entry)
  7018. X
  7019. X    # Maketc_table(s) (where s is a valid termcap entry for some
  7020. X    # terminal-type): Returns a table in which the keys are termcap
  7021. X    # capability designators, and the values are the entries in
  7022. X    # "entry" for those designators.
  7023. X
  7024. X    local k, v
  7025. X
  7026. X    /entry & er("maketc_table","no entry given",8)
  7027. X    if entry[-1] ~== ":" then entry ||:= ":"
  7028. X    
  7029. X    tc_table := table()
  7030. X
  7031. X    entry ? {
  7032. X
  7033. X    tab(find(":")+1)    # tab past initial (name) field
  7034. X
  7035. X    while tab((find(":")+1) \ 1) ? {
  7036. X
  7037. SHAR_EOF
  7038. echo "End of  part 1"
  7039. echo "File itlibdos.icn is continued in part 2"
  7040. echo "2" > shar3_seq_.tmp
  7041. exit 0
  7042.  
  7043. From @mirsa.inria.fr:ol@cerisi.cerisi.Fr  Thu Sep  6 05:21:14 1990
  7044. Resent-From: @mirsa.inria.fr:ol@cerisi.cerisi.Fr
  7045. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7046.     id AA20635; Thu, 6 Sep 90 05:21:14 -0700
  7047. Received: from mirsa.inria.fr by Arizona.edu; Thu, 6 Sep 90 05:20 MST
  7048. Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP (5.61+++/IDA-1.2.8)
  7049.  id AB08055; Thu, 6 Sep 90 14:21:25 +0200
  7050. Resent-Date: Thu, 6 Sep 90 05:21 MST
  7051. Date: Thu, 6 Sep 90 14:18:18 -0100
  7052. From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
  7053. Subject: true Icon compiler
  7054. Resent-To: icon-group@cs.arizona.edu
  7055. To: icon-group@arizona.edu
  7056. Resent-Message-Id: <3B3F7FE350AB008050@Arizona.edu>
  7057. Message-Id: <9009061221.AB08055@mirsa.inria.fr>
  7058. Posted-Date: Thu, 6 Sep 90 14:18:18 -0100
  7059. X-Envelope-To: icon-group@CS.Arizona.EDU
  7060. X-Vms-To: icon-group@Arizona.EDU
  7061.  
  7062. Recently somebody posted a message about a project on a true Icon
  7063. compiler, i.e. a compiler that would infer variable types and could
  7064. generate really efficient machine code in most simple cases.
  7065. Unfortunately, I can't retrieve the message in my (huge) archives. Could
  7066. anybody provide me some further information about this project?
  7067.  
  7068. Thanks in advance.
  7069.  
  7070.  
  7071.                 Olivier Lecarme
  7072.  
  7073. From icon-group-request@arizona.edu  Thu Sep  6 06:14:38 1990
  7074. Resent-From: icon-group-request@arizona.edu
  7075. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7076.     id AA21665; Thu, 6 Sep 90 06:14:38 -0700
  7077. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 6 Sep 90 06:14 MST
  7078. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02299; Thu, 6 Sep 90 06:10:28
  7079.  -0700
  7080. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7081.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7082.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7083. Resent-Date: Thu, 6 Sep 90 06:14 MST
  7084. Date: 6 Sep 90 00:07:45 GMT
  7085. From: usc!isi.edu!ata.isi.edu!paulp@apple.com
  7086. Subject: icon data types on disk
  7087. Sender: icon-group-request@arizona.edu
  7088. Resent-To: icon-group@cs.arizona.edu
  7089. To: icon-group@arizona.edu
  7090. Resent-Message-Id: <3B38113F826B0076B2@Arizona.edu>
  7091. Message-Id: <14847@venera.isi.edu>
  7092. Organization: USC-Information Sciences Institute
  7093. X-Envelope-To: icon-group@CS.Arizona.EDU
  7094. X-Vms-To: icon-group@Arizona.EDU
  7095.  
  7096.  
  7097.     I'm looking for some routines to write/read icon data types
  7098.     on disk.  The routines would allow a list or a table (or any
  7099.     icon data type for that matter) to be written out to a disk
  7100.     file and later read back into an icon variable of the same 
  7101.     type as the original.  I suppose each icon variable in the
  7102.     file would need to be tagged with its type, and a file would
  7103.     look like a sequence of icon variables of arbitrary types.
  7104.     Has anyone written something like this?
  7105.  
  7106.     Thanks in advance,
  7107.  
  7108.     Paul Postel
  7109.  
  7110. From kwalker  Thu Sep  6 09:42:02 1990
  7111. Resent-From: "Kenneth Walker" <kwalker>
  7112. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7113.     id AA00924; Thu, 6 Sep 90 09:42:02 -0700
  7114. Received: from megaron (megaron.cs.Arizona.EDU) by Arizona.edu; Thu, 6 Sep 90
  7115.  09:40 MST
  7116. Received: from gacham.cs.arizona.edu by megaron (5.61/15) via SMTP id AA00802;
  7117.  Thu, 6 Sep 90 09:40:01 -0700
  7118. Received: by gacham.cs.arizona.edu; Thu, 6 Sep 90 09:39:57 MST
  7119. Resent-Date: Thu, 6 Sep 90 09:41 MST
  7120. Date: Thu, 6 Sep 90 09:39:57 MST
  7121. From: Kenneth Walker <kwalker@cs.arizona.edu>
  7122. Subject: RE:  true Icon compiler
  7123. Resent-To: icon-group@cs.arizona.edu
  7124. To: icon-group@arizona.edu, ol@cerisi.cerisi.Fr
  7125. Resent-Message-Id: <3B1B265CF5AB008118@Arizona.edu>
  7126. Message-Id: <9009061639.AA12725@gacham.cs.arizona.edu>
  7127. In-Reply-To: <9009061221.AB08055@mirsa.inria.fr>
  7128. X-Envelope-To: icon-group@CS.Arizona.EDU
  7129. X-Vms-To: icon-group@Arizona.EDU, ol@cerisi.cerisi.Fr
  7130.  
  7131. > Date: Thu, 6 Sep 90 14:18:18 -0100
  7132. > From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
  7133. > Recently somebody posted a message about a project on a true Icon
  7134. > compiler, i.e. a compiler that would infer variable types and could
  7135. > generate really efficient machine code in most simple cases.
  7136. > Unfortunately, I can't retrieve the message in my (huge) archives. Could
  7137. > anybody provide me some further information about this project?
  7138.  
  7139. I wrote the compiler as part of my PhD research. It actually generates
  7140. C code and uses a C compiler as a back end rather than directly producing
  7141. machine code (the basic model for compiling Icon into C was developed
  7142. by Janalee O'Bagy as part of her PhD research here a couple years ago). It
  7143. does infer the types of variables and produces code that runs faster than
  7144. the interpreter. We have not done extensive timings yet, but the benchmark
  7145. suite programs runs 1.5 to 3 times faster compiled than interpreted. It is
  7146. possible to construct artifical examples that do much better than that.
  7147. For instance
  7148.  
  7149.    procedure main()
  7150.       local i
  7151.       every i := 1 to 1000000
  7152.    end
  7153.  
  7154. runs 37 times faster compiled than interpreted (the interpreter does at least
  7155. a couple C function calls each time around the loop - the compiled code does
  7156. none). However, I'm more interested in what happens with real programs.
  7157.  
  7158. We hope to do a Unix distribution of it at some point. However, there
  7159. is still work to do: documention, cleaning up the code, and doing a few
  7160. ports to local machines. I am currently busy writing a dissertation and
  7161. won't even start preparing the compiler for distribution this year.
  7162.  
  7163.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  7164.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  7165.  
  7166. From tenaglia@mis.mcw.edu  Thu Sep  6 20:54:03 1990
  7167. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  7168.     id AA04936; Thu, 6 Sep 90 20:54:03 -0700
  7169. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  7170.     id AA12071; Thu, 6 Sep 90 21:16:37 EDT
  7171. Received: by uwm.edu; id AA23257; Tue, 4 Sep 90 10:35:41 -0500
  7172. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7173.           Tue,  4 Sep 90 09:40:30 CDT
  7174. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7175.           Tue,  4 Sep 90 09:15:30 CDT
  7176. Date: Tue,  4 Sep 90 09:15:30 CDT
  7177. Message-Id: <0093C34EEBAB3D80.20201524@mis.mcw.edu>
  7178. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  7179. Subject: Otherwise
  7180. To: icon-group@cs.arizona.edu
  7181.  
  7182.  
  7183. Concerning icon language constructs, I was wondering if there is any call
  7184. for an 'otherwise' construct. This would be used in a conditional. This idea
  7185. is based in part on tri-state logic that is popular in AI products.
  7186.  
  7187.         if (num/div) > lim
  7188.           then write("Is true.")
  7189.           else write("Is false.")
  7190.           otherwise write("Is unknown or &null or div by 0")
  7191.  
  7192. This might be a cleaner way of handling things than messing with the error
  7193. count, and could be very handy for development and debugging. Or maybe there's
  7194. a more Iconish way of handling it. Any ideas?
  7195.  
  7196. Chris Tenaglia (System Manager) |  "Eat a good book lately?"
  7197. Medical College of Wisconsin    |   Q to Worf      STTNG
  7198. 8701 W. Watertown Plank Rd.     |        _
  7199. Milwaukee, WI 53226             |     =======  -------
  7200. (414)257-8765                   |          \===/===
  7201. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  7202.  
  7203.  
  7204. From tenaglia@mis.mcw.edu  Fri Sep  7 04:10:46 1990
  7205. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  7206.     id AA12336; Fri, 7 Sep 90 04:10:46 -0700
  7207. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  7208.     id AA22113; Fri, 7 Sep 90 00:43:23 EDT
  7209. Received: by uwm.edu; id AA22029; Wed, 5 Sep 90 10:35:39 -0500
  7210. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7211.           Wed,  5 Sep 90 10:05:13 CDT
  7212. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7213.           Wed,  5 Sep 90 09:28:12 CDT
  7214. Date: Wed,  5 Sep 90 09:28:12 CDT
  7215. Message-Id: <0093C419DC850CC0.204000DB@mis.mcw.edu>
  7216. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  7217. Subject: Soliciting Knowledge & Opinions
  7218. To: icon-group@cs.arizona.edu
  7219.  
  7220.  
  7221. I'm interested in finding out what is possible with ProIcon on the MAC.
  7222. I have the serial port of the MAC set up for MODEM or HARDWIRE connection
  7223. to a VMS host. I'd like to build a MAC like front end for certain boring
  7224. data entry screen. Does ProIcon give me easy access to the comm port?
  7225.  
  7226. Thanks,
  7227.  
  7228. Chris Tenaglia (System Manager)
  7229. Medical College of Wisconsin
  7230. 8701 W. Watertown Plank Rd.
  7231. Milwaukee, WI 53226
  7232. (414)257-8765
  7233. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  7234.  
  7235.  
  7236. From goer@midway.uchicago.edu  Mon Sep 10 19:18:45 1990
  7237. Resent-From: goer@midway.uchicago.edu
  7238. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7239.     id AA08551; Mon, 10 Sep 90 19:18:45 -0700
  7240. Received: from midway.uchicago.edu by Arizona.edu; Mon, 10 Sep 90 19:18 MST
  7241. Received: from quads.uchicago.edu  (quads.uchicago.edu) by midway.uchicago.edu
  7242.  Mon, 10 Sep 90 21:18:17 CDT
  7243. Resent-Date: Mon, 10 Sep 90 19:18 MST
  7244. Date: Mon, 10 Sep 90 21:18:17 CDT
  7245. From: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
  7246. Subject: snake; getch
  7247. Resent-To: icon-group@cs.arizona.edu
  7248. To: icon-group@arizona.edu
  7249. Resent-Message-Id: <37A5D65F020B00A2AB@Arizona.edu>
  7250. Message-Id: <9009110218.AA03571@midway.uchicago.edu>
  7251. X-Envelope-To: icon-group@CS.Arizona.EDU
  7252. X-Vms-To: icon-group@Arizona.EDU
  7253.  
  7254. I don't want to post it right now, but if anyone wants a Unix implemen-
  7255. tation of the getch() and getche() functions, please let me know.  I'll
  7256. pass it on.
  7257.  
  7258. Incidentally, I had a couple of requests for the snake "game" a while
  7259. back that I couldn't reply to.  For instance, I couldn't seem to get
  7260. a reply to a address at ...@damogran.pa.dec.com.  Sorry about this.  I
  7261. don't want to post the game to the group, though.  Most of it would
  7262. just be a repost of the Icon termlib-like functions I posted a while
  7263. back.
  7264.  
  7265. -Richard (goer@sophist.uchicago.edu)
  7266.  
  7267. From esquire!info8!yost@cmcl2.NYU.EDU  Tue Sep 11 07:35:22 1990
  7268. Resent-From: esquire!info8!yost@cmcl2.NYU.EDU
  7269. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7270.     id AA01642; Tue, 11 Sep 90 07:35:22 -0700
  7271. Received: from cmcl2.NYU.EDU (NYU.EDU) by Arizona.edu; Tue, 11 Sep 90 07:34 MST
  7272. Received: by cmcl2.NYU.EDU (5.61/1.34) id AA25806; Tue, 11 Sep 90 10:35:12 -0400
  7273. Received: from info8 by ESQUIRE.DPW. id aa17499; 11 Sep 90 9:55 EDT
  7274. Received: from localhost by info8. (4.0/SMI-4.0) id AA05688; Tue, 11 Sep 90
  7275.  09:58:48 EDT
  7276. Resent-Date: Tue, 11 Sep 90 07:35 MST
  7277. Date: Tue, 11 Sep 90 09:58:45 -0400
  7278. From: yost@DPW.COM
  7279. Subject: RE: snake; getch
  7280. Sender: yost@info8.NYU.EDU
  7281. Resent-To: icon-group@cs.arizona.edu
  7282. To: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
  7283. Cc: icon-group@arizona.edu, yost@cmcl2.NYU.EDU
  7284. Reply-To: yost@DPW.COM
  7285. Resent-Message-Id: <373EF0CA2F0B009A25@Arizona.edu>
  7286. Message-Id: <9009111358.AA05688@info8.>
  7287. In-Reply-To: Your message of Mon, 10 Sep 90 21:18:17 CDT.
  7288.  <9009110218.AA03571@midway.uchicago.edu>
  7289. Phone: +1 212-266-0796 (Voice Direct Line)
  7290. Fax: +1 212-266-0790
  7291. Organization: Davis Polk & Wardwell 1 Chase Manhattan Plaza New York, NY  10005
  7292. X-Envelope-To: icon-group@CS.Arizona.EDU
  7293. X-Vms-To: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
  7294. X-Vms-Cc: icon-group@Arizona.EDU, yost@cmcl2.NYU.EDU
  7295.  
  7296. > if anyone wants a Unix implementation of the getch() and getche() functions,
  7297. > please let me know.
  7298.  
  7299. I was disappointed that they weren't there when I was
  7300. writing a unix Icon program recently.  You should put
  7301. them up for adoption in the distribution.
  7302.  
  7303.  --dave
  7304.    yost@dpw.com or uunet!esquire!yost
  7305.    Please ignore the From or Reply-To fields above, if different.
  7306.  
  7307. From R.J.Hare@edinburgh.ac.uk  Thu Sep 13 12:29:24 1990
  7308. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7309.     id AA18001; Thu, 13 Sep 90 12:29:24 -0700
  7310. Received: from UKACRL.BITNET by Arizona.edu; Thu, 13 Sep 90 12:29 MST
  7311. Received: from RL.IB by UKACRL.BITNET (Mailer R2.03B) with BSMTP id 3669; Thu,
  7312.  13 Sep 90 11:37:46 BST
  7313. Date: 13 Sep 90  10:28:28 bst
  7314. From: R.J.Hare@edinburgh.ac.uk
  7315. Subject: Text-processors
  7316. To: icon-group@cs.arizona.edu
  7317. Message-Id: <13 Sep 90  10:28:28 bst  340970@EMAS-A>
  7318. Via:        UK.AC.ED.EMAS-A; 13 SEP 90 10:27:32 BST
  7319. X-Envelope-To: icon-group@cs.arizona.edu
  7320.  
  7321. Some time ago, I saw a request for an Icon version of TeX, either on this bb
  7322. or in the newsletter. I don't remember any reply, but I'd now like to pose the
  7323. following supplementary questions:
  7324.  
  7325. 1) has anyone implemented Brian reid's SCRIBE program (or a sub-set) in Icon?
  7326.  
  7327. 2) has anyone implemented any text-processor of any kind using Icon?
  7328.  
  7329. 3) Are these programs available?
  7330.  
  7331. Thanks.
  7332.  
  7333. Roger Hare.
  7334.  
  7335. From @mirsa.inria.fr:ol@cerisi.cerisi.Fr  Thu Sep 13 23:55:21 1990
  7336. Received: from mirsa.inria.fr by megaron (5.61/15) via SMTP
  7337.     id AA16440; Thu, 13 Sep 90 23:55:21 -0700
  7338. Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP
  7339.     (5.61+++/IDA-1.2.8) id AA12236; Fri, 14 Sep 90 08:57:31 +0200
  7340. Message-Id: <9009140657.AA12236@mirsa.inria.fr>
  7341. Date: Fri, 14 Sep 90 08:53:58 -0100
  7342. Posted-Date: Fri, 14 Sep 90 08:53:58 -0100
  7343. From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
  7344. To: R.J.Hare@edinburgh.ac.uk
  7345. Cc: icon-group@cs.arizona.edu
  7346. In-Reply-To: R.J.Hare@edinburgh.ac.uk's message of 13 Sep 90  10:28:28 bst <13 Sep 90  10:28:28 bst  340970@EMAS-A>
  7347. Subject: Text-processors
  7348.  
  7349. I implemented a text-processor in Icon.
  7350.  
  7351. From something extremely simple, capable of only some "natural"
  7352. pretty-printing, it grown to multiple features including indexes,
  7353. several tables of contents, running headings, floating figures, macros
  7354. and so on. It has some unusual characteristics, for example hyphenating
  7355. algorithms for both English and French, simple handling of French
  7356. diacritics, and "natural" heuristics for finding good page breaks.
  7357.  
  7358. But it suffers form severe weaknesses presently: 
  7359.  
  7360. 1) it was designed with an Epson LQ printer in mind, and turning it to
  7361. generate dvi or Postscript instead would be a major effort (although it
  7362. would be easy for another line printer);
  7363.  
  7364. 2) its growth was not planned in advance, and the last features added
  7365. use holes in the coding design; 
  7366.  
  7367. 3) programming it was done in the same manner, and a complete rewriting
  7368. would be neeeded for improving performances;
  7369.  
  7370. 4) its documentation is written in French!
  7371.  
  7372. It could be made available, along with its documentation, in a rather
  7373. short time, but only on an "as-is" basis, of course. It presently
  7374. amounts to about 2500 lines of moderately commented Icon code.
  7375.  
  7376.  
  7377.                 Olivier Lecarme
  7378.  
  7379. From tenaglia@mis.mcw.edu  Fri Sep 14 07:58:22 1990
  7380. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  7381.     id AA02582; Fri, 14 Sep 90 07:58:22 -0700
  7382. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  7383.     id AA21045; Fri, 14 Sep 90 10:45:36 EDT
  7384. Received: by uwm.edu; id AA01696; Fri, 14 Sep 90 09:38:59 -0500
  7385. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7386.           Fri, 14 Sep 90 09:06:50 CDT
  7387. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7388.           Fri, 14 Sep 90 09:07:45 CDT
  7389. Date: Fri, 14 Sep 90 09:07:45 CDT
  7390. Message-Id: <0093CB297E710460.202015C5@mis.mcw.edu>
  7391. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  7392. Subject: Text Processing
  7393. To: icon-group@cs.arizona.edu
  7394.  
  7395.  
  7396. We're running ICON 8 on VAX/VMS 5.2. VMS has RUNOFF for generating
  7397. documentation, and it has the same general look and feel of unix nroff.
  7398. It comes free with VMS as does EVE/TPU.
  7399.  
  7400. DECs EVE/TPU is another tool, which is the Extensible Vax Editor,
  7401. and Text Processing Utility. It's a programmable editor. The TPU programming
  7402. language has many Icon ideas built into it, such as pattern matching,
  7403. csets, alternation. The code even has a vaguely iconish appearance. However,
  7404. it doesn't have goal oriented processing, generators, and the data types
  7405. are very strict. Since it's an editor, the data types are editor oriented
  7406. such as buffer, range, process, window, line, pattern. There are also hundreds
  7407. of built in functions and global system variables and keywords.
  7408.  
  7409. I have a highly customized version of the editor. It does a lot of WYSIWYG
  7410. wordprocessor tricks. I have written Icon utilities to do pagination, table
  7411. of contents, and indeces on documentation I've written. This allows my
  7412. master doc files to be much more human readible than if I coded them in
  7413. RUNOFF. For table of contents and indexing I've had to use a little sleight
  7414. of hand to have the items I want retrieved match a certain pattern, yet look
  7415. unobtrusive.
  7416.  
  7417. It's not terribly fancy or postscript, but it's cheap and effective given
  7418. our hardware.
  7419.  
  7420. Chris Tenaglia (System Manager)
  7421. Medical College of Wisconsin
  7422. 8701 W. Watertown Plank Rd.
  7423. Milwaukee, WI 53226
  7424. (414)257-8765
  7425. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  7426.  
  7427.  
  7428. From tenaglia@mis.mcw.edu  Sat Sep 15 16:51:26 1990
  7429. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  7430.     id AA15432; Sat, 15 Sep 90 16:51:26 -0700
  7431. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  7432.     id AA28771; Sat, 15 Sep 90 19:23:05 EDT
  7433. Received: by uwm.edu; id AA01766; Sat, 15 Sep 90 09:31:18 -0500
  7434. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7435.           Sat, 15 Sep 90 09:28:52 CDT
  7436. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  7437.           Sat, 15 Sep 90 08:48:48 CDT
  7438. Date: Sat, 15 Sep 90 08:48:48 CDT
  7439. Message-Id: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
  7440. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  7441. Subject: UUXXCODE
  7442. To: icon-group@cs.arizona.edu
  7443.  
  7444.  
  7445. I have some files that I'd like to UUENCODE or UUDECODE. Being on a VMS
  7446. system without a C compiler, having the sources still doesn't help. I've
  7447. attempted a port to Icon of UUENCODE and UUDECODE. They are close, but not
  7448. quite right. Would someone care to look them over and offer suggestions or
  7449. corrections? Thanx.
  7450.  
  7451. Chris Tenaglia (System Manager)         about 160 lines follow
  7452. Medical College of Wisconsin
  7453. 8701 W. Watertown Plank Rd.
  7454. Milwaukee, WI 53226
  7455. (414)257-8765
  7456. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  7457.  
  7458. ------------------- uuencode.icn ---------------------------
  7459. ##################################################################
  7460. #                                                                #
  7461. # UUENCODE.ICN           09/14/90          BY TENAGLIA           #
  7462. #                                                                #
  7463. # UUENCODE BINARY FILES FOR EMAIL TRANSFER                       #
  7464. #                                                                #
  7465. ##################################################################
  7466. procedure main(param) 
  7467.  
  7468.   source := param[1]        | input("_Source:")
  7469.   target := param[2]        | input("_Target:")
  7470.   (in  := open(source))     | stop("Can't open ",source)
  7471.   (out := open(target,"w")) | stop("Can't open ",target)
  7472.  
  7473.   write("\fUUENCODE FROM ",source," TO ",target)
  7474.   write(out,"begin 0600 ",source)
  7475.   while line := reads(in,45) do
  7476.     {
  7477.     writes(*line,", ")
  7478.     writes(out,char(*line+32))
  7479.     every i := 1 to *line by 3 do output(out,line[i+:3])
  7480.     write(out,"")
  7481.     }
  7482.   write(out,"end")
  7483.   close(in) ; close(out)
  7484.   end
  7485.  
  7486. #
  7487. # THIS PROCEDURE TAKES AN OUTPUT FILE PARAMETER AND A 3 BYTE STRING
  7488. # OF BINARY DATA. IT WRITES OUT 4 BYTES OF PRINTABLE/MAILABLE ASCII
  7489. #
  7490. procedure output(fo,str)
  7491.   c1 := ord(str[1])*4
  7492.   c2 := ior( iand(ord(str[1])/16,8r060) , iand(ord(str[2])*16,8r017) )
  7493.   c3 := ior( iand(ord(str[2])/4, 8r074) , iand(ord(str[3])*64,8r003) )
  7494.   c4 := iand(ord(str[3]),8r077)
  7495.   writes(fo,char(enc(c1)),
  7496.             char(enc(c2)),
  7497.             char(enc(c3)),
  7498.             char(enc(c4)))
  7499.   end
  7500.  
  7501. #
  7502. # ENCRYPTION ASCIIZER ROUTINE
  7503. #
  7504. procedure enc(n)
  7505.   return iand(n,8r0077)+32
  7506.   end
  7507.  
  7508. #
  7509. # PROMPT AND TAKE AN INPUT
  7510. #
  7511. procedure input(prompt)       
  7512.   writes(prompt)
  7513.   return read()
  7514.   end
  7515. ----------------------- uudecode.icn ------------------------------
  7516. ##################################################################
  7517. #                                                                #
  7518. # UUDECODE.ICN           09/14/90          BY TENAGLIA           #
  7519. #                                                                #
  7520. # UUDECODE BINARY FILES FOR EMAIL TRANSFER                       #
  7521. #                                                                #
  7522. ##################################################################
  7523. procedure main(param)
  7524.  
  7525.   source := param[1]          | input("_Source:")
  7526.   target := param[2]          | input("_Target:")
  7527.   (in    := open(source))     | stop("Can't open ",source)
  7528.   (out   := open(target,"w")) | stop("Can't open ",target)
  7529.  
  7530.   write("\fUUDECODE FROM ",source," TO ",target)
  7531.   until match("begin",(line := read(in)))
  7532.   write("Found ",parse(line,' ')[3])
  7533.   while line := read(in) do
  7534.     {
  7535.     writes(*line,", ")
  7536.     p     := 0
  7537.     bytes := ord(line[1]) - 32
  7538.     if bytes = 64 then bytes := 0
  7539.     if (bytes=0) | match("end",line) then break
  7540.     count := integer(real(bytes)/3.0 + 0.9) * 4
  7541.     buf   := ""
  7542.     every i := 2 to count by 4 do
  7543.       {
  7544.       x1 := ord(line[i])   - 32
  7545.       if x1 = 64 then x1 := 0
  7546.       x2 := ord(line[i+1]) - 32
  7547.       if x2 = 64 then x2 := 0
  7548.       x3 := ord(line[i+2]) - 32
  7549.       if x3 = 64 then x3 := 0
  7550.       x4 := ord(line[i+3]) - 32
  7551.       if x4 = 64 then x4 := 0
  7552.       if p < bytes then
  7553.         {
  7554.         p +:= 1
  7555.         buf ||:= char(x2 / 16 + x1 * 4)
  7556.         }
  7557.       if p < bytes then
  7558.         {
  7559.         p +:= 1
  7560.         buf ||:= char(x3 / 4 + (x2 % 16) * 16)
  7561.         }
  7562.       if p < bytes then
  7563.         {
  7564.         p +:= 1
  7565.         buf ||:= char(x4 + (x3 % 4) * 64)
  7566.         }
  7567.       }
  7568.     writes(out,buf)
  7569.     writes("(",*buf,"), ")
  7570.     }
  7571.   close(in) ; close(out)
  7572.   end
  7573.  
  7574. #
  7575. # PARSE A STRING WITH RESPECT TO A DELIMITER CSET
  7576. #
  7577. procedure parse(line,delims)
  7578.   static chars
  7579.   chars  := &cset -- delims
  7580.   tokens := []
  7581.   line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
  7582.   return tokens
  7583.   end
  7584.  
  7585. #
  7586. # THIS PROCEDURE TAKES AN OUTPUT FILE PARAMETER AND A 3 BYTE STRING
  7587. # OF BINARY DATA. IT WRITES OUT 4 BYTES OF PRINTABLE/MAILABLE ASCII
  7588. #
  7589. procedure output(fo,str)
  7590.   c1 := ord(str[1])*4
  7591.   c2 := ior( iand(ord(str[1])/16,8r060) , iand(ord(str[2])*16,8r017) )
  7592.   c3 := ior( iand(ord(str[2])/4, 8r074) , iand(ord(str[3])*64,8r003) )
  7593.   c4 := iand(ord(str[3]),8r077)
  7594.   writes(fo,char(enc(c1)),
  7595.             char(enc(c2)),
  7596.             char(enc(c3)),
  7597.             char(enc(c4)))
  7598.   end
  7599.  
  7600. #
  7601. # ENCRYPTION ASCIIZER ROUTINE
  7602. #
  7603. procedure enc(n)
  7604.   return iand(n,8r0077)+32
  7605.   end
  7606.  
  7607. #
  7608. # PROMPT AND TAKE AN INPUT
  7609. #
  7610. procedure input(prompt)
  7611.   writes(prompt)
  7612.   return read()
  7613.   end
  7614.  
  7615.  
  7616. From icon-group-request@arizona.edu  Tue Sep 18 10:58:43 1990
  7617. Resent-From: icon-group-request@arizona.edu
  7618. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7619.     id AA07385; Tue, 18 Sep 90 10:58:43 -0700
  7620. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 18 Sep 90 10:58 MST
  7621. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA01144; Tue, 18 Sep 90
  7622.  10:46:55 -0700
  7623. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7624.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7625.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7626. Resent-Date: Tue, 18 Sep 90 10:58 MST
  7627. Date: 18 Sep 90 16:13:58 GMT
  7628. From: esquire!yost@nyu.edu
  7629. Subject: RE: UUXXCODE
  7630. Sender: icon-group-request@arizona.edu
  7631. Resent-To: icon-group@cs.arizona.edu
  7632. To: icon-group@arizona.edu
  7633. Resent-Message-Id: <31A25DEB912B00C636@Arizona.edu>
  7634. Message-Id: <2665@esquire.dpw.com>
  7635. Organization: Davis Polk & Wardwell
  7636. X-Envelope-To: icon-group@CS.Arizona.EDU
  7637. X-Vms-To: icon-group@Arizona.EDU
  7638. References: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
  7639.  
  7640. In article <0093CBF0039A4D60.20400E83@mis.mcw.edu> tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
  7641. >
  7642. >I've attempted a port to Icon of UUENCODE and UUDECODE.
  7643.  
  7644. Now there's a couple of programs I bet are really slow in Icon.
  7645. I'd love to see how fast they run with the Icon compiler,
  7646. compared to the interpreter and compared to the original
  7647. C version.
  7648.  
  7649. If the compiler can really do a good job on this sort of repetitive
  7650. low-level stuff that kills Icon performance, it would be the dawning
  7651. of a new day!  Imagine: we could use Icon instead of C for everything!
  7652.  
  7653. Ken, can we see a benchmark on this?
  7654.  
  7655.  --dave yost
  7656.    yost@dpw.com or uunet!esquire!yost
  7657.    Please don't use other mangled forms you may see
  7658.    in the From or Reply-To fields above.
  7659.  
  7660. From cargo@cherry.cray.com  Tue Sep 18 11:11:21 1990
  7661. Received: from timbuk.CRAY.COM by megaron (5.61/15) via SMTP
  7662.     id AA08371; Tue, 18 Sep 90 11:11:21 -0700
  7663. Received: from cherry04.cray.com by timbuk.CRAY.COM (4.1/SMI4.0 CRAY1.1)
  7664.     id AA11239; Tue, 18 Sep 90 13:11:16 CDT
  7665. Received: by cherry04.cray.com
  7666.     id AA15953; 4.1/CRI-3.21; Tue, 18 Sep 90 13:11:11 CDT
  7667. Date: Tue, 18 Sep 90 13:11:11 CDT
  7668. From: cargo@cherry.cray.com (David S. Cargo)
  7669. Message-Id: <9009181811.AA15953@cherry04.cray.com>
  7670. To: icon-group@cs.arizona.edu
  7671. Subject: ProIcon review
  7672.  
  7673. I was in my company library over lunch and happened to see that
  7674. the September issue of Computer Language had a review of ProIcon 1.0
  7675. in it (page 102).  The reviewer was not pleased with ProIcon's help
  7676. system nor with some of the error messages, but otherwise seemed
  7677. to look favorably on ProIcon.
  7678.  
  7679. David S. Cargo (cargo@cray.com)
  7680.  
  7681.  
  7682. From @mirsa.inria.fr:ol@taloa.unice.fr  Tue Sep 18 12:27:30 1990
  7683. Received: from mirsa.inria.fr by megaron (5.61/15) via SMTP
  7684.     id AA12050; Tue, 18 Sep 90 12:27:30 -0700
  7685. Received: from taloa.unice.fr by mirsa.inria.fr with SMTP
  7686.     (5.61+++/IDA-1.2.8) id AA10446; Tue, 18 Sep 90 21:28:25 +0200
  7687. Received: by taloa.unice.fr, Tue, 18 Sep 90 21:26:31 +0200
  7688. Date: Tue, 18 Sep 90 21:26:31 +0200
  7689. From: Olivier Lecarme <ol@taloa.unice.fr>
  7690. Message-Id: <9009181926.AA04451@taloa.unice.fr>
  7691. To: icon-group@cs.arizona.edu
  7692. Subject: simple test
  7693.  
  7694. This is is only a test for a new mail path. Please ignore this message.
  7695.  
  7696.  
  7697.             Olivier Lecarme
  7698.  
  7699. From icon-group-request@arizona.edu  Tue Sep 18 15:43:43 1990
  7700. Resent-From: icon-group-request@arizona.edu
  7701. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7702.     id AA21667; Tue, 18 Sep 90 15:43:43 -0700
  7703. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 18 Sep 90 15:43 MST
  7704. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA08895; Tue, 18 Sep 90
  7705.  15:36:57 -0700
  7706. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7707.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7708.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7709. Resent-Date: Tue, 18 Sep 90 15:43 MST
  7710. Date: 18 Sep 90 21:17:43 GMT
  7711. From: midway!quads.uchicago.edu!goer@handies.ucar.edu
  7712. Subject: RE: ProIcon review
  7713. Sender: icon-group-request@arizona.edu
  7714. Resent-To: icon-group@cs.arizona.edu
  7715. To: icon-group@arizona.edu
  7716. Resent-Message-Id: <317A8EA88DEB00D42A@Arizona.edu>
  7717. Message-Id: <1990Sep18.211743.23537@midway.uchicago.edu>
  7718. Organization: University of Chicago
  7719. X-Envelope-To: icon-group@CS.Arizona.EDU
  7720. X-Vms-To: icon-group@Arizona.EDU
  7721. References: <9009181811.AA15953@cherry04.cray.com>
  7722.  
  7723. Cargo@CHERRY.CRAY.COM (David S. Cargo) writes:
  7724. >I was in my company library over lunch and happened to see that
  7725. >the September issue of Computer Language had a review of ProIcon 1.0
  7726. >in it (page 102).  The reviewer was not pleased with ProIcon's help
  7727. >system nor with some of the error messages...
  7728.  
  7729. I wonder:  Did he seem to understand the history and purpose of the
  7730. Icon programming language, or was the reviewer new to Icon as well
  7731. as ProIcon?
  7732.  
  7733. -Richard
  7734.  
  7735. From kwalker  Wed Sep 19 15:22:43 1990
  7736. Received: from gacham.cs.arizona.edu by megaron (5.61/15) via SMTP
  7737.     id AA22050; Wed, 19 Sep 90 15:22:43 -0700
  7738. Date: Wed, 19 Sep 90 15:22:40 MST
  7739. From: "Kenneth Walker" <kwalker>
  7740. Message-Id: <9009192222.AA24483@gacham.cs.arizona.edu>
  7741. Received: by gacham.cs.arizona.edu; Wed, 19 Sep 90 15:22:40 MST
  7742. To: icon-group
  7743. Subject: RE: UUXXCODE
  7744.  
  7745.     Date: 18 Sep 90 16:13:58 GMT
  7746.     From: esquire!yost@nyu.edu
  7747.     
  7748.     In article <0093CBF0039A4D60.20400E83@mis.mcw.edu> tenaglia@mis.mcw.edu
  7749.         ("Chris Tenaglia - 257-8765") writes:
  7750.     >
  7751.     >I've attempted a port to Icon of UUENCODE and UUDECODE.
  7752.     
  7753.     Now there's a couple of programs I bet are really slow in Icon.
  7754.     I'd love to see how fast they run with the Icon compiler,
  7755.     compared to the interpreter and compared to the original
  7756.     C version.
  7757.     
  7758.     If the compiler can really do a good job on this sort of repetitive
  7759.     low-level stuff that kills Icon performance, it would be the dawning
  7760.     of a new day!  Imagine: we could use Icon instead of C for everything!
  7761.     
  7762.     Ken, can we see a benchmark on this?
  7763.     
  7764.  
  7765. I tried 3 runs of each program using the Unix time command and got a range
  7766. of results. The uuencode.icn I used has a fix that is not in the version
  7767. Chris posted. I also removed the write() expressions that print the number
  7768. of bytes in each group processed.
  7769.  
  7770.  uuencode:
  7771.      compiled is 4.0 - 5.8 times faster than interpreted
  7772.      system version is 21 - 40 times faster than compiled
  7773.  
  7774.  uudecode
  7775.       compiled is 2.4 - 2.9 times faster than interpreted
  7776.       system version is 22 - 36 times faster than compiled
  7777.  
  7778. While the time command is clearly not a very accurate measure of program
  7779. speed (I used the same data on all 3 runs), it does give a feeling
  7780. for how much the compiler improves speed and how much work is left to
  7781. do to get programs like these to run as fast as those coded in C.
  7782.  
  7783.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  7784.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  7785.  
  7786. From icon-group-request@arizona.edu  Wed Sep 19 17:46:51 1990
  7787. Resent-From: icon-group-request@arizona.edu
  7788. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7789.     id AA00568; Wed, 19 Sep 90 17:46:51 -0700
  7790. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 19 Sep 90 17:46 MST
  7791. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13509; Wed, 19 Sep 90
  7792.  17:34:02 -0700
  7793. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7794.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7795.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7796. Resent-Date: Wed, 19 Sep 90 17:46 MST
  7797. Date: 20 Sep 90 00:18:28 GMT
  7798. From: sdd.hp.com!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@ucsd.edu
  7799. Subject: RE: UUXXCODE
  7800. Sender: icon-group-request@arizona.edu
  7801. Resent-To: icon-group@cs.arizona.edu
  7802. To: icon-group@arizona.edu
  7803. Resent-Message-Id: <30A03110C10B00D8CD@Arizona.edu>
  7804. Message-Id: <1990Sep20.001828.10951@midway.uchicago.edu>
  7805. Organization: University of Chicago
  7806. X-Envelope-To: icon-group@CS.Arizona.EDU
  7807. X-Vms-To: icon-group@Arizona.EDU
  7808. References: <9009192222.AA24483@gacham.cs.arizona.edu>
  7809.  
  7810. Kwalker@CS.ARIZONA.EDU ("Kenneth Walker") writes:
  7811. >
  7812. > uuencode:
  7813. >     compiled is 4.0 - 5.8 times faster than interpreted
  7814. >     system version is 21 - 40 times faster than compiled
  7815. >
  7816. > uudecode
  7817. >      compiled is 2.4 - 2.9 times faster than interpreted
  7818. >      system version is 22 - 36 times faster than compiled
  7819. >
  7820. >While the time command is clearly not a very accurate measure of program
  7821. >speed (I used the same data on all 3 runs), it does give a feeling
  7822. >for how much the compiler improves speed and how much work is left to
  7823. >do to get programs like these to run as fast as those coded in C.
  7824.  
  7825. For short programs like this, it would probably be better to use C.
  7826. The real advantage of using Icon is in how it speeds up development
  7827. time, and aids program maintenance by simply cutting down on the amount
  7828. and complexity of the code.
  7829.  
  7830. I guess what I'm trying to say is that getting a two to five-fold
  7831. speed increase looks pretty good to people like me who can only think
  7832. with horror about what some of our programs would look like - or how
  7833. hard it would be to write/maintain them - if they had to be done in
  7834. C.
  7835.  
  7836. Don't be too deferential about the gap between compiled Icon and C.
  7837. What you and Janalee have done is terriffic.
  7838.  
  7839. -Richard
  7840.  
  7841. From icon-group-request@arizona.edu  Wed Sep 19 23:17:32 1990
  7842. Resent-From: icon-group-request@arizona.edu
  7843. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  7844.     id AA16249; Wed, 19 Sep 90 23:17:32 -0700
  7845. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 19 Sep 90 23:16 MST
  7846. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19555; Wed, 19 Sep 90
  7847.  23:14:17 -0700
  7848. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7849.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7850.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7851. Resent-Date: Wed, 19 Sep 90 23:17 MST
  7852. Date: 20 Sep 90 04:34:09 GMT
  7853. From: midway!quads.uchicago.edu!goer@handies.ucar.edu
  7854. Subject: RE: UUXXCODE
  7855. Sender: icon-group-request@arizona.edu
  7856. Resent-To: icon-group@cs.arizona.edu
  7857. To: icon-group@arizona.edu
  7858. Resent-Message-Id: <30720032018B00E529@Arizona.edu>
  7859. Message-Id: <1990Sep20.043409.14256@midway.uchicago.edu>
  7860. Organization: University of Chicago
  7861. X-Envelope-To: icon-group@CS.Arizona.EDU
  7862. X-Vms-To: icon-group@Arizona.EDU
  7863. References: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
  7864.  
  7865.  
  7866. ############################################################################
  7867. #
  7868. #    Name:     iidecode.icn
  7869. #
  7870. #    Title:     iidecode (port of the Unix/C uudecode program to Icon)
  7871. #
  7872. #    Author:     Richard L. Goerwitz
  7873. #
  7874. #    Version: 1.2
  7875. #
  7876. ############################################################################
  7877. #
  7878. #     This is an Icon port of the Unix/C uudecode utility.  Since
  7879. #  uudecode is publicly distributable BSD code, I simply grabbed a
  7880. #  copy, and rewrote it in Icon.  The only basic functional change I
  7881. #  made to the program was to simplify the notion of file mode.
  7882. #  Everything is encodedwith 0644 permissions.  Operating systems
  7883. #  differ so widely in how they handle this sort of thing that I
  7884. #  decided just not to worry about it.
  7885. #
  7886. #      Usage is the same as the Unix uudecode command, i.e. a first
  7887. #  (optional) argument gives the name the file to be decoded.  If this
  7888. #  is omitted, iidecode just uses the standard input:
  7889. #
  7890. #         iidecode [infile] remotefilename
  7891. #
  7892. #      Even people who do not customarily use Unix should be aware of
  7893. #  the uuen/decode program and file format.  It is widely used, and has
  7894. #  been implemented on a wide variety of machines for sending 8-bit
  7895. #  "binaries" through networks designed for ASCII transfers only.
  7896. #
  7897. #  BUGS:  Slow.  I decided to go for clarity and symmetry, rather than
  7898. #  speed, and so opted to do things like use ishift(i,j) instead of
  7899. #  straight multiplication (which under Icon v8 is much faster).
  7900. #
  7901. ############################################################################
  7902. #
  7903. #  See also: iiencode.icn
  7904. #
  7905. ############################################################################
  7906.  
  7907. procedure main(a)
  7908.  
  7909.     local in, filename, dest
  7910.  
  7911.     # optional 1st (and only) argument
  7912.     if *a = 1 then {
  7913.     filename := pop(a)
  7914.     if not (in := open(filename, "r")) then {
  7915.         write(&errout,"Can't open ",a[1],".")
  7916.         exit(1)
  7917.     }
  7918.     }
  7919.     else in := &input
  7920.  
  7921.     if *a ~= 0 then {
  7922.     write(&errout,"Usage:  iidecode [infile] remotefile")
  7923.     exit (2)
  7924.     }
  7925.  
  7926.     # Find the "begin" line, and determine the destination file name.
  7927.     !in ? {
  7928.     tab(match("begin ")) &
  7929.     tab(many(&digits))   &    # mode ignored
  7930.     tab(many(' '))       &
  7931.     dest := tab(0)
  7932.     }
  7933.  
  7934.     # If dest is null, the begin line either isn't present, or is
  7935.     # corrupt (which necessitates our aborting with an error msg.).
  7936.     if /dest then {
  7937.     write(&errout,"No begin line.")
  7938.     exit(3)
  7939.     }
  7940.  
  7941.     # Tilde expansion is heavily Unix dependent, and we can't always
  7942.     # safely write the file to the current directory.  Our only choice
  7943.     # is to abort.
  7944.     if match("~",dest) then {
  7945.     write(&errout,"Please remove ~ from input file begin line.")
  7946.     exit(4)
  7947.     }
  7948.        
  7949.     out := open(dest, "w")
  7950.     decode(in, out)        # decode checks for "end" line
  7951.     if not match("end", !in) then {
  7952.     write(&errout,"No end line.\n")
  7953.     exit(5)
  7954.     }
  7955.     exit(0)
  7956.  
  7957. end
  7958.  
  7959.  
  7960.  
  7961. procedure decode(in, out)
  7962.     
  7963.     # Copy from in to out, decoding as you go along.
  7964.  
  7965.     local line, chunk
  7966.  
  7967.     while line := read(in) do {
  7968.  
  7969.     if *line = 0 then {
  7970.         write(&errout,"Short file.\n")
  7971.         exit(10)
  7972.     }
  7973.  
  7974.     line ? {
  7975.         n := DEC(ord(move(1)))
  7976.  
  7977.         # Uuencode signals the end of the coded text by a space
  7978.         # and a line (i.e. a zero-length line, coded as a space).
  7979.         if n <= 0 then break
  7980.         
  7981.         while (n > 0) do {
  7982.         chunk := move(4) | tab(0)
  7983.         outdec(chunk, out, n)
  7984.         n -:= 3
  7985.         }
  7986.     }
  7987.     }
  7988.     
  7989.     return
  7990.  
  7991. end
  7992.  
  7993.  
  7994.  
  7995. procedure outdec(s, f, n)
  7996.  
  7997.     # Output a group of 3 bytes (4 input characters).  N is used to
  7998.     # tell us not to output all of the chars at the end of the file.
  7999.  
  8000.     local c1, c2, c3
  8001.  
  8002.     c1 := iand(
  8003.            ior(
  8004.            ishift(DEC(ord(s[1])),+2),
  8005.            ishift(DEC(ord(s[2])),-4)
  8006.            ),
  8007.            8r0377)
  8008.     c2 := iand(
  8009.            ior(
  8010.            ishift(DEC(ord(s[2])),+4),
  8011.            ishift(DEC(ord(s[3])),-2)
  8012.            ),
  8013.            8r0377)
  8014.     c3 := iand(
  8015.            ior(
  8016.            ishift(DEC(ord(s[3])),+6),
  8017.            DEC(ord(s[4]))
  8018.            ),
  8019.            8r0377)
  8020.  
  8021.     if (n >= 1) then
  8022.     writes(f,char(c1))
  8023.     if (n >= 2) then
  8024.     writes(f,char(c2))
  8025.     if (n >= 3) then
  8026.     writes(f,char(c3))
  8027.  
  8028. end    
  8029.  
  8030.  
  8031.  
  8032. procedure DEC(c)
  8033.  
  8034.     # single character decode
  8035.     return iand(c - 32, 8r077)
  8036.  
  8037. end
  8038.  
  8039. From icon-group-request@arizona.edu  Wed Sep 19 23:17:47 1990
  8040. Resent-From: icon-group-request@arizona.edu
  8041. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  8042.     id AA16258; Wed, 19 Sep 90 23:17:47 -0700
  8043. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 19 Sep 90 23:17 MST
  8044. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19538; Wed, 19 Sep 90
  8045.  23:13:29 -0700
  8046. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8047.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8048.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8049. Resent-Date: Wed, 19 Sep 90 23:17 MST
  8050. Date: 20 Sep 90 04:32:20 GMT
  8051. From: maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@uunet.uu.net
  8052. Subject: RE: UUXXCODE
  8053. Sender: icon-group-request@arizona.edu
  8054. Resent-To: icon-group@cs.arizona.edu
  8055. To: icon-group@arizona.edu
  8056. Resent-Message-Id: <3071F6AA202B00DD2A@Arizona.edu>
  8057. Message-Id: <1990Sep20.043220.14195@midway.uchicago.edu>
  8058. Organization: University of Chicago
  8059. X-Envelope-To: icon-group@CS.Arizona.EDU
  8060. X-Vms-To: icon-group@Arizona.EDU
  8061. References: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
  8062.  
  8063. Tenaglia@mis.mcw.edu ("Chris Tenaglia") writes:
  8064. >
  8065. >I have some files that I'd like to UUENCODE or UUDECODE. Being on a VMS
  8066. >system without a C compiler, having the sources still doesn't help. I've
  8067. >attempted a port to Icon of UUENCODE and UUDECODE. They are close, but not
  8068. >quite right. Would someone care to look them over and offer suggestions or
  8069. >corrections?
  8070.  
  8071. No C compiler?  How do you exist?  :-)
  8072.  
  8073. Here are a couple of Icon uuXXcode functions.  They should be pretty much
  8074. compatible with the latest BSD version.  Notes are offered on how to make
  8075. them work the same as the "old" version, though the two versions are com-
  8076. patible.
  8077.  
  8078. I guess I'll post uuencode first (I call it iiencode).  Iidecode will come
  8079. in a subsequent posting.
  8080.  
  8081. -Richard
  8082.  
  8083. ############################################################################
  8084. #
  8085. #    Name:     iiencode.icn
  8086. #
  8087. #    Title:     iiencode (port of the Unix/C uuencode program to Icon)
  8088. #
  8089. #    Author:     Richard L. Goerwitz
  8090. #
  8091. #    Version: 1.2
  8092. #
  8093. ############################################################################
  8094. #
  8095. #     This is an Icon port of the Unix/C uuencode utility.  Since
  8096. #  uuencode is publicly distributable BSD code, I simply grabbed a
  8097. #  copy, and rewrote it in Icon.  The only basic functional change I
  8098. #  made to the program was to simplify the notion of file mode.
  8099. #  Everything is encoded with 0644 permissions.  Operating systems
  8100. #  differ so widely in how they handle this sort of thing that I
  8101. #  decided just not to worry about it.
  8102. #
  8103. #      Usage is the same as the Unix uuencode command, i.e. a first
  8104. #  (optional) argument gives the name the file to be encoded.  If this
  8105. #  is omitted, iiencode just uses the standard input.  The second and
  8106. #  final argument gives the name the encoded file should be given when
  8107. #  it is ultimately decoded:
  8108. #
  8109. #         iiencode [infile] remotefilename
  8110. #
  8111. #  BUGS:  Slow.  I decided to go for clarity and symmetry, rather than
  8112. #  speed, and so opted to do things like use ishift(i,j) instead of
  8113. #  straight multiplication (which under Icon v8 is much faster).  Note
  8114. #  that I followed the format of the newest BSD release, which refuses
  8115. #  to output spaces.  If you want to change things back around so that
  8116. #  spaces are output, look for the string "BSD" in my comments, and
  8117. #  then (un)comment the appropriate sections of code.
  8118. #
  8119. ############################################################################
  8120. #
  8121. #  See also: iidecode.icn
  8122. #
  8123. ############################################################################
  8124.  
  8125.  
  8126. procedure main(a)
  8127.  
  8128.     local in, filename
  8129.  
  8130.     # optional 1st argument
  8131.     if *a = 2 then {
  8132.     filename := pop(a)
  8133.     if not (in := open(filename, "r")) then {
  8134.         write(&errout,"Can't open ",a[1],".")
  8135.         exit(1)
  8136.     }
  8137.     }
  8138.     else in := &input
  8139.  
  8140.     if *a ~= 1 then {
  8141.     write(&errout,"Usage:  iiencode [infile] remotefile")
  8142.     exit (2)
  8143.     }
  8144.  
  8145.     # This generic version of uuencode treats file modes in a primitive
  8146.     # manner so as to be usable in a number of environments.  Please
  8147.     # don't get fancy and change this unless you plan on keeping your
  8148.     # modified version on-site (or else modifying the code in such a
  8149.     # way as to avoid dependence on a specific operating system).
  8150.     writes("begin 644 ",a[1],"\n")
  8151.  
  8152.     encode(in)
  8153.  
  8154.     writes("end\n")
  8155.     exit(0)
  8156.  
  8157. end
  8158.  
  8159.  
  8160.  
  8161. procedure encode(in)
  8162.  
  8163.     # Copy from in to standard output, encoding as you go along.
  8164.  
  8165.     local line
  8166.  
  8167.     # 1 (up to) 45 character segment
  8168.     while line := reads(in, 45) do {
  8169.     writes(ENC(*line))
  8170.     line ? {
  8171.         while outdec(move(3))
  8172.         pos(0) | outdec(left(tab(0), 3, " "))
  8173.     }
  8174.     writes("\n")
  8175.     }
  8176.     # Uuencode adds a space and newline here, which is decoded later
  8177.     # as a zero-length line (signals the end of the decoded text).
  8178.     # writes(" \n")
  8179.     # The new BSD code (compatible with the old) avoids outputting
  8180.     # spaces by writing a ` (see also how it handles ENC() below).
  8181.     writes("`\n")
  8182.     
  8183. end
  8184.  
  8185.  
  8186.  
  8187. procedure outdec(s)
  8188.  
  8189.     # Output one group of 3 bytes (s) to standard output.  This is one
  8190.     # case where C is actually more elegant than Icon.  Note well!
  8191.  
  8192.     local c1, c2, c3, c4
  8193.  
  8194.     c1 := ishift(ord(s[1]),-2)
  8195.     c2 := ior(iand(ishift(ord(s[1]),+4), 8r060),
  8196.           iand(ishift(ord(s[2]),-4), 8r017))
  8197.     c3 := ior(iand(ishift(ord(s[2]),+2), 8r074),
  8198.           iand(ishift(ord(s[3]),-6), 8r003))
  8199.     c4 := iand(ord(s[3]),8r077)
  8200.     every writes(ENC(c1 | c2 | c3 | c4))
  8201.  
  8202.     return
  8203.  
  8204. end
  8205.  
  8206.  
  8207.  
  8208. procedure ENC(c)
  8209.  
  8210.     # ENC is the basic 1 character encoding procedure to make a char
  8211.     # printing.
  8212.  
  8213.     # New BSD code doesn't output spaces...
  8214.     return " " ~== char(iand(c, 8r077) + 32) | "`"
  8215.     # ...the way the old code does:
  8216.     # return char(iand(c, 8r077) + 32)
  8217.  
  8218. end
  8219.  
  8220. From R.J.Hare@edinburgh.ac.uk  Fri Sep 21 00:45:18 1990
  8221. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  8222.     id AA13858; Fri, 21 Sep 90 00:45:18 -0700
  8223. Received: from UKACRL.BITNET by Arizona.edu; Fri, 21 Sep 90 00:45 MST
  8224. Received: from RL.IB by UKACRL.BITNET (Mailer R2.03B) with BSMTP id 9946; Fri,
  8225.  21 Sep 90 08:33:35 BST
  8226. Date: 21 Sep 90  08:34:30 bst
  8227. From: R.J.Hare@edinburgh.ac.uk
  8228. Subject: Genealogy
  8229. To: icon-group@cs.arizona.edu
  8230. Message-Id: <21 Sep 90  08:34:30 bst  340090@EMAS-A>
  8231. Via:        UK.AC.ED.EMAS-A; 21 SEP 90  8:33:33 BST
  8232. X-Envelope-To: icon-group@cs.arizona.edu
  8233.  
  8234. Does anyone know of an Icon program which organises family trees please?
  8235.  
  8236. Thanks.
  8237.  
  8238. Roger Hare.
  8239.  
  8240. From tenaglia@mis.mcw.edu  Fri Sep 21 03:20:59 1990
  8241. Received: from rutgers.edu by megaron (5.61/15) via SMTP
  8242.     id AA21449; Fri, 21 Sep 90 03:20:59 -0700
  8243. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  8244.     id AA15499; Fri, 21 Sep 90 00:03:59 EDT
  8245. Received: by uwm.edu; id AA24276; Thu, 20 Sep 90 09:34:56 -0500
  8246. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  8247.           Thu, 20 Sep 90 09:19:48 CDT
  8248. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  8249.           Thu, 20 Sep 90 09:21:14 CDT
  8250. Date: Thu, 20 Sep 90 09:21:14 CDT
  8251. Message-Id: <0093CFE25F8CFBE0.20401477@mis.mcw.edu>
  8252. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  8253. Subject: UUXXCODE
  8254. To: icon-group@cs.arizona.edu
  8255.  
  8256.  
  8257. I'd like to thank Ken Walker for his corrective advice in getting the
  8258. uuencode fixed. Apparently the uudecode was ok. Thanks also for the
  8259. alternative iiencode/iidecode. It sure generated a stir. I was looking
  8260. for a little unix-like functionality, but it seems to be of great
  8261. interest to benchmarkers too. The uudecode is probably a pretty shabby
  8262. example, since I converted it almost literally from a PC BASIC program.
  8263.  
  8264. For VMS folks, uuencode and uudecode are nifty ways of converted binary
  8265. data to printable/mailable ascii and back again. It expands 3 binary
  8266. bytes into 4 printable bytes. This 33% increase is more compact than
  8267. vms dump data. Unfortunately vms has oodles of file types, and not all
  8268. will work. VMS Executables (.EXE) will compress and decompress just fine.
  8269. Icon executables work too (.ICX). Object files (.OBJ) won't work at all.
  8270. Text files almost work. Sometimes there is a little trailing garbage on
  8271. the end of the file (or is that a bug in my program?)
  8272.  
  8273. Is there any interest in a reposting of the finished programs?
  8274.  
  8275. Chris Tenaglia (System Manager)
  8276. Medical College of Wisconsin
  8277. 8701 W. Watertown Plank Rd.
  8278. Milwaukee, WI 53226
  8279. (414)257-8765
  8280. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  8281.  
  8282.  
  8283. From goer%sophist@gargoyle.uchicago.edu  Sun Sep 23 21:47:48 1990
  8284. Resent-From: goer%sophist@gargoyle.uchicago.edu
  8285. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8286.     id AA22685; Sun, 23 Sep 90 21:47:48 -0700
  8287. Return-Path: goer@sophist.uchicago.edu
  8288. Received: from gargoyle.uchicago.edu by Arizona.edu; Sun, 23 Sep 90 21:47 MST
  8289. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  8290.  AA04285; Sun, 23 Sep 90 23:47:21 199
  8291. Received: by sophist (4.1/UofC3.1X) id AA09126; Sun, 23 Sep 90 23:51:31 CDT
  8292. Resent-Date: Sun, 23 Sep 90 21:47 MST
  8293. Date: Sun, 23 Sep 90 23:51:31 CDT
  8294. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  8295. Subject: ms-dos *.*
  8296. Resent-To: icon-group@cs.arizona.edu
  8297. To: icon-group@arizona.edu
  8298. Resent-Message-Id: <2D59DB1BF6AB010EA2@Arizona.edu>
  8299. Message-Id: <9009240451.AA09126@sophist>
  8300. X-Envelope-To: icon-group@CS.Arizona.EDU
  8301. X-Vms-To: icon-group@Arizona.EDU
  8302.  
  8303. I recall some years ago reading a posting in which someone
  8304. included an MS-DOS function which returns a wild-card based
  8305. directory listing from within Icon.
  8306.  
  8307. I wonder whether this is still available anywhere.
  8308.  
  8309. In fact, I wonder in general how people using systems with-
  8310. out pipes get a directory listing from within Icon.  Under
  8311. Unix, I can simply read a pipe from /bin/ls.  How do peo-
  8312. ple using Macs do this, say?  Others?
  8313.  
  8314. -Richard
  8315.  
  8316. From icon-group-request@arizona.edu  Mon Sep 24 08:59:43 1990
  8317. Resent-From: icon-group-request@arizona.edu
  8318. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8319.     id AA16955; Mon, 24 Sep 90 08:59:43 -0700
  8320. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 08:59 MST
  8321. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09635; Mon, 24 Sep 90
  8322.  08:46:03 -0700
  8323. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8324.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8325.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8326. Resent-Date: Mon, 24 Sep 90 08:59 MST
  8327. Date: 24 Sep 90 15:42:51 GMT
  8328. From: boutell@louie.udel.edu
  8329. Subject: Babe in the Woods
  8330. Sender: icon-group-request@arizona.edu
  8331. Resent-To: icon-group@cs.arizona.edu
  8332. To: icon-group@arizona.edu
  8333. Resent-Message-Id: <2CFC035FAB6B0110A2@Arizona.edu>
  8334. Message-Id: <31372@nigel.ee.udel.edu>
  8335. Organization: University of Delaware -- ACIT Sun Lab
  8336. X-Envelope-To: icon-group@CS.Arizona.EDU
  8337. X-Vms-To: icon-group@Arizona.EDU
  8338.  
  8339. I've been keeping an eye on this group out of rabid curiosity, but have
  8340. yet to see an general information posting, so forgive the waste of
  8341. bandwidth: what is icon? Is it a publicly available language? Does its
  8342. name imply that it is a GUI- based language? I gathered this impression
  8343. from a few ads seen long, LONG ago.
  8344.  
  8345. i've seen mention of an MSDOS version, so I can't restrain my curiosity
  8346. any longer. Please enlighten!
  8347.  
  8348. -- 
  8349. What do you want from the fish of the fish that you fished when you fished
  8350. for the fish that you fished? How many numchuks could Chuck chuck if Chuck
  8351. could chuck numchuks? boutell@freezer.it.udel.edu? Or 27.598234821? Or not?
  8352.  
  8353. From kwalker  Mon Sep 24 09:28:29 1990
  8354. Resent-From: "Kenneth Walker" <kwalker>
  8355. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8356.     id AA19170; Mon, 24 Sep 90 09:28:29 -0700
  8357. Received: from megaron.cs.Arizona.EDU by Arizona.edu; Mon, 24 Sep 90 09:27 MST
  8358. Received: from gacham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via
  8359.  SMTP id AA19140; Mon, 24 Sep 90 09:27:32 -0700
  8360. Received: by gacham.cs.arizona.edu; Mon, 24 Sep 90 09:27:29 MST
  8361. Resent-Date: Mon, 24 Sep 90 09:28 MST
  8362. Date: Mon, 24 Sep 90 09:27:29 MST
  8363. From: Kenneth Walker <kwalker@cs.arizona.edu>
  8364. Subject: RE:  Babe in the Woods
  8365. Resent-To: icon-group@cs.arizona.edu
  8366. To: boutell@louie.udel.edu, icon-group@arizona.edu
  8367. Resent-Message-Id: <2CF80085D44B011122@Arizona.edu>
  8368. Message-Id: <9009241627.AA09502@gacham.cs.arizona.edu>
  8369. X-Envelope-To: icon-group@CS.Arizona.EDU
  8370. X-Vms-To: boutell@louie.udel.edu, icon-group@Arizona.EDU
  8371.  
  8372.     Date: 24 Sep 90 15:42:51 GMT
  8373.     From: boutell@louie.udel.edu
  8374.     
  8375.     I've been keeping an eye on this group out of rabid curiosity, but have
  8376.     yet to see an general information posting, so forgive the waste of
  8377.     bandwidth: what is icon? Is it a publicly available language? Does its
  8378.     name imply that it is a GUI- based language? I gathered this impression
  8379.     from a few ads seen long, LONG ago.
  8380.     
  8381.     i've seen mention of an MSDOS version, so I can't restrain my curiosity
  8382.     any longer. Please enlighten!
  8383.     
  8384.  
  8385. Icon is not a GUI-based language. The name Icon was affixed to the language
  8386. before the usage of the term icon to mean a pictograph became popular. It has
  8387. been a while since I posted my standard reply to the question "what is Icon",
  8388. so here it is.
  8389.  
  8390. Icon is a high level programming language designed for string processing
  8391. and other non-numeric applications (numeric processing can be done, but the
  8392. language and implementation are not tuned for it). Goal-directed evaluation
  8393. with control backtracking is an integral part of the language. However,
  8394. Icon is very different from other languages, such as Prolog, which use
  8395. this evaluation scheme. Icon has a rich set of control structures which
  8396. use and control backtracking. Most of these control structures look and
  8397. act very much like the control structures of more traditional languages,
  8398. allowing Pascal-like programming where the full power of goal-directed
  8399. evaluation is not required. Icon incorporates generators as a natural feature
  8400. within this goal-directed evaluation scheme.
  8401.  
  8402. Icon has a flexible run-time type system: variables may take on values of
  8403. any type and automatic type conversions are performed as needed by
  8404. operations. There are a variety of types including strings, sets, associative
  8405. tables, and lists with positional, queue, and stack access methods. All
  8406. storage management is automatic; garbage collection is performed as needed.
  8407.  
  8408. Icon is available for many system: Amiga, Atari, CMS, MS-DOS, MVS,
  8409. Macintosh, OS/2, most Unix systems, and VMS. All the versions that the
  8410. Icon Project distribute are in the public domain, except for MS-DOS/386
  8411. executables which use a commercial DOS extender (the regular MS-DOS
  8412. distribution is public domain). The Macintosh version we distribute runs
  8413. only under MPW. There is a commercial Mac version that runs stand-alone.
  8414.  
  8415. If you want information on obtaining Icon, let me know.
  8416.  
  8417.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  8418.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  8419.  
  8420. From icon-group-request@arizona.edu  Mon Sep 24 11:30:08 1990
  8421. Resent-From: icon-group-request@arizona.edu
  8422. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8423.     id AA25062; Mon, 24 Sep 90 11:30:08 -0700
  8424. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 11:29 MST
  8425. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13436; Mon, 24 Sep 90
  8426.  11:16:48 -0700
  8427. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8428.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8429.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8430. Resent-Date: Mon, 24 Sep 90 11:29 MST
  8431. Date: 24 Sep 90 17:48:07 GMT
  8432. From: jarthur!elroy.jpl.nasa.gov!suned1!zaft@uunet.uu.net
  8433. Subject: RE: Babe in the Woods (long)
  8434. Sender: icon-group-request@arizona.edu
  8435. Resent-To: icon-group@cs.arizona.edu
  8436. To: icon-group@arizona.edu
  8437. Resent-Message-Id: <2CE6FC3BDE4B01081E@Arizona.edu>
  8438. Message-Id: <5472@suned1.Nswses.Navy.MIL>
  8439. Organization: NSWSES, Port Hueneme, CA
  8440. X-Envelope-To: icon-group@CS.Arizona.EDU
  8441. X-Vms-To: icon-group@Arizona.EDU
  8442. References: <31372@nigel.ee.udel.edu>
  8443.  
  8444. In article <31372@nigel.ee.udel.edu> boutell@freezer.it.udel.edu (Tom Boutell) writes:
  8445. >I've been keeping an eye on this group out of rabid curiosity, but have
  8446. >yet to see an general information posting, so forgive the waste of
  8447. >bandwidth: what is icon? Is it a publicly available language? Does its
  8448. >name imply that it is a GUI- based language? I gathered this impression
  8449. >from a few ads seen long, LONG ago.
  8450. >
  8451. >i've seen mention of an MSDOS version, so I can't restrain my curiosity
  8452. >any longer. Please enlighten!
  8453.  
  8454. Quoted from "The Icon Programming Language", by Griswold & Griswold.
  8455.  
  8456. "Icon is a high-level, general-purpose programming language that 
  8457. contains many features for processing nonnumeric data, particularly
  8458. for textual material consisting of strings of characters.  Icon was
  8459. designed to aid in analyzing natural languages, reformatting data,
  8460. transforming computer programs, generating computer programs, 
  8461. manipulating formaulas, formatting documents, and so forth.  IT
  8462. is suited to situations where a quick solution is needed, one
  8463. that can be obtained with a minimum of time and programming effort.
  8464. Icon is extremely useful for 'one-shot' programs and for 
  8465. speculative efforts such as computer-generated poetry, in which a
  8466. proposed problem solution is more heuristic than algorithmic."
  8467.  
  8468. End quote.
  8469.  
  8470.     Icon is available for free, since it was written with
  8471. support of the NSF.  Icon was originally written by Ralph Griswold,
  8472. and a cast of thousands at the University of Arizona (my alma mater!).
  8473. Ralph Griswold, you may remember, was part of the team that developed
  8474. SNOBOL.
  8475.  
  8476.     Ports of Icon are available for most Unix machines, as well
  8477. as MS-DOS, VMS, and Macintosh (I believe the Macintosh version is
  8478. not available from UA but is a commercial project).
  8479.  
  8480.     You can get more information by writing:
  8481.  
  8482.     Icon Project
  8483.     Department of Computer Science
  8484.     University of Arizona
  8485.     Tucson, AZ  85721
  8486.  
  8487.     (602) 621-6613 (phone # is as of 1983 & may be different).
  8488.  
  8489.     I think you may also be able to anon. ftp  stuff from UA,
  8490. also, but I don't know the address.  
  8491.  
  8492.     The definitive book is 
  8493.  
  8494.     The Icon Programming Language
  8495.     Ralph E. Griswold & Madge T. Griswold, Prentice-Hall, 1983.
  8496.     ISBN 0-13-449777-5.
  8497.  
  8498.     I believe an updated book is on the way but I don't know if
  8499. it's been released yet.  The book describes version 5; the current
  8500. release is version 8.
  8501.  
  8502.     Hope this answers your questions.A
  8503. A
  8504. A
  8505. A
  8506. A
  8507. A
  8508.     
  8509. --
  8510. +  Gordon Zaft                        |  zaft@suned1.nswses.navy.mil         +
  8511. +  NSWSES, Code 4Y33                  |  suned1!zaft@elroy.jpl.nasa.gov      +
  8512. +  Port Hueneme, CA 93043-5007        |  Phone: (805) 982-0684 FAX: 982-8768 +
  8513.                   ++++ Ubi caritas et amor, Deus ibi est.++++
  8514.  
  8515. From icon-group-request@arizona.edu  Mon Sep 24 13:00:42 1990
  8516. Resent-From: icon-group-request@arizona.edu
  8517. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8518.     id AA29245; Mon, 24 Sep 90 13:00:42 -0700
  8519. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 12:59 MST
  8520. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA16093; Mon, 24 Sep 90
  8521.  12:56:25 -0700
  8522. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8523.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8524.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8525. Resent-Date: Mon, 24 Sep 90 13:00 MST
  8526. Date: 24 Sep 90 19:33:18 GMT
  8527. From: mephisto!prism!sun13!sun8.scri.fsu.edu!nall@rutgers.edu
  8528. Subject: RE: Babe in the Woods (long)
  8529. Sender: icon-group-request@arizona.edu
  8530. Resent-To: icon-group@cs.arizona.edu
  8531. To: icon-group@arizona.edu
  8532. Resent-Message-Id: <2CDA5D1A118B010C25@Arizona.edu>
  8533. Message-Id: <763@sun13.scri.fsu.edu>
  8534. Organization: Florida State University Computing Center
  8535. X-Envelope-To: icon-group@CS.Arizona.EDU
  8536. X-Vms-To: icon-group@Arizona.EDU
  8537. References: <31372@nigel.ee.udel.edu>, <5472@suned1.Nswses.Navy.MIL>
  8538.  
  8539. In article <5472@suned1.Nswses.Navy.MIL> zaft@nswses.navy.mil (Gordon C Zaft) writes:
  8540. >In article <31372@nigel.ee.udel.edu> boutell@freezer.it.udel.edu (Tom Boutell) writes:
  8541. >>I've been keeping an eye on this group out of rabid curiosity, but have
  8542. >>yet to see an general information posting, so forgive the waste of
  8543. >>bandwidth: what is icon? Is it a publicly available language? Does its
  8544.   [more deleted...]
  8545. >
  8546.   [lots of good info deleted, for brevity...]
  8547. >
  8548. >    I think you may also be able to anon. ftp  stuff from UA,
  8549. >also, but I don't know the address.  
  8550.  
  8551. I picked up up with ftp several months ago.  The address at that time
  8552. was cs.arizona.edu [128.196.128.118]
  8553.  
  8554. >
  8555. >    The definitive book is 
  8556. >
  8557. >    The Icon Programming Language
  8558. >    Ralph E. Griswold & Madge T. Griswold, Prentice-Hall, 1983.
  8559. >    ISBN 0-13-449777-5.
  8560. >
  8561. >    I believe an updated book is on the way but I don't know if
  8562. >it's been released yet.  The book describes version 5; the current
  8563. >release is version 8.
  8564.  
  8565. The new book is same title, but Second Edition.  Same publisher, 
  8566. 1990, ISBN 0-13-447889-4.  Describes Version 8.
  8567.  
  8568.  
  8569. >    Hope this answers your questions.A
  8570.  
  8571.      Ditto for the additional answers.  By the way, I think that I
  8572. heard somewhere that Version 8 is NOT running under MS-DOS, but have
  8573. not had that confirmed.  Anyone know??
  8574.  
  8575. >--
  8576. >+  Gordon Zaft                        |  zaft@suned1.nswses.navy.mil         +
  8577. >+  NSWSES, Code 4Y33                  |  suned1!zaft@elroy.jpl.nasa.gov      +
  8578. >+  Port Hueneme, CA 93043-5007        |  Phone: (805) 982-0684 FAX: 982-8768 +
  8579. >                  ++++ Ubi caritas et amor, Deus ibi est.++++
  8580.  
  8581.  
  8582. --
  8583. John W. Nall        | Supercomputation Computations Research Institute
  8584. nall@sun8.scri.fsu.edu  | Florida State University, Tallahassee, FL 32306
  8585.  "Real programmers can write assembly code in any language." - Larry Wall
  8586.  
  8587. From kwalker  Mon Sep 24 13:53:39 1990
  8588. Received: from gacham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  8589.     id AA02095; Mon, 24 Sep 90 13:53:39 -0700
  8590. Date: Mon, 24 Sep 90 13:53:36 MST
  8591. From: "Kenneth Walker" <kwalker>
  8592. Message-Id: <9009242053.AA10155@gacham.cs.arizona.edu>
  8593. Received: by gacham.cs.arizona.edu; Mon, 24 Sep 90 13:53:36 MST
  8594. To: icon-group
  8595. Subject: RE: Babe in the Woods (long)
  8596.  
  8597.     Date: 24 Sep 90 19:33:18 GMT
  8598.     From: mephisto!prism!sun13!sun8.scri.fsu.edu!nall@rutgers.edu
  8599.     
  8600.     By the way, I think that I
  8601.     heard somewhere that Version 8 is NOT running under MS-DOS, but have
  8602.     not had that confirmed.  Anyone know??
  8603.     
  8604.  
  8605. Version 8 of Icon does run under MS-DOS. However, it is recommended that
  8606. you have at least 500k of free RAM; Icon uses a lot of memory.
  8607.  
  8608.   Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  8609.   +1 602 621-4324  kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
  8610.  
  8611. From tenaglia@mis.mcw.edu  Mon Sep 24 15:44:01 1990
  8612. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  8613.     id AA07826; Mon, 24 Sep 90 15:44:01 -0700
  8614. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  8615.     id AA07031; Mon, 24 Sep 90 18:19:11 EDT
  8616. Received: by uwm.edu; id AA04145; Mon, 24 Sep 90 17:05:42 -0500
  8617. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  8618.           Mon, 24 Sep 90 13:42:42 CDT
  8619. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  8620.           Mon, 24 Sep 90 13:41:09 CDT
  8621. Date: Mon, 24 Sep 90 13:41:09 CDT
  8622. Message-Id: <0093D32B5856BB80.204002AD@mis.mcw.edu>
  8623. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  8624. Subject: Icon pipes in MSDOS
  8625. To: icon-group@cs.arizona.edu
  8626.  
  8627.  
  8628. MSDOS does have pipes, but they're implemented differently than unix. MSDOS
  8629. does it by generating scratch files. One can actually do a DIR|SORT or
  8630. DIR | ICONX PROG. Inside icon one can issue system("dir >_dir.tmp") and
  8631. then infile:=open("_dir.tmp") for subsequent processing. It also uses a
  8632. little more memory when using the system command.
  8633.  
  8634. I'd sure like to know how the MAC does it too. Is there a difference between
  8635. a MAC with Multifinder and one with MPW?
  8636.  
  8637. Chris Tenaglia (System Manager)
  8638. Medical College of Wisconsin
  8639. 8701 W. Watertown Plank Rd.
  8640. Milwaukee, WI 53226
  8641. (414)257-8765
  8642. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  8643.  
  8644.  
  8645.  
  8646. From icon-group-request@arizona.edu  Mon Sep 24 19:33:00 1990
  8647. Resent-From: icon-group-request@arizona.edu
  8648. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8649.     id AA16661; Mon, 24 Sep 90 19:33:00 -0700
  8650. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 19:32 MST
  8651. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA25323; Mon, 24 Sep 90
  8652.  19:17:24 -0700
  8653. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8654.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8655.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8656. Resent-Date: Mon, 24 Sep 90 19:32 MST
  8657. Date: 25 Sep 90 00:57:11 GMT
  8658. From: ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@iuvax.cs.indiana.edu
  8659. Subject: RE: Icon pipes in MSDOS
  8660. Sender: icon-group-request@arizona.edu
  8661. Resent-To: icon-group@cs.arizona.edu
  8662. To: icon-group@arizona.edu
  8663. Resent-Message-Id: <2CA3885B642B00F0D3@Arizona.edu>
  8664. Message-Id: <1990Sep25.005711.29504@midway.uchicago.edu>
  8665. Organization: University of Chicago
  8666. X-Envelope-To: icon-group@CS.Arizona.EDU
  8667. X-Vms-To: icon-group@Arizona.EDU
  8668. References: <0093D32B5856BB80.204002AD@mis.mcw.edu>
  8669.  
  8670. Tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
  8671.  
  8672. >MSDOS does have pipes, but they're implemented differently than unix...
  8673.  
  8674. This was in reference to my question about what people do to get direc-
  8675. tory listings on systems that don't support pipes.  I guess what I meant
  8676. to say was, "How do people get directory listings from within Icon on
  8677. systems that don't implement the "p" option for open() (i.e. do 'real'
  8678. pipes)?"
  8679.  
  8680. I'd be afraid to try to get a directory listing from Icon running under
  8681. MS-DOS using intermediate files because you can't always count on 1)
  8682. having enough free memory to do the system() function given Icon's
  8683. size, and 2) writing to disc introduces yet another level of indirec-
  8684. tion, and hence the possibility of many more errors (not enough disc
  8685. space, clobbering a previously existing tempfile, not being able to
  8686. write to the current directory, and not having a standard place for
  8687. temp files).
  8688.  
  8689. I'm searching for an answer to the dirlist from Icon problem because
  8690. I want to implement an indexing program in such a way that it can be
  8691. moved from Unix to Xenix to MS-DOS (others?) as easily as possible.
  8692. Part of the indexing procedure is to look at all file of a specified
  8693. type in a specified location.  This involves finding a portable way
  8694. of getting a directory listing....
  8695.  
  8696. -Richard
  8697.  
  8698. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS  Mon Sep 24 19:45:00 1990
  8699. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  8700.     id AA16888; Mon, 24 Sep 90 19:45:00 -0700
  8701. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  8702.     id AA20714; Mon, 24 Sep 90 22:44:56 -0400
  8703. Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Mon, 24 Sep 90 22:36:42 EDT
  8704. Date: Mon, 24 Sep 90 18:33:42 EDT
  8705. From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
  8706. To: icon-group@cs.arizona.edu
  8707. Message-Id: <251913@Wayne-MTS>
  8708. Subject: MS-DOS file generator
  8709.  
  8710.  
  8711. In response to Richard's request, here is the MS-DOS file generator that I
  8712. posted quite a while ago.  I haven't even looked at it for over a year, but
  8713. I don't suppose it has rusted.
  8714.  
  8715. It would be nice if there were some repository for tidbits like this, but I
  8716. guess the Icon project has enough else to do.
  8717.  
  8718. Paul Abrahams
  8719. abrahams%wayne-mts@um.cc.umich.edu
  8720.  
  8721. ====================================================================
  8722. # get_filename(pfn) accepts a DOS filename possibly containing wildcards.
  8723. # The filename can also include a drive letter and path.
  8724. # If the filename ends in "\" or ":", "*.*" is appended.
  8725. # The result sequence is a sequence of the filenames corresponding to pfn.
  8726.  
  8727. procedure get_filename(pfn)
  8728.     local asciiz, fnr, prefix, k, name
  8729.     local ds, dx, result, fnloc, string_block
  8730. #get Disk Transfer Address; filename locn is 30 beyond that
  8731.     result := Int86([16r21, 16r2f00] ||| list(7,0))
  8732.     fnloc := 16 * result[8] + result[3]+ 30
  8733. # get the generalized filename
  8734.     fnr := reverse(pfn)
  8735.     k := upto("\\:", fnr) | *fnr + 1
  8736.     prefix := reverse(fnr[k:0])
  8737.     name := "" ~== reverse(fnr[1:k]) | "*.*"
  8738. # Get the first file in the sequence
  8739.     asciiz := prefix || name || "\x00"
  8740.     Poke(string_block := GetSpace(*asciiz), asciiz)
  8741.     ds := string_block / 16
  8742.     dx := string_block % 16
  8743.     result := Int86([16r21, 16r4e00, 0, 0, dx, 0, 0, 0, ds])
  8744.     case result[2] of {
  8745.         0 : {}
  8746.         18 : fail
  8747.         default : stop("i/o error ", result[2])
  8748.         }
  8749.     suspend prefix || extract_name(fnloc)
  8750. # Get the remaining files in the sequence
  8751.     while Int86([16r21, 16r4f00, 0, 0, 0, 0, 0, 0, 0])[2] = 0 do
  8752.         suspend prefix || extract_name(fnloc)
  8753. end
  8754.  
  8755. procedure extract_name(fnloc)
  8756.     local asciiz
  8757.     asciiz := Peek(fnloc, 13)
  8758.     return asciiz[1:upto("\x00", asciiz)]
  8759. end
  8760.  
  8761.  
  8762. From icon-group-request@arizona.edu  Tue Sep 25 22:04:11 1990
  8763. Resent-From: icon-group-request@arizona.edu
  8764. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8765.     id AA21591; Tue, 25 Sep 90 22:04:11 -0700
  8766. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 25 Sep 90 22:02 MST
  8767. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA01852; Tue, 25 Sep 90
  8768.  21:51:18 -0700
  8769. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8770.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8771.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8772. Resent-Date: Tue, 25 Sep 90 22:03 MST
  8773. Date: 26 Sep 90 04:44:59 GMT
  8774. From: netcom!ergo@apple.com
  8775. Subject: RE: Icon pipes in MSDOS
  8776. Sender: icon-group-request@arizona.edu
  8777. Resent-To: icon-group@cs.arizona.edu
  8778. To: icon-group@arizona.edu
  8779. Resent-Message-Id: <2BC554CE84B9011C54@Arizona.edu>
  8780. Message-Id: <13829@netcom.UUCP>
  8781. Organization: UESPA
  8782. X-Envelope-To: icon-group@CS.Arizona.EDU
  8783. X-Vms-To: icon-group@Arizona.EDU
  8784. References: <0093D32B5856BB80.204002AD@mis.mcw.edu>
  8785.  
  8786. In <0093D32B5856BB80.204002AD@mis.mcw.edu> tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
  8787.  
  8788.  
  8789. >MSDOS does have pipes, but they're implemented differently than unix. MSDOS
  8790. >does it by generating scratch files. One can actually do a DIR|SORT or
  8791. >DIR | ICONX PROG. Inside icon one can issue system("dir >_dir.tmp") and
  8792. >then infile:=open("_dir.tmp") for subsequent processing. It also uses a
  8793. >little more memory when using the system command.
  8794.  
  8795. Those are *not* pipes.  They are *called* pipes, but what they really
  8796. are is a shorthand for specifying temporary files.  If they were
  8797. pipes, they would allow the two programs to execute concurrently, and
  8798. there would be no question of the "pipe" filling up the rest of the
  8799. disk volume.  As it is, each program in the pipeline has to finish
  8800. executing before the next can even start.  This makes for a lot of
  8801. inefficiency.
  8802.  
  8803. MS made it *look* like Unix commands like "find ... | grep ... | zoo ..."
  8804. also work under MS-DOS.  But for all practical purposes, they do not.
  8805.  
  8806. -- 
  8807.  
  8808. ergo@netcom.uucp            Isaac Rabinovitch
  8809. {apple,amdahl,claris}!netcom!ergo    Silicon Valley, CA
  8810.  
  8811. Collins's Law:
  8812.     If you can't make a mistake, you can't make anything.
  8813.  
  8814. Corollaries ("Rabinovitch's Rules of Sane Dialogue"):
  8815.     1. Everybody who matters is stupid now and then.
  8816.     2. If I'm being stupid, that's my problem.
  8817.     3. If my being stupid makes you stupid, that's your problem.
  8818.     4. If you think you're never stupid, boy are you stupid!
  8819.  
  8820. From goer%sophist@gargoyle.uchicago.edu  Wed Sep 26 11:33:54 1990
  8821. Resent-From: goer%sophist@gargoyle.uchicago.edu
  8822. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8823.     id AA23441; Wed, 26 Sep 90 11:33:54 -0700
  8824. Return-Path: goer@sophist.uchicago.edu
  8825. Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 11:17 MST
  8826. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  8827.  AA17607; Wed, 26 Sep 90 13:17:37 199
  8828. Received: by sophist (4.1/UofC3.1X) id AA10891; Wed, 26 Sep 90 13:21:45 CDT
  8829. Resent-Date: Wed, 26 Sep 90 11:18 MST
  8830. Date: Wed, 26 Sep 90 13:21:45 CDT
  8831. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  8832. Subject: icon #comments
  8833. Resent-To: icon-group@cs.arizona.edu
  8834. To: icon-group@arizona.edu
  8835. Resent-Message-Id: <2B5641E5BDA5400252@Arizona.edu>
  8836. Message-Id: <9009261821.AA10891@sophist>
  8837. X-Envelope-To: icon-group@CS.Arizona.EDU
  8838. X-Vms-To: icon-group@Arizona.EDU
  8839.  
  8840. Has anyone worked up an algorithm for stripping comments out of Icon
  8841. source files without having to parse every expression?  It appears
  8842. that the # shouldn't occur except in strings or csets, or as the com-
  8843. ment delineator.  If this is correct, it shouldn't be too hard to
  8844. strip them.  Is this correct?
  8845.  
  8846. -Richard
  8847.  
  8848. From ralph  Wed Sep 26 12:08:58 1990
  8849. Resent-From: "Ralph Griswold" <ralph>
  8850. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8851.     id AA25292; Wed, 26 Sep 90 12:08:58 -0700
  8852. Received: from megaron.cs.Arizona.EDU by Arizona.edu; Wed, 26 Sep 90 12:08 MST
  8853. Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15)
  8854.  via SMTP id AA25256; Wed, 26 Sep 90 12:08:12 -0700
  8855. Received: by cheltenham.cs.arizona.edu; Wed, 26 Sep 90 12:08:10 MST
  8856. Resent-Date: Wed, 26 Sep 90 12:08 MST
  8857. Date: Wed, 26 Sep 90 12:08:10 MST
  8858. From: Ralph Griswold <ralph@cs.arizona.edu>
  8859. Subject: RE:  icon #comments
  8860. Resent-To: icon-group@cs.arizona.edu
  8861. To: goer%sophist@gargoyle.uchicago.edu, icon-group@arizona.edu
  8862. Resent-Message-Id: <2B4F3D26B325400302@Arizona.edu>
  8863. Message-Id: <9009261908.AA03148@cheltenham.cs.arizona.edu>
  8864. X-Envelope-To: icon-group@CS.Arizona.EDU
  8865. X-Vms-To: goer%sophist@gargoyle.uchicago.edu, icon-group@Arizona.EDU
  8866.  
  8867. The character # can occur in string and cset literals.
  8868.  
  8869.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  8870.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  8871.  
  8872. From cjeffery  Wed Sep 26 12:15:22 1990
  8873. Resent-From: "Clinton Jeffery" <cjeffery>
  8874. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8875.     id AA25650; Wed, 26 Sep 90 12:15:22 -0700
  8876. Received: from megaron.cs.Arizona.EDU by Arizona.edu; Wed, 26 Sep 90 12:14 MST
  8877. Received: from caslon.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via
  8878.  SMTP id AA25603; Wed, 26 Sep 90 12:14:39 -0700
  8879. Received: by caslon.cs.arizona.edu; Wed, 26 Sep 90 12:14:37 -0700
  8880. Resent-Date: Wed, 26 Sep 90 12:15 MST
  8881. Date: Wed, 26 Sep 90 12:14:37 -0700
  8882. From: Clinton Jeffery <cjeffery@cs.arizona.edu>
  8883. Subject: icon #comments
  8884. Resent-To: icon-group@cs.arizona.edu
  8885. To: goer%sophist@gargoyle.uchicago.edu
  8886. Cc: icon-group@arizona.edu
  8887. Resent-Message-Id: <2B4E5A1657C5400310@Arizona.edu>
  8888. Message-Id: <9009261914.AA12171@caslon.cs.arizona.edu>
  8889. In-Reply-To: Richard Goerwitz's message of Wed, 26 Sep 90 13:21:45 CDT
  8890.  <9009261821.AA10891@sophist>
  8891. X-Envelope-To: icon-group@CS.Arizona.EDU
  8892. X-Vms-To: goer%sophist@gargoyle.uchicago.edu
  8893. X-Vms-Cc: icon-group@Arizona.EDU
  8894.  
  8895. (Richard Goerwitz asks about code to strip out comments)
  8896.  
  8897. There may be other programs in the Icon Program Library to do this, but
  8898. one comment-removal technique is exemplified in the Idol object-oriented
  8899. preprocessor.  It is not perfect, and I am always soliciting improvements.
  8900. It is characterized as a predicate for determining whether a position is
  8901. within a string or cset literal (which is useful for more than comments).
  8902.  
  8903. One interesting triviality is that it appears to use no csets.  On purpose.
  8904. Here is an extract, with an untested sample procedure main.
  8905. --
  8906. procedure main()
  8907.   while line := read() do {
  8908.     line[ 1(x<-find("#",line),notquote(line[1:x])) : 0] := ""
  8909.     write(trim(line))
  8910.   }
  8911. end
  8912. #
  8913. # tell whether the character *following* s is within a quote or not
  8914. #
  8915. procedure notquote(s)
  8916.   outs := ""
  8917.   #
  8918.   # eliminate escaped quotes.
  8919.   # this is a bug for people who write code like \"hello"...
  8920.   s ? {
  8921.     while outs ||:= tab(find("\\")+1) do move(1)
  8922.     outs ||:= tab(0)
  8923.   }
  8924.   # see if every quote has a matching endquote
  8925.   outs ? {
  8926.     while s := tab(find("\""|"'")+1) do {
  8927.     if not tab(find(s[-1])+1) then fail
  8928.     }
  8929.   }
  8930.   return
  8931. end
  8932.  
  8933.  
  8934. From goer%sophist@gargoyle.uchicago.edu  Wed Sep 26 13:01:22 1990
  8935. Resent-From: goer%sophist@gargoyle.uchicago.edu
  8936. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  8937.     id AA28647; Wed, 26 Sep 90 13:01:22 -0700
  8938. Return-Path: goer@Arizona.edu
  8939. Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 13:00 MST
  8940. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  8941.  AA00433; Wed, 26 Sep 90 14:59:52 199
  8942. Received: by sophist (4.1/UofC3.1X) id AA10950; Wed, 26 Sep 90 14:42:17 CDT
  8943. Resent-Date: Wed, 26 Sep 90 13:00 MST
  8944. Date: Wed, 26 Sep 90 14:42:17 CDT
  8945. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  8946. Subject: stripping #comments
  8947. Resent-To: icon-group@cs.arizona.edu
  8948. To: icon-group@arizona.edu
  8949. Resent-Message-Id: <2B47EFB790C5400384@Arizona.edu>
  8950. Message-Id: <9009261942.AA10950@sophist>
  8951. X-Envelope-To: icon-group@CS.Arizona.EDU
  8952. X-Vms-To: icon-group@Arizona.EDU
  8953.  
  8954. Ralph@cs.arizona.edu tells me that
  8955.  
  8956.     [t]he character # can occur in string and cset literals.
  8957.  
  8958. Okay, that helps me a lot.  If it only occurs in string and cset
  8959. literals, and as the comment delineator, I should be able to strip
  8960. out comments by counting " and '.  I don't see how this can be done
  8961. elegantly using bal.
  8962.  
  8963. -Richard
  8964.  
  8965.  
  8966. -------------------------------------------------------------------
  8967.  
  8968. procedure main()
  8969.      every write(strip_comments(!&input))
  8970. end
  8971.  
  8972.  
  8973.  
  8974. procedure strip_comments(s)
  8975.  
  8976.     #  Strip trailing, leading whitespace, and all comments, from
  8977.     #  string s (where s is a line from a .icn source file).
  8978.  
  8979.     local i, j
  8980.  
  8981.     s ?:= (tab(many(' \t')), tab(0))
  8982.     s ? {
  8983.     match("#") & fail
  8984.     (s2 <- tab(find("#"))) ? {
  8985.         i := j := 0
  8986.         while tab(upto('"\'')) do {
  8987.         case move(1) of {
  8988.             "\""    : {
  8989.             i +:= 1
  8990.             if tab(find("\"")+1)
  8991.             then i +:= 1
  8992.             else tab(find("\'")+1) | break
  8993.             }
  8994.             "\'"    : {
  8995.             j +:= 1
  8996.             if tab(find("\'")+1)
  8997.             then j +:= 1
  8998.             else tab(find("\"")+1) | break
  8999.             }
  9000.         }
  9001.         }
  9002.         i % 2 = 0 & j % 2 = 0
  9003.     }
  9004.     return "" ~== trim((\s2 | .&subject) \ 1, ' \t')
  9005.     }
  9006.  
  9007. end
  9008.  
  9009. From goer%sophist@gargoyle.uchicago.edu  Wed Sep 26 13:10:39 1990
  9010. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9011. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9012.     id AA29316; Wed, 26 Sep 90 13:10:39 -0700
  9013. Return-Path: goer@sophist.uchicago.edu
  9014. Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 13:09 MST
  9015. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  9016.  AA00780; Wed, 26 Sep 90 15:09:38 199
  9017. Received: by sophist (4.1/UofC3.1X) id AA10962; Wed, 26 Sep 90 15:13:45 CDT
  9018. Resent-Date: Wed, 26 Sep 90 13:10 MST
  9019. Date: Wed, 26 Sep 90 15:13:45 CDT
  9020. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9021. Subject: more #comments
  9022. Resent-To: icon-group@cs.arizona.edu
  9023. To: icon-group@arizona.edu
  9024. Resent-Message-Id: <2B46A0B711454003A4@Arizona.edu>
  9025. Message-Id: <9009262013.AA10962@sophist>
  9026. X-Envelope-To: icon-group@CS.Arizona.EDU
  9027. X-Vms-To: icon-group@Arizona.EDU
  9028.  
  9029.  
  9030. Okay, I admit that my routine wouldn't handle "hello\"" properly,
  9031. either.  It's pretty simple to modify it so that it will:
  9032.  
  9033.  
  9034. ------------------------------------------------------------------
  9035.  
  9036. procedure main()
  9037.      every write(strip_comments(!&input))
  9038. end
  9039.  
  9040.  
  9041.  
  9042. procedure strip_comments(s)
  9043.  
  9044.     # Commented-out portions of Icon code - strip 'em.
  9045.  
  9046.     local i, j, c, looking_for
  9047.  
  9048.     s ?:= (tab(many(' \t')), tab(0))
  9049.     s ? {
  9050.     match("#") & fail
  9051.     (s2 <- tab(find("#"))) ? {
  9052.         i := j := 0
  9053.         looking_for := "\"\'"
  9054.         while c := move(1) do {
  9055.         case c of {
  9056.             "\\"    : {
  9057.             move(1); next
  9058.             }
  9059.             "\""    : {
  9060.             if find(c,looking_for) & i +:= 1
  9061.             then looking_for := (looking_for ~== "\"") | "\"\'"
  9062.             }
  9063.             "\'"    : {
  9064.             if find(c,looking_for) & j +:= 1
  9065.             then looking_for := (looking_for ~== "\'") | "\"\'"
  9066.             }
  9067.         }
  9068.         }
  9069.         i % 2 = 0 & j % 2 = 0
  9070.     }
  9071.     return "" ~== trim((\s2 | .&subject) \ 1, ' \t')
  9072.     }
  9073.  
  9074. end
  9075.  
  9076. From metaphor!laguna.metaphor.com!alex@decwrl.dec.com  Wed Sep 26 13:54:06 1990
  9077. Received: from decwrl.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  9078.     id AA01376; Wed, 26 Sep 90 13:54:06 -0700
  9079. Received: by decwrl.dec.com; id AA02780; Wed, 26 Sep 90 13:53:57 -0700
  9080. Received: from laguna.Metaphor.COM by metaphor.com (3.2/SMI-3.2)
  9081.     id AA18776; Wed, 26 Sep 90 13:34:01 PDT
  9082. Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
  9083.     id AA01364; Wed, 26 Sep 90 13:33:19 PDT
  9084. Date: Wed, 26 Sep 90 13:33:19 PDT
  9085. From: metaphor!laguna.metaphor.com!alex@decwrl.dec.com (Bob Alexander)
  9086. Message-Id: <9009262033.AA01364@laguna.Metaphor.COM>
  9087. To: icon-group@cs.arizona.edu
  9088. Subject: Stripping comments
  9089.  
  9090. Here's a routine I just whipped up.  I tested it some but don't have
  9091. complete confidence in it.  Comments? (pun intended)
  9092.  
  9093. procedure trimcomment(s1) # s2
  9094.    local c,delim
  9095.    s1 ? {
  9096.       while tab(upto('"\'\\#')) do {
  9097.          case c := move(1) of {
  9098.             !"\"'": {
  9099.                delim := if \delim then {
  9100.                   if delim == c then &null
  9101.                   }
  9102.                else c
  9103.                }
  9104.             "\\": if \delim then ="^" & move(1)   # in case he used "\^'"
  9105.             "#": if /delim then return trim(&subject[1:&pos - 1])
  9106.             }
  9107.          }
  9108.       }
  9109.    return trim(s1)
  9110. end
  9111.  
  9112. -- Bob Alexander
  9113.  
  9114. Metaphor Computer Systems   (415) 961-3600 x751   alex@metaphor.com
  9115. ====^=== Mountain View, CA  ...{uunet}!{decwrl,apple}!metaphor!alex
  9116.  
  9117. From metaphor!laguna.metaphor.com!alex@decwrl.dec.com  Wed Sep 26 14:33:40 1990
  9118. Received: from decwrl.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  9119.     id AA03549; Wed, 26 Sep 90 14:33:40 -0700
  9120. Received: by decwrl.dec.com; id AA08035; Wed, 26 Sep 90 14:33:15 -0700
  9121. Received: from laguna.Metaphor.COM by metaphor.com (3.2/SMI-3.2)
  9122.     id AA19746; Wed, 26 Sep 90 14:23:42 PDT
  9123. Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
  9124.     id AA01446; Wed, 26 Sep 90 14:22:59 PDT
  9125. Date: Wed, 26 Sep 90 14:22:59 PDT
  9126. From: metaphor!laguna.metaphor.com!alex@decwrl.dec.com (Bob Alexander)
  9127. Message-Id: <9009262122.AA01446@laguna.Metaphor.COM>
  9128. To: icon-group@cs.arizona.edu
  9129. Subject: 1st bug in comment stripper
  9130.  
  9131. I *knew* I should let this routine age for a couple of days before
  9132. posting it!  It couldn't handle "abc\"def". First bug fix (with a bit
  9133. of vertical compactification, and other misc changes):
  9134.  
  9135. procedure trimcomment(s1) # s2
  9136. #
  9137. #  Trim comments (and any trailing spaces) from Icon program text line.
  9138. #
  9139.    local c,delim
  9140.    s1 ? {
  9141.       while tab(upto('"\'\\#')) do {
  9142.          case c := move(1) of {
  9143.             "#": if /delim then return trim(&subject[1:&pos - 1],' \t')
  9144.             "\\": if \delim then {="^" ; move(1)}   # in case he used "\^""
  9145.             default: delim := if \delim then (if delim == c then &null) else c
  9146.             }
  9147.          }
  9148.       }
  9149.    return trim(s1,' \t')
  9150. end
  9151.  
  9152.  
  9153. -- Bob Alexander
  9154.  
  9155. Metaphor Computer Systems   (415) 961-3600 x751   alex@metaphor.com
  9156. ====^=== Mountain View, CA  ...{uunet}!{decwrl,apple}!metaphor!alex
  9157.  
  9158.  
  9159. From goer%sophist@gargoyle.uchicago.edu  Wed Sep 26 19:41:07 1990
  9160. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9161. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9162.     id AA17222; Wed, 26 Sep 90 19:41:07 -0700
  9163. Return-Path: goer@sophist.uchicago.edu
  9164. Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 19:40 MST
  9165. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  9166.  AA11612; Wed, 26 Sep 90 21:40:30 199
  9167. Received: by sophist (4.1/UofC3.1X) id AA11488; Wed, 26 Sep 90 21:44:37 CDT
  9168. Resent-Date: Wed, 26 Sep 90 19:40 MST
  9169. Date: Wed, 26 Sep 90 21:44:37 CDT
  9170. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9171. Subject: trimming comments
  9172. Resent-To: icon-group@cs.arizona.edu
  9173. To: icon-group@arizona.edu
  9174. Resent-Message-Id: <2B10123E80A5400853@Arizona.edu>
  9175. Message-Id: <9009270244.AA11488@sophist>
  9176. X-Envelope-To: icon-group@CS.Arizona.EDU
  9177. X-Vms-To: icon-group@Arizona.EDU
  9178.  
  9179. Thanks everyone for the help with stripping out comments.  I
  9180. kinda synthesized all the postings and came up with the procedure
  9181. appended below.  Note that it now runs faster than any of the
  9182. previous postings people (including me) have made:
  9183.  
  9184. procedure strip_comments(s)
  9185.  
  9186.     #######
  9187.     #
  9188.     # Commented-out portions of Icon code - strip 'em.  Fails on lines
  9189.     # which, either stripped or otherwise, come out as an empty string.
  9190.     #
  9191.     # I'd expect strip_comments to be used typically as follows:
  9192.     #
  9193.     #     every write(strip_comments(!&input))
  9194.     #
  9195.     #######
  9196.  
  9197.     local i, j, c, c2
  9198.  
  9199.     s ? {
  9200.     tab(many(' \t'))
  9201.     match("#") & fail
  9202.     (s2 <- tab(find("#"))) ? {
  9203.         c2 := &null
  9204.         while tab(upto('\\"\'')) do {
  9205.         case c := move(1) of {
  9206.             "\\"   : {
  9207.             if match("^")
  9208.             then move(2)
  9209.             else move(1)
  9210.             }
  9211.             default: {
  9212.             if \c2
  9213.             then (c == c2, c2 := &null)
  9214.             else c2 := c
  9215.             }
  9216.         }
  9217.         }
  9218.         /c2
  9219.     }
  9220.     return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
  9221.     }
  9222.  
  9223. end
  9224.  
  9225.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  9226.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  9227.  
  9228. From tenaglia@mis.mcw.edu  Thu Sep 27 02:22:35 1990
  9229. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  9230.     id AA29993; Thu, 27 Sep 90 02:22:35 -0700
  9231. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  9232.     id AA21172; Thu, 27 Sep 90 04:27:30 EDT
  9233. Received: by uwm.edu; id AA08961; Wed, 26 Sep 90 18:27:55 -0500
  9234. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  9235.           Wed, 26 Sep 90 17:29:36 CDT
  9236. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  9237.           Wed, 26 Sep 90 16:35:22 CDT
  9238. Date: Wed, 26 Sep 90 16:35:22 CDT
  9239. Message-Id: <0093D4D603B5C380.204000C3@mis.mcw.edu>
  9240. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  9241. Subject: MSDOS Icon
  9242. To: icon-group@cs.arizona.edu
  9243.  
  9244.  
  9245. As a matter of fact I do my serious Icon development on a VAX. I do have
  9246. it on a pc or 2 as a filtering tool. I prefer Icon 5.9 which uses less
  9247. memory, and also DOS 3.1 or 3.3. While Icon 5.9 is missing some of the
  9248. latest goodies, it's just fine as long as I don't need interupts or getch.
  9249. I've even written a kind of unix shell environment in it. It has a form
  9250. of about 50 unixlike commands, translates \ to / for the paths, has a
  9251. login program written in compiled basic, and some other things. Mostly
  9252. it reads unix commands and reformats them to DOS with system(). It won't
  9253. work with recent versions of icon because of memory limits, but 5.9
  9254. does fit. Granted, it's not 'real', but it was a fun little project.
  9255.  
  9256. Any ideas about having the DOS version do swapping to reclaim memory,
  9257. maybe as an option with garbage collection. Also make iconx smarter
  9258. so one icon program could run another without reloading iconx.exe into
  9259. memory.
  9260.  
  9261. Oh well, pardon my frothing. I guess I just have a big imagination
  9262.  
  9263. Chris Tenaglia (System Manager)
  9264. Medical College of Wisconsin
  9265. 8701 W. Watertown Plank Rd.
  9266. Milwaukee, WI 53226
  9267. (414)257-8765
  9268. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  9269.  
  9270.  
  9271.  
  9272. From tenaglia@mis.mcw.edu  Thu Sep 27 13:37:38 1990
  9273. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  9274.     id AA01582; Thu, 27 Sep 90 13:37:38 -0700
  9275. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  9276.     id AA08301; Thu, 27 Sep 90 16:03:18 EDT
  9277. Received: by uwm.edu; id AA29656; Thu, 27 Sep 90 09:15:37 -0500
  9278. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  9279.           Thu, 27 Sep 90 08:47:53 CDT
  9280. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  9281.           Thu, 27 Sep 90 08:33:59 CDT
  9282. Date: Thu, 27 Sep 90 08:33:59 CDT
  9283. Message-Id: <0093D55BEE372CC0.204002CF@mis.mcw.edu>
  9284. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  9285. Subject: Uncommenting
  9286. To: icon-group@cs.arizona.edu
  9287.  
  9288.  
  9289. Uncommenting is a fascinating problem. It probably is important to compiler
  9290. writers. But for normal programming, I think one would want to add comments.
  9291.  
  9292. Anyway I've been watching the algorythms getting thorougher. Has anybody
  9293. thought about the pathological split line literal?
  9294.            
  9295.            tmp := []
  9296.            while find("\"567_
  9297.                  #934.\355\\\'",read()) do # Unbelievable isn't it
  9298.                     put(tmp,"Field_1_
  9299.                         _78\'#\\\"YYY_
  9300.                         Continuing_String_
  9301.                         Literally_Pathetic#")  # \\ "ack!" #\\
  9302.  
  9303. Granted, who would write an expression so pathetic, except to try to break
  9304. a parser. Food for thought and icon hackers.
  9305.  
  9306. Chris Tenaglia (System Manager)
  9307. Medical College of Wisconsin
  9308. 8701 W. Watertown Plank Rd.
  9309. Milwaukee, WI 53226
  9310. (414)257-8765
  9311. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  9312.  
  9313.  
  9314. From goer%sophist@gargoyle.uchicago.edu  Thu Sep 27 14:51:58 1990
  9315. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9316. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9317.     id AA05410; Thu, 27 Sep 90 14:51:58 -0700
  9318. Return-Path: goer@sophist.uchicago.edu
  9319. Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 27 Sep 90 14:51 MST
  9320. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  9321.  AA17586; Thu, 27 Sep 90 16:51:02 199
  9322. Received: by sophist (4.1/UofC3.1X) id AA11909; Thu, 27 Sep 90 16:55:09 CDT
  9323. Resent-Date: Thu, 27 Sep 90 14:51 MST
  9324. Date: Thu, 27 Sep 90 16:55:09 CDT
  9325. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9326. Subject: line splits & uncommenting
  9327. Resent-To: icon-group@cs.arizona.edu
  9328. To: icon-group@arizona.edu
  9329. Resent-Message-Id: <2A6F55B8BFA9401024@Arizona.edu>
  9330. Message-Id: <9009272155.AA11909@sophist>
  9331. X-Envelope-To: icon-group@CS.Arizona.EDU
  9332. X-Vms-To: icon-group@Arizona.EDU
  9333.  
  9334.     Has anybody thought about the pathological split line literal?
  9335.                
  9336.                tmp := []
  9337.                while find("\"567_
  9338.                      #934.\355\\\'",read()) do # Unbelievable isn't it
  9339.                         put(tmp,"Field_1_
  9340.                             _78\'#\\\"YYY_
  9341.                             Continuing_String_
  9342.                             Literally_Pathetic#")  # \\ "ack!" #\\
  9343.  
  9344. I confess that I hadn't thought about the split-line literal.  I don't
  9345. use them myself, and generally don't like the look of code that does.
  9346. That's no excuse, though.
  9347.  
  9348. BTW, do you have a solution in mind?
  9349.  
  9350. We know that the underscore has to be the last thing on the line, except
  9351. for whitespace and comments.  I'll bet it would be possible to modify the
  9352. procedures posted so that they look, not only for " and ' and \, but also
  9353. _.  If the underscore is encountered, then you could tab past any spaces
  9354. and newlines (if present), and if either pos(0) or match("#") succeed,
  9355. then abort all attempts at ' and "-matching, and return &subject[1:&pos].
  9356.  
  9357. Just an off-the-cuff guess.  If anyone cleans up our collective postings
  9358. and makes the _ thing work, could he or she please re-post the resulting
  9359. procedure?
  9360.  
  9361. -Richard
  9362.  
  9363. /
  9364.  
  9365. From goer%sophist@gargoyle.uchicago.edu  Thu Sep 27 15:09:59 1990
  9366. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9367. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9368.     id AA06603; Thu, 27 Sep 90 15:09:59 -0700
  9369. Return-Path: goer@sophist.uchicago.edu
  9370. Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 27 Sep 90 15:09 MST
  9371. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  9372.  AA18014; Thu, 27 Sep 90 17:09:20 199
  9373. Received: by sophist (4.1/UofC3.1X) id AA11929; Thu, 27 Sep 90 17:13:26 CDT
  9374. Resent-Date: Thu, 27 Sep 90 15:09 MST
  9375. Date: Thu, 27 Sep 90 17:13:26 CDT
  9376. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9377. Subject: write("hel_
  9378. Resent-To: icon-group@cs.arizona.edu
  9379. To: icon-group@arizona.edu
  9380. Resent-Message-Id: <2A6CC8C3C429400FC7@Arizona.edu>
  9381. Message-Id: <9009272213.AA11929@sophist>
  9382. X-Envelope-To: icon-group@CS.Arizona.EDU
  9383. X-Vms-To: icon-group@Arizona.EDU
  9384.  
  9385.  
  9386. I just tried compiling
  9387.  
  9388.     write("hel_   # this is a partial comment
  9389.           lo")
  9390.  
  9391. and it didn't work.  It seems obvious why.  What a nightmare to parse!
  9392. Anyway, that makes our comment-stripping that much easier.  How about
  9393. something like:
  9394.  
  9395. procedure strip_comments(s)
  9396.  
  9397.     #######
  9398.     #
  9399.     # Commented-out portions of Icon code - strip 'em.  Fails on lines
  9400.     # which, either stripped or otherwise, come out as an empty string.
  9401.     #
  9402.     # I'd expect strip_comments to be used typically as follows:
  9403.     #
  9404.     #     every write(strip_comments(!&input))
  9405.     #
  9406.     #######
  9407.  
  9408.     local i, j, c, c2
  9409.  
  9410.     s ? {
  9411.     tab(many(' \t'))
  9412.         find("#") | (return trim(tab(0),' \t'))
  9413.     match("#") & fail
  9414.     (s2 <- tab(find("#"))) ? {
  9415.         c2 := &null
  9416.         while tab(upto('_\\"\'')) do {
  9417.         case c := move(1) of {
  9418.             "\\"   : {
  9419.             if match("^")
  9420.             then move(2)
  9421.             else move(1)
  9422.             }
  9423.             "_"    : {
  9424.             if c2 == "\"" &
  9425.                tab(many(' \t')) | &null &
  9426.                pos(0)
  9427.             then return trim(&subject, ' \t')
  9428.             }
  9429.             default: {
  9430.             if \c2
  9431.             then (c == c2, c2 := &null)
  9432.             else c2 := c
  9433.             }
  9434.         }
  9435.         }
  9436.         /c2
  9437.     }
  9438.     return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
  9439.     }
  9440.  
  9441. end
  9442.  
  9443.  
  9444.     -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  9445.     goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  9446.  
  9447. From metaphor!laguna.metaphor.com!alex@decwrl.dec.com  Thu Sep 27 16:08:51 1990
  9448. Received: from decwrl.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  9449.     id AA09333; Thu, 27 Sep 90 16:08:51 -0700
  9450. Received: by decwrl.dec.com; id AA02796; Thu, 27 Sep 90 16:08:43 -0700
  9451. Received: from laguna.Metaphor.COM by metaphor.com (3.2/SMI-3.2)
  9452.     id AA27431; Thu, 27 Sep 90 15:38:05 PDT
  9453. Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
  9454.     id AA02317; Thu, 27 Sep 90 15:37:22 PDT
  9455. Date: Thu, 27 Sep 90 15:37:22 PDT
  9456. From: metaphor!laguna.metaphor.com!alex@decwrl.dec.com (Bob Alexander)
  9457. Message-Id: <9009272237.AA02317@laguna.Metaphor.COM>
  9458. To: icon-group@cs.arizona.edu
  9459. Subject: Re:  line splits & uncommenting
  9460.  
  9461. Wow -- the problems and solutions are coming in faster than I can
  9462. formulate a reply!  Have to learn to type (and think) faster.
  9463.  
  9464. Another possible solution to the split-string-literal problem is simply
  9465. to make the variable that remembers the string literal delimiter
  9466. persistant (static or global).  Using as an example the version I
  9467. previously posted, "delim" is the variable in question.  The results
  9468. could be very wierd if the input program contains certain syntax
  9469. errors.
  9470.  
  9471. procedure trimcomment(s1) # s2
  9472. #
  9473. #  Trim comments (and any trailing spaces) from Icon program text line "s1".
  9474. #
  9475.    static delim
  9476.    local c
  9477.    s1 ? {
  9478.       while tab(upto('"\'\\#')) do {
  9479.          case c := move(1) of {
  9480.             "#": if /delim then return trim(&subject[1:&pos - 1],' \t')
  9481.             "\\": if \delim then {="^" ; move(1)}   # in case he used "\^""
  9482.             default: delim := if \delim then (if delim == c then &null) else c
  9483.             }
  9484.          }
  9485.       }
  9486.    return trim(s1,' \t')
  9487. end
  9488.  
  9489. -- Bob Alexander
  9490.  
  9491. Metaphor Computer Systems   (415) 961-3600 x751   alex@metaphor.com
  9492. ====^=== Mountain View, CA  ...{uunet}!{decwrl,apple}!metaphor!alex
  9493.  
  9494.  
  9495. From goer%sophist@gargoyle.uchicago.edu  Fri Sep 28 04:29:06 1990
  9496. Resent-From: goer%sophist@gargoyle.uchicago.edu
  9497. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  9498.     id AA05479; Fri, 28 Sep 90 04:29:06 -0700
  9499. Return-Path: goer@sophist.uchicago.edu
  9500. Received: from gargoyle.uchicago.edu by Arizona.edu; Fri, 28 Sep 90 04:28 MST
  9501. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  9502.  AA12747; Fri, 28 Sep 90 05:41:56 199
  9503. Received: by sophist (4.1/UofC3.1X) id AA12149; Fri, 28 Sep 90 05:46:01 CDT
  9504. Resent-Date: Fri, 28 Sep 90 04:28 MST
  9505. Date: Fri, 28 Sep 90 05:46:01 CDT
  9506. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  9507. Subject: test posting of a strange program
  9508. Resent-To: icon-group@cs.arizona.edu
  9509. To: icon-group@arizona.edu
  9510. Resent-Message-Id: <29FD26AE14C9401003@Arizona.edu>
  9511. Message-Id: <9009281046.AA12149@sophist>
  9512. X-Envelope-To: icon-group@CS.Arizona.EDU
  9513. X-Vms-To: icon-group@Arizona.EDU
  9514.  
  9515.  
  9516. This is a test posting of a strange program.  Essentially, it takes
  9517. a source file, finds all procedure calls in it, looks for those pro-
  9518. cedure calls which are not a part of the source file itself in the
  9519. IPL (or in any directories you tell it to), then fetches those rou-
  9520. tines that it needs, writing the original source file and the neces-
  9521. sary library routines to the standard output.
  9522.  
  9523. Frequently I forget what file an IPL routine is in.  And there is
  9524. almost always stuff I don't want to link in present with the routines
  9525. that I do.  This program handles most of the hunting and pecking by
  9526. itself.
  9527.  
  9528. It's pretty slow right now, and probably won't work on anything but
  9529. Unix.  It might work under MS-DOS.  I don't know.  It's also been used
  9530. by me alone, and hasn't gone through any rigouous testing procedure.
  9531.  
  9532. I hope that others will fool with the code, as I will surely do, and
  9533. make this thing a bit more refined.  Comments are sparse at present.
  9534. This will doubtless change as I read it over more, and get comments
  9535. from brave souls who have tried it out.
  9536.  
  9537. -Richard
  9538.  
  9539. ---- Cut Here and feed the following to sh ----
  9540. #!/bin/sh
  9541. # This is a shell archive (produced by shar 3.49)
  9542. # To extract the files from this archive, save it to a file, remove
  9543. # everything above the "!/bin/sh" line above, and type "sh file_name".
  9544. #
  9545. # made 09/28/1990 10:26 UTC by goer@sophist.uchicago.edu
  9546. # Source directory /u/richard/Tmp
  9547. #
  9548. # existing files will NOT be overwritten unless -c is specified
  9549. # This format requires very little intelligence at unshar time.
  9550. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  9551. #
  9552. #                                                                          
  9553. #                                                                          
  9554. #
  9555. # This shar contains:
  9556. # length  mode       name
  9557. # ------ ---------- ------------------------------------------
  9558. #    269 -rw-r--r-- Makefile
  9559. #   1815 -rw-r--r-- README
  9560. #   3096 -rw-r--r-- getcalls.icn
  9561. #   3211 -rw-r--r-- getnames.icn
  9562. #    549 -rw-r--r-- getpaths.icn
  9563. #   1585 -rw-r--r-- getprocs.icn
  9564. #   3250 -rw-r--r-- main.icn
  9565. #    950 -rw-r--r-- stripcom.icn
  9566. #
  9567. if test -r _shar_seq_.tmp; then
  9568.     echo 'Must unpack archives in sequence!'
  9569.     echo Please unpack part `cat _shar_seq_.tmp` next
  9570.     exit 1
  9571. fi
  9572. # ============= Makefile ==============
  9573. if test -f 'Makefile' -a X"$1" != X"-c"; then
  9574.     echo 'x - skipping Makefile (File already exists)'
  9575.     rm -f _shar_wnt_.tmp
  9576. else
  9577. > _shar_wnt_.tmp
  9578. echo 'x - extracting Makefile (Text)'
  9579. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  9580. Ximerge:
  9581. X    icont -Sc 300 -o imerge getcalls.icn getnames.icn \
  9582. X        getpaths.icn getprocs.icn main.icn stripcom.icn
  9583. X
  9584. Xshar:
  9585. X    shar -fVc -oimerge -L23 -sgoer@sophist.uchicago.edu Makefile \
  9586. X        README getcalls.icn getnames.icn getpaths.icn getprocs.icn \
  9587. X        main.icn stripcom.icn
  9588. SHAR_EOF
  9589. true || echo 'restore of Makefile failed'
  9590. rm -f _shar_wnt_.tmp
  9591. fi
  9592. # ============= README ==============
  9593. if test -f 'README' -a X"$1" != X"-c"; then
  9594.     echo 'x - skipping README (File already exists)'
  9595.     rm -f _shar_wnt_.tmp
  9596. else
  9597. > _shar_wnt_.tmp
  9598. echo 'x - extracting README (Text)'
  9599. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  9600. XImerge simply merges the correct routines from the IPL, and from any
  9601. Xother directories you supply, into a given source file.  Often a given
  9602. XIPL file will have several procedures - not all of which are needed
  9603. Xin order to compile a given program.  Imerge obviates the need for
  9604. Xlinking in the entire library.
  9605. X
  9606. XUsage is
  9607. X
  9608. X    imerge sourcefile [libdirectories]
  9609. X
  9610. Xwhere sourcefile refers to an icon source code file, and libdirectories
  9611. Xis a space-separated list of directories in which .icn files containing
  9612. Xroutines needed by sourcefile are likely to be found.
  9613. X
  9614. XYou can remove the need to specify any directories on the command line
  9615. Xby setting the value of ILIBS in your environment to a space or colon-
  9616. Xseparated string of directory names.
  9617. X
  9618. XImerge writes to the standard output.  Slowly.  Bear with it, and it will
  9619. Xnormally do a pretty decent job.  Watch the end of the file for a report
  9620. Xof procedures not found (you'll have to go find them, and either link
  9621. Xthem in by hand, or add the directory they are in to the ILIBS variable).
  9622. X
  9623. XNOTE WELL:  This is pretty much untested on anything but Unix.  It might
  9624. Xrun under MS-DOS.  I simply don't know.  It certainly won't run under
  9625. Xanything else (although it could easily be modified to do so).  Note that
  9626. Xeven under Unix, this program has not been given a long-term workout, and
  9627. XI expect that many bugs will turn up....
  9628. X
  9629. XKNOWN BUGS:  Naming conflicts cannot be resolved.  Make sure no duplicate
  9630. Xnames exist for procedures in your libraries.  Also, the parsing algorithm
  9631. Xdoesn't handle the line-final underscore notation for string literals.
  9632. XFinally, indirect procedure invocations, such as a := b; a(), where b is
  9633. Xa global procedure name are not handled properly, though the resulting
  9634. Xfile should compile fine, assuming a() is not defined somewhere in a
  9635. Xlibrary file.
  9636. X
  9637. X-Richard
  9638. SHAR_EOF
  9639. true || echo 'restore of README failed'
  9640. rm -f _shar_wnt_.tmp
  9641. fi
  9642. # ============= getcalls.icn ==============
  9643. if test -f 'getcalls.icn' -a X"$1" != X"-c"; then
  9644.     echo 'x - skipping getcalls.icn (File already exists)'
  9645.     rm -f _shar_wnt_.tmp
  9646. else
  9647. > _shar_wnt_.tmp
  9648. echo 'x - extracting getcalls.icn (Text)'
  9649. sed 's/^X//' << 'SHAR_EOF' > 'getcalls.icn' &&
  9650. Xprocedure get_procedure_calls(line)
  9651. X
  9652. X    # Looks for non-builtin procedure calls in line.  Returns nothing
  9653. X    # until called without an argument, in which case it returns the
  9654. X    # accumulated set of procedure names found in the "line"s read so
  9655. X    # far.  When next invoked, get_procedure_calls starts with a fresh
  9656. X    # (i.e. freshly emptied) set.
  9657. X
  9658. X    local external_procedures
  9659. X    static keywords, builtins, wchars, procedures_called
  9660. X    initial {
  9661. X    wchars := &ucase ++ &lcase ++ &digits ++ '_'
  9662. X    keywords := set(
  9663. X        ["break","by","case","default","do","dynamic","else","end",
  9664. X        "every","fail","global","if","initial","link","local",
  9665. X        "next","not","of","procedure","record","repeat","return",
  9666. X        "static","suspend","then","to","until","while"])
  9667. X    builtins := set(
  9668. X        ["abs","acos","any","args","asin","bal","char",
  9669. X         "center","close","copy","collect","cos","cset","delete",
  9670. X         "detab","display","dtor","entab","exit","exp","find","get",
  9671. X         "getenv","iand","icom","ior","image","insert","integer",
  9672. X         "ishift","ixor","key","left","list","log","getch",
  9673. X         "getche","kbhit","main","many","map","match","member",
  9674. X         "move","name","numeric","open","ord","pop","pos",
  9675. X         "pull","push","put","read","reads","real","remove",
  9676. X         "rename","repl","reverse","right","rtod","seek","set",
  9677. X         "sin","sort","sqrt","stop","string","system","tab",
  9678. X         "table","trim","type","upto","variable","where",
  9679. X         "write","writes"])
  9680. X    procedures_called := set()
  9681. X    }
  9682. X
  9683. X    strip_comments(\line) ? {
  9684. X    while tab(upto_balanced(wchars)) do {
  9685. X        BEGIN := &pos
  9686. X        id := tab(many(wchars))
  9687. X        # Record constructors look like procedure invocations.
  9688. X        # Make the names of records like builtin function names.
  9689. X        if id == "record" then {
  9690. X        if tab(many(' \t')) & id := tab(many(wchars)) then
  9691. X            insert(builtins, id)
  9692. X        else break    # give up, bad code
  9693. X        }
  9694. X        # Make sure with "procedure proc1(arguments)" that proc1
  9695. X        # doesn't get taken as an invocation of proc1!
  9696. X        else if id == "procedure" then {
  9697. X        if not (tab(many(' \t')) & tab(many(wchars)))
  9698. X        then break    # give up, bad code
  9699. X        }
  9700. X        else {
  9701. X        tab(many(" \t"))
  9702. X        if tab(match("(")) then {
  9703. X            integer(id) & next
  9704. X            # Reject id if it is a keyword or builtin function
  9705. X            if member(keywords | builtins, id) then next
  9706. X            else {
  9707. X            # Conceivably, we could have rec.field(args)
  9708. X            if match(".",line,BEGIN -1) then next
  9709. X            else insert(procedures_called, id)
  9710. X            # Doesn't account for (proc1|proc2)(arguments)
  9711. X            }
  9712. X        }
  9713. X        }
  9714. X    }
  9715. X    }
  9716. X
  9717. X    if /line then {
  9718. X    external_procedures := (procedures_called -- builtins) -- keywords
  9719. X    procedures_called := set()
  9720. X    return external_procedures
  9721. X    }    
  9722. X
  9723. Xend
  9724. X
  9725. X
  9726. X
  9727. Xprocedure upto_balanced(cs)
  9728. X
  9729. X    local s2, c, c2, POS
  9730. X
  9731. X    &subject[.&pos:0] ? {
  9732. X    tab(upto(cs)) ? {
  9733. X        c2 := &null
  9734. X        while tab(upto('\\"\'')) do {
  9735. X        case c := move(1) of {
  9736. X            "\\"   : {
  9737. X            if match("^")
  9738. X            then move(2)
  9739. X            else move(1)
  9740. X            }
  9741. X            default: {
  9742. X            if \c2
  9743. X            then (c == c2, c2 := &null)
  9744. X            else c2 := c
  9745. X            }
  9746. X        }
  9747. X        }
  9748. X        /c2
  9749. X    } & POS := &pos
  9750. X    }
  9751. X
  9752. X    return &pos + \POS - 1
  9753. X
  9754. Xend
  9755. SHAR_EOF
  9756. true || echo 'restore of getcalls.icn failed'
  9757. rm -f _shar_wnt_.tmp
  9758. fi
  9759. # ============= getnames.icn ==============
  9760. if test -f 'getnames.icn' -a X"$1" != X"-c"; then
  9761.     echo 'x - skipping getnames.icn (File already exists)'
  9762.     rm -f _shar_wnt_.tmp
  9763. else
  9764. > _shar_wnt_.tmp
  9765. echo 'x - extracting getnames.icn (Text)'
  9766. sed 's/^X//' << 'SHAR_EOF' > 'getnames.icn' &&
  9767. Xprocedure get_ipl_names(lib_paths)
  9768. X
  9769. X    local procedure_stat_list
  9770. X    static get_dir
  9771. X    initial get_dir := set_getdir_by_os()
  9772. X
  9773. X    procedure_stat_list := list()
  9774. X    # Run through every possible path in which files might be found,
  9775. X    # and get a list of procedures contained in those files.
  9776. X    every procedure_stat_list |||:= get_dir(!lib_paths)
  9777. X
  9778. X    return procedure_stat_list
  9779. X
  9780. Xend
  9781. X
  9782. X
  9783. X
  9784. X
  9785. Xprocedure set_getdir_by_os()
  9786. X
  9787. X    if find("UNIX", &features)
  9788. X    then return unix_get_dir
  9789. X    else if find("MS-DOS", &features)
  9790. X    then return msdos_get_dir
  9791. X    else stop("Your operating system is not (yet) supported.")
  9792. X
  9793. Xend
  9794. X
  9795. X
  9796. X
  9797. Xprocedure msdos_get_dir(dir)
  9798. X
  9799. X    # Returns a sorted list of all filenames (full paths included) in
  9800. X    # directory "dir."  The list is sorted.  Fails on invalid or empty
  9801. X    # directory.  Aborts if temp file cannot be opened.
  9802. X    #
  9803. X    # Temp files can be directed to one or another directory either by
  9804. X    # manually setting the variable temp_dir below, or by setting the
  9805. X    # value of the environment variable TEMPDIR to an appropriate
  9806. X    # directory name.
  9807. X
  9808. X    local in_dir, filename_list, line
  9809. X    static temp_dir
  9810. X    initial {
  9811. X        temp_dir := 
  9812. X            (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
  9813. X                ".\\"
  9814. X    }
  9815. X
  9816. X    # Get name of tempfile to be used.
  9817. X    temp_name := get_dos_tempname(temp_dir) |
  9818. X    stop("No more available tempfile names!")
  9819. X
  9820. X    # Make sure we have an unambiguous directory name, with backslashes
  9821. X    # instead of Unix-like forward slashes.
  9822. X    dir := trim(map(dir, "/", "\\"), '\\') || "\\"
  9823. X
  9824. X    # Put dir listing into a temp file.
  9825. X    system("dir "||dir||" > "||temp_name)
  9826. X
  9827. X    # Put tempfile entries into a list, removing blank- and
  9828. X    # space-initial lines.  Exclude directories (i.e. return file
  9829. X    # names only).
  9830. X    in_dir := open(temp_name,"r") |
  9831. X    stop("Can't open temp file in directory ",temp_dir,".")
  9832. X    filename_list := list()
  9833. X    every filename := ("" ~== !in_dir) do {
  9834. X        match(" ",filename) | find(" <DIR>", filename) & next
  9835. X    # Exclude our own tempfiles (may not always be appropriate).
  9836. X    filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
  9837. X    if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
  9838. X    then put(filename_list, map(dir || filename))
  9839. X    }
  9840. X
  9841. X    # Clean up.
  9842. X    close(in_dir) & remove(temp_name)
  9843. X
  9844. X    # Check to be sure we actually managed to read some files.
  9845. X    if *filename_list = 0 then fail
  9846. X    else return sort(filename_list)
  9847. X
  9848. Xend
  9849. X
  9850. X
  9851. X
  9852. Xprocedure get_dos_tempname(dir)
  9853. X
  9854. X    # Don't clobber existing files.  Get a unique temp file name for
  9855. X    # use as a temporary storage site.
  9856. X
  9857. X    every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
  9858. X    temp_file := open(temp_name,"r") | break
  9859. X        close(temp_file)
  9860. X    }
  9861. X    return \temp_name
  9862. X
  9863. Xend
  9864. X
  9865. X
  9866. X
  9867. Xprocedure unix_get_dir(dir)
  9868. X
  9869. X    dir := trim(dir, '/') || "/"
  9870. X    filename_list := list()
  9871. X    in_dir := open("/bin/ls -F "||dir, "pr")
  9872. X    every filename := ("" ~== !in_dir) do {
  9873. X    match("/",filename,*filename) & next
  9874. X    if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
  9875. X    then put(filename_list, trim(dir || filename, '*'))
  9876. X    }
  9877. X    close(in_dir)
  9878. X
  9879. X    if *filename_list = 0 then fail
  9880. X    else return filename_list
  9881. X
  9882. Xend
  9883. SHAR_EOF
  9884. true || echo 'restore of getnames.icn failed'
  9885. rm -f _shar_wnt_.tmp
  9886. fi
  9887. # ============= getpaths.icn ==============
  9888. if test -f 'getpaths.icn' -a X"$1" != X"-c"; then
  9889.     echo 'x - skipping getpaths.icn (File already exists)'
  9890.     rm -f _shar_wnt_.tmp
  9891. else
  9892. > _shar_wnt_.tmp
  9893. echo 'x - extracting getpaths.icn (Text)'
  9894. sed 's/^X//' << 'SHAR_EOF' > 'getpaths.icn' &&
  9895. Xprocedure get_lib_paths(ipl_paths)
  9896. X
  9897. X    /ipl_paths := list()
  9898. X
  9899. X    # If the ILIBS environment variable is set, read it into
  9900. X    # ipl_paths.  Colons *or* spaces are okay as separators.
  9901. X    getenv("ILIBS") ? {
  9902. X    while path := tab(upto(' :')) do {
  9903. X        put(ipl_paths, "./" ~== fixup_path(path))
  9904. X        tab(many(' :'))
  9905. X    }
  9906. X    put(ipl_paths, "./" ~== fixup_path(tab(0)))
  9907. X    }
  9908. X
  9909. X    # Make sure the current directory is in the IPL path.
  9910. X    push(ipl_paths, "./")
  9911. X
  9912. X    return ipl_paths
  9913. X
  9914. Xend
  9915. X
  9916. X
  9917. X
  9918. Xprocedure fixup_path(s)
  9919. X    return "/" ~== (trim(s,'/') || "/")
  9920. Xend
  9921. SHAR_EOF
  9922. true || echo 'restore of getpaths.icn failed'
  9923. rm -f _shar_wnt_.tmp
  9924. fi
  9925. # ============= getprocs.icn ==============
  9926. if test -f 'getprocs.icn' -a X"$1" != X"-c"; then
  9927.     echo 'x - skipping getprocs.icn (File already exists)'
  9928.     rm -f _shar_wnt_.tmp
  9929. else
  9930. > _shar_wnt_.tmp
  9931. echo 'x - extracting getprocs.icn (Text)'
  9932. sed 's/^X//' << 'SHAR_EOF' > 'getprocs.icn' &&
  9933. Xrecord procedure_stats(name, file, byte)
  9934. Xglobal record_table, global_table
  9935. X
  9936. Xprocedure get_procedure_stats(fname)
  9937. X
  9938. X    # Extracts the names of all procedures declared in file f.
  9939. X    # Returns them in a list, each of whose elements have the
  9940. X    # form record procedure_stats(procedurename, filename, byte
  9941. X    # offset).
  9942. X
  9943. X    local intext, procedure_stat_list, f_pos, entry
  9944. X    # global record_table
  9945. X    static name_chars
  9946. X    initial {
  9947. X        record_table := table()
  9948. X    global_table := table()
  9949. X    name_chars := &ucase ++ &lcase ++ &digits ++ '_'
  9950. X    }
  9951. X
  9952. X    # Open fname.
  9953. X    intext := open(fname, "r") | fail
  9954. X
  9955. X    # Initialize procedure-name list.
  9956. X    procedure_stat_list := list()
  9957. X
  9958. X    # Find procedure declarations in intext.
  9959. X    while f_pos := where(intext) & line := read(intext) do {
  9960. X    strip_comments(line) ? {
  9961. X        if tab(match("procedure")) then {
  9962. X        tab(many(' \t')) &
  9963. X            put(procedure_stat_list,
  9964. X            procedure_stats(
  9965. X                "main" ~== tab(many(name_chars)), fname, f_pos
  9966. X                    )
  9967. X            )
  9968. X        }
  9969. X        else if tab(match("record")) then {
  9970. X        tab(many(' \t'))
  9971. X        if entry := "record " ||
  9972. X                tab(many(name_chars)) ||
  9973. X                (tab(many(' \t')) | &null, "") ||
  9974. X                tab(match("(")) ||
  9975. X                tab(find(")")+1) &  pos(0)
  9976. X        then {
  9977. X            /record_table[fname] := set()
  9978. X            insert(record_table[fname], entry)
  9979. X        }
  9980. X        }
  9981. X        else if tab(match("global")) then {
  9982. X        tab(many(' \t'))
  9983. X        /global_table[fname] := set()
  9984. X        insert(global_table[fname], "global "||tab(0))
  9985. X        }
  9986. X    }
  9987. X    }
  9988. X
  9989. X    # Clean up.
  9990. X    close(intext)
  9991. X
  9992. X    return procedure_stat_list   # returns empty list if no procedures found
  9993. X
  9994. Xend
  9995. SHAR_EOF
  9996. true || echo 'restore of getprocs.icn failed'
  9997. rm -f _shar_wnt_.tmp
  9998. fi
  9999. # ============= main.icn ==============
  10000. if test -f 'main.icn' -a X"$1" != X"-c"; then
  10001.     echo 'x - skipping main.icn (File already exists)'
  10002.     rm -f _shar_wnt_.tmp
  10003. else
  10004. > _shar_wnt_.tmp
  10005. echo 'x - extracting main.icn (Text)'
  10006. sed 's/^X//' << 'SHAR_EOF' > 'main.icn' &&
  10007. Xglobal unfound_procedures, st2, records, globals
  10008. X
  10009. Xprocedure main(a)
  10010. X
  10011. X    local usage, line, raw_line, elem, sourcefile_procedures
  10012. X
  10013. X    usage := "usage:  imerge sourcefile [libdirs]"
  10014. X    #
  10015. X    # Where sourcefile is a single filename, and libdirs is a series
  10016. X    # of space-separated directories in which relevant library files
  10017. X    # are to be found.
  10018. X
  10019. X    *a < 1 & stop(usage)
  10020. X
  10021. X    if not (intext := open(a[1],"r")) then {
  10022. X        write(&errout, "Cannot open source file.")
  10023. X    write(&errout, usage)
  10024. X        exit(2)
  10025. X    }
  10026. X
  10027. X    # Find every procedure call in intext.
  10028. X    every get_procedure_calls(!intext)
  10029. X    sourcefile_procedure_calls := get_procedure_calls()
  10030. X
  10031. X    if *sourcefile_procedure_calls = 0 then fail
  10032. X
  10033. X    # I know this is inefficient.  Change it, if you like.
  10034. X    sourcefile_procedures := set()
  10035. X    every insert(sourcefile_procedures, (!get_procedure_stats(a[1])).name)
  10036. X    sourcefile_procedure_calls --:= sourcefile_procedures
  10037. X
  10038. X    if *sourcefile_procedure_calls = 0 then fail
  10039. X
  10040. X    # Insert into procedure_stat_list the name of every procedure
  10041. X    # called by every library file.
  10042. X    prtbl := table()
  10043. X    every fname := !get_ipl_names(get_lib_paths()) do {
  10044. X        every elem := !get_procedure_stats(fname) do {
  10045. X        insert(prtbl,elem.name,elem)
  10046. X    }
  10047. X    }
  10048. X
  10049. X    # Copy input file to stdout.
  10050. X    seek(intext,1)
  10051. X    every line := strip_comments(raw_line := !intext) do {
  10052. X    line ? (tab(match("global"|"record"|"link")), tab(any(' \t'))) & next
  10053. X        write(raw_line)
  10054. X    }
  10055. X    close(intext)
  10056. X    write("\n\n\n")
  10057. X    write(repl("#",75))
  10058. X    write("#")
  10059. X    write("#  Auto merged procedures begin here.")
  10060. X    write("#")
  10061. X
  10062. X    # Fetch procedure calls, and write them to stdout.
  10063. X    fetch_procedure(sourcefile_procedure_calls, prtbl, a[1])
  10064. X    
  10065. Xend
  10066. X
  10067. X
  10068. X
  10069. Xprocedure fetch_procedure(st,prtbl,f_name,switch)
  10070. X
  10071. X    local stat, elem, p, st3
  10072. X
  10073. X    # global unfound_procedures, records, record_table, global_table
  10074. X    initial {
  10075. X    unfound_procedures := set()
  10076. X    records := set()
  10077. X        globals := set()
  10078. X    }
  10079. X
  10080. X    /st2 := set()
  10081. X
  10082. X    every insert(globals, !\global_table[f_name])
  10083. X
  10084. X    every p := !st do {
  10085. X    if /(stat := prtbl[p]) then {
  10086. X        # Record_table has record declarations catalogued by file name.
  10087. X        if find(" "||p||"(",elem := !\record_table[f_name] | !!record_table)
  10088. X        then insert(records,elem)
  10089. X        else insert(unfound_procedures, p)
  10090. X        next
  10091. X    }
  10092. X    intext := open(stat.file,"r")
  10093. X    seek(intext,stat.byte)
  10094. X    until "end" == (line := strip_comments(write(!intext \ 1))) do {
  10095. X        get_procedure_calls(line)
  10096. X    }
  10097. X    write("\n\n\n")
  10098. X    st2 ++:= st ++ set([stat.name])
  10099. X    st3 := get_procedure_calls() -- st2
  10100. X    close(intext)
  10101. X    fetch_procedure(st3,prtbl,stat.file,1)
  10102. X    }
  10103. X
  10104. X    if *records ~= 0 & /switch then {
  10105. X    # Output records that have been used.
  10106. X    write("#  Records.")
  10107. X    every write(!sort(records))
  10108. X    write()
  10109. X    }
  10110. X
  10111. X    if *globals ~= 0 & /switch then {
  10112. X    # Output global variables for all files visited.
  10113. X    write("#  Global variables.")
  10114. X    every write(!sort(globals))
  10115. X    write()
  10116. X    }
  10117. X
  10118. X    if *unfound_procedures ~= 0 & /switch then {
  10119. X        # Append a list of unlocated procedures to the stdout.
  10120. X        write("#  Unable to locate the following procedures:")
  10121. X        write("#")
  10122. X        every write("#      ",!sort(unfound_procedures),"()")
  10123. X        write("#")
  10124. X    }
  10125. X
  10126. X    return
  10127. X
  10128. Xend
  10129. X
  10130. SHAR_EOF
  10131. true || echo 'restore of main.icn failed'
  10132. rm -f _shar_wnt_.tmp
  10133. fi
  10134. # ============= stripcom.icn ==============
  10135. if test -f 'stripcom.icn' -a X"$1" != X"-c"; then
  10136.     echo 'x - skipping stripcom.icn (File already exists)'
  10137.     rm -f _shar_wnt_.tmp
  10138. else
  10139. > _shar_wnt_.tmp
  10140. echo 'x - extracting stripcom.icn (Text)'
  10141. sed 's/^X//' << 'SHAR_EOF' > 'stripcom.icn' &&
  10142. Xprocedure strip_comments(s)
  10143. X
  10144. X    #######
  10145. X    #
  10146. X    # Commented-out portions of Icon code - strip 'em.  Fails on lines
  10147. X    # which, either stripped or otherwise, come out as an empty string.
  10148. X    #
  10149. X    # I'd expect strip_comments to be used typically as follows:
  10150. X    #
  10151. X    #     every write(strip_comments(!&input))
  10152. X    #
  10153. X    # BUG:  Does not handle lines which use the _ string-continuation
  10154. X    # notation.  Typically strip_comments barfs on the next line.
  10155. X    #
  10156. X    #######
  10157. X
  10158. X    local i, j, c, c2
  10159. X
  10160. X    s ? {
  10161. X    tab(many(' \t'))
  10162. X    pos(0) & fail
  10163. X        find("#") | (return trim(tab(0),' \t'))
  10164. X    match("#") & fail
  10165. X    (s2 <- tab(find("#"))) ? {
  10166. X        c2 := &null
  10167. X        while tab(upto('\\"\'')) do {
  10168. X        case c := move(1) of {
  10169. X            "\\"   : {
  10170. X            if match("^")
  10171. X            then move(2)
  10172. X            else move(1)
  10173. X            }
  10174. X            default: {
  10175. X            if \c2
  10176. X            then (c == c2, c2 := &null)
  10177. X            else c2 := c
  10178. X            }
  10179. X        }
  10180. X        }
  10181. X        /c2
  10182. X    }
  10183. X    return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
  10184. X    }
  10185. X
  10186. Xend
  10187. SHAR_EOF
  10188. true || echo 'restore of stripcom.icn failed'
  10189. rm -f _shar_wnt_.tmp
  10190. fi
  10191. exit 0
  10192.  
  10193. From icon-group-request@arizona.edu  Tue Oct  2 17:51:01 1990
  10194. Resent-From: icon-group-request@arizona.edu
  10195. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10196.     id AA02574; Tue, 2 Oct 90 17:51:01 -0700
  10197. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 2 Oct 90 17:50 MST
  10198. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27217; Tue, 2 Oct 90 17:19:31
  10199.  -0700
  10200. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  10201.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  10202.  usenet@ucbvax.Berkeley.EDU if you have questions)
  10203. Resent-Date: Tue, 2 Oct 90 17:50 MST
  10204. Date: 2 Oct 90 05:41:54 GMT
  10205. From: midway!quads.uchicago.edu!goer@uunet.uu.net
  10206. Subject: RE: test posting of a strange program
  10207. Sender: icon-group-request@arizona.edu
  10208. Resent-To: icon-group@cs.arizona.edu
  10209. To: icon-group@arizona.edu
  10210. Resent-Message-Id: <266876AB890940289A@Arizona.edu>
  10211. Message-Id: <1990Oct2.054154.15481@midway.uchicago.edu>
  10212. Organization: University of Chicago
  10213. X-Envelope-To: icon-group@CS.Arizona.EDU
  10214. X-Vms-To: icon-group@Arizona.EDU
  10215. References: <9009281046.AA12149@sophist>
  10216.  
  10217. Goer%sophist@GARGOYLE.UCHICAGO.EDU (Richard Goerwitz) writes:
  10218.  
  10219. >This is a test posting of a strange program.  Essentially, it takes
  10220. >a source file, finds all procedure calls in it, looks for those pro-
  10221. >cedure calls which are not a part of the source file itself in the
  10222. >IPL (or in any directories you tell it to), then fetches those rou-
  10223. >tines that it needs, writing the original source file and the neces-
  10224. >sary library routines to the standard output.
  10225. >
  10226. >Frequently I forget what file an IPL routine is in.  And there is
  10227. >almost always stuff I don't want to link in present with the routines
  10228. >that I do.  This program handles most of the hunting and pecking by
  10229. >itself.
  10230.  
  10231. I now have an updated version of the program around.  It has been
  10232. tested in more environments, and seems to work pretty well.  I want
  10233. people who are interested in tinkering with the utility to let me
  10234. know so I can send them updates.  I'll refrain from reposting a
  10235. final version until it's looking pretty stable.
  10236.  
  10237. Thanks to those who offered me feedback.  Thanks in advance to those
  10238. who might choose to do so in the future.
  10239.  
  10240. -Richard
  10241.  
  10242. From icon-group-request@arizona.edu  Tue Oct  2 19:54:56 1990
  10243. Resent-From: icon-group-request@arizona.edu
  10244. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10245.     id AA06336; Tue, 2 Oct 90 19:54:56 -0700
  10246. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 2 Oct 90 19:54 MST
  10247. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03764; Tue, 2 Oct 90 19:40:59
  10248.  -0700
  10249. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  10250.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  10251.  usenet@ucbvax.Berkeley.EDU if you have questions)
  10252. Resent-Date: Tue, 2 Oct 90 19:54 MST
  10253. Date: 2 Oct 90 16:44:38 GMT
  10254. From: midway!quads.uchicago.edu!goer@handies.ucar.edu
  10255. Subject: avoid duplicate procedure id's
  10256. Sender: icon-group-request@arizona.edu
  10257. Resent-To: icon-group@cs.arizona.edu
  10258. To: icon-group@arizona.edu
  10259. Resent-Message-Id: <265726196049403217@Arizona.edu>
  10260. Message-Id: <1990Oct2.164438.24792@midway.uchicago.edu>
  10261. Organization: University of Chicago
  10262. X-Envelope-To: icon-group@CS.Arizona.EDU
  10263. X-Vms-To: icon-group@Arizona.EDU
  10264.  
  10265. As Icon code starts to pack my filesystem more and more, duplicate
  10266. procedure and record names have become a greater and greater problem,
  10267. especially when the duplicate names turn up in files intended as
  10268. Icon libraries.
  10269.  
  10270. Here's a program to make sure that duplicate procedure names don't
  10271. invade your libraries (or, for that matter, the IPL - which to start
  10272. with has a few duplicate names).
  10273.  
  10274. Certainly, in some cases, duplicate names are desirable (as when a
  10275. library exists in several OS-specific implementations).  In most
  10276. cases, though, they are not.  The following package might be especi-
  10277. ally useful to those who intend to post code.  At least this way,
  10278. they can be sure their procedure names don't conflict with a known
  10279. body of programs that everyone has access to (i.e. the IPL).
  10280.  
  10281. -Richard
  10282.  
  10283. P.S.  I write these things mainly for myself, so don't expect them
  10284.       to be "polished."  Naturally, though, I'll hungrily eat up any
  10285.       bug reports, and either re-post or send out individual diffs,
  10286.       depending on which seems more appropriate at the time.
  10287.  
  10288. ---- Cut Here and feed the following to sh ----
  10289. #!/bin/sh
  10290. # This is a shell archive (produced by shar 3.49)
  10291. # To extract the files from this archive, save it to a file, remove
  10292. # everything above the "!/bin/sh" line above, and type "sh file_name".
  10293. #
  10294. # made 10/02/1990 16:10 UTC by goer@sophist.uchicago.edu
  10295. # Source directory /u/richard/Tmp
  10296. #
  10297. # existing files will NOT be overwritten unless -c is specified
  10298. # This format requires very little intelligence at unshar time.
  10299. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  10300. #
  10301. #                                                                          
  10302. #                                                                          
  10303. #
  10304. # This shar contains:
  10305. # length  mode       name
  10306. # ------ ---------- ------------------------------------------
  10307. #   8344 -r--r--r-- duplproc.icn
  10308. #    692 -rw-r--r-- README
  10309. #    623 -rw-r--r-- Makefile.dist
  10310. #
  10311. if test -r _shar_seq_.tmp; then
  10312.     echo 'Must unpack archives in sequence!'
  10313.     echo Please unpack part `cat _shar_seq_.tmp` next
  10314.     exit 1
  10315. fi
  10316. # ============= duplproc.icn ==============
  10317. if test -f 'duplproc.icn' -a X"$1" != X"-c"; then
  10318.     echo 'x - skipping duplproc.icn (File already exists)'
  10319.     rm -f _shar_wnt_.tmp
  10320. else
  10321. > _shar_wnt_.tmp
  10322. echo 'x - extracting duplproc.icn (Text)'
  10323. sed 's/^X//' << 'SHAR_EOF' > 'duplproc.icn' &&
  10324. X############################################################################
  10325. X#
  10326. X#    Name:     duplproc.icn
  10327. X#
  10328. X#    Title:     Find duplicate procedure/record identifiers
  10329. X#
  10330. X#    Author:     Richard L. Goerwitz
  10331. X#
  10332. X#    Version: 1.1
  10333. X#
  10334. X############################################################################
  10335. X#
  10336. X#  Use this if you plan on posting code!
  10337. X#
  10338. X#  Finddupl.icn compiles into a program which will search through
  10339. X#  every directory in your ILIBS environment variable (and/or in the
  10340. X#  directories supplied as arguments to the program).  If it finds any
  10341. X#  duplicate procedure or record identifiers, it will report this on
  10342. X#  the standard output.
  10343. X#
  10344. X#  It is important to try to use unique procedure names in programs
  10345. X#  you write, especially if you intend to link in some of the routines
  10346. X#  contained in the IPL.  Checking for duplicate procedure names has
  10347. X#  been somewhat tedious in the past, and many of us (me included)
  10348. X#  must be counted as guilty for not checking more thoroughly.  Now,
  10349. X#  however, checking should be a breeze.
  10350. X#
  10351. X############################################################################
  10352. X#
  10353. X#  Links:  none
  10354. X#
  10355. X#  Requires:  Unix (MS-DOS may work; dunno)
  10356. X#
  10357. X############################################################################
  10358. X
  10359. Xrecord procedure_stats(name, file, lineno)
  10360. X
  10361. Xprocedure main(a)
  10362. X
  10363. X    local proc_table, fname, elem, lib_file, tmp
  10364. X
  10365. X    #     usage:  duplproc [libdirs]
  10366. X    #
  10367. X    # Where libdirs is a series of space-separated directories in
  10368. X    # which relevant library files are to be found.  To the
  10369. X    # directories listed in libdirs are added any directories found in
  10370. X    # the ILIBS environment variable.
  10371. X
  10372. X    proc_table := table()
  10373. X
  10374. X    # Put all command-line option paths, and ILIBS paths, into one sorted
  10375. X    # list.  Then get the names of all .icn filenames in those paths.
  10376. X    every fname := !get_icn_filenames(getlibpaths(a)) do {
  10377. X    # For each .icn filename, open that file, and find all procedure
  10378. X    # calls in it.
  10379. X    if not (lib_file := open(fname, "r")) then
  10380. X        write(&errout,"Can't open ",fname," for reading.")
  10381. X    else {
  10382. X        # Find all procedure calls in lib_file.
  10383. X        every elem := !get_procedures(lib_file,fname) do {
  10384. X        if /proc_table[elem.name] := set()
  10385. X        then insert(proc_table[elem.name],elem)
  10386. X        else {
  10387. X            write("\"", elem.name, "\"",
  10388. X            " is defined in ",*proc_table[elem.name]+1," places:")
  10389. X            every tmp := !proc_table[elem.name] do
  10390. X            write("     ",tmp.file, ", line ",tmp.lineno)
  10391. X            write("     ",elem.file, ", line ", elem.lineno)
  10392. X        }
  10393. X        }
  10394. X        close(lib_file)
  10395. X    }
  10396. X    }
  10397. X
  10398. X
  10399. Xend
  10400. X
  10401. X
  10402. X
  10403. Xprocedure getlibpaths(ipl_paths)
  10404. X
  10405. X    # Unite command-line args and ILIBS environment variable into one
  10406. X    # path list.
  10407. X
  10408. X    local i, path
  10409. X
  10410. X    # Make sure all paths have a consistent format (one trailing slash).a
  10411. X    if *\ipl_paths > 0 then {
  10412. X    every i := 1 to *ipl_paths do {
  10413. X        ipl_paths[i] := fixup_path(ipl_paths[i])
  10414. X    }
  10415. X    ipl_paths := set(ipl_paths)
  10416. X    }
  10417. X    else ipl_paths := set()
  10418. X
  10419. X    # If the ILIBS environment variable is set, read it into
  10420. X    # ipl_paths.  Colons *or* spaces are okay as separators.
  10421. X    getenv("ILIBS") ? {
  10422. X    while path := tab(upto(' :')) do {
  10423. X        insert(ipl_paths, fixup_path(path))
  10424. X        tab(many(' :'))
  10425. X    }
  10426. X    insert(ipl_paths, fixup_path(tab(0)))
  10427. X    }
  10428. X
  10429. X    return sort(ipl_paths)
  10430. X
  10431. Xend
  10432. X
  10433. X
  10434. X
  10435. Xprocedure fixup_path(s)
  10436. X    # Make sure paths have a consistent format.
  10437. X    return "/" ~== (trim(s,'/') || "/")
  10438. Xend
  10439. X
  10440. X
  10441. X
  10442. Xprocedure get_procedures(intext,fname)
  10443. X
  10444. X    # Extracts the names of all procedures declared in file f.
  10445. X    # Returns them in a list, each of whose elements have the
  10446. X    # form record procedure_stats(procedurename, filename, lineno).
  10447. X
  10448. X    local psl, f_pos
  10449. X    static name_chars
  10450. X    initial {
  10451. X    name_chars := &ucase ++ &lcase ++ &digits ++ '_'
  10452. X    }
  10453. X
  10454. X    # Initialize procedure-name list, line count.
  10455. X    psl := list()
  10456. X    line_no := 0
  10457. X
  10458. X    # Find procedure declarations in intext.
  10459. X    while line := read(intext) & line_no +:= 1 do {
  10460. X    take_out_comments(line) ? {
  10461. X        if tab(match("procedure")) then {
  10462. X        tab(many(' \t')) &
  10463. X            put(psl, procedure_stats(
  10464. X                "main" ~== tab(many(name_chars)), fname, line_no))
  10465. X        }
  10466. X    }
  10467. X    }
  10468. X
  10469. X    return psl   # returns empty list if no procedures found
  10470. X
  10471. Xend
  10472. X
  10473. X
  10474. X
  10475. Xprocedure take_out_comments(s)
  10476. X
  10477. X    # Commented-out portions of Icon code - strip 'em.  Fails on lines
  10478. X    # which, either stripped or otherwise, come out as an empty string.
  10479. X    #
  10480. X    # BUG:  Does not handle lines which use the _ string-continuation
  10481. X    # notation.  Typically take_out_comments barfs on the next line.
  10482. X
  10483. X    local i, j, c, c2
  10484. X
  10485. X    s ? {
  10486. X    tab(many(' \t'))
  10487. X    pos(0) & fail
  10488. X        find("#") | (return trim(tab(0),' \t'))
  10489. X    match("#") & fail
  10490. X    (s2 <- tab(find("#"))) ? {
  10491. X        c2 := &null
  10492. X        while tab(upto('\\"\'')) do {
  10493. X        case c := move(1) of {
  10494. X            "\\"   : {
  10495. X            if match("^")
  10496. X            then move(2)
  10497. X            else move(1)
  10498. X            }
  10499. X            default: {
  10500. X            if \c2
  10501. X            then (c == c2, c2 := &null)
  10502. X            else c2 := c
  10503. X            }
  10504. X        }
  10505. X        }
  10506. X        /c2
  10507. X    }
  10508. X    return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
  10509. X    }
  10510. X
  10511. Xend
  10512. X
  10513. X
  10514. X
  10515. Xprocedure get_icn_filenames(lib_paths)
  10516. X
  10517. X    # Return the names of all .icn files in all of the paths in the
  10518. X    # list lib_paths.  The dir routine used depends on which OS we
  10519. X    # are running under.
  10520. X
  10521. X    local procedure_stat_list
  10522. X    static get_dir
  10523. X    initial get_dir := set_getdir_by_os()
  10524. X
  10525. X    procedure_stat_list := list()
  10526. X    # Run through every possible path in which files might be found,
  10527. X    # and get a list of procedures contained in those files.
  10528. X    every procedure_stat_list |||:= get_dir(!lib_paths)
  10529. X
  10530. X    return procedure_stat_list
  10531. X
  10532. Xend
  10533. X
  10534. X
  10535. X
  10536. Xprocedure set_getdir_by_os()
  10537. X
  10538. X    if find("UNIX", &features)
  10539. X    then return unix_get_dir
  10540. X    else if find("MS-DOS", &features)
  10541. X    then return msdos_get_dir
  10542. X    else stop("Your operating system is not (yet) supported.")
  10543. X
  10544. Xend
  10545. X
  10546. X
  10547. X
  10548. Xprocedure msdos_get_dir(dir)
  10549. X
  10550. X    # Returns a sorted list of all filenames (full paths included) in
  10551. X    # directory "dir."  The list is sorted.  Fails on invalid or empty
  10552. X    # directory.  Aborts if temp file cannot be opened.
  10553. X    #
  10554. X    # Temp files can be directed to one or another directory either by
  10555. X    # manually setting the variable temp_dir below, or by setting the
  10556. X    # value of the environment variable TEMPDIR to an appropriate
  10557. X    # directory name.
  10558. X
  10559. X    local in_dir, filename_list, line
  10560. X    static temp_dir
  10561. X    initial {
  10562. X        temp_dir := 
  10563. X            (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
  10564. X                ".\\"
  10565. X    }
  10566. X
  10567. X    # Get name of tempfile to be used.
  10568. X    temp_name := get_dos_tempname(temp_dir) |
  10569. X    stop("No more available tempfile names!")
  10570. X
  10571. X    # Make sure we have an unambiguous directory name, with backslashes
  10572. X    # instead of Unix-like forward slashes.
  10573. X    dir := trim(map(dir, "/", "\\"), '\\') || "\\"
  10574. X
  10575. X    # Put dir listing into a temp file.
  10576. X    system("dir "||dir||" > "||temp_name)
  10577. X
  10578. X    # Put tempfile entries into a list, removing blank- and
  10579. X    # space-initial lines.  Exclude directories (i.e. return file
  10580. X    # names only).
  10581. X    in_dir := open(temp_name,"r") |
  10582. X    stop("Can't open temp file in directory ",temp_dir,".")
  10583. X    filename_list := list()
  10584. X    every filename := ("" ~== !in_dir) do {
  10585. X        match(" ",filename) | find(" <DIR>", filename) & next
  10586. X    # Exclude our own tempfiles (may not always be appropriate).
  10587. X    filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
  10588. X    if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
  10589. X    then put(filename_list, map(dir || filename))
  10590. X    }
  10591. X
  10592. X    # Clean up.
  10593. X    close(in_dir) & remove(temp_name)
  10594. X
  10595. X    # Check to be sure we actually managed to read some files.
  10596. X    if *filename_list = 0 then fail
  10597. X    else return sort(filename_list)
  10598. X
  10599. Xend
  10600. X
  10601. X
  10602. X
  10603. Xprocedure get_dos_tempname(dir)
  10604. X
  10605. X    # Don't clobber existing files.  Get a unique temp file name for
  10606. X    # use as a temporary storage site.
  10607. X
  10608. X    every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
  10609. X    temp_file := open(temp_name,"r") | break
  10610. X        close(temp_file)
  10611. X    }
  10612. X    return \temp_name
  10613. X
  10614. Xend
  10615. X
  10616. X
  10617. X
  10618. Xprocedure unix_get_dir(dir)
  10619. X
  10620. X    dir := trim(dir, '/') || "/"
  10621. X    filename_list := list()
  10622. X    in_dir := open("/bin/ls -F "||dir, "pr")
  10623. X    every filename := ("" ~== !in_dir) do {
  10624. X    match("/",filename,*filename) & next
  10625. X    if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
  10626. X    then put(filename_list, trim(dir || filename, '*'))
  10627. X    }
  10628. X    close(in_dir)
  10629. X
  10630. X    if *filename_list = 0 then fail
  10631. X    else return filename_list
  10632. X
  10633. Xend
  10634. SHAR_EOF
  10635. true || echo 'restore of duplproc.icn failed'
  10636. rm -f _shar_wnt_.tmp
  10637. fi
  10638. # ============= README ==============
  10639. if test -f 'README' -a X"$1" != X"-c"; then
  10640.     echo 'x - skipping README (File already exists)'
  10641.     rm -f _shar_wnt_.tmp
  10642. else
  10643. > _shar_wnt_.tmp
  10644. echo 'x - extracting README (Text)'
  10645. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  10646. XSee the comments prepended to duplproc.icn for a statement of what
  10647. Xthis program is and does.  To create it on a Unix system, you can
  10648. Xjust mv Makefile.dist to Makefile and make.  If you want to install
  10649. Xit, type "make Install" as root.  Be sure to check the Makefile
  10650. Xfirst, though, to be sure the installation routine uses the correct
  10651. Xdirectories and permissions for your system.
  10652. X
  10653. XUsers of other systems, you're on your own.  This may work under
  10654. XMS-DOS, but it hasn't been tested on anything other than Unix.  The
  10655. Xreason for the OS-specificity is duplproc's need to get a listing
  10656. Xof various filenames in various directories at run-time.  This has
  10657. Xto be implemented on a system-by-system basis.
  10658. SHAR_EOF
  10659. true || echo 'restore of README failed'
  10660. rm -f _shar_wnt_.tmp
  10661. fi
  10662. # ============= Makefile.dist ==============
  10663. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  10664.     echo 'x - skipping Makefile.dist (File already exists)'
  10665.     rm -f _shar_wnt_.tmp
  10666. else
  10667. > _shar_wnt_.tmp
  10668. echo 'x - extracting Makefile.dist (Text)'
  10669. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  10670. XPROGNAME = duplproc
  10671. X
  10672. X# Please edit these to reflect your local file structure & conventions.
  10673. XDESTDIR = /usr/local/bin
  10674. XOWNER = bin
  10675. XGROUP = bin
  10676. X
  10677. XSRC = $(PROGNAME).icn
  10678. X
  10679. X$(PROGNAME): $(PROGNAME).icn
  10680. X    icont $(PROGNAME).icn
  10681. X
  10682. X# Pessimistic assumptions regarding the environment (in particular,
  10683. X# I don't assume you have the BSD "install" shell script).
  10684. Xinstall: $(PROGNAME)
  10685. X    @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
  10686. X    cp $(PROGNAME) $(DESTDIR)/
  10687. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  10688. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  10689. X    @echo "\nInstallation done.\n"
  10690. X
  10691. Xclean:
  10692. X    -rm -f *~ .u?
  10693. X    -rm -f $(PROGNAME)
  10694. SHAR_EOF
  10695. true || echo 'restore of Makefile.dist failed'
  10696. rm -f _shar_wnt_.tmp
  10697. fi
  10698. exit 0
  10699.  
  10700. From icon-group-request@arizona.edu  Wed Oct  3 00:55:10 1990
  10701. Resent-From: icon-group-request@arizona.edu
  10702. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  10703.     id AA15103; Wed, 3 Oct 90 00:55:10 -0700
  10704. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 3 Oct 90 00:54 MST
  10705. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17179; Wed, 3 Oct 90 00:38:57
  10706.  -0700
  10707. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  10708.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  10709.  usenet@ucbvax.Berkeley.EDU if you have questions)
  10710. Resent-Date: Wed, 3 Oct 90 00:54 MST
  10711. Date: 2 Oct 90 09:45:56 GMT
  10712. From: mcsun!cernvax!chx400!hslrswi!naz@uunet.uu.net
  10713. Subject: Klondike: the game
  10714. Sender: icon-group-request@arizona.edu
  10715. Resent-To: icon-group@cs.arizona.edu
  10716. To: icon-group@arizona.edu
  10717. Resent-Message-Id: <262D34D74729403341@Arizona.edu>
  10718. Message-Id: <1562@hslrswi.UUCP>
  10719. Organization: Hasler AG
  10720. X-Envelope-To: icon-group@CS.Arizona.EDU
  10721. X-Vms-To: icon-group@Arizona.EDU
  10722.  
  10723. This is a card game, Solitaire to be precise, Klondike to be preciser.
  10724. I have built this mostly as a means of learning Icon.  I can't claim
  10725. credit for the user interface.  Some years ago I snatched a similar
  10726. (much faster) game built for PCs by Allyn Wade.  I have added a few
  10727. features in my version.  This one should work on any ANSI-compatible
  10728. terminal with 25 lines, but I don't have the opportunity to test that
  10729. here.  It works OK on my AT clone.
  10730.  
  10731. I understand that in Los Vegas one can lose money with this game too.
  10732. One buys a deck of cards for $55, and then you get $5 back for each
  10733. card that you put in the Ace piles.  Running my program for several
  10734. thousand games, I get an average of about 10.4 cards in the ace piles.
  10735. But the algorithm used (to date) is simplistic -- the goal for
  10736. future versions is to discover better algorithms so that I can get
  10737. rich quick in Los Vegas. :-)
  10738.  
  10739. I think this version basically works.  There is probably a bug or two
  10740. left in Undo.  Sorry, no documentation yet.  I'm still trying to get
  10741. my head wrapped around this Icon concept of generators, so I'm sure
  10742. the code could be better.  Bug fixes and suggestions for improvement
  10743. are welcome.
  10744.  
  10745. NHA
  10746. ---
  10747. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  10748. X.400:  naz@hslrswi.hasler
  10749. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  10750. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  10751.  
  10752. ----------- cut here -------------- cut here -------------------- cut here ---
  10753.  
  10754. #klondike.icn    900720    NHA
  10755. #The Klondike version of Solitaire.
  10756. # Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display.
  10757. #
  10758. # TO FIX:
  10759. #
  10760. # -    Undo is not 100%
  10761. #
  10762. #
  10763. # TO DO:
  10764. #
  10765. # -    Implement an heuristic to discover optimal play strategy,
  10766. #    with goal-directed evaluation and suchlike fancy stuff.
  10767. #    The basic idea is to tailor find1() such that its first suggestion
  10768. #    usually turns out to be the best one.  Measure this by trying the
  10769. #    entire tree of possibilities, recording what % of the time the
  10770. #    first suggestion was actually the best one.
  10771. #
  10772.  
  10773. record card(suit, rank)                                #suit is 1..4, rank is 1..13
  10774.  
  10775. # constants
  10776. global suitID                                        #suit identification chars
  10777. global isDOS                                        # 1 when running under DOS
  10778. global monochrome                                    # 1 when running Black&White
  10779. # Video control strings (ANSI.SYS)
  10780. global  ESC
  10781. global    Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL
  10782. global  Vred, Vblack                                #suit color strings
  10783. global color                                        #list of suit color strings
  10784.  
  10785. # variables
  10786. global deckUp, deckDown, stackUp, stackDown            #collections of card
  10787. global pile                                            #ace piles - top rank only
  10788. global totalGames, totalAces                        #statistics
  10789. global debugging, automaticAce, shuffling            #command-line flags
  10790. global clicking                                        # 1 for audible feedback
  10791. global randomSeed                                    #determinant for this game
  10792. global ops                                            #list of all operations
  10793.  
  10794.  
  10795. #    e r r o r
  10796. # Internal consistency check failed -- reveal all and die.
  10797. procedure error (x)
  10798.     display ()
  10799.     runerr (500, x)
  10800. end                                            #error
  10801.  
  10802.  
  10803. #    i n i t C o n s t a n t s
  10804. # Initialize the program "constants".  These are actually variables that
  10805. # are set just once at the beginning of the world.
  10806. procedure initConstants ()
  10807. local i
  10808.     #ensure that we are dealing with an ANSI-compatible screen
  10809.     writes ("\33[6n")                        #request cursor position report
  10810.     #NOTE that the first character to match should be an ESCape.
  10811.     #Unfortunately, reads() seems to eat that character
  10812.     if  not match ("[", reads (&input, 8))  then
  10813.         stop ("Klondike:  requires ANSI.SYS screen driver")
  10814.  
  10815.     isDOS := if find("MS-DOS", &host)  then  1  else  0
  10816.  
  10817.     if isDOS = 0  then
  10818.         monochrome := 1
  10819.     else {
  10820.         i := ord (Peek([16r40, 16r49]))            #BIOS display mode byte
  10821.         case i  of  {
  10822.             2        :    monochrome := 1
  10823.             3        :    monochrome := 0
  10824.             7        :    monochrome := 1
  10825.             default    :    stop ("Klondike:  unknown display mode ", i)
  10826.         }
  10827.     }
  10828.  
  10829.     ESC            := "\33"                    #escape character
  10830.     VclearAll    := "\33[2J"                    #also homes cursor
  10831.     VclearEOL    := "\33[K"
  10832.     Vnormal        := "\33[0m"
  10833.     Vbold        := "\33[1m"
  10834.     Vblink        := "\33[5m"
  10835.     Vreverse    := "\33[7m"
  10836.     if  monochrome = 0  then  {
  10837.         Vred    := "\33[0;47;31m"            # "extra" 0 seems to be necessary
  10838.         Vblack    := "\33[0;47;30m"
  10839.     } else {
  10840.         Vred    := Vnormal
  10841.         Vblack    := Vreverse
  10842.     }
  10843.  
  10844.     # Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades
  10845.     suitID := if isDOS ~= 0  then  "\3\4\5\6"  else  "HDCS"
  10846.     color := [Vred, Vred, Vblack, Vblack]
  10847. end                                            #initConstants
  10848.  
  10849.  
  10850. #    i n i t S c r e e n
  10851. # Initialize output and write the fixed parts of the screen.
  10852. # initConstants() must have been called earlier.
  10853. procedure initScreen ()
  10854. local i
  10855.     if  monochrome = 0  then  writes ("\33[=3h")    #25x80 color text mode
  10856.     else  writes ("\33[=2h")                        #25x80 B&W   text mode
  10857.     writes (VclearAll, "\33[=7l")                    #clear screen, prevent wrap
  10858.     every  i := 1 to 7  do
  10859.         writeStackNumber (i, Vnormal)
  10860.     every  i := 2 to 25  do
  10861.         writes ("\33[",i,";",64,"H\272")            #vertical stripe
  10862.     writes ("\33[2;64H\311\315\315\315\315SOLITAIRE\315\315\315\315")
  10863. end                                            #initScreen
  10864.  
  10865.  
  10866. #    w r i t e S t a c k N u m b e r
  10867. # Write the indicated stack number with the specified video attribute.
  10868. # Cursor position is preserved -- WARNING: THIS IS NOT NESTABLE.
  10869. procedure writeStackNumber (num, attr)
  10870.     writes (ESC, "[s")                        #save cursor position
  10871.     writeCursor (1, [2,11,20,29,38,47,56][num])
  10872.     writes (attr, num, Vnormal)
  10873.     writes (ESC, "[u")                        #restore cursor position
  10874. end                                            #writeStackNumber
  10875.  
  10876.  
  10877. #    w r i t e C u r s o r
  10878. # Position the cursor to row,col.
  10879. # Screen origin (top left corner) is row=1 and col=1.
  10880. procedure writeCursor (row, col)
  10881.     writes ("\33[", row, ";", col, "H") 
  10882. end                                            #writeCursor
  10883.  
  10884.  
  10885. #    w r i t e F r o n t
  10886. # Displays an image of the specified card fronts at the specified spot.
  10887. # WARNING: this eats the list that you provide -- pass a copy() if you care!!
  10888. # Top left corner of the first card will be placed at the specified position.
  10889. # Successive cards are displayed two rows higher (lower position on the screen).
  10890. # Cursor need not be in any particular position before this, and is left
  10891. # in a random position afterwards.  Video is left normal (not reversed).
  10892. # Cards are 7 columns wide by 5 rows tall.
  10893. # With 25 rows, we can put 12 cards in a stack (assuming we start in row 2).
  10894. # But if there are 11 in the stack we can only display 4 rows of the top card.
  10895. # If there are 12 cards, we can only display 2 rows of the topmost card.
  10896. ##We can only write a row at a time due to a problem with ANSI col 80 handling.
  10897. procedure writeFront (cardlist, row, col)
  10898. local suit, rank, card
  10899.     while  card := get(cardlist)  do  {
  10900.         #first 2 rows of card
  10901.         writeCursor (row+0, col);
  10902.         writes (Vreverse, "\332\304\304\304\304\304\277")
  10903.         writeCursor (row+1, col);
  10904.         writes ("\263", color[card.suit], "A23456789TJQK"[card.rank],
  10905.                 suitID[card.suit], Vreverse, "   \263")
  10906.         if (*cardlist = 0)  &  (row < 24)  then  {
  10907.             #next 2 rows of top card unless it's the 12th card on the stack
  10908.             writeCursor (row+2, col);
  10909.             writes (Vreverse, "\263     \263")
  10910.             writeCursor (row+3, col);
  10911.             writes ("\263   ", color[card.suit], "A23456789TJQK"[card.rank],
  10912.                     suitID[card.suit], Vreverse, "\263")
  10913.             if row < 22  then  {
  10914.                 #last row of card unless it's the 11th on the stack
  10915.                 writeCursor (row+4, col);
  10916.                 writes ("\300\304\304\304\304\304\331")
  10917.             }
  10918.         }
  10919.         row +:= 2
  10920.     }
  10921.     writes (Vnormal)
  10922. end                                            #writeFront
  10923.  
  10924.  
  10925. #    w r i t e B a c k
  10926. # Puts an image of the back of a card at the specified spot on the screen.
  10927. # Except that this shows the back instead of the front of the card,
  10928. # this is identical to writeFront().
  10929. procedure writeBack (row, col)
  10930. static backLine
  10931. initial {
  10932.     backLine := repl ("\260", 7)
  10933. }
  10934.     writeCursor (row+0, col);  writes (backLine)
  10935.     writeCursor (row+1, col);  writes (backLine)
  10936.     writeCursor (row+2, col);  writes (backLine)
  10937.     writeCursor (row+3, col);  writes (backLine)
  10938.     writeCursor (row+4, col);  writes (backLine)
  10939. end                                            #writeBack
  10940.  
  10941.  
  10942. #    w r i t e B l a n k
  10943. # Blanks a card-sized area at the specified spot on the screen.
  10944. # Except that this writes blanks instead of the back of a card,
  10945. # this is identical to writeBack().
  10946. procedure writeBlank (row, col)
  10947. static blankLine
  10948. initial {
  10949.     blankLine := repl (" ", 7)
  10950. }
  10951.     writeCursor (row+0, col);  writes (blankLine)
  10952.     writeCursor (row+1, col);  writes (blankLine)
  10953.     writeCursor (row+2, col);  writes (blankLine)
  10954.     writeCursor (row+3, col);  writes (blankLine)
  10955.     writeCursor (row+4, col);  writes (blankLine)
  10956. end                                            #writeBlank
  10957.  
  10958.  
  10959. #    w r i t e S t a c k
  10960. # Display the specified stack.  Left end is bottom of stackUp, top of stackDown.
  10961. # Stacks start in row 2, column1; with 2 columns between stacks.
  10962. # last[] holds, for each stack, the total number of visible cards
  10963. # on that stack as of the last time writeStack() was called.  This allows
  10964. # us to simply draw (or erase) the cards that have been added (or subtracted).
  10965. # By special arrangement, this routine can be called with a negative stack
  10966. # number!  This is a hint that our idea of what is on the display is actually
  10967. # wrong, and therefore the entire stack needs to be re-displayed.  This can
  10968. # happen in two situations:  1) in refreshScreen(), the entire screen is cleared
  10969. # before calling writeStack();  2) in undo() when undoing a move between
  10970. # stacks, the bottom card needs to be changed, although the normal algorithm
  10971. # would consider that it is already correctly displayed.  Note that in neither
  10972. # case is the stack shrinking, therefore we don't need to worry about erasing
  10973. # any cards that were displayed last time.
  10974. procedure writeStack (n)
  10975. local row, col, s
  10976. static last, blankLine, firstRow, lastRow
  10977. initial    {
  10978.     last := [0,0,0,0,0,0,0]
  10979.     blankLine := repl (" ", 7)
  10980.     firstRow := [2,4,6,8,10,12,14,16,18,20,22,24]    #first row of a card
  10981.     lastRow  := [6,8,10,12,14,16,18,20,22,24,25,25]    #last row of a card
  10982. }
  10983.     if n < 0  then  {
  10984.         n := -n
  10985.         last[n] := 0                            #force complete re-write
  10986.     }
  10987.  
  10988.     col := 1 + ((n -1) * 9)                        #leftmost column for this stack
  10989.  
  10990.     if *stackUp[n] <= last[n]  then  {
  10991.         #the stack just got smaller (or stayed the same)
  10992.         #blank out two rows for each card that has been removed
  10993.         row := lastRow[last[n]]                    #last row used by top card
  10994.         while *stackUp[n] < last[n]  do  {
  10995.             writeCursor (row-0, col);  writes (blankLine)
  10996.             writeCursor (row-1, col);  writes (blankLine)
  10997.             row -:= 2
  10998.             last[n] -:= 1                        #count and update simultaneously
  10999.         }
  11000.         if *stackUp[n] ~= last[n]  then  error (last[n])
  11001.         #re-write new top card
  11002.         if *stackUp[n] = 0  then
  11003.             if *stackDown[n] = 0  then
  11004.                 writeBlank (2, col)
  11005.             else
  11006.                 writeBack (2, col)
  11007.         else
  11008.             writeFront ([stackUp[n][-1]], firstRow[last[n]], col)
  11009.     } else {
  11010.         #the stack just got bigger -- display new cards
  11011.         s := stackUp[n][last[n]-(*stackUp[n]):0]
  11012.         writeFront (s, firstRow[last[n]+1], col)
  11013.         last[n] := *stackUp[n]                #remember how much is displayed
  11014.     }
  11015.  
  11016.     writeCursor (2, (7 + col))
  11017.     writes (" 123456???"[1+*stackDown[n]])    #display the number of hidden cards
  11018. end                                            #writeStack
  11019.  
  11020.  
  11021. #    w r i t e P i l e
  11022. # Displays an image of the specified ace pile, face up (or blank if empty)
  11023. procedure writePile (n)
  11024. static pileRow, pileCol
  11025. initial {
  11026.     pileRow := [3,3,9,9]
  11027.     pileCol := [66,74,66,74]
  11028. }
  11029.     if  0 = pile[n]  then  writeBlank (pileRow[n], pileCol[n])
  11030.     else  writeFront ([card(n,pile[n])], pileRow[n], pileCol[n])
  11031. end                                            #writePile
  11032.  
  11033.  
  11034. #    w r i t e D e c k D o w n
  11035. # Displays an image of deckDown (the face-down deck) in the proper spot.
  11036. procedure writeDeckDown ()
  11037.     if 0 < *deckDown  then
  11038.         writeBack (21, 74)
  11039.     else
  11040.         writeBlank (21, 74)
  11041.     writeCursor (20, 76)
  11042.     writes (right(*deckDown, 2))
  11043. end                                            #writeDeckDown
  11044.  
  11045.  
  11046. #    w r i t e D e c k U p
  11047. # Displays an image of deckUp (the face-up deck) in the proper spot.
  11048. procedure writeDeckUp ()
  11049.     if 0 < *deckUp  then
  11050.         writeFront ([deckUp[1]], 21, 66)
  11051.     else
  11052.         writeBlank (21, 66)
  11053.     writeCursor (20, 68)
  11054.     writes (right(*deckUp, 2))
  11055. end                                            #writeDeckUp
  11056.  
  11057.  
  11058. #    r e f r e s h S c r e e n
  11059. # Re-write entire screen.
  11060. procedure refreshScreen ()
  11061. local i
  11062.     initScreen ()
  11063.     every  i := 1 to 7  do
  11064.         writeStack (-i)
  11065.     every  i := 1 to 4  do
  11066.         writePile (i)
  11067.     writeDeckDown ()
  11068.     writeDeckUp ()
  11069. end                                            #refreshScreen
  11070.  
  11071.  
  11072. #    w r i t e I n f o
  11073. # Displays a new short string (up to 12 printing characters) in the
  11074. # officially approved information area of the screen.
  11075. # An empty string results in clearing the area and restoring normal attributes.
  11076. procedure writeInfo (s)
  11077.     writeCursor (16, 66)
  11078.     writes (Vnormal, VclearEOL)
  11079.     if  *s ~= 0  then  writes (s)
  11080. end                                            #writeInfo
  11081.  
  11082.  
  11083. #    c l i c k
  11084. # Make a quick sound to accompany card transfers
  11085. procedure click ()
  11086. local x
  11087.     if (clicking ~= 0)  &  (isDOS ~= 0)  then  {
  11088.         x := InPort (16r61)
  11089.         OutPort (16r61, 3)
  11090.         OutPort (16r61, x)
  11091.     }
  11092. end                                            #click
  11093.  
  11094.  
  11095. #    g e t C m d C h a r
  11096. # Returns an upper-case command character, echoed to current cursor position.
  11097. # Fails if character wasn't "normal" and complaint was made.
  11098. # For ESC, abort information is written, and ESC is returned.
  11099. # Normal calling sequence (from within a command procedure) is thus:
  11100. #        until (s := getCmdChar ())
  11101. #        if s == ESC  then  fail
  11102. procedure getCmdChar ()
  11103. local s
  11104.     s := getch ()                        #get command character
  11105.     if  s == "\0"  then  {                #non-ASCII character
  11106.         getch ()                        #discard keyboard scan code
  11107.         complain ()
  11108.         fail
  11109.     }
  11110.     s := map (s, &lcase, &ucase)
  11111.     if s == ESC  then
  11112.         writeInfo (Vbold || "Cmd Aborted.")
  11113.     else
  11114.         writes (s)                            #echo the command character
  11115.     return  s
  11116. end                                            #getCmdChar
  11117.  
  11118.  
  11119. #    f i t O n S t a c k
  11120. # Given a card and a stack number, fail unless card can be added to the stack.
  11121. # Note that we disallow putting an Ace on a stack, period.  This prevents
  11122. # ever building a stack with 13 cards, which we can't display in 25 rows.
  11123. # onto a stack, this problem is avoided.
  11124. ##This can certainly be done better...
  11125. procedure fitOnStack (c, n)
  11126. local top                                                    #top card on stack
  11127.     if *stackUp[n] = 0  then  {
  11128.         if 0 < *stackDown[n]  then  stop ("fitOnStack(): Up empty, Down not");
  11129.         if c.rank ~= 13  then  fail            #only a king can go to empty stack
  11130.     } else {
  11131.         top := stackUp[n][-1]                #copy of top card
  11132.         if (c.rank ~= (top.rank - 1))  then  fail            #wrong rank
  11133.         if (c.suit < 3)  &  (top.suit < 3)  then  fail        #same color
  11134.         if (c.suit > 2)  &  (top.suit > 2)  then  fail        #same color
  11135.         if *stackUp[n] = 12  then  fail                        #no room for ace
  11136.         if c.rank = 1  then  fail                            #no ace on stack
  11137.     }
  11138.     return                                    #success
  11139. end                                            #fitOnStack
  11140.  
  11141.  
  11142. #    c h e c k 4 a c e
  11143. # Only has an effect when global automaticAce is set!
  11144. # Given a stack number, check for an ace as the top of stackUp.
  11145. # If present, move it over to it's ace pile, turn over the next card
  11146. # from stackDown, and check again.
  11147. # Must not be more than one up card in stack.
  11148. # Returns a string of the operations performed.
  11149. procedure check4ace (n)
  11150. local c, op
  11151.     op := ""
  11152.     if automaticAce ~= 0  then  {
  11153.         if 1 < *stackUp[n]  then  error (*stackUp[n])
  11154.         while 0 < *stackUp[n]  do  {
  11155.             c := stackUp[n][1]                    #copy of (top = bottom) up card
  11156.             if c.rank = 1  then  {                #it's an ace!
  11157.                 pop (stackUp[n])                #remove it from the stack
  11158.                 pile[c.suit] := 1                #move to ace pile
  11159.                 op ||:= c.suit
  11160.                 push (stackUp[n], get(stackDown[n])) #turn over card underneath
  11161.                 writeStack (n)
  11162.                 writePile (c.suit)
  11163.                 click ()
  11164.             } else
  11165.                 break                            #not an ace
  11166.         }
  11167.     }
  11168.     return op
  11169. end                                            #check4ace
  11170.  
  11171.  
  11172. #    m o v e S t a c k
  11173. # Move a stack to another stack, no questions asked.
  11174. # Updates video and audio.
  11175. # Returns any automatic ace operations that were done as a consequence.
  11176. ##It would be nice to do this in a visually and audibly more satisfying way
  11177. procedure moveStack (src, dst)
  11178. local i
  11179.     every  i := 1 to *stackUp[src]  do
  11180.         put (stackUp[dst], get(stackUp[src]))
  11181.     put (stackUp[src], get(stackDown[src]))
  11182.     writeStack (src)
  11183.     writeStack (dst)
  11184.     click ()
  11185.     return  check4ace (src)
  11186. end                                            #moveStack
  11187.  
  11188.  
  11189. #    a u t o m a t i c
  11190. # Run the game, as far as possible, untouched by human hands
  11191. procedure automatic ()
  11192. local s, thumbCount
  11193.     thumbCount := 0
  11194.     repeat  {
  11195.         if kbhit ()  then
  11196.             return                            #stopped by human intervention
  11197.         if pile[1] = pile[2] = pile[3] = pile[4] = 13  then
  11198.             return                            #victory
  11199.         if s := find1()  then  {
  11200.             push (ops, move1 ("M" || s || "0"))
  11201.             thumbCount := 0
  11202.         } else {                            #no good move found -- thumb
  11203.             if not (s := thumb())  then
  11204.                 return                        #no cards left to thumb through
  11205.             push (ops, s)
  11206.             thumbCount :=  if s == "T"  then  thumbCount + 1  else  0
  11207.             if ((*deckUp + *deckDown + 2) / 3 + 1)  <  thumbCount  then
  11208.                 return                        #end of the line
  11209.         }
  11210.     }
  11211. end                                            #automatic
  11212.  
  11213.  
  11214. #    c o n t i n u o u s
  11215. # Plays automatic games -- forever (or until any keystroke)
  11216. procedure continuous()
  11217.     writes ("ontinuous")
  11218.     repeat  {
  11219.         writeInfo (string(totalGames) || "   " || string(totalAces))
  11220.         automatic()
  11221.         if kbhit()  then  {
  11222.             if  getch() == "\0"  then        #eat stopping char(s)
  11223.                 getch()
  11224.             return
  11225.         } else
  11226.             totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
  11227.         newGame()
  11228.     }
  11229. end                                            #continuous
  11230.  
  11231.  
  11232. #    h e l p
  11233. # Provide information
  11234. procedure help ()
  11235.     write (VclearAll, Vnormal)
  11236.     write ("Klondike version 1.1  901002 NHA\t\t", &version)
  11237.     write ("\n\nThe following commands are available:\n")
  11238.     write ("\t^L\tre-draw screen")
  11239.     write ("\tA\tAutomatic mode -- plays 1 game by itself until any key is hit")
  11240.     write ("\tC\tContinuous mode -- plays games continuously until any key hit")
  11241.     if debugging ~= 0  then
  11242.         write ("\tD\tDebug")
  11243.     write ("\tH,?\tHelp, this help screen")
  11244.     write ("\tM\tMove card (or stack) from Deck/Stack to Stack/Ace pile")
  11245.     write ("\tQ\tQuit this game")
  11246.     write ("\tS\tSuggest (another) possible move")
  11247.     write ("\tT\tThumb through the deck")
  11248.     write ("\tU\tUndo -- back up one move")
  11249.     write ("\tESC\tEscape -- abort current command")
  11250.  
  11251.     write ("\n\ntotalGames = ", totalGames, "      totalAces = ", totalAces)
  11252.     write ("\n\nPress any key to resume game")
  11253.     if  getch() == "\0"  then  getch()
  11254.     refreshScreen ()
  11255. end                                            #help
  11256.  
  11257.  
  11258. #    m o v e 1
  11259. # This is the internal move, taking a operation string.  No Thumbs allowed.
  11260. # Upon success it returns the (possibly modified) operation string.
  11261. procedure move1 (op)
  11262. local src, dst, c, moved
  11263.     if op[1] ~== "M"  then  error (op)
  11264.     src := op[2]
  11265.     dst := op[3]
  11266.     moved := 0
  11267.     if src == "D"  then  {
  11268.         c := deckUp[1]
  11269.         if dst == "A"  then  {                # Deck -> Ace
  11270.             if c.rank = (pile[c.suit] + 1)  then  {
  11271.                 op[4] := c.suit                # Deck -> Ace:  fits - do it
  11272.                 pile[c.suit] +:= 1
  11273.                 writePile (c.suit)
  11274.                 moved := 1
  11275.             } else
  11276.                 fail                        # Deck -> Ace:  doesn't fit
  11277.         } else  {                            # Deck -> stack
  11278.             if fitOnStack (c, dst)  then {
  11279.                 put (stackUp[dst], c)        # Deck -> stack:  fits - do it
  11280.                 writeStack (dst)
  11281.                 moved := 1
  11282.             } else
  11283.                 fail                        # Deck -> stack: doesn't fit
  11284.         }
  11285.         while moved ~= 0  do  {
  11286.             pop (deckUp)
  11287.             writeDeckUp ()                    # Deck -> somewhere, with success
  11288.             click ()
  11289.             moved := 0
  11290.             if automaticAce ~= 0  then  {
  11291.                 if (c := deckUp[1]).rank = 1  then  {    #automatic Ace handling
  11292.                     pile[c.suit] := 1
  11293.                     op ||:= c.suit
  11294.                     writePile (c.suit)
  11295.                     moved := 1
  11296.                 }
  11297.             }
  11298.         }
  11299.     } else {
  11300.         if dst == "A"  then  {                # stack -> Ace
  11301.             c := stackUp[src][-1]            #copy of card on top of stack
  11302.             if c.rank = (pile[c.suit] + 1)  then  {
  11303.                 op[4] := c.suit                # stack -> Ace:  fits - do it
  11304.                 pile[c.suit] +:= 1
  11305.                 pull (stackUp[src])
  11306.                 writeStack (src)
  11307.                 click ()
  11308.                 writePile (c.suit)
  11309.                 if *stackUp[src] = 0  then  {
  11310.                     op[4] +:= 4                #mark this case for undo()
  11311.                     put (stackUp[src], get(stackDown[src]))    #turn over a card
  11312.                     writeStack (src)
  11313.                     click ()
  11314.                     op ||:= check4ace (src)
  11315.                 }
  11316.             } else {
  11317.                 fail                        # stack -> Ace:  doesn't fit
  11318.             }
  11319.         } else {                            # stack -> stack
  11320.             if fitOnStack (stackUp[src][1], dst)  then  {
  11321.                 op[4] := *stackUp[src]        # stack -> stack:  fits - do it
  11322.                 op ||:= moveStack (src, dst)
  11323.             } else
  11324.                 fail                        # stack -> stack:  doesn't fit
  11325.         }
  11326.     }
  11327.     return  op                                #success
  11328. end                                            #move1
  11329.  
  11330.  
  11331. #    m o v e
  11332. # Move a card from deck to stack, or from stack to ace pile,
  11333. # or move a stack to another stack.
  11334. # Fails if this is not possible
  11335. # This is the routine that interacts with the user.
  11336. procedure move ()
  11337. local src, dst, c, op, moved
  11338.     writes ("ove " || Vbold);
  11339.  
  11340.     until (src := getCmdChar ())
  11341.     if src == ESC  then  return
  11342.     if src == "D"  then  {
  11343.         if *deckUp = 0  then  fail
  11344.     } else {
  11345.         if not any ('1234567', src)  then  fail
  11346.         if *stackUp[src] = 0  then  fail
  11347.         writeStackNumber (src, Vblink)
  11348.     }
  11349.  
  11350.     writes (Vnormal || " to " || Vbold)
  11351.     until (dst := getCmdChar ())
  11352.     if  src ~== "D"  then  writeStackNumber (src, Vnormal)
  11353.     if dst == ESC  then  return
  11354.     if not any ('A1234567', dst)  then  fail
  11355.     if dst == src  then  fail
  11356.  
  11357.     return  push (ops, move1("M" || src || dst || "0"))
  11358. end                                            #move
  11359.  
  11360.  
  11361. #    f i n d 1
  11362. # Find a (reasonable) possible move in this situation
  11363. procedure find1 ()
  11364. local i, j, k, c
  11365.     #look at deckUp to see if the top card fits on a pile
  11366.     if c := deckUp[1]  then
  11367.         if c.rank = (pile[c.suit] + 1)  then
  11368.             suspend "DA"
  11369.     #look at deckUp to see if the top card fits on a stack
  11370.     if c := deckUp[1]  then
  11371.         every i := 1 to 7  do
  11372.             if fitOnStack (c, i)  then
  11373.                 suspend "D" || string(i)
  11374.     #look at each stack to see if top card can be put on ace pile
  11375.     every i := 1 to 7  do
  11376.         if c := stackUp[i][-1]  then        #top card
  11377.             if c.rank = (pile[c.suit] + 1)  then
  11378.                 suspend  string(i) || "A"
  11379.     #look at each stack to see if something can be (reasonably) moved
  11380.     every i := 7 to 1 by -1  do
  11381.         every j := 1 to 7  do
  11382.             if fitOnStack (stackUp[i][1], j)  then  {
  11383.                 if (0 < *stackDown[i])  then
  11384.                     suspend  string(i) || string(j)
  11385.                 else {
  11386.                     # possibility, but since there are no cards hidden under
  11387.                     # this pile, we reject it UNLESS there are no empty slots
  11388.                     # AND one of the following is true:
  11389.                     #    1) deckUp[1].rank = 13
  11390.                     #    2) there is a king with cards hidden beneath it
  11391.                     c := 0                    #number of empty stacks
  11392.                     every k := 1 to 7  do
  11393.                         if *stackUp[k] = 0  then  c +:= 1
  11394.                     if c = 0  then
  11395.                         if (deckUp[1].rank = 13)  |
  11396.                           (every k := 1 to 7  do
  11397.                                 if (stackUp[k][1].rank = 13) &
  11398.                                    (0 < *stackDown[k])  then
  11399.                                     break            #success
  11400.                           )
  11401.                     then
  11402.                         suspend  string(i) || string(j)
  11403.                 }
  11404.             }
  11405.     #punt
  11406.     fail
  11407. end                                            #find1
  11408.  
  11409.  
  11410. #    s u g g e s t
  11411. # Suggest a (reasonable) possible move in this situation.
  11412. # Repeated invocations produce successive possibilities, until the
  11413. # only thing left to do is Thumb.  After this, it cycles around to the start.
  11414. procedure suggest (another)
  11415. static suggestions, i
  11416. local s, ss
  11417.     writes ("uggest")
  11418.     if another = 0  then  {
  11419.         suggestions := []                    #generate a new list of suggestions
  11420.         every put (suggestions, find1())
  11421.         i := 0
  11422.     }
  11423.     if ss := suggestions[i+:=1]  then  {
  11424.         s := "Move " ||    if ss[1] == "A"  then  "Ace"
  11425.                         else if ss[1] == "D"  then  "Deck"
  11426.                         else ss[1]
  11427.         s ||:= " to " || if ss[2] == "A"  then  "Ace" else ss[2]
  11428.         writeInfo (s)
  11429.     } else {
  11430.         writeInfo ("Thumb")
  11431.         i := 0
  11432.     }
  11433. end                                            #suggest
  11434.  
  11435.  
  11436. #    t h u m b
  11437. # Move to next spot in deckDown
  11438. # Returns the operation performed (usually just "T"), or fail if none possible.
  11439. procedure thumb ()
  11440. local c, op, moved
  11441.     if *deckDown = *deckUp = 0  then
  11442.         return complain()                        #no cards left in the deck
  11443.     op := "T"
  11444.     if *deckDown = 0  then
  11445.         while push (deckDown, pop(deckUp))
  11446.     push (deckUp, get(deckDown))
  11447.     push (deckUp, get(deckDown))
  11448.     push (deckUp, get(deckDown))
  11449.     moved := 1
  11450.     writeDeckDown ()
  11451.     while moved ~= 0  do  {
  11452.         writeDeckUp ()
  11453.         click ()
  11454.         moved := 0
  11455.         if automaticAce ~= 0  then  {
  11456.             if (c := deckUp[1]).rank = 1  then  {
  11457.                 pop (deckUp)
  11458.                 pile[c.suit] := 1
  11459.                 op ||:= c.suit
  11460.                 writePile (c.suit)
  11461.                 moved := 1
  11462.             }
  11463.         }
  11464.     }
  11465.     return op
  11466. end                                            #thumb
  11467.  
  11468.  
  11469. #    u n d o
  11470. # backup one move, including any automatic ace moves
  11471. procedure undo ()
  11472. local op, suit
  11473.     writes ("ndo")
  11474.     if op := pop (ops)  then  {
  11475.         writeInfo (op)
  11476.         # op looks like:  Msdixxx
  11477.         # where x is an [optional] number 1..4 of an ace pile
  11478.         # and s is either a stack number or "D"
  11479.         # and d is either "A" or a number 1..7 of a stack
  11480.         # and i is an extra piece of info which may be valid
  11481.         case op[1]  of   {
  11482.         "M"        :    {
  11483.                     if (*op < 4) | ((automaticAce = 0) & (4 < *op))  then
  11484.                         error (op)
  11485.                     if op[2] == "D"  then  {
  11486.                         #Move cards from Ace piles to deck, starting at end
  11487.                         while 4 < *op  do  {
  11488.                             suit := op[-1]
  11489.                             pile[suit] := 0
  11490.                             writePile (suit)
  11491.                             push (deckUp, card(suit,1))
  11492.                             writeDeckUp ()
  11493.                             click ()
  11494.                             op[-1] := ""
  11495.                         }
  11496.                         if op[3] == "A"  then  {
  11497.                             # unMove Deck to Ace op[4]
  11498.                             suit := op[4]
  11499.                             push (deckUp, card(suit,pile[suit]))
  11500.                             pile[suit] -:= 1
  11501.                             writePile (suit)
  11502.                         } else {
  11503.                             # unMove Deck to stack op[3]
  11504.                             push (deckUp, pull(stackUp[op[3]]))
  11505.                             writeStack (op[3])
  11506.                         }
  11507.                         writeDeckUp ()
  11508.                     } else {
  11509.                         #Move cards from Ace piles to stack, starting at end
  11510.                         while 4 < *op  do  {
  11511.                             suit := op[-1]
  11512.                             pile[suit] := 0
  11513.                             writePile (suit)
  11514.                             if 1 < *stackUp[op[2]]  then error (*stackUp[op[2]])
  11515.                             push (stackDown[op[2]], pull(stackUp[op[2]]))
  11516.                             push (stackUp[op[2]], card(suit,1))
  11517.                             writeStack (op[2])
  11518.                             click ()
  11519.                             op[-1] := ""
  11520.                         }
  11521.                         if op[3] == "A"  then  {
  11522.                             # unMove stack op[2] to Ace pile op[4]
  11523.                             suit := op[4]
  11524.                             if 4 < suit  then  {
  11525.                                 suit -:= 4        #ace pile card was last on stack
  11526.                                 if 1 < *stackUp[op[2]]  then
  11527.                                     error (*stackUp[op[2]])
  11528.                                 push (stackDown[op[2]], pull(stackUp[op[2]]))
  11529.                             }
  11530.                             put (stackUp[op[2]], card(suit,pile[suit]))
  11531.                             pile[suit] -:= 1
  11532.                             writePile (suit)
  11533.                             writeStack (op[2])
  11534.                         } else {
  11535.                             # unMove top op[4] cards on stack op[2]
  11536.                             # to stack op[3]
  11537.                             if 1 < *stackUp[op[2]]  then error (*stackUp[op[2]])
  11538.                             push (stackDown[op[2]], pull(stackUp[op[2]]))
  11539.                             every 1 to op[4]  do
  11540.                                 push (stackUp[op[2]], pull(stackUp[op[3]]))
  11541.                             writeStack (op[3])
  11542.                             writeStack (-op[2])
  11543.                         }
  11544.                     }
  11545.                 }
  11546.         "T"        :    {
  11547.                     if (automaticAce = 0) & (*op ~= 1)  then  error (op)
  11548.                     ### op looks like:  Txx
  11549.                     ### where x is an optional number 1..4 of an ace pile
  11550.                     ### There can be 0,1,2,3, or 4 of these x's.
  11551.                     # move cards from Ace piles to deck, starting at end
  11552.                     while 1 < *op  do  {
  11553.                         suit := op[-1]
  11554.                         pile[suit] := 0
  11555.                         writePile (suit)
  11556.                         push (deckUp, card(suit,1))
  11557.                         writeDeckUp ()
  11558.                         click ()
  11559.                         op[-1] := ""
  11560.                     }
  11561.                     # then undo the Thumb operation itself
  11562.                     if *deckUp = 0  then
  11563.                         while push(deckUp, pop(deckDown))
  11564.                     else {
  11565.                         push (deckDown, pop(deckUp))
  11566.                         until (*deckUp % 3) = 0  do
  11567.                             push (deckDown, pop(deckUp))
  11568.                     }
  11569.                     writeDeckUp ()
  11570.                     writeDeckDown ()
  11571.                 }
  11572.         default    :    stop ("Klondike: unknown operation `", op, "' in ops[]")
  11573.         }
  11574.         click ()
  11575.     } else
  11576.         writeInfo ("Stack Empty")
  11577.  
  11578. end                                            #undo
  11579.  
  11580.  
  11581. #    c o m p l a i n
  11582. # Let the boob know he done something wrong
  11583. procedure complain ()
  11584. local i, x
  11585.     writeInfo (Vbold || "INVALID")
  11586.     if isDOS ~= 0  then  {
  11587.         x := InPort (16r61)
  11588.         every i := 1 to 22 do
  11589.             OutPort (16r61, 3)
  11590.         OutPort (16r61, x)
  11591.     }
  11592. end                                            #complain
  11593.  
  11594.  
  11595. #    t e r m i n a t e
  11596. # Parameter should be non-zero if termination is due to complete success.
  11597. # Returns success to quit this game and start another.
  11598. # Returns failure to just continue this game.j
  11599. # If program termination is wished, that is done right here.
  11600. procedure terminate (victory)
  11601. local s, avg
  11602.     if victory ~= 0  then  {
  11603.         writeCursor (12, 22)
  11604.         writes (Vbold, "Congratulations -- You've WON !!!", Vnormal)
  11605.         s := "Y"
  11606.     } else {
  11607.         writes ("uit? ")
  11608.         until (s := getCmdChar ())
  11609.         if s == ESC  then  fail                #abort the quit command
  11610.     }
  11611.     if s == "Y"  then  {
  11612.         writeInfo (Vbold || "Another game? ")
  11613.         until (s := getCmdChar ())
  11614.         if s == ESC  then  fail()            #didn't really want to quit anyway
  11615.         if s == "Y"  then  return            #please start a new game
  11616.  
  11617.         #program termination requested
  11618.         writes ("\33[=7h", Vnormal)            #set cursor wrap mode, normal attr
  11619.         writeCursor (17, 1)
  11620.         totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
  11621.         if 1 < totalGames  then  {
  11622.             avg := string (real(totalAces) / real(totalGames))
  11623.             if 4 < *avg  then  avg := avg[1+:4]
  11624.             write (VclearAll, "In ", totalGames, " games, you put ", totalAces,
  11625.               " cards on the ace piles, for an average of ", avg, " per game")
  11626.         } else 
  11627.             writes (VclearAll, "You put ", totalAces, " cards on the ace piles")
  11628.         exit ()
  11629.     } else
  11630.         fail                                #oops!  didn't really want to quit
  11631. end                                            #terminate
  11632.  
  11633.  
  11634. #    s h o w L i s t
  11635. # Display a list of cards at the current cursor position.
  11636. # Intended for debugging only .
  11637. procedure showList (lst)
  11638. local i, c
  11639.     every  i := 1 to *lst  do  {
  11640.         c := lst[i]
  11641.         writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit],
  11642.                 Vnormal, " ")
  11643.     }
  11644. end                                            #showList
  11645.  
  11646.  
  11647. #    c a r d 2 s t r
  11648. # Given a list of card records, returns a string representation.
  11649. # WARNING: this eats the list, so you might want to pass a copy().
  11650. # Intended for debugging only.
  11651. procedure card2str (ll)
  11652. local c, s
  11653.     s := ""
  11654.     while c := get(ll)  do
  11655.         s ||:= string(c.suit) || "123456789abcd"[c.rank]
  11656.     return s
  11657. end                                            #card2str
  11658.  
  11659.  
  11660. #    s t r 2 c a r d
  11661. # Given a string [as generated by card2str()],
  11662. # return corresponding list of card records
  11663. procedure str2card (s)
  11664. local cc, i
  11665.     cc := []
  11666.     i := 0
  11667.     while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1])))
  11668.     return cc
  11669. end                                            #str2card
  11670.  
  11671.  
  11672. #    d e b u g
  11673. # Additional commands to support the implementer are done here.
  11674. procedure debug ()
  11675. local s, d, c, f, name
  11676.     writes ("ebug ")
  11677.     until (s := getCmdChar ())
  11678.     case s  of  {
  11679.         ESC        :    fail
  11680.         "A"        :    {
  11681.                     writes ("gain")
  11682.                     &random := randomSeed
  11683.                     writeCursor (23, 1)
  11684.                     write (Vbold, "&random set.  Quit to play this game again.",
  11685.                             Vnormal, VclearEOL)
  11686.                 }
  11687.         "H"|"?"    :    {
  11688.                     writes (if s == "?" then "[help]" else "elp")
  11689.                     writeCursor (23, 1)
  11690.                     write (Vbold,
  11691.                      "Again, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{ACDST}.",
  11692.                      Vnormal, VclearEOL)
  11693.                 }
  11694.         "M"        :    {
  11695.                     writes ("ove ")
  11696.                     until (s := getCmdChar ())    #Source
  11697.                     if s == ESC  then  fail
  11698.                     if s == "A"  then  fail
  11699.                     until (d := getCmdChar ())    #Destination
  11700.                     if d == ESC  then  fail
  11701.                     if d == s  then  fail
  11702.                     if not any('1234567', d)  then  fail
  11703.                     if s == "D"  then  {
  11704.                         if *deckUp = 0  then  fail
  11705.                         put (stackUp[d], get(deckUp))
  11706.                         writeDeckUp ()
  11707.                         writeStack (d)
  11708.                         push (ops, "MD" || d || "0")
  11709.                     } else {
  11710.                         moveStack (s, d)
  11711.                         push (ops, "M" || s || d || "0")
  11712.                     }
  11713.                 }
  11714.         "O"        :    {
  11715.                     writes ("ptions")
  11716.                     writeCursor (23, 1)
  11717.                     write (Vbold,
  11718.                      "automaticAce=", automaticAce, " shuffling=", shuffling,
  11719.                      " random seed=", randomSeed, " clicking=", clicking, ".",
  11720.                      Vnormal, VclearEOL)
  11721.                 }
  11722.         "P"        :    {
  11723.                     writes ("eek ")
  11724.                     until (s := getCmdChar ())
  11725.                     if s == ESC  then  fail
  11726.                     writeCursor (23, 1)
  11727.                     writes (VclearEOL, Vnormal)
  11728.                     if any('1234567', s)  then
  11729.                         showList (stackDown[s])
  11730.                     else if s == "D"  then
  11731.                         showList (deckDown)
  11732.                     else if s == "U"  then
  11733.                         showList (deckUp)
  11734.                     else
  11735.                         complain ()
  11736.                 }
  11737.         "R"        :    {
  11738.                     writes ("estore")
  11739.                     until (s := getCmdChar ())
  11740.                     if s == ESC  then  fail
  11741.                     name := "klondike.sv" || s
  11742.                     writeCursor (23, 1)
  11743.                     if not (f := open (name, "r"))  then
  11744.                         write (Vbold, "Can't read file ", name, ".",
  11745.                                 Vnormal, VclearEOL)
  11746.                     else {
  11747.                         write (Vbold, "Restoring position from file ", name,
  11748.                                 Vnormal, VclearEOL)
  11749.                         automaticAce := read (f, automaticAce)
  11750.                         clicking     := read (f)
  11751.                         randomSeed   := read (f)
  11752.                         shuffling    := read (f)
  11753.                         &random      := read (f)
  11754.                         totalGames   := read (f)
  11755.                         totalAces    := read (f)
  11756.                         every c := 1 to 4  do
  11757.                             pile[c] := read (f)
  11758.                         every c := 1 to 7  do  {
  11759.                             stackUp[c]   := str2card (read(f))
  11760.                             stackDown[c] := str2card (read(f))
  11761.                         }
  11762.                         deckUp   := str2card (read(f))
  11763.                         deckDown := str2card (read(f))
  11764.                         ops := []
  11765.                         while push (ops, read (f))
  11766.                         close (f) | stop ("Klondike: close failed")
  11767.                         refreshScreen()
  11768.                     }
  11769.                 }
  11770.         "S"        :    {
  11771.                     writes ("ave ")
  11772.                     until (s := getCmdChar ())
  11773.                     if s == ESC  then  fail
  11774.                     name := "klondike.sv" || s
  11775.                     writeCursor (23, 1)
  11776.                     if not (f := open (name, "c"))  then
  11777.                         write (Vbold, "Can't create file ", name, ".",
  11778.                                 Vnormal, VclearEOL)
  11779.                     else {
  11780.                         write (f, automaticAce)
  11781.                         write (f, clicking)
  11782.                         write (f, randomSeed)
  11783.                         write (f, shuffling)
  11784.                         write (f, &random)
  11785.                         write (f, totalGames)
  11786.                         write (f, totalAces)
  11787.                         every c := 1 to 4  do
  11788.                             write (f, pile[c])
  11789.                         every c := 1 to 7  do  {
  11790.                             write (f, card2str(copy(stackUp[c])))
  11791.                             write (f, card2str(copy(stackDown[c])))
  11792.                         }
  11793.                         write (f, card2str(copy(deckUp)))
  11794.                         write (f, card2str(copy(deckDown)))
  11795.                         while write (f, pull(ops))
  11796.                         close (f) | stop ("Klondike: close failed")
  11797.                         write (Vbold, "Position saved in file ",name,
  11798.                                 Vnormal, VclearEOL)
  11799.                     }
  11800.                 }
  11801.         "T"        :    {
  11802.                     writes ("oggle ")
  11803.                     until (s := getCmdChar ())
  11804.                     if s == ESC  then  fail
  11805.                     case s  of  {
  11806.                         "A"        : automaticAce:= if automaticAce=0 then 1 else 0
  11807.                         "C"        : clicking  := if clicking  = 0 then  1 else  0
  11808.                         "D"        : debugging    := if debugging = 0 then  1 else  0
  11809.                         "S"        : shuffling    := if shuffling = 0 then  1 else  0
  11810.                         "T"        : &trace    := if &trace    = 0 then -1 else  0
  11811.                         default    : complain ()
  11812.                     }                                    #case for Toggle
  11813.                 }
  11814.         default    :    complain ()
  11815.     }                                            #case for Debug command
  11816. end                                            #debug
  11817.  
  11818.  
  11819. #    n e w G a m e
  11820. # Set up all the global variables for a new game
  11821. procedure newGame ()
  11822. local i, j, s
  11823.     totalGames +:= 1
  11824.     initScreen ()
  11825.  
  11826. #initialize deck, stacks, piles
  11827.     ops       := []                            #no operations done yet
  11828.     deckUp    := []                            #deck in hand, face-up
  11829.     deckDown  := []                            #deck in hand, face-down
  11830.     stackUp   := list(7, 0)                    #columns on table, face up
  11831.     stackDown := list(7, 0)                    #columns on table, face down
  11832.     pile      := list(4, 0)                    #aces - only top rank stored
  11833.     every  i := 1 to 4  do
  11834.         every  j := 1 to 13  do
  11835.             put (deckDown, card(i, j))        #take cards out of the box
  11836.     if shuffling ~= 0  then  {
  11837.         writeInfo (Vblink || "Shuffling")
  11838.         every 1 to 100 do
  11839.             ?deckDown :=: ?deckDown
  11840.         writeInfo ("")
  11841.     }
  11842.     every  i := 1 to 7  do  {
  11843.         stackDown[i] := []
  11844.         stackUp[i]   := []
  11845.     }
  11846.     every  i := 1 to 7  do  {
  11847.         push (stackUp[i], get(deckDown))
  11848. ###        writeStack (-i)
  11849.         click ()
  11850.         every  j := (i+1) to 7  do  {
  11851.             push (stackDown[j], get(deckDown))
  11852. ###            writeStack (-j)
  11853.             click ()
  11854.         }
  11855.         writeStack (-i)
  11856.     }
  11857.     writeDeckDown()
  11858.  
  11859. every  i := 1 to 7  do
  11860.     if *(s := check4ace (i)) ~= 0  then
  11861.         push (ops, "M" || string(i) || "A" || string(integer(s) + 4))
  11862. end                                            #newGame
  11863.  
  11864.  
  11865. #    m a i n
  11866. procedure main (av)
  11867. local s, prevsCmd
  11868.  
  11869.     initConstants()
  11870.  
  11871. #deal with command-line parameters
  11872.     debugging        := 0                    # default is no debugging allowed
  11873.     clicking        := 1                    # audible feedback sometimes helps
  11874.     automaticAce    := 1                    # default is automatic ace handling
  11875.     shuffling        := 1                    # default is shuffle the deck
  11876.     &random := map (&clock, ":", "0")        # default is randomize the seed
  11877.     while  s := get (av)  do
  11878.         case  map (s, &lcase, &ucase)  of  {
  11879.             "-A"    :    automaticAce := 0    #disable automatic ace handling
  11880.             "-C"    :    clicking     := 0            #run silent
  11881.             "-D"    :    debugging     := 1            #grant all sorts of perqs
  11882.             "-R"    :    &random      := get (av)    #unrandomize
  11883.             "-S"    :    shuffling     := 0            #don't shuffle the deck
  11884.             default    :    { write ("klondike  [-ACDS]  [-R randomSeed]")
  11885.                           stop("klondike: bogus option ", s)  }
  11886.         }
  11887.     randomSeed := &random                        #remember for debug()
  11888.     totalGames := 0                                #games played
  11889.     totalAces  := 0                                #cards put on ace piles
  11890.  
  11891.     repeat  {                                    #game loop
  11892.         newGame()
  11893.         prevsCmd := "x"                            #anything but "S"uggest
  11894.  
  11895.     #respond to user input
  11896.         repeat  {                                    #command loop
  11897.             writeCursor (18, 66)
  11898.             writes (VclearEOL || Vnormal || "> ")    #clear command line
  11899.             if pile[1] = pile[2] = pile[3] = pile[4] = 13  then
  11900.                 if terminate (1) then break            # VICTORY!
  11901.             s := getCmdChar ()
  11902.             writeInfo ("")                            #clear info line
  11903.             writeCursor (18, 69)
  11904.             case  s  of  {
  11905.                 "?"        :    help()
  11906.                 "A"        :    {
  11907.                             writes ("utomatic")
  11908.                             automatic()                        #look Ma, no hands!
  11909.                             if kbhit()  then
  11910.                                 if  getch() == "\0"  then  getch()
  11911.                         }
  11912.                 "C"        :    continuous()                    #no hands, forever
  11913.                 "D"        :    if debugging = 0  then  complain()  else  debug()
  11914.                 "H"        :    help()
  11915.                 "M"        :    if not move() then complain()
  11916.                 "Q"        :    if terminate(0) then break        #new game
  11917.                 "S"        :    suggest (if s == prevsCmd then 1 else 0)
  11918.                 "T"        :    { writes ("humb");  push (ops, thumb()) }
  11919.                 "U"        :    undo()
  11920.                 "\14"    :    refreshScreen ()                #^L
  11921.                 ESC        :    s                                #do nothing
  11922.                 default    :    complain ()
  11923.             }                                #case
  11924.             prevsCmd := s
  11925.         }                                    #repeat command
  11926.         totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
  11927.     }                                        #repeat game
  11928. end                                            #main
  11929. -- 
  11930. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  11931. X.400:  naz@hslrswi.hasler
  11932. UUCP:   ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
  11933. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  11934.  
  11935. From icon-group-request@arizona.edu  Wed Oct  3 04:34:26 1990
  11936. Resent-From: icon-group-request@arizona.edu
  11937. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  11938.     id AA23642; Wed, 3 Oct 90 04:34:26 -0700
  11939. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 3 Oct 90 04:33 MST
  11940. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27160; Wed, 3 Oct 90 04:21:19
  11941.  -0700
  11942. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11943.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11944.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11945. Resent-Date: Wed, 3 Oct 90 04:34 MST
  11946. Date: 2 Oct 90 21:09:13 GMT
  11947. From: esquire!yost@nyu.edu
  11948. Subject: Icon as RDBMS report writer language
  11949. Sender: icon-group-request@arizona.edu
  11950. Resent-To: icon-group@cs.arizona.edu
  11951. To: icon-group@arizona.edu
  11952. Resent-Message-Id: <260E9215EAA940382A@Arizona.edu>
  11953. Message-Id: <2723@esquire.dpw.com>
  11954. Organization: DP&W, New York, NY
  11955. X-Envelope-To: icon-group@CS.Arizona.EDU
  11956. X-Vms-To: icon-group@Arizona.EDU
  11957.  
  11958. Has anyone used Icon as the basis for a RDBMS report writer language?
  11959. Such a beast could be soooo much better than some other things out there...
  11960.  
  11961.  --dave yost
  11962.    yost@dpw.com or uunet!esquire!yost
  11963.    Please don't use other mangled forms you may see
  11964.    in the From, Reply-To, or CC fields above.
  11965.  
  11966. From cargo@cherry.cray.com  Wed Oct  3 06:37:14 1990
  11967. Received: from timbuk.CRAY.COM by megaron.cs.arizona.edu (5.61/15) via SMTP
  11968.     id AA26141; Wed, 3 Oct 90 06:37:14 -0700
  11969. Received: from cherry04.cray.com by timbuk.CRAY.COM (4.1/SMI4.0 CRAY1.1)
  11970.     id AA00512; Wed, 3 Oct 90 08:37:10 CDT
  11971. Received: by cherry04.cray.com
  11972.     id AA01510; 4.1/CRI-3.21; Wed, 3 Oct 90 08:37:08 CDT
  11973. Date: Wed, 3 Oct 90 08:37:08 CDT
  11974. From: cargo@cherry.cray.com (David S. Cargo)
  11975. Message-Id: <9010031337.AA01510@cherry04.cray.com>
  11976. To: icon-group@cs.arizona.edu
  11977. Subject: Re: Icon as RDBMS report writer language
  11978.  
  11979. >Date: 2 Oct 90 21:09:13 GMT
  11980. >From: esquire!yost@nyu.edu
  11981. >Subject: Icon as RDBMS report writer language
  11982. >To: icon-group@arizona.edu
  11983. >Organization: DP&W, New York, NY
  11984. >
  11985. >Has anyone used Icon as the basis for a RDBMS report writer language?
  11986. >Such a beast could be soooo much better than some other things out there...
  11987. >
  11988. > --dave yost
  11989.  
  11990. I have used Icon as a part of a process for some data base publishing,
  11991. but only in conjunction with other programs.  Cray keeps a software
  11992. problem report data base using ORACLE.  My section in Cray likes to see
  11993. reports about our status weekly.  Using canned and dynamically
  11994. generated queries, I extract a formatted report that I then feed to an
  11995. Icon program for further processing.  The further processing in this
  11996. case means extracting data and rewriting it with LaTeX code and macro
  11997. calls defined in the tables.sty file.  The result is formatted with
  11998. LaTeX and printed with dvips on our Sun LaserWriters.
  11999.  
  12000. I have in some cases written PostScript directly from Icon programs,
  12001. but in this case it seemed a lot easier on me to let existing programs
  12002. shoulder the burden of doing the formatting.
  12003.  
  12004. dsc
  12005.  
  12006. From nowlin@iwtqg.att.com  Wed Oct  3 06:47:28 1990
  12007. Resent-From: nowlin@iwtqg.att.com
  12008. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  12009.     id AA26380; Wed, 3 Oct 90 06:47:28 -0700
  12010. Received: from att.att.com by Arizona.edu; Wed, 3 Oct 90 06:46 MST
  12011. Resent-Date: Wed, 3 Oct 90 06:47 MST
  12012. Date: Wed, 3 Oct 90 07:35 CDT
  12013. From: nowlin@iwtqg.att.com
  12014. Subject: RE: Icon...RDBMS report...
  12015. Resent-To: icon-group@cs.arizona.edu
  12016. To: att!arizona.edu!icon-group@cs.arizona.edu
  12017. Resent-Message-Id: <25FC023C8729403C4F@Arizona.edu>
  12018. Message-Id: <25FC09C78719A00903@Arizona.edu>
  12019. Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
  12020. X-Envelope-To: icon-group@CS.Arizona.EDU
  12021. X-Vms-To: att!arizona.edu!icon-group@cs.Arizona.edu
  12022.  
  12023. We have a modification request (bug report) tracking system that's based on
  12024. a relational database and most of our canned reports and even the graphs we
  12025. use to track things like the "fix" rate are programmed in Icon.  The Icon
  12026. programs spit out ascii reports and generate pic code for graphs.  I toyed
  12027. with making them generate PostScript but we already had a working pic
  12028. format for the graphs so I just used Icon to automate the data collection
  12029. and formatting.  It's customized to our specific project and wouldn't be
  12030. portable to other applications but does provide an example of the use you
  12031. were interested in.
  12032.  
  12033. Jerry Nowlin
  12034. (...!att!iwtqg!nowlin)
  12035.  
  12036. From S.P.Q.Rahtz@ecs.southampton.ac.uk  Wed Oct  3 09:05:15 1990
  12037. Received: from sun2.nsfnet-relay.ac.uk by megaron.cs.arizona.edu (5.61/15) via SMTP
  12038.     id AA01776; Wed, 3 Oct 90 09:05:15 -0700
  12039. Received: from vax.nsfnet-relay.ac.uk by sun2.nsfnet-relay.ac.uk 
  12040.           with SMTP inbound id aa04911; Wed, 3 Oct 90 15:12:39 +0000
  12041. Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet 
  12042.           with NIFTP id aa10399; 3 Oct 90 15:12 BST
  12043. Received: from vicky.ecs.soton.ac.uk by hilliard.ecs.soton.ac.uk;
  12044.           Wed, 3 Oct 90 15:42:10 BST
  12045. From: Sebastian Rahtz <S.P.Q.Rahtz@ecs.southampton.ac.uk>
  12046. Date: Wed, 3 Oct 90 15:41:36 bst
  12047. Message-Id: <5187.9010031441@manutius.ecs.soton.ac.uk>
  12048. To: icon-group@cs.arizona.edu
  12049. In-Reply-To: <9010031337.AA01510@cherry04.cray.com>
  12050. Subject: Re: Icon as RDBMS report writer language
  12051.  
  12052. "David S. Cargo" writes:
  12053.  > problem report data base using ORACLE.  My section in Cray likes to see
  12054.  > reports about our status weekly.  Using canned and dynamically
  12055.  > generated queries, I extract a formatted report that I then feed to an
  12056.  > Icon program for further processing.  The further processing in this
  12057.  > case means extracting data and rewriting it with LaTeX code and macro
  12058.  > calls defined in the tables.sty file.  The result is formatted with
  12059. I have a large Ingres database of gravestones and inscriptions, and I
  12060. used to have an Icon program to fiddle with the output, as in the
  12061. example above. then I realized that a lot of the same work could be
  12062. done in LaTeX itself...; so Icon now has no place in the scheme. This
  12063. is because I have to the database searching with a C program with
  12064. embedded SQL which is linked to Ingres libraries. What I would really
  12065. like to do, of course, is to write my program in Icon with embedded
  12066. SQL. I don't suppose anyone has done this by any chance? the idea of a
  12067. generator which returned tuples from the database is rather
  12068. attractive.
  12069.  
  12070. Sebastian Rahtz
  12071.  
  12072.  
  12073. From tenaglia@mis.mcw.edu  Wed Oct  3 09:06:08 1990
  12074. Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  12075.     id AA01819; Wed, 3 Oct 90 09:06:08 -0700
  12076. Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP 
  12077.     id AA08815; Wed, 3 Oct 90 11:47:55 EDT
  12078. Received: by uwm.edu; id AA22471; Wed, 3 Oct 90 10:40:01 -0500
  12079. Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  12080.           Wed,  3 Oct 90 09:42:21 CDT
  12081. Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
  12082.           Wed,  3 Oct 90 09:23:11 CDT
  12083. Date: Wed,  3 Oct 90 09:23:11 CDT
  12084. Message-Id: <0093DA19CC40C1E0.20200837@mis.mcw.edu>
  12085. From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
  12086. Subject: Icon Database
  12087. To: icon-group@cs.arizona.edu
  12088.  
  12089.  
  12090. Concerning Icon Databases :
  12091.  
  12092. I wrote one. It's not relational. The initial version held the data in a list.
  12093. The records had fixed size fields delimited with \377 (X'FF'). Later I stored
  12094. the data in a table of lists where the database key formed the 'entry' and
  12095. entire lines (\377 delimited) in a list as the 'assignment'. A database would
  12096. actually occupy 2 files. The data file and a description file. Here's a sample
  12097. of a description file (PB.ATCP).
  12098.  
  12099. data in pb.dat
  12100. header is ABBREVIATED PHONEBOOK DATABASE &DATE
  12101. fields are First_Name Last__Name Ext/Flag__ Department Main_Phone Information 
  12102. lengths are 10 10 4 20 12 20 
  12103. look up 2
  12104. sort on 2
  12105. print using 1 57 lpa0 n/a
  12106. title begin
  12107. < <    PERSONAL VENDOR/DEPARTMENTAL TELEPHONE DATABASE > >
  12108. TODAY IS &DATE                                        &PAGE
  12109. NAME                    E/F   DEPARTMENT            PHONE         INFORMATION
  12110. ======================  ====  ====================  ========      ===========
  12111. title end
  12112.  
  12113. One invokes the database using the description file. 'data in' tells which file
  12114. the data is in. 'header is' puts a header on all the screens to remind one what
  12115. database is active. 'fields are' describes the field names as they would appear
  12116. on the screen. 'lengths are' describes the number of bytes in each field. Space
  12117. characters delimit the tokens, and the 'fields are' and 'lengths are' must have
  12118. the same amount of tokens. 'look up' defines the look up key, which is one or
  12119. for fields referenced by position from 1 to ???.'sort on' specified the default
  12120. order for purposes of printing or viewing. 'print using' indicated the spacing,
  12121. 1=single 2=double, lines per page, default printer queue, and whether to print
  12122. all as a solid block (n/a), skip a line when the 'lookup' field changed (skip),
  12123. or to eject a page when the the 'lookup' field(s) changed. 'title begin' and
  12124. 'title end' describe the print out title for every page. &DATE generates todays
  12125. date on the screen header or print title. &PAGE in the print title generates
  12126. the page # while printing the report.
  12127.  
  12128. The database capacity and performance may be an issue. The list based version
  12129. was very slow with lookups and deletes. The table version is real slow on the
  12130. print version, as it sorts the data before printing. I never measured it's
  12131. maximum limit. It seems useful upto 1000 items. One can change to a different
  12132. database or data file on the fly, insert or delete columns, change the lookup
  12133. key, alter the default settings. I actually use it for some useful things.
  12134. But it's not relational. I think of it as a data 'editor' and report writer.
  12135.  
  12136. Chris Tenaglia (System Manager)
  12137. Medical College of Wisconsin
  12138. 8701 W. Watertown Plank Rd.
  12139. Milwaukee, WI 53226
  12140. (414)257-8765
  12141. tenaglia@mis.mcw.edu, mcwmis!tenaglia
  12142.  
  12143. From eric@ai.leeds.ac.uk  Wed Oct  3 13:33:45 1990
  12144. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  12145.     id AA17216; Wed, 3 Oct 90 13:33:45 -0700
  12146. Received: from UKACRL.BITNET by Arizona.edu; Wed, 3 Oct 90 13:33 MST
  12147. Received: from RL.IB by UKACRL.BITNET (Mailer R2.03B) with BSMTP id 6391; Wed,
  12148.  03 Oct 90 19:16:43 BST
  12149. Date: Wed, 3 Oct 90 11:55:28 GMT
  12150. From: E S Atwell <eric@ai.leeds.ac.uk>
  12151. Subject: NeuralNets: help requested
  12152. To: icon-group@cs.arizona.edu
  12153. Cc: eric@ai.leeds.ac.uk
  12154. Message-Id: <5656.9010031155@ai.leeds.ac.uk>
  12155. Via:        UK.AC.LEEDS.AI;  3 OCT 90 19:16:05 BST
  12156. Via: 
  12157. X-Envelope-To: icon-group@cs.arizona.edu
  12158.  
  12159. I mailed icon-project@edu.arizona.cs asking for any Icon implemetations of
  12160. Neural Networks; the reply came that the Icon project team didnt have any,
  12161. but other subscribers to icon-group might.  Is there anyone else out there
  12162. interested in neural nets, who can help us?    cf the following:
  12163.  
  12164. From eric Mon Oct  1 12:22:38 1990
  12165. Subject: Neural Networks
  12166.  
  12167. Are there any Icon implementations of neural networks that you know of?
  12168. I have an eural network simulator package for Sun workstations (NeuralWare)
  12169. which requires input and outputs to be specified as numerical values in a file;
  12170. I am experimenting with language processing (specifically, parsing), so need
  12171. to convert my training data (a Treebank or Corpus of syntax-trees for parsed
  12172. English text samples) into numerical form.  I have started with varoius Icon
  12173. reformatting programs to transform the trees into required input/output training
  12174. format; but it struck me that it would be much neater to do the whole thing
  12175. in a single icon program, rather than Icon programs interfacing to a 'black
  12176. box' package.  Any suggestions?  I couldnt find anything suitable in the
  12177. library programs availale by FTP from edu.arizona.cs.
  12178. Thanks for any help you can offer.  The AI Division here at Leeds has only
  12179. recently been established (over the past year we have swelled from 5 to 10
  12180. teaching staff, and we're just setting up new courses including a BSc in
  12181. Cognitive Science), so this may be a good time to impress my new colleagues
  12182. with the versatility and elegance of Icon (opinion is split between Pop-11,
  12183. Prolog, Lisp, and C at the moment).
  12184.  
  12185.  Eric Steven Atwell
  12186.                 Centre for Computer Analysis of Language And Speech (CCALAS)
  12187.                 Artificial Intelligence Division, School of Computer Studies
  12188.  phone: +44 532 335761                                      Leeds University
  12189.  FAX:   +44 532 335468                                         Leeds LS2 9JT
  12190.  JANET: eric@uk.ac.leeds.ai                                          England
  12191.  EARN/BITNET/ARPA: eric%leeds.ai@ac.uk
  12192.  
  12193.  
  12194. From shafto@eos.arc.nasa.gov  Thu Oct  4 09:35:03 1990
  12195. Received: from eos.arc.nasa.gov by megaron (5.61/15) via SMTP
  12196.     id AA29950; Thu, 4 Oct 90 09:35:03 -0700
  12197. Received: Thu, 4 Oct 90 09:33:52 PDT by eos.arc.nasa.gov (5.59/1.2)
  12198. Date: Thu, 4 Oct 90 09:33:52 PDT
  12199. From: Michael Shafto <shafto@eos.arc.nasa.gov>
  12200. Message-Id: <9010041633.AA08099@eos.arc.nasa.gov>
  12201. To: eric@ai.leeds.ac.uk, icon-group@cs.arizona.edu
  12202. Subject: Re:  NeuralNets: help requested
  12203. Cc: shafto@EOS.ARC.NASA.GOV
  12204.  
  12205. I played around with neural nets in Icon a few
  12206. years ago.  Bottom line:  the flexibility of
  12207. Icon in manipulating lists and other data structures
  12208. was a big plus at development time, but you would
  12209. want to be in C for serious work due to the hard
  12210. requirement for raw speed (plus the complexity of
  12211. your program is not a real driving factor in this
  12212. kind of work).
  12213.  
  12214. Mike
  12215.  
  12216. From icon-group-request@arizona.edu  Thu Oct  4 22:53:52 1990
  12217. Resent-From: icon-group-request@arizona.edu
  12218. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
  12219.     id AA07959; Thu, 4 Oct 90 22:53:52 -0700
  12220. Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 4 Oct 90 22:53 MST
  12221. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27311; Thu, 4 Oct 90 22:46:20
  12222.  -0700
  12223. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  12224.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  12225.  usenet@ucbvax.Berkeley.EDU if you have questions)
  12226. Resent-Date: Thu, 4 Oct 90 22:53 MST
  12227. Date: 5 Oct 90 04:57:53 GMT
  12228. From: midway!quads.uchicago.edu!goer@mimsy.umd.edu
  12229. Subject: more code; bal like routine
  12230. Sender: icon-group-request@arizona.edu
  12231. Resent-To: icon-group@cs.arizona.edu
  12232. To: icon-group@arizona.edu
  12233. Resent-Message-Id: <24ABD06BD6152009B0@Arizona.edu>
  12234. Message-Id: <1990Oct5.045753.29857@midway.uchicago.edu>
  12235. Organization: University of Chicago
  12236. X-Envelope-To: icon-group@CS.Arizona.EDU
  12237. X-Vms-To: icon-group@Arizona.EDU
  12238.  
  12239.  
  12240. I had to write this the other day, and it seemed to be something that
  12241. would be of general interest.
  12242.  
  12243. -Richard
  12244.  
  12245.  
  12246. ############################################################################
  12247. #
  12248. #    Name:     slashbal.icn
  12249. #
  12250. #    Title:     Bal() with backslash escaping
  12251. #
  12252. #    Author:     Richard L. Goerwitz
  12253. #
  12254. #    Version: 1.1
  12255. #
  12256. ############################################################################
  12257. #
  12258. #  I am often frustrated at bal()'s inability to deal elegantly with
  12259. #  the common \backslash escaping convention (a way of telling Unix
  12260. #  Bourne and C shells, for instance, not to interpret a given
  12261. #  character as a "metacharacter").  I recognize that bal()'s generic
  12262. #  behavior is a must, and so I wrote slashbal() to fill the gap.
  12263. #
  12264. #  Slashbal behaves like bal, except that it ignores, for purposes of
  12265. #  balancing, any character which is preceded by a backslash.  Note
  12266. #  that we are talking about internal backslashes, and not necessarily
  12267. #  the backslashes used in Icon string literals.  If you have "\(" in
  12268. #  your source code, the string produced will have no backslash.  To
  12269. #  get this effect, you would need to write "\\(."
  12270. #
  12271. #  BUGS:  Note that, like bal() (v8), slashbal() cannot correctly
  12272. #  handle cases where c2 and c3 intersect.
  12273. #
  12274. ############################################################################
  12275. #
  12276. #  Links: none
  12277. #
  12278. ############################################################################
  12279.  
  12280. procedure slashbal(c1, c2, c3, s, i, j)
  12281.  
  12282.     local allcs, chr, count
  12283.  
  12284.     /c1 := &cset
  12285.     /c2 := '('
  12286.     /c3 := ')'
  12287.     allcs := c1 ++ c2 ++ c3 ++ '\\'
  12288.  
  12289.     /s := \&subject | stop("slashbal:  No string argument.")
  12290.     /i := \&pos | 1
  12291.     /j := *s + 1
  12292.  
  12293.     count := 0
  12294.     s ? {
  12295.     while tab(upto(allcs)) do {
  12296.         chr := move(1)
  12297.         if chr == "\\" then {
  12298.         chr := move(1) | fail
  12299.         if any(c1, chr) & count = 0 then
  12300.             suspend .&pos - 1
  12301.         }
  12302.         else {
  12303.         if any(c1, chr) & count = 0 then
  12304.             suspend .&pos - 1
  12305.         if any(c2, chr) then
  12306.             count +:= 1
  12307.         else if any(c3, chr) then
  12308.             count -:= 1
  12309.         }
  12310.     }
  12311.     }
  12312.  
  12313. end
  12314.  
  12315. From goer%sophist@gargoyle.uchicago.edu  Sat Oct  6 12:16:35 1990
  12316. Resent-From: goer%sophist@gargoyle.uchicago.edu
  12317. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  12318.     id AA07236; Sat, 6 Oct 90 12:16:35 -0700
  12319. Return-Path: goer@sophist.uchicago.edu
  12320. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 6 Oct 90 12:16 MST
  12321. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  12322.  AA15090; Sat, 6 Oct 90 14:15:54 199
  12323. Received: by sophist (4.1/UofC3.1X) id AA18746; Sat, 6 Oct 90 14:19:53 CDT
  12324. Resent-Date: Sat, 6 Oct 90 12:16 MST
  12325. Date: Sat, 6 Oct 90 14:19:53 CDT
  12326. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  12327. Subject: find duplicate procedures
  12328. Resent-To: icon-group@cs.arizona.edu
  12329. To: icon-group@arizona.edu
  12330. Resent-Message-Id: <237282D0BE4B201416@Arizona.edu>
  12331. Message-Id: <9010061919.AA18746@sophist>
  12332. X-Envelope-To: icon-group@CS.Arizona.EDU
  12333. X-Vms-To: icon-group@Arizona.EDU
  12334.  
  12335. I posted some code a while ago for removing duplicate procedures
  12336. from library files.  It was tested under Unix only, and only in
  12337. my own environment.  It's now been tested under MS-DOS (thanks to
  12338. a few helpers), and works satisfactorily, as long as the lib-
  12339. raries are all in MS-DOS text-file format.  Here's a re-post.
  12340.  
  12341. Please, use this if you plan on posting library-style code.  It
  12342. will save a lot of headaches for the elves who put together the
  12343. IPL....
  12344.  
  12345. -Richard
  12346.  
  12347. P.S.  If someone wants this, and can't umpack a shell archive,
  12348. please tell me what format you can upack (tar, arc, zoo, etc.),
  12349. and I'll mail it to you.
  12350.  
  12351. ---- Cut Here and feed the following to sh ----
  12352. #!/bin/sh
  12353. # This is a shell archive (produced by shar 3.49)
  12354. # To extract the files from this archive, save it to a file, remove
  12355. # everything above the "!/bin/sh" line above, and type "sh file_name".
  12356. #
  12357. # made 10/06/1990 16:34 UTC by goer@sophist.uchicago.edu
  12358. #
  12359. # existing files will NOT be overwritten unless -c is specified
  12360. # This format requires very little intelligence at unshar time.
  12361. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  12362. #                                                                          
  12363. #
  12364. # This shar contains:
  12365. # length  mode       name
  12366. # ------ ---------- ------------------------------------------
  12367. #   8294 -r--r--r-- duplproc.icn
  12368. #    603 -rw-r--r-- README
  12369. #    623 -rw-r--r-- Makefile.dist
  12370. #
  12371. if test -r _shar_seq_.tmp; then
  12372.     echo 'Must unpack archives in sequence!'
  12373.     echo Please unpack part `cat _shar_seq_.tmp` next
  12374.     exit 1
  12375. fi
  12376. # ============= duplproc.icn ==============
  12377. if test -f 'duplproc.icn' -a X"$1" != X"-c"; then
  12378.     echo 'x - skipping duplproc.icn (File already exists)'
  12379.     rm -f _shar_wnt_.tmp
  12380. else
  12381. > _shar_wnt_.tmp
  12382. echo 'x - extracting duplproc.icn (Text)'
  12383. sed 's/^X//' << 'SHAR_EOF' > 'duplproc.icn' &&
  12384. X############################################################################
  12385. X#
  12386. X#    Name:     duplproc.icn
  12387. X#
  12388. X#    Title:     Find duplicate procedure/record identifiers
  12389. X#
  12390. X#    Author:     Richard L. Goerwitz
  12391. X#
  12392. X#    Version: 1.5
  12393. X#
  12394. X############################################################################
  12395. X#
  12396. X#  Use this if you plan on posting code!
  12397. X#
  12398. X#  Duplproc.icn compiles into a program which will search through
  12399. X#  every directory in your ILIBS environment variable (and/or in the
  12400. X#  directories supplied as arguments to the program).  If it finds any
  12401. X#  duplicate procedure or record identifiers, it will report this on
  12402. X#  the standard output.
  12403. X#
  12404. X#  It is important to try to use unique procedure names in programs
  12405. X#  you write, especially if you intend to link in some of the routines
  12406. X#  contained in the IPL.  Checking for duplicate procedure names has
  12407. X#  been somewhat tedious in the past, and many of us (me included)
  12408. X#  must be counted as guilty for not checking more thoroughly.  Now,
  12409. X#  however, checking should be a breeze.
  12410. X#
  12411. X############################################################################
  12412. X#
  12413. X#  Links:  none
  12414. X#
  12415. X#  Requires:  Unix (MS-DOS will work if all files are in MS-DOS format)
  12416. X#
  12417. X############################################################################
  12418. X
  12419. Xrecord procedure_stats(name, file, lineno)
  12420. X
  12421. Xprocedure main(a)
  12422. X
  12423. X    local proc_table, fname, elem, lib_file, tmp
  12424. X
  12425. X    #     usage:  duplproc [libdirs]
  12426. X    #
  12427. X    # Where libdirs is a series of space-separated directories in
  12428. X    # which relevant library files are to be found.  To the
  12429. X    # directories listed in libdirs are added any directories found in
  12430. X    # the ILIBS environment variable.
  12431. X
  12432. X    proc_table := table()
  12433. X
  12434. X    # Put all command-line option paths, and ILIBS paths, into one sorted
  12435. X    # list.  Then get the names of all .icn filenames in those paths.
  12436. X    every fname := !get_icn_filenames(getlibpaths(a)) do {
  12437. X    # For each .icn filename, open that file, and find all procedure
  12438. X    # calls in it.
  12439. X    if not (lib_file := open(fname, "r")) then
  12440. X        write(&errout,"Can't open ",fname," for reading.")
  12441. X    else {
  12442. X        # Find all procedure calls in lib_file.
  12443. X        every elem := !get_procedures(lib_file,fname) do {
  12444. X        if /proc_table[elem.name] := set()
  12445. X        then insert(proc_table[elem.name],elem)
  12446. X        else {
  12447. X            write("\"", elem.name, "\"",
  12448. X            " is defined in ",*proc_table[elem.name]+1," places:")
  12449. X            every tmp := !proc_table[elem.name] do
  12450. X            write("     ",tmp.file, ", line ",tmp.lineno)
  12451. X            write("     ",elem.file, ", line ", elem.lineno)
  12452. X        }
  12453. X        }
  12454. X        close(lib_file)
  12455. X    }
  12456. X    }
  12457. X
  12458. X
  12459. Xend
  12460. X
  12461. X
  12462. X
  12463. Xprocedure getlibpaths(ipl_paths)
  12464. X
  12465. X    # Unite command-line args and ILIBS environment variable into one
  12466. X    # path list.
  12467. X
  12468. X    local i, path
  12469. X
  12470. X    # Make sure all paths have a consistent format (one trailing slash).a
  12471. X    if *\ipl_paths > 0 then {
  12472. X    every i := 1 to *ipl_paths do {
  12473. X        ipl_paths[i] := fixup_path(ipl_paths[i])
  12474. X    }
  12475. X    ipl_paths := set(ipl_paths)
  12476. X    }
  12477. X    else ipl_paths := set()
  12478. X
  12479. X    # If the ILIBS environment variable is set, read it into
  12480. X    # ipl_paths.  Spaces - NOT COLONS - are used as separators.
  12481. X    getenv("ILIBS") ? {
  12482. X    while path := tab(find(" ")) do {
  12483. X        insert(ipl_paths, fixup_path(path))
  12484. X        tab(many(' '))
  12485. X    }
  12486. X    insert(ipl_paths, fixup_path(tab(0)))
  12487. X    }
  12488. X
  12489. X    return sort(ipl_paths)
  12490. X
  12491. Xend
  12492. X
  12493. X
  12494. X
  12495. Xprocedure fixup_path(s)
  12496. X    # Make sure paths have a consistent format.
  12497. X    return "/" ~== (trim(s,'/') || "/")
  12498. Xend
  12499. X
  12500. X
  12501. X
  12502. Xprocedure get_procedures(intext,fname)
  12503. X
  12504. X    # Extracts the names of all procedures declared in file f.
  12505. X    # Returns them in a list, each of whose elements have the
  12506. X    # form record procedure_stats(procedurename, filename, lineno).
  12507. X
  12508. X    local psl, f_pos
  12509. X    static name_chars
  12510. X    initial {
  12511. X    name_chars := &ucase ++ &lcase ++ &digits ++ '_'
  12512. X    }
  12513. X
  12514. X    # Initialize procedure-name list, line count.
  12515. X    psl := list()
  12516. X    line_no := 0
  12517. X
  12518. X    # Find procedure declarations in intext.
  12519. X    while line := read(intext) & line_no +:= 1 do {
  12520. X    take_out_comments(line) ? {
  12521. X        if tab(match("procedure")) then {
  12522. X        tab(many(' \t')) &
  12523. X            put(psl, procedure_stats(
  12524. X                "main" ~== tab(many(name_chars)), fname, line_no))
  12525. X        }
  12526. X    }
  12527. X    }
  12528. X
  12529. X    return psl   # returns empty list if no procedures found
  12530. X
  12531. Xend
  12532. X
  12533. X
  12534. X
  12535. Xprocedure take_out_comments(s)
  12536. X
  12537. X    # Commented-out portions of Icon code - strip 'em.  Fails on lines
  12538. X    # which, either stripped or otherwise, come out as an empty string.
  12539. X    #
  12540. X    # BUG:  Does not handle lines which use the _ string-continuation
  12541. X    # notation.  Typically take_out_comments barfs on the next line.
  12542. X
  12543. X    local i, j, c, c2
  12544. X
  12545. X    s ? {
  12546. X    tab(many(' \t'))
  12547. X    pos(0) & fail
  12548. X        find("#") | (return trim(tab(0),' \t'))
  12549. X    match("#") & fail
  12550. X    (s2 <- tab(find("#"))) ? {
  12551. X        c2 := &null
  12552. X        while tab(upto('\\"\'')) do {
  12553. X        case c := move(1) of {
  12554. X            "\\"   : {
  12555. X            if match("^")
  12556. X            then move(2)
  12557. X            else move(1)
  12558. X            }
  12559. X            default: {
  12560. X            if \c2
  12561. X            then (c == c2, c2 := &null)
  12562. X            else c2 := c
  12563. X            }
  12564. X        }
  12565. X        }
  12566. X        /c2
  12567. X    }
  12568. X    return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
  12569. X    }
  12570. X
  12571. Xend
  12572. X
  12573. X
  12574. X
  12575. Xprocedure get_icn_filenames(lib_paths)
  12576. X
  12577. X    # Return the names of all .icn files in all of the paths in the
  12578. X    # list lib_paths.  The dir routine used depends on which OS we
  12579. X    # are running under.
  12580. X
  12581. X    local procedure_stat_list
  12582. X    static get_dir
  12583. X    initial get_dir := set_getdir_by_os()
  12584. X
  12585. X    procedure_stat_list := list()
  12586. X    # Run through every possible path in which files might be found,
  12587. X    # and get a list of procedures contained in those files.
  12588. X    every procedure_stat_list |||:= get_dir(!lib_paths)
  12589. X
  12590. X    return procedure_stat_list
  12591. X
  12592. Xend
  12593. X
  12594. X
  12595. X
  12596. Xprocedure set_getdir_by_os()
  12597. X
  12598. X    if find("UNIX", &features)
  12599. X    then return unix_get_dir
  12600. X    else if find("MS-DOS", &features)
  12601. X    then return msdos_get_dir
  12602. X    else stop("Your operating system is not (yet) supported.")
  12603. X
  12604. Xend
  12605. X
  12606. X
  12607. X
  12608. Xprocedure msdos_get_dir(dir)
  12609. X
  12610. X    # Returns a sorted list of all filenames (full paths included) in
  12611. X    # directory "dir."  The list is sorted.  Fails on invalid or empty
  12612. X    # directory.  Aborts if temp file cannot be opened.
  12613. X    #
  12614. X    # Temp files can be directed to one or another directory either by
  12615. X    # manually setting the variable temp_dir below, or by setting the
  12616. X    # value of the environment variable TEMPDIR to an appropriate
  12617. X    # directory name.
  12618. X
  12619. X    local in_dir, filename_list, line
  12620. X    static temp_dir
  12621. X    initial {
  12622. X        temp_dir := 
  12623. X            (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
  12624. X                ".\\"
  12625. X    }
  12626. X
  12627. X    # Get name of tempfile to be used.
  12628. X    temp_name := get_dos_tempname(temp_dir) |
  12629. X    stop("No more available tempfile names!")
  12630. X
  12631. X    # Make sure we have an unambiguous directory name, with backslashes
  12632. X    # instead of Unix-like forward slashes.
  12633. X    dir := trim(map(dir, "/", "\\"), '\\') || "\\"
  12634. X
  12635. X    # Put dir listing into a temp file.
  12636. X    system("dir "||dir||" > "||temp_name)
  12637. X
  12638. X    # Put tempfile entries into a list, removing blank- and
  12639. X    # space-initial lines.  Exclude directories (i.e. return file
  12640. X    # names only).
  12641. X    in_dir := open(temp_name,"r") |
  12642. X    stop("Can't open temp file in directory ",temp_dir,".")
  12643. X    filename_list := list()
  12644. X    every filename := ("" ~== !in_dir) do {
  12645. X        match(" ",filename) | find(" <DIR>", filename) & next
  12646. X    filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
  12647. X    if filename ? (tab(find(".ICN")+4), pos(0))
  12648. X    then put(filename_list, map(dir || filename))
  12649. X    }
  12650. X
  12651. X    # Clean up.
  12652. X    close(in_dir) & remove(temp_name)
  12653. X
  12654. X    # Check to be sure we actually managed to read some files.
  12655. X    if *filename_list = 0 then fail
  12656. X    else return sort(filename_list)
  12657. X
  12658. Xend
  12659. X
  12660. X
  12661. X
  12662. Xprocedure get_dos_tempname(dir)
  12663. X
  12664. X    # Don't clobber existing files.  Get a unique temp file name for
  12665. X    # use as a temporary storage site.
  12666. X
  12667. X    every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
  12668. X    temp_file := open(temp_name,"r") | break
  12669. X        close(temp_file)
  12670. X    }
  12671. X    return \temp_name
  12672. X
  12673. Xend
  12674. X
  12675. X
  12676. X
  12677. Xprocedure unix_get_dir(dir)
  12678. X
  12679. X    dir := trim(dir, '/') || "/"
  12680. X    filename_list := list()
  12681. X    in_dir := open("/bin/ls -F "||dir, "pr")
  12682. X    every filename := ("" ~== !in_dir) do {
  12683. X    match("/",filename,*filename) & next
  12684. X    if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
  12685. X    then put(filename_list, trim(dir || filename, '*'))
  12686. X    }
  12687. X    close(in_dir)
  12688. X
  12689. X    if *filename_list = 0 then fail
  12690. X    else return filename_list
  12691. X
  12692. Xend
  12693. SHAR_EOF
  12694. true || echo 'restore of duplproc.icn failed'
  12695. rm -f _shar_wnt_.tmp
  12696. fi
  12697. # ============= README ==============
  12698. if test -f 'README' -a X"$1" != X"-c"; then
  12699.     echo 'x - skipping README (File already exists)'
  12700.     rm -f _shar_wnt_.tmp
  12701. else
  12702. > _shar_wnt_.tmp
  12703. echo 'x - extracting README (Text)'
  12704. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  12705. XSee the comments prepended to duplproc.icn for a statement of what
  12706. Xthis program is and does.  To create it on a Unix system, you can
  12707. Xjust mv Makefile.dist to Makefile and make.  If you want to install
  12708. Xit, type "make install" as root.  Be sure to check the Makefile
  12709. Xfirst, though, to be sure the installation routine uses the correct
  12710. Xdirectories and permissions for your system.
  12711. X
  12712. XUsers of other systems, you're on your own.  This will probably work
  12713. XMS-DOS, but it has not been extensively tested under that OS.  It is
  12714. Xhard to get a directory listing from within Icon on systems that
  12715. Xdon't support pipes.
  12716. SHAR_EOF
  12717. true || echo 'restore of README failed'
  12718. rm -f _shar_wnt_.tmp
  12719. fi
  12720. # ============= Makefile.dist ==============
  12721. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  12722.     echo 'x - skipping Makefile.dist (File already exists)'
  12723.     rm -f _shar_wnt_.tmp
  12724. else
  12725. > _shar_wnt_.tmp
  12726. echo 'x - extracting Makefile.dist (Text)'
  12727. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  12728. XPROGNAME = duplproc
  12729. X
  12730. X# Please edit these to reflect your local file structure & conventions.
  12731. XDESTDIR = /usr/local/bin
  12732. XOWNER = bin
  12733. XGROUP = bin
  12734. X
  12735. XSRC = $(PROGNAME).icn
  12736. X
  12737. X$(PROGNAME): $(PROGNAME).icn
  12738. X    icont $(PROGNAME).icn
  12739. X
  12740. X# Pessimistic assumptions regarding the environment (in particular,
  12741. X# I don't assume you have the BSD "install" shell script).
  12742. Xinstall: $(PROGNAME)
  12743. X    @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
  12744. X    cp $(PROGNAME) $(DESTDIR)/
  12745. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  12746. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  12747. X    @echo "\nInstallation done.\n"
  12748. X
  12749. Xclean:
  12750. X    -rm -f *~ .u?
  12751. X    -rm -f $(PROGNAME)
  12752. SHAR_EOF
  12753. true || echo 'restore of Makefile.dist failed'
  12754. rm -f _shar_wnt_.tmp
  12755. fi
  12756. exit 0
  12757.  
  12758. From goer%sophist@gargoyle.uchicago.edu  Sat Oct  6 12:29:51 1990
  12759. Resent-From: goer%sophist@gargoyle.uchicago.edu
  12760. Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  12761.     id AA07483; Sat, 6 Oct 90 12:29:51 -0700
  12762. Return-Path: goer@sophist.uchicago.edu
  12763. Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 6 Oct 90 12:29 MST
  12764. Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
  12765.  AA15387; Sat, 6 Oct 90 14:29:09 199
  12766. Received: by sophist (4.1/UofC3.1X) id AA18781; Sat, 6 Oct 90 14:33:08 CDT
  12767. Resent-Date: Sat, 6 Oct 90 12:29 MST
  12768. Date: Sat, 6 Oct 90 14:33:08 CDT
  12769. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  12770. Subject: improved merging program
  12771. Resent-To: icon-group@cs.arizona.edu
  12772. To: icon-group@arizona.edu
  12773. Resent-Message-Id: <2370A7C5B86B201427@Arizona.edu>
  12774. Message-Id: <9010061933.AA18781@sophist>
  12775. X-Envelope-To: icon-group@CS.Arizona.EDU
  12776. X-Vms-To: icon-group@Arizona.EDU
  12777.  
  12778. This is the promised improved merging program.  Essentially, you can
  12779. feed it a file you've created, and it will go through all your lib-
  12780. raries, digging up any procedures called in the file, and then out-
  12781. putting them, together with the original file, on the standard out-
  12782. put.
  12783.  
  12784. Not everyone has the IPL installed.  Not everyone has the most recent
  12785. *version* installed.  Not everyone knows how to link programs to lib-
  12786. rary routines.  Not everyone has their IPATH environment variable set
  12787. up correctly anyway.
  12788.  
  12789. Sometimes it's just easier to post a program as-is, with all necessary
  12790. routines present in the source.  This program will do all the work of
  12791. linking in necessary routines for you, and merging them all into a
  12792. single source file.
  12793.  
  12794. If you are lazy, you can even use this program to concatenate relevant
  12795. files in a single directory into a single file.  Just offer the file
  12796. with the main procedure as arg 1, and then make the current directory
  12797. arg 2.  Imerge (the program's name) will find everything it needs, and
  12798. discard the rest.
  12799.  
  12800. Note that you usually get a space savings in the icode file that results
  12801. from compiling imerge's output.  It does not link in whole source files,
  12802. but only those portions of the source file that are needed by the pro-
  12803. gram in question.
  12804.  
  12805. -Richard
  12806.  
  12807.  
  12808. ---- Cut Here and feed the following to sh ----
  12809. #!/bin/sh
  12810. # This is a shell archive (produced by shar 3.49)
  12811. # To extract the files from this archive, save it to a file, remove
  12812. # everything above the "!/bin/sh" line above, and type "sh file_name".
  12813. #
  12814. # made 10/06/1990 08:12 UTC by goer@sophist.uchicago.edu
  12815. # Source directory /u/richard/Imerge
  12816. #
  12817. # existing files will NOT be overwritten unless -c is specified
  12818. # This format requires very little intelligence at unshar time.
  12819. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  12820. #
  12821. #                                                                          
  12822. #                                                                          
  12823. #
  12824. # This shar contains:
  12825. # length  mode       name
  12826. # ------ ---------- ------------------------------------------
  12827. #   1611 -r--r--r-- findrecs.icn
  12828. #   4161 -r--r--r-- getcalls.icn
  12829. #   3638 -r--r--r-- getnames.icn
  12830. #   1457 -r--r--r-- getpaths.icn
  12831. #   1248 -r--r--r-- getprocs.icn
  12832. #   7738 -r--r--r-- imerge.icn
  12833. #   1513 -r--r--r-- stripcom.icn
  12834. #    832 -rw-r--r-- Makefile.dist
  12835. #    607 -rw-r--r-- README
  12836. #
  12837. if test -r _shar_seq_.tmp; then
  12838.     echo 'Must unpack archives in sequence!'
  12839.     echo Please unpack part `cat _shar_seq_.tmp` next
  12840.     exit 1
  12841. fi
  12842. # ============= findrecs.icn ==============
  12843. if test -f 'findrecs.icn' -a X"$1" != X"-c"; then
  12844.     echo 'x - skipping findrecs.icn (File already exists)'
  12845.     rm -f _shar_wnt_.tmp
  12846. else
  12847. > _shar_wnt_.tmp
  12848. echo 'x - extracting findrecs.icn (Text)'
  12849. sed 's/^X//' << 'SHAR_EOF' > 'findrecs.icn' &&
  12850. X############################################################################
  12851. X#
  12852. X#    Name:     findrecs.icn
  12853. X#
  12854. X#    Title:     find record & global declarations
  12855. X#
  12856. X#    Author:     Richard L. Goerwitz
  12857. X#
  12858. X#    Version: 1.2
  12859. X#
  12860. X############################################################################
  12861. X#
  12862. X#  Hunts down global and record declarations.  Puts them into two global
  12863. X#  tables to be used later (part of the imerge package).
  12864. X#
  12865. X############################################################################
  12866. X
  12867. Xglobal record_table, global_table
  12868. X
  12869. Xprocedure find_records(intext, fname)
  12870. X
  12871. X    local line, i, entry
  12872. X    # global record_table, global_table
  12873. X    static wchars, name_chars
  12874. X    initial {
  12875. X        record_table := table()
  12876. X    global_table := table()
  12877. X    wchars := &cset -- ','
  12878. X    name_chars := &ucase ++ &lcase ++ &digits ++ '_'
  12879. X    }
  12880. X
  12881. X    every line := strip_comments(!intext) do {
  12882. X    match("global"|"record",line) | next
  12883. X        until bal(wchars, "(", ")", line, -1) do
  12884. X        line ||:= strip_comments(!intext)
  12885. X    line ? {
  12886. X        if tab(match("record")) then {
  12887. X        tab(many(' \t')) &
  12888. X        if entry := "#  Source file:  " || fname || "\n" ||
  12889. X            "record " || tab(many(name_chars)) ||
  12890. X            (tab(many(' \t')) | &null, "") || tab(match("(")) ||
  12891. X            tab(find(")")+1) & pos(0)
  12892. X        then {
  12893. X            /record_table[fname] := set()
  12894. X            insert(record_table[fname], entry)
  12895. X        }
  12896. X        }
  12897. X        else if tab(match("global")) then {
  12898. X        if tab(many(' \t')) then {
  12899. X            /global_table[fname] := set()
  12900. X            insert(global_table[fname], 
  12901. X                "#  Source file:  "|| fname ||"\n"|| "global "||tab(0))
  12902. X        }
  12903. X        }
  12904. X    }
  12905. X    }
  12906. X
  12907. X    return "records & globals accumulated"
  12908. X
  12909. Xend
  12910. SHAR_EOF
  12911. true || echo 'restore of findrecs.icn failed'
  12912. rm -f _shar_wnt_.tmp
  12913. fi
  12914. # ============= getcalls.icn ==============
  12915. if test -f 'getcalls.icn' -a X"$1" != X"-c"; then
  12916.     echo 'x - skipping getcalls.icn (File already exists)'
  12917.     rm -f _shar_wnt_.tmp
  12918. else
  12919. > _shar_wnt_.tmp
  12920. echo 'x - extracting getcalls.icn (Text)'
  12921. sed 's/^X//' << 'SHAR_EOF' > 'getcalls.icn' &&
  12922. X############################################################################
  12923. X#
  12924. X#    Name:     getcalls.icn
  12925. X#
  12926. X#    Title:     Get_procedure_calls - accumulate a list of proc. calls
  12927. X#
  12928. X#    Author:     Richard L. Goerwitz
  12929. X#
  12930. X#    Version: 1.2
  12931. X#
  12932. X############################################################################
  12933. X#
  12934. X#  Determines if arg (line) contains a procedure call, and if so, puts
  12935. X#  that call's id into a list.
  12936. X#
  12937. X#  I hate this procedure.  It works on a line-by-line basis.  Returns
  12938. X#  nothing until invoked with a null argument.  This lets me run it on
  12939. X#  as many lines as I want, and then fetch a full listing whenever it
  12940. X#  seems appropriate.  Some calculations need to be done on return, so
  12941. X#  this is the most practical solution.
  12942. X#
  12943. X#  Part of the imerge package.  See imerge.icn.
  12944. X#
  12945. X############################################################################
  12946. X
  12947. Xprocedure get_procedure_calls(line)
  12948. X
  12949. X    # Looks for non-builtin procedure calls in line.  Returns nothing
  12950. X    # until called without an argument, in which case it returns the
  12951. X    # accumulated set of procedure names found in the "line"s read so
  12952. X    # far.  When next invoked, get_procedure_calls starts with a fresh
  12953. X    # (i.e. freshly emptied) set.
  12954. X
  12955. X    local external_procedures
  12956. X    static keywords, builtins, wchars, procedures_called
  12957. X    initial {
  12958. X    wchars := &ucase ++ &lcase ++ &digits ++ '_'
  12959. X    keywords := set(
  12960. X        ["break","by","case","default","do","dynamic","else","end",
  12961. X        "every","fail","global","if","initial","link","local",
  12962. X        "next","not","of","procedure","record","repeat","return",
  12963. X        "static","suspend","then","to","until","while"])
  12964. X    builtins := set(
  12965. X        ["abs","acos","any","args","asin","bal","char",
  12966. X         "center","close","copy","collect","cos","cset","delete",
  12967. X         "detab","display","dtor","entab","exit","exp","find","get",
  12968. X         "getenv","iand","icom","ior","image","insert","integer",
  12969. X         "ishift","ixor","key","left","list","log","getch",
  12970. X         "getche","kbhit","main","many","map","match","member",
  12971. X         "move","name","numeric","open","ord","pop","pos",
  12972. X         "pull","push","put","read","reads","real","remove",
  12973. X         "rename","repl","reverse","right","rtod","seek","set",
  12974. X         "sin","sort","sqrt","stop","string","system","tab",
  12975. X         "table","trim","type","upto","variable","where",
  12976. X         "write","writes"])
  12977. X    procedures_called := set()
  12978. X    }
  12979. X
  12980. X    strip_comments(\line) ? {
  12981. X    while tab(upto_balanced(wchars)) do {
  12982. X        BEGIN := &pos
  12983. X        id := tab(many(wchars))
  12984. X        # Record constructors look like procedure invocations.
  12985. X        # Make the names of records like builtin function names.
  12986. X        if id == "record" then {
  12987. X        if tab(many(' \t')) & id := tab(many(wchars)) then
  12988. X            insert(builtins, id)
  12989. X        else break    # give up, bad code
  12990. X        }
  12991. X        # Make sure with "procedure proc1(arguments)" that proc1
  12992. X        # doesn't get taken as an invocation of proc1!
  12993. X        else if id == "procedure" then {
  12994. X        if not (tab(many(' \t')) & tab(many(wchars)))
  12995. X        then break    # give up, bad code
  12996. X        }
  12997. X        else {
  12998. X        tab(many(" \t"))
  12999. X        if tab(match(".")) then {
  13000. X            tab(many(wchars))
  13001. X            # What the heck, stick records in with procedures.
  13002. X            insert(procedures_called, id)
  13003. X        }
  13004. X        else if tab(match("(")) then {
  13005. X            integer(id) & next
  13006. X            # Reject id if it is a keyword or builtin function
  13007. X            if member(keywords | builtins, id) then next
  13008. X            else {
  13009. X            # Conceivably, we could have rec.field(args)
  13010. X            if match(".",line,BEGIN -1) then next
  13011. X            else insert(procedures_called, id)
  13012. X            # Doesn't account for (proc1|proc2)(arguments)
  13013. X            }
  13014. X        }
  13015. X        }
  13016. X    }
  13017. X    }
  13018. X
  13019. X    if /line then {
  13020. X    external_procedures := (procedures_called -- builtins) -- keywords
  13021. X    procedures_called := set()
  13022. X    return external_procedures
  13023. X    }    
  13024. X
  13025. Xend
  13026. X
  13027. X
  13028. X
  13029. Xprocedure upto_balanced(cs)
  13030. X
  13031. X    local s2, c, c2, POS
  13032. X
  13033. X    &subject[.&pos:0] ? {
  13034. X    tab(upto(cs)) ? {
  13035. X        c2 := &null
  13036. X            if upto('\"\'') then {
  13037. X        while tab(upto('\\"\'')) do {
  13038. X            case c := move(1) of {
  13039. X            "\\"   : {
  13040. X                if match("^")
  13041. X                then move(2)
  13042. X                else move(1)
  13043. X            }
  13044. X            default: {
  13045. X                if \c2
  13046. X                then (c == c2, c2 := &null)
  13047. X                else c2 := c
  13048. X            }
  13049. X            }
  13050. X        }
  13051. X        }
  13052. X        /c2
  13053. X    } & POS := &pos
  13054. X    }
  13055. X
  13056. X    return &pos + \POS - 1
  13057. X
  13058. Xend
  13059. SHAR_EOF
  13060. true || echo 'restore of getcalls.icn failed'
  13061. rm -f _shar_wnt_.tmp
  13062. fi
  13063. # ============= getnames.icn ==============
  13064. if test -f 'getnames.icn' -a X"$1" != X"-c"; then
  13065.     echo 'x - skipping getnames.icn (File already exists)'
  13066.     rm -f _shar_wnt_.tmp
  13067. else
  13068. > _shar_wnt_.tmp
  13069. echo 'x - extracting getnames.icn (Text)'
  13070. sed 's/^X//' << 'SHAR_EOF' > 'getnames.icn' &&
  13071. X############################################################################
  13072. X#
  13073. X#    Name:     getnames.icn
  13074. X#
  13075. X#    Title:     Get_ipl_names - get names .icn files in a list of dirs
  13076. X#
  13077. X#    Author:     Richard L. Goerwitz
  13078. X#
  13079. X#    Version: 1.3
  13080. X#
  13081. X############################################################################
  13082. X#
  13083. X#  Part of the imerge package.  See imerge.icn.
  13084. X#
  13085. X############################################################################
  13086. X
  13087. Xprocedure get_ipl_names(lib_paths)
  13088. X
  13089. X    local procedure_stat_list
  13090. X    static get_dir
  13091. X    initial get_dir := set_getdir_by_os()
  13092. X
  13093. X    procedure_stat_list := list()
  13094. X    # Run through every possible path in which files might be found,
  13095. X    # and get a list of procedures contained in those files.
  13096. X    every procedure_stat_list |||:= get_dir(!lib_paths)
  13097. X
  13098. X    return procedure_stat_list
  13099. X
  13100. Xend
  13101. X
  13102. X
  13103. X
  13104. X
  13105. Xprocedure set_getdir_by_os()
  13106. X
  13107. X    if find("UNIX", &features)
  13108. X    then return unix_get_dir
  13109. X    else if find("MS-DOS", &features)
  13110. X    then return msdos_get_dir
  13111. X    else stop("Your operating system is not (yet) supported.")
  13112. X
  13113. Xend
  13114. X
  13115. X
  13116. X
  13117. Xprocedure msdos_get_dir(dir)
  13118. X
  13119. X    # Returns a sorted list of all filenames (full paths included) in
  13120. X    # directory "dir."  The list is sorted.  Fails on invalid or empty
  13121. X    # directory.  Aborts if temp file cannot be opened.
  13122. X    #
  13123. X    # Temp files can be directed to one or another directory either by
  13124. X    # manually setting the variable temp_dir below, or by setting the
  13125. X    # value of the environment variable TEMPDIR to an appropriate
  13126. X    # directory name.
  13127. X
  13128. X    local in_dir, filename_list, line
  13129. X    static temp_dir
  13130. X    initial {
  13131. X        temp_dir := 
  13132. X            (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
  13133. X                ".\\"
  13134. X    }
  13135. X
  13136. X    # Get name of tempfile to be used.
  13137. X    temp_name := get_dos_tempname(temp_dir) |
  13138. X    stop("No more available tempfile names!")
  13139. X
  13140. X    # Make sure we have an unambiguous directory name, with backslashes
  13141. X    # instead of Unix-like forward slashes.
  13142. X    dir := trim(map(dir, "/", "\\"), '\\') || "\\"
  13143. X
  13144. X    # Put dir listing into a temp file.
  13145. X    system("dir "||dir||" > "||temp_name)
  13146. X
  13147. X    # Put tempfile entries into a list, removing blank- and
  13148. X    # space-initial lines.  Exclude directories (i.e. return file
  13149. X    # names only).
  13150. X    in_dir := open(temp_name,"r") |
  13151. X    stop("Can't open temp file in directory ",temp_dir,".")
  13152. X    filename_list := list()
  13153. X    every filename := ("" ~== !in_dir) do {
  13154. X        match(" ",filename) | find(" <DIR>", filename) & next
  13155. X    # Exclude our own tempfiles (may not always be appropriate).
  13156. X    filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
  13157. X    if filename ? (not match("s."), tab(find(".ICN")+4), pos(0))
  13158. X    then put(filename_list, map(dir || filename))
  13159. X    }
  13160. X
  13161. X    # Clean up.
  13162. X    close(in_dir) & remove(temp_name)
  13163. X
  13164. X    # Check to be sure we actually managed to read some files.
  13165. X    if *filename_list = 0 then fail
  13166. X    else return sort(filename_list)
  13167. X
  13168. Xend
  13169. X
  13170. X
  13171. X
  13172. Xprocedure get_dos_tempname(dir)
  13173. X
  13174. X    # Don't clobber existing files.  Get a unique temp file name for
  13175. X    # use as a temporary storage site.
  13176. X
  13177. X    every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
  13178. X    temp_file := open(temp_name,"r") | break
  13179. X        close(temp_file)
  13180. X    }
  13181. X    return \temp_name
  13182. X
  13183. Xend
  13184. X
  13185. X
  13186. X
  13187. Xprocedure unix_get_dir(dir)
  13188. X
  13189. X    dir := trim(dir, '/') || "/"
  13190. X    filename_list := list()
  13191. X    in_dir := open("/bin/ls -F "||dir, "pr")
  13192. X    every filename := ("" ~== !in_dir) do {
  13193. X    match("/",filename,*filename) & next
  13194. X    if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
  13195. X    then put(filename_list, trim(dir || filename, '*'))
  13196. X    }
  13197. X    close(in_dir)
  13198. X
  13199. X    if *filename_list = 0 then fail
  13200. X    else return filename_list
  13201. X
  13202. Xend
  13203. SHAR_EOF
  13204. true || echo 'restore of getnames.icn failed'
  13205. rm -f _shar_wnt_.tmp
  13206. fi
  13207. # ============= getpaths.icn ==============
  13208. if test -f 'getpaths.icn' -a X"$1" != X"-c"; then
  13209.     echo 'x - skipping getpaths.icn (File already exists)'
  13210.     rm -f _shar_wnt_.tmp
  13211. else
  13212. > _shar_wnt_.tmp
  13213. echo 'x - extracting getpaths.icn (Text)'
  13214. sed 's/^X//' << 'SHAR_EOF' > 'getpaths.icn' &&
  13215. X############################################################################
  13216. X#
  13217. X#    Name:     getpaths.icn
  13218. X#
  13219. X#    Title:     Get_lib_paths - puts library paths into a sorted list
  13220. X#
  13221. X#    Author:     Richard L. Goerwitz
  13222. X#
  13223. X#    Version: 1.4
  13224. X#
  13225. X############################################################################
  13226. X#  
  13227. X#  Get_lib_paths() examines the env. variable ILIBS, and also command
  13228. X#  args 2-end, sorting them, and normalizing them, making them all into
  13229. X#  directory names.  Later on, these directories are examined to see if
  13230. X#  they contain .icn files....
  13231. X#
  13232. X#  Part of the imerge package.  See imerge.icn.
  13233. X#
  13234. X############################################################################
  13235. X
  13236. Xprocedure get_lib_paths(ipl_paths)
  13237. X
  13238. X    local i, path
  13239. X
  13240. X    # Make sure all paths have a consistent format (one trailing slash).a
  13241. X    if *\ipl_paths > 0 then {
  13242. X    every i := 1 to *ipl_paths do {
  13243. X        ipl_paths[i] := fixup_path(ipl_paths[i])
  13244. X    }
  13245. X    ipl_paths := set(ipl_paths)
  13246. X    }
  13247. X    else ipl_paths := set()
  13248. X
  13249. X    # If the ILIBS environment variable is set, read it into
  13250. X    # ipl_paths.  Spaces - NOT COLONS - are used as separators.
  13251. X    getenv("ILIBS") ? {
  13252. X    while path := tab(find(" ")) do {
  13253. X        insert(ipl_paths, fixup_path(path))
  13254. X        tab(many(' '))
  13255. X    }
  13256. X    insert(ipl_paths, fixup_path(tab(0)))
  13257. X    }
  13258. X
  13259. X    return sort(ipl_paths)
  13260. X
  13261. Xend
  13262. X
  13263. X
  13264. X
  13265. Xprocedure fixup_path(s)
  13266. X    return "/" ~== (trim(s,'/') || "/")
  13267. Xend
  13268. X
  13269. X
  13270. X
  13271. Xprocedure Basename(s)
  13272. X
  13273. X    every i := find("/",s)
  13274. X    return s[1:\i]
  13275. X
  13276. Xend
  13277. SHAR_EOF
  13278. true || echo 'restore of getpaths.icn failed'
  13279. rm -f _shar_wnt_.tmp
  13280. fi
  13281. # ============= getprocs.icn ==============
  13282. if test -f 'getprocs.icn' -a X"$1" != X"-c"; then
  13283.     echo 'x - skipping getprocs.icn (File already exists)'
  13284.     rm -f _shar_wnt_.tmp
  13285. else
  13286. > _shar_wnt_.tmp
  13287. echo 'x - extracting getprocs.icn (Text)'
  13288. sed 's/^X//' << 'SHAR_EOF' > 'getprocs.icn' &&
  13289. X############################################################################
  13290. X#
  13291. X#    Name:     getprocs.icn
  13292. X#
  13293. X#    Title:     Get stats on procedure calls declared in a file.
  13294. X#
  13295. X#    Author:     Richard L. Goerwitz
  13296. X#
  13297. X#    Version: 1.2
  13298. X#
  13299. X############################################################################
  13300. X#
  13301. X#  Part of the imerge package.  See imerge.icn.
  13302. X#
  13303. X############################################################################
  13304. X
  13305. Xrecord procedure_stats(name, file, byte)
  13306. X
  13307. Xprocedure get_procedure_stats(intext,fname)
  13308. X
  13309. X    # Extracts the names of all procedures declared in file f.
  13310. X    # Returns them in a list, each of whose elements have the
  13311. X    # form record procedure_stats(procedurename, filename, byte-
  13312. X    # offset).
  13313. X
  13314. X    local psl, f_pos
  13315. X    static name_chars
  13316. X    initial {
  13317. X    name_chars := &ucase ++ &lcase ++ &digits ++ '_'
  13318. X    }
  13319. X
  13320. X    # Initialize procedure-name list.
  13321. X    psl := list()
  13322. X
  13323. X    # Find procedure declarations in intext.
  13324. X    while f_pos := where(intext) & line := read(intext) do {
  13325. X    strip_comments(line) ? {
  13326. X        if tab(match("procedure")) then {
  13327. X        tab(many(' \t')) &
  13328. X            put(psl, procedure_stats(
  13329. X                "main" ~== tab(many(name_chars)), fname, f_pos))
  13330. X        }
  13331. X    }
  13332. X    }
  13333. X
  13334. X    return psl   # returns empty list if no procedures found
  13335. X
  13336. Xend
  13337. SHAR_EOF
  13338. true || echo 'restore of getprocs.icn failed'
  13339. rm -f _shar_wnt_.tmp
  13340. fi
  13341. # ============= imerge.icn ==============
  13342. if test -f 'imerge.icn' -a X"$1" != X"-c"; then
  13343.     echo 'x - skipping imerge.icn (File already exists)'
  13344.     rm -f _shar_wnt_.tmp
  13345. else
  13346. > _shar_wnt_.tmp
  13347. echo 'x - extracting imerge.icn (Text)'
  13348. sed 's/^X//' << 'SHAR_EOF' > 'imerge.icn' &&
  13349. X############################################################################
  13350. X#
  13351. X#    Name:     imerge.icn
  13352. X#
  13353. X#    Title:     IPL merge utility
  13354. X#
  13355. X#    Author:     Richard L. Goerwitz
  13356. X#
  13357. X#    Version: 1.6
  13358. X#
  13359. X############################################################################
  13360. X#  
  13361. X#      Imerge simply merges needed routines from the IPL (and from any
  13362. X#  other directories you supply), into a given source file.  Often an
  13363. X#  IPL file will house several related procedures - not all of which
  13364. X#  are needed in order to compile a program.  Imerge obviates the need
  13365. X#  for linking in the entire library file.
  13366. X#  
  13367. X#  Usage is
  13368. X#  
  13369. X#      imerge sourcefile [libdirectories]
  13370. X#  
  13371. X#  where "sourcefile" refers to a .icn file, and libdirectories is a
  13372. X#  space-separated list of directories in which .icn files containing
  13373. X#  routines needed by sourcefile are likely to be found.
  13374. X#
  13375. X#  You can remove the need to specify any directories on the command
  13376. X#  line by setting the value of ILIBS in your environment to a space-
  13377. X#  or colon-separated string of directory names.  Csh users, for
  13378. X#  instance, could put the following in their .login files:
  13379. X#
  13380. X#      setenv ILIBS = "/usr/local/lib/icon/procs ~/isrc"
  13381. X#
  13382. X#  Imerge will recognize all files ending in ".icn" which do not begin
  13383. X#  with "s." (s + period = a SCCS file) as possible library files in
  13384. X#  the ILIBS directories.
  13385. X#
  13386. X#  Imerge writes to the standard output.  Slowly.  Bear with it, and
  13387. X#  it will normally do a pretty decent job.  Watch the end of the file
  13388. X#  for a report of records and procedures not found (you'll have to go
  13389. X#  find them, and either link them in by hand, or add the directory
  13390. X#  they are in to the ILIBS variable).  Imerge is annoyed at duplicate
  13391. X#  procedure names in your library files, and will complain at length
  13392. X#  about them.  In many cases, it complains about things that don't
  13393. X#  really matter.  Ignore the complaints unless the output won't
  13394. X#  compile.
  13395. X#
  13396. X#  BUGS:  1) Naming conflicts cannot be resolved (the workaround is
  13397. X#  simply to make sure no duplicate names exist for procedures in your
  13398. X#  libraries).  2) The parsing algorithm doesn't handle line-final
  13399. X#  underscore notation for string literals (this should not normally
  13400. X#  cause problems).  3) Indirect procedure invocations, such as a :=
  13401. X#  b; a(), where b is a global identifier, confuse imerge, though the
  13402. X#  resulting output should normally compile fine.  Same goes for
  13403. X#  records.  Again, the resulting output should compile just fine.
  13404. X#
  13405. X############################################################################
  13406. X#
  13407. X#  Links:  imerge.icn is part of a package including the following
  13408. X#  files - findrecs.icn, getcalls.icn, getnames.icn, getpaths.icn,
  13409. X#  getprocs.icn, imerge.icn, and stripcom.icn.
  13410. X#
  13411. X#  Requires:  Unix (will work under MS-DOS if all files are in MS-
  13412. X#             DOS format - CR+LF = EOL)
  13413. X#
  13414. X############################################################################
  13415. X
  13416. Xglobal unfound_procedures, st2, records, globals
  13417. X
  13418. Xprocedure main(a)
  13419. X
  13420. X    local usage, line, raw_line, elem, sourcefile_procedures
  13421. X
  13422. X    usage := "usage:  imerge sourcefile [libdirs]"
  13423. X    #
  13424. X    # Where sourcefile is a single filename, and libdirs is a series
  13425. X    # of space-separated directories in which relevant library files
  13426. X    # are to be found.
  13427. X
  13428. X    *a < 1 & stop(usage)
  13429. X
  13430. X    # Open arg 1 - the source .icn file into which the library
  13431. X    # routines are to be merged.
  13432. X    if not (intext := open(a[1],"r")) then {
  13433. X        write(&errout, "Cannot open source file.")
  13434. X    write(&errout, usage)
  13435. X        exit(2)
  13436. X    }
  13437. X
  13438. X    # Now accumulate the set of all procedures called in the source
  13439. X    # file, and then remove from that set all procedures which are
  13440. X    # defined in that file.  What is left is the set of all "external"
  13441. X    # procedures called in the source file.
  13442. X
  13443. X    # Find every procedure call in intext.
  13444. X    every get_procedure_calls(!intext)
  13445. X    sourcefile_procedure_calls := get_procedure_calls()
  13446. X
  13447. X    # Find all the procedures defined in intext, then remove them from
  13448. X    # the set of procedure calls accumulated just above.
  13449. X    seek(intext,1)
  13450. X    sourcefile_procedures := set()
  13451. X    # Get_procedure_stats returns a list of procedure_stats records.
  13452. X    every insert(sourcefile_procedures,
  13453. X       (!get_procedure_stats(intext,a[1])).name)
  13454. X    sourcefile_procedure_calls --:= sourcefile_procedures
  13455. X
  13456. X    # Check to see whether the source file in fact calls any
  13457. X    # procedures not defined in that file.  If not, there's no need to
  13458. X    # continue.
  13459. X    if *sourcefile_procedure_calls = 0 then {
  13460. X    write(&errout,"No external procedure calls in ",a[1],".")
  13461. X    exit(3)
  13462. X    }
  13463. X
  13464. X    prtbl := table()
  13465. X    every fname := !get_ipl_names(get_lib_paths(a[2:0])) do {
  13466. X    # If the source file is in one of the libraries, don't index it.
  13467. X        fname == a[1] & next
  13468. X    if not (lib_file := open(fname, "r")) then
  13469. X        write(&errout,"Can't open ",fname," for reading.")
  13470. X    else {
  13471. X        every elem := !get_procedure_stats(lib_file,fname) do {
  13472. X        if /prtbl[elem.name]
  13473. X        then insert(prtbl,elem.name,elem)
  13474. X        else {
  13475. X            write(&errout, "Warning:  ",elem.name,
  13476. X              " is defined in more than one place.")
  13477. X            every write(&errout,"     ",prtbl[elem.name].file)
  13478. X            write(&errout,"     ",elem.file)
  13479. X        }
  13480. X        }
  13481. X        seek(lib_file, 1)
  13482. X        # Side-effects!  Find_records() sets up the global tables,
  13483. X        # record_table and global_table (see below).
  13484. X        find_records(lib_file, fname)
  13485. X        close(lib_file)
  13486. X    }
  13487. X    }
  13488. X
  13489. X    # Copy input file to stdout.  Comment out link declaration (if there is
  13490. X    # one).  This program is supposed to obviate the need for links.
  13491. X    seek(intext,1)
  13492. X    every line := !intext do {
  13493. X    if line ? (tab(many(' \t'))|&null, tab(match("link")), tab(any(' \t')))
  13494. X    then write("# ",line)
  13495. X        else write(line)
  13496. X    }
  13497. X    close(intext)
  13498. X    write("\n\n\n")
  13499. X
  13500. X    # Fetch procedure calls, and write them to the standard output, in
  13501. X    # effect, appending them to intext, the source file.
  13502. X    write_separator("Merged library procedures begin here.")
  13503. X    fetch_procedure(sourcefile_procedure_calls, prtbl, a[1])
  13504. X    
  13505. Xend
  13506. X
  13507. X
  13508. X
  13509. Xprocedure fetch_procedure(st,prtbl,f_name,switch)
  13510. X
  13511. X    local stat, elem, p, st3
  13512. X
  13513. X    # global unfound_procedures, records, record_table, global_table
  13514. X    initial {
  13515. X    unfound_procedures := set()
  13516. X    records := set()
  13517. X        globals := set()
  13518. X    }
  13519. X
  13520. X    /st2 := set()
  13521. X
  13522. X    every insert(globals, !\global_table[f_name])
  13523. X
  13524. X    every p := !st do {
  13525. X    if /(stat := prtbl[p]) then {
  13526. X        # Record_table has record declarations catalogued by file
  13527. X        # name.  First look by f_name.  If you can't find a
  13528. X        # variable that way, just go through the entire table.
  13529. X        if find(" "||p||"(",elem := !\record_table[f_name]| !!record_table)
  13530. X        then insert(records,elem)
  13531. X        else insert(unfound_procedures, p)
  13532. X        next
  13533. X    }
  13534. X    intext := open(stat.file,"r")
  13535. X    seek(intext,stat.byte)
  13536. X    write("#  Source file:  ",stat.file)
  13537. X    until "end" == (line := strip_comments(write(!intext \ 1))) do {
  13538. X        get_procedure_calls(line)
  13539. X    }
  13540. X    write("\n\n\n")
  13541. X    st2 ++:= st ++ set([stat.name])
  13542. X    st3 := get_procedure_calls() -- st2
  13543. X    close(intext)
  13544. X    fetch_procedure(st3,prtbl,stat.file,1)
  13545. X    }
  13546. X
  13547. X    if *records ~= 0 & /switch then {
  13548. X    write_separator("Records.")
  13549. X    every write(!sort(records))
  13550. X    write()
  13551. X    }
  13552. X
  13553. X    if *globals ~= 0 & /switch then {
  13554. X    # Output global variables for all files visited.
  13555. X    write_separator("Global variables.")
  13556. X    every write(!sort(globals))
  13557. X    write()
  13558. X    }
  13559. X
  13560. X    if *unfound_procedures ~= 0 & /switch then {
  13561. X        # Append a list of unlocated procedures to the stdout.
  13562. X        write_separator("Unable to locate the following procedures/records:",
  13563. X            sort(unfound_procedures))
  13564. X    }
  13565. X
  13566. X    return
  13567. X
  13568. Xend
  13569. X
  13570. X
  13571. X
  13572. Xprocedure write_separator(s,l)
  13573. X
  13574. X    write(repl("#",75))
  13575. X    write("#")
  13576. X    write("#  ",s)
  13577. X    every write("#    ",!\l)
  13578. X    write("#")
  13579. X    write("")
  13580. X
  13581. Xend
  13582. SHAR_EOF
  13583. true || echo 'restore of imerge.icn failed'
  13584. rm -f _shar_wnt_.tmp
  13585. fi
  13586. # ============= stripcom.icn ==============
  13587. if test -f 'stripcom.icn' -a X"$1" != X"-c"; then
  13588.     echo 'x - skipping stripcom.icn (File already exists)'
  13589.     rm -f _shar_wnt_.tmp
  13590. else
  13591. > _shar_wnt_.tmp
  13592. echo 'x - extracting stripcom.icn (Text)'
  13593. sed 's/^X//' << 'SHAR_EOF' > 'stripcom.icn' &&
  13594. X############################################################################
  13595. X#
  13596. X#    Name:     stripcom.icn
  13597. X#
  13598. X#    Title:     Strip out comments from a line of Icon code
  13599. X#
  13600. X#    Author:     Richard L. Goerwitz
  13601. X#
  13602. X#    Version: 1.2
  13603. X#
  13604. X############################################################################
  13605. X#  
  13606. X#  BUGS:  Can't handle lines ending in an underscore as part of a
  13607. X#  broken string literal.
  13608. X#
  13609. X#  Part of the imerge package.  See imerge.icn.  Could be used as a
  13610. X#  general utility, I suppose.
  13611. X#
  13612. X############################################################################
  13613. X
  13614. Xprocedure strip_comments(s)
  13615. X
  13616. X    #######
  13617. X    #
  13618. X    # Commented-out portions of Icon code - strip 'em.  Fails on lines
  13619. X    # which, either stripped or otherwise, come out as an empty string.
  13620. X    #
  13621. X    # I'd expect strip_comments to be used typically as follows:
  13622. X    #
  13623. X    #     every write(strip_comments(!&input))
  13624. X    #
  13625. X    # BUG:  Does not handle lines which use the _ string-continuation
  13626. X    # notation.  Typically strip_comments barfs on the next line.
  13627. X    #
  13628. X    #######
  13629. X
  13630. X    local i, j, c, c2
  13631. X
  13632. X    s ? {
  13633. X    tab(many(' \t'))
  13634. X    pos(0) & fail
  13635. X        find("#") | (return trim(tab(0),' \t'))
  13636. X    match("#") & fail
  13637. X    (s2 <- tab(find("#"))) ? {
  13638. X        c2 := &null
  13639. X        while tab(upto('\\"\'')) do {
  13640. X        case c := move(1) of {
  13641. X            "\\"   : {
  13642. X            if match("^")
  13643. X            then move(2)
  13644. X            else move(1)
  13645. X            }
  13646. X            default: {
  13647. X            if \c2
  13648. X            then (c == c2, c2 := &null)
  13649. X            else c2 := c
  13650. X            }
  13651. X        }
  13652. X        }
  13653. X        /c2
  13654. X    }
  13655. X    return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
  13656. X    }
  13657. X
  13658. Xend
  13659. SHAR_EOF
  13660. true || echo 'restore of stripcom.icn failed'
  13661. rm -f _shar_wnt_.tmp
  13662. fi
  13663. # ============= Makefile.dist ==============
  13664. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  13665.     echo 'x - skipping Makefile.dist (File already exists)'
  13666.     rm -f _shar_wnt_.tmp
  13667. else
  13668. > _shar_wnt_.tmp
  13669. echo 'x - extracting Makefile.dist (Text)'
  13670. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  13671. XPROGNAME = imerge
  13672. X
  13673. X# Please edit these to reflect your local file structure & conventions.
  13674. XDESTDIR = /usr/local/bin
  13675. XOWNER = bin
  13676. XGROUP = bin
  13677. X
  13678. XSRC = findrecs.icn getcalls.icn getnames.icn getpaths.icn \
  13679. X    getprocs.icn imerge.icn stripcom.icn
  13680. XICONT = /usr/local/bin/icont #/usr/icon/v8/bin/icont
  13681. XIFLAGS = -Sc300 #-t
  13682. X
  13683. X# Compile program.
  13684. X$(PROGNAME): $(SRC)
  13685. X    $(ICONT) $(IFLAGS) -o $(PROGNAME) $(SRC)
  13686. X
  13687. X# Install.
  13688. X# Pessimistic assumptions regarding the environment (in particular,
  13689. X# I don't assume you have the BSD "install" shell script or that sh
  13690. X# is your default shell).
  13691. Xinstall: $(PROGNAME)
  13692. X    @sh -c "test -d $(DESTDIR)|| (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
  13693. X    cp $(PROGNAME) $(DESTDIR)/
  13694. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  13695. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  13696. X    @echo "\nInstallation done.\n"
  13697. X
  13698. Xclean:
  13699. X    -/bin/rm *.u?
  13700. X    -rm *~
  13701. SHAR_EOF
  13702. true || echo 'restore of Makefile.dist failed'
  13703. rm -f _shar_wnt_.tmp
  13704. fi
  13705. # ============= README ==============
  13706. if test -f 'README' -a X"$1" != X"-c"; then
  13707.     echo 'x - skipping README (File already exists)'
  13708.     rm -f _shar_wnt_.tmp
  13709. else
  13710. > _shar_wnt_.tmp
  13711. echo 'x - extracting README (Text)'
  13712. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  13713. X
  13714. XThis package contains the parts necessary to build imerge - a utility
  13715. Xused for merging relevant parts of the IPL into an icon source file.
  13716. XIf you have a make utility, you can build imerge simply by renaming
  13717. Xthe file "Makefile.dist" as "Makefile" and then typing "make."  Some
  13718. Xadjustments may be needed to tailor the makefile to your particular
  13719. Xfile system.
  13720. X
  13721. XIf you have no make utility, you will need to type
  13722. X
  13723. X    icont -Sc300 -o imerge [names of all .icn files]
  13724. X
  13725. XThis program has been tested under both Unix and MS-DOS.  It will
  13726. Xwork under DOS only if all files have been converted to DOS CR+LF
  13727. Xtext format.
  13728. SHAR_EOF
  13729. true || echo 'restore of README failed'
  13730. rm -f _shar_wnt_.tmp
  13731. fi
  13732. exit 0
  13733.