mwm@violet.berkeley.edu (Mike (I'll think of something yet) Meyer) (05/31/89)
Here's yet more ARexx scripts, since someone called for them. This is a shar file with various small tools in it. You'll find: - an exec to create a small window with a one-month calendar in it, defaulting to the current month - an exec to put an arbitrary file, or standard input, into a window - an exec to delete the window used by the two above tools. N.B. both post and month use the RexxArpLib window. You no got RexxArpLib, they no work. - A qad Unix-like "foreach." No variables, just maps % to each filename. Uses C-\ to end the command list. Many of these use ExecIO, which comes with WShell. All I do is read a file or standard input into a variable, with "execio <magic> stem varname.". You can get the same effect by opening the file (if it's indeed a file), and reading lines into varname.#, one line per variable, starting with 1. Finally, load varname.0 with the number of lines read. ExecIO is just an order of magnitude faster, is all. <mike # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # month.rexx # post.rexx # nomsg.rexx # expand.rexx # foreach.rexx # man.rexx # This archive created: Tue May 30 20:23:25 1989 cat << \SHAR_EOF > month.rexx /* * cal - open a month's calendar on the workbench screen for the * user. * * usage: cal [month [year]] * * If no args are given, use the current month & year. * * Month may be either a month name (only the first three characters * are used), or the number of the month. * * Year is the year of the christian era. If the length is exactly two * characters, then a '19' is prepended to it. So '9' is the year 9, * '09' is the year 1909; '34' is the year 1934, 034 is the year 34. * * The calendar presented is correct for England & it's colonies for * periods when there was more than one calendar in general use. For * grins, try 'cal 9 1752' */ arg month year . /* Set up the months table - from names to numbers, */ months. = 0 months.jan = 1 months.feb = 2 months.mar = 3 months.apr = 4 months.may = 5 months.jun = 6 months.jul = 7 months.aug = 8 months.sep = 9 months.oct = 10 months.nov = 11 months.dec = 12 /* and now from numbers to days/month & print names */ months.1 = 'January' months.1.days = 31 months.2 = 'February' months.2.days = 1 /* Fixed later */ months.3 = 'March' months.3.days = 31 months.4 = 'April' months.4.days = 30 months.5 = 'May' months.5.days = 31 months.6 = 'June' months.6.days = 30 months.7 = 'July' months.7.days = 31 months.8 = 'August' months.8.days = 31 months.9 = 'September' months.9.days = 30 months.10 = 'October' months.10.days = 31 months.11 = 'November' months.11.days = 30 months.12 = 'December' months.12.days = 31 /* Not needed, but here for completeness */ /* Get the current date for later use*/ parse value date('Normal') with . mymonth myyear /* Get a month to work with */ if datatype(month, 'Numeric') then mymonth = month else do if month ~= "" then mymonth = month mymonth = upper(left(mymonth, 3)) mymonth = months.mymonth end if months.mymonth.days = 0 then do say "Month must be a month name or a number from 1 to 12, not" month exit 10 end /* Got a valid month, now see about the year */ select when year = "" then nop /* myyear is already right */ when ~datatype(year, 'Numeric') then do say "Year must be a number between 1 and 9999, not" year exit 10 end when length(year) = 2 then myyear = '19'year otherwise myyear = year end if myyear < 1 | myyear > 9999 then do say "Year must be between 1 and 9999 inclusive, not" myyear exit 10 end /* Figure out what day of the week that month started on */ firstday = jan1(myyear) /* Get difference in weekdays between this year & next */ fudge = (jan1(myyear + 1) + 7 - firstday) // 7 select /* this is a regular year */ when fudge = 1 then months.2.days = 28 /* This is a leap year */ when fudge = 2 then months.2.days = 29 /* Otherwise, it must be 1752! */ otherwise months.2.days = 29 months.9.days = 19 end do i = 1 to mymonth - 1 firstday = firstday + months.i.days end firstday = firstday // 7 /* Got the day of the week */ /* * Now, go from that to the name of a day of the week. This table is also * used for formatting the output. The line at the top of the body consists * of these things concatenated together, with a space in between them. * The length of that string is the width of the calendar. Finally, we * line the numbers up under the last character of each name. All names * _must_ be the same length for this to work. */ daynames.0 = 'Sun' daynames.1 = 'Mon' daynames.2 = 'Tue' daynames.3 = 'Wed' daynames.4 = 'Thu' daynames.5 = 'Fri' daynames.6 = 'Sat' firstday = daynames.firstday /* and now it's name */ /* Get number of days in this month */ days = months.mymonth.days /* Next, we set up the header for the calendar. */ headerline = daynames.0 do i = 1 to 6 headerline = headerline daynames.i end linelength = length(headerline) /* width of calendar */ /* Set up the header for the calender */ lines.1 = center(months.mymonth myyear, linelength) lines.2 = " " lines.3 = headerline linecount = 4 /* First line of body of calendar */ /* Now set up to put together lines of the body */ maxline = linecount + 5 /* 6 weeks on a monthly calendar, max */ do i = linecount + 1 to maxline lines.i = "" end width = length(daynames.0) outline = right(1, index(headerline, firstday) - 1 + width) linelength = linelength - width /* * Special case the first & second of the month to deal with September, 1752. */ if length(outline) <= linelength then outline = outline right(2, width) else do lines.linecount = outline linecount = linecount + 1 outline = right(2, width) end if days > 20 then start = 3 else do days = days + 11 start = 14 end do i = start to days if length(outline) <= linelength then outline = outline right(i, width) else do lines.linecount = outline linecount = linecount + 1 outline = right(i, width) end end lines.linecount = outline /* now display it - in a window if possible, to the console if not */ if ~show('Libraries', 'rexxarplib.library') then do if ~addlib('rexxarplib.library', 0, -30) then do /* Now rexxarplib, just dump it to the console */ do i = 1 to linecount say lines.i end exit end end /* Got a rexxarplib, so put it in a window */ outline = lines.1 do i = 2 to maxline outline = outline '\'lines.i end /* * We tack a space onto the end here, and in each line, so they will be * cleared by postmsg. Sigh. */ call postmsg 395, 11, outline "" exit /* * jan1 - returns the day of the week that january first falls on for * any specific year, 1 through 9999 (assuming they don't change * the rules again). */ jan1: procedure arg year /* Julian calendar; one extra day every four years */ day = 4 + year + (year + 3) % 4 /* Gregorian calendar - lose three days over four centuries */ if year > 1800 then do day = day - (year - 1701) % 100 day = day + (year - 1601) % 400 end /* And the instant changeover in 1752 */ if year > 1752 then day = day + 3 return day // 7 SHAR_EOF cat << \SHAR_EOF > post.rexx /* post - puts it's standard input in the postmsg window */ if ~show('Libraries', 'rexxarplib.library') then do if ~addlib('rexxarplib.library', 0, -30) then do say "No rexxarplib, so no posting!" exit end end if arg() = 0 then 'execio stem lines.' else 'execio read' arg(1) 'stem lines.' if lines.0 > 0 then do out = translate(lines.1, " ", '09'x) do i = 2 to lines.0 out = out '\' || translate(lines.i, " ", '09'x) end end call postmsg , , out "" exit SHAR_EOF cat << \SHAR_EOF > nomsg.rexx /* nomsg - turn of thepostmsg window */ if ~show('Libraries', 'rexxarplib.library') then do if ~addlib('rexxarplib.library', 0, -30) then do say "A msg window and no rexxarplib? Good trick, that." exit end end call postmsg exit SHAR_EOF cat << \SHAR_EOF > expand.rexx /* expand - function to expand AMIGAdos wild cards */ parse arg files out = "" do i = 1 to words(files) pat = word(files, i) if verify(pat, '#?', 'Match') = 0 then out = out pat else do 'list nohead quick' pat '| execio stem lines.' do i = 1 to lines.0 out = out lines.i end end end dropbuf /* just to be sure */ return out break_c: dropbuf return "" SHAR_EOF cat << \SHAR_EOF > foreach.rexx /* * foreach - execute commands from stdin for each file in arg list, * replacing any "%"'s with the file's name. */ parse arg arg 'execio stem commands.' /* Get commands into the command buffer */ files = expand(arg(1)) do i = 1 to words(files) file = word(files, i) do j = 1 to commands.0 command = mapinfile(commands.j, file) command end end exit /* * mapinfile - replace every occurence of % in the first argument with the * second argument. */ mapinfile: procedure parse arg pattern, fill i = index(pattern, '%') do while i > 0 pattern = substr(pattern, 1, i - 1) || fill || substr(pattern, i + 1) i = index(pattern, '%') end return pattern SHAR_EOF cat << \SHAR_EOF > man.rexx /* man - just get me a man page */ arg page file = 'docs:'page if exists(file) then 'more' file exit SHAR_EOF # End of shell archive exit 0 -- It's been a hard day's night, Mike Meyer And I been working like a dog. mwm@berkeley.edu It's been a hard day's night, ucbvax!mwm I should be sleeping like a log. mwm@ucbjade.BITNET