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 >
Wrap
Internet Message Format
|
1991-01-03
|
482KB
From R@edinburgh.ac.uk Tue Jun 5 03:02:43 1990
Received: from rvax.ccit.arizona.edu by megaron (5.61/15) via SMTP
id AA06671; Tue, 5 Jun 90 03:02:43 -0700
Received: from UKACRL.BITNET by rvax.ccit.arizona.edu; Tue, 5 Jun 90 03:02 MST
Received: from RL.IB by UKACRL.BITNET (Mailer X1.25) with BSMTP id 0481; Tue,
05 Jun 90 10:50:51 BST
Date: 05 Jun 90 10:41:26 bst
From: R.J.Hare@edinburgh.ac.uk
Subject: Icon Book
To: icon-group@cs.arizona.edu
Message-Id: <05 Jun 90 10:41:26 bst 340083@EMAS-A>
Via: UK.AC.ED.EMAS-A; 5 JUN 90 10:41:03 BST
X-Envelope-To: icon-group@cs.arizona.edu
Status: O
Could someone please remind me of the publication details (date, edition
number, isbn, price) of the new edition of the Icon book please - I want to
order a copy and want to make sure that I don't get the first edition...
Thanks.
RH.
From cargo@tardis.cray.com Tue Jun 5 12:01:53 1990
Received: from timbuk.CRAY.COM by megaron (5.61/15) via SMTP
id AA00187; Tue, 5 Jun 90 12:01:53 -0700
Received: from hall.cray.com by timbuk.CRAY.COM (4.1/CRI-1.34)
id AA05899; Tue, 5 Jun 90 14:01:03 CDT
Received: from zk.cray.com by hall.cray.com
id AA02627; 4.1/CRI-3.12; Tue, 5 Jun 90 14:00:40 CDT
Received: by zk.cray.com
id AA12356; 3.2/CRI-3.12; Tue, 5 Jun 90 14:00:54 CDT
Date: Tue, 5 Jun 90 14:00:54 CDT
From: cargo@tardis.cray.com (David S. Cargo)
Message-Id: <9006051900.AA12356@zk.cray.com>
To: icon-group@cs.arizona.edu
Subject: BASIC, expression parsing
Status: O
As an actual, real-world application I am building an application
that analyzes the memory of a microprocessor. I'm using Icon to
write it. I've got some useful parts of it working, but I want
some more, to simplify it for its users. I'm wondering if anybody
has implemented a general-purpose expression evaluator that can
handles variables and does not use co-expressions. I'm looking for
something on the order of a BASIC LET statement with more flexibility
for expression types (in need shifts and boolean operations) and
variable types. o o
\_____/
/-o-o-\ _______
DDDD SSSS CCCC / ^ \ /\\\\\\\\
D D S C \ \___/ / /\ ___ \
D D SSS C \_ _/ /\ /\\\\ \
D D S C \ \__/\ /\ @_/ /
DDDDavid SSSS. CCCCargo \____\____\______/ cargo@tardis.cray.com
From icon-group-request@arizona.edu Tue Jun 5 21:53:45 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA02155; Tue, 5 Jun 90 21:53:45 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Tue, 5 Jun 90 21:55 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA05786; Tue, 5 Jun 90 21:40:54
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 5 Jun 90 21:55 MST
Date: 6 Jun 90 04:42:24 GMT
From: iris!wood@ucdavis.ucdavis.EDU
Subject: Compiling icon
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <83C8ED3FC45FA00304@Arizona.EDU>
Message-Id: <7432@ucdavis.ucdavis.edu>
Organization: U.C. Davis - Department of Electrical Engineering and Computer
Science
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I'm trying to compile the icon source for research for a class of mine.
However, I can't get the original source to compile. Is the 'as' opcode
"ADDL3" (from a file called create.c in int/operations) valid?
Or did I completely miss something?
I know, I know, I should probably ask the 'Icon project', could someone
please send me the address and some guidelines on getting them to answer
questions? Thanks.
Jeff Wood
wood@iris.ucdavis.edu
Univ. of California, Davis
From tenaglia@fps.mcw.edu Wed Jun 6 15:19:26 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA20568; Wed, 6 Jun 90 15:19:26 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.3/3.06) with UUCP
id AA06432; Wed, 6 Jun 90 17:50:15 EDT
Received: by uwm.edu; id AA20935; Wed, 6 Jun 90 16:48:04 -0500
Message-Id: <9006062148.AA20935@uwm.edu>
Received: from mis by fps.mcw.edu (DECUS UUCP w/Smail);
Wed, 6 Jun 90 15:04:59 CDT
Received: by mis.mcw.edu (DECUS UUCP w/Smail);
Wed, 6 Jun 90 13:45:15 CDT
Date: Wed, 6 Jun 90 13:45:15 CDT
From: Chris Tenaglia - 257-8765 <tenaglia@mis.mcw.edu>
To: icon-group@cs.arizona.edu
Subject: Anyone want to be adventurous with VMS and C ?
Status: O
I've discovered a small bug in Icon Version 8 under VAX/VMS 5.2. I like
mixing VMS and icon (to imitate pipes that are natural under unix. For
example.
###########################################################################
# #
# resp.icn 5/29/90 by tenaglia #
# #
# used in determining what slow response time is #
# #
###########################################################################
procedure main()
out := open("bench.log","w")
repeat
{
bucket := []
now := edit(&clock,"##$##$##")
(test:= open("@RESP.COM","pr")) | stop("broken pipe") # 1
(log := open("RESP.LOG","w")) | stop("what's with resp.log?")
while put(bucket,read(test))
close(test) | stop("Can't close process") # 2
every write(log,!bucket) ; close(log)
fin := edit(&clock,"##$##$##")
write(out,&dateline," --> ",fin - now)
system("wait 00:01:00")
}
end
########################################################################
# #
# EXAMPLES : edit("12/03/89","##$##$##") returns 120389 #
# edit("120389","##/##/19##") returns 12/03/1989 #
# edit("12/03/1989","##$") returns 12 #
# #
########################################################################
procedure edit(var,mask)
text := ""
var ? {
every chr := !mask do {
case chr of {
"#" : text ||:= move(1)
"$" : move(1)
default : text ||:= chr
}
}
}
return text
end
In #1 I open a process for read. Later I read lines out of it. Finally in #2
I close the process to make it go away. It does, but not quite. After it loops
the number of times that equals the PRCLM on my account, it dies. Even if SHOW
SYSTEM shows no such processes.
Another similar and related problem is that if I would try to close the process
before reading all the lines. The close() is successful but the processes are
left hanging out there.
My question is, is there any VMS/C guru out there in Iconland who might have a
patch? I don't have C on our systems. I do have UUDECODE, in case you'd want to
mail the whole executable. Which exectable? ICONX.EXE. I browsed over the code
briefly. The close is accomplished by FSYS.C in [ICON.SRC.ICONX] around lines
43 to 54. Thanks in advance. (But I think most users are unix people).
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu
From icon-group-request@arizona.edu Thu Jun 7 07:45:33 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA00240; Thu, 7 Jun 90 07:45:33 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 7 Jun 90 07:47 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA26697; Thu, 7 Jun 90 07:24:12
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 7 Jun 90 07:47 MST
Date: 6 Jun 90 23:37:07 GMT
From: amdahl!ntmtv!hildum@apple.COM
Subject: What is the best way to do this?
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <82AD14150D5FA00DB3@Arizona.EDU>
Message-Id: <1214@ntmtv.UUCP>
Organization: Northern Telecom (Mountain View, CA)
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I am writing a procedure which scans a file for the objects that it
includes, and returns the name of the object. Objects are included
via a line of the form:
*=> [chars]* COPY name
where name is the name of the object, COPY is a keyword, *=> marks the
beginning of the line, and [chars]* are any characters but the sequence
COPY. White space is ignored, and there are a random number of them on a
line.
I have written the following procedure to open the files and generate
the names of objects included in the file. The commented out portion is
a previous version of the loop body, and I have created a new loop body
using an if expression. Which one of these is better, and why? If there
is a better solution, I would like to see it.
Thank you,
Eric Hildum
procedure find_segments(name)
local msource_file
static segment_chars
initial segment_chars := &ucase ++ &lcase ++ '0123456789'
(msource_file := open(name, "r")) | stop("Unable to open: " || name)
while line := read(msource_file) do
#new
line ? if (match("*=>") & tab(find("COPY") + 4)) then
{
tab(upto(segment_chars))
suspend tab(many(segment_chars)) \ 1
}
#old
# suspend( line ? (match("*=>"),
# tab(find("COPY") + 4) ,
# tab(upto(segment_chars)) ,
# tab(many(segment_chars))) ) \ 1
close(msource_file)
end
From icon-group-request@arizona.edu Thu Jun 7 10:16:24 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA06958; Thu, 7 Jun 90 10:16:24 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 7 Jun 90 10:18 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA06539; Thu, 7 Jun 90 10:05:11
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 7 Jun 90 10:18 MST
Date: 7 Jun 90 17:04:58 GMT
From: swrinde!cs.utexas.edu!uwm.edu!csd4.csd.uwm.edu!corre@ucsd.EDU
Subject: ProIcon Windows
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <8298059F78BFA008C6@Arizona.EDU>
Message-Id: <4356@uwm.edu>
Organization: University of Wisconsin-Milwaukee
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I should like to say something about a feature of ProIcon windows which can
potentially cause a bug in programs which may go undetected for some time,
and then cause the program to fail at a distance from the causative event,
leaving the user with a cryptic error message.
A window is opened by the function wopen() which assigns an integer to
identify the window, and returns this integer as its value. In this respect
it is not parallel to open() which returns a file value. The window can be
closed with wclose(). This is where the problem arises. If the user closes
the window by clicking on the box, and then the program attempts to close
the window, there is a "hole" in the roster of windows, and the variable to
which the integer is assigned has the same value, but no longer references a
window. This causes an error.
There are several ways in which this can be handled. One is always to attach
windows to files by opening the window as a file. In this case the window is
hidden rather than dismissed, and no error will be caused. But this changes
the rules of the game, and does not permit the user to dismiss the window,
which under some circumstances might be desirable. An alternative solution
is to routinely use wopen() again before using wclose() or indeed before any
window function. If the window is still open, wopen() will simply return an
integer. If it is not, it will give wclose() something to work with. A final
possibility might be to give &error a positive value, changing the error to
a failure. This is not recommended, since &error is meant as a debugging
aid, allowing programs to limp home if errors are encountered. In such cases
the final value of &error should always be checked and adjustments made. At
this point I add a "tangent" which discusses an essentially different issue.
Tangent
The TopSpeed Modula-2 Language Tutorial (p. 27) contains a program to
reverse an integer using arithmetic rather than string methods:
...
BEGIN
WrStr("Enter number to be reversed: ");
number := RdCard();
WrStr("The reversal is: ");
REPEAT
WrCard(number MOD 10, 1);
number := number DIV 10
UNTIL number = 0;
WrLn
END
...
I tried entering a non-integer, A79 for example. The program accepted the
bad data gladly, and gave me a garbage answer. I wrote and asked the company
what was the point of the strict typing of RdCard() which on its face will
only read a cardinal number, if it accepts A79? The answer: It's the job of
the programmer to protect against that. A global variable OK is set to FALSE
in such a case. Fine, but who knows about it?
It's curious how the inventor of a language has fanatically strict typing,
stricter than Pascal, and it is subverted by the implementor. Obviously
programmers dislike such strict rules, and call for modification which is
supplied to them. It seems to me that Icon makes a lot more sense. That
program translated into Icon would fail by default. The arithmetic operator
would take care of it. You would have to TELL &error explicitly that you
wanted the Modula-2 situation to prevail--and that is how &error should be
used.
--
Alan D. Corre
Department of Hebrew Studies
University of Wisconsin-Milwaukee (414) 229-4245
PO Box 413, Milwaukee, WI 53201 corre@csd4.csd.uwm.edu
From utah-cs!boulder!ncar.UCAR.EDU!oddjob!sophist.uchicago.edu.goer!zenu! Thu Jun 7 10:48:31 1990
Received: from utah-cs.UUCP by megaron.cs.arizona.edu (5.61/15) via UUCP
id AA08732; Thu, 7 Jun 90 10:48:31 -0700
Received: from boulder.UUCP by cs.utah.edu (5.61/utah-2.11-cs)
id AA19334; Thu, 7 Jun 90 11:48:05 -0600
Received: by boulder.Colorado.EDU (cu-hub.890824)
Received: by ncar.ucar.EDU (5.61/ NCAR Central Post Office 04/10/90)
id AA25008; Thu, 7 Jun 90 11:47:19 MDT
Received: from tank.uchicago.edu by oddjob.uchicago.edu Thu, 7 Jun 90 12:14:53 CDT
Received: from sophist.uchicago.edu by tank.uchicago.edu Thu, 7 Jun 90 12:16:28 CDT
Return-Path: <goer@zenu.uucp>
Received: by sophist.uchicago.edu (3.2/UofC3.0)
id AA25377; Thu, 7 Jun 90 12:12:10 CDT
Received: by sophist.uchicago.edu (smail2.5)
id AA02103; 7 Jun 90 09:41:42 PDT (Thu)
Subject: yuck!
To: icon-group@arizona.edu
Date: Thu, 7 Jun 90 9:41:42 PDT
X-Mailer: ELM [version 2.2 PL0]
Message-Id: <9006070941.AA02103@sophist.uchicago.edu>
From: utah-cs!boulder!sophist.uchicago.edu!goer (Richard Goerwitz qua goer.)
Status: O
From the pathologically-averse-to-explicit-intermediate-variables devil:
Status: O
procedure find_segment(name)
suspend !((open(name,"r") | stop("can't open "||name)) \ 1) ? {
trim((="*=>", tab(find("COPY")+4), tab(many('\t ')), tab(0)) \ 1)
}
end
From icon-group-request@arizona.edu Fri Jun 8 20:28:30 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA02710; Fri, 8 Jun 90 20:28:30 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Fri, 8 Jun 90 20:30 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA00704; Fri, 8 Jun 90 20:11:16
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Fri, 8 Jun 90 20:30 MST
Date: 8 Jun 90 13:38:08 GMT
From: esquire!yost@nyu.EDU
Subject: RE: ProIcon Windows
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <8179592BEDDFA01155@Arizona.EDU>
Message-Id: <2064@esquire.UUCP>
Organization: DP&W, New York, NY
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
References: <4356@uwm.edu>
Status: O
In article <4356@uwm.edu> corre@csd4.csd.uwm.edu (Alan D Corre) writes:
>If the user closes
>the window by clicking on the box, and then the program attempts to close
>the window, there is a "hole" in the roster of windows, and the variable to
>which the integer is assigned has the same value, but no longer references a
>window. This causes an error.
The right way to handle this, I think, is for an icon procedure
to be called when the user clicks the close box. Which is to say
that opening a window should do more than return an integer; it
should hook some procedures to be called when the user does
certain things to the window.
--dave yost
yost@dpw.com or uunet!esquire!yost
Please ignore the From or Reply-To fields above, if different.
From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU Fri Jun 15 23:46:30 1990
Received: from noao.edu by megaron (5.61/15) via SMTP
id AA07477; Fri, 15 Jun 90 23:46:30 -0700
Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G40)
id AA06107; Fri, 15 Jun 90 23:46:24 MST; for icon-group@cs.arizona.edu
Received: by ncar.ucar.EDU (5.61/ NCAR Central Post Office 04/10/90)
id AA18113; Sat, 16 Jun 90 00:46:27 MDT
Received: from tank.uchicago.edu by oddjob.uchicago.edu Sat, 16 Jun 90 01:45:04 -0500
Received: from sophist.uchicago.edu by tank.uchicago.edu Sat, 16 Jun 90 01:46:51 CDT
Return-Path: <goer@zenu.uucp>
Received: by sophist.uchicago.edu (3.2/UofC3.0)
id AA07745; Sat, 16 Jun 90 01:42:48 CDT
Received: by sophist.uchicago.edu (smail2.5)
id AA00360; 15 Jun 90 18:48:16 PDT (Fri)
Subject: local, static, etc.
To: icon-group@arizona.edu
Date: Fri, 15 Jun 90 18:48:16 PDT
X-Mailer: ELM [version 2.2 PL0]
Message-Id: <9006151848.AA00360@sophist.uchicago.edu>
From: goer@sophist.uchicago.edu (Richard Goerwitz)
Status: O
Question for those versed in the underlying implementation, and in
the fine points of Icon syntax:
Sure, B is local. But do we call C local or not? -
procedure a(A)
local B
use A and B to come up with a value, which is assigned to C
return C
end
(Note that Icon programmers normally recognize that return is not
a function, but a keyword in a control structure. When can we tell
C programmers the news? :-]).
The variable C above is local. Its value is not. Do I put it with
B?
Actually, I have to wonder about A as well. When the arguments get
popped off the stack, don't they basically get assigned to variables
in the parameter list, as if by a normal assignment? Is there any
harm in calling A local? Any reason *not* to?
Haven't tested anything out. Just an idle curiosity....
--
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From cfcl!rdm@apple.com Sun Jun 17 20:50:48 1990
Received: from apple.com by megaron (5.61/15) via SMTP
id AA04946; Sun, 17 Jun 90 20:50:48 -0700
Received: by apple.com (5.61/25-eef)
id AA17694; Sun, 17 Jun 90 20:42:45 -0700
for
Received: by cfcl.uucp id AA00962; Sun, 17 Jun 90 16:35:11 PDT
Date: Sun, 17 Jun 90 16:35:11 PDT
From: cfcl!rdm@apple.com (Rich Morin)
Message-Id: <9006172335.AA00962@cfcl.uucp>
To: icon-group@cs.arizona.edu
Subject: Permuted indices of V8 pro[cg]s
Status: O
Here are some simple scripts for generating and printing permuted indices
of the Icon V8 procs and progs. For non-UNIXoids, I have included some
printable output. Hope this is useful (despite its non-Icon nature :-)...
This is all in the public domain - use it as you wish...
::::::::::::::
g_index
::::::::::::::
:
: g_index - generate index of icon pro[cg]s
:
# Usage: g_index > list
#
# Written by Rich Morin, CFCL, 1990
# IPL=/usr/icon/v8/ipl
IPL=/usr/local/src/icon/v8/ipl
for type in procs progs; do
cd $IPL/$type
for file in *.icn; do
base=`basename $file .icn`
expand |
awk '$2 == "Title:" {
printf("'$type'/%s %s\n", "'$base'", substr($0, 17))
exit
}' |
sed 's@ *@ @g'
done
done
::::::::::::::
n_index
::::::::::::::
:
: n_index - generate nroffed index of Icon pro[cg]s
:
# Usage: n_index list > list.nr
#
# Written by Rich Morin, CFCL, 1990
ptx -r $1 |
awk '
BEGIN {
print ".de hd"
print "'\''sp 1i"
print ".."
print ".de fo"
print "'\''bp"
print ".."
print ".wh 0 hd"
print ".wh -1i fo"
}
{ print $0 }
' |
nroff -mptx
# The nroff output may have backspace sequences in it for bolding.
# These can be removed by something like: sed 's@.^H@@g;s@^H@@g'
::::::::::::::
t_index
::::::::::::::
:
: t_index - generate troffed index of Icon pro[cg]s
:
# Usage: t_index list
#
# Written by Rich Morin, CFCL, 1990
ptx -r -t $1 |
awk '
BEGIN {
print ".de hd"
print "'\''sp 1i"
print ".."
print ".de fo"
print "'\''bp"
print ".."
print ".wh 0 hd"
print ".wh -1i fo"
}
{ print $0 }
' |
troff -Tpsc -mptx |
psdit |
lpr
::::::::::::::
nn
::::::::::::::
Animal game ................ progs/animal
Arrange data into columns .. procs/colmize
Arrange data into columns .. progs/colm
UNIX-like Wild Card Pattern Matching Function procs/wildcard
Collate and decollate strings procs/collate
Huffman decoding. Compute state transitions for progs/hufftab
Utility LZW Compression and Decompression progs/press
denominator Compute greatest common ..... procs/gcd
Iterative Conjunction Control Operation procs/allof
Iterative Conjunction Control Operation .......... procs/allof
Convert binary data ........ procs/bincvt
Convert string to Morse code procs/morse
Icon "link" Cross Reference Utility .... progs/ilnkxref
Currency formatting procedure procs/currency
Customizable sort procedure procs/isort
Deal bridge hands .......... progs/deal
LZW Compression and Decompression Utility ...... progs/press
Delaminate file ............ progs/delam
characters Delaminate file using tab .. progs/delamc
Desk calculator ............ progs/calc
of strings Diagram character intersections progs/kross
Diff engine ................ procs/dif
Display intersection of words progs/cross
characters in file Display representations of . progs/fileprnt
problem Display solutions to n-queens progs/vnq
Encode and decode Icon values procs/object
Entab an Icon program ...... progs/itab
Generator Expression Measurement Program progs/empg
Generate Farberisms ................. progs/farb
lines Filter out identical adjacent progs/unique
text Filter to word wrap a range of progs/format
Format and convert numbers . procs/numbers
Format columnar data ....... procs/printcol
Format mailing labels ...... progs/labels
Wild Card Pattern Matching Function UNIX-like ......... procs/wildcard
Generate Farberisms ........ progs/farb
from context-sensitive grammars Generate instances of sentences progs/csgen
phone numbers Generate letter combinations for procs/phoname
Generate miscellaneous sequences procs/gener
Generate n-grams ........... procs/ngrams
Generate random text ....... progs/monkeys
sentences from a grammar Generate randomly selected . progs/rsg
in a context-free language Generate recognizer for sentences progs/recgen
system Generate sentences in Lindenmayer progs/linden
n-queens problem Generate solutions to the .. progs/queens
system Generate strings from the MIU progs/miu
Expression Measurement Program Generator .................. progs/empg
Generic filter skeleton in Icon progs/filter
Hexadecimal conversion ..... procs/hexcvt
Compute state transitions for Huffman decoding. .......... progs/hufftab
Write Icon code to write input ... progs/iwriter
Procedures to encode and decode Icon data .................. procs/codeobj
Utility Icon "link" Cross Reference progs/ilnkxref
Interpret Icon literal escapes ....... procs/escape
Summarize Icon memory management ..... progs/memsum
Icon preprocessor .......... progs/ipp
Sort Icon procedures ............ progs/ipsort
Split Icon program into separate files progs/ipsplit
Print Icon program ............... progs/iprint
Produce cross reference for Icon program ............... progs/ipxref
Entab an Icon program ............... progs/itab
Generic filter skeleton in Icon ....................... progs/filter
of different syntactic forms in Icon Instances ............. progs/proto
Produce string image of Icon result sequence ....... procs/seqimage
to find undeclared variables in Icon source program. Utility progs/iundecl
Show snapshot of Icon string scanning ....... procs/snapshot
Produce generalized image of Icon value ................. procs/image
Encode and decode Icon values ................ procs/object
forms in Icon Instances of different syntactic progs/proto
Interpret Icon literal escapes procs/escape
Operation Iterative Conjunction Control procs/allof
Utility LZW Compression and Decompression progs/press
Process LaTeX .idx file ............ progs/latexidx
Laminate files ............. progs/lam
Large integer arithmetic ... procs/largint
Letter patterns in words ... procs/patword
Generate sentences in Lindenmayer system ......... progs/linden
Lisp interpreter ........... progs/lisp
roff document List commands and macros in a progs/roffcmds
List different words ....... progs/diffword
Generate strings from the MIU system ................. progs/miu
Map list elements .......... procs/lmap
representation Map string into bit ........ procs/mapbit
UNIX-like Wild Card Pattern Matching Function .......... procs/wildcard
Expression Measurement Program Generator progs/empg
Convert string to Morse code ................. procs/morse
Iterative Conjunction Control Operation .................. procs/allof
Package multiple files ..... progs/pack
Parse arithmetic expressions progs/parsex
Parse file names ........... procs/filename
Parse simple statements .... progs/parse
UNIX-like Wild Card Pattern Matching Function .. procs/wildcard
SNOBOL4 Pattern matching in the style of procs/patterns
numbers Perform arithmetic on rational procs/rational
Perform complex arithmetic . procs/complex
Perform mathematical computations procs/math
such Permutations, combinations, and procs/permute
Play kriegspiel ............ progs/krieg
Play the game of solitaire . progs/solit
Print Icon program ......... progs/iprint
Printf-style formatting .... procs/printf
underscoring test Procedures for enboldening and procs/bold
Icon data Procedures to encode and decode procs/codeobj
Process LaTeX .idx file .... progs/latexidx
Process n-tuples ........... procs/tuple
specification Produce complement of file . progs/gcomp
Produce concordance ........ progs/concord
program Produce cross reference for Icon progs/ipxref
value Produce generalized image of Icon procs/image
Produce keywords in context progs/kwic
file Produce load map of UNIX obect progs/loadmap
parenthesis-balanced strings Produce random ............. progs/parens
Produce script for the ed editor progs/edscript
result sequence Produce string image of Icon procs/seqimage
structured data Produces complete image of . procs/fullimag
structured data Produces "executable" image of procs/ximage
Expression Measurement Program Generator .......... progs/empg
operations Programmer-defined control ... procs/pdco
evaluation Programmer-defined argument procs/pdae
Quote word for shells ...... procs/shquote
Radix conversion ........... procs/radcon
Icon "link" Cross Reference Utility .......... progs/ilnkxref
Pattern matching in the style of SNOBOL4 .................... procs/patterns
Segment string ............. procs/segment
Service procedures ......... procs/usage
Show differences files ..... progs/diffn
scanning Show snapshot of Icon string procs/snapshot
Shuffle lines in a file .... progs/shuffile
Shuffle values ............. procs/shuffle
Simulate a Turing machine .. progs/turing
Sort Icon procedures ....... progs/ipsort
Sort groups of lines ....... progs/grpsort
Sort mailing labels by ZIP code progs/zipsort
files Split Icon program into separate progs/ipsplit
String utilities ........... procs/strings
Structure operations ....... procs/structs
Summarize Icon memory management progs/memsum
Tabulate characters in a file progs/tablc
Tabulate properties of text file progs/textcnt
Tabulate words in a file ... progs/tablw
Trim lines in a file ....... progs/trim
Simulate a Turing machine ............. progs/turing
Produce load map of UNIX obect file ............ progs/loadmap
Matching Function UNIX-like Wild Card Pattern procs/wildcard
Unpackage files ............ progs/unpack
Icon "link" Cross Reference Utility .................... progs/ilnkxref
LZW Compression and Decompression Utility .................... progs/press
variables in Icon source/ Utility to find undeclared . progs/iundecl
Function UNIX-like Wild Card Pattern Matching . procs/wildcard
write() Wrap lines of output for use with procs/wrap
Write Icon code to write input progs/iwriter
standard output Write a character ruler to . progs/ruler
Sort mailing labels by ZIP code ................... progs/zipsort
Filter out identical adjacent lines ............. progs/unique
Programmer-defined argument evaluation ........ procs/pdae
Parse arithmetic expressions ..... progs/parsex
Perform arithmetic on rational numbers procs/rational
Perform complex arithmetic ................. procs/complex
Large integer arithmetic ................. procs/largint
Convert binary data ................ procs/bincvt
Map string into bit representation ......... procs/mapbit
Deal bridge hands ............... progs/deal
Desk calculator ................. progs/calc
strings Diagram character intersections of . progs/kross
output Write a character ruler to standard progs/ruler
Tabulate characters in a file ....... progs/tablc
Display representations of characters in file ......... progs/fileprnt
Delaminate file using tab characters ................. progs/delamc
Compute greatest cmmon denominator .......... procs/gcd
Format columnar data .............. procs/printcol
Arrange data into columns .................... procs/colmize
Arrange data into columns .................... progs/colm
Permutations, combinations, and such ..... procs/permute
Generate letter combinations for phone numbers procs/phoname
Get command-line options ....... procs/options
document List commands and macros in a roff progs/roffcmds
Produce complement of file specification progs/gcomp
Produces complete image of structured data procs/fullimag
Perform complex arithmetic ......... procs/complex
Perform mathematical computations ............... procs/math
Produce concordance ................ progs/concord
Produce keywords in context .................... progs/kwic
recognizer for sentences in a context-free language Generate progs/recgen
/instances of sentences from context-sensitive grammars . progs/csgen
Programmer-defined control operations ......... procs/pdco
Hexadecimal conversion ................. procs/hexcvt
Radix conversion ................. procs/radcon
Format and convert numbers ............ procs/numbers
Produce cross reference for Icon program progs/ipxref
Arrange data into columns .......... procs/colmize
Arrange data into columns .......... progs/colm
Convert binary data ....................... procs/bincvt
to encode and decode Icon data Procedures ............ procs/codeobj
complete image of structured data Produces .............. procs/fullimag
Format columnar data ....................... procs/printcol
image of structured data Produces "executable" . procs/ximage
Procedures to encode and decode Icon data ........... procs/codeobj
Encode and decode Icon values ......... procs/object
state transitions for Huffman decoding. Compute ......... progs/hufftab
Collate and decollate strings .......... procs/collate
Compute greatest cmmon denominator ................ procs/gcd
Show differences files .......... progs/diffn
Instances of different syntactic forms in Icon progs/proto
List different words ............ progs/diffword
commands and macros in a roff document List .............. progs/roffcmds
Produce script for the ed editor .................. progs/edscript
Produce script for the ed editor ..................... progs/edscript
Map list elements ................... procs/lmap
Procedures for enboldening and underscoring test procs/bold
Procedures to encode and decode Icon data procs/codeobj
Diff engine ..................... procs/dif
Interpret Icon literal escapes .................... procs/escape
Programmer-defined argument evaluation ................. procs/pdae
structured data Produces "executable" image of ...... procs/ximage
Parse arithmetic expressions ................ progs/parsex
Parse file names ................. procs/filename
Delaminate file ....................... progs/delam
representations of characters in file Display ............... progs/fileprnt
Process LaTeX .idx file ....................... progs/latexidx
Produce load map of UNIX obect file ....................... progs/loadmap
Shuffle lines in a file ....................... progs/shuffile
Tabulate characters in a file ....................... progs/tablc
Tabulate words in a file ....................... progs/tablw
Tabulate properties of text file ....................... progs/textcnt
Trim lines in a file ....................... progs/trim
Produce complement of file specification ......... progs/gcomp
Delaminate file using tab characters .. progs/delamc
Show differences files ...................... progs/diffn
Split Icon program into separate files ...................... progs/ipsplit
Laminate files ...................... progs/lam
Package multiple files ...................... progs/pack
Unpackage files ...................... progs/unpack
Generic filter skeleton in Icon .... progs/filter
source program. Utility to find undeclared variables in Icon progs/iundecl
Currency formatting procedure ....... procs/currency
Printf-style formatting ................. procs/printf
Instances of different syntactic forms in Icon .............. progs/proto
Play the game of solitaire .......... progs/solit
Animal game ....................... progs/animal
Produce generalized image of Icon value procs/image
selected sentences from a grammar Generate randomly .. progs/rsg
sentences from context-sensitive grammars Generate instances of progs/csgen
Compute greatest cmmon denominator . procs/gcd
Sort groups of lines ............ progs/grpsort
Deal bridge hands ...................... progs/deal
Filter out identical adjacent lines ... progs/unique
Process LaTeX .idx file .................. progs/latexidx
Produce string image of Icon result sequence procs/seqimage
Produce generalized image of Icon value ........ procs/image
Produces complete image of structured data ... procs/fullimag
Produces "executable" image of structured data ... procs/ximage
Write Icon code to write input ...................... progs/iwriter
context-sensitive/ Generate instances of sentences from progs/csgen
Large integer arithmetic ......... procs/largint
Lisp interpreter ................ progs/lisp
Display intersection of words ...... progs/cross
Diagram character intersections of strings ... progs/kross
Produce keywords in context ........ progs/kwic
Play kriegspiel ................. progs/krieg
Sort mailing labels by ZIP code ......... progs/zipsort
Format mailing labels ..................... progs/labels
for sentences in a context-free language Generate recognizer progs/recgen
numbers Generate letter combinations for phone procs/phoname
Shuffle lines in a file ............ progs/shuffile
Trim lines in a file ............ progs/trim
write() Wrap lines of output for use with procs/wrap
Sort groups of lines ...................... progs/grpsort
Filter out identical adjacent lines ...................... progs/unique
Icon "link" Cross Reference Utility progs/ilnkxref
Map list elements .............. procs/lmap
Interpret Icon literal escapes ............ procs/escape
Produce load map of UNIX obect file progs/loadmap
Simulate a Turing machine .................... progs/turing
List commands and macros in a roff document .. progs/roffcmds
Sort mailing labels by ZIP code . progs/zipsort
Format mailing labels ............. progs/labels
Summarize Icon memory management ................. progs/memsum
Produce load map of UNIX obect file ..... progs/loadmap
Pattern matching in the style of SNOBOL4 procs/patterns
Perform mathematical computations .. procs/math
Summarize Icon memory management .......... progs/memsum
Generate miscellaneous sequences .... procs/gener
Package multiple files ............. progs/pack
Parse file names ...................... procs/filename
Generate n-grams .................... procs/ngrams
Generate solutions to the n-queens problem ........... progs/queens
Display solutions to n-queens problem ........... progs/vnq
Process n-tuples ................... procs/tuple
Format and convert numbers .................... procs/numbers
letter combinations for phone numbers Generate ........... procs/phoname
Perform arithmetic on rational numbers .................... procs/rational
Produce load map of UNIX obect file ................. progs/loadmap
Programmer-defined control operations ................. procs/pdco
Structure operations ................. procs/structs
Get command-line options .................... procs/options
Wrap lines of output for use with write() procs/wrap
a character ruler to standard output Write ............... progs/ruler
Produce random parenthesis-balanced strings progs/parens
Letter patterns in words .......... procs/patword
Generate letter combinations for phone numbers .............. procs/phoname
Icon preprocessor ............... progs/ipp
solutions to the n-queens problem Generate ........... progs/queens
Display solutions to n-queens problem .................... progs/vnq
Currency formatting procedure .................. procs/currency
Customizable sort procedure .................. procs/isort
Service procedures ................. procs/usage
Sort Icon procedures ................. progs/ipsort
Split Icon program into separate files progs/ipsplit
Print Icon program .................... progs/iprint
Produce cross reference for Icon program .................... progs/ipxref
Entab an Icon program .................... progs/itab
variables in Icon source program. /to find undeclared progs/iundecl
Tabulate properties of text file .... progs/textcnt
strings Produce random parenthesis-balanced progs/parens
Generate random text ................ progs/monkeys
a grammar Generate randomly selected sentences from progs/rsg
Filter to word wrap a range of text .............. progs/format
Perform arithmetic on rational numbers ........... procs/rational
context-free language Generate recognizer for sentences in a progs/recgen
Produce cross reference for Icon program . progs/ipxref
Map string into bit representation ............. procs/mapbit
file Display representations of characters in progs/fileprnt
Produce string image of Icon result sequence ............ procs/seqimage
List commands and macros in a roff document .............. progs/roffcmds
Write a character ruler to standard output ... progs/ruler
Show snapshot of Icon string scanning ................... procs/snapshot
Produce script for the ed editor ... progs/edscript
Generate randomly selected sentences from a grammar progs/rsg
Generate randomly selected sentences from a grammar ... progs/rsg
grammars Generate instances of sentences from context-sensitive progs/csgen
Generate sentences in Lindenmayer system progs/linden
language Generate recognizer for sentences in a context-free progs/recgen
Split Icon program into separate files ............. progs/ipsplit
string image of Icon result sequence Produce ........... procs/seqimage
Generate miscellaneous sequences .................. procs/gener
Quote word for shells ..................... procs/shquote
Parse simple statements .......... progs/parse
Generic filter skeleton in Icon ........... progs/filter
Show snapshot of Icon string scanning procs/snapshot
Play the game of solitaire .................. progs/solit
Display solutions to n-queens problem progs/vnq
Generate solutions to the n-queens problem progs/queens
Customizable sort procedure ............. procs/isort
Produce complement of file specification .............. progs/gcomp
Write a character ruler to standard output ............ progs/ruler
Parse simple statements ................. progs/parse
sequence Produce string image of Icon result procs/seqimage
Map string into bit representation procs/mapbit
Segment string ..................... procs/segment
Show snapshot of Icon string scanning ............ procs/snapshot
Convert string to Morse code ....... procs/morse
Generate strings from the MIU system progs/miu
Collate and decollate strings .................... procs/collate
character intersections of strings Diagram ............ progs/kross
random parenthesis-balanced strings Produce ............ progs/parens
Produces complete image of structured data ............ procs/fullimag
Produces "executable" image of structured data ............ procs/ximage
Pattern matching in the style of SNOBOL4 ........... procs/patterns
Instances of different syntactic forms in Icon .... progs/proto
Generate sentences in Lindenmayer system ..................... progs/linden
Generate strings from the MIU system ..................... progs/miu
Delaminate file using tab characters ............. progs/delamc
for enboldening and underscoring test Procedures ............ procs/bold
Tabulate properties of text file .................. progs/textcnt
Filter to word wrap a range of text ....................... progs/format
Generate random text ....................... progs/monkeys
Compute state transitions for Huffman decoding. progs/hufftab
source program. Utility to find undeclared variables in Icon progs/iundecl
Procedures for enboldening and underscoring test .......... procs/bold
Wrap lines of output for use with write() ........... procs/wrap
Delaminate file using tab characters ....... progs/delamc
String utilities .................. procs/strings
Produce generalized image of Icon value ...................... procs/image
Encode and decode Icon values ..................... procs/object
Shuffle values ..................... procs/shuffle
Utility to find undeclared variables in Icon source program. progs/iundecl
Quote word for shells ............ procs/shquote
Filter to word wrap a range of text .. progs/format
Tabulate words in a file ............ progs/tablw
Letter patterns in words ...................... procs/patword
Display intersection of words ...................... progs/cross
List different words ...................... progs/diffword
Filter to word wrap a range of text ....... progs/format
Write Icon code to write input ................ progs/iwriter
Wrap lines of output for use with write() .................... procs/wrap
From tenaglia@fps.mcw.edu Wed Jun 20 07:50:25 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA20919; Wed, 20 Jun 90 07:50:25 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.3/3.06) with UUCP
id AA06084; Wed, 20 Jun 90 10:18:14 EDT
Received: by uwm.edu; id AA12108; Wed, 20 Jun 90 08:43:17 -0500
Message-Id: <9006201343.AA12108@uwm.edu>
Received: from mis by fps.mcw.edu (DECUS UUCP w/Smail);
Wed, 20 Jun 90 08:20:23 CDT
Received: by mis.mcw.edu (DECUS UUCP w/Smail);
Wed, 20 Jun 90 08:11:31 CDT
Date: Wed, 20 Jun 90 08:11:31 CDT
From: Chris Tenaglia - 257-8765 <tenaglia@mis.mcw.edu>
To: icon-group@cs.arizona.edu
Subject: Generators with tables
Status: O
Icon has these wonderful generator things. They work well with strings and
numbers, and lists, and perhaps even sets. But it doesn't lend itself to
tables. I wonder if there isn't a better way to generate the contents of
a table other than sort(). What about some amper variables like &first,
&next, &prior, &last, and &pointer that one could use to peruse the
entries and assignments in a table structure. For example :
# initialization
tank := table("")
while line := read() do
{
entry := parse(line,1)
asgn := parse(line,2)
tank[entry] := asgn
}
# and now the main loop
first_entry := tank[&first]
last_asgn := member(tank,&last)
repeat # this code really doesn't do
{ # anything except illustrate
&pointer := &first # a possibility
while asgn := tank[&next] do
if asgn == tank[&prior] then handle_dupe()
}
Perhaps a ?? operator might be envisioned for structure scanning? These
amper variables could be used like &pos, and &subject. Any ideas? Are these
concepts compatible with the destiny of icon? Would anyone else think they're
useful? Hmmm.
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu
From ralph Wed Jun 20 08:03:47 1990
Date: Wed, 20 Jun 90 08:03:47 -0700
From: "Ralph Griswold" <ralph>
Message-Id: <9006201503.AA21476@megaron.cs.arizona.edu>
Received: by megaron.cs.arizona.edu (5.61/15)
id AA21476; Wed, 20 Jun 90 08:03:47 -0700
To: icon-group@cs.arizona.edu, tenaglia@mis.mcw.edu
Subject: Re: Generators with tables
In-Reply-To: <9006201343.AA12108@uwm.edu>
Status: O
Version 8 of Icon has a generator for tables -- key(T). It generates
the keys, and from them you can get to the values, if you wish.
See pages 74-75 of the second edition of The Icon Programming Language.
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From esquire!info8!yost@cmcl2.NYU.EDU Wed Jun 20 09:17:53 1990
Received: from cmcl2.NYU.EDU (NYU.EDU) by megaron (5.61/15) via SMTP
id AA26062; Wed, 20 Jun 90 09:17:53 -0700
Received: by cmcl2.NYU.EDU (5.61/1.34)
id AA09571; Wed, 20 Jun 90 12:19:09 -0400
Received: from info8 by ESQUIRE.DPW. id aa23235; 20 Jun 90 12:06 EDT
Received: from localhost by info8. (4.0/SMI-4.0)
id AA09048; Wed, 20 Jun 90 12:09:34 EDT
Message-Id: <9006201609.AA09048@info8.>
From: yost@DPW.COM (Dave Yost)
Reply-To: yost@DPW.COM (Dave Yost)
To: "Ralph Griswold" <ralph@cs.arizona.edu>
Cc: icon-group@cs.arizona.edu, yost@cmcl2.NYU.EDU
Subject: Re: Generators with tables
In-Reply-To: Your message of Wed, 20 Jun 90 08:03:47 PDT.
<9006201503.AA21476@megaron.cs.arizona.edu>
Phone: +1 212-266-0796 (Voice Direct Line)
Fax: +1 212-266-0790
Organization: Davis Polk & Wardwell
1 Chase Manhattan Plaza
New York, NY 10005
Date: Wed, 20 Jun 90 12:09:30 -0400
Sender: yost@info8.NYU.EDU
Status: O
# Version 8 of Icon has a generator for tables -- key(T). It generates
# the keys, and from them you can get to the values, if you wish.
The book doesn't specify the order in which key(T)
generates the keys. I assume it is likely not the same
order you would get from a sort on the table, right?
While we're on the subject,
The sort operations on tables generate lists that
include all the keys and values. In some (many?)
circumstances one uses only the values from that sorted
list. Wouldn't it be more efficient in those cases if
there were a table sort operation that generated a list
of table values only, sorted by key?
--dave yost
yost@dpw.com or uunet!esquire!yost
Please ignore the From or Reply-To fields above, if different.
From goer@sophist.uchicago.EDU Wed Jun 20 10:05:46 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA29473; Wed, 20 Jun 90 10:05:46 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from tank.uchicago.edu by Arizona.EDU; Wed, 20 Jun 90 10:07 MST
Received: from sophist.uchicago.edu by tank.uchicago.edu Wed, 20 Jun 90
12:03:25 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA12922; Wed, 20 Jun 90
11:56:16 CDT
Resent-Date: Wed, 20 Jun 90 10:07 MST
Date: Wed, 20 Jun 90 11:56:16 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: followup on tables
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <7862590EE75F4009CF@Arizona.EDU>
Message-Id: <9006201656.AA12922@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
Dave Yost says:
The sort operations on tables generate lists that
include all the keys and values. In some (many?)
circumstances one uses only the values from that sorted
list. Wouldn't it be more efficient in those cases if
there were a table sort operation that generated a list
of table values only, sorted by key?
I dunno, but Icon seems to be pretty big as it is. Let's see
if this can be done using existing facilities. Hmmm:
procedure get_values(tbl)
# suspends the values of tbl, in order, sorted by the
# their respective keys
tmp_list := sort(tbl,3)
suspend tmp_list[2 to *tmp_list by 2]
end
If you want these sorted values in a list, you could say
val_list := []
every put(val_list,get_values(tbl))
It's just my personal opinion, but I think that this is easier and
clearer at it is, without an extra function or operator. You could
put a set of little functions like this into a library, and use them
as if they were built-in.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From icon-group-request@arizona.edu Wed Jun 20 10:37:51 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA02600; Wed, 20 Jun 90 10:37:51 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Wed, 20 Jun 90 10:39 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA02376; Wed, 20 Jun 90
10:27:20 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 20 Jun 90 10:40 MST
Date: 20 Jun 90 16:09:40 GMT
From: midway!sophist!goer@uunet.uu.NET
Subject: RE: Generators with tables
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <785DDB3506BF400A30@Arizona.EDU>
Message-Id: <1990Jun20.160940.3058@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
References: <9006201343.AA12108@uwm.edu>
Status: O
In article <9006201343.AA12108@uwm.edu> tenaglia@mis.mcw.edu (Chris Tenaglia - 257-8765) writes:
>Perhaps a ?? operator might be envisioned for structure scanning? These
>amper variables could be used like &pos, and &subject. Any ideas? Are these
>concepts compatible with the destiny of icon? Would anyone else think they're
>useful? Hmmm.
I don't usually have to scan tables, since any tables I use are usually
there for dynamic modification and extension, and not for the things one
normally associates with scanning. HOWEVER, there are times when I would
have liked to do things like "scan" lists and "strings" of integers or
just bits (say when Huffmon encoding, doing BCD, etc). I'll bet that, at
least for lists, it wouldn't be too hard to simulate scanning.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From esquire!info8!yost@cmcl2.NYU.EDU Wed Jun 20 12:03:43 1990
Received: from cmcl2.NYU.EDU (NYU.EDU) by megaron (5.61/15) via SMTP
id AA11359; Wed, 20 Jun 90 12:03:43 -0700
Received: by cmcl2.NYU.EDU (5.61/1.34)
id AA15697; Wed, 20 Jun 90 15:05:18 -0400
Received: from info8 by ESQUIRE.DPW. id aa25472; 20 Jun 90 14:12 EDT
Received: from localhost by info8. (4.0/SMI-4.0)
id AA09449; Wed, 20 Jun 90 14:15:49 EDT
Message-Id: <9006201815.AA09449@info8.>
From: yost@DPW.COM (Dave Yost)
Reply-To: yost@DPW.COM (Dave Yost)
To: griswold@cs.arizona.edu
Subject: The Image(x,style) ipl proc
Cc: yost@cmcl2.NYU.EDU, icon-group@cs.arizona.edu
Phone: +1 212-266-0796 (Voice Direct Line)
Fax: +1 212-266-0790
Organization: Davis Polk & Wardwell
1 Chase Manhattan Plaza
New York, NY 10005
Date: Wed, 20 Jun 90 14:15:47 -0400
Sender: yost@info8.NYU.EDU
Status: O
I was very pleased and honored to see in the v8 release
that you adopted my 'style' argument enhancement to the
Image() procedure (practically without change!), and
credited me at the top of the file.
Thank you very much. You made my day (and maybe week).
And many thanks for the new updated Icon book. I
hope somebody will send out press releases to all the
periodicals that might write it up. It's a perfect
opportunity for some articles to start appearing about
Icon, one of the "best kept secrets" in software.
--dave yost
yost@dpw.com or uunet!esquire!yost
Please ignore the From or Reply-To fields above, if different.
From icon-group-request@arizona.edu Wed Jun 20 12:52:23 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA14250; Wed, 20 Jun 90 12:52:23 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Wed, 20 Jun 90 12:54 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA11759; Wed, 20 Jun 90
12:38:53 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 20 Jun 90 12:54 MST
Date: 19 Jun 90 22:02:52 GMT
From: amdahl!ntmtv!hildum@apple.COM
Subject: Excess paging problem. Bug?
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <784B0DA6369F400B2E@Arizona.EDU>
Message-Id: <1259@ntmtv.UUCP>
Organization: Northern Telecom (Mountain View, CA)
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
The following program, when run on my Sun workstation, uses about
2.5Mbytes of resident and 7Mbytes of virtual address when the -s
and -m options are specified. The input file contains two tables, the
first with ~1300 entries, each a set of ~1.2 elements on average. The
second table contains ~200 entries, each a set of ~7 elements.
I have noticed that the coexpression processing takes a long time, and
that a lot of garbage collection is taking place. The program will
create and delete ~1500 coexpressions, but they are all the same size.
What is causing the program to grow to a very large size, and is the
paging caused by garbage collection when the size is ~7Mbytes?
Is this a bug in Icon?
System Sun 3/60, 8Mbytes, SunOS 4.0.3, 68881
Icon version 8, software checking for 68881 (cc -fswitch)
#
#
# This program reads two tables which store the dependencies
# among source files and segments. One table is a list of
# source file (names) and the segments that are included in
# file, the other is a list of segment names and the source
# files which include them. It then scans the tables for the
# source or segments specified on the command line and
# reports the corresponding segments included or sources
# including the source or segment.
#
# Invokation:
#
# msl1depend -d dependencies names [-m] [-s]
#
# where
#
# -d dependencies
# the name of the file containing the dependencies
# tables.
#
# -m print all the source files and the segments that
# that they contain
#
# -s print all the segments and the files that contain
# them
#
#
#
link colmize, object, options, usage
global arguments
procedure main(parameters)
static usage_string
local dependencies # The dependencies table
local includes # The includes table
local source_names # The requested source names
local segment_names # The requested segment names
local name
local input_file # The dependencies data file
#
# Set the command description string to describe the command
# and all valid options.
#
initial {
usage_string := "msl1depend " ||
"-d dependenciesfile" ||
"names [-m] [-s]"
}
#
# Test the Icon implementation to ensure that all required
# features are implemented.
#
Requires("UNIX")
Requires("co-expressions")
Requires("environment variables")
#
# Set the name lists to be empty sets
#
source_names := set()
segment_names := set()
#
# Process the command line options, obtaining a table of the
# specified options and a list of parameters.
#
arguments := options(parameters, "d:ms")
#
# Make sure some names will be processed.
#
if /arguments["m"] & /arguments["s"] & *parameters = 0 then
Usage(usage_string)
#
# Verify that the dependencies file has been specified and may be
# read.
#
\arguments["d"] | Usage(usage_string)
(input_file := open(arguments["d"], "r")) | stop("Unable to open" ||
arguments["d"])
#
# Load the dependencies and includes tables.
#
dependencies := getobj(input_file)
includes := getobj(input_file)
#
# Close the input file
#
close(input_file)
#
# Determine the type of name requested, and add it to the
# appropriate list of names for later processing. If a name
# is not in one of the key lists, then print a message.
#
every name := lowercase(!parameters) do {
if name == key(dependencies) then insert(segment_names, name)
else if name == key(includes) then insert(source_names, name)
else write("Name ", name, " is not a segment or source name")
}
#
# Process remaining arguments.
#
/arguments["m"] | every name := key(includes) do
insert(source_names, name)
/arguments["s"] | every name := key(dependencies) do
insert(segment_names, name)
#
# Print requested information or stop.
#
if *source_names = *segment_names = 0 then
stop("No valid names have been specified")
write()
if 0 < *source_names then
print_source_includes(sort(source_names), includes)
write()
if 0 < *segment_names then
print_segment_dependencies(sort(segment_names), dependencies)
return
end
procedure lowercase(name)
#
# Convert all the uppercase characters in name to lower case.
#
return map(name, &ucase, &lcase)
end
procedure print_source_includes(names, values)
local name
local line
local tag
write("Source Segments included")
write("-----------------------------")
every name := !names do {
tag := create(left(name, 10) | |repl(" ", 10))
if 0 < *values[name] then
every line := colmize(sort(values[name]), 70, 2, 10) do
write(@tag || line)
else
write(left(name, 10), "-- does not include any segments --")
}
end
procedure print_segment_dependencies(names, values)
local name
local line
local tag
write("Segment Msource files including segment")
write("-------------------------------------------")
every name := !names do {
tag := create(left(name, 10) | |repl(" ", 10))
if 0 < *values[name] then
every line := colmize(sort(values[name]), 70, 2, 10) do
write(@tag || line)
else
write(left(name, 10), "-- is not included in any source --")
}
end
From ralph Wed Jun 20 13:01:49 1990
Date: Wed, 20 Jun 90 13:01:49 -0700
From: "Ralph Griswold" <ralph>
Message-Id: <9006202001.AA14789@megaron.cs.arizona.edu>
Received: by megaron.cs.arizona.edu (5.61/15)
id AA14789; Wed, 20 Jun 90 13:01:49 -0700
To: amdahl!ntmtv!hildum@apple.COM
Subject: Re: Excess paging problem. Bug?
Cc: icon-group
Status: O
Without looking closely, I'd suspect your problem is that your program
is never able to collect any co-expression. When you create a co-expression,
it clones a copy of all local variables. In something like
every ... do {
tab := create ...
}
the newly created co-expression references the identifier tag, and hence
the last co-expression. What you get is a long chain of inaccessible, but
also uncollectable co-expressions. The thing to do is
every ... do {
tab := &null
tab := create ...
}
This problem is mentioned in TR 90-1, incidentally, but unless you've
been bitten by it, you'd probably not think to look for it.
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From cjeffery Wed Jun 20 14:59:15 1990
Resent-From: "Clinton Jeffery" <cjeffery>
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA20763; Wed, 20 Jun 90 14:59:15 -0700
Received: from megaron (megaron.cs.Arizona.EDU) by Arizona.EDU; Wed, 20 Jun 90
15:01 MST
Received: from cheltenham.cs.arizona.edu by megaron (5.61/15) via SMTP id
AA20745; Wed, 20 Jun 90 14:58:33 -0700
Received: by cheltenham.cs.arizona.edu; Wed, 20 Jun 90 14:58:31 MST
Resent-Date: Wed, 20 Jun 90 15:01 MST
Date: Wed, 20 Jun 90 14:58:31 MST
From: Clinton Jeffery <cjeffery@cs.arizona.edu>
Subject: Generators with tables
Resent-To: icon-group@cs.arizona.edu
To: midway!sophist!goer@uunet.uu.NET
Cc: icon-group@arizona.edu
Resent-Message-Id: <78395BCC2F3F40089D@Arizona.EDU>
Message-Id: <9006202158.AA22477@cheltenham.cs.arizona.edu>
In-Reply-To: midway!sophist!goer@uunet.uu.NET's message of 20 Jun 90 16:09:40
GMT <1990Jun20.160940.3058@midway.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: midway!sophist!goer@uunet.uu.NET
X-Vms-Cc: icon-group@Arizona.edu
Status: O
On generalizations of Icon's string scanning, Chris Tenaglia writes:
>>Perhaps a ?? operator might be envisioned for structure scanning?
Richard Goerwitz responds:
>I don't usually have to scan tables...HOWEVER, there are times when I would
>have liked to do things like "scan" lists and "strings" of integers or
>just bits (say when Huffmon encoding, doing BCD, etc). I'll bet that, at
>least for lists, it wouldn't be too hard to simulate scanning.
I don't have a complete implementation for you, but one approach to list
scanning is suggested in the technical report on Idol, present in the
Version 8 Icon Program Library. If anyone extends my class ListScan to
the point where it is generally useful, I'd appreciate a copy. List
scanning is a good example of where Idol can be useful to regular Icon
programmers who want nothing to do with "object-oriented programming".
From goer@sophist.uchicago.EDU Thu Jun 21 10:15:24 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA02553; Thu, 21 Jun 90 10:15:24 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from tank.uchicago.edu by Arizona.EDU; Thu, 21 Jun 90 10:17 MST
Received: from sophist.uchicago.edu by tank.uchicago.edu Thu, 21 Jun 90
12:16:19 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA14288; Thu, 21 Jun 90
12:12:30 CDT
Resent-Date: Thu, 21 Jun 90 10:17 MST
Date: Thu, 21 Jun 90 12:12:30 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: list manipulation
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <7797DB36ED7F401056@Arizona.EDU>
Message-Id: <9006211712.AA14288@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
Short question for anyone (not just experts):
What is the most facile way of moving an element from one position
to another in a list? Suppose I have ["a","b","c"], and I want
["a","c","b"]. Does anyone have any suggestions as to how this
sort of manipulation might be done in Icon (in a generalized man-
ner), short of
lst := lst[1:i-1] ||| lst[i+1:0] ||| lst[i-1:i+1]
That looks terrible, and slow to boot.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From ralph Thu Jun 21 10:30:35 1990
Date: Thu, 21 Jun 90 10:30:35 -0700
From: "Ralph Griswold" <ralph>
Message-Id: <9006211730.AA03365@megaron.cs.arizona.edu>
Received: by megaron.cs.arizona.edu (5.61/15)
id AA03365; Thu, 21 Jun 90 10:30:35 -0700
To: goer@sophist.uchicago.EDU
Subject: Re: list manipulation
Cc: icon-group
In-Reply-To: <9006211712.AA14288@sophist.uchicago.edu>
Status: O
Try
L[i] :=: L[j]
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From ralph Thu Jun 21 10:58:14 1990
Date: Thu, 21 Jun 90 10:58:14 -0700
From: "Ralph Griswold" <ralph>
Message-Id: <9006211758.AA05465@megaron.cs.arizona.edu>
Received: by megaron.cs.arizona.edu (5.61/15)
id AA05465; Thu, 21 Jun 90 10:58:14 -0700
To: icon-group
Subject: rearranging list elements
Status: O
For a general way to *rearrange* the elements in a list, see lmap.icn
in Version 8 of the Icon program library and the portion of the Icon
language book that deals with transpositions.
(This method is overbearing unless you want to do the same rearrangement
on several lists.)
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From R@edinburgh.ac.uk Fri Jun 22 09:06:46 1990
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA01873; Fri, 22 Jun 90 09:06:46 -0700
Received: from UKACRL.BITNET by Arizona.EDU; Fri, 22 Jun 90 08:06 MST
Received: from RL.IB by UKACRL.BITNET (Mailer X1.25) with BSMTP id 0850; Fri,
22 Jun 90 15:40:45 BST
Date: 22 Jun 90 15:41:02 bst
From: R.J.Hare@edinburgh.ac.uk
Subject: Constant table space
To: icon-group@cs.arizona.edu
Message-Id: <22 Jun 90 15:41:02 bst 340301@EMAS-A>
Via: UK.AC.ED.EMAS-A; 22 JUN 90 15:40:36 BST
X-Envelope-To: icon-group@cs.arizona.EDU
Status: O
This may be a dumb question...
I am getting the message "out of constant table space" from an Icon program I
am trying to run on our Sequent, running Dynix. I can't see anything in the
Icon book which tells me which environment variable to set to get round this
problem (if it can be got round at all) can anyone suggest a way round this
problem please (It is rather a large table...)?
Thanks.
Roger Hare.
From goer@sophist.uchicago.EDU Fri Jun 22 11:25:56 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA09538; Fri, 22 Jun 90 11:25:56 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from tank.uchicago.edu by Arizona.EDU; Fri, 22 Jun 90 11:28 MST
Received: from sophist.uchicago.edu by tank.uchicago.edu Fri, 22 Jun 90
13:27:11 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA15827; Fri, 22 Jun 90
13:23:20 CDT
Resent-Date: Fri, 22 Jun 90 11:28 MST
Date: Fri, 22 Jun 90 13:23:20 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: testers
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <76C4CACB1F7F40161D@Arizona.EDU>
Message-Id: <9006221823.AA15827@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I'm writing an icon-termlib and windowing library. The termlib part
is done (please, no sniping for not using terminfo :-). I'm now work-
ing on the windows part. So far I can create, foreground, delete,
etc., and I've gotten things so that you can write to any window at
any time (whether visible or not). There is no notion of a "current
window." My difficulty is that I don't have anything but ANSI-family
terminals to work with, and so I don't have the opportunity of testing
anything out on a broad range of platforms. I'd really appreciate it
if some kind unix-using soul could test a sample program out on a non-
ANSI-ish terminal (wyses, vt100s, etc. are all out). Though the win-
dowing part is not done, you'll get a fairly well-tested termlib out
of it (and a warm feeling in your heart :-). I just want to be sure
this thing works, such as it is, before going on much farther. Thanks.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU Wed Jun 27 00:47:35 1990
Received: from noao.edu by megaron (5.61/15) via SMTP
id AA10270; Wed, 27 Jun 90 00:47:35 -0700
Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G41)
id AA29553; Wed, 27 Jun 90 00:47:29 MST; for icon-group@cs.arizona.edu
Received: by ncar.ucar.EDU (5.61/ NCAR Central Post Office 04/10/90)
id AA21602; Wed, 27 Jun 90 01:47:27 MDT
Received: from tank.uchicago.edu by oddjob.uchicago.edu Wed, 27 Jun 90 01:47:04 -0500
Received: from sophist.uchicago.edu by tank.uchicago.edu Wed, 27 Jun 90 01:48:47 CDT
Return-Path: <goer@zenu.uucp>
Received: by sophist.uchicago.edu (3.2/UofC3.0)
id AA21090; Wed, 27 Jun 90 01:44:52 CDT
Received: by sophist.uchicago.edu (smail2.5)
id AA00415; 26 Jun 90 23:36:49 PDT (Tue)
Subject: itermlib
To: icon-group@arizona.edu
Date: Tue, 26 Jun 90 23:36:48 PDT
X-Mailer: ELM [version 2.2 PL0]
Message-Id: <9006262336.AA00415@sophist.uchicago.edu>
From: goer@sophist.uchicago.edu (Richard Goerwitz)
Status: O
I've been asked by several people to post the following software, des-
pite its preliminary nature. That's fine with me. I've been using it
for a while now, and there are sections of code I just won't ever have
the opportunity of testing in my current range of computing environ-
ments. I can use all the bug reports I can get.
Sorry about the annoying disclaimer included below. Some recent con-
tacts with the legal staff of an outfit using software posted here
has led me to think it sensible a) to copyright everything, however
trivial, b) to make absolutely clear the free and unrestricted nature
of the code, and c) to disclaim any responsibility for anything that
might occur in conjunction with its (ab)use.
Note: Contrary to my usual practices, I've packed this as a shar
archive. It's 400 lines of code, too. If anyone feels that one of
the source newsgroups might be a better place, please let me know.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
#!/bin/sh
# This is a shell archive (shar 3.24)
# made 06/27/1990 06:12 UTC by richard@zenu (goer@sophist.uchicago.edu)
#
# existing files WILL be overwritten
# This format requires very little intelligence at unshar time.
# "echo" and "sed" will be needed.
#
# ============= itlib024.icn ==============
echo "x - extracting itlib024.icn (Text)"
sed 's/^X//' << 'SHAR_EOF' > itlib024.icn &&
X########################################################################
X#
X# Name: itermlib.icn
X#
X# Title: Icon termlib-type tools
X#
X# Author: Richard L. Goerwitz
X#
X# Date: June 19, 1990 (version 0.24 - beta test)
X#
X########################################################################
X#
X# Copyright (c) 1990, Richard L. Goerwitz, III
X#
X# This software is intended for free and unrestricted distribution.
X# I place only two conditions on its use: 1) That you clearly mark
X# any additions or changes you make to the source code, and 2) that
X# you do not delete this message therefrom. In order to protect
X# myself from spurious litigation, it must also be stated here that,
X# because this is free software, I, Richard Goerwitz, make no claim
X# about the applicability or fitness of this software for any
X# purpose, and expressly disclaim any responsibility for any damages
X# that might be incurred in conjunction with its use.
X#
X########################################################################
X#
X# The following library represents a series of rough functional
X# equivalents to the standard Unix low-level termcap routines. They
X# are not meant as exact termlib clones. Nor are they enhanced to
X# take care of magic cookie terminals, terminals that use \D in their
X# termcap entries, or, in short, anything I felt would not affect my
X# work. If anyone enhances these routines, I'd deeply appreciate it
X# if they would share their changes with me and/or the rest of the
X# Icon community.
X#
X# Requires: A unix platform & co-expressions. Certainly the
X# package could be altered for use with MS-DOS and other systems.
X# Please contact me if advice on how to do this is needed.
X#
X# setname(term)
X# Use only if you wish to initialize itermlib for a terminal
X# other than what your current environment specifies. "Term" is the
X# name of the termcap entry to use. Normally this initialization is
X# done automatically, and need not concern the user.
X#
X# getval(id)
X# Works something like tgetnum, tgetflag, and tgetstr. In the
X# spirit of Icon, all three have been collapsed into one routine.
X# Integer valued caps are returned as integers, strings as strings,
X# and flags as records (if a flag is set, then type(id) will return
X# "true"). Absence of a given capability is signalled by procedure
X# failure.
X#
X# igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)!
X# Analogous to tgoto. Make "cm" the cursor movement command for
X# the current terminal, as obtained via getval("cm"). Igoto()
X# returns a string which, when output via iputs, will cause the
X# cursor to move to column "destcol" and line "destline." Column and
X# line are always calculated using a *one* offset. This is far more
X# Iconish than the normal zero offset used by tgoto. If you want to
X# go to the first square on your screen, then input
X# "igoto(getval("cm"),1,1).
X#
X# iputs(cp,affcnt)
X# Equivalent to tputs. "Cp" is a string obtained via getval(),
X# or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a
X# count of affected lines. It is only relevant for terminals which
X# specify proportional (starred) delays in their termcap entries.
X#
X##########################################################################
X
X
Xglobal tc_table, tty_speed
Xrecord true()
X
X
Xprocedure check_features()
X
X local in_params, yes_tabs, line
X # global tty_speed
X
X initial {
X find("unix",map(&features)) |
X er("check_features","unix system required",1)
X find("o-expres",&features) |
X er("check_features","co-expressions not implemented - &$#!",1)
X system("/bin/stty tabs") |
X er("check_features","can't set tabs option",1)
X }
X
X # clumsy, clumsy, clumsy, and probably won't work on all systems
X in_params := open("/bin/stty 2>&1","pr") |
X (ospeed := &null, fail)
X every line := !in_params do {
X yes_tabs := find("tabs",line) #unused
X line ? {
X tty_speed := (tab(find("speed")+5), tab(many(' ')),
X integer(tab(many(&digits))))
X }
X }
X close(in_params)
X return "term characteristics reset; features check out"
X
Xend
X
X
X
Xprocedure setname(name)
X
X # Sets current terminal type to "name" and builds a new termcap
X # capability database (residing in tc_table). Fails if unable to
X # find a termcap entry for terminal type "name." If you want it
X # to terminate with an error message under these circumstances,
X # comment out "| fail" below, and uncomment the er() line.
X
X #tc_table is global
X
X check_features()
X
X tc_table := maketc_table(getentry(name)) | fail
X # er("setname","no termcap entry found for "||name,3)
X return "successfully reset for terminal " || name
X
Xend
X
X
X
Xprocedure getname()
X
X # Getname() first checks to be sure we're running under Unix, and,
X # if so, tries to figure out what the current terminal type is,
X # checking successively the value of the environment variable
X # TERM, and then the output of "tset -". Terminates with an error
X # message if the terminal type cannot be ascertained.
X
X local term, tset_output
X
X check_features()
X
X if not (term := getenv("TERM")) then {
X tset_output := open("/bin/tset -","pr") |
X er("getname","can't find tset command",1)
X term := !tset_output
X close(tset_output)
X }
X return \term |
X er("getname","can't seem to determine your terminal type",1)
X
Xend
X
X
X
Xprocedure er(func,msg,errnum)
X
X # short error processing utility
X write(&errout,func,": ",msg)
X exit(errnum)
X
Xend
X
X
X
Xprocedure getentry(name)
X
X # "Name" designates the current terminal type. Getentry() scans
X # the current environment for the variable TERMCAP. If the
X # TERMCAP string represents a termcap entry for a terminal of type
X # "name," then getentry() returns the TERMCAP string. Otherwise,
X # getentry() will check to see if TERMCAP is a file name. If so,
X # getentry() will scan that file for an entry corresponding to
X # "name." If the TERMCAP string does not designate a filename,
X # getentry() will scan /etc/termcap for the correct entry.
X # Whatever the input file, if an entry for terminal "name" is
X # found, getentry() returns that entry. Otherwise, getentry()
X # fails.
X
X local termcap_string, f, getline, line
X
X termcap_string := getenv("TERMCAP")
X
X if termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name)
X then return termcap_string
X else {
X
X if find("/",termcap_string)
X then f := open(termcap_string)
X /f := open("/etc/termcap") |
X er("getentry","I can't access your /etc/termcap file",1)
X
X getline := create read_file(f)
X
X while line := @getline do {
X if line ? (pos(0) | tab(find("|")+1), =name) then {
X entry := ""
X while (\line | @getline) ? {
X if not (entry ||:= 1(tab(find("\\")), pos(-1)))
X then close(f) & (return entry || &subject)
X \line := &null
X }
X }
X }
X }
X
X close(f)
X fail
X
Xend
X
X
X
Xprocedure read_file(fname)
X
X # Suspends all non #-initial lines in the file named "fname."
X # Removes leading tabs and spaces from lines before suspending
X # them.
X
X local intext, line
X
X intext := open(fname) |
X er("read_tcap_file","can't open "||fname,3)
X while line := read(intext) do {
X match("#",line) & next
X suspend line ? (tab(many('\t ')), tab(0))
X }
X
X close(intext)
X fail
X
Xend
X
X
X
Xprocedure maketc_table(entry)
X
X # Maketc_table(s) (where s is a valid termcap entry for some
X # terminal-type): Returns a table in which the keys are termcap
X # capability designators, and the values are the entries in
X # "entry" for those designators.
X
X local k, v
X
X tc_table := table()
X entry ? {
X
X tab(find(":")+1) # tab past initial (name) field
X while tab(find(":")+1) ? {
X
X if k := 1(move(2), ="=")
X then insert(tc_table, k, decode(tab(find(":"))))
X else if k := 1(move(2), ="#")
X then insert(tc_table, k, integer(tab(find(":"))))
X else if k := 1(tab(find(":")), pos(-1))
X then insert(tc_table, k, true())
X else er("maketc_table", "your termcap file has a bad entry",3)
X
X }
X }
X
X return tc_table
X
Xend
X
X
X
Xprocedure getval(id)
X
X /tc_table := maketc_table(getentry(getname())) |
X er("getval","can't make a table for your terminal",4)
X
X return \tc_table[id] | fail
X # er("getval","terminal doesn't support "||id,7)
X
Xend
X
X
X
Xprocedure decode(s)
X
X new_s := ""
X
X s ? {
X while new_s ||:= tab(upto('\\^')) do {
X chr := move(1)
X if chr == "\\" then {
X new_s ||:= {
X case chr2 := move(1) of {
X "\\" : "\\"
X "^" : "^"
X "E" : "\e"
X "b" : "\b"
X "f" : "\f"
X "n" : "\n"
X "r" : "\r"
X "t" : "\t"
X default : {
X if any(&digits,chr)
X then char(integer("8r"||chr2||move(2))) |
X er("decode","bad termcap entry",3)
X else chr2
X }
X }
X }
X }
X else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
X }
X new_s ||:= tab(0)
X }
X
X return new_s
X
Xend
X
X
X
Xprocedure igoto(cm,col,line)
X
X local colline, range, outstr, chr, x, y
X
X if col > (tc_table["co"]) | line > (tc_table["li"]) then {
X colline := string(col) || "," || string(line)
X range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
X er("igoto",colline || " out of range " || range,9)
X }
X
X # use iconish 1 offset, rather than C-ish 0
X find("%i",cm) | (col +:= 1, line +:= 1)
X outstr := ""
X
X cm ? {
X while outstr ||:= tab(find("%")) do {
X tab(match("%"))
X chr := move(1)
X if case chr of {
X "." : outstr ||:= char(line)
X "+" : line +:= ord(move(1))
X "d" : {
X outstr ||:=
X right(string(line), integer(tab(any('23'))), "0") |
X string(line)
X }
X }
X then line :=: col
X else {
X case chr of {
X "n" : line := ixor(line,96) & col := ixor(col,96)
X "i" : &null
X "r" : line :=: col
X "%" : outstr ||:= "%"
X "B" : line := ior(ishift(line / 10, 4), line % 10)
X ">" : {
X x := move(1); y := move(1)
X line > ord(x) & line +:= ord(y)
X &null
X }
X } | er("goto","bad termcap entry",5)
X }
X }
X return outstr || tab(0)
X }
X
Xend
X
X
X
Xprocedure iputs(cp, affcnt)
X
X local baud_rates, char_rates, i, delay, PC
X static num_chars, char_times
X # global tty_speed
X
X initial {
X num_chars := &digits ++ '.'
X char_times := table()
X baud_rates := [0,300,600,1200,1800,2400,4800,9600,19200]
X char_rates := [0,333,166,83,55,41,20,10,5]
X every i := 1 to *baud_rates do {
X char_times[baud_rates[i]] := char_rates[i]
X }
X }
X
X type(cp) == "string" |
X er("iputs","you can't iputs() a non-string value!",10)
X
X cp ? {
X delay := tab(many(num_chars))
X if ="*" then {
X delay *:= \affcnt |
X er("iputs","affected line count missing",6)
X }
X writes(tab(0))
X }
X
X if (\delay, tty_speed ~= 0) then {
X PC := tc_table["pc"] | "\000"
X char_time := char_times[tty_speed] | (return "speed error")
X delay := (delay * char_time) + (char_time / 2)
X every 1 to delay by 10
X do writes(PC)
X }
X
X return
X
Xend
SHAR_EOF
exit 0
From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU Thu Jun 28 13:50:01 1990
Received: from noao.edu by megaron (5.61/15) via SMTP
id AA06092; Thu, 28 Jun 90 13:50:01 -0700
Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G42)
id AA04329; Thu, 28 Jun 90 13:49:52 MST; for icon-group@cs.arizona.edu
Received: by ncar.ucar.EDU (5.64/ NCAR Central Post Office 04/10/90)
id AA04634; Thu, 28 Jun 90 14:49:53 MDT
Received: from tank.uchicago.edu by oddjob.uchicago.edu Thu, 28 Jun 90 14:47:21 -0500
Received: from sophist.uchicago.edu by tank.uchicago.edu Thu, 28 Jun 90 14:49:07 CDT
Return-Path: <goer@zenu.uucp>
Received: by sophist.uchicago.edu (3.2/UofC3.0)
id AA22581; Thu, 28 Jun 90 14:45:09 CDT
Received: by sophist.uchicago.edu (smail2.5)
id AA01422; 28 Jun 90 12:15:23 PDT (Thu)
Subject: BSD -> SysV filename conversion
To: icon-group@arizona.edu
Date: Thu, 28 Jun 90 12:15:22 PDT
X-Mailer: ELM [version 2.2 PL0]
Message-Id: <9006281215.AA01422@sophist.uchicago.edu>
From: goer@sophist.uchicago.edu (Richard Goerwitz)
Status: O
Yes, more code. Isn't this newsgroup fun?
This is a repost of a now much enlarged and expanded tar archive
converter. I frequently find that the main hassle porting BSD things
to SysV comes down to renaming files, and then weeding through the
source to find references to the old, overlong filenames. This soft-
ware essentially automates the process.
Note: This is NOT just a filename re-namer. Yes, it renames files.
It also goes through any text files in the archive, and inserts the
new filenames there as well. Note also: The mapping algorithm is
smart. It will keep one-letter extensions like .c, and will at the
user's option, keep any other extensions as well (e.g. .icn, .tex,
.uu). With most archives, you should be able to just run this pro-
gram, pipe it to a file, unarchive this file, and then forget about
filename-length problems.
No one complained about the shar archive last time, so I'll shar
this one as well. As usual, send me bug reports.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
#!/bin/sh
# This is a shell archive (shar 3.24)
# made 06/28/1990 18:46 UTC by richard@zenu (goer@sophist.uchicago.edu)
#
# existing files WILL be overwritten
# This format requires very little intelligence at unshar time.
# "echo" and "sed" will be needed.
#
# ============= mtf3.icn ==============
echo "x - extracting mtf3.icn (Text)"
sed 's/^X//' << 'SHAR_EOF' > mtf3.icn &&
X#############################################################################
X#
X# NAME: mtf3.icn
X#
X# TITLE: map tar file
X#
X# AUTHOR: Richard Goerwitz
X#
X# DATE: 5/23/90 (version 3.0 - beta)
X#
X#############################################################################
X#
X# Copyright (c) 1990, Richard L. Goerwitz, III
X#
X# This software is intended for free and unrestricted distribution.
X# I place only two conditions on its use: 1) That you clearly mark
X# any additions or changes you make to the source code, and 2) that
X# you do not delete this message therefrom. In order to protect
X# myself from spurious litigation, it must also be stated here that,
X# because this is free software, I, Richard Goerwitz, make no claim
X# about the applicability or fitness of this software for any
X# purpose, and expressly disclaim any responsibility for any damages
X# that might be incurred in conjunction with its use.
X#
X###########################################################################
X#
X# PURPOSE: Maps 15+ char. filenames in a tar archive to 14 chars.
X# Handles both header blocks and the archive itself. Mtf is intended
X# to facilitate installation of tar'd archives on systems subject to
X# the System V 14-character filename limit.
X#
X# USAGE: mtf3 inputfile [-r reportfile] [-e .extensions] [-x exceptions]
X#
X# "Inputfile" is a tar archive. "Reportfile" is file containing a
X# list of files already mapped by mtf in a previous run (used to
X# avoid clashes with filenames in use outside the current archive).
X# The -e switch precedes a list of filename .extensions which mtf is
X# supposed to leave unscathed by the mapping process
X# (single-character extensions such as .c and .o are automatically
X# preserved; -e allows the user to specify additional extensions,
X# such as .pxl, .cpi, and .icn). The final switch, -x, precedes a
X# list of strings which should not be mapped at all. Use this switch
X# if, say, you have a C file with a structure.field combination such
X# as "thisisveryverybig.hashptr" in an archive that contains a file
X# called "thisisveryverybig.h," and you want to avoid mapping that
X# portion of the struct name which matches the name of the overlong
X# file (to wit, "mtf inputfile -x thisisveryverybig.hashptr"). To
X# prevent mapping of any string (including overlong filenames) begin-
X# ning, say, with "thisisvery," use "mtf inputfile -x thisisvery."
X# Be careful with this option, or you might end up defeating the
X# whole point of using mtf in the first place.
X#
X# OUTPUT FORMAT: Mtf writes a mapped tar archive to the stdout.
X# When finished, it leaves a file called "map.report" in the current
X# directory which records what filenames were mapped and how. Rename
X# and save this file, and use it as the "reportfile" argument to any
X# subsequent runs of mtf in this same directory. Even if you don't
X# plan to run mtf again, this file should still be examined, just to
X# be sure that the new filenames are acceptable, and to see if
X# perhaps additional .extensions and/or exceptions should be
X# specified.
X#
X# BUGS: Mtf only maps filenames found in the main tar headers.
X# Because of this, mtf cannot accept nested tar archives. If you try
X# to map a tar archive within a tar file, mtf will abort with a nasty
X# message about screwing up your files. Please note that, unless you
X# give mtf a "reportfile" to consider, it knows nothing about files
X# existing outside the archive. Hence, if an input archive refers to
X# an overlong filename in another archive, mtf naturally will not
X# know to shorten it. Mtf will, in fact, have no way of knowing that
X# it is a filename, and not, say, an identifier in a C program.
X# Final word of caution: Try not to use mtf on binaries. It cannot
X# possibly preserve the correct format and alignment of strings in an
X# executable. Same goes for compressed files. Mtf can't map
X# filenames that it can't read!
X#
X####################################################################
X
X
Xglobal filenametbl, chunkset, short_chunkset # see procedure mappiece(s)
Xglobal extensions, no_nos # ditto
X
Xrecord hblock(name,junk,size,mtime,chksum, # tar header struct;
X linkflag,linkname,therest) # see readtarhdr(s)
X
X
Xprocedure main(a)
X
X usage := "usage: mtf3 inputfile [-r reportfile] " ||
X "[-e .extensions] [-x exceptions]"
X
X *a = 0 & stop(usage)
X
X intext := open_input_file(a[1]) & pop(a)
X
X i := 0
X extensions := []; no_nos := []
X while (i +:= 1) <= *a do {
X case a[i] of {
X "-r" : readin_old_map_report(a[i+:=1])
X "-e" : current_list := extensions
X "-x" : current_list := no_nos
X default : put(current_list,a[i])
X }
X }
X
X every !extensions ?:= (=".", tab(0))
X
X # Run through all the headers in the input file, filling
X # (global) filenametbl with the names of overlong files;
X # make_table_of_filenames fails if there are no such files.
X make_table_of_filenames(intext) | {
X write(&errout,"mtf: no overlong path names to map")
X a[1] ? (tab(find(".tar")+4), pos(0)) |
X write(&errout,"(Is ",a[1]," even a tar archive?)")
X exit(1)
X }
X
X # Now that a table of overlong filenames exists, go back
X # through the text, remapping all occurrences of these names
X # to new, 14-char values; also, reset header checksums, and
X # reformat text into correctly padded 512-byte blocks. Ter-
X # minate output with 512 nulls.
X seek(intext,1)
X every writes(output_mapped_headers_and_texts(intext))
X
X close(intext)
X write_report() # Record mapped file and dir names for future ref.
X exit(0)
X
Xend
X
X
X
Xprocedure open_input_file(s)
X intext := open("" ~== s,"r") |
X stop("mtf: can't open ",s)
X find("UNIX",&features) |
X stop("mtf: I'm not tested on non-Unix systems.")
X s[-2:0] == ".Z" &
X stop("mtf: sorry, can't accept compressed files")
X return intext
Xend
X
X
X
Xprocedure readin_old_map_report(s)
X
X initial {
X filenametbl := table()
X chunkset := set()
X short_chunkset := set()
X }
X
X mapfile := open_input_file(s)
X while line := read(mapfile) do {
X line ? {
X if chunk := tab(many(~' \t')) & tab(upto(~' \t')) &
X lchunk := move(14) & pos(0) then {
X filenametbl[chunk] := lchunk
X insert(chunkset,chunk)
X insert(short_chunkset,chunk[1:16])
X }
X if /chunk | /lchunk
X then stop("mtf: report file, ",s," seems mangled.")
X }
X }
X
Xend
X
X
X
Xprocedure make_table_of_filenames(intext)
X
X local header # chunkset is global
X
X # search headers for overlong filenames; for now
X # ignore everything else
X while header := readtarhdr(reads(intext,512)) do {
X # tab upto the next header block
X tab_nxt_hdr(intext,trim_str(header.size),1)
X # record overlong filenames in several global tables, sets
X fixpath(trim_str(header.name))
X }
X *\chunkset ~= 0 | fail
X return &null
X
Xend
X
X
X
Xprocedure output_mapped_headers_and_texts(intext)
X
X # Remember that filenametbl, chunkset, and short_chunkset
X # (which are used by various procedures below) are global.
X local header, newtext, full_block, block, lastblock
X
X # Read in headers, one at a time.
X while header := readtarhdr(reads(intext,512)) do {
X
X # Replace overlong filenames with shorter ones, according to
X # the conversions specified in the global hash table filenametbl
X # (which were generated by fixpath() on the first pass).
X header.name := left(map_filenams(header.name),100,"\x00")
X header.linkname := left(map_filenams(header.linkname),100,"\x00")
X
X # Use header.size field to determine the size of the subsequent text.
X # Read in the text as one string. Map overlong filenames found in it
X # to shorter names as specified in the global hash table filenamtbl.
X newtext := map_filenams(tab_nxt_hdr(intext,trim_str(header.size)))
X
X # Now, find the length of newtext, and insert it into the size field.
X header.size := right(exbase10(*newtext,8) || " ",12," ")
X
X # Calculate the checksum of the newly retouched header.
X header.chksum := right(exbase10(get_checksum(header),8)||"\x00 ",8," ")
X
X # Finally, join all the header fields into a new block and write it out
X full_block := ""; every full_block ||:= !header
X suspend left(full_block,512,"\x00")
X
X # Now we're ready to write out the text, padding the final block
X # out to an even 512 bytes if necessary; the next header must start
X # right at the beginning of a 512-byte block.
X newtext ? {
X while block := move(512)
X do suspend block
X pos(0) & next
X lastblock := left(tab(0),512,"\x00")
X suspend lastblock
X }
X }
X # Write out a final null-filled block. Some tar programs will write
X # out 1024 nulls at the end. Dunno why.
X return repl("\x00",512)
X
Xend
X
X
X
Xprocedure trim_str(s)
X
X # Knock out spaces, nulls from those crazy tar header
X # block fields (some of which end in a space and a null,
X # some just a space, and some just a null [anyone know
X # why?]).
X return s ? {
X (tab(many(' ')) | &null) &
X trim(tab(find("\x00")|0))
X } \ 1
X
Xend
X
X
X
Xprocedure tab_nxt_hdr(f,size_str,firstpass)
X
X # Tab upto the next header block. Return the bypassed text
X # as a string if not the first pass.
X
X local hs, next_header_offset
X
X hs := integer("8r" || size_str)
X next_header_offset := (hs / 512) * 512
X hs % 512 ~= 0 & next_header_offset +:= 512
X if 0 = next_header_offset then return ""
X else {
X # if this is pass no. 1 don't bother returning a value; we're
X # just collecting long filenames;
X if \firstpass then {
X seek(f,where(f)+next_header_offset)
X return
X }
X else {
X return reads(f,next_header_offset)[1:hs+1] |
X stop("mtf: error reading in ",
X string(next_header_offset)," bytes.")
X }
X }
X
Xend
X
X
X
Xprocedure fixpath(s)
X
X # Fixpath is a misnomer of sorts, since it is used on
X # the first pass only, and merely examines each filename
X # in a path, using the procedure mappiece to record any
X # overlong ones in the global table filenametbl and in
X # the global sets chunkset and short_chunkset; no fixing
X # is actually done here.
X
X s2 := ""
X s ? {
X while piece := tab(find("/")+1)
X do s2 ||:= mappiece(piece)
X s2 ||:= mappiece(tab(0))
X }
X return s2
X
Xend
X
X
X
Xprocedure mappiece(s)
X
X # Check s (the name of a file or dir as recorded in the tar header
X # being examined) to see if it is over 14 chars long. If so,
X # generate a unique 14-char version of the name, and store
X # both values in the global hashtable filenametbl. Also store
X # the original (overlong) file name in chunkset. Store the
X # first fifteen chars of the original file name in short_chunkset.
X # Sorry about all of the tables and sets. It actually makes for
X # a reasonably efficient program. Doing away with both sets,
X # while possible, causes a tenfold drop in execution speed!
X
X # global filenametbl, chunkset, short_chunkset, extensions
X local j, ending
X
X initial {
X /filenametbl := table()
X /chunkset := set()
X /short_chunkset := set()
X }
X
X chunk := trim(s,'/')
X if chunk ? (tab(find(".tar")+4), pos(0)) then {
X write(&errout, "mtf: Sorry, I can't let you do this.\n",
X " You've nested a tar archive within\n",
X " another tar archive, which makes it\n",
X " likely I'll f your filenames ubar.")
X exit(2)
X }
X if *chunk > 14 then {
X i := 0
X
X if /filenametbl[chunk] then {
X # if we have not seen this file, then...
X repeat {
X # ...find a new unique 14-character name for it;
X # preserve important suffixes like ".Z," ".c," etc.
X # First, check to see if the original filename (chunk)
X # ends in an important extension...
X if chunk ?
X (tab(find(".")),
X ending := move(1) || tab(match(!extensions)|any(&ascii)),
X pos(0)
X )
X # ...If so, then leave the extension alone; mess with the
X # middle part of the filename (e.g. file.with.extension.c ->
X # file.with001.c).
X then {
X j := (15 - *ending - 3)
X lchunk:= chunk[1:j] || right(string(i+:=1),3,"0") || ending
X }
X # If no important extension is present, then reformat the
X # end of the file (e.g. too.long.file.name -> too.long.fi01).
X else lchunk := chunk[1:13] || right(string(i+:=1),2,"0")
X
X # If the resulting shorter file name has already been used...
X if lchunk == !filenametbl
X # ...then go back and find another (i.e. increment i & try
X # again; else break from the repeat loop, and...
X then next else break
X }
X # ...record both the old filename (chunk) and its new,
X # mapped name (lchunk) in filenametbl. Also record the
X # mapped names in chunkset and short_chunkset.
X filenametbl[chunk] := lchunk
X insert(chunkset,chunk)
X insert(short_chunkset,chunk[1:16])
X }
X }
X
X # If the filename is overlong, return lchunk (the shortened
X # name), else return the original name (chunk). If the name,
X # as passed to the current function, contained a trailing /
X # (i.e. if s[-1]=="/"), then put the / back. This could be
X # done more elegantly.
X return (\lchunk | chunk) || ((s[-1] == "/") | "")
X
Xend
X
X
X
Xprocedure readtarhdr(s)
X
X # Read the silly tar header into a record. Note that, as was
X # complained about above, some of the fields end in a null, some
X # in a space, and some in a space and a null. The procedure
X # trim_str() may (and in fact often _is_) used to remove this
X # extra garbage.
X
X this_block := hblock()
X s ? {
X this_block.name := move(100) # <- to be looked at later
X this_block.junk := move(8+8+8) # skip the permissions, uid, etc.
X this_block.size := move(12) # <- to be looked at later
X this_block.mtime := move(12)
X this_block.chksum := move(8) # <- to be looked at later
X this_block.linkflag := move(1)
X this_block.linkname := move(100) # <- to be looked at later
X this_block.therest := tab(0)
X }
X integer(this_block.size) | fail # If it's not an integer, we've hit
X # the final (null-filled) block.
X return this_block
X
Xend
X
X
X
Xprocedure map_filenams(s)
X
X # Chunkset is global, and contains all the overlong filenames
X # found in the first pass through the input file; here the aim
X # is to map these filenames to the shortened variants as stored
X # in filenametbl (GLOBAL).
X
X local s2, tmp_chunk_tbl, tmp_lst
X static new_chunklist
X initial {
X
X # Make sure filenames are sorted, longest first. Say we
X # have a file called long_file_name_here.1 and one called
X # long_file_name_here.1a. We want to check for the longer
X # one first. Otherwise the portion of the second file which
X # matches the first file will get remapped.
X tmp_chunk_tbl := table()
X every el := !chunkset
X do insert(tmp_chunk_tbl,el,*el)
X tmp_lst := sort(tmp_chunk_tbl,4)
X new_chunklist := list()
X every put(new_chunklist,tmp_lst[*tmp_lst-1 to 1 by -2])
X
X }
X
X s2 := ""
X s ? {
X until pos(0) do {
X # first narrow the possibilities, using short_chunkset
X if member(short_chunkset,&subject[&pos:&pos+15])
X # then try to map from a long to a shorter 14-char filename
X then {
X if match(ch := !new_chunklist) & not match(!no_nos)
X then s2 ||:= filenametbl[=ch]
X else s2 ||:= move(1)
X }
X else s2 ||:= move(1)
X }
X }
X return s2
X
Xend
X
X
X# From the IPL. Thanks, Ralph -
X# Author: Ralph E. Griswold
X# Date: June 10, 1988
X# exbase10(i,j) convert base-10 integer i to base j
X# The maximum base allowed is 36.
X
Xprocedure exbase10(i,j)
X
X static digits
X local s, d, sign
X initial digits := &digits || &lcase
X if i = 0 then return 0
X if i < 0 then {
X sign := "-"
X i := -i
X }
X else sign := ""
X s := ""
X while i > 0 do {
X d := i % j
X if d > 9 then d := digits[d + 1]
X s := d || s
X i /:= j
X }
X return sign || s
X
Xend
X
X# end IPL material
X
X
Xprocedure get_checksum(r)
X
X # Calculates the new value of the checksum field for the
X # current header block. Note that the specification say
X # that, when calculating this value, the chksum field must
X # be blank-filled.
X
X sum := 0
X r.chksum := " "
X every field := !r
X do every sum +:= ord(!field)
X return sum
X
Xend
X
X
X
Xprocedure write_report()
X
X # This procedure writes out a list of filenames which were
X # remapped (because they exceeded the SysV 14-char limit),
X # and then notifies the user of the existence of this file.
X
X local outtext, stbl, i, j, mapfile_name
X
X # Get a unique name for the map.report (thereby preventing
X # us from overwriting an older one).
X mapfile_name := "map.report"; j := 1
X until not close(open(mapfile_name,"r"))
X do mapfile_name := (mapfile_name[1:11] || string(j+:=1))
X
X (outtext := open(mapfile_name,"w")) |
X open(mapfile_name := "/tmp/map.report","w") |
X stop("mtf: Can't find a place to put map.report!")
X stbl := sort(filenametbl,3)
X every i := 1 to *stbl -1 by 2 do {
X match(!no_nos,stbl[i]) |
X write(outtext,left(stbl[i],35," ")," ",stbl[i+1])
X }
X write(&errout,"\nmtf: ",mapfile_name," contains the list of changes.")
X write(&errout," Please save this list!")
X close(outtext)
X return &null
X
Xend
SHAR_EOF
exit 0
From icon-group-request@arizona.edu Mon Jul 2 10:28:13 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA13884; Mon, 2 Jul 90 10:28:13 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Mon, 2 Jul 90 10:30 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA19095; Mon, 2 Jul 90 10:22:02
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Mon, 2 Jul 90 10:30 MST
Date: 2 Jul 90 12:08:15 GMT
From: fed!arccs2!m1bjk00@uunet.uu.NET
Subject: icont
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <6EF12BAC2A9F404DD5@Arizona.EDU>
Message-Id: <M1BJK00.90Jul2130815@arccs3.fed.frb.gov>
Organization: Federal Reserve Board
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
I am new to icon and new to this newsgroup. I have the following 2 problems
with respect to using icon on a Sun 3/60 for anyone willing to direct or
correct me:
1. Under v7, the following syntax works:
icont fn1 ./mylib/fn2.u1
Under v8, I get:
icont: cannot resolve reference to file 'fn2.u1'
2. Under v7, the following syntax fails:
icont /abc/def/myprog
with:
Can't resolve reference to file '/arc/fame/icon/myprog.u1'
when I am not in the directory /abc/def.
Under v8, the preceding works, but the following fails:
icont /abc/def/myprog /abc/def/mysub.u1
with:
icont: cannot resolve reference to file 'mysub.u1'
From icon-group-request@arizona.edu Tue Jul 3 21:43:31 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA04196; Tue, 3 Jul 90 21:43:31 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Tue, 3 Jul 90 21:45 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA29225; Tue, 3 Jul 90 21:28:07
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 3 Jul 90 21:46 MST
Date: 4 Jul 90 01:46:26 GMT
From: sumax!amc-gw!thebes!happym!irv@beaver.cs.washington.EDU
Subject: need icon project email address
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <6DC9A9B3A63F405E47@Arizona.EDU>
Message-Id: <325@happym.wa.com>
Organization: Happy Man Corp., Seattle
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
Since I've moved, I've apparently lost contact with the Icon people. Does
someone have their email address handy, so I could let them know my new
mailing address and get the newsletter once again?
Thanks!
--
Irving Wolfe irv@happym.wa.com 206/463-9399 ext.101
Happy Man Corp. 4410 SW Pt. Robinson Road, Vashon Island, WA 98070-7399
SOLID VALUE, the investment letter for Benj. Graham's intelligent investors
From ralph Wed Jul 4 05:49:29 1990
Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA16477; Wed, 4 Jul 90 05:49:29 -0700
Date: Wed, 4 Jul 90 05:49:25 MST
From: "Ralph Griswold" <ralph>
Message-Id: <9007041249.AA29693@cheltenham.cs.arizona.edu>
Received: by cheltenham.cs.arizona.edu; Wed, 4 Jul 90 05:49:25 MST
To: icon-group
Subject: Icon context switch for the Sun4
Status: O
An Icon co-expression context switch for the Sun4 folllows. If you use it
and encounter any problems, please let the Icon project know.
This context switch was written by Phil Kaslo of our laboratory staff, with
initial assistance from Dave Bakken.
+++++++++++CUT HERE+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
* rswitch.c for Sun-4 Sparc.
*
* Compile this with 'cc -c rswitch.c'. Do not use cc -O.
*/
#include <sun4/asm_linkage.h>
#include <sun4/trap.h>
int coswitch(old_cs, new_cs, first)
int *old_cs, *new_cs;
int first;
{
asm("ta 0x03"); /* ST_FLUSH_WINDOWS in trap.h */
asm("ld [%fp+0x44], %o0"); /* load old_cs into %o0 */
asm("st %sp,[%o0]"); /* Save user stack pointer */
asm("st %fp,[%o0+0x4]"); /* Save frame pointer */
asm("st %i7,[%o0+0x8]"); /* Save return address */
if (first == 0) { /* this is the first activation */
asm("ld [%fp+0x48], %o0"); /* load new_cs into %o0 */
asm("ld [%o0], %o1"); /* load %o1 from cstate[0] */
/* Decrement new stack pointer value before loading it into sp. */
/* The top 64 bytes of the stack are reserved for the kernel, to */
/* save the 8 local and 8 in registers into, on context switches, */
/* interrupts, traps, etc. */
asm("dec 96,%o1");
asm("mov %o1, %sp"); /* load %sp from %o1 */
interp(0,0);
syserr("interp() returned in coswitch");
} else {
asm("ld [%fp+0x48], %o0"); /* load new_cs into %o0 */
asm("ld [%o0+0x4],%fp"); /* Load frame pointer */
asm("ld [%o0+0x8],%i7"); /* Load return address */
asm("ld [%o0],%sp"); /* Load user stack pointer */
}
}
+++++++++++CUT HERE+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From ralph Wed Jul 4 05:54:23 1990
Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA16608; Wed, 4 Jul 90 05:54:23 -0700
Date: Wed, 4 Jul 90 05:54:20 MST
From: "Ralph Griswold" <ralph>
Message-Id: <9007041254.AA29743@cheltenham.cs.arizona.edu>
Received: by cheltenham.cs.arizona.edu; Wed, 4 Jul 90 05:54:20 MST
To: icon-group
Subject: Icon program available
Status: O
Alan Corre has provided us with an Icon program and some ancillary materials
for a visually equivalent Jewish/Civil calendar. The file is rather large
(about 29K bytes), so we're offering to send copies to individuals rather
than posting it to the entire group.
If you'd like a copy, send your request to me (not icon-group or icon-project).
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From kwalker Wed Jul 4 14:09:27 1990
Date: Wed, 4 Jul 90 14:09:27 -0700
From: "Kenneth Walker" <kwalker>
Message-Id: <9007042109.AA03875@megaron.cs.arizona.edu>
Received: by megaron.cs.arizona.edu (5.61/15)
id AA03875; Wed, 4 Jul 90 14:09:27 -0700
To: fed!arccs2!m1bjk00@uunet.uu.NET, icon-group
Subject: Re: icont
Status: O
> Date: 2 Jul 90 12:08:15 GMT
> From: fed!arccs2!m1bjk00@uunet.uu.NET
> 1. Under v7, the following syntax works:
> icont fn1 ./mylib/fn2.u1
> Under v8, I get:
> icont: cannot resolve reference to file 'fn2.u1'
This is a known bug in V8. The work around is to include the "mylib"
directory in the search path specified with the IPATH environment
variable.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From esquire!info8!yost@cmcl2.NYU.EDU Thu Jul 5 09:28:18 1990
Received: from cmcl2.NYU.EDU (NYU.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA00410; Thu, 5 Jul 90 09:28:18 -0700
Received: by cmcl2.NYU.EDU (5.61/1.34)
id AA26327; Thu, 5 Jul 90 10:15:58 -0400
Received: from info8 by ESQUIRE.DPW. id aa01992; 5 Jul 90 10:01 EDT
Received: from localhost by info8. (4.0/SMI-4.0)
id AA24281; Thu, 5 Jul 90 10:02:36 EDT
Message-Id: <9007051402.AA24281@info8.>
From: yost@DPW.COM (Dave Yost)
Reply-To: yost@DPW.COM (Dave Yost)
To: "Ralph Griswold" <ralph@cs.arizona.edu>
Cc: icon-group@cs.arizona.edu, yost@cmcl2.NYU.EDU
Subject: Re: Icon context switch for the Sun4
In-Reply-To: Your message of Wed, 04 Jul 90 05:49:25 MST.
<9007041249.AA29693@cheltenham.cs.arizona.edu>
Phone: +1 212-266-0796 (Voice Direct Line)
Fax: +1 212-266-0790
Organization: Davis Polk & Wardwell
1 Chase Manhattan Plaza
New York, NY 10005
Date: Thu, 05 Jul 90 10:02:33 -0400
Sender: yost@info8.NYU.EDU
Status: O
> An Icon co-expression context switch for the Sun4 folllows. If you use it
> and encounter any problems, please let the Icon project know.
You forgot to mention why we might want this.
Is the standard v8 rswitch.c buggy? Too slow?
--dave yost
yost@dpw.com or uunet!esquire!yost
Please ignore the From or Reply-To fields above, if different.
From icon-group-request@arizona.edu Thu Jul 5 15:01:10 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA19371; Thu, 5 Jul 90 15:01:10 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 5 Jul 90 15:03 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA11996; Thu, 5 Jul 90 14:58:48
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 5 Jul 90 15:03 MST
Date: 5 Jul 90 20:41:35 GMT
From: bunny!nic!hri!sparc9!rolandi@husc6.harvard.EDU
Subject: passing variable patterns to egrep
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <6C6F85623B3F4065C9@Arizona.EDU>
Message-Id: <1990Jul5.204135.13202@hri.com>
Organization: Horizon Research
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
can anyone suggest a way to pass variable patterns to egrep via a
quoted argument as in
system("egrep 'ABC[d.]'")
i would like to be able to assemble the 'ABC[d.]' type parts on the
fly and then push them out to the system.
any ideas?
***************************************
* Walter G. Rolandi *
* Horizon Research, Inc. *
* 1432 Main Street *
* Waltham, MA 02154 USA *
* (617) 466 8339 *
* *
* rolandi@hri.com *
***************************************
From goer@sophist.uchicago.EDU Thu Jul 5 22:11:12 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA07107; Thu, 5 Jul 90 22:11:12 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from xtank.uchicago.edu by Arizona.EDU; Thu, 5 Jul 90 22:13 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Fri, 6 Jul 90
00:12:42 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA04804; Fri, 6 Jul 90
00:08:34 CDT
Resent-Date: Thu, 5 Jul 90 22:13 MST
Date: Fri, 6 Jul 90 00:08:34 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: egrep & variable patterns
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <6C337544D4BF4063A1@Arizona.EDU>
Message-Id: <9007060508.AA04804@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
> Can anyone suggest a way to pass variable patterns to egrep via a
> quoted argument as in,
>
> system("egrep 'ABC[d.]'")
>
> I would like to be able to assemble the 'ABC[d.]' type parts on the
> fly and then push them out to the system.
>
> Any ideas?
Sure. I got a lot of ideas. You judge for yourself which (if any) are
going to work out.
First of all, you could try something cute like:
while ans := read(&input) do {
system("/bin/egrep "||ans||" filename")
}
I don't see what good this will do, because egrep will write to the
standard output and standard error output, and will not pipe to iconx.
You might as well write a shell script that does the same thing.
I might add that, unless you are writing a utility geared specifically
for the Unix environment, you'd best avoid such heavily OS-dependent
things as /bin/egrep (I gather the system function itself is not ter-
ribly portable, too).
Finally, you'll find that repeated calls to system() are expensive. They
take a lot of time.
So much for my first suggestion.
A second suggestion might be to do something with
open("/bin/egrep "||ans||" filename","pr")
You could then use egrep's output within Icon.
The problems here are again OS dependency and slowness. Many implemen-
tations don't give you the "p" option with open(). And even if you can
do it, you'll pay the price of having to open and close pipes repeatedly.
A third suggestion might be to complain to the Icon Project that an in-
ternal grep-like command is needed, and try to convince them to create
one (after all, most C libraries have regex functions).
My objection to this is that it would be very un-Iconish. Icon's pat-
tern-matching facilities are far more powerful than the facilities of-
fered by egrep, and of a wholly different kind. You can easily construct
scanning expressions that will do anything egrep's regular expressions
will do. I don't think anyone at the Icon project will be interested
in adding an igrep(), or whatever, function.
This leads to yet another solution to your problem: Why not just use
Icon's intrinsic pattern-matching facilities? Your
egrep 'ABC[de]' filename
above can just as easily be expressed in Icon. The following is very
inelegant, but suffices to show what can be done:
every write(!open("filename") ? (tab(find("ABC")+3), any('de'), &subject))
You can, of course, use the results by assigning them to an intermediate
variable. And you can vary the search pattern yourself simply by changing
the expression used after the question mark above. You can vary the file
("filename" -> "filename1"|"filename2"|"filename3"), and anything else
you like. Easy as pie, once you "get it."
The only problem likely to crop up in this connection has to do with con-
structing automata to match patterns at run-time. You'll likely have some
trouble getting Icon to do this.
Lucky for you some nutcase posted a program called find_re, which is inten-
ded just for this very thing. It works a bit like find() and a bit like
egrep, though it's not as fast as the C egrep program. It's fast enough
for most purposes, though. And since it's written in Icon, you don't have
to worry about piping, system(), and what not. If you want find_re(),
please send a note to the following address:
Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
This person appreciates it very much when people test his software, and
send back bug reports.
From alfred@alpha.uni-paderborn.de Fri Jul 6 07:56:52 1990
Received: from unido.informatik.uni-dortmund.de by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA22421; Fri, 6 Jul 90 07:56:52 -0700
Received: from pbinfo-n.uni-paderborn.de
by unido.informatik.uni-dortmund.de with SMTP via EUnet (UNIDO-2.0.1.q) via EUnet
for cs.arizona.edu
id AQ16967; Fri, 6 Jul 90 16:55:00 +0100
Received: by pbinfo-n.uni-paderborn.de; Fri, 6 Jul 90 11:34:15 +0200 PBINFO2.1
Received: by pbinfo.uni-paderborn.de; Fri, 6 Jul 90 11:48:23 +0200 PBINFO2.1
From: Alfred Schmidt <alfred@alpha.uni-paderborn.de>
Date: Wed, 4 Jul 90 08:34:11 MEZ
Message-Id: <9007040934.AA00311@alpha.uni-paderborn.de>
Received: by alpha.uni-paderborn.de; Wed, 4 Jul 90 08:34:11 MEZ
To: icon-group@cs.arizona.edu
Status: O
Dear Sirs:
I would like to order
1x (code DE) MS-DOS executables ICON V8 (5 1/4") $25
1x (code NL) Newsletter back issues complete (1-33) $20
1x (code LB) Icon book, 2nd edition $43
--------------------------------------------------------
total $88
=========
Name and address (this is a new address!):
Alfred Schmidt
Linnebornweg 3
D-4790 Paderborn
WEST GERMANY
phone: (+49) 5251 603158
(+49) 5251 55295
Payment: MasterCard
I hereby authorize the billing of the above order
to my credit card:
card number: 5232 5411 1001 2038
exp. date: 08/91
name on card: Alfred Schmidt
I would appreciate very much if you could confirm the receipt of
this message.
Yours Sincerely,
Alfred Schmidt
From ralph Fri Jul 6 09:15:08 1990
Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA25966; Fri, 6 Jul 90 09:15:08 -0700
Date: Fri, 6 Jul 90 09:14:54 MST
From: "Ralph Griswold" <ralph>
Message-Id: <9007061614.AA22701@cheltenham.cs.arizona.edu>
Received: by cheltenham.cs.arizona.edu; Fri, 6 Jul 90 09:14:54 MST
To: icon-group
Subject: Icon orders
Status: O
Orders for Icon material should be sent to icon-project@cs.arizona.edu,
*not* to icon-group@cs.arizona.edu. Electronic mail to the icon-project goes
only to persons affiliated with the Icon Project at the University
of Arizona, while mail to icon-group goes to hundreds of persons all
over the world.
In particular, you should not post credit card information to icon-group.
For confidential material, send it directly to a person. If in doubt,
send credit-card orders directly to me: ralph@cs.arizona.edu.
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From icon-group-request@arizona.edu Sun Jul 8 09:35:55 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA27371; Sun, 8 Jul 90 09:35:55 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Sun, 8 Jul 90 09:38 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA16743; Sun, 8 Jul 90 09:20:21
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Sun, 8 Jul 90 09:38 MST
Date: 6 Jul 90 00:04:23 GMT
From: att!mcdchg!ddsw1!corpane!disk!stevenw@ucbvax.Berkeley.EDU
Subject: RE: need icon project email address
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <6A4177C2DA5F4008CA@Arizona.EDU>
Message-Id: <3314@disk.UUCP>
Organization: Digital Information Systems of Ky (DISK), Louisville, Ky
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
References: <325@happym.wa.com>
Status: O
Re: ICON address.
Their BBS number is (602) 621-2283 (Arizona).
I also have the following address for FTP: cs.arizona.edu (cd /icon)
Hope this helps
--
: Phone: (502) 425 9560 << Steven Weller >> Fax: (502) 426 3944 :
: Windsor Systems, 2407 Lime Kiln Lane, Louisville, KY, 40222 USA :
: "A substance almost, but not quite, entirely unlike tea" :
: stevenw@disk.UUCP or uunet!ukma!corpane!disk!stevenw :
From ralph Wed Jul 11 09:06:34 1990
Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA06153; Wed, 11 Jul 90 09:06:34 -0700
Date: Wed, 11 Jul 90 09:06:30 MST
From: "Ralph Griswold" <ralph>
Message-Id: <9007111606.AA21919@cheltenham.cs.arizona.edu>
Received: by cheltenham.cs.arizona.edu; Wed, 11 Jul 90 09:06:30 MST
To: icon-group
Subject: electronic mail
Status: O
Someone has raised the question of security of electronic mail and
"confidentiality".
I assume everyone knows that electronic mail is anything but secure.
In using it for transmitting sensitive information, you're taking a
risk.
My point about e-mail regarding Icon is simply that the fewer persons
to which you transmit sensitive information, the less the risk is.
There is no way to eliminate risk completely, but you can minimize
it by being careful.
The Icon Project does not encourage orders of Icon material by
electronic mail. However, many persons find convenience outweighs
risk. It comes down to an individual decision.
Another issue is the potential confusion between the e-mail addresses
icon-project and icon-group. We use icon-group for the electronic news
function because that's the de facto naming standard on the network.
The address icon-project predated icon-group and it's been disseminated
so widely that we couldn't change it now without creating more problems
than we could hope to solve.
Do give some thought before addressing e-mail about Icon. Use icon-project
for queries about Icon availability, trouble reports, and in general
for things that are not of significant interest to the Icon community. Use
icon-group for things you think may have wide interest. Realize that
e-mail to icon-group is redistributed to hundreds (possibly thousands)
of individuals.
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From goer@sophist.uchicago.EDU Mon Jul 16 10:11:57 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA10081; Mon, 16 Jul 90 10:11:57 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from xtank.uchicago.edu by Arizona.EDU; Mon, 16 Jul 90 10:14 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Mon, 16 Jul 90
12:12:24 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA21287; Mon, 16 Jul 90
12:07:54 CDT
Resent-Date: Mon, 16 Jul 90 10:14 MST
Date: Mon, 16 Jul 90 12:07:54 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: Unix port of Alan Corre's prgm.
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <63F31AEF0E1F40424C@Arizona.EDU>
Message-Id: <9007161707.AA21287@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I just did a Unix port of Alan Corre's MS-DOS Jewish/Civil calendar
program. I'm still in the process of working out the bugs. Would
anyone like to volunteer to test it? I've tried it out under Xenix,
BSD 4.2, and some others. Need further input. NB: No support yet
for magic cookie terminals.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From goer@sophist.uchicago.EDU Tue Jul 17 09:24:22 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA14911; Tue, 17 Jul 90 09:24:22 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from xtank.uchicago.edu by Arizona.EDU; Tue, 17 Jul 90 09:26 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Tue, 17 Jul 90
11:24:36 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA23326; Tue, 17 Jul 90
11:20:05 CDT
Resent-Date: Tue, 17 Jul 90 09:27 MST
Date: Tue, 17 Jul 90 11:20:05 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: resend requests
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <6330949CB19F405636@Arizona.EDU>
Message-Id: <9007171620.AA23326@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I clobbered several requests I had queued for find_re and for the test
version of the port of Alan Corre's program. Could those who sent them
perhaps resend these requests. I feel terrible. Sorry.
-Richard
From icon-group-request@arizona.edu Thu Jul 19 09:09:51 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA13990; Thu, 19 Jul 90 09:09:51 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 19 Jul 90 09:12 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA00445; Thu, 19 Jul 90
08:53:01 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 19 Jul 90 09:12 MST
Date: 18 Jul 90 13:38:23 GMT
From: amdahl!ntmtv!hildum@sun.COM
Subject: Enhanced colmize procedure
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <61A0405B267F405BCD@Arizona.EDU>
Message-Id: <1414@ntmtv.UUCP>
Organization: Northern Telecom (Mountain View, CA)
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I have made a modification to colmize to allow a tag field to be added
to the data. The tag will count against the maxcols in determining the
arrangement of data. The resulting output will appear as follows:
tag data1 data3 data5 data7 data9 data11 data13 data15 data17
data2 data4 data6 data8 data10 data12 data14 data16 data18
---------------- Cut here------------------------------------------
############################################################################
#
# Name: colmize.icn
#
# Title: Arrange data into columns
#
# Author: Robert J. Alexander
#
# Date: December 5, 1989
#
#
# Modification History
#
# 15-Jun-1990 Eric Hildum Added tag field.
############################################################################
#
# colmize() -- Arrange data into columns.
#
# Procedure to arrange a number of data items into multiple columns.
# Items are arranged in column-wise order, that is, the sequence runs
# down the first column, then down the second, etc.
#
# This procedure goes to great lengths to print the items in as few
# vertical lines as possible.
#
############################################################################
procedure colmize(entries,maxcols,space,minwidth,tag,tagspace,tagminwidth,rowwise,distribute)
local mean,cols,lines,width,i,x,wid,extra,t,j,first_tagfield,tagfield
#
# Process arguments -- provide defaults.
#
# entries: a list of items to be columnized
/maxcols := 80 # max width of output lines
/space := 2 # min nbr of spaces between columns
/minwidth := 0 # min column width
# tag: a label to be placed on the first line of output
/tagminwidth := 0
/tagspace := 2
# rowwise: if nonnull, entries are listed in rowwise order rather than
# columnwise
#
#
# Process the tag field information. The tag will appear on the
# first line to the left of the data.
#
if \tag then {
tagminwidth <:= *tag + tagspace
maxcols -:= tagminwidth
first_tagfield := left(tag, tagminwidth - tagspace) || repl(" ",tagspace)
tagfield := repl(" ",tagminwidth)
} else
tagfield := first_tagfield := ""
# Starting with a trial number-of-columns that is guaranteed
# to be too wide, successively reduce the number until the
# items can be packed into the allotted width.
#
mean := 0
every mean +:= *!entries
mean := mean / (0 ~= *entries) | 1
every cols := (maxcols + space) * 2 / (mean + space) to 1 by -1 do {
lines := (*entries + cols - 1) / cols
width := list(cols,minwidth)
i := 0
if /rowwise then { # if column-wise
every x := !entries do {
width[i / lines + 1] <:= *x + space
i +:= 1
}
}
else { # else row-wise
every x := !entries do {
width[i % cols + 1] <:= *x + space
i +:= 1
}
}
wid := 0
every x := !width do wid +:= x
if wid <= maxcols + space then break
}
#
# Now output the data in columns.
#
extra := (\distribute & (maxcols - wid) / (0 < cols - 1)) | 0
if /rowwise then { # if column-wise
every i := 1 to lines do {
if i = 1 then
t := first_tagfield
else
t := tagfield
every j := 0 to cols - 1 do
t ||:= left(entries[i + j * lines],width[j + 1] + extra)
suspend trim(t)
}
}
else { # else row-wise
every i := 0 to lines - 1 do {
if i = 0 then
t := first_tagfield
else
t := tagfield
every j := 1 to cols do
t ||:= left(entries[j + i * cols],width[j] + extra)
suspend trim(t)
}
}
end
From icon-group-request@arizona.edu Thu Jul 19 20:09:24 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA15325; Thu, 19 Jul 90 20:09:24 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Thu, 19 Jul 90 20:12 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA13549; Thu, 19 Jul 90
20:07:53 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 19 Jul 90 20:12 MST
Date: 19 Jul 90 12:49:43 GMT
From: decvax.dec.com!elrond!shodsdon@mcnc.ORG
Subject: Wanted: latest ICON
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <61441E22F21F405F52@Arizona.EDU>
Message-Id: <2838@elrond.CalComp.COM>
Organization: Calcomp Display Products Division, Hudson, NH, USA
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
I'm looking for the latest sources for icon. The only version that I have
worked with is ver 6 on the mac (MPW).
Tks.
--
Steve Hodsdon | Keep sane inside insanity.
shodsdon@elrond.CalComp.COM | Don't dream it, be it.
{decvax|harvard}!elrond!shodsdon |
(603) 885-8324 |
From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Sat Jul 21 01:03:37 1990
Received: from umich.edu by megaron (5.61/15) via SMTP
id AA16704; Sat, 21 Jul 90 01:03:37 -0700
Received: from ummts.cc.umich.edu by umich.edu (5.61/1123-1.0)
id AA27857; Sat, 21 Jul 90 04:03:32 -0400
Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 21 Jul 90 04:03:23 EDT
Date: Fri, 20 Jul 90 23:07:30 EDT
From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
To: icon-group@cs.arizona.edu
Message-Id: <239208@Wayne-MTS>
Subject: Semantics of break break
Status: O
You can break out of two loops at once by using "break break", which
can even return a value. For instance, the program:
procedure main()
write(
every i := 10 to 30 by 10 do every j := 1 to 4 do
{write(i+j); if i+j=23 then break break "outer"}
)
end
prints 11 12 13 14 21 22 23 outer (on several lines).
However, a reading of the new (or old) Icon book does not make it at all clear
why this should work. On p. 285 it states that break x produces the outcome
of x, and on p. it states that outcomes include results (values and variables)
as well as failure. But if x is "break 2", this is neither a result nor
failure.
I think I understand what break does, but I don't understand how I'm supposed
to think about it.
Paul Abrahams
From sbw@turing Sat Jul 21 06:49:06 1990
Received: from turing (turing.cse.nau.edu) by megaron (5.61/15) via SMTP
id AA00102; Sat, 21 Jul 90 06:49:06 -0700
Received: by turing (5.57/1.34)
id AA02352; Sat, 21 Jul 90 06:48:02 MST
Message-Id: <9007211348.AA02352@turing>
From: sbw@turing (Steve Wampler)
Date: Sat, 21 Jul 1990 06:48:01 MST
In-Reply-To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu's mail message of Jul 21, 1:04.
X-Mailer: Mail User's Shell (7.1.1 5/02/90)
To: icon-group@cs.arizona.edu
Subject: Re: Semantics of break break
Status: O
I think the easiest way to think about 'break expr' is that it is
a control structure where first the break is performed and then the
expression is evaluated. This has the effect that the expression
is evaluated in the context surrounding the loop, not within the loop.
--
Steve Wampler
{....!arizona!naucse!sbw}
{sbw@naucse.cse.nau.edu}
From kwalker Sat Jul 21 19:32:05 1990
Date: Sat, 21 Jul 90 19:32:05 -0700
From: "Kenneth Walker" <kwalker>
Message-Id: <9007220232.AA24868@megaron.cs.arizona.edu>
Received: by megaron.cs.arizona.edu (5.61/15)
id AA24868; Sat, 21 Jul 90 19:32:05 -0700
To: icon-group
Subject: Re: Semantics of break break
Status: O
> Date: Fri, 20 Jul 90 23:07:30 EDT
> From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
>
> I think I understand what break does, but I don't understand how I'm supposed
> to think about it.
I was told that break is designed to act as if the loop were replaced
by the expression. That is, that it is supposed to act like textual
substitution. This applies to the value produced, goal-directed evaluation,
other breaks, etc. I find this view very helpful.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Sun Jul 22 13:08:01 1990
Received: from umich.edu by megaron (5.61/15) via SMTP
id AA00454; Sun, 22 Jul 90 13:08:01 -0700
Received: from ummts.cc.umich.edu by umich.edu (5.61/1123-1.0)
id AA01175; Sun, 22 Jul 90 16:07:57 -0400
Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sun, 22 Jul 90 16:07:39 EDT
Date: Sun, 22 Jul 90 12:05:30 EDT
From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
To: icon-group@cs.arizona.edu
Message-Id: <239317@Wayne-MTS>
Subject: Semantics of break break
Status: O
The interesting thing about
break (break 2)
is that the argument of the first break is returned *unevaluated* as the
result of the inner loop. Are there any other places in Icon where
unevaluated expressions are returned? I can't think of any.
Paul Abrahams
From sbw@turing Sun Jul 22 13:44:33 1990
Received: from turing (turing.cse.nau.edu) by megaron (5.61/15) via SMTP
id AA01450; Sun, 22 Jul 90 13:44:33 -0700
Received: by turing (5.57/1.34)
id AA03438; Sun, 22 Jul 90 13:43:22 MST
Message-Id: <9007222043.AA03438@turing>
From: sbw@turing (Steve Wampler)
Date: Sun, 22 Jul 1990 13:43:22 MST
In-Reply-To: Mail Delivery Subsystem's mail message of Jul 22, 13:40.
X-Mailer: Mail User's Shell (7.1.1 5/02/90)
To: icon-group@cs.arizona.edu
Subject: Re: Returned mail: Host unknown
Status: O
Subject: Re: Semantics of break break
Hmmm, maybe it isn't proper to think of break as having an argument.
That is, one normally doesn't consider the 'then' or 'else' clause
of an 'if-then-else' as being an argument, per se.
Break is a control structure that evaluates an expression (its
'argument') after performing the loop break. Is that all that
different than an if returning the outcome of its else clause?
In both cases the control flow has occurred before evaluation.
--
Steve Wampler
{....!arizona!naucse!sbw}
{sbw@naucse.cse.nau.edu}
From goer@sophist.uchicago.EDU Sun Jul 22 15:14:28 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA04336; Sun, 22 Jul 90 15:14:28 -0700
Return-Path: goer@sophist.uchicago.EDU
Received: from xtank.uchicago.edu by Arizona.EDU; Sun, 22 Jul 90 15:15 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Sun, 22 Jul 90
17:13:52 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA00920; Sun, 22 Jul 90
17:09:21 CDT
Resent-Date: Sun, 22 Jul 90 15:16 MST
Date: Sun, 22 Jul 90 17:09:21 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: break, goto
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <5F11E3F3A05F40730F@Arizona.EDU>
Message-Id: <9007222209.AA00920@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
Having break act as a control structure has helped me avoid a helluva
lot of kludgy constructions (which in C would normally be uncluttered
with a goto). E.g. I occasionally have reason to write
every i := 1 to 2 do {
every j := 1 to 10 do {
i+j = 5 & {break next}
}
}
Naturally, there are ways to code this without using the break. It's
a nice bit of sugar, though, isn't it?
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From goer@sophist.uchicago.EDU Mon Jul 23 12:27:13 1990
Resent-From: goer@sophist.uchicago.EDU
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA19723; Mon, 23 Jul 90 12:27:13 -0700
Return-Path: goer@Arizona.edu
Received: from xtank.uchicago.edu by Arizona.EDU; Mon, 23 Jul 90 12:29 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Mon, 23 Jul 90
14:27:43 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA01435; Mon, 23 Jul 90
01:49:18 CDT
Resent-Date: Mon, 23 Jul 90 12:30 MST
Date: Mon, 23 Jul 90 01:49:18 CDT
From: Richard Goerwitz <goer@sophist.uchicago.EDU>
Subject: Icon yacc
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <5E60031C989FA00B4F@Arizona.EDU>
Message-Id: <9007230649.AA01435@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Status: O
Has anyone at any point felt a desire to create an Icon yacc
program? I'm just curious. Such a utility could be very
useful. Maybe yacc is the wrong term. Yaicc? Yuck.
Anyway, the question is a serious one.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From oddjob!sophist.uchicago.edu.goer!zenu!@ncar.UCAR.EDU Mon Jul 23 12:47:42 1990
Received: from noao.edu by megaron (5.61/15) via SMTP
id AA20372; Mon, 23 Jul 90 12:47:42 -0700
Received: from ncar.UCAR.EDU (handies.ucar.edu) by noao.edu (4.1/SAG-Gemini.G43)
id AA08435; Mon, 23 Jul 90 12:47:38 MST; for icon-group@cs.arizona.edu
Received: by ncar.ucar.EDU (5.64/ NCAR Central Post Office 04/10/90)
id AA11120; Mon, 23 Jul 90 13:47:38 MDT
Received: from xtank.uchicago.edu by oddjob.uchicago.edu Mon, 23 Jul 90 14:25:27 -0500
Received: from sophist.uchicago.edu by xtank.uchicago.edu Mon, 23 Jul 90 14:26:59 CDT
Return-Path: <goer@zenu.uucp>
Received: by sophist.uchicago.edu (3.2/UofC3.0)
id AA01963; Mon, 23 Jul 90 12:46:20 CDT
Received: by sophist.uchicago.edu (smail2.5)
id AA00244; 23 Jul 90 10:26:18 PDT (Mon)
Subject: scanning lists & not just strings
To: icon-group@arizona.edu
Date: Mon, 23 Jul 90 10:26:18 PDT
X-Mailer: ELM [version 2.2 PL0]
Message-Id: <9007231026.AA00244@sophist.uchicago.edu>
From: goer@sophist.uchicago.edu (Richard Goerwitz)
Status: O
A few months ago, some kind soul send me some examples of generalized
scanning routines for data types other than strings. I remember look-
ing them over, thinking that they looked interesting, and then delet-
ing them because I felt I wouldn't use them.
Hmmm.
Almost as soon as I threw the sample code away, I became embroiled in
several projects that required me to tokenize strings, and then essen-
tially "scan" lists. At first I did this in an ad hoc fashion. After
a few weeks of this, however, I realized that a set of generalized list
scanning routines would be better.
Anyway, I've written a set of routines, l_tab, l_move, l_match, l_pos,
etc., which transpose string-like scanning functions to lists. They
correctly handle nesting of list scanning, and what not. I seem to
recall some discussion of how scanning might be generalized to lists
a few months back. If anyone is still interested, I'd be happy to
send them my library of l_ functions.
--
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From icon-group-request@arizona.edu Mon Jul 23 18:57:46 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.EDU (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA09302; Mon, 23 Jul 90 18:57:46 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.EDU; Mon, 23 Jul 90 19:00 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.41) id AA26427; Mon, 23 Jul 90
18:42:19 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Mon, 23 Jul 90 19:00 MST
Date: 24 Jul 90 01:07:55 GMT
From: cca.ucsf.edu!root@cgl.ucsf.EDU
Subject: RE: Wanted: latest ICON
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <5E2973D7903FA00BA3@Arizona.EDU>
Message-Id: <3036@ucsfcca.ucsf.edu>
Organization: Computer Center, UCSF
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
References: <2838@elrond.CalComp.COM>
Status: O
In article <2838@elrond.CalComp.COM>, shodsdon@elrond.CalComp.COM (Steve V. Hodsdon) writes:
> I'm looking for the latest sources for icon. The only version that I have
> worked with is ver 6 on the mac (MPW).
Version 8 is now available from cs.arizona.edu [128.196.128.118]
by anonymous FTP.
Thos Sumner Internet: thos@cca.ucsf.edu
(The I.G.) UUCP: ...ucbvax!ucsfcgl!cca.ucsf!thos
BITNET: thos@ucsfcca
U.S. Mail: Thos Sumner, Computer Center, Rm U-76, UCSF
San Francisco, CA 94143-0704 USA
I hear nothing in life is certain but death and taxes -- and they're
working on death.
#include <disclaimer.std>
From goer@sophist.uchicago.edu Tue Jul 24 11:29:30 1990
Resent-From: goer@sophist.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA20121; Tue, 24 Jul 90 11:29:30 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from xtank.uchicago.edu by Arizona.edu; Tue, 24 Jul 90 11:31 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Tue, 24 Jul 90
13:29:46 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA03438; Tue, 24 Jul 90
13:25:14 CDT
Resent-Date: Tue, 24 Jul 90 11:32 MST
Date: Tue, 24 Jul 90 13:25:14 CDT
From: Richard Goerwitz <goer@sophist.uchicago.edu>
Subject: list scanning; here it is
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <5D9EEE753E9FA0182F@Arizona.edu>
Message-Id: <9007241825.AA03438@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
I've been swamped with requests for my list scanning routines.
This was quite unexpected. I sometimes post programs that I
think will be of great general interest, only to get two or
three responses. This last time, I didn't post code because
I couldn't imagine more than two or three people wanting list
scanning routines. The opposite seems to have been the case.
With a somewhat red face, I'm going to do an about-face, and
post the list scanning code.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
############################################################################
#
# Name: lscan.icn
#
# Title: Quasi ? scanning routines for lists.
#
# Author: Richard L. Goerwitz
#
# Date: 7/24/90 (version 1.10)
#
############################################################################
#
# Copyright (c) 1990, Richard L. Goerwitz, III
#
# This software is intended for free and unrestricted distribution.
# I place only two conditions on its use: 1) That you clearly mark
# any additions or changes you make to the source code, and 2) that
# you do not delete this message from it. In order to protect
# myself from spurious litigation, it must also be stated here that,
# because this is free software, I, Richard Goerwitz, make no claim
# about the applicability or fitness of this software for any
# purpose, and disclaim any responsibility for any damages that
# might be incurred in conjunction with its use.
#
############################################################################
#
# PURPOSE: String scanning is terriffic, but often I am forced to
# tokenize and work with lists. So as to make operations on these
# lists as close to corresponding string operations as possible, I've
# implemented a series of list analogues to any(), find(), many(),
# match(), move(), pos(), tab(), and upto(). Their names are just
# like corresponding string functions, except with a prepended "l_"
# (e.g. l_any()). Since Icon does not permit me to define new
# control structures via infix operators, list scanning must be
# initialized via a procedure, namely l_scan(l), where l is the list
# to be scanned. Scanning is ended by calling end_l_scan(l).
# Nesting is permitted, but you'd better make sure your indentation
# is correct. Since l_scan() does not represent a real control
# structure, you must call end_l_scan() before "breaking" from an
# l_scan. Otherwise l_POS and l_SUBJ will not be handled properly.
#
# If someone can think of a way to do this more elegantly let me
# know. Personally, I'd like p{a,b,c} to be extended to allow
# p{a;b;c} (where ; = ; or a newline). I could then do something
# like
#
# l_scan {
# a
# b
# c
# }
#
# Now that's a user-defined control structure. (How, though, would
# we work variable args into this scheme?)
#
# I envision l_scan being used (and in fact use it myself) to parse
# trees and compare complicated list structures. One big time-saver
# in parsing natural languages, for instance, is to store partial
# trees. The l_scan routines enable you to take your list structures
# and say, "Give me that portion of list 2 which corresponds
# structurally to list 1." Or you can say, "Tell me if the first
# portion of x list corresponds structurally to y." In effect, the
# structure of the tree can be checked without necessitating a
# reparse.
#
# BUGS: Can you say slow? I thought you could.
#
############################################################################
#
# Here's a trivial example of how one might utilize the lscan routines:
#
# procedure main()
#
# l := ["h","e","l","l","o"," ","t","t","t","h","e","r","e"]
#
# l_scan(l)
# hello_list := l_tab(l_match(["h","e","l","l","o"]))
# every writes(!hello_list)
# write()
#
# l_scan(l_tab(0))
# l_tab(l_many([[" "],["t"]]) - 1)
# every writes(!l_tab(0))
# write()
# end_l_scan()
#
# end_l_scan()
#
# end
#
# The above program simply writes "hello" and "there" on successive
# lines to the standard output.
#
# PITFALLS: In general, note that we are comparing lists here instead
# of strings, so l_find("h", l), for instance, will yield an error
# message (use l_find(["h"], l) instead). The point at which I
# expect this nuance will be most confusing will be in cases where
# one is looking for lists within lists. Suppose we have a list,
#
# l1 := ["junk",[["hello"]," ",["there"]],"!","m","o","r","e","junk"]
#
# and suppose, morover, that we wish to find the position in l1 at
# which the list
#
# [["hello"]," ",["there"]]
#
# occurs. If, say, we assign [["hello"]," ",["there"]] to the
# variable l2, then our l_find() expression will need to look like
#
# l_scan(l1)
# l_tab(l_find([l2]))
# etc.
#
# The reason l2 must be enclosed within a list is that we are
# searching for a single element within l1, not a series of three
# elements. Hence, just as l_find("h") would not work correctly
# above, so l_find(l2) will not work here (although in this latter
# case, no error message is generated; the expression merely fails
# when it finds no sequence of elements in l1 corresponding to the
# sequence of elements occurring in l2).
#
############################################################################
global l_POS
global l_SUBJ
procedure l_scan(l)
if /l_POS then {
l_POS := []
l_SUBJ := []
}
push(l_POS, 1)
push(l_SUBJ, l)
return
end
procedure end_l_scan()
every pop(l_POS|l_SUBJ)
if *l_POS = 0 then {
l_POS := &null
l_SUBJ := &null
}
return
end
procedure l_move(i)
/i & stop("l_move: Null argument.")
if /l_POS | /l_SUBJ
then stop("l_move: Call l_scan first.")
suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1 >= l_POS[1]+i))]
end
procedure l_tab(i)
/i & stop("l_tab: Null argument.")
if /l_POS | /l_SUBJ
then stop("l_tab: Call l_scan first.")
if i = 0
then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- *l_SUBJ[1]+1]
else {
if i < 0
then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1) + i)]
else suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (*l_SUBJ[1]+1 >= i)]
}
end
procedure l_any(l1,l2,i,j)
# Like any(c,s2,i,j) except that the string & cset arguments are
# replaced by list arguments. l1 must be a list of one-element
# lists, while l2 can be any list (l_SUBJ[1] by default).
local sub_l
/l1 & stop("l_any: Null first argument!")
if /l_POS | /l_SUBJ
then stop("l_any: Call l_scan first.")
if type(l1) == "set" then l1 := sort(l1)
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
every sub_l := !l1 do {
if not (type(sub_l) == "list", *sub_l = 1) then
stop("l_any: Elements of l1 must be lists of length 1.")
if x := l_match(sub_l,l2,i,i+1)
then return x
}
end
procedure l_match(l1,l2,i,j)
# Analogous to match(s1,s2,i,j), except that s1 and s2 are lists,
# and l_match returns the next position in l2 after that portion
# (if any) which is structurally identical to l1. If a match is not
# found, l_match fails.
if /l1
then stop("l_match: Null first argument!")
if /l_POS | /l_SUBJ
then stop("l_match: Call l_scan first.")
if type(l1) ~== "list"
then stop("l_match: Call me with a list as the first arg.")
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
if l_comp(l1,l2[i+:*l1])
then return i + *l1
end
procedure l_comp(l1,l2)
# List comparison routine basically taken from Griswold & Griswold
# (1st ed.), p. 174.
local i
/l1 | /l2 & stop("l_comp: Null argument!")
l1 === l2 & return l2
if type(l1) == type(l2) == "list" then {
*l1 ~= *l2 & fail
every i := 1 to *l1
do l_comp(l1[i],l2[i]) | fail
return l2
}
end
procedure l_find(l1,l2,i,j)
local x
/l1 & stop("l_find: Null first argument!")
if /l_POS | /l_SUBJ
then stop("l_find: Call l_scan first.")
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
every x := i to ((*l2+1) - *l1) do {
if l_match(l1,l2,x,j)
then suspend x
}
end
procedure l_upto(l1,l2,i,j)
local x
/l1 & stop("l_upto: Null first argument!")
if /l_POS | /l_SUBJ
then stop("l_upto: Call l_scan first.")
if type(l1) == "set" then l1 := sort(l1)
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
every x := i to ((*l2+1) - *l1) do {
if l_any(l1,l2,x,j)
then suspend x
}
end
procedure l_many(l1,l2,i,j)
/l1 & stop("l_many: Null first argument!")
if /l_POS | /l_SUBJ
then stop("l_many: Call l_scan first.")
if type(l1) == "set" then l1 := sort(l1)
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
l_scan(l2)
while x := l_any(l1,,,j)
do l_tab(x)
end_l_scan(l2)
return \x
end
procedure l_pos(i)
local x
if /l_POS | /l_SUBJ
then stop("l_many: Call l_scan first.")
if i <= 0
then x := 0 < (*l_SUBJ[1]+1 >= (*l_SUBJ[1]+1)+i) | fail
else x := 0 < (*l_SUBJ[1]+1 >= i) | fail
if x = l_POS[1]
then return i
else fail
end
From goer@sophist.uchicago.edu Tue Jul 24 21:16:32 1990
Resent-From: goer@sophist.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA17441; Tue, 24 Jul 90 21:16:32 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from xtank.uchicago.edu by Arizona.edu; Tue, 24 Jul 90 21:18 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Tue, 24 Jul 90
23:17:01 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA03991; Tue, 24 Jul 90
23:12:27 CDT
Resent-Date: Tue, 24 Jul 90 21:19 MST
Date: Tue, 24 Jul 90 23:12:27 CDT
From: Richard Goerwitz <goer@sophist.uchicago.edu>
Subject: user-defined control structures; limitation expressions
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <5D4CE9E1A5FFA017C1@Arizona.edu>
Message-Id: <9007250412.AA03991@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
Mixed in with a recent posting on another topic, I suggested
that p{a,b,c...} might possibly be extended to p{a;b;c}, where
; is actually intended to represent a comma, semicolon, or new-
line. This would permit the creation of user-defined control
structures that *looked* like control structures. I.e. instead
of p{a,b,c} you could just write
p {
a
b
c
etc.
}
This just looks to me like a control structure. In the case of
my list scanning routines, it would permit me to say -
l_scan(l) {
junk1
junk2
etc.
}
The procedure l_scan would set up l_POS and l_SUBJ (the list equiva-
lents to &pos and &subject), and then return a control procedure
(call it setup_scan). Setup_scan(lst[]) would then simply execute
each of its args, noting whether they were a break or next or some
other control structure that might necessitate ending the scanning
operation. If encountered, l_POS and l_SUBJ could be restored cor-
rectly, and the loop could be terminated, just as with regular
string scans.
I've got another idea I'd be interested in hearing ideas about.
Why not let &null limiters work like no limiters at all? Just
curious. Often I change the amount of backtracking on the fly,
and I find it rather awkward to use backslashes and what not to
try to find a way to get a \ expression to do no limitation at
all. Is there some easy and elegant way I'm overlooking?
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From goer@sophist.uchicago.edu Wed Jul 25 09:14:16 1990
Resent-From: goer@sophist.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA12518; Wed, 25 Jul 90 09:14:16 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from xtank.uchicago.edu by Arizona.edu; Wed, 25 Jul 90 09:16 MST
Received: from sophist.uchicago.edu by xtank.uchicago.edu Wed, 25 Jul 90
11:14:34 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA04565; Wed, 25 Jul 90
11:10:00 CDT
Resent-Date: Wed, 25 Jul 90 09:17 MST
Date: Wed, 25 Jul 90 11:10:00 CDT
From: Richard Goerwitz <goer@sophist.uchicago.edu>
Subject: list scanning
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <5CE8A4D1BDBFA021B3@Arizona.edu>
Message-Id: <9007251610.AA04565@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
A postscript to the list scanning routines: They are new and
largely untested. Normally, I'd have labeled them as BETA in
the posting, but I just plain forgot. In the next couple of
days, I'll probably add l_bal() and some other things. Please
drop me a line any time if you find bugs, or want the latest
version. It's the sort of thing I'll eventually submit to the
IPL, but will play with for some time to see whether they are
really useful enough to warrant such a drastic step.
-Richard
From icon-group-request@arizona.edu Fri Aug 3 10:58:32 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA15365; Fri, 3 Aug 90 10:58:32 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 3 Aug 90 11:01 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA12757; Fri, 3 Aug 90 10:42:57
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Fri, 3 Aug 90 11:01 MST
Date: 3 Aug 90 16:19:17 GMT
From: ux1.cso.uiuc.edu!midway!sophist!goer@iuvax.cs.indiana.edu
Subject: fits posting; new l_scan() routines
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <55C79229F8DFA05F1A@Arizona.edu>
Message-Id: <1990Aug3.161917.28358@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
I'm having fits posting here because of mail reorganizations at
the U of Chicago. I assume nothing I've posted in the last week
has gotten through.
Anyway, I've just been trying to post a newer version of the list
scanning routines I posted a couple of weeks back. This new ver-
sion fixes a couple of bugs and provides the "missing" l_bal()
function.
I want very much to prototype this new scanning method using user-
defined control structures, but it's proving very hard. Let's say
you want to write -
repeat {
do something
l_scan(l) {
expresion1,
expression2 & break
}
}
Okay, the l_scan(l) routine sets pos and subject for the list, and
then returns a procedure geared for {}-style invocation. Expres-
sion1 and expression2 & break are the arguments to this procedure.
The trouble is that, even if we could say "create break" (which we
can't), we end up with a break in an invalid context.
The user-defined control structures seem not to allow real Iconish
control. Is this the case? If so, no matter. If not (i.e. if I
am overlooking something), could someone kindly enlighten me? Alter-
natively, if someone has an idea about how to prototype new control
structures, could they perhaps post a followup?
I dearly hope that our news software & mail router doesn't barf on
this one.
Anyway, here's the code:
############################################################################
#
# Name: lscan.icn
#
# Title: Quasi ? scanning routines for lists.
#
# Author: Richard L. Goerwitz
#
# Version: 1.16
#
############################################################################
#
# Copyright (c) 1990, Richard L. Goerwitz, III
#
# This software is intended for free and unrestricted distribution.
# I place only two conditions on its use: 1) That you clearly mark
# any additions or changes you make to the source code, and 2) that
# you do not delete this message from it. In order to protect
# myself from spurious litigation, it must also be stated here that,
# because this is free software, I, Richard Goerwitz, make no claim
# about the applicability or fitness of this software for any
# purpose, and disclaim any responsibility for any damages that
# might be incurred in conjunction with its use.
#
############################################################################
#
# PURPOSE: String scanning is terrific, but often I am forced to
# tokenize and work with lists. So as to make operations on these
# lists as close to corresponding string operations as possible, I've
# implemented a series of list analogues to any(), bal(), find(),
# many(), match(), move(), pos(), tab(), and upto(). Their names are
# just like corresponding string functions, except with a prepended
# "l_" (e.g. l_any()). Functionally, the list routines parallel the
# string ones closely, except that in place of strings, l_find and
# l_match accept lists as their first argument. L_any(), l_many(),
# and l_upto() all take either sets or lists of lists (e.g.
# l_tab(l_upto([["a"],["b"],["j","u","n","k"]])). Note that l_bal(),
# unlike the builtin bal(), has no defaults for the first four
# arguments. This just seemed appropriate, given that no precise
# list analogue to &cset, etc. occurs.
#
# Since Icon does not permit me to define new control structures via
# infix operators, list scanning must be initialized via a procedure,
# namely l_scan(l), where l is the list to be scanned. Scanning is
# ended by calling end_l_scan(l). Nesting is permitted, but you'd
# better make sure your indentation is correct. Since l_scan() does
# not represent a real control structure, you must call end_l_scan()
# before "breaking" from an l_scan. Otherwise l_POS and l_SUBJ will
# not be handled properly.
#
# If someone can think of a way to do this more elegantly let me
# know. Personally, I'd like p{a,b,c} to be extended to allow p{a S
# b S c} (where S ::= ; | \n). I could then do something cute, like
# have l_scan initialize l_POS and l_SUBJ for list l, and then return
# a control procedure geared for {}-style invocation:
#
# l_scan(l) {
# a
# b
# c
# }
#
# I just think this *looks* like a control structure (much more so
# than the kludge I give below). I'd just set up the control pro-
# cedure to handle variable-length arguments.
#
# I envision l_scan being used (and in fact use it myself) to parse
# trees and compare complicated list structures. One big time-saver
# in parsing natural languages, for instance, is to store partial
# trees. The l_scan routines enable you to take your list structures
# and say, "Give me that portion of list 2 which corresponds
# structurally to list 1." Or you can say, "Tell me if the first
# portion of x list corresponds structurally to y." In effect, the
# structure of the tree can be checked without necessitating a
# reparse.
#
# BUGS: Can you say slow? I thought you could.
#
############################################################################
#
# Here's a trivial example of how one might utilize the lscan routines:
#
# procedure main()
#
# l := ["h","e","l","l","o"," ","t","t","t","h","e","r","e"]
#
# l_scan(l)
# hello_list := l_tab(l_match(["h","e","l","l","o"]))
# every writes(!hello_list)
# write()
#
# l_scan(l_tab(0))
# l_tab(l_many([[" "],["t"]]) - 1)
# every writes(!l_tab(0))
# write()
# end_l_scan()
#
# end_l_scan()
#
# end
#
# The above program simply writes "hello" and "there" on successive
# lines to the standard output.
#
# PITFALLS: In general, note that we are comparing lists here instead
# of strings, so l_find("h", l), for instance, will yield an error
# message (use l_find(["h"], l) instead). The point at which I
# expect this nuance will be most confusing will be in cases where
# one is looking for lists within lists. Suppose we have a list,
#
# l1 := ["junk",[["hello"]," ",["there"]],"!","m","o","r","e","junk"]
#
# and suppose, moreover, that we wish to find the position in l1 at
# which the list
#
# [["hello"]," ",["there"]]
#
# occurs. If, say, we assign [["hello"]," ",["there"]] to the
# variable l2, then our l_find() expression will need to look like
#
# l_scan(l1)
# l_tab(l_find([l2]))
# etc.
#
# The reason l2 must be enclosed within a list is that we are
# searching for a single element within l1, not a series of three
# elements. Just as l_find("h") would not work correctly above, so
# l_find(l2) will not work here (although in this latter case, no
# error message is generated; the expression merely fails when it
# finds no sequence of elements in l1 corresponding to the sequence
# of elements occurring in l2).
#
############################################################################
global l_POS
global l_SUBJ
procedure l_scan(l)
if /l_POS then {
l_POS := []
l_SUBJ := []
}
push(l_POS, 1)
push(l_SUBJ, l)
return
end
procedure end_l_scan()
every pop(l_POS|l_SUBJ)
if *l_POS = 0 then {
l_POS := &null
l_SUBJ := &null
}
return
end
procedure l_move(i)
/i & stop("l_move: Null argument.")
if /l_POS | /l_SUBJ
then stop("l_move: Call l_scan first.")
suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1 >= l_POS[1]+i))]
end
procedure l_tab(i)
/i & stop("l_tab: Null argument.")
if /l_POS | /l_SUBJ
then stop("l_tab: Call l_scan first.")
if i = 0
then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- *l_SUBJ[1]+1]
else {
if i < 0
then suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (0 < (*l_SUBJ[1]+1) + i)]
else suspend l_SUBJ[1][.l_POS[1]:l_POS[1] <- (*l_SUBJ[1]+1 >= i)]
}
end
procedure l_any(l1,l2,i,j)
# Like any(c,s2,i,j) except that the string & cset arguments are
# replaced by list arguments. l1 must be a list of one-element
# lists, while l2 can be any list (l_SUBJ[1] by default).
local sub_l
/l1 & stop("l_any: Null first argument!")
if type(l1) == "set" then l1 := sort(l1)
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
(i+1) > j & fail
every sub_l := !l1 do {
if not (type(sub_l) == "list", *sub_l = 1) then
stop("l_any: Elements of l1 must be lists of length 1.")
if x := l_match(sub_l,l2,i,i+1)
then return x
}
end
procedure l_match(l1,l2,i,j)
# Analogous to match(s1,s2,i,j), except that s1 and s2 are lists,
# and l_match returns the next position in l2 after that portion
# (if any) which is structurally identical to l1. If a match is not
# found, l_match fails.
if /l1
then stop("l_match: Null first argument!")
if type(l1) ~== "list"
then stop("l_match: Call me with a list as the first arg.")
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
i + *l1 > j & fail
if l_comp(l1,l2[i+:*l1])
then return i + *l1
end
procedure l_comp(l1,l2)
# List comparison routine basically taken from Griswold & Griswold
# (1st ed.), p. 174.
local i
/l1 | /l2 & stop("l_comp: Null argument!")
l1 === l2 & (return l2)
if type(l1) == type(l2) == "list" then {
*l1 ~= *l2 & fail
every i := 1 to *l1
do l_comp(l1[i],l2[i]) | fail
return l2
}
end
procedure l_find(l1,l2,i,j)
local x
/l1 & stop("l_find: Null first argument!")
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
every x := i to ((*l2+1) - *l1) do {
if l_match(l1,l2,x,j)
then suspend x
}
end
procedure l_upto(l1,l2,i,j)
local x
/l1 & stop("l_upto: Null first argument!")
if type(l1) == "set" then l1 := sort(l1)
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
every x := i to ((*l2+1) - *l1) do {
if l_any(l1,l2,x,j)
then suspend x
}
end
procedure l_many(l1,l2,i,j)
/l1 & stop("l_many: Null first argument!")
if type(l1) == "set" then l1 := sort(l1)
/l2 := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
l_scan(l2)
while x := l_any(l1,,,j)
do l_tab(x)
end_l_scan(l2)
return \x
end
procedure l_pos(i)
local x
if /l_POS | /l_SUBJ
then stop("l_move: Call l_scan first.")
if i <= 0
then x := 0 < (*l_SUBJ[1]+1 >= (*l_SUBJ[1]+1)+i) | fail
else x := 0 < (*l_SUBJ[1]+1 >= i) | fail
if x = l_POS[1]
then return x
else fail
end
procedure l_bal(l1,l2,l3,l,i,j)
local l2_count, l3_count, x, position
/l1 & stop("l_bal: Null first argument!")
if type(l1) == "set" then l1 := sort(l1) # convert to a list
if type(l2) == "set" then l1 := sort(l2)
if type(l3) == "set" then l1 := sort(l3)
/l := l_SUBJ[1]
/i := \l_POS[1] | 1
/j := *l_SUBJ[1]+1
l2_count := l3_count := 0
every x := i to j-1 do {
if l_any(l2, l, x, x+1) then {
l2_count +:= 1
}
if l_any(l3, l, x, x+1) then {
l3_count +:= 1
}
if l2_count = l3_count then {
if l_any(l1,l,x,x+1)
then suspend x
}
}
end
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From kwalker Fri Aug 3 16:06:05 1990
Resent-From: "Kenneth Walker" <kwalker>
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA28424; Fri, 3 Aug 90 16:06:05 -0700
Received: from megaron.cs.Arizona.EDU by Arizona.edu; Fri, 3 Aug 90 16:05 MST
Received: by megaron.cs.arizona.edu (5.61/15) id AA28394; Fri, 3 Aug 90
16:05:32 -0700
Resent-Date: Fri, 3 Aug 90 16:05 MST
Date: Fri, 3 Aug 90 16:05:32 -0700
From: Kenneth Walker <kwalker@cs.arizona.edu>
Subject: RE: fits posting; new l_scan() routines
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <559D0E62DF9BA05A95@Arizona.edu>
Message-Id: <9008032305.AA28394@megaron.cs.arizona.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
> Date: 3 Aug 90 16:19:17 GMT
> From: ux1.cso.uiuc.edu!midway!sophist!goer@iuvax.cs.indiana.edu
> I want very much to prototype this new scanning method using user-
> defined control structures, but it's proving very hard.
Emulating regular string scanning using user-defined control structures
is also awkward. There is a way to emulate string scanning using nested
procedure calls. It does not correctly handle breaking out of string
scanning (but then neither did the Icon intepreter until V7!).
The idea is to translate
expr1 ? expr2
into
escan(bscan(expr1), expr2)
(Of course, expr2 can be a compound expression, if you want it to be.)
This allows the setup routine, bscan, to comunicate with the termination
routine, escan. It allows nesting of scanning along with full backtracking
into and out of scanning. In addition, escan returns the value of the
scanning expression.
Saved scanning environments are stored in records
record scan_env(subject, pos)
procedure bscan(expr1)
local outer_env
outer_env := scan_env(&subject, &pos)
&subject := expr1
&pos := 1
suspend outer_env # pass saved environment to escan
&subject = outer_env.subject
&pos = outer_env.pos
fail # resume expression for expr1
end
procedure escan(outer_env, expr2)
local inner_env
inner_env := scan_env(&subject, &pos)
&subject = outer_env.subject
&pos = outer_env.pos
suspend expr2
outer_env.subject = &subject
outer_env.pos = &pos
&subject = inner_env.subject
&pos = inner_env.pos
fail # resume expression for expr2
end
(disclaimer: these routines are based on code that works, but I
typed them in without trying to translate or run them)
This bscan-escan expression works well if you are using a preprocess
(for example, one bassed on the variant translator system) to translate
from a notation that looks like a control structure, but looks
rather odd if you code it directly. However, it may give you some
ideas.
The only way I know of to solve the "break" problem is to use something
more primative than suspend (break just wipes out suspened generators
without considering that something more might need to be done), but you
can only do this in the run-time system routines written in C, not within
Icon itself.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From goer@sophist.uchicago.edu Thu Aug 9 14:57:17 1990
Resent-From: goer@sophist.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA14726; Thu, 9 Aug 90 14:57:17 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from midway.uchicago.edu by Arizona.edu; Thu, 9 Aug 90 14:56 MST
Received: from sophist.uchicago.edu by midway.uchicago.edu Thu, 9 Aug 90
16:56:23 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA24489; Thu, 9 Aug 90
16:54:06 CDT
Resent-Date: Thu, 9 Aug 90 14:56 MST
Date: Thu, 9 Aug 90 16:54:06 CDT
From: Richard Goerwitz <goer@sophist.uchicago.edu>
Subject: Alan Corre's calendar program; Unix port
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <50EFB04DB03BA090B0@Arizona.edu>
Message-Id: <9008092154.AA24489@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
This is a blanket response to those who are inquiring about the
availability of the Unix port of Alan Corre's Jewish/Civil calen-
dar. A few weeks ago I had asked for beta testers - i.e. people
who might be willing to try the program out under various Unix
versions. Within a few days, the main bugs had been worked out,
and the port was sent to cs.arizona.edu and to Alan Corre.
I am still getting occasional offers to beta test, and I'd just
like to let everyone who might be inclined to make such an offer
know that, although I'm happy about the interest, I've really done
all I'm going to do with the port (unless some really big bugs
are found). Those wanting to know more about the program should,
at this point, mail to Alan Corre, unless the questions are spe-
cifically related to my port. I'll be happy to send out shars if
requested, but I'd suggest that those with good access to cs.
arizona.edu just get them there (in icon/contrib/hebcalen.*.Z).
Again, thanks to those who offered their help. No need for any
more guinea pigs to volunteer!
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
PS. Those interested in the latest icon-termlib routines should
grab the calendar program, since it's got the latest version there.
It's probably the last anyone will see of it, unless it ends up in
the IPL.
From icon-group-request@arizona.edu Sun Aug 12 13:10:20 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA28281; Sun, 12 Aug 90 13:10:20 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Sun, 12 Aug 90 12:35 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15354; Sun, 12 Aug 90
12:30:37 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Sun, 12 Aug 90 12:57 MST
Date: 12 Aug 90 19:14:49 GMT
From: cs.utexas.edu!wuarchive!brutus.cs.uiuc.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@tut.cis.ohio-state.edu
Subject: style checkers?
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <4EA4B7795CDBA08184@Arizona.edu>
Message-Id: <1990Aug12.191449.14458@midway.uchicago.edu>
Organization: University of Chicago Computing Organizations
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
Icon seems to me to offer just the sorts of facilities that
one would need to write a good style checker (hash tables,
sets, elegant string processing facilities). Has anyone out
there done this? Just curious.
From goer@sophist.uchicago.edu Mon Aug 13 11:55:51 1990
Resent-From: goer@sophist.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA13980; Mon, 13 Aug 90 11:55:51 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from midway.uchicago.edu by Arizona.edu; Mon, 13 Aug 90 11:55 MST
Received: from sophist.uchicago.edu by midway.uchicago.edu Mon, 13 Aug 90
13:55:14 CDT
Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA27841; Mon, 13 Aug 90
13:52:55 CDT
Resent-Date: Mon, 13 Aug 90 11:55 MST
Date: Mon, 13 Aug 90 13:52:55 CDT
From: Richard Goerwitz <goer@sophist.uchicago.edu>
Subject: snipping out sentences from text files
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <4DE45CB598BBA09918@Arizona.edu>
Message-Id: <9008131852.AA27841@sophist.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: O
Recently I have had to do some analysis on my prose (my sentences tend
to be too long, contain too many polysyllabic words, and to have too
many subordinate clauses). To do this I wrote a short Icon program.
One procedure I needed to write was a sentence-finder, which snips out
sentences from a given ASCII file. This seemed to be of general in-
terest, so I'm posting it here.
My ulterior motive is that I'll bet a lot of literary types are on
this mailing list, and could improve the algorithm substantially.
I'd really like to see any modifications anyone makes to this code.
-Richard
------------------------------ cut here ------------------------------
procedure main(a)
intext := open(\a[1]) | &input
every write("\n",sentence(intext))
end
############################################################################
#
# Name: sentence.icn
#
# Title: A simple sentence-finder
#
# Author: Richard Goerwitz
#
# Version: (just a preliminary hack)
#
############################################################################
#
# This procedure simply reads an ASCII file (or maybe an n/troff file),
# and suspends the sentences contained in it. Sentences are defined as
# any string of characters ending in a punctuation-group containing an
# exclamation point, period, or question mark, followed by two spaces, or
# else by a space, an (optional) string of sentence-initial punctuation,
# and finally a capital letter or number. If I could count on everyone
# having a /usr/dict/words file, I'd require that the capital letter be-
# gin a word which maps to a lowercase entry in /usr/dict/words (so as to
# avoid calling cases like "R. Goerwitz" a sentence-break). Since not every-
# one has such a wordlist, I'll just rest content to leave the algorithm
# (imperfect) as it is. Note that cases where a sentence ends a line are
# handled by appending a space to that line, and then appending the next
# line from the input file. This puts the sentence break into a form the
# algorithm can recognize as a sentence break.
#
############################################################################
#
# Requires: coexpressions
#
# See also: segment.icn (if you wish to tokenize)
#
############################################################################
procedure sentence(intext)
local sentence, get_line, line, tmp_s, end_part
static inits, punct
initial {
inits := &ucase ++ &digits
punct := ".\"'!?)]"
}
sentence := ""
get_line := create read_line(intext)
while line := @get_line do {
# Go on until you can't find any more sentence-endings in line,
# then break and get another line.
repeat {
# Scan for a sentence break somewhere in line.
line ? {
# Ugly, but it works. Look for sequences containing
# things like periods and question marks, followed by
# a space and another space or a word beginning with
# a capital letter. If we don't have enough context,
# append the next line from intext to line & scan again.
if tmp_s := tab(upto(punct)) &
upto('!?.', end_part := tab(many(punct))) &
not (pos(-1), line ||:= @get_line, next) &
=" " & (=" " | (tab(many('\'"('))|&null,any(inits)))
then {
suspend sentence || tmp_s || end_part
tab(many(' '))
line := tab(0)
sentence := ""
next
}
else break
}
}
# Otherwise just tack line onto sentence & try again.
sentence ||:= line
}
return sentence
end
procedure read_line(intext)
local new_line
while line := trim(!intext,'\t ') do {
line ? {
match(".") & next
tab(many('\t #'))
pos(0) & next
new_line := tab(-1) || (="-" | (move(1) || " "))
}
suspend new_line
}
end
From cargo@cherry.cray.com Fri Aug 17 13:20:29 1990
Received: from timbuk.CRAY.COM by megaron (5.61/15) via SMTP
id AA12741; Fri, 17 Aug 90 13:20:29 -0700
Received: from cherry04.cray.com by timbuk.CRAY.COM (4.1/SMI4.0 CRAY1.1)
id AA24602; Fri, 17 Aug 90 15:20:23 CDT
Received: by cherry04.cray.com
id AA07741; 4.1/CRI-3.20; Fri, 17 Aug 90 15:20:19 CDT
Date: Fri, 17 Aug 90 15:20:19 CDT
From: cargo@cherry.cray.com (David S. Cargo)
Message-Id: <9008172020.AA07741@cherry04.cray.com>
To: icon-group@cs.arizona.edu
Subject: new table mechanism
Status: O
I was thinking about the new table mechanisms in the latest version
of Icon. I think that a change in the way that the tables are
initially allocated could double the size of tables that can be handled
effectively as well as improve space and time performance for handling
small tables.
As I understand it, minimum size tables are now composed of two parts,
a table header, and a hash chain header. The table header contains
"slots" for pointing to hash chain headers. The hash chain headers
are sizes based on powers of two. The first hash chain header will be
of size 8 (for example), the second will be of the same size, the
third will be equal to the sum of the sizes of the first two, the
fourth will be equal to the sum of the sizes of the first three, etc.
I believe the current implementation also has 8 slots for pointing to
hash chain headers. Therefore it can point to 8 + 8 + 16 + 32 + 64 +
128 + 256 + 512 = 1024 chains.
An empty table has a table header that points to an empty hash chain
header.
What I think might be worth investigating is using the table header
slots as hash chain headers for small tables. This still gives you 8
hash chain slots. Then, if the table load factor grows to the point
where more hash chain slots are needed, allocate a hash chain header
with 16 slots. Instead of starting the sizes of hash chain headers at
8, this would start them at 16, doubling the number of total slots
that could be pointed to by the 8 slots in the table header.
For small tables, this eliminates one level of indirection and reduces
the space overhead for small and empty tables. It also reduces the
time overhead for creating tables, since fewer memory allocations are
required. This would be most noticable when many small tables are
created.
For large tables, this doubles the maximum number of potential hash
chains.
Certainly the semantics of tables require that more issues than just
the space considerations be examined (e.g., element generation), but
making this implementation change would further improve the benefit of
dynamic tables.
David S. Cargo (cargo@cray.com)
From CELEX@CELEX.KUN.NL Mon Aug 20 06:29:29 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA23098; Mon, 20 Aug 90 06:29:29 -0700
Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Mon, 20 Aug 90 06:29 MST
Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Mon, 20 Aug 90 15:31 MET
Date: Mon, 20 Aug 90 15:24 MET
From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
Subject: Output to screen.
To: icon-group@cs.arizona.edu
Message-Id: <484607C22EDF402586@KUNRC1.URC.KUN.NL>
X-Envelope-To: icon-group@cs.ARIZONA.EDU
X-Vms-To: IN%"icon-group@cs.arizona.edu"
Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
SURF/DECNET: celex::celexmail JANET: celex%earn.hnympi52@uk.ac.earn-relay
Status: RO
We have recently installed version 8 of Icon on our micro-VAXes. Compared
to version 6 the output to the screen is much slower. Can anything be done
about that?
Marcel Bingley
CELEX
Nijmegen, the Netherlands.
From CELEX@CELEX.KUN.NL Mon Aug 20 09:14:59 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA02148; Mon, 20 Aug 90 09:14:59 -0700
Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Mon, 20 Aug 90 09:14 MST
Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Mon, 20 Aug 90 18:07 MET
Date: Mon, 20 Aug 90 18:00 MET
From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
Subject: Output to screen.
To: icon-group@cs.arizona.edu
Message-Id: <483042BF825F40152B@KUNRC1.URC.KUN.NL>
X-Envelope-To: icon-group@cs.ARIZONA.EDU
X-Vms-To: IN%"icon-group@cs.arizona.edu"
Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
SURF/DECNET: celex::celexmail JANET: celex%earn.hnympi52@uk.ac.earn-relay
Status: RO
Richard,
We still have version 6 installed, so if your answer will be the only
solution we can "down-grade" in a minute.
I don't know what gcc is (must have something to do with C, I guess),
so I don't know whether it will run. We use the VAX-C compiler.
-Marcel
From tenaglia@mis.mcw.edu Mon Aug 20 10:24:03 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA05591; Mon, 20 Aug 90 10:24:03 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.3/3.07) with UUCP
id AA10495; Mon, 20 Aug 90 13:11:40 EDT
Received: by uwm.edu; id AA07857; Mon, 20 Aug 90 11:31:09 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Mon, 20 Aug 90 11:13:53 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Mon, 20 Aug 90 10:31:34 CDT
Date: Mon, 20 Aug 90 10:31:34 CDT
Message-Id: <0093B790107BF840.2040021F@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: ICON on VMS
To: icon-group@cs.arizona.edu
Status: RO
Recently someone mentioned something about Icon V8 being slower than V6 on a
microvax in regards to screen IO. This sounds like a VMS system. I've used
in primarily on VAX/VMS, but also a little on a VAX 780 running Berkeley Unix
4.3 and the screen IO behaviour difference is quite noticable.
I think it's because the VMS version is trying to emulate the data stream
concept of unix. This is why the unix redirectors <, >, and >> can be used
with VMS ICON where VAX FORTRAN doesn't handle them automatically. Therefore,
I'm not sure that we could or should ever expect speedy screen IO under VMS.
I really like the redirectors and wouldn't want to loose them. Eventually,
I'd like to see the PIPE | come to VMS ICON as well. Then we could issue
commands like ICONX PROG1 <DATA.LIS | PROG2 | PROG3 >FILTERED.LIS where
PROG1, PROG2, and PROG3 are icon executables.
There is another problem with screen IO. Here's a little program...
procedure main()
write("Hello there")
end
If this is run interactively the output is "Hello there". If it's run in a
batch or in a DCL subprocess window under EVE the output is
H
e
l
l
o
t
h
e
r
e
Which can make the batch log or editor buffer pretty long. I wrote a log
squeezer. Its usage is ICONX LOG <BATCH.LOG >BATCH.LIS
#######################################################################
# #
# LOG.ICN 7/5/90 BY TENAGLIA #
# #
# THIS PROGRAM SMOOTHS A BATCH LOG THAT RAN AN ICON PROGRAM #
# ICON PROGRAMS IN BATCH TEND TO PUT ONE CHARACTER PER LINE #
# IN THE LOG FILES, MAKING THEM HORRIBLE TO PRINT AND READ. #
# THIS PROGRAM SENSES THE ICON ENVIRONMENT, AND TRIES TO MAKE #
# THE LOG FILE MORE COMPRESSED AND READIBLE. #
# USAGE : ICONX LOG <INPUT_FILE >OUTPUT_FILE WIDTH [132] #
# #
#######################################################################
global tty
procedure main(param)
width := param[1] | 132
width := ((-width > width) | width) - 3
text := ""
while line := read() do
{
if *line > 2 then
{
if match("$",line) & (trim(text) ~== "") then line := "\n" || line
both := text || line
write(unscape(both))
text := ""
next
}
text ||:= line
if *text > width then
{
write(unscape(text))
text := ""
}
}
end
#
# REMOVES MOST UGLY ESCAPE SEQUENCES
#
procedure unscape(data)
new := "" ; toggle := -1
while i := find("\e#"|"\e("|"\e)",data) do data[i+:3] := ""
every byte := !data do
{
if byte == "\e" then
{
toggle := 1
next
}
if toggle = 1 then
{
if any(&letters,byte) then toggle := -1
next
} else new ||:= byte
}
return new
end
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From kwalker Tue Aug 21 15:46:13 1990
Received: from gacham.cs.arizona.edu by megaron (5.61/15) via SMTP
id AA15524; Tue, 21 Aug 90 15:46:13 -0700
Date: Tue, 21 Aug 90 15:46:11 MST
From: "Kenneth Walker" <kwalker>
Message-Id: <9008212246.AA12413@gacham.cs.arizona.edu>
Received: by gacham.cs.arizona.edu; Tue, 21 Aug 90 15:46:11 MST
To: icon-group
Subject: Re: ICON on VMS
Status: RO
> Date: Mon, 20 Aug 90 10:31:34 CDT
> From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
> Subject: ICON on VMS
> Recently someone mentioned something about Icon V8 being slower than V6 on a
> microvax in regards to screen IO. This sounds like a VMS system.
> There is another problem with screen IO. Here's a little program...
The Icon interpreter is a C program that uses C's fwrite() to implement
the write() function. Do other C programs have these problems under VMS?
Ken Walker, kwalker@cs.arizona.edu
From icon-group-request@arizona.edu Wed Aug 22 06:44:59 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA13328; Wed, 22 Aug 90 06:44:59 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 22 Aug 90 06:44 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA22123; Wed, 22 Aug 90
06:30:12 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 22 Aug 90 06:44 MST
Date: 22 Aug 90 12:25:18 GMT
From: mcsun!hp4nl!mhres!squirrel!jv@uunet.uu.net
Subject: Catspaw
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <46FD4904D9FF001618@Arizona.edu>
Message-Id: <1990Aug22.122518.28178@squirrel.mh.nl>
Organization: Multihouse Automation, the Netherlands
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Status: RO
Is Catspaw still on the net? Their old address
<...%cats.uucp@arizona.edu> bounces.
I wanted to find out if there is anything
new on the ProIcon front.
Johan
--
Johan Vromans jv@mh.nl via internet backbones
Multihouse Automatisering bv uucp: ..!{uunet,hp4nl}!mh.nl!jv
Doesburgweg 7, 2803 PL Gouda, The Netherlands phone/fax: +31 1820 62911/62500
------------------------ "Arms are made for hugging" -------------------------
From CELEX@CELEX.KUN.NL Wed Aug 22 09:17:03 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA20264; Wed, 22 Aug 90 09:17:03 -0700
Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Wed, 22 Aug 90 09:16 MST
Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Wed, 22 Aug 90 18:18 MET
Date: Wed, 22 Aug 90 18:13 MET
From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
Subject: Screen I/O
To: icon-group@cs.arizona.edu
Message-Id: <469C508A341F402C33@KUNRC1.URC.KUN.NL>
X-Envelope-To: icon-group@cs.ARIZONA.EDU
X-Vms-To: IN%"icon-group@cs.arizona.edu"
Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
SURF/DECNET: celex::celexmail JANET: celex%earn.hnympi52@uk.ac.earn-relay
Status: RO
Thanks to everyone who replied to my problem with the slow screen I/O
with Icon V8.
Richard wrote:
> Gcc is the GNU C compiler, and it produces much better code, in many
> instances, than the native compilers that come on various systems.
> I just wondered whether there was a VAX version.
Sorry Richard, I don't know if one is available.
> I do not use VMS, but I would be curious to know if anyone sends you
> a solution to your problem with Icon version 8. I might be tempted
> to try version 7.5 to see if it works as fast as 8, since 7.5 is very
> close syntactically to version 8. Version 8 mainly represents a change
> in the internal handling of tables and sets. Version 8 also allows
> memory monitoring.
We had the same problem with v. 7.5, so we stayed with v.6 (I guess
we should have reported this problem then).
> You may find that, despite slower I/O, version 8 saves you so much
> space that it's worth it. The space savings will show up in programs
> that use large sets and tables.
> Please let me know what you do. I am curious.
I will.
Chris wrote:
> Recently someone mentioned something about Icon V8 being slower than V6 on a
> microvax in regards to screen IO. This sounds like a VMS system. I've used
> in primarily on VAX/VMS, but also a little on a VAX 780 running Berkeley Unix
> 4.3 and the screen IO behaviour difference is quite noticable.
> I think it's because the VMS version is trying to emulate the data stream
> concept of unix. This is why the unix redirectors <, >, and >> can be used
> with VMS ICON where VAX FORTRAN doesn't handle them automatically. Therefore,
> I'm not sure that we could or should ever expect speedy screen IO under VMS.
> I really like the redirectors and wouldn't want to loose them. Eventually,
> I'd like to see the PIPE | come to VMS ICON as well. Then we could issue
> commands like ICONX PROG1 <DATA.LIS | PROG2 | PROG3 >FILTERED.LIS where
> PROG1, PROG2, and PROG3 are icon executables.
From this I conclude that you think that above v6 the fast screen I/O
is sacrificed for the possibility of using redirectors. I can understand
you don't want to loose them, but we don't want to loose the fast screen
I/O. Wouldn't it be great, if your theory is right, to introduce 2 Icon
versions to keep both of us happy?
And finally Ken wrote:
> The Icon interpreter is a C program that uses C's fwrite() to implement
> the write() function. Do other C programs have these problems under VMS?
No, other (well, we only tried one) C-programs don't have that problem.
We compared the screen-output of the following 2 programs:
The C-version:
---
#include stdio
main()
{
int i;
char s[20] = "Hello world.\n";
FILE term;
term = fopen("SYS$OUTPUT","w");
for (i=0; i<100; i++)
fwrite(s,strlen(s),1,term);
}
---
The Icon-version:
---
procedure main()
s := "Hello world."
every i := 1 to 100 do
write(s)
end
---
The Icon-output was considerably slower. Is the problem somewhere else?
Marcel Bingley
CELEX
Nijmegen University - The Netherlands.
From CELEX@CELEX.KUN.NL Wed Aug 22 12:50:54 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA01353; Wed, 22 Aug 90 12:50:54 -0700
Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Wed, 22 Aug 90 12:50 MST
Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Wed, 22 Aug 90 18:23 MET
Date: Wed, 22 Aug 90 18:17 MET
From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
Subject: Screen I/O
To: icon-group@cs.arizona.edu
Message-Id: <469BBD46503F4031B6@KUNRC1.URC.KUN.NL>
X-Envelope-To: icon-group@cs.ARIZONA.EDU
X-Vms-To: IN%"icon-group@cs.arizona.edu"
Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
SURF/DECNET: celex::celexmail JANET: celex%earn.hnympi52@uk.ac.earn-relay
Status: RO
In addition to my previous message: as Chris already guessed, we run
indeed VAX/VMS (version 5.1-B).
Marcel Bingley
CELEX
Nijmegen University - The Netherlands
From CELEX@CELEX.KUN.NL Wed Aug 22 12:56:00 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA01530; Wed, 22 Aug 90 12:56:00 -0700
Received: from KUNRC1.URC.KUN.NL by Arizona.edu; Wed, 22 Aug 90 12:55 MST
Received: from CELEX.KUN.NL by KUNRC1.URC.KUN.NL; Wed, 22 Aug 90 19:58 MET
Date: Wed, 22 Aug 90 19:51 MET
From: CELEX -- Centre for Lexical Information <CELEX@CELEX.KUN.NL>
Subject: RE: VMS I/O
To: icon-group@cs.arizona.edu
Message-Id: <468E719C6C3F4028D7@KUNRC1.URC.KUN.NL>
X-Envelope-To: icon-group@cs.ARIZONA.EDU
X-Vms-To: IN%"icon-group@cs.arizona.edu"
Comments: Users of other networks can reply to EARN/BITNET: celex@hnympi52
SURF/DECNET: celex::celexmail JANET: celex%earn.hnympi52@uk.ac.earn-relay
Status: RO
Dear Gregg,
I tried your alternative C-program and it works fine (i.e. fast output).
The 2 C-programs and the V6-Icon-program produce fast output (you don't
see the cursor). With the V8-program you actually see the cursor writing
a line.
Hope this gives you a clue.
Marcel Bingley
CELEX
Nijmegen University - The Netherlands.
From icon-group-request@arizona.edu Wed Aug 22 13:30:25 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA03374; Wed, 22 Aug 90 13:30:25 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 22 Aug 90 13:30 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA20284; Wed, 22 Aug 90
13:29:42 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 22 Aug 90 13:30 MST
Date: 22 Aug 90 20:07:02 GMT
From: news@psuvax1.cs.psu.edu
Subject: RE: Screen I/O
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <46C4A27228FF001B3F@Arizona.edu>
Message-Id: <F53rjst1@cs.psu.edu>
Organization: Pennsylvania State University, computer science
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <469C508A341F402C33@KUNRC1.URC.KUN.NL>
Status: RO
Marcel Bingley writes:
Sorry Richard, I don't know if one is available.
There is. prep.ai.mit.edu has gcc-vms.tar in pub/gnu.
From icon-group-request@arizona.edu Tue Aug 28 18:10:20 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (hopey.telcom.arizona.edu) by megaron (5.61/15) via SMTP
id AA05479; Tue, 28 Aug 90 18:10:20 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 28 Aug 90 18:09 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09685; Tue, 28 Aug 90
18:00:36 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 28 Aug 90 18:10 MST
Date: 29 Aug 90 00:30:44 GMT
From: sdd.hp.com!zaphod.mps.ohio-state.edu!brutus.cs.uiuc.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@ucsd.edu
Subject: game
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <41E68D3299CB003A39@Arizona.edu>
Message-Id: <1990Aug29.003044.10129@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Would anyone like to try out an idle game I wrote which simply does
pretty things on the screen?
I wrote it to test out some utility libraries, so the real reason
behind my asking is to get feedback on those libraries.
NB: To run everything, you'll need to be operating in a Unix envi-
ronment, or else enjoy hacking.
-Richard
From @mirsa.inria.fr:ol@cerisi.cerisi.Fr Wed Aug 29 00:48:06 1990
Resent-From: @mirsa.inria.fr:ol@cerisi.cerisi.Fr
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA17796; Wed, 29 Aug 90 00:48:06 -0700
Received: from mirsa.inria.fr by Arizona.edu; Wed, 29 Aug 90 00:47 MST
Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP (5.61+++/IDA-1.2.8)
id AA08085; Wed, 29 Aug 90 09:49:14 +0200
Resent-Date: Wed, 29 Aug 90 00:47 MST
Date: Wed, 29 Aug 90 09:45:50 -0100
From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
Subject: game
Resent-To: icon-group@cs.arizona.edu
To: quads.%midway@ux1.cso.uiuc.edu
Cc: icon-group@arizona.edu
Resent-Message-Id: <41AEFF3FD06B004B84@Arizona.edu>
Message-Id: <9008290749.AA08085@mirsa.inria.fr>
Posted-Date: Wed, 29 Aug 90 09:45:50 -0100
In-Reply-To:
sdd.hp.com!zaphod.mps.ohio-state.edu!brutus.cs.uiuc.edu!ux1.cso.uiuc.edu!midway!quads.'s message
of 29 Aug 90 00:30:44 GMT <1990Aug29.003044.10129@midway.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: quads.%midway@ux1.cso.uiuc.edu
X-Vms-Cc: icon-group@Arizona.EDU
Why not?
Olivier Lecarme
From MYankowski.BSPO@DOCKMASTER.NCSC.MIL Tue Sep 4 08:34:13 1990
Received: from DOCKMASTER.NCSC.MIL by megaron (5.61/15) via SMTP
id AA29669; Tue, 4 Sep 90 08:34:13 -0700
Date: Tue, 4 Sep 90 11:27 EDT
From: MYankowski@DOCKMASTER.NCSC.MIL
Subject: parsing the backslash character
To: icon-group@128.196.128.118
Message-Id: <900904152756.009633@DOCKMASTER.NCSC.MIL>
I am trying to parse a string which is a DOS path name. I cannot pull
out the directory separators ("\") because ICON recognizes them as an
escape sequence, if it is valid, or just returns the character that
follows the backslash. Can anyone offer any sug- gestions.
Michael Yankowski Dockmaster.ARPA
From nowlin@iwtqg.att.com Tue Sep 4 11:37:19 1990
Resent-From: nowlin@iwtqg.att.com
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA11697; Tue, 4 Sep 90 11:37:19 -0700
Received: from att-in.att.com by Arizona.edu; Tue, 4 Sep 90 11:36 MST
Resent-Date: Tue, 4 Sep 90 11:37 MST
Date: Tue, 4 Sep 90 11:23 CDT
From: nowlin@iwtqg.att.com
Subject: RE: parsing the backslash character
Resent-To: icon-group@cs.arizona.edu
To: att!arizona.edu!icon-group@cs.arizona.edu
Resent-Message-Id: <3C9D4C53B8A7006AD2@Arizona.edu>
Message-Id: <3C9D55EB9F972059DB@Arizona.edu>
Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: att!arizona.edu!icon-group@cs.Arizona.edu
> I am trying to parse a string which is a DOS path name. I cannot pull
> out the directory separators ("\") because ICON recognizes them as an
> escape sequence, if it is valid, or just returns the character that
> follows the backslash. Can anyone offer any sug- gestions.
>
> Michael Yankowski Dockmaster.ARPA
A backslash is just another character if it's in a string you're
scanning. The trick is specifying the backslash as the scanning
target. Two backslashes is the way. For example, if the your
program reads lines containing DOS pathnames to be scanned you
could pull off the directory segments of the paths and the command
names with this simple program:
procedure main()
while line := read() do {
line ? {
dir := []
while put(dir,tab(upto('\\'))) do tab(many('\\'))
cmd := tab(0)
}
every writes(!dir,"\\")
write(cmd)
}
end
This program reconstructs the paths and writes them back out but
you could do anything with them at that point.
Jerry Nowlin
(...!att!iwtqg!nowlin)
From icon-group-request@arizona.edu Wed Sep 5 03:25:50 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA28854; Wed, 5 Sep 90 03:25:50 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 5 Sep 90 03:25 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29436; Wed, 5 Sep 90 03:14:59
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 5 Sep 90 03:25 MST
Date: 4 Sep 90 04:59:25 GMT
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
Subject: I/O routines, part 02 of 02
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <3C18CE2794EB006839@Arizona.edu>
Message-Id: <1990Sep4.045925.26376@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
---- Cut Here and unpack ----
#!/bin/sh
# this is itlib.02 (part 2 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file itlibdos.icn continued
#
if test ! -r shar3_seq_.tmp; then
echo "Please unpack part 1 first!"
exit 1
fi
(read Scheck
if test "$Scheck" != 2; then
echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < shar3_seq_.tmp || exit 1
echo "x - Continuing file itlibdos.icn"
sed 's/^X//' << 'SHAR_EOF' >> itlibdos.icn &&
X &subject == "" & next
X if k := 1(move(2), ="=")
X then /tc_table[k] := decode(tab(find(":")))
X else if k := 1(move(2), ="#")
X then /tc_table[k] := integer(tab(find(":")))
X else if k := 1(tab(find(":")), pos(-1))
X then /tc_table[k] := true()
X else er("maketc_table", "your termcap file has a bad entry",3)
X &null # in case insertion fails due to duplicate entry
X }
X }
X
X return tc_table
X
Xend
X
X
X
Xprocedure getval(id)
X
X /tc_table := maketc_table(getentry(getname())) |
X er("getval","can't make a table for your terminal",4)
X
X return \tc_table[id] | fail
X # er("getval","the current terminal doesn't support "||id,7)
X
Xend
X
X
X
Xprocedure decode(s)
X
X # Does things like turn ^ plus a letter into a genuine control
X # character.
X
X new_s := ""
X
X s ? {
X while new_s ||:= tab(upto('\\^')) do {
X chr := move(1)
X if chr == "\\" then {
X new_s ||:= {
X case chr2 := move(1) of {
X "\\" : "\\"
X "^" : "^"
X "E" : "\e"
X "b" : "\b"
X "f" : "\f"
X "n" : "\n"
X "r" : "\r"
X "t" : "\t"
X default : {
X if any(&digits,chr2) then {
X char(integer("8r"||chr2||move(2 to 0 by -1))) |
X er("decode","bad termcap entry",3)
X }
X else chr2
X }
X }
X }
X }
X else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
X }
X new_s ||:= tab(0)
X }
X
X return new_s
X
Xend
X
X
X
Xprocedure igoto(cm,col,line)
X
X local colline, range, increment, str, outstr, chr, x, y
X
X if col > (tc_table["co"]) | line > (tc_table["li"]) then {
X colline := string(\col) || "," || string(\line) | string(\col|line)
X range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
X er("igoto",colline || " out of range " || (\range|""),9)
X }
X
X # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
X increment := -1
X outstr := ""
X
X cm ? {
X while outstr ||:= tab(find("%")) do {
X tab(match("%"))
X chr := move(1)
X if case chr of {
X "." : outstr ||:= char(line + increment)
X "+" : outstr ||:= char(line + ord(move(1)) + increment)
X "d" : {
X str := string(line + increment)
X outstr ||:= right(str, integer(tab(any('23'))), "0") | str
X }
X }
X then line :=: col
X else {
X case chr of {
X "n" : line := ixor(line,96) & col := ixor(col,96)
X "i" : increment := 0
X "r" : line :=: col
X "%" : outstr ||:= "%"
X "B" : line := ior(ishift(line / 10, 4), line % 10)
X ">" : {
X x := move(1); y := move(1)
X line > ord(x) & line +:= ord(y)
X &null
X }
X } | er("goto","bad termcap entry",5)
X }
X }
X return outstr || tab(0)
X }
X
Xend
X
X
X
Xprocedure iputs(cp, affcnt)
X
X # Writes cp to the screen. Use this instead of writes() for
X # compatibility with the Unix version (which will need to send
X # null padding in some cases). Iputs() also does a useful type
X # check.
X
X static num_chars
X initial num_chars := &digits ++ '.'
X
X type(cp) == "string" |
X er("iputs","you can't iputs() a non-string value!",10)
X
X cp ? {
X if tab(many(num_chars)) & ="*" then
X stop("iputs: MS-DOS termcap files shouldn't specify padding.")
X writes(tab(0))
X }
X
X return
X
Xend
SHAR_EOF
echo "File itlibdos.icn is complete" &&
# ============= termcap.dos ==============
echo "x - extracting termcap.dos (Text)"
sed 's/^X//' << 'SHAR_EOF' > termcap.dos &&
Xansi|color|ansi-color|ibm|ibmpc|ANSI.SYS color:\
X :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\
X :cl=\E[H\E[2J:ce=\E[K:\
X :ho=\E[H:cm=\E[%i%d;%dH:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :ti=\E[0;44m:te=\E[0m:\
X :so=\E[1;35;44m:se=\E[0;44m:\
X :us=\E[1;31;44m:ue=\E[0;44m:\
X :mb=\E[5m:md=\E[1m:me=\E[0;44m:
Xmono|ansi-mono|ANSI.SYS:\
X :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\
X :cl=\E[H\E[2J:ce=\E[K:\
X :ho=\E[H:cm=\E[%i%d;%dH:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :so=\E[1m:se=\E[m:us=\E[4m:ue=\E[m:\
X :mb=\E[5m:md=\E[1m:me=\E[m:
Xnnansi-mono|NNANSI.SYS:\
X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
X :cl=\E[2J:cd=\E[J:ce=\E[K:\
X :ho=\E[H:cm=\E[%i%d;%dH:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :so=\E[1m:se=\E[2m:\
X :us=\E[4m:ue=\E[24m:\
X :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[m:\
X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
Xnnansi|nnansi-color|NNANSI.SYS color:\
X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
X :cl=\E[2J:cd=\E[J:ce=\E[K:\
X :ho=\E[H:cm=\E[%i%d;%dH:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :ti=\E[0;44m:te=\E[0m:\
X :so=\E[1;35;44m:se=\E[2;37m:\
X :us=\E[4m:ue=\E[24m:\
X :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[0;44m:\
X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
Xnansi-mono|zansi-mono|N/ZANSI.SYS:\
X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
X :cl=\E[2J:ce=\E[K:\
X :ho=\E[H:cm=\E[%i%d;%dH:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :ti=\E[0m:te=\E[0m:\
X :so=\E[1;35m:se=\E[0m:\
X :us=\E[1;31m:ue=\E[0m:\
X :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:\
X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
Xnansi|zansi|nansi-color|zansi-color|N/ZANSI.SYS color:\
X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
X :cl=\E[2J:ce=\E[K:\
X :ho=\E[H:cm=\E[%i%d;%dH:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :ti=\E[0;44m:te=\E[0m:\
X :so=\E[1;35;44m:se=\E[0;44m:\
X :us=\E[1;31;44m:ue=\E[0;44m:\
X :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[0;44m:\
X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
XAX|ANSI X3.64|full ANSI X3.64 (1977) standard:\
X :co#80:li#24:bs:pt:am:mi:bl=^G:le=^H:\
X :cl=\E[2J:ce=\E[K:cd=\E[J:\
X :ho=\E[H:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\
X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
X :UP=\E[%dA:DO=\E[%dB:LE=\E[%dC:RI=\E[%dD:\
X :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
X :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:as=^N:ae=^O:\
X :ku=\E[A:kd=\E[B:kl=\E[C:kr=\E[D:kb=^H:\
X :kn#4:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\
X :im=\E[4h:ei=\E[4l:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:sf=\ED:sr=\EM:
SHAR_EOF
rm -f shar3_seq_.tmp
echo "You have unpacked the last part"
exit 0
From icon-group-request@arizona.edu Wed Sep 5 03:26:14 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA28870; Wed, 5 Sep 90 03:26:14 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 5 Sep 90 03:25 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29438; Wed, 5 Sep 90 03:14:59
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 5 Sep 90 03:25 MST
Date: 4 Sep 90 04:57:30 GMT
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
Subject: I/O library, part 01 of 02
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <3C18BD78A58B006ABA@Arizona.edu>
Message-Id: <1990Sep4.045730.26320@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <1990Aug29.003044.10129@midway.uchicago.edu>,
<9008290749.AA08085@mirsa.inria.fr>
A few months ago, I posted a set of generalized I/O routines for Icon
running on Unix routines. Since then, I've used various underhanded
means of testing them, such as porting Alan Corre's calendar program
to Unix, and sending out a little snake game.
The routines are now in fair shape. What is more, I've ported them to
MS-DOS, so that people can now write programs for the one environment,
and expect them to run (and look pretty much the same) in the other.
I really hope that, by using these generalized routines, people will
be able to avoid the cardinal sin of hard-coding OS and terminal spe-
cific I/O routines into their source code.
This posting is long, but I've received a number of requests for the
package. To be sure no one's mailer barf's on it, it's been split
into two parts. This is part 1.
-Richard
(BTW: The MS-DOS version is much less well-tested than the Unix ver-
sion, mainly because I don't use DOS much, and when I do it's usually
by way of a DOS emulator running as a task under Xenix.)
---- Cut Here and unpack ----
#!/bin/sh
# This is a shell archive (shar 3.24)
# made 08/31/1990 05:59 UTC by goer@sophist.uchicago.edu
# Source directory /u/richard/Itermlib
#
# existing files WILL be overwritten
# This format requires very little intelligence at unshar time.
# "echo" and "sed" will be needed.
#
# This is part 1 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 12054 -r--r--r-- itlib.icn
# 4980 -r--r--r-- iscreen.icn
# 15452 -r--r--r-- itlibdos.icn
# 2391 -r--r--r-- termcap.dos
#
if test -r shar3_seq_.tmp; then
echo "Must unpack archives in sequence!"
next=`cat shar3_seq_.tmp`; echo "Please unpack part $next next"
exit 1
fi
# ============= itlib.icn ==============
echo "x - extracting itlib.icn (Text)"
sed 's/^X//' << 'SHAR_EOF' > itlib.icn &&
X########################################################################
X#
X# Name: itlib.icn
X#
X# Title: Icon termlib-type tools
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.12
X#
X########################################################################
X#
X# Copyright (c) 1990, Richard L. Goerwitz, III
X#
X# This software is intended for free and unrestricted distribution.
X# I place only two conditions on its use: 1) That you clearly mark
X# any additions or changes you make to the source code, and 2) that
X# you do not delete this message therefrom. In order to protect
X# myself from spurious litigation, it must also be stated here that,
X# because this is free software, I, Richard Goerwitz, make no claim
X# about the applicability or fitness of this software for any
X# purpose, and expressly disclaim any responsibility for any damages
X# that might be incurred in conjunction with its use.
X#
X########################################################################
X#
X# The following library represents a series of rough functional
X# equivalents to the standard Unix low-level termcap routines. They
X# are not meant as exact termlib clones. Nor are they enhanced to
X# take care of magic cookie terminals, terminals that use \D in their
X# termcap entries, or, in short, anything I felt would not affect my
X# normal, day-to-day work with ANSI and vt100 terminals.
X#
X# Requires: A unix platform & co-expressions. I have diffs for a
X# MS-DOS version, if anyone wants them.
X#
X# setname(term)
X# Use only if you wish to initialize itermlib for a terminal
X# other than what your current environment specifies. "Term" is the
X# name of the termcap entry to use. Normally this initialization is
X# done automatically, and need not concern the user.
X#
X# getval(id)
X# Works something like tgetnum, tgetflag, and tgetstr. In the
X# spirit of Icon, all three have been collapsed into one routine.
X# Integer valued caps are returned as integers, strings as strings,
X# and flags as records (if a flag is set, then type(flag) will return
X# "true"). Absence of a given capability is signalled by procedure
X# failure.
X#
X# igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)!
X# Analogous to tgoto. "Cm" is the cursor movement command for
X# the current terminal, as obtained via getval("cm"). Igoto()
X# returns a string which, when output via iputs, will cause the
X# cursor to move to column "destcol" and line "destline." Column and
X# line are always calculated using a *one* offset. This is far more
X# Iconish than the normal zero offset used by tgoto. If you want to
X# go to the first square on your screen, then include in your program
X# "iputs(igoto(getval("cm"),1,1))."
X#
X# iputs(cp,affcnt)
X# Equivalent to tputs. "Cp" is a string obtained via getval(),
X# or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a
X# count of affected lines. It is only relevant for terminals which
X# specify proportional (starred) delays in their termcap entries.
X#
X# Bugs: I have not tested these routines on terminals that require
X# padding.
X#
X##########################################################################
X#
X# Requires: UNIX, co-expressions
X#
X# See also: iscreen.icn (a set of companion utilities)
X#
X##########################################################################
X
X
Xglobal tc_table, tty_speed
Xrecord true()
X
X
Xprocedure check_features()
X
X local in_params, line
X # global tty_speed
X
X initial {
X find("unix",map(&features)) |
X er("check_features","unix system required",1)
X find("o-expres",&features) |
X er("check_features","co-expressions not implemented - &$#!",1)
X system("/bin/stty tabs") |
X er("check_features","can't set tabs option",1)
X }
X
X # clumsy, clumsy, clumsy, and probably won't work on all systems
X in_params := open("/bin/stty 2>&1","pr") | fail
X every line := !in_params do {
X line ? {
X tab(find("speed")+5) &
X tab(many(' ')) &
X tty_speed := integer(tab(many(&digits)))
X }
X }
X close(in_params)
X return "term characteristics reset; features check out"
X
Xend
X
X
X
Xprocedure setname(name)
X
X # Sets current terminal type to "name" and builds a new termcap
X # capability database (residing in tc_table). Fails if unable to
X # find a termcap entry for terminal type "name." If you want it
X # to terminate with an error message under these circumstances,
X # comment out "| fail" below, and uncomment the er() line.
X
X #tc_table is global
X
X check_features()
X
X tc_table := maketc_table(getentry(name)) | fail
X # er("setname","no termcap entry found for "||name,3)
X return "successfully reset for terminal " || name
X
Xend
X
X
X
Xprocedure getname()
X
X # Getname() first checks to be sure we're running under Unix, and,
X # if so, tries to figure out what the current terminal type is,
X # checking successively the value of the environment variable
X # TERM, and then the output of "tset -". Terminates with an error
X # message if the terminal type cannot be ascertained.
X
X local term, tset_output
X
X check_features()
X
X if not (term := getenv("TERM")) then {
X tset_output := open("/bin/tset -","pr") |
X er("getname","can't find tset command",1)
X term := !tset_output
X close(tset_output)
X }
X return \term |
X er("getname","can't seem to determine your terminal type",1)
X
Xend
X
X
X
Xprocedure er(func,msg,errnum)
X
X # short error processing utility
X write(&errout,func,": ",msg)
X exit(errnum)
X
Xend
X
X
X
Xprocedure getentry(name)
X
X # "Name" designates the current terminal type. Getentry() scans
X # the current environment for the variable TERMCAP. If the
X # TERMCAP string represents a termcap entry for a terminal of type
X # "name," then getentry() returns the TERMCAP string. Otherwise,
X # getentry() will check to see if TERMCAP is a file name. If so,
X # getentry() will scan that file for an entry corresponding to
X # "name." If the TERMCAP string does not designate a filename,
X # getentry() will scan /etc/termcap for the correct entry.
X # Whatever the input file, if an entry for terminal "name" is
X # found, getentry() returns that entry. Otherwise, getentry()
X # fails.
X
X local termcap_string, f, getline, line, nm, ent1, ent2
X
X termcap_string := getenv("TERMCAP")
X
X if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name)
X then return termcap_string
X else {
X
X # The logic here probably isn't clear. The idea is to try to use
X # the termcap environment variable successively as 1) a termcap en-
X # try and then 2) as a termcap file. If neither works, 3) go to
X # the /etc/termcap file. The else clause here does 2 and, if ne-
X # cessary, 3. The "\termcap_string ? (not match..." expression
X # handles 1.
X
X if find("/",\termcap_string)
X then f := open(termcap_string)
X /f := open("/etc/termcap") |
X er("getentry","I can't access your /etc/termcap file",1)
X
X getline := create read_file(f)
X
X while line := @getline do {
X if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
X entry := ""
X while (\line | @getline) ? {
X if entry ||:= 1(tab(find(":")+1), pos(0))
X then {
X close(f)
X # if entry ends in tc= then add in the named tc entry
X entry ?:= tab(find("tc=")) ||
X # recursively fetch the new termcap entry
X (move(3), getentry(tab(find(":"))) ?
X # remove the name field from the new entry
X (tab(find(":")+1), tab(0)))
X return entry
X }
X else {
X \line := &null # must precede the next line
X entry ||:= tab(-2)
X }
X }
X }
X }
X }
X
X close(f)
X er("getentry","can't find and/or process your termcap entry",3)
X
Xend
X
X
X
Xprocedure read_file(f)
X
X # Suspends all non #-initial lines in the file f.
X # Removes leading tabs and spaces from lines before suspending
X # them.
X
X local line
X
X \f | er("read_tcap_file","no valid termcap file found",3)
X while line := read(f) do {
X match("#",line) & next
X line ?:= (tab(many('\t ')) | &null, tab(0))
X suspend line
X }
X
X fail
X
Xend
X
X
X
Xprocedure maketc_table(entry)
X
X # Maketc_table(s) (where s is a valid termcap entry for some
X # terminal-type): Returns a table in which the keys are termcap
X # capability designators, and the values are the entries in
X # "entry" for those designators.
X
X local k, v
X
X /entry & er("maketc_table","no entry given",8)
X if entry[-1] ~== ":" then entry ||:= ":"
X
X tc_table := table()
X
X entry ? {
X
X tab(find(":")+1) # tab past initial (name) field
X
X while tab((find(":")+1) \ 1) ? {
X
X &subject == "" & next
X if k := 1(move(2), ="=")
X then /tc_table[k] := decode(tab(find(":")))
X else if k := 1(move(2), ="#")
X then /tc_table[k] := integer(tab(find(":")))
X else if k := 1(tab(find(":")), pos(-1))
X then /tc_table[k] := true()
X else er("maketc_table", "your termcap file has a bad entry",3)
X &null # in case insertion fails due to duplicate entry
X }
X }
X
X return tc_table
X
Xend
X
X
X
Xprocedure getval(id)
X
X /tc_table := maketc_table(getentry(getname())) |
X er("getval","can't make a table for your terminal",4)
X
X return \tc_table[id] | fail
X # er("getval","the current terminal doesn't support "||id,7)
X
Xend
X
X
X
Xprocedure decode(s)
X
X # Does things like turn ^ plus a letter into a genuine control
X # character.
X
X new_s := ""
X
X s ? {
X while new_s ||:= tab(upto('\\^')) do {
X chr := move(1)
X if chr == "\\" then {
X new_s ||:= {
X case chr2 := move(1) of {
X "\\" : "\\"
X "^" : "^"
X "E" : "\e"
X "b" : "\b"
X "f" : "\f"
X "n" : "\n"
X "r" : "\r"
X "t" : "\t"
X default : {
X if any(&digits,chr2) then {
X char(integer("8r"||chr2||move(2 to 0 by -1))) |
X er("decode","bad termcap entry",3)
X }
X else chr2
X }
X }
X }
X }
X else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
X }
X new_s ||:= tab(0)
X }
X
X return new_s
X
Xend
X
X
X
Xprocedure igoto(cm,col,line)
X
X local colline, range, increment, str, outstr, chr, x, y
X
X if col > (tc_table["co"]) | line > (tc_table["li"]) then {
X colline := string(\col) || "," || string(\line) | string(\col|line)
X range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
X er("igoto",colline || " out of range " || (\range|""),9)
X }
X
X # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
X increment := -1
X outstr := ""
X
X cm ? {
X while outstr ||:= tab(find("%")) do {
X tab(match("%"))
X chr := move(1)
X if case chr of {
X "." : outstr ||:= char(line + increment)
X "+" : outstr ||:= char(line + ord(move(1)) + increment)
X "d" : {
X str := string(line + increment)
X outstr ||:= right(str, integer(tab(any('23'))), "0") | str
X }
X }
X then line :=: col
X else {
X case chr of {
X "n" : line := ixor(line,96) & col := ixor(col,96)
X "i" : increment := 0
X "r" : line :=: col
X "%" : outstr ||:= "%"
X "B" : line := ior(ishift(line / 10, 4), line % 10)
X ">" : {
X x := move(1); y := move(1)
X line > ord(x) & line +:= ord(y)
X &null
X }
X } | er("goto","bad termcap entry",5)
X }
X }
X return outstr || tab(0)
X }
X
Xend
X
X
X
Xprocedure iputs(cp, affcnt)
X
X local baud_rates, char_rates, i, delay, PC
X static num_chars, char_times
X # global tty_speed
X
X initial {
X num_chars := &digits ++ '.'
X char_times := table()
X baud_rates := [0,300,600,1200,1800,2400,4800,9600,19200]
X char_rates := [0,333,166,83,55,41,20,10,5]
X every i := 1 to *baud_rates do {
X char_times[baud_rates[i]] := char_rates[i]
X }
X }
X
X type(cp) == "string" |
X er("iputs","you can't iputs() a non-string value!",10)
X
X cp ? {
X delay := tab(many(num_chars))
X if ="*" then {
X delay *:= \affcnt |
X er("iputs","affected line count missing",6)
X }
X writes(tab(0))
X }
X
X if (\delay, tty_speed ~= 0) then {
X PC := tc_table["pc"] | "\000"
X char_time := char_times[tty_speed] | (return "speed error")
X delay := (delay * char_time) + (char_time / 2)
X every 1 to delay by 10
X do writes(PC)
X }
X
X return
X
Xend
SHAR_EOF
# ============= iscreen.icn ==============
echo "x - extracting iscreen.icn (Text)"
sed 's/^X//' << 'SHAR_EOF' > iscreen.icn &&
X############################################################################
X#
X# Name: iscreen.icn
X#
X# Title: Icon screen functions
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.11
X#
X############################################################################
X#
X# Copyright (c) 1990, Richard L. Goerwitz, III
X#
X# This software is intended for free and unrestricted distribution.
X# I place only two conditions on its use: 1) That you clearly mark
X# any additions or changes you make to the source code, and 2) that
X# you do not delete this message from it. In order to protect
X# myself from spurious litigation, it must also be stated here that,
X# because this is free software, I, Richard Goerwitz, make no claim
X# about the applicability or fitness of this software for any
X# purpose, and disclaim any responsibility for any damages that
X# might be incurred in conjunction with its use.
X#
X############################################################################
X#
X# This file contains some rudimentary screen functions for use with
X# itlib.icn (termlib-like routines for Icon).
X#
X# clear() - clears the screen (tries several methods)
X# emphasize() - initiates emphasized mode
X# normal(mode) - resets to normal mode; if mode is null,
X# or "b," normal() assumes you were in emphasize mode,
X# otherwise you are assumed to have been in underline mode
X# message(s) - displays message s on 2nd-to-last line
X# underline() - initiates underline mode
X# status_line(s,s2,p) - draws status line s on the 3rd-to-last
X# screen line; if s is too short for the terminal, s2 is used;
X# if p is nonnull then it either centers, left-, or right-justi-
X# fies, depending on the value, "c," "l," or "r."
X#
X############################################################################
X#
X# Requires: UNIX
X#
X# Links: itlib.icn (or your OS-specific port of itlib)
X#
X# See also: boldface.icn
X#
X############################################################################
X
X
Xprocedure clear()
X
X # Clears the screen. Tries several methods.
X
X if not iputs(getval("cl"))
X then iputs(igoto(getval("cm"),1,1))
X if not iputs(getval("cd"))
X then {
X every i := 1 to getval("li") do {
X iputs(igoto(getval("cm"),1,i))
X iputs(getval("ce"))
X }
X iputs(igoto(getval("cm"),1,1))
X }
X return
X
Xend
X
X
X
Xprocedure emphasize()
X
X static bold_str, cookie_str
X initial {
X if bold_str := getval("so")
X then cookie_str := repl(getval("bc") | "\b", getval("sg"))
X else {
X if bold_str := getval("us")
X then cookie_str := repl(getval("bc") | "\b", getval("ug"))
X }
X }
X
X iputs(\bold_str)
X iputs(\cookie_str)
X return
X
Xend
X
X
X
Xprocedure underline()
X
X static underline_str, cookie_str
X initial {
X if underline_str := getval("us")
X then cookie_str := repl(getval("bc") | "\b", getval("sg"))
X }
X
X iputs(\underline_str)
X iputs(\cookie_str)
X return
X
Xend
X
X
X
Xprocedure normal(mode)
X
X static UN_bold_str, bold_cookie_str,
X UN_underline_str, underline_cookie_str
X initial {
X
X if UN_bold_str := getval("se") then
X bold_cookie_str := repl(getval("bc") | "\b", getval("sg"))
X else {
X UN_bold_str := getval("ue")
X bold_cookie_str := repl(getval("bc")|"\b", getval("ug"))
X }
X if UN_underline_str := getval("ue") then
X underline_cookie_str := repl(getval("bc")|"\b", getval("ug"))
X }
X
X if /mode | (mode == "b") then {
X iputs(\UN_bold_str)
X iputs(\bold_cookie_str)
X return
X }
X
X iputs(\UN_underline_str)
X iputs(\underline_cookie_str)
X return
X
Xend
X
X
X
Xprocedure status_line(s,s2,p)
X
X # Writes a status line on the terminal's third-to-last line
X # The only necessary argument is s. S2 (optional) is used
X # for extra narrow screens. In other words, by specifying
X # s2 you give status_line an alternate, shorter status string
X # to display, in case the terminal isn't wide enough to sup-
X # port s. If p is nonnull, then the status line is either
X # centered (if equal to "c"), left justified ("l"), or right
X # justified ("r").
X
X local width
X
X /s := ""
X width := getval("co")
X if *s > width then {
X (*s2 < width, s := \s2) |
X er("status_line","Your terminal is too narrow.",4)
X }
X case \p of {
X "c" : s := center(s,width-1)
X "l" : s := left(s,width-1)
X "r" : s := right(s,width-1)
X default: stop("status_line: Unknown option "||string(p),4)
X }
X
X iputs(igoto(getval("cm"), 1, getval("li")-2))
X emphasize(); writes(s); iputs(getval("ce"))
X normal()
X return
X
Xend
X
X
X
Xprocedure message(s)
X
X # Display prompt s on the second-to-last line of the screen.
X # I hate to use the last line, due to all the problems with
X # automatic scrolling.
X
X /s := ""
X normal()
X iputs(igoto(getval("cm"), 1, getval("li")-1))
X writes(s[1:getval("co")] | s)
X iputs(getval("ce"))
X return
X
Xend
SHAR_EOF
# ============= itlibdos.icn ==============
echo "x - extracting itlibdos.icn (Text)"
sed 's/^X//' << 'SHAR_EOF' > itlibdos.icn &&
X########################################################################
X#
X# Name: itlibdos.icn
X#
X# Title: Icon termlib-type tools (MS-DOS version)
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.3
X#
X########################################################################
X#
X# Copyright (c) 1990, Richard L. Goerwitz, III
X#
X# This software is intended for free and unrestricted distribution.
X# I place only two conditions on its use: 1) That you clearly mark
X# any additions or changes you make to the source code, and 2) that
X# you do not delete this message therefrom. In order to protect
X# myself from spurious litigation, it must also be stated here that,
X# because this is free software, I, Richard Goerwitz, make no claim
X# about the applicability or fitness of this software for any
X# purpose, and expressly disclaim any responsibility for any damages
X# that might be incurred in conjunction with its use.
X#
X########################################################################
X#
X# The following library represents a series of rough functional
X# equivalents to the standard Unix low-level termcap routines. They
X# are not meant as exact termlib clones. Nor are they enhanced to
X# take care of magic cookie terminals, terminals that use \D in their
X# termcap entries, or, in short, anything I felt would not affect my
X# normal, day-to-day work with ANSI and vt100 terminals.
X#
X# Requires: An MS-DOS platform & co-expressions. The MS-DOS version
X# is a port of the Unix version. Software you write for this library
X# can be made to run under Unix simply by substituting the Unix ver-
X# sion of this library. See below for additional notes on how to use
X# this MS-DOS port.
X#
X# setname(term)
X# Use only if you wish to initialize itermlib for a terminal
X# other than what your current environment specifies. "Term" is the
X# name of the termcap entry to use. Normally this initialization is
X# done automatically, and need not concern the user.
X#
X# getval(id)
X# Works something like tgetnum, tgetflag, and tgetstr. In the
X# spirit of Icon, all three have been collapsed into one routine.
X# Integer valued caps are returned as integers, strings as strings,
X# and flags as records (if a flag is set, then type(flag) will return
X# "true"). Absence of a given capability is signalled by procedure
X# failure.
X#
X# igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)!
X# Analogous to tgoto. "Cm" is the cursor movement command for
X# the current terminal, as obtained via getval("cm"). Igoto()
X# returns a string which, when output via iputs, will cause the
X# cursor to move to column "destcol" and line "destline." Column and
X# line are always calculated using a *one* offset. This is far more
X# Iconish than the normal zero offset used by tgoto. If you want to
X# go to the first square on your screen, then include in your program
X# "iputs(igoto(getval("cm"),1,1))."
X#
X# iputs(cp,affcnt)
X# Equivalent to tputs. "Cp" is a string obtained via getval(),
X# or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a
X# count of affected lines. It is only relevant for terminals which
X# specify proportional (starred) delays in their termcap entries.
X#
X# Notes on the MS-DOS version:
X# There are two basic reasons for using the I/O routines
X# contained in this package. First, by using a set of generalized
X# routines, your code will become much more readable. Secondly, by
X# using a high level interface, you can avoid the cardinal
X# programming error of hard coding things like screen length and
X# escape codes into your programs.
X# To use this collection of programs, you must do two things.
X# First, you must add the line "device=ansi.sys" (or the name of some
X# other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new
X# nansi.sys]) to your config.sys file. Secondly, you must add two
X# lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2)
X# "set TERMCAP=\location\termcap." The purpose of setting the TERM
X# variable is to tell this program what driver you are using. If you
X# have a color system, use "ansi-color" instead of "ansi-mono," and
X# if you are using nansi or zansi instead of vanilla ansi, use one of
X# these names instead of the "ansi" (e.g. "zansi-mono"). The purpose
X# of setting TERMCAP is to make it possible to determine where the
X# termcap file is located. The termcap file (which should have been
X# packed with this library as termcap.dos) is a short database of all
X# the escape sequences used by the various terminal drivers. Set
X# TERMCAP so that it reflects the location of this file (which should
X# be renamed as termcap, for the sake of consistency with the Unix
X# version). Naturally, you must change "\location\" above to reflect
X# the correct path on your system.
X# Although I make no pretense here of providing here a complete
X# introduction to the format of the termcap database file, it will be
X# useful, I think, to explain a few basic facts about how to use this
X# program in conjunction with it. If, say, you want to clear the
X# screen, add the line,
X#
X# iputs(getval("cl"))
X#
X# to your program. The function iputs() outputs screen control
X# sequences. Getval retrieves a specific sequence from the termcap
X# file. The string "cl" is the symbol used in the termcap file to
X# mark the code used to clear the screen. By executing the
X# expression "iputs(getval("cl"))," you are 1) looking up the "cl"
X# (clear) code in the termcap database entry for your terminal, and
X# the 2) outputting that sequence to the screen.
X# Some other useful termcap symbols are "ce" (clear to end of
X# line), "ho" (go to the top left square on the screen), "so" (begin
X# standout mode), and "se" (end standout mode). To output a
X# boldfaced string, str, to the screen, you would write -
X#
X# iputs(getval("so"))
X# writes(str)
X# iputs(getval("se"))
X#
X# You could write "iputs(getval("so") || str || getval("se")), but
X# this would only work for DOS. Some Unix terminals require padding,
X# and iputs() handles them specially. Normally you should not worry
X# about Unix quirks under DOS. It is in general wise, though, to
X# separate out screen control sequences, and output them via iputs().
X# It is also heartily to be recommended that MS-DOS programmers
X# try not to assume that everyone will be using a 25-line screen.
X# Some terminals are 24-line. Some 43. Some have variable window
X# sizes. If you want to put a status line on, say, the 2nd-to-last
X# line of the screen, then determine what that line is by executing
X# "getval("li")." The termcap database holds not only string-valued
X# sequences, but numeric ones as well. The value of "li" tells you
X# how many lines the terminal has (compare "co," which will tell you
X# how many columns). To go to the beginning of the second-to-last
X# line on the screen, type in:
X#
X# iputs(igoto(getval("cm"), 1, getval("li")-1))
X#
X# The "cm" capability is a special capability, and needs to be output
X# via igoto(cm,x,y), where cm is the sequence telling your computer
X# to move the cursor to a specified spot, x is the column, and y is
X# the row. The expression "getval("li")-1" will return the number of
X# the second-to-last line on your screen.
X#
X##########################################################################
X#
X# Requires: MS-DOS, coexpressions
X#
X# See also: iscreen.icn (a set of companion utilities)
X#
X##########################################################################
X
X
Xglobal tc_table
Xrecord true()
X
X
Xprocedure check_features()
X
X local in_params, line
X # global tty_speed
X
X initial {
X find("ms-dos",map(&features)) |
X er("check_features","unix system required",1)
X find("o-expres",&features) |
X er("check_features","co-expressions not implemented - &$#!",1)
X }
X
X return "term characteristics reset; features check out"
X
Xend
X
X
X
Xprocedure setname(name)
X
X # Sets current terminal type to "name" and builds a new termcap
X # capability database (residing in tc_table). Fails if unable to
X # find a termcap entry for terminal type "name." If you want it
X # to terminate with an error message under these circumstances,
X # comment out "| fail" below, and uncomment the er() line.
X
X #tc_table is global
X
X check_features()
X
X tc_table := maketc_table(getentry(name)) | fail
X # er("setname","no termcap entry found for "||name,3)
X return "successfully reset for terminal " || name
X
Xend
X
X
X
Xprocedure getname()
X
X # Getname() first checks to be sure we're running under DOS, and,
X # if so, tries to figure out what the current terminal type is,
X # checking the value of the environment variable TERM, and if this
X # is unsuccessful, defaulting to "mono."
X
X local term, tset_output
X
X check_features()
X
X if not (term := getenv("TERM")) then {
X tset_output := open("/bin/tset -","pr") |
X er("getname","can't find tset command",1)
X term := !tset_output
X close(tset_output)
X }
X return \term |
X er("getname","can't seem to determine your terminal type",1)
X
Xend
X
X
X
Xprocedure er(func,msg,errnum)
X
X # short error processing utility
X write(&errout,func,": ",msg)
X exit(errnum)
X
Xend
X
X
X
Xprocedure getentry(name)
X
X # "Name" designates the current terminal type. Getentry() scans
X # the current environment for the variable TERMCAP. If the
X # TERMCAP string represents a termcap entry for a terminal of type
X # "name," then getentry() returns the TERMCAP string. Otherwise,
X # getentry() will check to see if TERMCAP is a file name. If so,
X # getentry() will scan that file for an entry corresponding to
X # "name." If the TERMCAP string does not designate a filename,
X # getentry() will look through ./termcap for the correct entry.
X # Whatever the input file, if an entry for terminal "name" is
X # found, getentry() returns that entry. Otherwise, getentry()
X # fails.
X
X local termcap_string, f, getline, line, nm, ent1, ent2
X
X termcap_string := getenv("TERMCAP")
X
X if \termcap_string ? (not match("\\"), pos(0) | tab(find("|")+1), =name)
X then return termcap_string
X else {
X
X # The logic here probably isn't clear. The idea is to try to use
X # the termcap environment variable successively as 1) a termcap en-
X # try and then 2) as a termcap file. If neither works, 3) go to
X # the ./termcap file. The else clause here does 2 and, if ne-
X # cessary, 3. The "\termcap_string ? (not match..." expression
X # handles 1.
X
X if find("\\",\termcap_string)
X then f := open(termcap_string)
X /f := open("termcap") |
X er("getentry","I can't access your termcap file",1)
X
X getline := create read_file(f)
X
X while line := @getline do {
X if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
X entry := ""
X while (\line | @getline) ? {
X if entry ||:= 1(tab(find(":")+1), pos(0))
X then {
X close(f)
X # if entry ends in tc= then add in the named tc entry
X entry ?:= tab(find("tc=")) ||
X # recursively fetch the new termcap entry
X (move(3), getentry(tab(find(":"))) ?
X # remove the name field from the new entry
X (tab(find(":")+1), tab(0)))
X return entry
X }
X else {
X \line := &null # must precede the next line
X entry ||:= tab(-2)
X }
X }
X }
X }
X }
X
X close(f)
X er("getentry","can't find and/or process your termcap entry",3)
X
Xend
X
X
X
Xprocedure read_file(f)
X
X # Suspends all non #-initial lines in the file f.
X # Removes leading tabs and spaces from lines before suspending
X # them.
X
X local line
X
X \f | er("read_tcap_file","no valid termcap file found",3)
X while line := read(f) do {
X match("#",line) & next
X line ?:= (tab(many('\t ')) | &null, tab(0))
X suspend line
X }
X
X fail
X
Xend
X
X
X
Xprocedure maketc_table(entry)
X
X # Maketc_table(s) (where s is a valid termcap entry for some
X # terminal-type): Returns a table in which the keys are termcap
X # capability designators, and the values are the entries in
X # "entry" for those designators.
X
X local k, v
X
X /entry & er("maketc_table","no entry given",8)
X if entry[-1] ~== ":" then entry ||:= ":"
X
X tc_table := table()
X
X entry ? {
X
X tab(find(":")+1) # tab past initial (name) field
X
X while tab((find(":")+1) \ 1) ? {
X
SHAR_EOF
echo "End of part 1"
echo "File itlibdos.icn is continued in part 2"
echo "2" > shar3_seq_.tmp
exit 0
From @mirsa.inria.fr:ol@cerisi.cerisi.Fr Thu Sep 6 05:21:14 1990
Resent-From: @mirsa.inria.fr:ol@cerisi.cerisi.Fr
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA20635; Thu, 6 Sep 90 05:21:14 -0700
Received: from mirsa.inria.fr by Arizona.edu; Thu, 6 Sep 90 05:20 MST
Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP (5.61+++/IDA-1.2.8)
id AB08055; Thu, 6 Sep 90 14:21:25 +0200
Resent-Date: Thu, 6 Sep 90 05:21 MST
Date: Thu, 6 Sep 90 14:18:18 -0100
From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
Subject: true Icon compiler
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <3B3F7FE350AB008050@Arizona.edu>
Message-Id: <9009061221.AB08055@mirsa.inria.fr>
Posted-Date: Thu, 6 Sep 90 14:18:18 -0100
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Recently somebody posted a message about a project on a true Icon
compiler, i.e. a compiler that would infer variable types and could
generate really efficient machine code in most simple cases.
Unfortunately, I can't retrieve the message in my (huge) archives. Could
anybody provide me some further information about this project?
Thanks in advance.
Olivier Lecarme
From icon-group-request@arizona.edu Thu Sep 6 06:14:38 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA21665; Thu, 6 Sep 90 06:14:38 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 6 Sep 90 06:14 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02299; Thu, 6 Sep 90 06:10:28
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 6 Sep 90 06:14 MST
Date: 6 Sep 90 00:07:45 GMT
From: usc!isi.edu!ata.isi.edu!paulp@apple.com
Subject: icon data types on disk
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <3B38113F826B0076B2@Arizona.edu>
Message-Id: <14847@venera.isi.edu>
Organization: USC-Information Sciences Institute
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I'm looking for some routines to write/read icon data types
on disk. The routines would allow a list or a table (or any
icon data type for that matter) to be written out to a disk
file and later read back into an icon variable of the same
type as the original. I suppose each icon variable in the
file would need to be tagged with its type, and a file would
look like a sequence of icon variables of arbitrary types.
Has anyone written something like this?
Thanks in advance,
Paul Postel
From kwalker Thu Sep 6 09:42:02 1990
Resent-From: "Kenneth Walker" <kwalker>
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA00924; Thu, 6 Sep 90 09:42:02 -0700
Received: from megaron (megaron.cs.Arizona.EDU) by Arizona.edu; Thu, 6 Sep 90
09:40 MST
Received: from gacham.cs.arizona.edu by megaron (5.61/15) via SMTP id AA00802;
Thu, 6 Sep 90 09:40:01 -0700
Received: by gacham.cs.arizona.edu; Thu, 6 Sep 90 09:39:57 MST
Resent-Date: Thu, 6 Sep 90 09:41 MST
Date: Thu, 6 Sep 90 09:39:57 MST
From: Kenneth Walker <kwalker@cs.arizona.edu>
Subject: RE: true Icon compiler
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu, ol@cerisi.cerisi.Fr
Resent-Message-Id: <3B1B265CF5AB008118@Arizona.edu>
Message-Id: <9009061639.AA12725@gacham.cs.arizona.edu>
In-Reply-To: <9009061221.AB08055@mirsa.inria.fr>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU, ol@cerisi.cerisi.Fr
> Date: Thu, 6 Sep 90 14:18:18 -0100
> From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
>
> Recently somebody posted a message about a project on a true Icon
> compiler, i.e. a compiler that would infer variable types and could
> generate really efficient machine code in most simple cases.
> Unfortunately, I can't retrieve the message in my (huge) archives. Could
> anybody provide me some further information about this project?
I wrote the compiler as part of my PhD research. It actually generates
C code and uses a C compiler as a back end rather than directly producing
machine code (the basic model for compiling Icon into C was developed
by Janalee O'Bagy as part of her PhD research here a couple years ago). It
does infer the types of variables and produces code that runs faster than
the interpreter. We have not done extensive timings yet, but the benchmark
suite programs runs 1.5 to 3 times faster compiled than interpreted. It is
possible to construct artifical examples that do much better than that.
For instance
procedure main()
local i
every i := 1 to 1000000
end
runs 37 times faster compiled than interpreted (the interpreter does at least
a couple C function calls each time around the loop - the compiled code does
none). However, I'm more interested in what happens with real programs.
We hope to do a Unix distribution of it at some point. However, there
is still work to do: documention, cleaning up the code, and doing a few
ports to local machines. I am currently busy writing a dissertation and
won't even start preparing the compiler for distribution this year.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From tenaglia@mis.mcw.edu Thu Sep 6 20:54:03 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA04936; Thu, 6 Sep 90 20:54:03 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA12071; Thu, 6 Sep 90 21:16:37 EDT
Received: by uwm.edu; id AA23257; Tue, 4 Sep 90 10:35:41 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Tue, 4 Sep 90 09:40:30 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Tue, 4 Sep 90 09:15:30 CDT
Date: Tue, 4 Sep 90 09:15:30 CDT
Message-Id: <0093C34EEBAB3D80.20201524@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: Otherwise
To: icon-group@cs.arizona.edu
Concerning icon language constructs, I was wondering if there is any call
for an 'otherwise' construct. This would be used in a conditional. This idea
is based in part on tri-state logic that is popular in AI products.
if (num/div) > lim
then write("Is true.")
else write("Is false.")
otherwise write("Is unknown or &null or div by 0")
This might be a cleaner way of handling things than messing with the error
count, and could be very handy for development and debugging. Or maybe there's
a more Iconish way of handling it. Any ideas?
Chris Tenaglia (System Manager) | "Eat a good book lately?"
Medical College of Wisconsin | Q to Worf STTNG
8701 W. Watertown Plank Rd. | _
Milwaukee, WI 53226 | ======= -------
(414)257-8765 | \===/===
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From tenaglia@mis.mcw.edu Fri Sep 7 04:10:46 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA12336; Fri, 7 Sep 90 04:10:46 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA22113; Fri, 7 Sep 90 00:43:23 EDT
Received: by uwm.edu; id AA22029; Wed, 5 Sep 90 10:35:39 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Wed, 5 Sep 90 10:05:13 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Wed, 5 Sep 90 09:28:12 CDT
Date: Wed, 5 Sep 90 09:28:12 CDT
Message-Id: <0093C419DC850CC0.204000DB@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: Soliciting Knowledge & Opinions
To: icon-group@cs.arizona.edu
I'm interested in finding out what is possible with ProIcon on the MAC.
I have the serial port of the MAC set up for MODEM or HARDWIRE connection
to a VMS host. I'd like to build a MAC like front end for certain boring
data entry screen. Does ProIcon give me easy access to the comm port?
Thanks,
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From goer@midway.uchicago.edu Mon Sep 10 19:18:45 1990
Resent-From: goer@midway.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA08551; Mon, 10 Sep 90 19:18:45 -0700
Received: from midway.uchicago.edu by Arizona.edu; Mon, 10 Sep 90 19:18 MST
Received: from quads.uchicago.edu (quads.uchicago.edu) by midway.uchicago.edu
Mon, 10 Sep 90 21:18:17 CDT
Resent-Date: Mon, 10 Sep 90 19:18 MST
Date: Mon, 10 Sep 90 21:18:17 CDT
From: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
Subject: snake; getch
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <37A5D65F020B00A2AB@Arizona.edu>
Message-Id: <9009110218.AA03571@midway.uchicago.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I don't want to post it right now, but if anyone wants a Unix implemen-
tation of the getch() and getche() functions, please let me know. I'll
pass it on.
Incidentally, I had a couple of requests for the snake "game" a while
back that I couldn't reply to. For instance, I couldn't seem to get
a reply to a address at ...@damogran.pa.dec.com. Sorry about this. I
don't want to post the game to the group, though. Most of it would
just be a repost of the Icon termlib-like functions I posted a while
back.
-Richard (goer@sophist.uchicago.edu)
From esquire!info8!yost@cmcl2.NYU.EDU Tue Sep 11 07:35:22 1990
Resent-From: esquire!info8!yost@cmcl2.NYU.EDU
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA01642; Tue, 11 Sep 90 07:35:22 -0700
Received: from cmcl2.NYU.EDU (NYU.EDU) by Arizona.edu; Tue, 11 Sep 90 07:34 MST
Received: by cmcl2.NYU.EDU (5.61/1.34) id AA25806; Tue, 11 Sep 90 10:35:12 -0400
Received: from info8 by ESQUIRE.DPW. id aa17499; 11 Sep 90 9:55 EDT
Received: from localhost by info8. (4.0/SMI-4.0) id AA05688; Tue, 11 Sep 90
09:58:48 EDT
Resent-Date: Tue, 11 Sep 90 07:35 MST
Date: Tue, 11 Sep 90 09:58:45 -0400
From: yost@DPW.COM
Subject: RE: snake; getch
Sender: yost@info8.NYU.EDU
Resent-To: icon-group@cs.arizona.edu
To: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
Cc: icon-group@arizona.edu, yost@cmcl2.NYU.EDU
Reply-To: yost@DPW.COM
Resent-Message-Id: <373EF0CA2F0B009A25@Arizona.edu>
Message-Id: <9009111358.AA05688@info8.>
In-Reply-To: Your message of Mon, 10 Sep 90 21:18:17 CDT.
<9009110218.AA03571@midway.uchicago.edu>
Phone: +1 212-266-0796 (Voice Direct Line)
Fax: +1 212-266-0790
Organization: Davis Polk & Wardwell 1 Chase Manhattan Plaza New York, NY 10005
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: "Richard L. Goerwitz" <goer@midway.uchicago.edu>
X-Vms-Cc: icon-group@Arizona.EDU, yost@cmcl2.NYU.EDU
> if anyone wants a Unix implementation of the getch() and getche() functions,
> please let me know.
I was disappointed that they weren't there when I was
writing a unix Icon program recently. You should put
them up for adoption in the distribution.
--dave
yost@dpw.com or uunet!esquire!yost
Please ignore the From or Reply-To fields above, if different.
From R.J.Hare@edinburgh.ac.uk Thu Sep 13 12:29:24 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA18001; Thu, 13 Sep 90 12:29:24 -0700
Received: from UKACRL.BITNET by Arizona.edu; Thu, 13 Sep 90 12:29 MST
Received: from RL.IB by UKACRL.BITNET (Mailer R2.03B) with BSMTP id 3669; Thu,
13 Sep 90 11:37:46 BST
Date: 13 Sep 90 10:28:28 bst
From: R.J.Hare@edinburgh.ac.uk
Subject: Text-processors
To: icon-group@cs.arizona.edu
Message-Id: <13 Sep 90 10:28:28 bst 340970@EMAS-A>
Via: UK.AC.ED.EMAS-A; 13 SEP 90 10:27:32 BST
X-Envelope-To: icon-group@cs.arizona.edu
Some time ago, I saw a request for an Icon version of TeX, either on this bb
or in the newsletter. I don't remember any reply, but I'd now like to pose the
following supplementary questions:
1) has anyone implemented Brian reid's SCRIBE program (or a sub-set) in Icon?
2) has anyone implemented any text-processor of any kind using Icon?
3) Are these programs available?
Thanks.
Roger Hare.
From @mirsa.inria.fr:ol@cerisi.cerisi.Fr Thu Sep 13 23:55:21 1990
Received: from mirsa.inria.fr by megaron (5.61/15) via SMTP
id AA16440; Thu, 13 Sep 90 23:55:21 -0700
Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP
(5.61+++/IDA-1.2.8) id AA12236; Fri, 14 Sep 90 08:57:31 +0200
Message-Id: <9009140657.AA12236@mirsa.inria.fr>
Date: Fri, 14 Sep 90 08:53:58 -0100
Posted-Date: Fri, 14 Sep 90 08:53:58 -0100
From: Lecarme Olivier <ol@cerisi.cerisi.Fr>
To: R.J.Hare@edinburgh.ac.uk
Cc: icon-group@cs.arizona.edu
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>
Subject: Text-processors
I implemented a text-processor in Icon.
From something extremely simple, capable of only some "natural"
pretty-printing, it grown to multiple features including indexes,
several tables of contents, running headings, floating figures, macros
and so on. It has some unusual characteristics, for example hyphenating
algorithms for both English and French, simple handling of French
diacritics, and "natural" heuristics for finding good page breaks.
But it suffers form severe weaknesses presently:
1) it was designed with an Epson LQ printer in mind, and turning it to
generate dvi or Postscript instead would be a major effort (although it
would be easy for another line printer);
2) its growth was not planned in advance, and the last features added
use holes in the coding design;
3) programming it was done in the same manner, and a complete rewriting
would be neeeded for improving performances;
4) its documentation is written in French!
It could be made available, along with its documentation, in a rather
short time, but only on an "as-is" basis, of course. It presently
amounts to about 2500 lines of moderately commented Icon code.
Olivier Lecarme
From tenaglia@mis.mcw.edu Fri Sep 14 07:58:22 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA02582; Fri, 14 Sep 90 07:58:22 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA21045; Fri, 14 Sep 90 10:45:36 EDT
Received: by uwm.edu; id AA01696; Fri, 14 Sep 90 09:38:59 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Fri, 14 Sep 90 09:06:50 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Fri, 14 Sep 90 09:07:45 CDT
Date: Fri, 14 Sep 90 09:07:45 CDT
Message-Id: <0093CB297E710460.202015C5@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: Text Processing
To: icon-group@cs.arizona.edu
We're running ICON 8 on VAX/VMS 5.2. VMS has RUNOFF for generating
documentation, and it has the same general look and feel of unix nroff.
It comes free with VMS as does EVE/TPU.
DECs EVE/TPU is another tool, which is the Extensible Vax Editor,
and Text Processing Utility. It's a programmable editor. The TPU programming
language has many Icon ideas built into it, such as pattern matching,
csets, alternation. The code even has a vaguely iconish appearance. However,
it doesn't have goal oriented processing, generators, and the data types
are very strict. Since it's an editor, the data types are editor oriented
such as buffer, range, process, window, line, pattern. There are also hundreds
of built in functions and global system variables and keywords.
I have a highly customized version of the editor. It does a lot of WYSIWYG
wordprocessor tricks. I have written Icon utilities to do pagination, table
of contents, and indeces on documentation I've written. This allows my
master doc files to be much more human readible than if I coded them in
RUNOFF. For table of contents and indexing I've had to use a little sleight
of hand to have the items I want retrieved match a certain pattern, yet look
unobtrusive.
It's not terribly fancy or postscript, but it's cheap and effective given
our hardware.
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From tenaglia@mis.mcw.edu Sat Sep 15 16:51:26 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA15432; Sat, 15 Sep 90 16:51:26 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA28771; Sat, 15 Sep 90 19:23:05 EDT
Received: by uwm.edu; id AA01766; Sat, 15 Sep 90 09:31:18 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Sat, 15 Sep 90 09:28:52 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Sat, 15 Sep 90 08:48:48 CDT
Date: Sat, 15 Sep 90 08:48:48 CDT
Message-Id: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: UUXXCODE
To: icon-group@cs.arizona.edu
I have some files that I'd like to UUENCODE or UUDECODE. Being on a VMS
system without a C compiler, having the sources still doesn't help. I've
attempted a port to Icon of UUENCODE and UUDECODE. They are close, but not
quite right. Would someone care to look them over and offer suggestions or
corrections? Thanx.
Chris Tenaglia (System Manager) about 160 lines follow
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
------------------- uuencode.icn ---------------------------
##################################################################
# #
# UUENCODE.ICN 09/14/90 BY TENAGLIA #
# #
# UUENCODE BINARY FILES FOR EMAIL TRANSFER #
# #
##################################################################
procedure main(param)
source := param[1] | input("_Source:")
target := param[2] | input("_Target:")
(in := open(source)) | stop("Can't open ",source)
(out := open(target,"w")) | stop("Can't open ",target)
write("\fUUENCODE FROM ",source," TO ",target)
write(out,"begin 0600 ",source)
while line := reads(in,45) do
{
writes(*line,", ")
writes(out,char(*line+32))
every i := 1 to *line by 3 do output(out,line[i+:3])
write(out,"")
}
write(out,"end")
close(in) ; close(out)
end
#
# THIS PROCEDURE TAKES AN OUTPUT FILE PARAMETER AND A 3 BYTE STRING
# OF BINARY DATA. IT WRITES OUT 4 BYTES OF PRINTABLE/MAILABLE ASCII
#
procedure output(fo,str)
c1 := ord(str[1])*4
c2 := ior( iand(ord(str[1])/16,8r060) , iand(ord(str[2])*16,8r017) )
c3 := ior( iand(ord(str[2])/4, 8r074) , iand(ord(str[3])*64,8r003) )
c4 := iand(ord(str[3]),8r077)
writes(fo,char(enc(c1)),
char(enc(c2)),
char(enc(c3)),
char(enc(c4)))
end
#
# ENCRYPTION ASCIIZER ROUTINE
#
procedure enc(n)
return iand(n,8r0077)+32
end
#
# PROMPT AND TAKE AN INPUT
#
procedure input(prompt)
writes(prompt)
return read()
end
----------------------- uudecode.icn ------------------------------
##################################################################
# #
# UUDECODE.ICN 09/14/90 BY TENAGLIA #
# #
# UUDECODE BINARY FILES FOR EMAIL TRANSFER #
# #
##################################################################
procedure main(param)
source := param[1] | input("_Source:")
target := param[2] | input("_Target:")
(in := open(source)) | stop("Can't open ",source)
(out := open(target,"w")) | stop("Can't open ",target)
write("\fUUDECODE FROM ",source," TO ",target)
until match("begin",(line := read(in)))
write("Found ",parse(line,' ')[3])
while line := read(in) do
{
writes(*line,", ")
p := 0
bytes := ord(line[1]) - 32
if bytes = 64 then bytes := 0
if (bytes=0) | match("end",line) then break
count := integer(real(bytes)/3.0 + 0.9) * 4
buf := ""
every i := 2 to count by 4 do
{
x1 := ord(line[i]) - 32
if x1 = 64 then x1 := 0
x2 := ord(line[i+1]) - 32
if x2 = 64 then x2 := 0
x3 := ord(line[i+2]) - 32
if x3 = 64 then x3 := 0
x4 := ord(line[i+3]) - 32
if x4 = 64 then x4 := 0
if p < bytes then
{
p +:= 1
buf ||:= char(x2 / 16 + x1 * 4)
}
if p < bytes then
{
p +:= 1
buf ||:= char(x3 / 4 + (x2 % 16) * 16)
}
if p < bytes then
{
p +:= 1
buf ||:= char(x4 + (x3 % 4) * 64)
}
}
writes(out,buf)
writes("(",*buf,"), ")
}
close(in) ; close(out)
end
#
# PARSE A STRING WITH RESPECT TO A DELIMITER CSET
#
procedure parse(line,delims)
static chars
chars := &cset -- delims
tokens := []
line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
return tokens
end
#
# THIS PROCEDURE TAKES AN OUTPUT FILE PARAMETER AND A 3 BYTE STRING
# OF BINARY DATA. IT WRITES OUT 4 BYTES OF PRINTABLE/MAILABLE ASCII
#
procedure output(fo,str)
c1 := ord(str[1])*4
c2 := ior( iand(ord(str[1])/16,8r060) , iand(ord(str[2])*16,8r017) )
c3 := ior( iand(ord(str[2])/4, 8r074) , iand(ord(str[3])*64,8r003) )
c4 := iand(ord(str[3]),8r077)
writes(fo,char(enc(c1)),
char(enc(c2)),
char(enc(c3)),
char(enc(c4)))
end
#
# ENCRYPTION ASCIIZER ROUTINE
#
procedure enc(n)
return iand(n,8r0077)+32
end
#
# PROMPT AND TAKE AN INPUT
#
procedure input(prompt)
writes(prompt)
return read()
end
From icon-group-request@arizona.edu Tue Sep 18 10:58:43 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA07385; Tue, 18 Sep 90 10:58:43 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 18 Sep 90 10:58 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA01144; Tue, 18 Sep 90
10:46:55 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 18 Sep 90 10:58 MST
Date: 18 Sep 90 16:13:58 GMT
From: esquire!yost@nyu.edu
Subject: RE: UUXXCODE
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <31A25DEB912B00C636@Arizona.edu>
Message-Id: <2665@esquire.dpw.com>
Organization: Davis Polk & Wardwell
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
In article <0093CBF0039A4D60.20400E83@mis.mcw.edu> tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
>
>I've attempted a port to Icon of UUENCODE and UUDECODE.
Now there's a couple of programs I bet are really slow in Icon.
I'd love to see how fast they run with the Icon compiler,
compared to the interpreter and compared to the original
C version.
If the compiler can really do a good job on this sort of repetitive
low-level stuff that kills Icon performance, it would be the dawning
of a new day! Imagine: we could use Icon instead of C for everything!
Ken, can we see a benchmark on this?
--dave yost
yost@dpw.com or uunet!esquire!yost
Please don't use other mangled forms you may see
in the From or Reply-To fields above.
From cargo@cherry.cray.com Tue Sep 18 11:11:21 1990
Received: from timbuk.CRAY.COM by megaron (5.61/15) via SMTP
id AA08371; Tue, 18 Sep 90 11:11:21 -0700
Received: from cherry04.cray.com by timbuk.CRAY.COM (4.1/SMI4.0 CRAY1.1)
id AA11239; Tue, 18 Sep 90 13:11:16 CDT
Received: by cherry04.cray.com
id AA15953; 4.1/CRI-3.21; Tue, 18 Sep 90 13:11:11 CDT
Date: Tue, 18 Sep 90 13:11:11 CDT
From: cargo@cherry.cray.com (David S. Cargo)
Message-Id: <9009181811.AA15953@cherry04.cray.com>
To: icon-group@cs.arizona.edu
Subject: ProIcon review
I was in my company library over lunch and happened to see that
the September issue of Computer Language had a review of ProIcon 1.0
in it (page 102). The reviewer was not pleased with ProIcon's help
system nor with some of the error messages, but otherwise seemed
to look favorably on ProIcon.
David S. Cargo (cargo@cray.com)
From @mirsa.inria.fr:ol@taloa.unice.fr Tue Sep 18 12:27:30 1990
Received: from mirsa.inria.fr by megaron (5.61/15) via SMTP
id AA12050; Tue, 18 Sep 90 12:27:30 -0700
Received: from taloa.unice.fr by mirsa.inria.fr with SMTP
(5.61+++/IDA-1.2.8) id AA10446; Tue, 18 Sep 90 21:28:25 +0200
Received: by taloa.unice.fr, Tue, 18 Sep 90 21:26:31 +0200
Date: Tue, 18 Sep 90 21:26:31 +0200
From: Olivier Lecarme <ol@taloa.unice.fr>
Message-Id: <9009181926.AA04451@taloa.unice.fr>
To: icon-group@cs.arizona.edu
Subject: simple test
This is is only a test for a new mail path. Please ignore this message.
Olivier Lecarme
From icon-group-request@arizona.edu Tue Sep 18 15:43:43 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA21667; Tue, 18 Sep 90 15:43:43 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 18 Sep 90 15:43 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA08895; Tue, 18 Sep 90
15:36:57 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 18 Sep 90 15:43 MST
Date: 18 Sep 90 21:17:43 GMT
From: midway!quads.uchicago.edu!goer@handies.ucar.edu
Subject: RE: ProIcon review
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <317A8EA88DEB00D42A@Arizona.edu>
Message-Id: <1990Sep18.211743.23537@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <9009181811.AA15953@cherry04.cray.com>
Cargo@CHERRY.CRAY.COM (David S. Cargo) writes:
>I was in my company library over lunch and happened to see that
>the September issue of Computer Language had a review of ProIcon 1.0
>in it (page 102). The reviewer was not pleased with ProIcon's help
>system nor with some of the error messages...
I wonder: Did he seem to understand the history and purpose of the
Icon programming language, or was the reviewer new to Icon as well
as ProIcon?
-Richard
From kwalker Wed Sep 19 15:22:43 1990
Received: from gacham.cs.arizona.edu by megaron (5.61/15) via SMTP
id AA22050; Wed, 19 Sep 90 15:22:43 -0700
Date: Wed, 19 Sep 90 15:22:40 MST
From: "Kenneth Walker" <kwalker>
Message-Id: <9009192222.AA24483@gacham.cs.arizona.edu>
Received: by gacham.cs.arizona.edu; Wed, 19 Sep 90 15:22:40 MST
To: icon-group
Subject: RE: UUXXCODE
Date: 18 Sep 90 16:13:58 GMT
From: esquire!yost@nyu.edu
In article <0093CBF0039A4D60.20400E83@mis.mcw.edu> tenaglia@mis.mcw.edu
("Chris Tenaglia - 257-8765") writes:
>
>I've attempted a port to Icon of UUENCODE and UUDECODE.
Now there's a couple of programs I bet are really slow in Icon.
I'd love to see how fast they run with the Icon compiler,
compared to the interpreter and compared to the original
C version.
If the compiler can really do a good job on this sort of repetitive
low-level stuff that kills Icon performance, it would be the dawning
of a new day! Imagine: we could use Icon instead of C for everything!
Ken, can we see a benchmark on this?
I tried 3 runs of each program using the Unix time command and got a range
of results. The uuencode.icn I used has a fix that is not in the version
Chris posted. I also removed the write() expressions that print the number
of bytes in each group processed.
uuencode:
compiled is 4.0 - 5.8 times faster than interpreted
system version is 21 - 40 times faster than compiled
uudecode
compiled is 2.4 - 2.9 times faster than interpreted
system version is 22 - 36 times faster than compiled
While the time command is clearly not a very accurate measure of program
speed (I used the same data on all 3 runs), it does give a feeling
for how much the compiler improves speed and how much work is left to
do to get programs like these to run as fast as those coded in C.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From icon-group-request@arizona.edu Wed Sep 19 17:46:51 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA00568; Wed, 19 Sep 90 17:46:51 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 19 Sep 90 17:46 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13509; Wed, 19 Sep 90
17:34:02 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 19 Sep 90 17:46 MST
Date: 20 Sep 90 00:18:28 GMT
From: sdd.hp.com!zaphod.mps.ohio-state.edu!uwm.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@ucsd.edu
Subject: RE: UUXXCODE
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <30A03110C10B00D8CD@Arizona.edu>
Message-Id: <1990Sep20.001828.10951@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <9009192222.AA24483@gacham.cs.arizona.edu>
Kwalker@CS.ARIZONA.EDU ("Kenneth Walker") writes:
>
> uuencode:
> compiled is 4.0 - 5.8 times faster than interpreted
> system version is 21 - 40 times faster than compiled
>
> uudecode
> compiled is 2.4 - 2.9 times faster than interpreted
> system version is 22 - 36 times faster than compiled
>
>While the time command is clearly not a very accurate measure of program
>speed (I used the same data on all 3 runs), it does give a feeling
>for how much the compiler improves speed and how much work is left to
>do to get programs like these to run as fast as those coded in C.
For short programs like this, it would probably be better to use C.
The real advantage of using Icon is in how it speeds up development
time, and aids program maintenance by simply cutting down on the amount
and complexity of the code.
I guess what I'm trying to say is that getting a two to five-fold
speed increase looks pretty good to people like me who can only think
with horror about what some of our programs would look like - or how
hard it would be to write/maintain them - if they had to be done in
C.
Don't be too deferential about the gap between compiled Icon and C.
What you and Janalee have done is terriffic.
-Richard
From icon-group-request@arizona.edu Wed Sep 19 23:17:32 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA16249; Wed, 19 Sep 90 23:17:32 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 19 Sep 90 23:16 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19555; Wed, 19 Sep 90
23:14:17 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 19 Sep 90 23:17 MST
Date: 20 Sep 90 04:34:09 GMT
From: midway!quads.uchicago.edu!goer@handies.ucar.edu
Subject: RE: UUXXCODE
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <30720032018B00E529@Arizona.edu>
Message-Id: <1990Sep20.043409.14256@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
############################################################################
#
# Name: iidecode.icn
#
# Title: iidecode (port of the Unix/C uudecode program to Icon)
#
# Author: Richard L. Goerwitz
#
# Version: 1.2
#
############################################################################
#
# This is an Icon port of the Unix/C uudecode utility. Since
# uudecode is publicly distributable BSD code, I simply grabbed a
# copy, and rewrote it in Icon. The only basic functional change I
# made to the program was to simplify the notion of file mode.
# Everything is encodedwith 0644 permissions. Operating systems
# differ so widely in how they handle this sort of thing that I
# decided just not to worry about it.
#
# Usage is the same as the Unix uudecode command, i.e. a first
# (optional) argument gives the name the file to be decoded. If this
# is omitted, iidecode just uses the standard input:
#
# iidecode [infile] remotefilename
#
# Even people who do not customarily use Unix should be aware of
# the uuen/decode program and file format. It is widely used, and has
# been implemented on a wide variety of machines for sending 8-bit
# "binaries" through networks designed for ASCII transfers only.
#
# BUGS: Slow. I decided to go for clarity and symmetry, rather than
# speed, and so opted to do things like use ishift(i,j) instead of
# straight multiplication (which under Icon v8 is much faster).
#
############################################################################
#
# See also: iiencode.icn
#
############################################################################
procedure main(a)
local in, filename, dest
# optional 1st (and only) argument
if *a = 1 then {
filename := pop(a)
if not (in := open(filename, "r")) then {
write(&errout,"Can't open ",a[1],".")
exit(1)
}
}
else in := &input
if *a ~= 0 then {
write(&errout,"Usage: iidecode [infile] remotefile")
exit (2)
}
# Find the "begin" line, and determine the destination file name.
!in ? {
tab(match("begin ")) &
tab(many(&digits)) & # mode ignored
tab(many(' ')) &
dest := tab(0)
}
# If dest is null, the begin line either isn't present, or is
# corrupt (which necessitates our aborting with an error msg.).
if /dest then {
write(&errout,"No begin line.")
exit(3)
}
# Tilde expansion is heavily Unix dependent, and we can't always
# safely write the file to the current directory. Our only choice
# is to abort.
if match("~",dest) then {
write(&errout,"Please remove ~ from input file begin line.")
exit(4)
}
out := open(dest, "w")
decode(in, out) # decode checks for "end" line
if not match("end", !in) then {
write(&errout,"No end line.\n")
exit(5)
}
exit(0)
end
procedure decode(in, out)
# Copy from in to out, decoding as you go along.
local line, chunk
while line := read(in) do {
if *line = 0 then {
write(&errout,"Short file.\n")
exit(10)
}
line ? {
n := DEC(ord(move(1)))
# Uuencode signals the end of the coded text by a space
# and a line (i.e. a zero-length line, coded as a space).
if n <= 0 then break
while (n > 0) do {
chunk := move(4) | tab(0)
outdec(chunk, out, n)
n -:= 3
}
}
}
return
end
procedure outdec(s, f, n)
# Output a group of 3 bytes (4 input characters). N is used to
# tell us not to output all of the chars at the end of the file.
local c1, c2, c3
c1 := iand(
ior(
ishift(DEC(ord(s[1])),+2),
ishift(DEC(ord(s[2])),-4)
),
8r0377)
c2 := iand(
ior(
ishift(DEC(ord(s[2])),+4),
ishift(DEC(ord(s[3])),-2)
),
8r0377)
c3 := iand(
ior(
ishift(DEC(ord(s[3])),+6),
DEC(ord(s[4]))
),
8r0377)
if (n >= 1) then
writes(f,char(c1))
if (n >= 2) then
writes(f,char(c2))
if (n >= 3) then
writes(f,char(c3))
end
procedure DEC(c)
# single character decode
return iand(c - 32, 8r077)
end
From icon-group-request@arizona.edu Wed Sep 19 23:17:47 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA16258; Wed, 19 Sep 90 23:17:47 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 19 Sep 90 23:17 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19538; Wed, 19 Sep 90
23:13:29 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 19 Sep 90 23:17 MST
Date: 20 Sep 90 04:32:20 GMT
From: maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@uunet.uu.net
Subject: RE: UUXXCODE
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <3071F6AA202B00DD2A@Arizona.edu>
Message-Id: <1990Sep20.043220.14195@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <0093CBF0039A4D60.20400E83@mis.mcw.edu>
Tenaglia@mis.mcw.edu ("Chris Tenaglia") writes:
>
>I have some files that I'd like to UUENCODE or UUDECODE. Being on a VMS
>system without a C compiler, having the sources still doesn't help. I've
>attempted a port to Icon of UUENCODE and UUDECODE. They are close, but not
>quite right. Would someone care to look them over and offer suggestions or
>corrections?
No C compiler? How do you exist? :-)
Here are a couple of Icon uuXXcode functions. They should be pretty much
compatible with the latest BSD version. Notes are offered on how to make
them work the same as the "old" version, though the two versions are com-
patible.
I guess I'll post uuencode first (I call it iiencode). Iidecode will come
in a subsequent posting.
-Richard
############################################################################
#
# Name: iiencode.icn
#
# Title: iiencode (port of the Unix/C uuencode program to Icon)
#
# Author: Richard L. Goerwitz
#
# Version: 1.2
#
############################################################################
#
# This is an Icon port of the Unix/C uuencode utility. Since
# uuencode is publicly distributable BSD code, I simply grabbed a
# copy, and rewrote it in Icon. The only basic functional change I
# made to the program was to simplify the notion of file mode.
# Everything is encoded with 0644 permissions. Operating systems
# differ so widely in how they handle this sort of thing that I
# decided just not to worry about it.
#
# Usage is the same as the Unix uuencode command, i.e. a first
# (optional) argument gives the name the file to be encoded. If this
# is omitted, iiencode just uses the standard input. The second and
# final argument gives the name the encoded file should be given when
# it is ultimately decoded:
#
# iiencode [infile] remotefilename
#
# BUGS: Slow. I decided to go for clarity and symmetry, rather than
# speed, and so opted to do things like use ishift(i,j) instead of
# straight multiplication (which under Icon v8 is much faster). Note
# that I followed the format of the newest BSD release, which refuses
# to output spaces. If you want to change things back around so that
# spaces are output, look for the string "BSD" in my comments, and
# then (un)comment the appropriate sections of code.
#
############################################################################
#
# See also: iidecode.icn
#
############################################################################
procedure main(a)
local in, filename
# optional 1st argument
if *a = 2 then {
filename := pop(a)
if not (in := open(filename, "r")) then {
write(&errout,"Can't open ",a[1],".")
exit(1)
}
}
else in := &input
if *a ~= 1 then {
write(&errout,"Usage: iiencode [infile] remotefile")
exit (2)
}
# This generic version of uuencode treats file modes in a primitive
# manner so as to be usable in a number of environments. Please
# don't get fancy and change this unless you plan on keeping your
# modified version on-site (or else modifying the code in such a
# way as to avoid dependence on a specific operating system).
writes("begin 644 ",a[1],"\n")
encode(in)
writes("end\n")
exit(0)
end
procedure encode(in)
# Copy from in to standard output, encoding as you go along.
local line
# 1 (up to) 45 character segment
while line := reads(in, 45) do {
writes(ENC(*line))
line ? {
while outdec(move(3))
pos(0) | outdec(left(tab(0), 3, " "))
}
writes("\n")
}
# Uuencode adds a space and newline here, which is decoded later
# as a zero-length line (signals the end of the decoded text).
# writes(" \n")
# The new BSD code (compatible with the old) avoids outputting
# spaces by writing a ` (see also how it handles ENC() below).
writes("`\n")
end
procedure outdec(s)
# Output one group of 3 bytes (s) to standard output. This is one
# case where C is actually more elegant than Icon. Note well!
local c1, c2, c3, c4
c1 := ishift(ord(s[1]),-2)
c2 := ior(iand(ishift(ord(s[1]),+4), 8r060),
iand(ishift(ord(s[2]),-4), 8r017))
c3 := ior(iand(ishift(ord(s[2]),+2), 8r074),
iand(ishift(ord(s[3]),-6), 8r003))
c4 := iand(ord(s[3]),8r077)
every writes(ENC(c1 | c2 | c3 | c4))
return
end
procedure ENC(c)
# ENC is the basic 1 character encoding procedure to make a char
# printing.
# New BSD code doesn't output spaces...
return " " ~== char(iand(c, 8r077) + 32) | "`"
# ...the way the old code does:
# return char(iand(c, 8r077) + 32)
end
From R.J.Hare@edinburgh.ac.uk Fri Sep 21 00:45:18 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA13858; Fri, 21 Sep 90 00:45:18 -0700
Received: from UKACRL.BITNET by Arizona.edu; Fri, 21 Sep 90 00:45 MST
Received: from RL.IB by UKACRL.BITNET (Mailer R2.03B) with BSMTP id 9946; Fri,
21 Sep 90 08:33:35 BST
Date: 21 Sep 90 08:34:30 bst
From: R.J.Hare@edinburgh.ac.uk
Subject: Genealogy
To: icon-group@cs.arizona.edu
Message-Id: <21 Sep 90 08:34:30 bst 340090@EMAS-A>
Via: UK.AC.ED.EMAS-A; 21 SEP 90 8:33:33 BST
X-Envelope-To: icon-group@cs.arizona.edu
Does anyone know of an Icon program which organises family trees please?
Thanks.
Roger Hare.
From tenaglia@mis.mcw.edu Fri Sep 21 03:20:59 1990
Received: from rutgers.edu by megaron (5.61/15) via SMTP
id AA21449; Fri, 21 Sep 90 03:20:59 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA15499; Fri, 21 Sep 90 00:03:59 EDT
Received: by uwm.edu; id AA24276; Thu, 20 Sep 90 09:34:56 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Thu, 20 Sep 90 09:19:48 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Thu, 20 Sep 90 09:21:14 CDT
Date: Thu, 20 Sep 90 09:21:14 CDT
Message-Id: <0093CFE25F8CFBE0.20401477@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: UUXXCODE
To: icon-group@cs.arizona.edu
I'd like to thank Ken Walker for his corrective advice in getting the
uuencode fixed. Apparently the uudecode was ok. Thanks also for the
alternative iiencode/iidecode. It sure generated a stir. I was looking
for a little unix-like functionality, but it seems to be of great
interest to benchmarkers too. The uudecode is probably a pretty shabby
example, since I converted it almost literally from a PC BASIC program.
For VMS folks, uuencode and uudecode are nifty ways of converted binary
data to printable/mailable ascii and back again. It expands 3 binary
bytes into 4 printable bytes. This 33% increase is more compact than
vms dump data. Unfortunately vms has oodles of file types, and not all
will work. VMS Executables (.EXE) will compress and decompress just fine.
Icon executables work too (.ICX). Object files (.OBJ) won't work at all.
Text files almost work. Sometimes there is a little trailing garbage on
the end of the file (or is that a bug in my program?)
Is there any interest in a reposting of the finished programs?
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From goer%sophist@gargoyle.uchicago.edu Sun Sep 23 21:47:48 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA22685; Sun, 23 Sep 90 21:47:48 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Sun, 23 Sep 90 21:47 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA04285; Sun, 23 Sep 90 23:47:21 199
Received: by sophist (4.1/UofC3.1X) id AA09126; Sun, 23 Sep 90 23:51:31 CDT
Resent-Date: Sun, 23 Sep 90 21:47 MST
Date: Sun, 23 Sep 90 23:51:31 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: ms-dos *.*
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2D59DB1BF6AB010EA2@Arizona.edu>
Message-Id: <9009240451.AA09126@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I recall some years ago reading a posting in which someone
included an MS-DOS function which returns a wild-card based
directory listing from within Icon.
I wonder whether this is still available anywhere.
In fact, I wonder in general how people using systems with-
out pipes get a directory listing from within Icon. Under
Unix, I can simply read a pipe from /bin/ls. How do peo-
ple using Macs do this, say? Others?
-Richard
From icon-group-request@arizona.edu Mon Sep 24 08:59:43 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA16955; Mon, 24 Sep 90 08:59:43 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 08:59 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09635; Mon, 24 Sep 90
08:46:03 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Mon, 24 Sep 90 08:59 MST
Date: 24 Sep 90 15:42:51 GMT
From: boutell@louie.udel.edu
Subject: Babe in the Woods
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2CFC035FAB6B0110A2@Arizona.edu>
Message-Id: <31372@nigel.ee.udel.edu>
Organization: University of Delaware -- ACIT Sun Lab
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I've been keeping an eye on this group out of rabid curiosity, but have
yet to see an general information posting, so forgive the waste of
bandwidth: what is icon? Is it a publicly available language? Does its
name imply that it is a GUI- based language? I gathered this impression
from a few ads seen long, LONG ago.
i've seen mention of an MSDOS version, so I can't restrain my curiosity
any longer. Please enlighten!
--
What do you want from the fish of the fish that you fished when you fished
for the fish that you fished? How many numchuks could Chuck chuck if Chuck
could chuck numchuks? boutell@freezer.it.udel.edu? Or 27.598234821? Or not?
From kwalker Mon Sep 24 09:28:29 1990
Resent-From: "Kenneth Walker" <kwalker>
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA19170; Mon, 24 Sep 90 09:28:29 -0700
Received: from megaron.cs.Arizona.EDU by Arizona.edu; Mon, 24 Sep 90 09:27 MST
Received: from gacham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via
SMTP id AA19140; Mon, 24 Sep 90 09:27:32 -0700
Received: by gacham.cs.arizona.edu; Mon, 24 Sep 90 09:27:29 MST
Resent-Date: Mon, 24 Sep 90 09:28 MST
Date: Mon, 24 Sep 90 09:27:29 MST
From: Kenneth Walker <kwalker@cs.arizona.edu>
Subject: RE: Babe in the Woods
Resent-To: icon-group@cs.arizona.edu
To: boutell@louie.udel.edu, icon-group@arizona.edu
Resent-Message-Id: <2CF80085D44B011122@Arizona.edu>
Message-Id: <9009241627.AA09502@gacham.cs.arizona.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: boutell@louie.udel.edu, icon-group@Arizona.EDU
Date: 24 Sep 90 15:42:51 GMT
From: boutell@louie.udel.edu
I've been keeping an eye on this group out of rabid curiosity, but have
yet to see an general information posting, so forgive the waste of
bandwidth: what is icon? Is it a publicly available language? Does its
name imply that it is a GUI- based language? I gathered this impression
from a few ads seen long, LONG ago.
i've seen mention of an MSDOS version, so I can't restrain my curiosity
any longer. Please enlighten!
Icon is not a GUI-based language. The name Icon was affixed to the language
before the usage of the term icon to mean a pictograph became popular. It has
been a while since I posted my standard reply to the question "what is Icon",
so here it is.
Icon is a high level programming language designed for string processing
and other non-numeric applications (numeric processing can be done, but the
language and implementation are not tuned for it). Goal-directed evaluation
with control backtracking is an integral part of the language. However,
Icon is very different from other languages, such as Prolog, which use
this evaluation scheme. Icon has a rich set of control structures which
use and control backtracking. Most of these control structures look and
act very much like the control structures of more traditional languages,
allowing Pascal-like programming where the full power of goal-directed
evaluation is not required. Icon incorporates generators as a natural feature
within this goal-directed evaluation scheme.
Icon has a flexible run-time type system: variables may take on values of
any type and automatic type conversions are performed as needed by
operations. There are a variety of types including strings, sets, associative
tables, and lists with positional, queue, and stack access methods. All
storage management is automatic; garbage collection is performed as needed.
Icon is available for many system: Amiga, Atari, CMS, MS-DOS, MVS,
Macintosh, OS/2, most Unix systems, and VMS. All the versions that the
Icon Project distribute are in the public domain, except for MS-DOS/386
executables which use a commercial DOS extender (the regular MS-DOS
distribution is public domain). The Macintosh version we distribute runs
only under MPW. There is a commercial Mac version that runs stand-alone.
If you want information on obtaining Icon, let me know.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From icon-group-request@arizona.edu Mon Sep 24 11:30:08 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA25062; Mon, 24 Sep 90 11:30:08 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 11:29 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13436; Mon, 24 Sep 90
11:16:48 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Mon, 24 Sep 90 11:29 MST
Date: 24 Sep 90 17:48:07 GMT
From: jarthur!elroy.jpl.nasa.gov!suned1!zaft@uunet.uu.net
Subject: RE: Babe in the Woods (long)
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2CE6FC3BDE4B01081E@Arizona.edu>
Message-Id: <5472@suned1.Nswses.Navy.MIL>
Organization: NSWSES, Port Hueneme, CA
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <31372@nigel.ee.udel.edu>
In article <31372@nigel.ee.udel.edu> boutell@freezer.it.udel.edu (Tom Boutell) writes:
>I've been keeping an eye on this group out of rabid curiosity, but have
>yet to see an general information posting, so forgive the waste of
>bandwidth: what is icon? Is it a publicly available language? Does its
>name imply that it is a GUI- based language? I gathered this impression
>from a few ads seen long, LONG ago.
>
>i've seen mention of an MSDOS version, so I can't restrain my curiosity
>any longer. Please enlighten!
Quoted from "The Icon Programming Language", by Griswold & Griswold.
"Icon is a high-level, general-purpose programming language that
contains many features for processing nonnumeric data, particularly
for textual material consisting of strings of characters. Icon was
designed to aid in analyzing natural languages, reformatting data,
transforming computer programs, generating computer programs,
manipulating formaulas, formatting documents, and so forth. IT
is suited to situations where a quick solution is needed, one
that can be obtained with a minimum of time and programming effort.
Icon is extremely useful for 'one-shot' programs and for
speculative efforts such as computer-generated poetry, in which a
proposed problem solution is more heuristic than algorithmic."
End quote.
Icon is available for free, since it was written with
support of the NSF. Icon was originally written by Ralph Griswold,
and a cast of thousands at the University of Arizona (my alma mater!).
Ralph Griswold, you may remember, was part of the team that developed
SNOBOL.
Ports of Icon are available for most Unix machines, as well
as MS-DOS, VMS, and Macintosh (I believe the Macintosh version is
not available from UA but is a commercial project).
You can get more information by writing:
Icon Project
Department of Computer Science
University of Arizona
Tucson, AZ 85721
(602) 621-6613 (phone # is as of 1983 & may be different).
I think you may also be able to anon. ftp stuff from UA,
also, but I don't know the address.
The definitive book is
The Icon Programming Language
Ralph E. Griswold & Madge T. Griswold, Prentice-Hall, 1983.
ISBN 0-13-449777-5.
I believe an updated book is on the way but I don't know if
it's been released yet. The book describes version 5; the current
release is version 8.
Hope this answers your questions.A
A
A
A
A
A
--
+ Gordon Zaft | zaft@suned1.nswses.navy.mil +
+ NSWSES, Code 4Y33 | suned1!zaft@elroy.jpl.nasa.gov +
+ Port Hueneme, CA 93043-5007 | Phone: (805) 982-0684 FAX: 982-8768 +
++++ Ubi caritas et amor, Deus ibi est.++++
From icon-group-request@arizona.edu Mon Sep 24 13:00:42 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA29245; Mon, 24 Sep 90 13:00:42 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 12:59 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA16093; Mon, 24 Sep 90
12:56:25 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Mon, 24 Sep 90 13:00 MST
Date: 24 Sep 90 19:33:18 GMT
From: mephisto!prism!sun13!sun8.scri.fsu.edu!nall@rutgers.edu
Subject: RE: Babe in the Woods (long)
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2CDA5D1A118B010C25@Arizona.edu>
Message-Id: <763@sun13.scri.fsu.edu>
Organization: Florida State University Computing Center
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <31372@nigel.ee.udel.edu>, <5472@suned1.Nswses.Navy.MIL>
In article <5472@suned1.Nswses.Navy.MIL> zaft@nswses.navy.mil (Gordon C Zaft) writes:
>In article <31372@nigel.ee.udel.edu> boutell@freezer.it.udel.edu (Tom Boutell) writes:
>>I've been keeping an eye on this group out of rabid curiosity, but have
>>yet to see an general information posting, so forgive the waste of
>>bandwidth: what is icon? Is it a publicly available language? Does its
[more deleted...]
>
[lots of good info deleted, for brevity...]
>
> I think you may also be able to anon. ftp stuff from UA,
>also, but I don't know the address.
I picked up up with ftp several months ago. The address at that time
was cs.arizona.edu [128.196.128.118]
>
> The definitive book is
>
> The Icon Programming Language
> Ralph E. Griswold & Madge T. Griswold, Prentice-Hall, 1983.
> ISBN 0-13-449777-5.
>
> I believe an updated book is on the way but I don't know if
>it's been released yet. The book describes version 5; the current
>release is version 8.
The new book is same title, but Second Edition. Same publisher,
1990, ISBN 0-13-447889-4. Describes Version 8.
> Hope this answers your questions.A
Ditto for the additional answers. By the way, I think that I
heard somewhere that Version 8 is NOT running under MS-DOS, but have
not had that confirmed. Anyone know??
>--
>+ Gordon Zaft | zaft@suned1.nswses.navy.mil +
>+ NSWSES, Code 4Y33 | suned1!zaft@elroy.jpl.nasa.gov +
>+ Port Hueneme, CA 93043-5007 | Phone: (805) 982-0684 FAX: 982-8768 +
> ++++ Ubi caritas et amor, Deus ibi est.++++
--
John W. Nall | Supercomputation Computations Research Institute
nall@sun8.scri.fsu.edu | Florida State University, Tallahassee, FL 32306
"Real programmers can write assembly code in any language." - Larry Wall
From kwalker Mon Sep 24 13:53:39 1990
Received: from gacham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA02095; Mon, 24 Sep 90 13:53:39 -0700
Date: Mon, 24 Sep 90 13:53:36 MST
From: "Kenneth Walker" <kwalker>
Message-Id: <9009242053.AA10155@gacham.cs.arizona.edu>
Received: by gacham.cs.arizona.edu; Mon, 24 Sep 90 13:53:36 MST
To: icon-group
Subject: RE: Babe in the Woods (long)
Date: 24 Sep 90 19:33:18 GMT
From: mephisto!prism!sun13!sun8.scri.fsu.edu!nall@rutgers.edu
By the way, I think that I
heard somewhere that Version 8 is NOT running under MS-DOS, but have
not had that confirmed. Anyone know??
Version 8 of Icon does run under MS-DOS. However, it is recommended that
you have at least 500k of free RAM; Icon uses a lot of memory.
Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
+1 602 621-4324 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker
From tenaglia@mis.mcw.edu Mon Sep 24 15:44:01 1990
Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA07826; Mon, 24 Sep 90 15:44:01 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA07031; Mon, 24 Sep 90 18:19:11 EDT
Received: by uwm.edu; id AA04145; Mon, 24 Sep 90 17:05:42 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Mon, 24 Sep 90 13:42:42 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Mon, 24 Sep 90 13:41:09 CDT
Date: Mon, 24 Sep 90 13:41:09 CDT
Message-Id: <0093D32B5856BB80.204002AD@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: Icon pipes in MSDOS
To: icon-group@cs.arizona.edu
MSDOS does have pipes, but they're implemented differently than unix. MSDOS
does it by generating scratch files. One can actually do a DIR|SORT or
DIR | ICONX PROG. Inside icon one can issue system("dir >_dir.tmp") and
then infile:=open("_dir.tmp") for subsequent processing. It also uses a
little more memory when using the system command.
I'd sure like to know how the MAC does it too. Is there a difference between
a MAC with Multifinder and one with MPW?
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From icon-group-request@arizona.edu Mon Sep 24 19:33:00 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA16661; Mon, 24 Sep 90 19:33:00 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 24 Sep 90 19:32 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA25323; Mon, 24 Sep 90
19:17:24 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Mon, 24 Sep 90 19:32 MST
Date: 25 Sep 90 00:57:11 GMT
From: ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer@iuvax.cs.indiana.edu
Subject: RE: Icon pipes in MSDOS
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2CA3885B642B00F0D3@Arizona.edu>
Message-Id: <1990Sep25.005711.29504@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <0093D32B5856BB80.204002AD@mis.mcw.edu>
Tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
>MSDOS does have pipes, but they're implemented differently than unix...
This was in reference to my question about what people do to get direc-
tory listings on systems that don't support pipes. I guess what I meant
to say was, "How do people get directory listings from within Icon on
systems that don't implement the "p" option for open() (i.e. do 'real'
pipes)?"
I'd be afraid to try to get a directory listing from Icon running under
MS-DOS using intermediate files because you can't always count on 1)
having enough free memory to do the system() function given Icon's
size, and 2) writing to disc introduces yet another level of indirec-
tion, and hence the possibility of many more errors (not enough disc
space, clobbering a previously existing tempfile, not being able to
write to the current directory, and not having a standard place for
temp files).
I'm searching for an answer to the dirlist from Icon problem because
I want to implement an indexing program in such a way that it can be
moved from Unix to Xenix to MS-DOS (others?) as easily as possible.
Part of the indexing procedure is to look at all file of a specified
type in a specified location. This involves finding a portable way
of getting a directory listing....
-Richard
From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Mon Sep 24 19:45:00 1990
Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA16888; Mon, 24 Sep 90 19:45:00 -0700
Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
id AA20714; Mon, 24 Sep 90 22:44:56 -0400
Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Mon, 24 Sep 90 22:36:42 EDT
Date: Mon, 24 Sep 90 18:33:42 EDT
From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu
To: icon-group@cs.arizona.edu
Message-Id: <251913@Wayne-MTS>
Subject: MS-DOS file generator
In response to Richard's request, here is the MS-DOS file generator that I
posted quite a while ago. I haven't even looked at it for over a year, but
I don't suppose it has rusted.
It would be nice if there were some repository for tidbits like this, but I
guess the Icon project has enough else to do.
Paul Abrahams
abrahams%wayne-mts@um.cc.umich.edu
====================================================================
# get_filename(pfn) accepts a DOS filename possibly containing wildcards.
# The filename can also include a drive letter and path.
# If the filename ends in "\" or ":", "*.*" is appended.
# The result sequence is a sequence of the filenames corresponding to pfn.
procedure get_filename(pfn)
local asciiz, fnr, prefix, k, name
local ds, dx, result, fnloc, string_block
#get Disk Transfer Address; filename locn is 30 beyond that
result := Int86([16r21, 16r2f00] ||| list(7,0))
fnloc := 16 * result[8] + result[3]+ 30
# get the generalized filename
fnr := reverse(pfn)
k := upto("\\:", fnr) | *fnr + 1
prefix := reverse(fnr[k:0])
name := "" ~== reverse(fnr[1:k]) | "*.*"
# Get the first file in the sequence
asciiz := prefix || name || "\x00"
Poke(string_block := GetSpace(*asciiz), asciiz)
ds := string_block / 16
dx := string_block % 16
result := Int86([16r21, 16r4e00, 0, 0, dx, 0, 0, 0, ds])
case result[2] of {
0 : {}
18 : fail
default : stop("i/o error ", result[2])
}
suspend prefix || extract_name(fnloc)
# Get the remaining files in the sequence
while Int86([16r21, 16r4f00, 0, 0, 0, 0, 0, 0, 0])[2] = 0 do
suspend prefix || extract_name(fnloc)
end
procedure extract_name(fnloc)
local asciiz
asciiz := Peek(fnloc, 13)
return asciiz[1:upto("\x00", asciiz)]
end
From icon-group-request@arizona.edu Tue Sep 25 22:04:11 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA21591; Tue, 25 Sep 90 22:04:11 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 25 Sep 90 22:02 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA01852; Tue, 25 Sep 90
21:51:18 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 25 Sep 90 22:03 MST
Date: 26 Sep 90 04:44:59 GMT
From: netcom!ergo@apple.com
Subject: RE: Icon pipes in MSDOS
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2BC554CE84B9011C54@Arizona.edu>
Message-Id: <13829@netcom.UUCP>
Organization: UESPA
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <0093D32B5856BB80.204002AD@mis.mcw.edu>
In <0093D32B5856BB80.204002AD@mis.mcw.edu> tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes:
>MSDOS does have pipes, but they're implemented differently than unix. MSDOS
>does it by generating scratch files. One can actually do a DIR|SORT or
>DIR | ICONX PROG. Inside icon one can issue system("dir >_dir.tmp") and
>then infile:=open("_dir.tmp") for subsequent processing. It also uses a
>little more memory when using the system command.
Those are *not* pipes. They are *called* pipes, but what they really
are is a shorthand for specifying temporary files. If they were
pipes, they would allow the two programs to execute concurrently, and
there would be no question of the "pipe" filling up the rest of the
disk volume. As it is, each program in the pipeline has to finish
executing before the next can even start. This makes for a lot of
inefficiency.
MS made it *look* like Unix commands like "find ... | grep ... | zoo ..."
also work under MS-DOS. But for all practical purposes, they do not.
--
ergo@netcom.uucp Isaac Rabinovitch
{apple,amdahl,claris}!netcom!ergo Silicon Valley, CA
Collins's Law:
If you can't make a mistake, you can't make anything.
Corollaries ("Rabinovitch's Rules of Sane Dialogue"):
1. Everybody who matters is stupid now and then.
2. If I'm being stupid, that's my problem.
3. If my being stupid makes you stupid, that's your problem.
4. If you think you're never stupid, boy are you stupid!
From goer%sophist@gargoyle.uchicago.edu Wed Sep 26 11:33:54 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA23441; Wed, 26 Sep 90 11:33:54 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 11:17 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA17607; Wed, 26 Sep 90 13:17:37 199
Received: by sophist (4.1/UofC3.1X) id AA10891; Wed, 26 Sep 90 13:21:45 CDT
Resent-Date: Wed, 26 Sep 90 11:18 MST
Date: Wed, 26 Sep 90 13:21:45 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: icon #comments
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2B5641E5BDA5400252@Arizona.edu>
Message-Id: <9009261821.AA10891@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Has anyone worked up an algorithm for stripping comments out of Icon
source files without having to parse every expression? It appears
that the # shouldn't occur except in strings or csets, or as the com-
ment delineator. If this is correct, it shouldn't be too hard to
strip them. Is this correct?
-Richard
From ralph Wed Sep 26 12:08:58 1990
Resent-From: "Ralph Griswold" <ralph>
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA25292; Wed, 26 Sep 90 12:08:58 -0700
Received: from megaron.cs.Arizona.EDU by Arizona.edu; Wed, 26 Sep 90 12:08 MST
Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15)
via SMTP id AA25256; Wed, 26 Sep 90 12:08:12 -0700
Received: by cheltenham.cs.arizona.edu; Wed, 26 Sep 90 12:08:10 MST
Resent-Date: Wed, 26 Sep 90 12:08 MST
Date: Wed, 26 Sep 90 12:08:10 MST
From: Ralph Griswold <ralph@cs.arizona.edu>
Subject: RE: icon #comments
Resent-To: icon-group@cs.arizona.edu
To: goer%sophist@gargoyle.uchicago.edu, icon-group@arizona.edu
Resent-Message-Id: <2B4F3D26B325400302@Arizona.edu>
Message-Id: <9009261908.AA03148@cheltenham.cs.arizona.edu>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: goer%sophist@gargoyle.uchicago.edu, icon-group@Arizona.EDU
The character # can occur in string and cset literals.
Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
+1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph
From cjeffery Wed Sep 26 12:15:22 1990
Resent-From: "Clinton Jeffery" <cjeffery>
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA25650; Wed, 26 Sep 90 12:15:22 -0700
Received: from megaron.cs.Arizona.EDU by Arizona.edu; Wed, 26 Sep 90 12:14 MST
Received: from caslon.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via
SMTP id AA25603; Wed, 26 Sep 90 12:14:39 -0700
Received: by caslon.cs.arizona.edu; Wed, 26 Sep 90 12:14:37 -0700
Resent-Date: Wed, 26 Sep 90 12:15 MST
Date: Wed, 26 Sep 90 12:14:37 -0700
From: Clinton Jeffery <cjeffery@cs.arizona.edu>
Subject: icon #comments
Resent-To: icon-group@cs.arizona.edu
To: goer%sophist@gargoyle.uchicago.edu
Cc: icon-group@arizona.edu
Resent-Message-Id: <2B4E5A1657C5400310@Arizona.edu>
Message-Id: <9009261914.AA12171@caslon.cs.arizona.edu>
In-Reply-To: Richard Goerwitz's message of Wed, 26 Sep 90 13:21:45 CDT
<9009261821.AA10891@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: goer%sophist@gargoyle.uchicago.edu
X-Vms-Cc: icon-group@Arizona.EDU
(Richard Goerwitz asks about code to strip out comments)
There may be other programs in the Icon Program Library to do this, but
one comment-removal technique is exemplified in the Idol object-oriented
preprocessor. It is not perfect, and I am always soliciting improvements.
It is characterized as a predicate for determining whether a position is
within a string or cset literal (which is useful for more than comments).
One interesting triviality is that it appears to use no csets. On purpose.
Here is an extract, with an untested sample procedure main.
--
procedure main()
while line := read() do {
line[ 1(x<-find("#",line),notquote(line[1:x])) : 0] := ""
write(trim(line))
}
end
#
# tell whether the character *following* s is within a quote or not
#
procedure notquote(s)
outs := ""
#
# eliminate escaped quotes.
# this is a bug for people who write code like \"hello"...
s ? {
while outs ||:= tab(find("\\")+1) do move(1)
outs ||:= tab(0)
}
# see if every quote has a matching endquote
outs ? {
while s := tab(find("\""|"'")+1) do {
if not tab(find(s[-1])+1) then fail
}
}
return
end
From goer%sophist@gargoyle.uchicago.edu Wed Sep 26 13:01:22 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA28647; Wed, 26 Sep 90 13:01:22 -0700
Return-Path: goer@Arizona.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 13:00 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA00433; Wed, 26 Sep 90 14:59:52 199
Received: by sophist (4.1/UofC3.1X) id AA10950; Wed, 26 Sep 90 14:42:17 CDT
Resent-Date: Wed, 26 Sep 90 13:00 MST
Date: Wed, 26 Sep 90 14:42:17 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: stripping #comments
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2B47EFB790C5400384@Arizona.edu>
Message-Id: <9009261942.AA10950@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Ralph@cs.arizona.edu tells me that
[t]he character # can occur in string and cset literals.
Okay, that helps me a lot. If it only occurs in string and cset
literals, and as the comment delineator, I should be able to strip
out comments by counting " and '. I don't see how this can be done
elegantly using bal.
-Richard
-------------------------------------------------------------------
procedure main()
every write(strip_comments(!&input))
end
procedure strip_comments(s)
# Strip trailing, leading whitespace, and all comments, from
# string s (where s is a line from a .icn source file).
local i, j
s ?:= (tab(many(' \t')), tab(0))
s ? {
match("#") & fail
(s2 <- tab(find("#"))) ? {
i := j := 0
while tab(upto('"\'')) do {
case move(1) of {
"\"" : {
i +:= 1
if tab(find("\"")+1)
then i +:= 1
else tab(find("\'")+1) | break
}
"\'" : {
j +:= 1
if tab(find("\'")+1)
then j +:= 1
else tab(find("\"")+1) | break
}
}
}
i % 2 = 0 & j % 2 = 0
}
return "" ~== trim((\s2 | .&subject) \ 1, ' \t')
}
end
From goer%sophist@gargoyle.uchicago.edu Wed Sep 26 13:10:39 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA29316; Wed, 26 Sep 90 13:10:39 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 13:09 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA00780; Wed, 26 Sep 90 15:09:38 199
Received: by sophist (4.1/UofC3.1X) id AA10962; Wed, 26 Sep 90 15:13:45 CDT
Resent-Date: Wed, 26 Sep 90 13:10 MST
Date: Wed, 26 Sep 90 15:13:45 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: more #comments
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2B46A0B711454003A4@Arizona.edu>
Message-Id: <9009262013.AA10962@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Okay, I admit that my routine wouldn't handle "hello\"" properly,
either. It's pretty simple to modify it so that it will:
------------------------------------------------------------------
procedure main()
every write(strip_comments(!&input))
end
procedure strip_comments(s)
# Commented-out portions of Icon code - strip 'em.
local i, j, c, looking_for
s ?:= (tab(many(' \t')), tab(0))
s ? {
match("#") & fail
(s2 <- tab(find("#"))) ? {
i := j := 0
looking_for := "\"\'"
while c := move(1) do {
case c of {
"\\" : {
move(1); next
}
"\"" : {
if find(c,looking_for) & i +:= 1
then looking_for := (looking_for ~== "\"") | "\"\'"
}
"\'" : {
if find(c,looking_for) & j +:= 1
then looking_for := (looking_for ~== "\'") | "\"\'"
}
}
}
i % 2 = 0 & j % 2 = 0
}
return "" ~== trim((\s2 | .&subject) \ 1, ' \t')
}
end
From metaphor!laguna.metaphor.com!alex@decwrl.dec.com Wed Sep 26 13:54:06 1990
Received: from decwrl.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA01376; Wed, 26 Sep 90 13:54:06 -0700
Received: by decwrl.dec.com; id AA02780; Wed, 26 Sep 90 13:53:57 -0700
Received: from laguna.Metaphor.COM by metaphor.com (3.2/SMI-3.2)
id AA18776; Wed, 26 Sep 90 13:34:01 PDT
Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
id AA01364; Wed, 26 Sep 90 13:33:19 PDT
Date: Wed, 26 Sep 90 13:33:19 PDT
From: metaphor!laguna.metaphor.com!alex@decwrl.dec.com (Bob Alexander)
Message-Id: <9009262033.AA01364@laguna.Metaphor.COM>
To: icon-group@cs.arizona.edu
Subject: Stripping comments
Here's a routine I just whipped up. I tested it some but don't have
complete confidence in it. Comments? (pun intended)
procedure trimcomment(s1) # s2
local c,delim
s1 ? {
while tab(upto('"\'\\#')) do {
case c := move(1) of {
!"\"'": {
delim := if \delim then {
if delim == c then &null
}
else c
}
"\\": if \delim then ="^" & move(1) # in case he used "\^'"
"#": if /delim then return trim(&subject[1:&pos - 1])
}
}
}
return trim(s1)
end
-- Bob Alexander
Metaphor Computer Systems (415) 961-3600 x751 alex@metaphor.com
====^=== Mountain View, CA ...{uunet}!{decwrl,apple}!metaphor!alex
From metaphor!laguna.metaphor.com!alex@decwrl.dec.com Wed Sep 26 14:33:40 1990
Received: from decwrl.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA03549; Wed, 26 Sep 90 14:33:40 -0700
Received: by decwrl.dec.com; id AA08035; Wed, 26 Sep 90 14:33:15 -0700
Received: from laguna.Metaphor.COM by metaphor.com (3.2/SMI-3.2)
id AA19746; Wed, 26 Sep 90 14:23:42 PDT
Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
id AA01446; Wed, 26 Sep 90 14:22:59 PDT
Date: Wed, 26 Sep 90 14:22:59 PDT
From: metaphor!laguna.metaphor.com!alex@decwrl.dec.com (Bob Alexander)
Message-Id: <9009262122.AA01446@laguna.Metaphor.COM>
To: icon-group@cs.arizona.edu
Subject: 1st bug in comment stripper
I *knew* I should let this routine age for a couple of days before
posting it! It couldn't handle "abc\"def". First bug fix (with a bit
of vertical compactification, and other misc changes):
procedure trimcomment(s1) # s2
#
# Trim comments (and any trailing spaces) from Icon program text line.
#
local c,delim
s1 ? {
while tab(upto('"\'\\#')) do {
case c := move(1) of {
"#": if /delim then return trim(&subject[1:&pos - 1],' \t')
"\\": if \delim then {="^" ; move(1)} # in case he used "\^""
default: delim := if \delim then (if delim == c then &null) else c
}
}
}
return trim(s1,' \t')
end
-- Bob Alexander
Metaphor Computer Systems (415) 961-3600 x751 alex@metaphor.com
====^=== Mountain View, CA ...{uunet}!{decwrl,apple}!metaphor!alex
From goer%sophist@gargoyle.uchicago.edu Wed Sep 26 19:41:07 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA17222; Wed, 26 Sep 90 19:41:07 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Wed, 26 Sep 90 19:40 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA11612; Wed, 26 Sep 90 21:40:30 199
Received: by sophist (4.1/UofC3.1X) id AA11488; Wed, 26 Sep 90 21:44:37 CDT
Resent-Date: Wed, 26 Sep 90 19:40 MST
Date: Wed, 26 Sep 90 21:44:37 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: trimming comments
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2B10123E80A5400853@Arizona.edu>
Message-Id: <9009270244.AA11488@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Thanks everyone for the help with stripping out comments. I
kinda synthesized all the postings and came up with the procedure
appended below. Note that it now runs faster than any of the
previous postings people (including me) have made:
procedure strip_comments(s)
#######
#
# Commented-out portions of Icon code - strip 'em. Fails on lines
# which, either stripped or otherwise, come out as an empty string.
#
# I'd expect strip_comments to be used typically as follows:
#
# every write(strip_comments(!&input))
#
#######
local i, j, c, c2
s ? {
tab(many(' \t'))
match("#") & fail
(s2 <- tab(find("#"))) ? {
c2 := &null
while tab(upto('\\"\'')) do {
case c := move(1) of {
"\\" : {
if match("^")
then move(2)
else move(1)
}
default: {
if \c2
then (c == c2, c2 := &null)
else c2 := c
}
}
}
/c2
}
return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
}
end
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From tenaglia@mis.mcw.edu Thu Sep 27 02:22:35 1990
Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA29993; Thu, 27 Sep 90 02:22:35 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA21172; Thu, 27 Sep 90 04:27:30 EDT
Received: by uwm.edu; id AA08961; Wed, 26 Sep 90 18:27:55 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Wed, 26 Sep 90 17:29:36 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Wed, 26 Sep 90 16:35:22 CDT
Date: Wed, 26 Sep 90 16:35:22 CDT
Message-Id: <0093D4D603B5C380.204000C3@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: MSDOS Icon
To: icon-group@cs.arizona.edu
As a matter of fact I do my serious Icon development on a VAX. I do have
it on a pc or 2 as a filtering tool. I prefer Icon 5.9 which uses less
memory, and also DOS 3.1 or 3.3. While Icon 5.9 is missing some of the
latest goodies, it's just fine as long as I don't need interupts or getch.
I've even written a kind of unix shell environment in it. It has a form
of about 50 unixlike commands, translates \ to / for the paths, has a
login program written in compiled basic, and some other things. Mostly
it reads unix commands and reformats them to DOS with system(). It won't
work with recent versions of icon because of memory limits, but 5.9
does fit. Granted, it's not 'real', but it was a fun little project.
Any ideas about having the DOS version do swapping to reclaim memory,
maybe as an option with garbage collection. Also make iconx smarter
so one icon program could run another without reloading iconx.exe into
memory.
Oh well, pardon my frothing. I guess I just have a big imagination
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From tenaglia@mis.mcw.edu Thu Sep 27 13:37:38 1990
Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA01582; Thu, 27 Sep 90 13:37:38 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA08301; Thu, 27 Sep 90 16:03:18 EDT
Received: by uwm.edu; id AA29656; Thu, 27 Sep 90 09:15:37 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Thu, 27 Sep 90 08:47:53 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Thu, 27 Sep 90 08:33:59 CDT
Date: Thu, 27 Sep 90 08:33:59 CDT
Message-Id: <0093D55BEE372CC0.204002CF@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: Uncommenting
To: icon-group@cs.arizona.edu
Uncommenting is a fascinating problem. It probably is important to compiler
writers. But for normal programming, I think one would want to add comments.
Anyway I've been watching the algorythms getting thorougher. Has anybody
thought about the pathological split line literal?
tmp := []
while find("\"567_
#934.\355\\\'",read()) do # Unbelievable isn't it
put(tmp,"Field_1_
_78\'#\\\"YYY_
Continuing_String_
Literally_Pathetic#") # \\ "ack!" #\\
Granted, who would write an expression so pathetic, except to try to break
a parser. Food for thought and icon hackers.
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From goer%sophist@gargoyle.uchicago.edu Thu Sep 27 14:51:58 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA05410; Thu, 27 Sep 90 14:51:58 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 27 Sep 90 14:51 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA17586; Thu, 27 Sep 90 16:51:02 199
Received: by sophist (4.1/UofC3.1X) id AA11909; Thu, 27 Sep 90 16:55:09 CDT
Resent-Date: Thu, 27 Sep 90 14:51 MST
Date: Thu, 27 Sep 90 16:55:09 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: line splits & uncommenting
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2A6F55B8BFA9401024@Arizona.edu>
Message-Id: <9009272155.AA11909@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Has anybody thought about the pathological split line literal?
tmp := []
while find("\"567_
#934.\355\\\'",read()) do # Unbelievable isn't it
put(tmp,"Field_1_
_78\'#\\\"YYY_
Continuing_String_
Literally_Pathetic#") # \\ "ack!" #\\
I confess that I hadn't thought about the split-line literal. I don't
use them myself, and generally don't like the look of code that does.
That's no excuse, though.
BTW, do you have a solution in mind?
We know that the underscore has to be the last thing on the line, except
for whitespace and comments. I'll bet it would be possible to modify the
procedures posted so that they look, not only for " and ' and \, but also
_. If the underscore is encountered, then you could tab past any spaces
and newlines (if present), and if either pos(0) or match("#") succeed,
then abort all attempts at ' and "-matching, and return &subject[1:&pos].
Just an off-the-cuff guess. If anyone cleans up our collective postings
and makes the _ thing work, could he or she please re-post the resulting
procedure?
-Richard
/
From goer%sophist@gargoyle.uchicago.edu Thu Sep 27 15:09:59 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA06603; Thu, 27 Sep 90 15:09:59 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 27 Sep 90 15:09 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA18014; Thu, 27 Sep 90 17:09:20 199
Received: by sophist (4.1/UofC3.1X) id AA11929; Thu, 27 Sep 90 17:13:26 CDT
Resent-Date: Thu, 27 Sep 90 15:09 MST
Date: Thu, 27 Sep 90 17:13:26 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: write("hel_
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2A6CC8C3C429400FC7@Arizona.edu>
Message-Id: <9009272213.AA11929@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I just tried compiling
write("hel_ # this is a partial comment
lo")
and it didn't work. It seems obvious why. What a nightmare to parse!
Anyway, that makes our comment-stripping that much easier. How about
something like:
procedure strip_comments(s)
#######
#
# Commented-out portions of Icon code - strip 'em. Fails on lines
# which, either stripped or otherwise, come out as an empty string.
#
# I'd expect strip_comments to be used typically as follows:
#
# every write(strip_comments(!&input))
#
#######
local i, j, c, c2
s ? {
tab(many(' \t'))
find("#") | (return trim(tab(0),' \t'))
match("#") & fail
(s2 <- tab(find("#"))) ? {
c2 := &null
while tab(upto('_\\"\'')) do {
case c := move(1) of {
"\\" : {
if match("^")
then move(2)
else move(1)
}
"_" : {
if c2 == "\"" &
tab(many(' \t')) | &null &
pos(0)
then return trim(&subject, ' \t')
}
default: {
if \c2
then (c == c2, c2 := &null)
else c2 := c
}
}
}
/c2
}
return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
}
end
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer
From metaphor!laguna.metaphor.com!alex@decwrl.dec.com Thu Sep 27 16:08:51 1990
Received: from decwrl.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA09333; Thu, 27 Sep 90 16:08:51 -0700
Received: by decwrl.dec.com; id AA02796; Thu, 27 Sep 90 16:08:43 -0700
Received: from laguna.Metaphor.COM by metaphor.com (3.2/SMI-3.2)
id AA27431; Thu, 27 Sep 90 15:38:05 PDT
Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
id AA02317; Thu, 27 Sep 90 15:37:22 PDT
Date: Thu, 27 Sep 90 15:37:22 PDT
From: metaphor!laguna.metaphor.com!alex@decwrl.dec.com (Bob Alexander)
Message-Id: <9009272237.AA02317@laguna.Metaphor.COM>
To: icon-group@cs.arizona.edu
Subject: Re: line splits & uncommenting
Wow -- the problems and solutions are coming in faster than I can
formulate a reply! Have to learn to type (and think) faster.
Another possible solution to the split-string-literal problem is simply
to make the variable that remembers the string literal delimiter
persistant (static or global). Using as an example the version I
previously posted, "delim" is the variable in question. The results
could be very wierd if the input program contains certain syntax
errors.
procedure trimcomment(s1) # s2
#
# Trim comments (and any trailing spaces) from Icon program text line "s1".
#
static delim
local c
s1 ? {
while tab(upto('"\'\\#')) do {
case c := move(1) of {
"#": if /delim then return trim(&subject[1:&pos - 1],' \t')
"\\": if \delim then {="^" ; move(1)} # in case he used "\^""
default: delim := if \delim then (if delim == c then &null) else c
}
}
}
return trim(s1,' \t')
end
-- Bob Alexander
Metaphor Computer Systems (415) 961-3600 x751 alex@metaphor.com
====^=== Mountain View, CA ...{uunet}!{decwrl,apple}!metaphor!alex
From goer%sophist@gargoyle.uchicago.edu Fri Sep 28 04:29:06 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA05479; Fri, 28 Sep 90 04:29:06 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Fri, 28 Sep 90 04:28 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA12747; Fri, 28 Sep 90 05:41:56 199
Received: by sophist (4.1/UofC3.1X) id AA12149; Fri, 28 Sep 90 05:46:01 CDT
Resent-Date: Fri, 28 Sep 90 04:28 MST
Date: Fri, 28 Sep 90 05:46:01 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: test posting of a strange program
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <29FD26AE14C9401003@Arizona.edu>
Message-Id: <9009281046.AA12149@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
This is a test posting of a strange program. Essentially, it takes
a source file, finds all procedure calls in it, looks for those pro-
cedure calls which are not a part of the source file itself in the
IPL (or in any directories you tell it to), then fetches those rou-
tines that it needs, writing the original source file and the neces-
sary library routines to the standard output.
Frequently I forget what file an IPL routine is in. And there is
almost always stuff I don't want to link in present with the routines
that I do. This program handles most of the hunting and pecking by
itself.
It's pretty slow right now, and probably won't work on anything but
Unix. It might work under MS-DOS. I don't know. It's also been used
by me alone, and hasn't gone through any rigouous testing procedure.
I hope that others will fool with the code, as I will surely do, and
make this thing a bit more refined. Comments are sparse at present.
This will doubtless change as I read it over more, and get comments
from brave souls who have tried it out.
-Richard
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 09/28/1990 10:26 UTC by goer@sophist.uchicago.edu
# Source directory /u/richard/Tmp
#
# existing files will NOT be overwritten unless -c is specified
# This format requires very little intelligence at unshar time.
# "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
#
#
#
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 269 -rw-r--r-- Makefile
# 1815 -rw-r--r-- README
# 3096 -rw-r--r-- getcalls.icn
# 3211 -rw-r--r-- getnames.icn
# 549 -rw-r--r-- getpaths.icn
# 1585 -rw-r--r-- getprocs.icn
# 3250 -rw-r--r-- main.icn
# 950 -rw-r--r-- stripcom.icn
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
Ximerge:
X icont -Sc 300 -o imerge getcalls.icn getnames.icn \
X getpaths.icn getprocs.icn main.icn stripcom.icn
X
Xshar:
X shar -fVc -oimerge -L23 -sgoer@sophist.uchicago.edu Makefile \
X README getcalls.icn getnames.icn getpaths.icn getprocs.icn \
X main.icn stripcom.icn
SHAR_EOF
true || echo 'restore of Makefile failed'
rm -f _shar_wnt_.tmp
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
echo 'x - skipping README (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XImerge simply merges the correct routines from the IPL, and from any
Xother directories you supply, into a given source file. Often a given
XIPL file will have several procedures - not all of which are needed
Xin order to compile a given program. Imerge obviates the need for
Xlinking in the entire library.
X
XUsage is
X
X imerge sourcefile [libdirectories]
X
Xwhere sourcefile refers to an icon source code file, and libdirectories
Xis a space-separated list of directories in which .icn files containing
Xroutines needed by sourcefile are likely to be found.
X
XYou can remove the need to specify any directories on the command line
Xby setting the value of ILIBS in your environment to a space or colon-
Xseparated string of directory names.
X
XImerge writes to the standard output. Slowly. Bear with it, and it will
Xnormally do a pretty decent job. Watch the end of the file for a report
Xof procedures not found (you'll have to go find them, and either link
Xthem in by hand, or add the directory they are in to the ILIBS variable).
X
XNOTE WELL: This is pretty much untested on anything but Unix. It might
Xrun under MS-DOS. I simply don't know. It certainly won't run under
Xanything else (although it could easily be modified to do so). Note that
Xeven under Unix, this program has not been given a long-term workout, and
XI expect that many bugs will turn up....
X
XKNOWN BUGS: Naming conflicts cannot be resolved. Make sure no duplicate
Xnames exist for procedures in your libraries. Also, the parsing algorithm
Xdoesn't handle the line-final underscore notation for string literals.
XFinally, indirect procedure invocations, such as a := b; a(), where b is
Xa global procedure name are not handled properly, though the resulting
Xfile should compile fine, assuming a() is not defined somewhere in a
Xlibrary file.
X
X-Richard
SHAR_EOF
true || echo 'restore of README failed'
rm -f _shar_wnt_.tmp
fi
# ============= getcalls.icn ==============
if test -f 'getcalls.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getcalls.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getcalls.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getcalls.icn' &&
Xprocedure get_procedure_calls(line)
X
X # Looks for non-builtin procedure calls in line. Returns nothing
X # until called without an argument, in which case it returns the
X # accumulated set of procedure names found in the "line"s read so
X # far. When next invoked, get_procedure_calls starts with a fresh
X # (i.e. freshly emptied) set.
X
X local external_procedures
X static keywords, builtins, wchars, procedures_called
X initial {
X wchars := &ucase ++ &lcase ++ &digits ++ '_'
X keywords := set(
X ["break","by","case","default","do","dynamic","else","end",
X "every","fail","global","if","initial","link","local",
X "next","not","of","procedure","record","repeat","return",
X "static","suspend","then","to","until","while"])
X builtins := set(
X ["abs","acos","any","args","asin","bal","char",
X "center","close","copy","collect","cos","cset","delete",
X "detab","display","dtor","entab","exit","exp","find","get",
X "getenv","iand","icom","ior","image","insert","integer",
X "ishift","ixor","key","left","list","log","getch",
X "getche","kbhit","main","many","map","match","member",
X "move","name","numeric","open","ord","pop","pos",
X "pull","push","put","read","reads","real","remove",
X "rename","repl","reverse","right","rtod","seek","set",
X "sin","sort","sqrt","stop","string","system","tab",
X "table","trim","type","upto","variable","where",
X "write","writes"])
X procedures_called := set()
X }
X
X strip_comments(\line) ? {
X while tab(upto_balanced(wchars)) do {
X BEGIN := &pos
X id := tab(many(wchars))
X # Record constructors look like procedure invocations.
X # Make the names of records like builtin function names.
X if id == "record" then {
X if tab(many(' \t')) & id := tab(many(wchars)) then
X insert(builtins, id)
X else break # give up, bad code
X }
X # Make sure with "procedure proc1(arguments)" that proc1
X # doesn't get taken as an invocation of proc1!
X else if id == "procedure" then {
X if not (tab(many(' \t')) & tab(many(wchars)))
X then break # give up, bad code
X }
X else {
X tab(many(" \t"))
X if tab(match("(")) then {
X integer(id) & next
X # Reject id if it is a keyword or builtin function
X if member(keywords | builtins, id) then next
X else {
X # Conceivably, we could have rec.field(args)
X if match(".",line,BEGIN -1) then next
X else insert(procedures_called, id)
X # Doesn't account for (proc1|proc2)(arguments)
X }
X }
X }
X }
X }
X
X if /line then {
X external_procedures := (procedures_called -- builtins) -- keywords
X procedures_called := set()
X return external_procedures
X }
X
Xend
X
X
X
Xprocedure upto_balanced(cs)
X
X local s2, c, c2, POS
X
X &subject[.&pos:0] ? {
X tab(upto(cs)) ? {
X c2 := &null
X while tab(upto('\\"\'')) do {
X case c := move(1) of {
X "\\" : {
X if match("^")
X then move(2)
X else move(1)
X }
X default: {
X if \c2
X then (c == c2, c2 := &null)
X else c2 := c
X }
X }
X }
X /c2
X } & POS := &pos
X }
X
X return &pos + \POS - 1
X
Xend
SHAR_EOF
true || echo 'restore of getcalls.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getnames.icn ==============
if test -f 'getnames.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getnames.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getnames.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getnames.icn' &&
Xprocedure get_ipl_names(lib_paths)
X
X local procedure_stat_list
X static get_dir
X initial get_dir := set_getdir_by_os()
X
X procedure_stat_list := list()
X # Run through every possible path in which files might be found,
X # and get a list of procedures contained in those files.
X every procedure_stat_list |||:= get_dir(!lib_paths)
X
X return procedure_stat_list
X
Xend
X
X
X
X
Xprocedure set_getdir_by_os()
X
X if find("UNIX", &features)
X then return unix_get_dir
X else if find("MS-DOS", &features)
X then return msdos_get_dir
X else stop("Your operating system is not (yet) supported.")
X
Xend
X
X
X
Xprocedure msdos_get_dir(dir)
X
X # Returns a sorted list of all filenames (full paths included) in
X # directory "dir." The list is sorted. Fails on invalid or empty
X # directory. Aborts if temp file cannot be opened.
X #
X # Temp files can be directed to one or another directory either by
X # manually setting the variable temp_dir below, or by setting the
X # value of the environment variable TEMPDIR to an appropriate
X # directory name.
X
X local in_dir, filename_list, line
X static temp_dir
X initial {
X temp_dir :=
X (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
X ".\\"
X }
X
X # Get name of tempfile to be used.
X temp_name := get_dos_tempname(temp_dir) |
X stop("No more available tempfile names!")
X
X # Make sure we have an unambiguous directory name, with backslashes
X # instead of Unix-like forward slashes.
X dir := trim(map(dir, "/", "\\"), '\\') || "\\"
X
X # Put dir listing into a temp file.
X system("dir "||dir||" > "||temp_name)
X
X # Put tempfile entries into a list, removing blank- and
X # space-initial lines. Exclude directories (i.e. return file
X # names only).
X in_dir := open(temp_name,"r") |
X stop("Can't open temp file in directory ",temp_dir,".")
X filename_list := list()
X every filename := ("" ~== !in_dir) do {
X match(" ",filename) | find(" <DIR>", filename) & next
X # Exclude our own tempfiles (may not always be appropriate).
X filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
X if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
X then put(filename_list, map(dir || filename))
X }
X
X # Clean up.
X close(in_dir) & remove(temp_name)
X
X # Check to be sure we actually managed to read some files.
X if *filename_list = 0 then fail
X else return sort(filename_list)
X
Xend
X
X
X
Xprocedure get_dos_tempname(dir)
X
X # Don't clobber existing files. Get a unique temp file name for
X # use as a temporary storage site.
X
X every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
X temp_file := open(temp_name,"r") | break
X close(temp_file)
X }
X return \temp_name
X
Xend
X
X
X
Xprocedure unix_get_dir(dir)
X
X dir := trim(dir, '/') || "/"
X filename_list := list()
X in_dir := open("/bin/ls -F "||dir, "pr")
X every filename := ("" ~== !in_dir) do {
X match("/",filename,*filename) & next
X if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
X then put(filename_list, trim(dir || filename, '*'))
X }
X close(in_dir)
X
X if *filename_list = 0 then fail
X else return filename_list
X
Xend
SHAR_EOF
true || echo 'restore of getnames.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getpaths.icn ==============
if test -f 'getpaths.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getpaths.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getpaths.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getpaths.icn' &&
Xprocedure get_lib_paths(ipl_paths)
X
X /ipl_paths := list()
X
X # If the ILIBS environment variable is set, read it into
X # ipl_paths. Colons *or* spaces are okay as separators.
X getenv("ILIBS") ? {
X while path := tab(upto(' :')) do {
X put(ipl_paths, "./" ~== fixup_path(path))
X tab(many(' :'))
X }
X put(ipl_paths, "./" ~== fixup_path(tab(0)))
X }
X
X # Make sure the current directory is in the IPL path.
X push(ipl_paths, "./")
X
X return ipl_paths
X
Xend
X
X
X
Xprocedure fixup_path(s)
X return "/" ~== (trim(s,'/') || "/")
Xend
SHAR_EOF
true || echo 'restore of getpaths.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getprocs.icn ==============
if test -f 'getprocs.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getprocs.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getprocs.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getprocs.icn' &&
Xrecord procedure_stats(name, file, byte)
Xglobal record_table, global_table
X
Xprocedure get_procedure_stats(fname)
X
X # Extracts the names of all procedures declared in file f.
X # Returns them in a list, each of whose elements have the
X # form record procedure_stats(procedurename, filename, byte
X # offset).
X
X local intext, procedure_stat_list, f_pos, entry
X # global record_table
X static name_chars
X initial {
X record_table := table()
X global_table := table()
X name_chars := &ucase ++ &lcase ++ &digits ++ '_'
X }
X
X # Open fname.
X intext := open(fname, "r") | fail
X
X # Initialize procedure-name list.
X procedure_stat_list := list()
X
X # Find procedure declarations in intext.
X while f_pos := where(intext) & line := read(intext) do {
X strip_comments(line) ? {
X if tab(match("procedure")) then {
X tab(many(' \t')) &
X put(procedure_stat_list,
X procedure_stats(
X "main" ~== tab(many(name_chars)), fname, f_pos
X )
X )
X }
X else if tab(match("record")) then {
X tab(many(' \t'))
X if entry := "record " ||
X tab(many(name_chars)) ||
X (tab(many(' \t')) | &null, "") ||
X tab(match("(")) ||
X tab(find(")")+1) & pos(0)
X then {
X /record_table[fname] := set()
X insert(record_table[fname], entry)
X }
X }
X else if tab(match("global")) then {
X tab(many(' \t'))
X /global_table[fname] := set()
X insert(global_table[fname], "global "||tab(0))
X }
X }
X }
X
X # Clean up.
X close(intext)
X
X return procedure_stat_list # returns empty list if no procedures found
X
Xend
SHAR_EOF
true || echo 'restore of getprocs.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= main.icn ==============
if test -f 'main.icn' -a X"$1" != X"-c"; then
echo 'x - skipping main.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting main.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'main.icn' &&
Xglobal unfound_procedures, st2, records, globals
X
Xprocedure main(a)
X
X local usage, line, raw_line, elem, sourcefile_procedures
X
X usage := "usage: imerge sourcefile [libdirs]"
X #
X # Where sourcefile is a single filename, and libdirs is a series
X # of space-separated directories in which relevant library files
X # are to be found.
X
X *a < 1 & stop(usage)
X
X if not (intext := open(a[1],"r")) then {
X write(&errout, "Cannot open source file.")
X write(&errout, usage)
X exit(2)
X }
X
X # Find every procedure call in intext.
X every get_procedure_calls(!intext)
X sourcefile_procedure_calls := get_procedure_calls()
X
X if *sourcefile_procedure_calls = 0 then fail
X
X # I know this is inefficient. Change it, if you like.
X sourcefile_procedures := set()
X every insert(sourcefile_procedures, (!get_procedure_stats(a[1])).name)
X sourcefile_procedure_calls --:= sourcefile_procedures
X
X if *sourcefile_procedure_calls = 0 then fail
X
X # Insert into procedure_stat_list the name of every procedure
X # called by every library file.
X prtbl := table()
X every fname := !get_ipl_names(get_lib_paths()) do {
X every elem := !get_procedure_stats(fname) do {
X insert(prtbl,elem.name,elem)
X }
X }
X
X # Copy input file to stdout.
X seek(intext,1)
X every line := strip_comments(raw_line := !intext) do {
X line ? (tab(match("global"|"record"|"link")), tab(any(' \t'))) & next
X write(raw_line)
X }
X close(intext)
X write("\n\n\n")
X write(repl("#",75))
X write("#")
X write("# Auto merged procedures begin here.")
X write("#")
X
X # Fetch procedure calls, and write them to stdout.
X fetch_procedure(sourcefile_procedure_calls, prtbl, a[1])
X
Xend
X
X
X
Xprocedure fetch_procedure(st,prtbl,f_name,switch)
X
X local stat, elem, p, st3
X
X # global unfound_procedures, records, record_table, global_table
X initial {
X unfound_procedures := set()
X records := set()
X globals := set()
X }
X
X /st2 := set()
X
X every insert(globals, !\global_table[f_name])
X
X every p := !st do {
X if /(stat := prtbl[p]) then {
X # Record_table has record declarations catalogued by file name.
X if find(" "||p||"(",elem := !\record_table[f_name] | !!record_table)
X then insert(records,elem)
X else insert(unfound_procedures, p)
X next
X }
X intext := open(stat.file,"r")
X seek(intext,stat.byte)
X until "end" == (line := strip_comments(write(!intext \ 1))) do {
X get_procedure_calls(line)
X }
X write("\n\n\n")
X st2 ++:= st ++ set([stat.name])
X st3 := get_procedure_calls() -- st2
X close(intext)
X fetch_procedure(st3,prtbl,stat.file,1)
X }
X
X if *records ~= 0 & /switch then {
X # Output records that have been used.
X write("# Records.")
X every write(!sort(records))
X write()
X }
X
X if *globals ~= 0 & /switch then {
X # Output global variables for all files visited.
X write("# Global variables.")
X every write(!sort(globals))
X write()
X }
X
X if *unfound_procedures ~= 0 & /switch then {
X # Append a list of unlocated procedures to the stdout.
X write("# Unable to locate the following procedures:")
X write("#")
X every write("# ",!sort(unfound_procedures),"()")
X write("#")
X }
X
X return
X
Xend
X
SHAR_EOF
true || echo 'restore of main.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= stripcom.icn ==============
if test -f 'stripcom.icn' -a X"$1" != X"-c"; then
echo 'x - skipping stripcom.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting stripcom.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stripcom.icn' &&
Xprocedure strip_comments(s)
X
X #######
X #
X # Commented-out portions of Icon code - strip 'em. Fails on lines
X # which, either stripped or otherwise, come out as an empty string.
X #
X # I'd expect strip_comments to be used typically as follows:
X #
X # every write(strip_comments(!&input))
X #
X # BUG: Does not handle lines which use the _ string-continuation
X # notation. Typically strip_comments barfs on the next line.
X #
X #######
X
X local i, j, c, c2
X
X s ? {
X tab(many(' \t'))
X pos(0) & fail
X find("#") | (return trim(tab(0),' \t'))
X match("#") & fail
X (s2 <- tab(find("#"))) ? {
X c2 := &null
X while tab(upto('\\"\'')) do {
X case c := move(1) of {
X "\\" : {
X if match("^")
X then move(2)
X else move(1)
X }
X default: {
X if \c2
X then (c == c2, c2 := &null)
X else c2 := c
X }
X }
X }
X /c2
X }
X return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
X }
X
Xend
SHAR_EOF
true || echo 'restore of stripcom.icn failed'
rm -f _shar_wnt_.tmp
fi
exit 0
From icon-group-request@arizona.edu Tue Oct 2 17:51:01 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA02574; Tue, 2 Oct 90 17:51:01 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 2 Oct 90 17:50 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27217; Tue, 2 Oct 90 17:19:31
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 2 Oct 90 17:50 MST
Date: 2 Oct 90 05:41:54 GMT
From: midway!quads.uchicago.edu!goer@uunet.uu.net
Subject: RE: test posting of a strange program
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <266876AB890940289A@Arizona.edu>
Message-Id: <1990Oct2.054154.15481@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
References: <9009281046.AA12149@sophist>
Goer%sophist@GARGOYLE.UCHICAGO.EDU (Richard Goerwitz) writes:
>This is a test posting of a strange program. Essentially, it takes
>a source file, finds all procedure calls in it, looks for those pro-
>cedure calls which are not a part of the source file itself in the
>IPL (or in any directories you tell it to), then fetches those rou-
>tines that it needs, writing the original source file and the neces-
>sary library routines to the standard output.
>
>Frequently I forget what file an IPL routine is in. And there is
>almost always stuff I don't want to link in present with the routines
>that I do. This program handles most of the hunting and pecking by
>itself.
I now have an updated version of the program around. It has been
tested in more environments, and seems to work pretty well. I want
people who are interested in tinkering with the utility to let me
know so I can send them updates. I'll refrain from reposting a
final version until it's looking pretty stable.
Thanks to those who offered me feedback. Thanks in advance to those
who might choose to do so in the future.
-Richard
From icon-group-request@arizona.edu Tue Oct 2 19:54:56 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA06336; Tue, 2 Oct 90 19:54:56 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 2 Oct 90 19:54 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03764; Tue, 2 Oct 90 19:40:59
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Tue, 2 Oct 90 19:54 MST
Date: 2 Oct 90 16:44:38 GMT
From: midway!quads.uchicago.edu!goer@handies.ucar.edu
Subject: avoid duplicate procedure id's
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <265726196049403217@Arizona.edu>
Message-Id: <1990Oct2.164438.24792@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
As Icon code starts to pack my filesystem more and more, duplicate
procedure and record names have become a greater and greater problem,
especially when the duplicate names turn up in files intended as
Icon libraries.
Here's a program to make sure that duplicate procedure names don't
invade your libraries (or, for that matter, the IPL - which to start
with has a few duplicate names).
Certainly, in some cases, duplicate names are desirable (as when a
library exists in several OS-specific implementations). In most
cases, though, they are not. The following package might be especi-
ally useful to those who intend to post code. At least this way,
they can be sure their procedure names don't conflict with a known
body of programs that everyone has access to (i.e. the IPL).
-Richard
P.S. I write these things mainly for myself, so don't expect them
to be "polished." Naturally, though, I'll hungrily eat up any
bug reports, and either re-post or send out individual diffs,
depending on which seems more appropriate at the time.
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 10/02/1990 16:10 UTC by goer@sophist.uchicago.edu
# Source directory /u/richard/Tmp
#
# existing files will NOT be overwritten unless -c is specified
# This format requires very little intelligence at unshar time.
# "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
#
#
#
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 8344 -r--r--r-- duplproc.icn
# 692 -rw-r--r-- README
# 623 -rw-r--r-- Makefile.dist
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= duplproc.icn ==============
if test -f 'duplproc.icn' -a X"$1" != X"-c"; then
echo 'x - skipping duplproc.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting duplproc.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'duplproc.icn' &&
X############################################################################
X#
X# Name: duplproc.icn
X#
X# Title: Find duplicate procedure/record identifiers
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.1
X#
X############################################################################
X#
X# Use this if you plan on posting code!
X#
X# Finddupl.icn compiles into a program which will search through
X# every directory in your ILIBS environment variable (and/or in the
X# directories supplied as arguments to the program). If it finds any
X# duplicate procedure or record identifiers, it will report this on
X# the standard output.
X#
X# It is important to try to use unique procedure names in programs
X# you write, especially if you intend to link in some of the routines
X# contained in the IPL. Checking for duplicate procedure names has
X# been somewhat tedious in the past, and many of us (me included)
X# must be counted as guilty for not checking more thoroughly. Now,
X# however, checking should be a breeze.
X#
X############################################################################
X#
X# Links: none
X#
X# Requires: Unix (MS-DOS may work; dunno)
X#
X############################################################################
X
Xrecord procedure_stats(name, file, lineno)
X
Xprocedure main(a)
X
X local proc_table, fname, elem, lib_file, tmp
X
X # usage: duplproc [libdirs]
X #
X # Where libdirs is a series of space-separated directories in
X # which relevant library files are to be found. To the
X # directories listed in libdirs are added any directories found in
X # the ILIBS environment variable.
X
X proc_table := table()
X
X # Put all command-line option paths, and ILIBS paths, into one sorted
X # list. Then get the names of all .icn filenames in those paths.
X every fname := !get_icn_filenames(getlibpaths(a)) do {
X # For each .icn filename, open that file, and find all procedure
X # calls in it.
X if not (lib_file := open(fname, "r")) then
X write(&errout,"Can't open ",fname," for reading.")
X else {
X # Find all procedure calls in lib_file.
X every elem := !get_procedures(lib_file,fname) do {
X if /proc_table[elem.name] := set()
X then insert(proc_table[elem.name],elem)
X else {
X write("\"", elem.name, "\"",
X " is defined in ",*proc_table[elem.name]+1," places:")
X every tmp := !proc_table[elem.name] do
X write(" ",tmp.file, ", line ",tmp.lineno)
X write(" ",elem.file, ", line ", elem.lineno)
X }
X }
X close(lib_file)
X }
X }
X
X
Xend
X
X
X
Xprocedure getlibpaths(ipl_paths)
X
X # Unite command-line args and ILIBS environment variable into one
X # path list.
X
X local i, path
X
X # Make sure all paths have a consistent format (one trailing slash).a
X if *\ipl_paths > 0 then {
X every i := 1 to *ipl_paths do {
X ipl_paths[i] := fixup_path(ipl_paths[i])
X }
X ipl_paths := set(ipl_paths)
X }
X else ipl_paths := set()
X
X # If the ILIBS environment variable is set, read it into
X # ipl_paths. Colons *or* spaces are okay as separators.
X getenv("ILIBS") ? {
X while path := tab(upto(' :')) do {
X insert(ipl_paths, fixup_path(path))
X tab(many(' :'))
X }
X insert(ipl_paths, fixup_path(tab(0)))
X }
X
X return sort(ipl_paths)
X
Xend
X
X
X
Xprocedure fixup_path(s)
X # Make sure paths have a consistent format.
X return "/" ~== (trim(s,'/') || "/")
Xend
X
X
X
Xprocedure get_procedures(intext,fname)
X
X # Extracts the names of all procedures declared in file f.
X # Returns them in a list, each of whose elements have the
X # form record procedure_stats(procedurename, filename, lineno).
X
X local psl, f_pos
X static name_chars
X initial {
X name_chars := &ucase ++ &lcase ++ &digits ++ '_'
X }
X
X # Initialize procedure-name list, line count.
X psl := list()
X line_no := 0
X
X # Find procedure declarations in intext.
X while line := read(intext) & line_no +:= 1 do {
X take_out_comments(line) ? {
X if tab(match("procedure")) then {
X tab(many(' \t')) &
X put(psl, procedure_stats(
X "main" ~== tab(many(name_chars)), fname, line_no))
X }
X }
X }
X
X return psl # returns empty list if no procedures found
X
Xend
X
X
X
Xprocedure take_out_comments(s)
X
X # Commented-out portions of Icon code - strip 'em. Fails on lines
X # which, either stripped or otherwise, come out as an empty string.
X #
X # BUG: Does not handle lines which use the _ string-continuation
X # notation. Typically take_out_comments barfs on the next line.
X
X local i, j, c, c2
X
X s ? {
X tab(many(' \t'))
X pos(0) & fail
X find("#") | (return trim(tab(0),' \t'))
X match("#") & fail
X (s2 <- tab(find("#"))) ? {
X c2 := &null
X while tab(upto('\\"\'')) do {
X case c := move(1) of {
X "\\" : {
X if match("^")
X then move(2)
X else move(1)
X }
X default: {
X if \c2
X then (c == c2, c2 := &null)
X else c2 := c
X }
X }
X }
X /c2
X }
X return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
X }
X
Xend
X
X
X
Xprocedure get_icn_filenames(lib_paths)
X
X # Return the names of all .icn files in all of the paths in the
X # list lib_paths. The dir routine used depends on which OS we
X # are running under.
X
X local procedure_stat_list
X static get_dir
X initial get_dir := set_getdir_by_os()
X
X procedure_stat_list := list()
X # Run through every possible path in which files might be found,
X # and get a list of procedures contained in those files.
X every procedure_stat_list |||:= get_dir(!lib_paths)
X
X return procedure_stat_list
X
Xend
X
X
X
Xprocedure set_getdir_by_os()
X
X if find("UNIX", &features)
X then return unix_get_dir
X else if find("MS-DOS", &features)
X then return msdos_get_dir
X else stop("Your operating system is not (yet) supported.")
X
Xend
X
X
X
Xprocedure msdos_get_dir(dir)
X
X # Returns a sorted list of all filenames (full paths included) in
X # directory "dir." The list is sorted. Fails on invalid or empty
X # directory. Aborts if temp file cannot be opened.
X #
X # Temp files can be directed to one or another directory either by
X # manually setting the variable temp_dir below, or by setting the
X # value of the environment variable TEMPDIR to an appropriate
X # directory name.
X
X local in_dir, filename_list, line
X static temp_dir
X initial {
X temp_dir :=
X (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
X ".\\"
X }
X
X # Get name of tempfile to be used.
X temp_name := get_dos_tempname(temp_dir) |
X stop("No more available tempfile names!")
X
X # Make sure we have an unambiguous directory name, with backslashes
X # instead of Unix-like forward slashes.
X dir := trim(map(dir, "/", "\\"), '\\') || "\\"
X
X # Put dir listing into a temp file.
X system("dir "||dir||" > "||temp_name)
X
X # Put tempfile entries into a list, removing blank- and
X # space-initial lines. Exclude directories (i.e. return file
X # names only).
X in_dir := open(temp_name,"r") |
X stop("Can't open temp file in directory ",temp_dir,".")
X filename_list := list()
X every filename := ("" ~== !in_dir) do {
X match(" ",filename) | find(" <DIR>", filename) & next
X # Exclude our own tempfiles (may not always be appropriate).
X filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
X if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
X then put(filename_list, map(dir || filename))
X }
X
X # Clean up.
X close(in_dir) & remove(temp_name)
X
X # Check to be sure we actually managed to read some files.
X if *filename_list = 0 then fail
X else return sort(filename_list)
X
Xend
X
X
X
Xprocedure get_dos_tempname(dir)
X
X # Don't clobber existing files. Get a unique temp file name for
X # use as a temporary storage site.
X
X every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
X temp_file := open(temp_name,"r") | break
X close(temp_file)
X }
X return \temp_name
X
Xend
X
X
X
Xprocedure unix_get_dir(dir)
X
X dir := trim(dir, '/') || "/"
X filename_list := list()
X in_dir := open("/bin/ls -F "||dir, "pr")
X every filename := ("" ~== !in_dir) do {
X match("/",filename,*filename) & next
X if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
X then put(filename_list, trim(dir || filename, '*'))
X }
X close(in_dir)
X
X if *filename_list = 0 then fail
X else return filename_list
X
Xend
SHAR_EOF
true || echo 'restore of duplproc.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
echo 'x - skipping README (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XSee the comments prepended to duplproc.icn for a statement of what
Xthis program is and does. To create it on a Unix system, you can
Xjust mv Makefile.dist to Makefile and make. If you want to install
Xit, type "make Install" as root. Be sure to check the Makefile
Xfirst, though, to be sure the installation routine uses the correct
Xdirectories and permissions for your system.
X
XUsers of other systems, you're on your own. This may work under
XMS-DOS, but it hasn't been tested on anything other than Unix. The
Xreason for the OS-specificity is duplproc's need to get a listing
Xof various filenames in various directories at run-time. This has
Xto be implemented on a system-by-system basis.
SHAR_EOF
true || echo 'restore of README failed'
rm -f _shar_wnt_.tmp
fi
# ============= Makefile.dist ==============
if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile.dist (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Makefile.dist (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
XPROGNAME = duplproc
X
X# Please edit these to reflect your local file structure & conventions.
XDESTDIR = /usr/local/bin
XOWNER = bin
XGROUP = bin
X
XSRC = $(PROGNAME).icn
X
X$(PROGNAME): $(PROGNAME).icn
X icont $(PROGNAME).icn
X
X# Pessimistic assumptions regarding the environment (in particular,
X# I don't assume you have the BSD "install" shell script).
Xinstall: $(PROGNAME)
X @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
X cp $(PROGNAME) $(DESTDIR)/
X chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
X chown $(OWNER) $(DESTDIR)/$(PROGNAME)
X @echo "\nInstallation done.\n"
X
Xclean:
X -rm -f *~ .u?
X -rm -f $(PROGNAME)
SHAR_EOF
true || echo 'restore of Makefile.dist failed'
rm -f _shar_wnt_.tmp
fi
exit 0
From icon-group-request@arizona.edu Wed Oct 3 00:55:10 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA15103; Wed, 3 Oct 90 00:55:10 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 3 Oct 90 00:54 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17179; Wed, 3 Oct 90 00:38:57
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 3 Oct 90 00:54 MST
Date: 2 Oct 90 09:45:56 GMT
From: mcsun!cernvax!chx400!hslrswi!naz@uunet.uu.net
Subject: Klondike: the game
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <262D34D74729403341@Arizona.edu>
Message-Id: <1562@hslrswi.UUCP>
Organization: Hasler AG
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
This is a card game, Solitaire to be precise, Klondike to be preciser.
I have built this mostly as a means of learning Icon. I can't claim
credit for the user interface. Some years ago I snatched a similar
(much faster) game built for PCs by Allyn Wade. I have added a few
features in my version. This one should work on any ANSI-compatible
terminal with 25 lines, but I don't have the opportunity to test that
here. It works OK on my AT clone.
I understand that in Los Vegas one can lose money with this game too.
One buys a deck of cards for $55, and then you get $5 back for each
card that you put in the Ace piles. Running my program for several
thousand games, I get an average of about 10.4 cards in the ace piles.
But the algorithm used (to date) is simplistic -- the goal for
future versions is to discover better algorithms so that I can get
rich quick in Los Vegas. :-)
I think this version basically works. There is probably a bug or two
left in Undo. Sorry, no documentation yet. I'm still trying to get
my head wrapped around this Icon concept of generators, so I'm sure
the code could be better. Bug fixes and suggestions for improvement
are welcome.
NHA
---
PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
X.400: naz@hslrswi.hasler
UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET
----------- cut here -------------- cut here -------------------- cut here ---
#klondike.icn 900720 NHA
#The Klondike version of Solitaire.
# Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display.
#
# TO FIX:
#
# - Undo is not 100%
#
#
# TO DO:
#
# - Implement an heuristic to discover optimal play strategy,
# with goal-directed evaluation and suchlike fancy stuff.
# The basic idea is to tailor find1() such that its first suggestion
# usually turns out to be the best one. Measure this by trying the
# entire tree of possibilities, recording what % of the time the
# first suggestion was actually the best one.
#
record card(suit, rank) #suit is 1..4, rank is 1..13
# constants
global suitID #suit identification chars
global isDOS # 1 when running under DOS
global monochrome # 1 when running Black&White
# Video control strings (ANSI.SYS)
global ESC
global Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL
global Vred, Vblack #suit color strings
global color #list of suit color strings
# variables
global deckUp, deckDown, stackUp, stackDown #collections of card
global pile #ace piles - top rank only
global totalGames, totalAces #statistics
global debugging, automaticAce, shuffling #command-line flags
global clicking # 1 for audible feedback
global randomSeed #determinant for this game
global ops #list of all operations
# e r r o r
# Internal consistency check failed -- reveal all and die.
procedure error (x)
display ()
runerr (500, x)
end #error
# i n i t C o n s t a n t s
# Initialize the program "constants". These are actually variables that
# are set just once at the beginning of the world.
procedure initConstants ()
local i
#ensure that we are dealing with an ANSI-compatible screen
writes ("\33[6n") #request cursor position report
#NOTE that the first character to match should be an ESCape.
#Unfortunately, reads() seems to eat that character
if not match ("[", reads (&input, 8)) then
stop ("Klondike: requires ANSI.SYS screen driver")
isDOS := if find("MS-DOS", &host) then 1 else 0
if isDOS = 0 then
monochrome := 1
else {
i := ord (Peek([16r40, 16r49])) #BIOS display mode byte
case i of {
2 : monochrome := 1
3 : monochrome := 0
7 : monochrome := 1
default : stop ("Klondike: unknown display mode ", i)
}
}
ESC := "\33" #escape character
VclearAll := "\33[2J" #also homes cursor
VclearEOL := "\33[K"
Vnormal := "\33[0m"
Vbold := "\33[1m"
Vblink := "\33[5m"
Vreverse := "\33[7m"
if monochrome = 0 then {
Vred := "\33[0;47;31m" # "extra" 0 seems to be necessary
Vblack := "\33[0;47;30m"
} else {
Vred := Vnormal
Vblack := Vreverse
}
# Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades
suitID := if isDOS ~= 0 then "\3\4\5\6" else "HDCS"
color := [Vred, Vred, Vblack, Vblack]
end #initConstants
# i n i t S c r e e n
# Initialize output and write the fixed parts of the screen.
# initConstants() must have been called earlier.
procedure initScreen ()
local i
if monochrome = 0 then writes ("\33[=3h") #25x80 color text mode
else writes ("\33[=2h") #25x80 B&W text mode
writes (VclearAll, "\33[=7l") #clear screen, prevent wrap
every i := 1 to 7 do
writeStackNumber (i, Vnormal)
every i := 2 to 25 do
writes ("\33[",i,";",64,"H\272") #vertical stripe
writes ("\33[2;64H\311\315\315\315\315SOLITAIRE\315\315\315\315")
end #initScreen
# w r i t e S t a c k N u m b e r
# Write the indicated stack number with the specified video attribute.
# Cursor position is preserved -- WARNING: THIS IS NOT NESTABLE.
procedure writeStackNumber (num, attr)
writes (ESC, "[s") #save cursor position
writeCursor (1, [2,11,20,29,38,47,56][num])
writes (attr, num, Vnormal)
writes (ESC, "[u") #restore cursor position
end #writeStackNumber
# w r i t e C u r s o r
# Position the cursor to row,col.
# Screen origin (top left corner) is row=1 and col=1.
procedure writeCursor (row, col)
writes ("\33[", row, ";", col, "H")
end #writeCursor
# w r i t e F r o n t
# Displays an image of the specified card fronts at the specified spot.
# WARNING: this eats the list that you provide -- pass a copy() if you care!!
# Top left corner of the first card will be placed at the specified position.
# Successive cards are displayed two rows higher (lower position on the screen).
# Cursor need not be in any particular position before this, and is left
# in a random position afterwards. Video is left normal (not reversed).
# Cards are 7 columns wide by 5 rows tall.
# With 25 rows, we can put 12 cards in a stack (assuming we start in row 2).
# But if there are 11 in the stack we can only display 4 rows of the top card.
# If there are 12 cards, we can only display 2 rows of the topmost card.
##We can only write a row at a time due to a problem with ANSI col 80 handling.
procedure writeFront (cardlist, row, col)
local suit, rank, card
while card := get(cardlist) do {
#first 2 rows of card
writeCursor (row+0, col);
writes (Vreverse, "\332\304\304\304\304\304\277")
writeCursor (row+1, col);
writes ("\263", color[card.suit], "A23456789TJQK"[card.rank],
suitID[card.suit], Vreverse, " \263")
if (*cardlist = 0) & (row < 24) then {
#next 2 rows of top card unless it's the 12th card on the stack
writeCursor (row+2, col);
writes (Vreverse, "\263 \263")
writeCursor (row+3, col);
writes ("\263 ", color[card.suit], "A23456789TJQK"[card.rank],
suitID[card.suit], Vreverse, "\263")
if row < 22 then {
#last row of card unless it's the 11th on the stack
writeCursor (row+4, col);
writes ("\300\304\304\304\304\304\331")
}
}
row +:= 2
}
writes (Vnormal)
end #writeFront
# w r i t e B a c k
# Puts an image of the back of a card at the specified spot on the screen.
# Except that this shows the back instead of the front of the card,
# this is identical to writeFront().
procedure writeBack (row, col)
static backLine
initial {
backLine := repl ("\260", 7)
}
writeCursor (row+0, col); writes (backLine)
writeCursor (row+1, col); writes (backLine)
writeCursor (row+2, col); writes (backLine)
writeCursor (row+3, col); writes (backLine)
writeCursor (row+4, col); writes (backLine)
end #writeBack
# w r i t e B l a n k
# Blanks a card-sized area at the specified spot on the screen.
# Except that this writes blanks instead of the back of a card,
# this is identical to writeBack().
procedure writeBlank (row, col)
static blankLine
initial {
blankLine := repl (" ", 7)
}
writeCursor (row+0, col); writes (blankLine)
writeCursor (row+1, col); writes (blankLine)
writeCursor (row+2, col); writes (blankLine)
writeCursor (row+3, col); writes (blankLine)
writeCursor (row+4, col); writes (blankLine)
end #writeBlank
# w r i t e S t a c k
# Display the specified stack. Left end is bottom of stackUp, top of stackDown.
# Stacks start in row 2, column1; with 2 columns between stacks.
# last[] holds, for each stack, the total number of visible cards
# on that stack as of the last time writeStack() was called. This allows
# us to simply draw (or erase) the cards that have been added (or subtracted).
# By special arrangement, this routine can be called with a negative stack
# number! This is a hint that our idea of what is on the display is actually
# wrong, and therefore the entire stack needs to be re-displayed. This can
# happen in two situations: 1) in refreshScreen(), the entire screen is cleared
# before calling writeStack(); 2) in undo() when undoing a move between
# stacks, the bottom card needs to be changed, although the normal algorithm
# would consider that it is already correctly displayed. Note that in neither
# case is the stack shrinking, therefore we don't need to worry about erasing
# any cards that were displayed last time.
procedure writeStack (n)
local row, col, s
static last, blankLine, firstRow, lastRow
initial {
last := [0,0,0,0,0,0,0]
blankLine := repl (" ", 7)
firstRow := [2,4,6,8,10,12,14,16,18,20,22,24] #first row of a card
lastRow := [6,8,10,12,14,16,18,20,22,24,25,25] #last row of a card
}
if n < 0 then {
n := -n
last[n] := 0 #force complete re-write
}
col := 1 + ((n -1) * 9) #leftmost column for this stack
if *stackUp[n] <= last[n] then {
#the stack just got smaller (or stayed the same)
#blank out two rows for each card that has been removed
row := lastRow[last[n]] #last row used by top card
while *stackUp[n] < last[n] do {
writeCursor (row-0, col); writes (blankLine)
writeCursor (row-1, col); writes (blankLine)
row -:= 2
last[n] -:= 1 #count and update simultaneously
}
if *stackUp[n] ~= last[n] then error (last[n])
#re-write new top card
if *stackUp[n] = 0 then
if *stackDown[n] = 0 then
writeBlank (2, col)
else
writeBack (2, col)
else
writeFront ([stackUp[n][-1]], firstRow[last[n]], col)
} else {
#the stack just got bigger -- display new cards
s := stackUp[n][last[n]-(*stackUp[n]):0]
writeFront (s, firstRow[last[n]+1], col)
last[n] := *stackUp[n] #remember how much is displayed
}
writeCursor (2, (7 + col))
writes (" 123456???"[1+*stackDown[n]]) #display the number of hidden cards
end #writeStack
# w r i t e P i l e
# Displays an image of the specified ace pile, face up (or blank if empty)
procedure writePile (n)
static pileRow, pileCol
initial {
pileRow := [3,3,9,9]
pileCol := [66,74,66,74]
}
if 0 = pile[n] then writeBlank (pileRow[n], pileCol[n])
else writeFront ([card(n,pile[n])], pileRow[n], pileCol[n])
end #writePile
# w r i t e D e c k D o w n
# Displays an image of deckDown (the face-down deck) in the proper spot.
procedure writeDeckDown ()
if 0 < *deckDown then
writeBack (21, 74)
else
writeBlank (21, 74)
writeCursor (20, 76)
writes (right(*deckDown, 2))
end #writeDeckDown
# w r i t e D e c k U p
# Displays an image of deckUp (the face-up deck) in the proper spot.
procedure writeDeckUp ()
if 0 < *deckUp then
writeFront ([deckUp[1]], 21, 66)
else
writeBlank (21, 66)
writeCursor (20, 68)
writes (right(*deckUp, 2))
end #writeDeckUp
# r e f r e s h S c r e e n
# Re-write entire screen.
procedure refreshScreen ()
local i
initScreen ()
every i := 1 to 7 do
writeStack (-i)
every i := 1 to 4 do
writePile (i)
writeDeckDown ()
writeDeckUp ()
end #refreshScreen
# w r i t e I n f o
# Displays a new short string (up to 12 printing characters) in the
# officially approved information area of the screen.
# An empty string results in clearing the area and restoring normal attributes.
procedure writeInfo (s)
writeCursor (16, 66)
writes (Vnormal, VclearEOL)
if *s ~= 0 then writes (s)
end #writeInfo
# c l i c k
# Make a quick sound to accompany card transfers
procedure click ()
local x
if (clicking ~= 0) & (isDOS ~= 0) then {
x := InPort (16r61)
OutPort (16r61, 3)
OutPort (16r61, x)
}
end #click
# g e t C m d C h a r
# Returns an upper-case command character, echoed to current cursor position.
# Fails if character wasn't "normal" and complaint was made.
# For ESC, abort information is written, and ESC is returned.
# Normal calling sequence (from within a command procedure) is thus:
# until (s := getCmdChar ())
# if s == ESC then fail
procedure getCmdChar ()
local s
s := getch () #get command character
if s == "\0" then { #non-ASCII character
getch () #discard keyboard scan code
complain ()
fail
}
s := map (s, &lcase, &ucase)
if s == ESC then
writeInfo (Vbold || "Cmd Aborted.")
else
writes (s) #echo the command character
return s
end #getCmdChar
# f i t O n S t a c k
# Given a card and a stack number, fail unless card can be added to the stack.
# Note that we disallow putting an Ace on a stack, period. This prevents
# ever building a stack with 13 cards, which we can't display in 25 rows.
# onto a stack, this problem is avoided.
##This can certainly be done better...
procedure fitOnStack (c, n)
local top #top card on stack
if *stackUp[n] = 0 then {
if 0 < *stackDown[n] then stop ("fitOnStack(): Up empty, Down not");
if c.rank ~= 13 then fail #only a king can go to empty stack
} else {
top := stackUp[n][-1] #copy of top card
if (c.rank ~= (top.rank - 1)) then fail #wrong rank
if (c.suit < 3) & (top.suit < 3) then fail #same color
if (c.suit > 2) & (top.suit > 2) then fail #same color
if *stackUp[n] = 12 then fail #no room for ace
if c.rank = 1 then fail #no ace on stack
}
return #success
end #fitOnStack
# c h e c k 4 a c e
# Only has an effect when global automaticAce is set!
# Given a stack number, check for an ace as the top of stackUp.
# If present, move it over to it's ace pile, turn over the next card
# from stackDown, and check again.
# Must not be more than one up card in stack.
# Returns a string of the operations performed.
procedure check4ace (n)
local c, op
op := ""
if automaticAce ~= 0 then {
if 1 < *stackUp[n] then error (*stackUp[n])
while 0 < *stackUp[n] do {
c := stackUp[n][1] #copy of (top = bottom) up card
if c.rank = 1 then { #it's an ace!
pop (stackUp[n]) #remove it from the stack
pile[c.suit] := 1 #move to ace pile
op ||:= c.suit
push (stackUp[n], get(stackDown[n])) #turn over card underneath
writeStack (n)
writePile (c.suit)
click ()
} else
break #not an ace
}
}
return op
end #check4ace
# m o v e S t a c k
# Move a stack to another stack, no questions asked.
# Updates video and audio.
# Returns any automatic ace operations that were done as a consequence.
##It would be nice to do this in a visually and audibly more satisfying way
procedure moveStack (src, dst)
local i
every i := 1 to *stackUp[src] do
put (stackUp[dst], get(stackUp[src]))
put (stackUp[src], get(stackDown[src]))
writeStack (src)
writeStack (dst)
click ()
return check4ace (src)
end #moveStack
# a u t o m a t i c
# Run the game, as far as possible, untouched by human hands
procedure automatic ()
local s, thumbCount
thumbCount := 0
repeat {
if kbhit () then
return #stopped by human intervention
if pile[1] = pile[2] = pile[3] = pile[4] = 13 then
return #victory
if s := find1() then {
push (ops, move1 ("M" || s || "0"))
thumbCount := 0
} else { #no good move found -- thumb
if not (s := thumb()) then
return #no cards left to thumb through
push (ops, s)
thumbCount := if s == "T" then thumbCount + 1 else 0
if ((*deckUp + *deckDown + 2) / 3 + 1) < thumbCount then
return #end of the line
}
}
end #automatic
# c o n t i n u o u s
# Plays automatic games -- forever (or until any keystroke)
procedure continuous()
writes ("ontinuous")
repeat {
writeInfo (string(totalGames) || " " || string(totalAces))
automatic()
if kbhit() then {
if getch() == "\0" then #eat stopping char(s)
getch()
return
} else
totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
newGame()
}
end #continuous
# h e l p
# Provide information
procedure help ()
write (VclearAll, Vnormal)
write ("Klondike version 1.1 901002 NHA\t\t", &version)
write ("\n\nThe following commands are available:\n")
write ("\t^L\tre-draw screen")
write ("\tA\tAutomatic mode -- plays 1 game by itself until any key is hit")
write ("\tC\tContinuous mode -- plays games continuously until any key hit")
if debugging ~= 0 then
write ("\tD\tDebug")
write ("\tH,?\tHelp, this help screen")
write ("\tM\tMove card (or stack) from Deck/Stack to Stack/Ace pile")
write ("\tQ\tQuit this game")
write ("\tS\tSuggest (another) possible move")
write ("\tT\tThumb through the deck")
write ("\tU\tUndo -- back up one move")
write ("\tESC\tEscape -- abort current command")
write ("\n\ntotalGames = ", totalGames, " totalAces = ", totalAces)
write ("\n\nPress any key to resume game")
if getch() == "\0" then getch()
refreshScreen ()
end #help
# m o v e 1
# This is the internal move, taking a operation string. No Thumbs allowed.
# Upon success it returns the (possibly modified) operation string.
procedure move1 (op)
local src, dst, c, moved
if op[1] ~== "M" then error (op)
src := op[2]
dst := op[3]
moved := 0
if src == "D" then {
c := deckUp[1]
if dst == "A" then { # Deck -> Ace
if c.rank = (pile[c.suit] + 1) then {
op[4] := c.suit # Deck -> Ace: fits - do it
pile[c.suit] +:= 1
writePile (c.suit)
moved := 1
} else
fail # Deck -> Ace: doesn't fit
} else { # Deck -> stack
if fitOnStack (c, dst) then {
put (stackUp[dst], c) # Deck -> stack: fits - do it
writeStack (dst)
moved := 1
} else
fail # Deck -> stack: doesn't fit
}
while moved ~= 0 do {
pop (deckUp)
writeDeckUp () # Deck -> somewhere, with success
click ()
moved := 0
if automaticAce ~= 0 then {
if (c := deckUp[1]).rank = 1 then { #automatic Ace handling
pile[c.suit] := 1
op ||:= c.suit
writePile (c.suit)
moved := 1
}
}
}
} else {
if dst == "A" then { # stack -> Ace
c := stackUp[src][-1] #copy of card on top of stack
if c.rank = (pile[c.suit] + 1) then {
op[4] := c.suit # stack -> Ace: fits - do it
pile[c.suit] +:= 1
pull (stackUp[src])
writeStack (src)
click ()
writePile (c.suit)
if *stackUp[src] = 0 then {
op[4] +:= 4 #mark this case for undo()
put (stackUp[src], get(stackDown[src])) #turn over a card
writeStack (src)
click ()
op ||:= check4ace (src)
}
} else {
fail # stack -> Ace: doesn't fit
}
} else { # stack -> stack
if fitOnStack (stackUp[src][1], dst) then {
op[4] := *stackUp[src] # stack -> stack: fits - do it
op ||:= moveStack (src, dst)
} else
fail # stack -> stack: doesn't fit
}
}
return op #success
end #move1
# m o v e
# Move a card from deck to stack, or from stack to ace pile,
# or move a stack to another stack.
# Fails if this is not possible
# This is the routine that interacts with the user.
procedure move ()
local src, dst, c, op, moved
writes ("ove " || Vbold);
until (src := getCmdChar ())
if src == ESC then return
if src == "D" then {
if *deckUp = 0 then fail
} else {
if not any ('1234567', src) then fail
if *stackUp[src] = 0 then fail
writeStackNumber (src, Vblink)
}
writes (Vnormal || " to " || Vbold)
until (dst := getCmdChar ())
if src ~== "D" then writeStackNumber (src, Vnormal)
if dst == ESC then return
if not any ('A1234567', dst) then fail
if dst == src then fail
return push (ops, move1("M" || src || dst || "0"))
end #move
# f i n d 1
# Find a (reasonable) possible move in this situation
procedure find1 ()
local i, j, k, c
#look at deckUp to see if the top card fits on a pile
if c := deckUp[1] then
if c.rank = (pile[c.suit] + 1) then
suspend "DA"
#look at deckUp to see if the top card fits on a stack
if c := deckUp[1] then
every i := 1 to 7 do
if fitOnStack (c, i) then
suspend "D" || string(i)
#look at each stack to see if top card can be put on ace pile
every i := 1 to 7 do
if c := stackUp[i][-1] then #top card
if c.rank = (pile[c.suit] + 1) then
suspend string(i) || "A"
#look at each stack to see if something can be (reasonably) moved
every i := 7 to 1 by -1 do
every j := 1 to 7 do
if fitOnStack (stackUp[i][1], j) then {
if (0 < *stackDown[i]) then
suspend string(i) || string(j)
else {
# possibility, but since there are no cards hidden under
# this pile, we reject it UNLESS there are no empty slots
# AND one of the following is true:
# 1) deckUp[1].rank = 13
# 2) there is a king with cards hidden beneath it
c := 0 #number of empty stacks
every k := 1 to 7 do
if *stackUp[k] = 0 then c +:= 1
if c = 0 then
if (deckUp[1].rank = 13) |
(every k := 1 to 7 do
if (stackUp[k][1].rank = 13) &
(0 < *stackDown[k]) then
break #success
)
then
suspend string(i) || string(j)
}
}
#punt
fail
end #find1
# s u g g e s t
# Suggest a (reasonable) possible move in this situation.
# Repeated invocations produce successive possibilities, until the
# only thing left to do is Thumb. After this, it cycles around to the start.
procedure suggest (another)
static suggestions, i
local s, ss
writes ("uggest")
if another = 0 then {
suggestions := [] #generate a new list of suggestions
every put (suggestions, find1())
i := 0
}
if ss := suggestions[i+:=1] then {
s := "Move " || if ss[1] == "A" then "Ace"
else if ss[1] == "D" then "Deck"
else ss[1]
s ||:= " to " || if ss[2] == "A" then "Ace" else ss[2]
writeInfo (s)
} else {
writeInfo ("Thumb")
i := 0
}
end #suggest
# t h u m b
# Move to next spot in deckDown
# Returns the operation performed (usually just "T"), or fail if none possible.
procedure thumb ()
local c, op, moved
if *deckDown = *deckUp = 0 then
return complain() #no cards left in the deck
op := "T"
if *deckDown = 0 then
while push (deckDown, pop(deckUp))
push (deckUp, get(deckDown))
push (deckUp, get(deckDown))
push (deckUp, get(deckDown))
moved := 1
writeDeckDown ()
while moved ~= 0 do {
writeDeckUp ()
click ()
moved := 0
if automaticAce ~= 0 then {
if (c := deckUp[1]).rank = 1 then {
pop (deckUp)
pile[c.suit] := 1
op ||:= c.suit
writePile (c.suit)
moved := 1
}
}
}
return op
end #thumb
# u n d o
# backup one move, including any automatic ace moves
procedure undo ()
local op, suit
writes ("ndo")
if op := pop (ops) then {
writeInfo (op)
# op looks like: Msdixxx
# where x is an [optional] number 1..4 of an ace pile
# and s is either a stack number or "D"
# and d is either "A" or a number 1..7 of a stack
# and i is an extra piece of info which may be valid
case op[1] of {
"M" : {
if (*op < 4) | ((automaticAce = 0) & (4 < *op)) then
error (op)
if op[2] == "D" then {
#Move cards from Ace piles to deck, starting at end
while 4 < *op do {
suit := op[-1]
pile[suit] := 0
writePile (suit)
push (deckUp, card(suit,1))
writeDeckUp ()
click ()
op[-1] := ""
}
if op[3] == "A" then {
# unMove Deck to Ace op[4]
suit := op[4]
push (deckUp, card(suit,pile[suit]))
pile[suit] -:= 1
writePile (suit)
} else {
# unMove Deck to stack op[3]
push (deckUp, pull(stackUp[op[3]]))
writeStack (op[3])
}
writeDeckUp ()
} else {
#Move cards from Ace piles to stack, starting at end
while 4 < *op do {
suit := op[-1]
pile[suit] := 0
writePile (suit)
if 1 < *stackUp[op[2]] then error (*stackUp[op[2]])
push (stackDown[op[2]], pull(stackUp[op[2]]))
push (stackUp[op[2]], card(suit,1))
writeStack (op[2])
click ()
op[-1] := ""
}
if op[3] == "A" then {
# unMove stack op[2] to Ace pile op[4]
suit := op[4]
if 4 < suit then {
suit -:= 4 #ace pile card was last on stack
if 1 < *stackUp[op[2]] then
error (*stackUp[op[2]])
push (stackDown[op[2]], pull(stackUp[op[2]]))
}
put (stackUp[op[2]], card(suit,pile[suit]))
pile[suit] -:= 1
writePile (suit)
writeStack (op[2])
} else {
# unMove top op[4] cards on stack op[2]
# to stack op[3]
if 1 < *stackUp[op[2]] then error (*stackUp[op[2]])
push (stackDown[op[2]], pull(stackUp[op[2]]))
every 1 to op[4] do
push (stackUp[op[2]], pull(stackUp[op[3]]))
writeStack (op[3])
writeStack (-op[2])
}
}
}
"T" : {
if (automaticAce = 0) & (*op ~= 1) then error (op)
### op looks like: Txx
### where x is an optional number 1..4 of an ace pile
### There can be 0,1,2,3, or 4 of these x's.
# move cards from Ace piles to deck, starting at end
while 1 < *op do {
suit := op[-1]
pile[suit] := 0
writePile (suit)
push (deckUp, card(suit,1))
writeDeckUp ()
click ()
op[-1] := ""
}
# then undo the Thumb operation itself
if *deckUp = 0 then
while push(deckUp, pop(deckDown))
else {
push (deckDown, pop(deckUp))
until (*deckUp % 3) = 0 do
push (deckDown, pop(deckUp))
}
writeDeckUp ()
writeDeckDown ()
}
default : stop ("Klondike: unknown operation `", op, "' in ops[]")
}
click ()
} else
writeInfo ("Stack Empty")
end #undo
# c o m p l a i n
# Let the boob know he done something wrong
procedure complain ()
local i, x
writeInfo (Vbold || "INVALID")
if isDOS ~= 0 then {
x := InPort (16r61)
every i := 1 to 22 do
OutPort (16r61, 3)
OutPort (16r61, x)
}
end #complain
# t e r m i n a t e
# Parameter should be non-zero if termination is due to complete success.
# Returns success to quit this game and start another.
# Returns failure to just continue this game.j
# If program termination is wished, that is done right here.
procedure terminate (victory)
local s, avg
if victory ~= 0 then {
writeCursor (12, 22)
writes (Vbold, "Congratulations -- You've WON !!!", Vnormal)
s := "Y"
} else {
writes ("uit? ")
until (s := getCmdChar ())
if s == ESC then fail #abort the quit command
}
if s == "Y" then {
writeInfo (Vbold || "Another game? ")
until (s := getCmdChar ())
if s == ESC then fail() #didn't really want to quit anyway
if s == "Y" then return #please start a new game
#program termination requested
writes ("\33[=7h", Vnormal) #set cursor wrap mode, normal attr
writeCursor (17, 1)
totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
if 1 < totalGames then {
avg := string (real(totalAces) / real(totalGames))
if 4 < *avg then avg := avg[1+:4]
write (VclearAll, "In ", totalGames, " games, you put ", totalAces,
" cards on the ace piles, for an average of ", avg, " per game")
} else
writes (VclearAll, "You put ", totalAces, " cards on the ace piles")
exit ()
} else
fail #oops! didn't really want to quit
end #terminate
# s h o w L i s t
# Display a list of cards at the current cursor position.
# Intended for debugging only .
procedure showList (lst)
local i, c
every i := 1 to *lst do {
c := lst[i]
writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit],
Vnormal, " ")
}
end #showList
# c a r d 2 s t r
# Given a list of card records, returns a string representation.
# WARNING: this eats the list, so you might want to pass a copy().
# Intended for debugging only.
procedure card2str (ll)
local c, s
s := ""
while c := get(ll) do
s ||:= string(c.suit) || "123456789abcd"[c.rank]
return s
end #card2str
# s t r 2 c a r d
# Given a string [as generated by card2str()],
# return corresponding list of card records
procedure str2card (s)
local cc, i
cc := []
i := 0
while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1])))
return cc
end #str2card
# d e b u g
# Additional commands to support the implementer are done here.
procedure debug ()
local s, d, c, f, name
writes ("ebug ")
until (s := getCmdChar ())
case s of {
ESC : fail
"A" : {
writes ("gain")
&random := randomSeed
writeCursor (23, 1)
write (Vbold, "&random set. Quit to play this game again.",
Vnormal, VclearEOL)
}
"H"|"?" : {
writes (if s == "?" then "[help]" else "elp")
writeCursor (23, 1)
write (Vbold,
"Again, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{ACDST}.",
Vnormal, VclearEOL)
}
"M" : {
writes ("ove ")
until (s := getCmdChar ()) #Source
if s == ESC then fail
if s == "A" then fail
until (d := getCmdChar ()) #Destination
if d == ESC then fail
if d == s then fail
if not any('1234567', d) then fail
if s == "D" then {
if *deckUp = 0 then fail
put (stackUp[d], get(deckUp))
writeDeckUp ()
writeStack (d)
push (ops, "MD" || d || "0")
} else {
moveStack (s, d)
push (ops, "M" || s || d || "0")
}
}
"O" : {
writes ("ptions")
writeCursor (23, 1)
write (Vbold,
"automaticAce=", automaticAce, " shuffling=", shuffling,
" random seed=", randomSeed, " clicking=", clicking, ".",
Vnormal, VclearEOL)
}
"P" : {
writes ("eek ")
until (s := getCmdChar ())
if s == ESC then fail
writeCursor (23, 1)
writes (VclearEOL, Vnormal)
if any('1234567', s) then
showList (stackDown[s])
else if s == "D" then
showList (deckDown)
else if s == "U" then
showList (deckUp)
else
complain ()
}
"R" : {
writes ("estore")
until (s := getCmdChar ())
if s == ESC then fail
name := "klondike.sv" || s
writeCursor (23, 1)
if not (f := open (name, "r")) then
write (Vbold, "Can't read file ", name, ".",
Vnormal, VclearEOL)
else {
write (Vbold, "Restoring position from file ", name,
Vnormal, VclearEOL)
automaticAce := read (f, automaticAce)
clicking := read (f)
randomSeed := read (f)
shuffling := read (f)
&random := read (f)
totalGames := read (f)
totalAces := read (f)
every c := 1 to 4 do
pile[c] := read (f)
every c := 1 to 7 do {
stackUp[c] := str2card (read(f))
stackDown[c] := str2card (read(f))
}
deckUp := str2card (read(f))
deckDown := str2card (read(f))
ops := []
while push (ops, read (f))
close (f) | stop ("Klondike: close failed")
refreshScreen()
}
}
"S" : {
writes ("ave ")
until (s := getCmdChar ())
if s == ESC then fail
name := "klondike.sv" || s
writeCursor (23, 1)
if not (f := open (name, "c")) then
write (Vbold, "Can't create file ", name, ".",
Vnormal, VclearEOL)
else {
write (f, automaticAce)
write (f, clicking)
write (f, randomSeed)
write (f, shuffling)
write (f, &random)
write (f, totalGames)
write (f, totalAces)
every c := 1 to 4 do
write (f, pile[c])
every c := 1 to 7 do {
write (f, card2str(copy(stackUp[c])))
write (f, card2str(copy(stackDown[c])))
}
write (f, card2str(copy(deckUp)))
write (f, card2str(copy(deckDown)))
while write (f, pull(ops))
close (f) | stop ("Klondike: close failed")
write (Vbold, "Position saved in file ",name,
Vnormal, VclearEOL)
}
}
"T" : {
writes ("oggle ")
until (s := getCmdChar ())
if s == ESC then fail
case s of {
"A" : automaticAce:= if automaticAce=0 then 1 else 0
"C" : clicking := if clicking = 0 then 1 else 0
"D" : debugging := if debugging = 0 then 1 else 0
"S" : shuffling := if shuffling = 0 then 1 else 0
"T" : &trace := if &trace = 0 then -1 else 0
default : complain ()
} #case for Toggle
}
default : complain ()
} #case for Debug command
end #debug
# n e w G a m e
# Set up all the global variables for a new game
procedure newGame ()
local i, j, s
totalGames +:= 1
initScreen ()
#initialize deck, stacks, piles
ops := [] #no operations done yet
deckUp := [] #deck in hand, face-up
deckDown := [] #deck in hand, face-down
stackUp := list(7, 0) #columns on table, face up
stackDown := list(7, 0) #columns on table, face down
pile := list(4, 0) #aces - only top rank stored
every i := 1 to 4 do
every j := 1 to 13 do
put (deckDown, card(i, j)) #take cards out of the box
if shuffling ~= 0 then {
writeInfo (Vblink || "Shuffling")
every 1 to 100 do
?deckDown :=: ?deckDown
writeInfo ("")
}
every i := 1 to 7 do {
stackDown[i] := []
stackUp[i] := []
}
every i := 1 to 7 do {
push (stackUp[i], get(deckDown))
### writeStack (-i)
click ()
every j := (i+1) to 7 do {
push (stackDown[j], get(deckDown))
### writeStack (-j)
click ()
}
writeStack (-i)
}
writeDeckDown()
every i := 1 to 7 do
if *(s := check4ace (i)) ~= 0 then
push (ops, "M" || string(i) || "A" || string(integer(s) + 4))
end #newGame
# m a i n
procedure main (av)
local s, prevsCmd
initConstants()
#deal with command-line parameters
debugging := 0 # default is no debugging allowed
clicking := 1 # audible feedback sometimes helps
automaticAce := 1 # default is automatic ace handling
shuffling := 1 # default is shuffle the deck
&random := map (&clock, ":", "0") # default is randomize the seed
while s := get (av) do
case map (s, &lcase, &ucase) of {
"-A" : automaticAce := 0 #disable automatic ace handling
"-C" : clicking := 0 #run silent
"-D" : debugging := 1 #grant all sorts of perqs
"-R" : &random := get (av) #unrandomize
"-S" : shuffling := 0 #don't shuffle the deck
default : { write ("klondike [-ACDS] [-R randomSeed]")
stop("klondike: bogus option ", s) }
}
randomSeed := &random #remember for debug()
totalGames := 0 #games played
totalAces := 0 #cards put on ace piles
repeat { #game loop
newGame()
prevsCmd := "x" #anything but "S"uggest
#respond to user input
repeat { #command loop
writeCursor (18, 66)
writes (VclearEOL || Vnormal || "> ") #clear command line
if pile[1] = pile[2] = pile[3] = pile[4] = 13 then
if terminate (1) then break # VICTORY!
s := getCmdChar ()
writeInfo ("") #clear info line
writeCursor (18, 69)
case s of {
"?" : help()
"A" : {
writes ("utomatic")
automatic() #look Ma, no hands!
if kbhit() then
if getch() == "\0" then getch()
}
"C" : continuous() #no hands, forever
"D" : if debugging = 0 then complain() else debug()
"H" : help()
"M" : if not move() then complain()
"Q" : if terminate(0) then break #new game
"S" : suggest (if s == prevsCmd then 1 else 0)
"T" : { writes ("humb"); push (ops, thumb()) }
"U" : undo()
"\14" : refreshScreen () #^L
ESC : s #do nothing
default : complain ()
} #case
prevsCmd := s
} #repeat command
totalAces +:= pile[1] + pile[2] + pile[3] + pile[4]
} #repeat game
end #main
--
PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
X.400: naz@hslrswi.hasler
UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz
VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET
From icon-group-request@arizona.edu Wed Oct 3 04:34:26 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA23642; Wed, 3 Oct 90 04:34:26 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 3 Oct 90 04:33 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27160; Wed, 3 Oct 90 04:21:19
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Wed, 3 Oct 90 04:34 MST
Date: 2 Oct 90 21:09:13 GMT
From: esquire!yost@nyu.edu
Subject: Icon as RDBMS report writer language
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <260E9215EAA940382A@Arizona.edu>
Message-Id: <2723@esquire.dpw.com>
Organization: DP&W, New York, NY
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
Has anyone used Icon as the basis for a RDBMS report writer language?
Such a beast could be soooo much better than some other things out there...
--dave yost
yost@dpw.com or uunet!esquire!yost
Please don't use other mangled forms you may see
in the From, Reply-To, or CC fields above.
From cargo@cherry.cray.com Wed Oct 3 06:37:14 1990
Received: from timbuk.CRAY.COM by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA26141; Wed, 3 Oct 90 06:37:14 -0700
Received: from cherry04.cray.com by timbuk.CRAY.COM (4.1/SMI4.0 CRAY1.1)
id AA00512; Wed, 3 Oct 90 08:37:10 CDT
Received: by cherry04.cray.com
id AA01510; 4.1/CRI-3.21; Wed, 3 Oct 90 08:37:08 CDT
Date: Wed, 3 Oct 90 08:37:08 CDT
From: cargo@cherry.cray.com (David S. Cargo)
Message-Id: <9010031337.AA01510@cherry04.cray.com>
To: icon-group@cs.arizona.edu
Subject: Re: Icon as RDBMS report writer language
>Date: 2 Oct 90 21:09:13 GMT
>From: esquire!yost@nyu.edu
>Subject: Icon as RDBMS report writer language
>To: icon-group@arizona.edu
>Organization: DP&W, New York, NY
>
>Has anyone used Icon as the basis for a RDBMS report writer language?
>Such a beast could be soooo much better than some other things out there...
>
> --dave yost
I have used Icon as a part of a process for some data base publishing,
but only in conjunction with other programs. Cray keeps a software
problem report data base using ORACLE. My section in Cray likes to see
reports about our status weekly. Using canned and dynamically
generated queries, I extract a formatted report that I then feed to an
Icon program for further processing. The further processing in this
case means extracting data and rewriting it with LaTeX code and macro
calls defined in the tables.sty file. The result is formatted with
LaTeX and printed with dvips on our Sun LaserWriters.
I have in some cases written PostScript directly from Icon programs,
but in this case it seemed a lot easier on me to let existing programs
shoulder the burden of doing the formatting.
dsc
From nowlin@iwtqg.att.com Wed Oct 3 06:47:28 1990
Resent-From: nowlin@iwtqg.att.com
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA26380; Wed, 3 Oct 90 06:47:28 -0700
Received: from att.att.com by Arizona.edu; Wed, 3 Oct 90 06:46 MST
Resent-Date: Wed, 3 Oct 90 06:47 MST
Date: Wed, 3 Oct 90 07:35 CDT
From: nowlin@iwtqg.att.com
Subject: RE: Icon...RDBMS report...
Resent-To: icon-group@cs.arizona.edu
To: att!arizona.edu!icon-group@cs.arizona.edu
Resent-Message-Id: <25FC023C8729403C4F@Arizona.edu>
Message-Id: <25FC09C78719A00903@Arizona.edu>
Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268)
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: att!arizona.edu!icon-group@cs.Arizona.edu
We have a modification request (bug report) tracking system that's based on
a relational database and most of our canned reports and even the graphs we
use to track things like the "fix" rate are programmed in Icon. The Icon
programs spit out ascii reports and generate pic code for graphs. I toyed
with making them generate PostScript but we already had a working pic
format for the graphs so I just used Icon to automate the data collection
and formatting. It's customized to our specific project and wouldn't be
portable to other applications but does provide an example of the use you
were interested in.
Jerry Nowlin
(...!att!iwtqg!nowlin)
From S.P.Q.Rahtz@ecs.southampton.ac.uk Wed Oct 3 09:05:15 1990
Received: from sun2.nsfnet-relay.ac.uk by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA01776; Wed, 3 Oct 90 09:05:15 -0700
Received: from vax.nsfnet-relay.ac.uk by sun2.nsfnet-relay.ac.uk
with SMTP inbound id aa04911; Wed, 3 Oct 90 15:12:39 +0000
Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet
with NIFTP id aa10399; 3 Oct 90 15:12 BST
Received: from vicky.ecs.soton.ac.uk by hilliard.ecs.soton.ac.uk;
Wed, 3 Oct 90 15:42:10 BST
From: Sebastian Rahtz <S.P.Q.Rahtz@ecs.southampton.ac.uk>
Date: Wed, 3 Oct 90 15:41:36 bst
Message-Id: <5187.9010031441@manutius.ecs.soton.ac.uk>
To: icon-group@cs.arizona.edu
In-Reply-To: <9010031337.AA01510@cherry04.cray.com>
Subject: Re: Icon as RDBMS report writer language
"David S. Cargo" writes:
> problem report data base using ORACLE. My section in Cray likes to see
> reports about our status weekly. Using canned and dynamically
> generated queries, I extract a formatted report that I then feed to an
> Icon program for further processing. The further processing in this
> case means extracting data and rewriting it with LaTeX code and macro
> calls defined in the tables.sty file. The result is formatted with
I have a large Ingres database of gravestones and inscriptions, and I
used to have an Icon program to fiddle with the output, as in the
example above. then I realized that a lot of the same work could be
done in LaTeX itself...; so Icon now has no place in the scheme. This
is because I have to the database searching with a C program with
embedded SQL which is linked to Ingres libraries. What I would really
like to do, of course, is to write my program in Icon with embedded
SQL. I don't suppose anyone has done this by any chance? the idea of a
generator which returned tuples from the database is rather
attractive.
Sebastian Rahtz
From tenaglia@mis.mcw.edu Wed Oct 3 09:06:08 1990
Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA01819; Wed, 3 Oct 90 09:06:08 -0700
Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP
id AA08815; Wed, 3 Oct 90 11:47:55 EDT
Received: by uwm.edu; id AA22471; Wed, 3 Oct 90 10:40:01 -0500
Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Wed, 3 Oct 90 09:42:21 CDT
Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/);
Wed, 3 Oct 90 09:23:11 CDT
Date: Wed, 3 Oct 90 09:23:11 CDT
Message-Id: <0093DA19CC40C1E0.20200837@mis.mcw.edu>
From: "Chris Tenaglia - 257-8765" <tenaglia@mis.mcw.edu>
Subject: Icon Database
To: icon-group@cs.arizona.edu
Concerning Icon Databases :
I wrote one. It's not relational. The initial version held the data in a list.
The records had fixed size fields delimited with \377 (X'FF'). Later I stored
the data in a table of lists where the database key formed the 'entry' and
entire lines (\377 delimited) in a list as the 'assignment'. A database would
actually occupy 2 files. The data file and a description file. Here's a sample
of a description file (PB.ATCP).
data in pb.dat
header is ABBREVIATED PHONEBOOK DATABASE &DATE
fields are First_Name Last__Name Ext/Flag__ Department Main_Phone Information
lengths are 10 10 4 20 12 20
look up 2
sort on 2
print using 1 57 lpa0 n/a
title begin
< < PERSONAL VENDOR/DEPARTMENTAL TELEPHONE DATABASE > >
TODAY IS &DATE &PAGE
NAME E/F DEPARTMENT PHONE INFORMATION
====================== ==== ==================== ======== ===========
title end
One invokes the database using the description file. 'data in' tells which file
the data is in. 'header is' puts a header on all the screens to remind one what
database is active. 'fields are' describes the field names as they would appear
on the screen. 'lengths are' describes the number of bytes in each field. Space
characters delimit the tokens, and the 'fields are' and 'lengths are' must have
the same amount of tokens. 'look up' defines the look up key, which is one or
for fields referenced by position from 1 to ???.'sort on' specified the default
order for purposes of printing or viewing. 'print using' indicated the spacing,
1=single 2=double, lines per page, default printer queue, and whether to print
all as a solid block (n/a), skip a line when the 'lookup' field changed (skip),
or to eject a page when the the 'lookup' field(s) changed. 'title begin' and
'title end' describe the print out title for every page. &DATE generates todays
date on the screen header or print title. &PAGE in the print title generates
the page # while printing the report.
The database capacity and performance may be an issue. The list based version
was very slow with lookups and deletes. The table version is real slow on the
print version, as it sorts the data before printing. I never measured it's
maximum limit. It seems useful upto 1000 items. One can change to a different
database or data file on the fly, insert or delete columns, change the lookup
key, alter the default settings. I actually use it for some useful things.
But it's not relational. I think of it as a data 'editor' and report writer.
Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu, mcwmis!tenaglia
From eric@ai.leeds.ac.uk Wed Oct 3 13:33:45 1990
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA17216; Wed, 3 Oct 90 13:33:45 -0700
Received: from UKACRL.BITNET by Arizona.edu; Wed, 3 Oct 90 13:33 MST
Received: from RL.IB by UKACRL.BITNET (Mailer R2.03B) with BSMTP id 6391; Wed,
03 Oct 90 19:16:43 BST
Date: Wed, 3 Oct 90 11:55:28 GMT
From: E S Atwell <eric@ai.leeds.ac.uk>
Subject: NeuralNets: help requested
To: icon-group@cs.arizona.edu
Cc: eric@ai.leeds.ac.uk
Message-Id: <5656.9010031155@ai.leeds.ac.uk>
Via: UK.AC.LEEDS.AI; 3 OCT 90 19:16:05 BST
Via:
X-Envelope-To: icon-group@cs.arizona.edu
I mailed icon-project@edu.arizona.cs asking for any Icon implemetations of
Neural Networks; the reply came that the Icon project team didnt have any,
but other subscribers to icon-group might. Is there anyone else out there
interested in neural nets, who can help us? cf the following:
From eric Mon Oct 1 12:22:38 1990
Subject: Neural Networks
Are there any Icon implementations of neural networks that you know of?
I have an eural network simulator package for Sun workstations (NeuralWare)
which requires input and outputs to be specified as numerical values in a file;
I am experimenting with language processing (specifically, parsing), so need
to convert my training data (a Treebank or Corpus of syntax-trees for parsed
English text samples) into numerical form. I have started with varoius Icon
reformatting programs to transform the trees into required input/output training
format; but it struck me that it would be much neater to do the whole thing
in a single icon program, rather than Icon programs interfacing to a 'black
box' package. Any suggestions? I couldnt find anything suitable in the
library programs availale by FTP from edu.arizona.cs.
Thanks for any help you can offer. The AI Division here at Leeds has only
recently been established (over the past year we have swelled from 5 to 10
teaching staff, and we're just setting up new courses including a BSc in
Cognitive Science), so this may be a good time to impress my new colleagues
with the versatility and elegance of Icon (opinion is split between Pop-11,
Prolog, Lisp, and C at the moment).
Eric Steven Atwell
Centre for Computer Analysis of Language And Speech (CCALAS)
Artificial Intelligence Division, School of Computer Studies
phone: +44 532 335761 Leeds University
FAX: +44 532 335468 Leeds LS2 9JT
JANET: eric@uk.ac.leeds.ai England
EARN/BITNET/ARPA: eric%leeds.ai@ac.uk
From shafto@eos.arc.nasa.gov Thu Oct 4 09:35:03 1990
Received: from eos.arc.nasa.gov by megaron (5.61/15) via SMTP
id AA29950; Thu, 4 Oct 90 09:35:03 -0700
Received: Thu, 4 Oct 90 09:33:52 PDT by eos.arc.nasa.gov (5.59/1.2)
Date: Thu, 4 Oct 90 09:33:52 PDT
From: Michael Shafto <shafto@eos.arc.nasa.gov>
Message-Id: <9010041633.AA08099@eos.arc.nasa.gov>
To: eric@ai.leeds.ac.uk, icon-group@cs.arizona.edu
Subject: Re: NeuralNets: help requested
Cc: shafto@EOS.ARC.NASA.GOV
I played around with neural nets in Icon a few
years ago. Bottom line: the flexibility of
Icon in manipulating lists and other data structures
was a big plus at development time, but you would
want to be in C for serious work due to the hard
requirement for raw speed (plus the complexity of
your program is not a real driving factor in this
kind of work).
Mike
From icon-group-request@arizona.edu Thu Oct 4 22:53:52 1990
Resent-From: icon-group-request@arizona.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron (5.61/15) via SMTP
id AA07959; Thu, 4 Oct 90 22:53:52 -0700
Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 4 Oct 90 22:53 MST
Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27311; Thu, 4 Oct 90 22:46:20
-0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
icon-group@arizona.edu (icon-group@arizona.edu) (contact
usenet@ucbvax.Berkeley.EDU if you have questions)
Resent-Date: Thu, 4 Oct 90 22:53 MST
Date: 5 Oct 90 04:57:53 GMT
From: midway!quads.uchicago.edu!goer@mimsy.umd.edu
Subject: more code; bal like routine
Sender: icon-group-request@arizona.edu
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <24ABD06BD6152009B0@Arizona.edu>
Message-Id: <1990Oct5.045753.29857@midway.uchicago.edu>
Organization: University of Chicago
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I had to write this the other day, and it seemed to be something that
would be of general interest.
-Richard
############################################################################
#
# Name: slashbal.icn
#
# Title: Bal() with backslash escaping
#
# Author: Richard L. Goerwitz
#
# Version: 1.1
#
############################################################################
#
# I am often frustrated at bal()'s inability to deal elegantly with
# the common \backslash escaping convention (a way of telling Unix
# Bourne and C shells, for instance, not to interpret a given
# character as a "metacharacter"). I recognize that bal()'s generic
# behavior is a must, and so I wrote slashbal() to fill the gap.
#
# Slashbal behaves like bal, except that it ignores, for purposes of
# balancing, any character which is preceded by a backslash. Note
# that we are talking about internal backslashes, and not necessarily
# the backslashes used in Icon string literals. If you have "\(" in
# your source code, the string produced will have no backslash. To
# get this effect, you would need to write "\\(."
#
# BUGS: Note that, like bal() (v8), slashbal() cannot correctly
# handle cases where c2 and c3 intersect.
#
############################################################################
#
# Links: none
#
############################################################################
procedure slashbal(c1, c2, c3, s, i, j)
local allcs, chr, count
/c1 := &cset
/c2 := '('
/c3 := ')'
allcs := c1 ++ c2 ++ c3 ++ '\\'
/s := \&subject | stop("slashbal: No string argument.")
/i := \&pos | 1
/j := *s + 1
count := 0
s ? {
while tab(upto(allcs)) do {
chr := move(1)
if chr == "\\" then {
chr := move(1) | fail
if any(c1, chr) & count = 0 then
suspend .&pos - 1
}
else {
if any(c1, chr) & count = 0 then
suspend .&pos - 1
if any(c2, chr) then
count +:= 1
else if any(c3, chr) then
count -:= 1
}
}
}
end
From goer%sophist@gargoyle.uchicago.edu Sat Oct 6 12:16:35 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA07236; Sat, 6 Oct 90 12:16:35 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 6 Oct 90 12:16 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA15090; Sat, 6 Oct 90 14:15:54 199
Received: by sophist (4.1/UofC3.1X) id AA18746; Sat, 6 Oct 90 14:19:53 CDT
Resent-Date: Sat, 6 Oct 90 12:16 MST
Date: Sat, 6 Oct 90 14:19:53 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: find duplicate procedures
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <237282D0BE4B201416@Arizona.edu>
Message-Id: <9010061919.AA18746@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
I posted some code a while ago for removing duplicate procedures
from library files. It was tested under Unix only, and only in
my own environment. It's now been tested under MS-DOS (thanks to
a few helpers), and works satisfactorily, as long as the lib-
raries are all in MS-DOS text-file format. Here's a re-post.
Please, use this if you plan on posting library-style code. It
will save a lot of headaches for the elves who put together the
IPL....
-Richard
P.S. If someone wants this, and can't umpack a shell archive,
please tell me what format you can upack (tar, arc, zoo, etc.),
and I'll mail it to you.
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 10/06/1990 16:34 UTC by goer@sophist.uchicago.edu
#
# existing files will NOT be overwritten unless -c is specified
# This format requires very little intelligence at unshar time.
# "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
#
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 8294 -r--r--r-- duplproc.icn
# 603 -rw-r--r-- README
# 623 -rw-r--r-- Makefile.dist
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= duplproc.icn ==============
if test -f 'duplproc.icn' -a X"$1" != X"-c"; then
echo 'x - skipping duplproc.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting duplproc.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'duplproc.icn' &&
X############################################################################
X#
X# Name: duplproc.icn
X#
X# Title: Find duplicate procedure/record identifiers
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.5
X#
X############################################################################
X#
X# Use this if you plan on posting code!
X#
X# Duplproc.icn compiles into a program which will search through
X# every directory in your ILIBS environment variable (and/or in the
X# directories supplied as arguments to the program). If it finds any
X# duplicate procedure or record identifiers, it will report this on
X# the standard output.
X#
X# It is important to try to use unique procedure names in programs
X# you write, especially if you intend to link in some of the routines
X# contained in the IPL. Checking for duplicate procedure names has
X# been somewhat tedious in the past, and many of us (me included)
X# must be counted as guilty for not checking more thoroughly. Now,
X# however, checking should be a breeze.
X#
X############################################################################
X#
X# Links: none
X#
X# Requires: Unix (MS-DOS will work if all files are in MS-DOS format)
X#
X############################################################################
X
Xrecord procedure_stats(name, file, lineno)
X
Xprocedure main(a)
X
X local proc_table, fname, elem, lib_file, tmp
X
X # usage: duplproc [libdirs]
X #
X # Where libdirs is a series of space-separated directories in
X # which relevant library files are to be found. To the
X # directories listed in libdirs are added any directories found in
X # the ILIBS environment variable.
X
X proc_table := table()
X
X # Put all command-line option paths, and ILIBS paths, into one sorted
X # list. Then get the names of all .icn filenames in those paths.
X every fname := !get_icn_filenames(getlibpaths(a)) do {
X # For each .icn filename, open that file, and find all procedure
X # calls in it.
X if not (lib_file := open(fname, "r")) then
X write(&errout,"Can't open ",fname," for reading.")
X else {
X # Find all procedure calls in lib_file.
X every elem := !get_procedures(lib_file,fname) do {
X if /proc_table[elem.name] := set()
X then insert(proc_table[elem.name],elem)
X else {
X write("\"", elem.name, "\"",
X " is defined in ",*proc_table[elem.name]+1," places:")
X every tmp := !proc_table[elem.name] do
X write(" ",tmp.file, ", line ",tmp.lineno)
X write(" ",elem.file, ", line ", elem.lineno)
X }
X }
X close(lib_file)
X }
X }
X
X
Xend
X
X
X
Xprocedure getlibpaths(ipl_paths)
X
X # Unite command-line args and ILIBS environment variable into one
X # path list.
X
X local i, path
X
X # Make sure all paths have a consistent format (one trailing slash).a
X if *\ipl_paths > 0 then {
X every i := 1 to *ipl_paths do {
X ipl_paths[i] := fixup_path(ipl_paths[i])
X }
X ipl_paths := set(ipl_paths)
X }
X else ipl_paths := set()
X
X # If the ILIBS environment variable is set, read it into
X # ipl_paths. Spaces - NOT COLONS - are used as separators.
X getenv("ILIBS") ? {
X while path := tab(find(" ")) do {
X insert(ipl_paths, fixup_path(path))
X tab(many(' '))
X }
X insert(ipl_paths, fixup_path(tab(0)))
X }
X
X return sort(ipl_paths)
X
Xend
X
X
X
Xprocedure fixup_path(s)
X # Make sure paths have a consistent format.
X return "/" ~== (trim(s,'/') || "/")
Xend
X
X
X
Xprocedure get_procedures(intext,fname)
X
X # Extracts the names of all procedures declared in file f.
X # Returns them in a list, each of whose elements have the
X # form record procedure_stats(procedurename, filename, lineno).
X
X local psl, f_pos
X static name_chars
X initial {
X name_chars := &ucase ++ &lcase ++ &digits ++ '_'
X }
X
X # Initialize procedure-name list, line count.
X psl := list()
X line_no := 0
X
X # Find procedure declarations in intext.
X while line := read(intext) & line_no +:= 1 do {
X take_out_comments(line) ? {
X if tab(match("procedure")) then {
X tab(many(' \t')) &
X put(psl, procedure_stats(
X "main" ~== tab(many(name_chars)), fname, line_no))
X }
X }
X }
X
X return psl # returns empty list if no procedures found
X
Xend
X
X
X
Xprocedure take_out_comments(s)
X
X # Commented-out portions of Icon code - strip 'em. Fails on lines
X # which, either stripped or otherwise, come out as an empty string.
X #
X # BUG: Does not handle lines which use the _ string-continuation
X # notation. Typically take_out_comments barfs on the next line.
X
X local i, j, c, c2
X
X s ? {
X tab(many(' \t'))
X pos(0) & fail
X find("#") | (return trim(tab(0),' \t'))
X match("#") & fail
X (s2 <- tab(find("#"))) ? {
X c2 := &null
X while tab(upto('\\"\'')) do {
X case c := move(1) of {
X "\\" : {
X if match("^")
X then move(2)
X else move(1)
X }
X default: {
X if \c2
X then (c == c2, c2 := &null)
X else c2 := c
X }
X }
X }
X /c2
X }
X return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
X }
X
Xend
X
X
X
Xprocedure get_icn_filenames(lib_paths)
X
X # Return the names of all .icn files in all of the paths in the
X # list lib_paths. The dir routine used depends on which OS we
X # are running under.
X
X local procedure_stat_list
X static get_dir
X initial get_dir := set_getdir_by_os()
X
X procedure_stat_list := list()
X # Run through every possible path in which files might be found,
X # and get a list of procedures contained in those files.
X every procedure_stat_list |||:= get_dir(!lib_paths)
X
X return procedure_stat_list
X
Xend
X
X
X
Xprocedure set_getdir_by_os()
X
X if find("UNIX", &features)
X then return unix_get_dir
X else if find("MS-DOS", &features)
X then return msdos_get_dir
X else stop("Your operating system is not (yet) supported.")
X
Xend
X
X
X
Xprocedure msdos_get_dir(dir)
X
X # Returns a sorted list of all filenames (full paths included) in
X # directory "dir." The list is sorted. Fails on invalid or empty
X # directory. Aborts if temp file cannot be opened.
X #
X # Temp files can be directed to one or another directory either by
X # manually setting the variable temp_dir below, or by setting the
X # value of the environment variable TEMPDIR to an appropriate
X # directory name.
X
X local in_dir, filename_list, line
X static temp_dir
X initial {
X temp_dir :=
X (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
X ".\\"
X }
X
X # Get name of tempfile to be used.
X temp_name := get_dos_tempname(temp_dir) |
X stop("No more available tempfile names!")
X
X # Make sure we have an unambiguous directory name, with backslashes
X # instead of Unix-like forward slashes.
X dir := trim(map(dir, "/", "\\"), '\\') || "\\"
X
X # Put dir listing into a temp file.
X system("dir "||dir||" > "||temp_name)
X
X # Put tempfile entries into a list, removing blank- and
X # space-initial lines. Exclude directories (i.e. return file
X # names only).
X in_dir := open(temp_name,"r") |
X stop("Can't open temp file in directory ",temp_dir,".")
X filename_list := list()
X every filename := ("" ~== !in_dir) do {
X match(" ",filename) | find(" <DIR>", filename) & next
X filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
X if filename ? (tab(find(".ICN")+4), pos(0))
X then put(filename_list, map(dir || filename))
X }
X
X # Clean up.
X close(in_dir) & remove(temp_name)
X
X # Check to be sure we actually managed to read some files.
X if *filename_list = 0 then fail
X else return sort(filename_list)
X
Xend
X
X
X
Xprocedure get_dos_tempname(dir)
X
X # Don't clobber existing files. Get a unique temp file name for
X # use as a temporary storage site.
X
X every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
X temp_file := open(temp_name,"r") | break
X close(temp_file)
X }
X return \temp_name
X
Xend
X
X
X
Xprocedure unix_get_dir(dir)
X
X dir := trim(dir, '/') || "/"
X filename_list := list()
X in_dir := open("/bin/ls -F "||dir, "pr")
X every filename := ("" ~== !in_dir) do {
X match("/",filename,*filename) & next
X if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
X then put(filename_list, trim(dir || filename, '*'))
X }
X close(in_dir)
X
X if *filename_list = 0 then fail
X else return filename_list
X
Xend
SHAR_EOF
true || echo 'restore of duplproc.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
echo 'x - skipping README (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XSee the comments prepended to duplproc.icn for a statement of what
Xthis program is and does. To create it on a Unix system, you can
Xjust mv Makefile.dist to Makefile and make. If you want to install
Xit, type "make install" as root. Be sure to check the Makefile
Xfirst, though, to be sure the installation routine uses the correct
Xdirectories and permissions for your system.
X
XUsers of other systems, you're on your own. This will probably work
XMS-DOS, but it has not been extensively tested under that OS. It is
Xhard to get a directory listing from within Icon on systems that
Xdon't support pipes.
SHAR_EOF
true || echo 'restore of README failed'
rm -f _shar_wnt_.tmp
fi
# ============= Makefile.dist ==============
if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile.dist (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Makefile.dist (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
XPROGNAME = duplproc
X
X# Please edit these to reflect your local file structure & conventions.
XDESTDIR = /usr/local/bin
XOWNER = bin
XGROUP = bin
X
XSRC = $(PROGNAME).icn
X
X$(PROGNAME): $(PROGNAME).icn
X icont $(PROGNAME).icn
X
X# Pessimistic assumptions regarding the environment (in particular,
X# I don't assume you have the BSD "install" shell script).
Xinstall: $(PROGNAME)
X @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
X cp $(PROGNAME) $(DESTDIR)/
X chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
X chown $(OWNER) $(DESTDIR)/$(PROGNAME)
X @echo "\nInstallation done.\n"
X
Xclean:
X -rm -f *~ .u?
X -rm -f $(PROGNAME)
SHAR_EOF
true || echo 'restore of Makefile.dist failed'
rm -f _shar_wnt_.tmp
fi
exit 0
From goer%sophist@gargoyle.uchicago.edu Sat Oct 6 12:29:51 1990
Resent-From: goer%sophist@gargoyle.uchicago.edu
Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
id AA07483; Sat, 6 Oct 90 12:29:51 -0700
Return-Path: goer@sophist.uchicago.edu
Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 6 Oct 90 12:29 MST
Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id
AA15387; Sat, 6 Oct 90 14:29:09 199
Received: by sophist (4.1/UofC3.1X) id AA18781; Sat, 6 Oct 90 14:33:08 CDT
Resent-Date: Sat, 6 Oct 90 12:29 MST
Date: Sat, 6 Oct 90 14:33:08 CDT
From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
Subject: improved merging program
Resent-To: icon-group@cs.arizona.edu
To: icon-group@arizona.edu
Resent-Message-Id: <2370A7C5B86B201427@Arizona.edu>
Message-Id: <9010061933.AA18781@sophist>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.EDU
This is the promised improved merging program. Essentially, you can
feed it a file you've created, and it will go through all your lib-
raries, digging up any procedures called in the file, and then out-
putting them, together with the original file, on the standard out-
put.
Not everyone has the IPL installed. Not everyone has the most recent
*version* installed. Not everyone knows how to link programs to lib-
rary routines. Not everyone has their IPATH environment variable set
up correctly anyway.
Sometimes it's just easier to post a program as-is, with all necessary
routines present in the source. This program will do all the work of
linking in necessary routines for you, and merging them all into a
single source file.
If you are lazy, you can even use this program to concatenate relevant
files in a single directory into a single file. Just offer the file
with the main procedure as arg 1, and then make the current directory
arg 2. Imerge (the program's name) will find everything it needs, and
discard the rest.
Note that you usually get a space savings in the icode file that results
from compiling imerge's output. It does not link in whole source files,
but only those portions of the source file that are needed by the pro-
gram in question.
-Richard
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 10/06/1990 08:12 UTC by goer@sophist.uchicago.edu
# Source directory /u/richard/Imerge
#
# existing files will NOT be overwritten unless -c is specified
# This format requires very little intelligence at unshar time.
# "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
#
#
#
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 1611 -r--r--r-- findrecs.icn
# 4161 -r--r--r-- getcalls.icn
# 3638 -r--r--r-- getnames.icn
# 1457 -r--r--r-- getpaths.icn
# 1248 -r--r--r-- getprocs.icn
# 7738 -r--r--r-- imerge.icn
# 1513 -r--r--r-- stripcom.icn
# 832 -rw-r--r-- Makefile.dist
# 607 -rw-r--r-- README
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= findrecs.icn ==============
if test -f 'findrecs.icn' -a X"$1" != X"-c"; then
echo 'x - skipping findrecs.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting findrecs.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'findrecs.icn' &&
X############################################################################
X#
X# Name: findrecs.icn
X#
X# Title: find record & global declarations
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.2
X#
X############################################################################
X#
X# Hunts down global and record declarations. Puts them into two global
X# tables to be used later (part of the imerge package).
X#
X############################################################################
X
Xglobal record_table, global_table
X
Xprocedure find_records(intext, fname)
X
X local line, i, entry
X # global record_table, global_table
X static wchars, name_chars
X initial {
X record_table := table()
X global_table := table()
X wchars := &cset -- ','
X name_chars := &ucase ++ &lcase ++ &digits ++ '_'
X }
X
X every line := strip_comments(!intext) do {
X match("global"|"record",line) | next
X until bal(wchars, "(", ")", line, -1) do
X line ||:= strip_comments(!intext)
X line ? {
X if tab(match("record")) then {
X tab(many(' \t')) &
X if entry := "# Source file: " || fname || "\n" ||
X "record " || tab(many(name_chars)) ||
X (tab(many(' \t')) | &null, "") || tab(match("(")) ||
X tab(find(")")+1) & pos(0)
X then {
X /record_table[fname] := set()
X insert(record_table[fname], entry)
X }
X }
X else if tab(match("global")) then {
X if tab(many(' \t')) then {
X /global_table[fname] := set()
X insert(global_table[fname],
X "# Source file: "|| fname ||"\n"|| "global "||tab(0))
X }
X }
X }
X }
X
X return "records & globals accumulated"
X
Xend
SHAR_EOF
true || echo 'restore of findrecs.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getcalls.icn ==============
if test -f 'getcalls.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getcalls.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getcalls.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getcalls.icn' &&
X############################################################################
X#
X# Name: getcalls.icn
X#
X# Title: Get_procedure_calls - accumulate a list of proc. calls
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.2
X#
X############################################################################
X#
X# Determines if arg (line) contains a procedure call, and if so, puts
X# that call's id into a list.
X#
X# I hate this procedure. It works on a line-by-line basis. Returns
X# nothing until invoked with a null argument. This lets me run it on
X# as many lines as I want, and then fetch a full listing whenever it
X# seems appropriate. Some calculations need to be done on return, so
X# this is the most practical solution.
X#
X# Part of the imerge package. See imerge.icn.
X#
X############################################################################
X
Xprocedure get_procedure_calls(line)
X
X # Looks for non-builtin procedure calls in line. Returns nothing
X # until called without an argument, in which case it returns the
X # accumulated set of procedure names found in the "line"s read so
X # far. When next invoked, get_procedure_calls starts with a fresh
X # (i.e. freshly emptied) set.
X
X local external_procedures
X static keywords, builtins, wchars, procedures_called
X initial {
X wchars := &ucase ++ &lcase ++ &digits ++ '_'
X keywords := set(
X ["break","by","case","default","do","dynamic","else","end",
X "every","fail","global","if","initial","link","local",
X "next","not","of","procedure","record","repeat","return",
X "static","suspend","then","to","until","while"])
X builtins := set(
X ["abs","acos","any","args","asin","bal","char",
X "center","close","copy","collect","cos","cset","delete",
X "detab","display","dtor","entab","exit","exp","find","get",
X "getenv","iand","icom","ior","image","insert","integer",
X "ishift","ixor","key","left","list","log","getch",
X "getche","kbhit","main","many","map","match","member",
X "move","name","numeric","open","ord","pop","pos",
X "pull","push","put","read","reads","real","remove",
X "rename","repl","reverse","right","rtod","seek","set",
X "sin","sort","sqrt","stop","string","system","tab",
X "table","trim","type","upto","variable","where",
X "write","writes"])
X procedures_called := set()
X }
X
X strip_comments(\line) ? {
X while tab(upto_balanced(wchars)) do {
X BEGIN := &pos
X id := tab(many(wchars))
X # Record constructors look like procedure invocations.
X # Make the names of records like builtin function names.
X if id == "record" then {
X if tab(many(' \t')) & id := tab(many(wchars)) then
X insert(builtins, id)
X else break # give up, bad code
X }
X # Make sure with "procedure proc1(arguments)" that proc1
X # doesn't get taken as an invocation of proc1!
X else if id == "procedure" then {
X if not (tab(many(' \t')) & tab(many(wchars)))
X then break # give up, bad code
X }
X else {
X tab(many(" \t"))
X if tab(match(".")) then {
X tab(many(wchars))
X # What the heck, stick records in with procedures.
X insert(procedures_called, id)
X }
X else if tab(match("(")) then {
X integer(id) & next
X # Reject id if it is a keyword or builtin function
X if member(keywords | builtins, id) then next
X else {
X # Conceivably, we could have rec.field(args)
X if match(".",line,BEGIN -1) then next
X else insert(procedures_called, id)
X # Doesn't account for (proc1|proc2)(arguments)
X }
X }
X }
X }
X }
X
X if /line then {
X external_procedures := (procedures_called -- builtins) -- keywords
X procedures_called := set()
X return external_procedures
X }
X
Xend
X
X
X
Xprocedure upto_balanced(cs)
X
X local s2, c, c2, POS
X
X &subject[.&pos:0] ? {
X tab(upto(cs)) ? {
X c2 := &null
X if upto('\"\'') then {
X while tab(upto('\\"\'')) do {
X case c := move(1) of {
X "\\" : {
X if match("^")
X then move(2)
X else move(1)
X }
X default: {
X if \c2
X then (c == c2, c2 := &null)
X else c2 := c
X }
X }
X }
X }
X /c2
X } & POS := &pos
X }
X
X return &pos + \POS - 1
X
Xend
SHAR_EOF
true || echo 'restore of getcalls.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getnames.icn ==============
if test -f 'getnames.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getnames.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getnames.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getnames.icn' &&
X############################################################################
X#
X# Name: getnames.icn
X#
X# Title: Get_ipl_names - get names .icn files in a list of dirs
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.3
X#
X############################################################################
X#
X# Part of the imerge package. See imerge.icn.
X#
X############################################################################
X
Xprocedure get_ipl_names(lib_paths)
X
X local procedure_stat_list
X static get_dir
X initial get_dir := set_getdir_by_os()
X
X procedure_stat_list := list()
X # Run through every possible path in which files might be found,
X # and get a list of procedures contained in those files.
X every procedure_stat_list |||:= get_dir(!lib_paths)
X
X return procedure_stat_list
X
Xend
X
X
X
X
Xprocedure set_getdir_by_os()
X
X if find("UNIX", &features)
X then return unix_get_dir
X else if find("MS-DOS", &features)
X then return msdos_get_dir
X else stop("Your operating system is not (yet) supported.")
X
Xend
X
X
X
Xprocedure msdos_get_dir(dir)
X
X # Returns a sorted list of all filenames (full paths included) in
X # directory "dir." The list is sorted. Fails on invalid or empty
X # directory. Aborts if temp file cannot be opened.
X #
X # Temp files can be directed to one or another directory either by
X # manually setting the variable temp_dir below, or by setting the
X # value of the environment variable TEMPDIR to an appropriate
X # directory name.
X
X local in_dir, filename_list, line
X static temp_dir
X initial {
X temp_dir :=
X (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") |
X ".\\"
X }
X
X # Get name of tempfile to be used.
X temp_name := get_dos_tempname(temp_dir) |
X stop("No more available tempfile names!")
X
X # Make sure we have an unambiguous directory name, with backslashes
X # instead of Unix-like forward slashes.
X dir := trim(map(dir, "/", "\\"), '\\') || "\\"
X
X # Put dir listing into a temp file.
X system("dir "||dir||" > "||temp_name)
X
X # Put tempfile entries into a list, removing blank- and
X # space-initial lines. Exclude directories (i.e. return file
X # names only).
X in_dir := open(temp_name,"r") |
X stop("Can't open temp file in directory ",temp_dir,".")
X filename_list := list()
X every filename := ("" ~== !in_dir) do {
X match(" ",filename) | find(" <DIR>", filename) & next
X # Exclude our own tempfiles (may not always be appropriate).
X filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ')
X if filename ? (not match("s."), tab(find(".ICN")+4), pos(0))
X then put(filename_list, map(dir || filename))
X }
X
X # Clean up.
X close(in_dir) & remove(temp_name)
X
X # Check to be sure we actually managed to read some files.
X if *filename_list = 0 then fail
X else return sort(filename_list)
X
Xend
X
X
X
Xprocedure get_dos_tempname(dir)
X
X # Don't clobber existing files. Get a unique temp file name for
X # use as a temporary storage site.
X
X every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do {
X temp_file := open(temp_name,"r") | break
X close(temp_file)
X }
X return \temp_name
X
Xend
X
X
X
Xprocedure unix_get_dir(dir)
X
X dir := trim(dir, '/') || "/"
X filename_list := list()
X in_dir := open("/bin/ls -F "||dir, "pr")
X every filename := ("" ~== !in_dir) do {
X match("/",filename,*filename) & next
X if filename ? (not match("s."), tab(find(".icn")+4), pos(0))
X then put(filename_list, trim(dir || filename, '*'))
X }
X close(in_dir)
X
X if *filename_list = 0 then fail
X else return filename_list
X
Xend
SHAR_EOF
true || echo 'restore of getnames.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getpaths.icn ==============
if test -f 'getpaths.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getpaths.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getpaths.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getpaths.icn' &&
X############################################################################
X#
X# Name: getpaths.icn
X#
X# Title: Get_lib_paths - puts library paths into a sorted list
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.4
X#
X############################################################################
X#
X# Get_lib_paths() examines the env. variable ILIBS, and also command
X# args 2-end, sorting them, and normalizing them, making them all into
X# directory names. Later on, these directories are examined to see if
X# they contain .icn files....
X#
X# Part of the imerge package. See imerge.icn.
X#
X############################################################################
X
Xprocedure get_lib_paths(ipl_paths)
X
X local i, path
X
X # Make sure all paths have a consistent format (one trailing slash).a
X if *\ipl_paths > 0 then {
X every i := 1 to *ipl_paths do {
X ipl_paths[i] := fixup_path(ipl_paths[i])
X }
X ipl_paths := set(ipl_paths)
X }
X else ipl_paths := set()
X
X # If the ILIBS environment variable is set, read it into
X # ipl_paths. Spaces - NOT COLONS - are used as separators.
X getenv("ILIBS") ? {
X while path := tab(find(" ")) do {
X insert(ipl_paths, fixup_path(path))
X tab(many(' '))
X }
X insert(ipl_paths, fixup_path(tab(0)))
X }
X
X return sort(ipl_paths)
X
Xend
X
X
X
Xprocedure fixup_path(s)
X return "/" ~== (trim(s,'/') || "/")
Xend
X
X
X
Xprocedure Basename(s)
X
X every i := find("/",s)
X return s[1:\i]
X
Xend
SHAR_EOF
true || echo 'restore of getpaths.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= getprocs.icn ==============
if test -f 'getprocs.icn' -a X"$1" != X"-c"; then
echo 'x - skipping getprocs.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting getprocs.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'getprocs.icn' &&
X############################################################################
X#
X# Name: getprocs.icn
X#
X# Title: Get stats on procedure calls declared in a file.
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.2
X#
X############################################################################
X#
X# Part of the imerge package. See imerge.icn.
X#
X############################################################################
X
Xrecord procedure_stats(name, file, byte)
X
Xprocedure get_procedure_stats(intext,fname)
X
X # Extracts the names of all procedures declared in file f.
X # Returns them in a list, each of whose elements have the
X # form record procedure_stats(procedurename, filename, byte-
X # offset).
X
X local psl, f_pos
X static name_chars
X initial {
X name_chars := &ucase ++ &lcase ++ &digits ++ '_'
X }
X
X # Initialize procedure-name list.
X psl := list()
X
X # Find procedure declarations in intext.
X while f_pos := where(intext) & line := read(intext) do {
X strip_comments(line) ? {
X if tab(match("procedure")) then {
X tab(many(' \t')) &
X put(psl, procedure_stats(
X "main" ~== tab(many(name_chars)), fname, f_pos))
X }
X }
X }
X
X return psl # returns empty list if no procedures found
X
Xend
SHAR_EOF
true || echo 'restore of getprocs.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= imerge.icn ==============
if test -f 'imerge.icn' -a X"$1" != X"-c"; then
echo 'x - skipping imerge.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting imerge.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'imerge.icn' &&
X############################################################################
X#
X# Name: imerge.icn
X#
X# Title: IPL merge utility
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.6
X#
X############################################################################
X#
X# Imerge simply merges needed routines from the IPL (and from any
X# other directories you supply), into a given source file. Often an
X# IPL file will house several related procedures - not all of which
X# are needed in order to compile a program. Imerge obviates the need
X# for linking in the entire library file.
X#
X# Usage is
X#
X# imerge sourcefile [libdirectories]
X#
X# where "sourcefile" refers to a .icn file, and libdirectories is a
X# space-separated list of directories in which .icn files containing
X# routines needed by sourcefile are likely to be found.
X#
X# You can remove the need to specify any directories on the command
X# line by setting the value of ILIBS in your environment to a space-
X# or colon-separated string of directory names. Csh users, for
X# instance, could put the following in their .login files:
X#
X# setenv ILIBS = "/usr/local/lib/icon/procs ~/isrc"
X#
X# Imerge will recognize all files ending in ".icn" which do not begin
X# with "s." (s + period = a SCCS file) as possible library files in
X# the ILIBS directories.
X#
X# Imerge writes to the standard output. Slowly. Bear with it, and
X# it will normally do a pretty decent job. Watch the end of the file
X# for a report of records and procedures not found (you'll have to go
X# find them, and either link them in by hand, or add the directory
X# they are in to the ILIBS variable). Imerge is annoyed at duplicate
X# procedure names in your library files, and will complain at length
X# about them. In many cases, it complains about things that don't
X# really matter. Ignore the complaints unless the output won't
X# compile.
X#
X# BUGS: 1) Naming conflicts cannot be resolved (the workaround is
X# simply to make sure no duplicate names exist for procedures in your
X# libraries). 2) The parsing algorithm doesn't handle line-final
X# underscore notation for string literals (this should not normally
X# cause problems). 3) Indirect procedure invocations, such as a :=
X# b; a(), where b is a global identifier, confuse imerge, though the
X# resulting output should normally compile fine. Same goes for
X# records. Again, the resulting output should compile just fine.
X#
X############################################################################
X#
X# Links: imerge.icn is part of a package including the following
X# files - findrecs.icn, getcalls.icn, getnames.icn, getpaths.icn,
X# getprocs.icn, imerge.icn, and stripcom.icn.
X#
X# Requires: Unix (will work under MS-DOS if all files are in MS-
X# DOS format - CR+LF = EOL)
X#
X############################################################################
X
Xglobal unfound_procedures, st2, records, globals
X
Xprocedure main(a)
X
X local usage, line, raw_line, elem, sourcefile_procedures
X
X usage := "usage: imerge sourcefile [libdirs]"
X #
X # Where sourcefile is a single filename, and libdirs is a series
X # of space-separated directories in which relevant library files
X # are to be found.
X
X *a < 1 & stop(usage)
X
X # Open arg 1 - the source .icn file into which the library
X # routines are to be merged.
X if not (intext := open(a[1],"r")) then {
X write(&errout, "Cannot open source file.")
X write(&errout, usage)
X exit(2)
X }
X
X # Now accumulate the set of all procedures called in the source
X # file, and then remove from that set all procedures which are
X # defined in that file. What is left is the set of all "external"
X # procedures called in the source file.
X
X # Find every procedure call in intext.
X every get_procedure_calls(!intext)
X sourcefile_procedure_calls := get_procedure_calls()
X
X # Find all the procedures defined in intext, then remove them from
X # the set of procedure calls accumulated just above.
X seek(intext,1)
X sourcefile_procedures := set()
X # Get_procedure_stats returns a list of procedure_stats records.
X every insert(sourcefile_procedures,
X (!get_procedure_stats(intext,a[1])).name)
X sourcefile_procedure_calls --:= sourcefile_procedures
X
X # Check to see whether the source file in fact calls any
X # procedures not defined in that file. If not, there's no need to
X # continue.
X if *sourcefile_procedure_calls = 0 then {
X write(&errout,"No external procedure calls in ",a[1],".")
X exit(3)
X }
X
X prtbl := table()
X every fname := !get_ipl_names(get_lib_paths(a[2:0])) do {
X # If the source file is in one of the libraries, don't index it.
X fname == a[1] & next
X if not (lib_file := open(fname, "r")) then
X write(&errout,"Can't open ",fname," for reading.")
X else {
X every elem := !get_procedure_stats(lib_file,fname) do {
X if /prtbl[elem.name]
X then insert(prtbl,elem.name,elem)
X else {
X write(&errout, "Warning: ",elem.name,
X " is defined in more than one place.")
X every write(&errout," ",prtbl[elem.name].file)
X write(&errout," ",elem.file)
X }
X }
X seek(lib_file, 1)
X # Side-effects! Find_records() sets up the global tables,
X # record_table and global_table (see below).
X find_records(lib_file, fname)
X close(lib_file)
X }
X }
X
X # Copy input file to stdout. Comment out link declaration (if there is
X # one). This program is supposed to obviate the need for links.
X seek(intext,1)
X every line := !intext do {
X if line ? (tab(many(' \t'))|&null, tab(match("link")), tab(any(' \t')))
X then write("# ",line)
X else write(line)
X }
X close(intext)
X write("\n\n\n")
X
X # Fetch procedure calls, and write them to the standard output, in
X # effect, appending them to intext, the source file.
X write_separator("Merged library procedures begin here.")
X fetch_procedure(sourcefile_procedure_calls, prtbl, a[1])
X
Xend
X
X
X
Xprocedure fetch_procedure(st,prtbl,f_name,switch)
X
X local stat, elem, p, st3
X
X # global unfound_procedures, records, record_table, global_table
X initial {
X unfound_procedures := set()
X records := set()
X globals := set()
X }
X
X /st2 := set()
X
X every insert(globals, !\global_table[f_name])
X
X every p := !st do {
X if /(stat := prtbl[p]) then {
X # Record_table has record declarations catalogued by file
X # name. First look by f_name. If you can't find a
X # variable that way, just go through the entire table.
X if find(" "||p||"(",elem := !\record_table[f_name]| !!record_table)
X then insert(records,elem)
X else insert(unfound_procedures, p)
X next
X }
X intext := open(stat.file,"r")
X seek(intext,stat.byte)
X write("# Source file: ",stat.file)
X until "end" == (line := strip_comments(write(!intext \ 1))) do {
X get_procedure_calls(line)
X }
X write("\n\n\n")
X st2 ++:= st ++ set([stat.name])
X st3 := get_procedure_calls() -- st2
X close(intext)
X fetch_procedure(st3,prtbl,stat.file,1)
X }
X
X if *records ~= 0 & /switch then {
X write_separator("Records.")
X every write(!sort(records))
X write()
X }
X
X if *globals ~= 0 & /switch then {
X # Output global variables for all files visited.
X write_separator("Global variables.")
X every write(!sort(globals))
X write()
X }
X
X if *unfound_procedures ~= 0 & /switch then {
X # Append a list of unlocated procedures to the stdout.
X write_separator("Unable to locate the following procedures/records:",
X sort(unfound_procedures))
X }
X
X return
X
Xend
X
X
X
Xprocedure write_separator(s,l)
X
X write(repl("#",75))
X write("#")
X write("# ",s)
X every write("# ",!\l)
X write("#")
X write("")
X
Xend
SHAR_EOF
true || echo 'restore of imerge.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= stripcom.icn ==============
if test -f 'stripcom.icn' -a X"$1" != X"-c"; then
echo 'x - skipping stripcom.icn (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting stripcom.icn (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stripcom.icn' &&
X############################################################################
X#
X# Name: stripcom.icn
X#
X# Title: Strip out comments from a line of Icon code
X#
X# Author: Richard L. Goerwitz
X#
X# Version: 1.2
X#
X############################################################################
X#
X# BUGS: Can't handle lines ending in an underscore as part of a
X# broken string literal.
X#
X# Part of the imerge package. See imerge.icn. Could be used as a
X# general utility, I suppose.
X#
X############################################################################
X
Xprocedure strip_comments(s)
X
X #######
X #
X # Commented-out portions of Icon code - strip 'em. Fails on lines
X # which, either stripped or otherwise, come out as an empty string.
X #
X # I'd expect strip_comments to be used typically as follows:
X #
X # every write(strip_comments(!&input))
X #
X # BUG: Does not handle lines which use the _ string-continuation
X # notation. Typically strip_comments barfs on the next line.
X #
X #######
X
X local i, j, c, c2
X
X s ? {
X tab(many(' \t'))
X pos(0) & fail
X find("#") | (return trim(tab(0),' \t'))
X match("#") & fail
X (s2 <- tab(find("#"))) ? {
X c2 := &null
X while tab(upto('\\"\'')) do {
X case c := move(1) of {
X "\\" : {
X if match("^")
X then move(2)
X else move(1)
X }
X default: {
X if \c2
X then (c == c2, c2 := &null)
X else c2 := c
X }
X }
X }
X /c2
X }
X return "" ~== trim((\s2 | tab(0)) \ 1, ' \t')
X }
X
Xend
SHAR_EOF
true || echo 'restore of stripcom.icn failed'
rm -f _shar_wnt_.tmp
fi
# ============= Makefile.dist ==============
if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile.dist (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Makefile.dist (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
XPROGNAME = imerge
X
X# Please edit these to reflect your local file structure & conventions.
XDESTDIR = /usr/local/bin
XOWNER = bin
XGROUP = bin
X
XSRC = findrecs.icn getcalls.icn getnames.icn getpaths.icn \
X getprocs.icn imerge.icn stripcom.icn
XICONT = /usr/local/bin/icont #/usr/icon/v8/bin/icont
XIFLAGS = -Sc300 #-t
X
X# Compile program.
X$(PROGNAME): $(SRC)
X $(ICONT) $(IFLAGS) -o $(PROGNAME) $(SRC)
X
X# Install.
X# Pessimistic assumptions regarding the environment (in particular,
X# I don't assume you have the BSD "install" shell script or that sh
X# is your default shell).
Xinstall: $(PROGNAME)
X @sh -c "test -d $(DESTDIR)|| (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))"
X cp $(PROGNAME) $(DESTDIR)/
X chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
X chown $(OWNER) $(DESTDIR)/$(PROGNAME)
X @echo "\nInstallation done.\n"
X
Xclean:
X -/bin/rm *.u?
X -rm *~
SHAR_EOF
true || echo 'restore of Makefile.dist failed'
rm -f _shar_wnt_.tmp
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
echo 'x - skipping README (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
X
XThis package contains the parts necessary to build imerge - a utility
Xused for merging relevant parts of the IPL into an icon source file.
XIf you have a make utility, you can build imerge simply by renaming
Xthe file "Makefile.dist" as "Makefile" and then typing "make." Some
Xadjustments may be needed to tailor the makefile to your particular
Xfile system.
X
XIf you have no make utility, you will need to type
X
X icont -Sc300 -o imerge [names of all .icn files]
X
XThis program has been tested under both Unix and MS-DOS. It will
Xwork under DOS only if all files have been converted to DOS CR+LF
Xtext format.
SHAR_EOF
true || echo 'restore of README failed'
rm -f _shar_wnt_.tmp
fi
exit 0