Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!midway!quads.uchicago.edu!goer From: goer@quads.uchicago.edu (Richard L. Goerwitz) Newsgroups: comp.lang.icon Subject: Re: UUXXCODE Message-ID: <1990Sep20.043220.14195@midway.uchicago.edu> Date: 20 Sep 90 04:32:20 GMT References: <0093CBF0039A4D60.20400E83@mis.mcw.edu> Sender: news@midway.uchicago.edu (News Administrator) Distribution: inet Organization: University of Chicago Lines: 156 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