wiml@milton.u.washington.edu (William Lewis) (08/09/90)
In the spirit of the recent spate of random-text-generation programs to alt.sources, I have converted two of those programs (sifi and madrock) to SPEW rulefile format, and am reposting them here. Since I had to modify SPEW slightly to port sifi, I'm also posting it, and the original spewfile (headline). I also added word-wrap to spew's output. Note to people who plan to do dome more modification to spew: The current implementation of \PRUNE is pretty kludgy. It should really be done by return values instead of setjmp/longjmp, but I'm too lazy right now. Also, the indication of prunsetops could be a bit "nicer". I haven't done this yet, but if seeing this post makes you improve spew some more, get in touch with me so we don't duplicate changes or create incompatible versions =8) ----------------------cut here--------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # readme # headline # sifi.sp # madrock.sp # manual # spew.c # This archive created: Wed Aug 8 23:33:28 1990 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'readme'" '(4509 characters)' if test -f 'readme' then echo shar: "will not over-write existing file 'readme'" else sed 's/^X//' << \SHAR_EOF > 'readme' XA while back, mark@pixar posted a program to generate random 'National XEnquirer' headlines. This program worked from a 'rules file' which was a text Xfile describing how the headlines would be constructed. X XMark's program was, unfortunately, highly non-portable, and rather than Xtry to salvage it I wrote a new interpreter for the same text file. XSince then I have added several features, and thus greatly changed the Xformat of the rules file. Credits go to mark for the original concept Xand much of the text in the supplied rulesfile ( which I have cleaned up Xand added to ). X XThis shar includes the National Enquirer rules-file 'headline', the XMAD rock concert rulesfile 'madrock.sp', the Sci-Fi plot rulesfile X'sifi.sp', the source to the 'spew' interpreter, a 'manual' for the Xformat of the control file, and this READ_ME file. I believe this Xprogram might actually be useful, for such tasks as generating huge Xquantities of input text for testing programs. ( I may have a Xfile which generates random syntactically-correct C code, but I Xwon't admit to it!! :-). The format of the file allows a wide variety of text Xformats to be generated - it almost works like Yacc in reverse. XAnyway, things like 'festoon' could certainly be coded as 'spew' rulesfiles, Xand could thus be sent to the net as a 'spew' source. XSorry I haven't written a proper manual page, but... X XUSAGE: X spew [n] generate one [or n] random thing(s) from default X rulesfile. If the environment variable RULESFILE X is set, the file-name is taken from there; other- X wise a compiled-in name is used ( see Installation X instructions ). X X spew [n] file Same, but use the given file as input. X X spew -c Xor spew -c file 'Compress' the default or given file to the X standard output (the compressed format is unreadable X and must be redirected). 'Compress' is a misnomer X because the file gets about 20% larger. The X 'compressed' format is more efficient for spew to X operate from, though. Spew automatically knows X whether it is reading a compressed or human-readable X rulesfile. Examples: X spew headline << make a headline X spew -c headline >headline.comp << make compressed file X spew headline.comp << make another headline X X spew -d X spew -d file Read the default or given file, and dump the X resulting internal structure to the std output. X The format is pretty easy to figure out. It is X somewhat different when the input file is in X 'compressed' format. DUMP must be #define'd X to enable this feeping creature. X X XINSTALLATION INSTRUCTIONS: XThe file spew.c contains some clearly labeled #defines which you may Xwant to play with. It should be possible to port to non-Un*x systems Xjust by changing these. The most important ones to start with are: X XDEFFILE which is the default rules file to use. Set this to the path X of your 'headline' file and then you can just put 'spew' in your X .login. XENVIRON which is set to "RULESFILE" in the release package. If this X environment variable is set, it is assumed to be a default file-name X over-riding the DEFFILE. You may want to change this. X Remove the #define if you don't have getenv(). XSETRAND XROLL(n) define the former to a STATEMENT (not an expression) which X initializes your random number generator. Define the latter as X an expression which gives a random integer in the range 0<=i<n. X 'n' will be an integer from 1 to several hundred. X The supplied definitions may or may not work well, depending X on your machine (here we have a VAX 11/780 4.2BSD, works ok X on a Sun too ). X X------------------------------------------------------------------------- XNotes of modification: X XI have modified the source to make it compilable under DOS on an IBM-PC Xwith Borland Turbo C. It is still compilable under UNIX, just make sure Xthe #define DOS is commented out. It should compile just fine with XMicrosoft C v4.0/v5.x, but I have not tried it. X -- Ti Kan -- X------------------------------------------------------------------------- XI modified Ti Kan's version to include the \PRUNE pseudoclass (described Xabove) and to break output lines on word boundaries (which could Xconcievably hurt some uses, but I've never seen a spewfile for Xanything but humor text). It should still compile everywhere it used Xto ( :-) ); if setjmp/longjmp is not available then #define PRUNE can Xbe commented out. X William Lewis (phelliax) X wiml@milton.u.washington.edu X------------------------------------------------------------------------- echo shar: "a missing newline was added to 'readme'" SHAR_EOF if test 4509 -ne "`wc -c < 'readme'`" then echo shar: "error transmitting 'readme'" '(should have been 4509 characters)' fi fi echo shar: "extracting 'headline'" '(8211 characters)' if test -f 'headline' then echo shar: "will not over-write existing file 'headline'" else sed 's/^X//' << \SHAR_EOF > 'headline' X\* National Enquirer Headlines. X\* X%SPIRITUAL XSpiritual XClairvoyant XTelepathic XTelekinetic X%RELATIVE XFather XUncle XGrandfather XGrandmother XSon XDaughter XMother XAunt XPostman XAccountant XDog Catcher XIRS Man XHairdresser XAvon Lady X%WEAPON{a} X{|a }Meat Cleaver X{|a }Hatchet X{|a }Machete X{|a }Phased Plasma Rifle X{|a }Chain Saw X{|a }Samurai Sword X{|an }Axe X{|a }Machine Gun X{|an }Anti-tank weapon X\*{\FRUIT|\FRUIT/a} X\FRUIT/& X%GHOST XGhost XEvil Spirt XPoltergist XDemon XPhantom XBogie Man X%RELIGION XBuddist XMethodist XBaptist XIslamic XMoslem XRoman Catholic XAtheist X%UFFO XUFO XFlying Saucer XSpace Ship XMother Ship XSpace cruiser XUSS Enterprise XGalactic Space Cruiser X%PLANET XPluto XMars XVenus XMercury XNeptune XSaturn XJupiter XThe Moon X%ET{s} XExtra-Terrestrial{|s} XE.T.{|'s} XSpace Alien{|s} XBeing{|s} XSpace Being{|s} XCyborg{|s} XHumanoid{|s} XAlien{|s} X%DRUG XHeroin XLSD XAngel Dust XCoke XCocaine XCrack XQuaaludes XAmphetamines XSpam X%FRUIT{as} X{|a |}Mango{||es} X{|a |}Tomato{||es} X{|a |}Banana{||s} X{|a |}Cherr{y|y|ies} X{|an |}Apple{||s} X{|a |}Plum{||s} X{|a |}Pear{||s} X{|an |}Orange{||s} X{|a |}Tangerine{||s} X{|a |}Lemon{||s} X{|a |}Lime{||s} X{|a |}Block{||s} of Spam X%MADNESS XCrazed XDrug-Crazed XInsane XManic Depressive XNeurotic XPsychotic XPsychopathic XDevoted XReligious XFanatical XPathological X%KILLER{s} X(2)\KILLERX/& X\MADNESS \KILLERX/& X%KILLERX{s} X\FRUIT/& XGreat White Shark{|s} XTerminator{|s} XEwok{|s} XWombat{|s} XBee{|s} XWasp{|s} XWhale{|s} XShark{|s} XLion{|s} XDolphin{|s} XElephant{|s} XWorm{|s} XClam{|s} XKitten{|s} XLobster{|s} XTiger{|s} XLeopard{|s} XPanda{|s} XCrocodile{|s} X%MCELEB XRonald Reagan XDan Quayle XFrank Sinatra XMichael Jackson XPrince XMick Jagger XDonny Osmond XLou Albano XSylvester Stallone XSean Penn XBob Dylan XDavid Letterman XJohnny Carson XMuammar Quadaffi XMoammar Khadafy XKenny Rogers XBurt Reynolds XJohn Davidson XRichard Nixon XPrince Charles XGeorge Lucas X%FCELEB XPrincess Diana XQueen Elizabeth XNancy Reagan XLinda Ronstadt XMaggie Trudeau XLiz Taylor XTina Turner XDolly Parton XCher XJane Fonda XEva Gabor XJoan Rivers XMadonna XCindi Lauper X%BABY{s} XBab{y|ies} XChild{|ren} XSon{|s} XDaughter{|s} X%FDEAD\* female persons long dead XCleopatra XJoan of Arc XLady Godiva XQueen Victoria XThe Queen of Sheba X%DFCELEB\* dead female 'celebrities' XMarilyn Monroe XJanis Joplin X(4)\FDEAD X%MDEAD\* male persons long dead XAtilla the Hun XKing Henry VIII XAbraham Lincoln XGeorge Washington XMoses X%DMCELEB\* dead male celebs X(3)Elvis XJimi Hendrix XJim Morrison XJohn F. Kennedy XBing Crosby XJohn Lennon XJFK XGroucho Marx XHarry Chapin X\MDEAD X%DCELEB X\DMCELEB X\DFCELEB X%DEAD X\FDEAD X\MDEAD X%EAT{sd} X{eat|eats|ate} Xkidnap{|s|ped} X{take|takes|took} Xkill{|s|ed} Xdevour{|s|ed} Xmaim{|s|ed} Xinjure{|s|d} Xrape{|s|d} X%SAY{s} XSay{|s} XReveal{|s} X\*Admit{|s} XClaim{|s} XInsist{|s} X\*Warn{|s} X%DOCTOR{s} XDoctor{|s} XPsychologist{|s} XPsychiatrist{|s} XPhysician{|s} XNeurologist{|s} XDentist{|s} XPediatrician{|s} XVetrinarian{|s} XOptician{|s} X%SCIENTIST{s} XScientist{|s} X\DOCTOR/& XChemist{|s} XPhysicist{|s} XMeta-physicist{|s} XEngineer{|s} XComputer Scientist{|s} XProfessor{|s} XTechnician{|s} XWhiz Kid{|s} XBrain Boff{|s} XAI Expert{|s} XPattern Recognition Researcher{|s} X%NATIONALITY XRussian XSoviet XBritish XPolish XFrench XBelgian XSwiss XGerman XSpanish XMexican XUkranian XAmerican XCanadian XAlbanian XAustralian XChinese XJapanese X%DISEASE XHerpes XAIDS XFlu XLeprosy XVD Xa Backache XChicken Pox XMalaria XLaryngitis Xa Nosebleed XTuberculosis XCancer X%FICTCHAR XSanta Claus XBigfoot XSnow White XGod XBhudda XMary Poppins XThe Loch Ness Monster XYogi Bear XJames Bond XThe Wicked Witch of the West XThe Wizard of Oz XCaptain Kirk XThe Tooth Fairy XKermit the frog XBatman XSuperman XSpiderman X%KILL{sd} XKill{|s|ed} XMurder{|s|ed} XMaim{|s|ed} XSlaughter{|s|ed} XMutilate{|s|d} XSho{ot|ots|t} XMug{|s|ged} X%NUMBER X\NUMBER1 X(2)\NUMBER2 XTwenty-\NUMBER1 XThirty-\NUMBER1 XForty-\NUMBER1 XFifty-\NUMBER1 XSixty-\NUMBER1 XSeventy-\NUMBER1 XEighty-\NUMBER1 XNinety-\NUMBER1 X%NUMBER1 XTwo XThree XFour XFive XSix XSeven XEight XNine X%NUMBER2 XTen XEleven XTwelve XThirteen XFourteen XFifteen XSixteen XSeventeen XEighteen XNineteen X%FOOD{a} X{|a }Taco X(5)\FRUIT/& X{|an }Enchilada X{|a }Burrito X{|a }Watermelon X{|a }Triple Ice Cream Cone X{|a }Tostada X%PERSON{s} X\KILLER/& XFootball player{|s} X{Man|Men} XWom{an|en} XTV Personalit{y|ies} XGame Show Host{|s} XPolitician{|s} X\SCIENTIST/& X\DOCTOR/& X\NATIONALITY \SCIENTIST/& X\NATIONALITY \DOCTOR/& XUnemployed \SCIENTIST/& XStudent{|s} XAir Traffic Controller{|s} X\NATIONALITY Student{|s} X\ET/& X%AIRCRAFT XAirplane XHelicopter XAirship XHot Air Balloon XHang Glider XHelium Balloon XUFO XJet Fighter X747 XDC-10 X%CELEB X\MCELEB X\FCELEB X%PLACE XRedwood City XAustralia XNevada XAustin, Texas XMagrathea XOuter Space XMemphis XEngland XSan Francisco XCastro Street XSan Jose XL.A. XNew York XOrlando, Florida XMissouri XMiddle Earth XThe Shire XBarsoom XPlanet Vulcan XFremont Airport XTokyo XTransylvania XTimes Square XWall Street XSan Rafael XIsrael XBeirut XMordor XBBC television center XDr. Who's Tardis XStalingrad XMoscow XAmsterdam XManchester XEdinburgh XRed Square XKremlin XMimico XHollywood XDaytona Beach XSalt Lake City XMississauga XMajorca XBangkok XMonte Carlo XLisbon XBarrie XNirvana X%MAIN X\CONST.\!\! X%INVOLVED X.\! -- \CELEB Reveals All X.\! -- \CELEB May Be Involved X%PROOF X\PHOTO X\PHOTO X.\! -- \NATIONALITY \SCIENTIST/s Offer Undeniable Proof X%PHOTO X.\! -- Exclusive Pictures Inside X.\! -- Photographic Evidence Offers Proof X.\! -- National Enquirer Photo Exclusive X%CONST X"Killer \KILLER/s From \PLANET \EAT/d My \BABY" \SAY/s \CELEB\PHOTO X"\CELEB Is Really \ET From \PLANET" \SAY/s \CELEB X"\CELEB Is Really \ET From \PLANET" \SAY \NATIONALITY \SCIENTIST/s X\MCELEB and \FCELEB Secretly Wed in \PLACE, It's Official\PHOTO XEating \FRUIT/s Can Give You \DISEASE, \SAY \NATIONALITY \DOCTOR/s X"\ET/s From \PLANET Gave Me \DISEASE" \SAY/s \CELEB X"\FICTCHAR is for real".\! -- \NATIONALITY \SCIENTIST/s come up with undeniable proof X"\MCELEB is really my father", \SAY/s \CELEB X"\FCELEB is really my mother", \SAY/s \CELEB X\NATIONALITY \SCIENTIST/s discover lost city of \PLACE X\CELEB \KILL/s \NUMBER \PERSON/s in drunken rampage X\PERSON, stoned on \DRUG, \KILL/s \NUMBER \PERSON/s X\CELEB Falls \NUMBER thousand feet out of \AIRCRAFT ... and survives X"\ET/s From \PLANET Landed In My Garden And \EAT/d \NUMBER \FRUIT/s" \SAY/s \CELEB X\FCELEB Gives birth to \NUMBER \BABY/s\INVOLVED X\RELIGION Monks report \UFFO Sighting in \PLACE\! "They Came From \PLANET!"\PROOF XReal Life Ghost Busters Exorcise \GHOST from \CELEB/ 's home in \PLACE X\BABY \KILL/d by Pet \KILLER\PHOTO XAmazing \MADNESS \KILLERX from \PLACE X"I Chopped My \RELATIVE To Death With \WEAPON/a" -- \PERSON X\PERSON Goes Berserk And \KILL/s \NUMBER \PERSON/s With \WEAPON X\FCELEB Tells Of Night Of Terror With \MCELEB. "He Threatened Me With \WEAPON/a" X\MCELEB Tells Of Night Of Terror With \FCELEB. "She Threatened Me With \WEAPON/a" X\FRUIT/s Have \SPIRITUAL Powers, \SAY \NATIONALITY \SCIENTIST/s\PROOF X\PERSON Sees Face Of \FICTCHAR In \FOOD/a X"Elvis Died From Eating \FRUIT/s", \SAY/s \CELEB\PROOF X\NATIONALITY \SCIENTIST/s Produce \SPIRITUAL \KILLER Girl X\PERSON \KILL/s \NUMBER \PERSON/s With \WEAPON,\!Then Is Acquitted By Jury X\NUMBER Years For \MADNESS \WEAPON Murderer. "I Would Do It Again" Says \CELEB X\PERSON Struck By Lightning -- \NUMBER Times XJury Acquit Notorious \WEAPON Murderer From \PLACE X\MCELEB and \FCELEB Seen Together in \PLACE. "Is It Love?" X\PERSON/ 's Bizarre Claim: "\NATIONALITY \SCIENTIST/s Planted Mind Control Device In My Head" X"Does \FICTCHAR Exist?" \NATIONALITY \SCIENTIST/s Offer New Evidence XTravelling To \PLACE In A Stolen \AIRCRAFT -- \CELEB Tells All\PHOTO X"\FICTCHAR \EAT/d My \BABY", \SAY/s \PERSON X"\MCELEB is the Father Of My \BABY", \SAY/s \MADNESS \PERSON X"\FCELEB is the Mother Of My \BABY", \SAY/s \MCELEB\INVOLVED X\FCELEB Files Paternity Suit Against \FCELEB -- Claiming Sex Change X"I Am The Reincarnation of \FDEAD", \SAY/s \FCELEB X"I Am The Reincarnation of \MDEAD", \SAY/s \MCELEB X\SCIENTIST/s Discover \FCELEB Was Married to \MDEAD in Previous Life X"I spoke to \DCELEB through \FRUIT/a" \SAY/s \PERSON X"I Saw \DCELEB Alive and Well in \PLACE" \SAY/s \PERSON X\NATIONALITY \SCIENTIST/s resurrect \DCELEB\PROOF XIn \MADNESS Rage, \PERSON \KILL/s \NUMBER, Self X"\CELEB Is Addicted to \DRUG"\PROOF X"\FCELEB is the \RELATIVE of my \RELATIVE" says \MCELEB \PROOF X%% SHAR_EOF if test 8211 -ne "`wc -c < 'headline'`" then echo shar: "error transmitting 'headline'" '(should have been 8211 characters)' fi fi echo shar: "extracting 'sifi.sp'" '(2958 characters)' if test -f 'sifi.sp' then echo shar: "will not over-write existing file 'sifi.sp'" else sed 's/^X//' << \SHAR_EOF > 'sifi.sp' X\* SIFI: Sci-Fi Plot Generator X\* Last Modified: 8 July 1990 by wiml@milton.u.washington.edu X\* X\* Originally coded by Kevin D. Quitt (demott!kdq, kdq@demott.com) X\* who commented, in the C version, X\* "This program was converted on [24-July-1990] from a spaghetti- X\* coded BASIC program (that almost worked). I am the original X\* author of both works, though G*d only knows why someone would X\* claim otherwise. .... Note that the original flowchart for this X\* program is *not* my [kdq's] creation - I believe Gahan Wilson did it X\* originally, I think about '81, published in OMNI magazine." X\* Minor modifications to the C code by chad@anasaz.UUCP on 31 July 1990. X\* Converted to spewfile format 7 August 1990 by wiml@milton.u.washington.edu, X\* also a few more phrases added and probabilities tweaked. X\* The \PRUNE pseudo-class is unique to the version of SPEW modified X\* for this rulesfile. X%SIZE Xtiny Xgiant Xmicroscopic Xplanet-sized Xhumongous Xitty-bitty X%BEING Xbugs, which Xreptiles, which Xmechanical devices, which Xsuper persons, who Xicky things, which Xbeings composed completely of energy, which X%BEINGTYPE Xextra-galactic XMartian XMoon XBetelgeusian X%COMETRESULTS Xdestroyed. Xsaved by Jesus and the J.D.L. Xnot destroyed, but everybody dies. Xsaved by a a reclusive hermit and his cute alien pet. X%KILLEDBY Xthe Atomic Bomb Xa crowd of peasnts with torches Xthe Army, Navy, Air Force, Marine Corps and/or Coast Guard Xorbiting laser satellites Xguerilla foces X%BUT Xthey fall in love with a beautiful girl Xa cute little kid convinces them that people are OK Xa priest talks to them of God XCaptain Kirk uses logic on them X%TERM1 Xand they die. \PRUNE Xand they leave. \PRUNE Xand they turn into disgusting lumps. \PRUNE X%TERM2 Xbut they die from catching chicken pox. \PRUNE Xso they kill us. \PRUNE Xso they put us under a benign dictatorship. \PRUNE Xso they eat us. \PRUNE X%WEAPONRESULTS Xwhich fails Xwhich kills them. \PRUNE Xwhich turns them into disgusting lumps. \PRUNE X%DESCRIBEBEING X\SIZE \BEINGTYPE \BEING \DESCRIBEBEINGTAIL X%DESCRIBEBEINGTAIL Xwant our women, Xwant our women, take a few and leave. \PRUNE Xare friendly. \PRUNE Xare friendly, but misunderstood, Xmisunderstand us Xunderstand us too well Xare emissaries from God Xlook upon us only as a source of nourishment Xlook upon us only as a source of nourishment, and eat us. \PRUNE X%DOBUT X, but \BUT \TERM1 X%SIFI! X(2)Earth is struck by a giant comet and \COMETRESULTS X(5)Scientists discover or invent \DESCRIBEBEINGCURIE X(5)Earth is attacked by \DESCRIBEBEINGCURIE XEarth burns up or freezes or falls into the sun and everybody dies. XEarth burns up or freezes or falls into the sun and almost everybody dies. X%MAYBE X(1) X(1) not X%DESCRIBEBEINGCURIE X\DESCRIBEBEING and are\MAYBE radioactive, and can\MAYBE be killed by \KILLEDBY/ \WHATTODO X%WHATTODO \* WHATTODO is a recursive version of the iterative original X\DOBUT \TERM2 X\DOBUT so scientists invent a weapon \WEAPONRESULTS \WHATTODO X%MAIN X\SIFI!/ \!\! X%% SHAR_EOF if test 2958 -ne "`wc -c < 'sifi.sp'`" then echo shar: "error transmitting 'sifi.sp'" '(should have been 2958 characters)' fi fi echo shar: "extracting 'madrock.sp'" '(3470 characters)' if test -f 'madrock.sp' then echo shar: "will not over-write existing file 'madrock.sp'" else sed 's/^X//' << \SHAR_EOF > 'madrock.sp' X\* SPEW implementation of MAD rock concert article generator X\* Based on: "C Implementation of MAD magazine's X\* ALL-INCLUSIVE DO-IT-YOURSELF ROCK CONCERT Newspaper Story X\* by satyr@ucscb.ucsc.edu 1987 X\* SPEW implementation by wiml@u.washington.edu 1990 X%HOWMANY XThousands of XMillions of XHundreds of XSeveral XUncounted millions of XFourteen XA huge number of XBillions of XSeven and a half XMany XQuite a few XMore than one X%WHATSTATE Xscreaming Xripped-off Xborn-again XBloom County Xsuicidal Xtoxic Xwhacked-out Xslightly used Xpregnant Xmolting Xfrigid Xcalcium deficient X%WHO Xrock fans Xteenagers Xmarmot-breeders XSandanistas XBob Uecker look-alikes Xboat people Xamnesiacs XTrivial Pursuit players Xowl worshippers Xbed-wetters XDeLorean dealers Xsoothsayers X%WHERE Xthe City Auditorium Xthe Kingdome XBernie's Car Wash XSt. Patrick's Cathedral Xthe Oval Office XBuddy Hackett's hot tub Xthe Australian outback Xa new Honda Civic XTed and Rita's family room Xthe K-Mart linens section XLake Huron Xthe Exit 17 offramp X%WHOTOSEE Xthe Jacksons XVan Halen XBoy George Xthe Little Rascals XKate and Allie XBotswana wife-swappers Xthe Dallas Mavericks XMr. T's caterer Xthe Miss Bulgaria finalists Xthe last Civil War veteran XCasper Weinberger Xa KGB double agent X%DIDSOMETHING Xstood in line Xcounted their toes Xshouted pygmy oaths Xchanted "DEE-fense!" Xaged prematurely Xlicked Snickers wrappers Xdonned wet suits Xpolished their nose-rings Xwept openly Xbroke wind Xswapped zip-codes Xfondled their ear-lobes X%DOSOMETHING Xpay $30 Xsell their sisters Xgrovel shamelessly Xlose their virginity Xrenounce Satan Xgive up breathing Xsacrifice a beagle Xbetray their scoutmaster Xsell their vital organs Xgive up their citizenship Xpawn their phony Omegas Xchange their sex X%SOME Xa few outbreaks of Xthe usual Xsome harmless Xpost-Olympic Xsloppy attempts at Xauthentic Haitian Xprecision drill Xthe romantic lure of Xthe Bush Cabinet's Xsome very creative Xthe lethal effects of Xthe distinctive odor of X%DISTRACTION Xrioting Xterrorism Xdrunkenness Xcar-stripping Xpillaging Xnude break-dancing Xpossum worship XKarl Malden impersonations Xsilicone rejection Xout-of-body retching Xestate planning Xparakeet training X%ANNOYANCE Xarrest Xflogging Xhearing loss Xdeath screams Xmelt-down Xspraying Xflossing Xglassy-eyed stares Xpre-soaking Xpoor penalty-killing Xfactory recall Xpainless removal X%ANNOYADJ Xunruly Xoff-duty Xstoned Xpre-Columbian Xsingles-bar Xfur-bearing XLucasfilm XLibyan-backed Xreincarnated Xset-user-id Xmoss-covered Xcutesy-pie Xsplattered X%ANNOYOBJ Xpunks Xdrug dealers XSagittarians Xnerds Xwelfare cheats XUnitarians Xsurfers Xmercenaries XCornhuskers Xskycaps XMunchkins Xcenterfolds X%FUN Xan unqualified success Xa victory for good taste Xmore fun than Pearl Harbor Xa vindication of greed Xproof of God's love Xan incredible waste of time Xas significant as Flag Day Xa triumph of Jerry Falwell Xa glorification of self-abuse Xas memorable as 'Lottery' Xa festival for degenerates Xan answer for Communism X%MAIN X\* We have to break this line up or SPEW will chop it X\HEADER\! \PART1 \PART2 \PART3 \!\! X%HEADER X MAD MAGAZINE\! \ X------------\! ROCK CONCERT LAST NIGHT\! X%PART1 X \HOWMANY \WHATSTATE \WHO packed \WHERE last night to see \WHOTOSEE in concert. X%PART2 X Many fans \DIDSOMETHING for more than ten hours while waiting to \DOSOMETHING for a ticket. X%PART3 X Despite \SOME \DISTRACTION and the occasional \ANNOYANCE of \ANNOYADJ \ANNOYOBJ, the promoters of the event called it \FUN. X%% SHAR_EOF if test 3470 -ne "`wc -c < 'madrock.sp'`" then echo shar: "error transmitting 'madrock.sp'" '(should have been 3470 characters)' fi fi echo shar: "extracting 'manual'" '(5498 characters)' if test -f 'manual' then echo shar: "will not over-write existing file 'manual'" else sed 's/^X//' << \SHAR_EOF > 'manual' XINPUT FILE FORMAT: X XThe file is a series of class definitions followed by an end Xmarker. The end marker is a line containing only "%%". X XA class definition begins with a line containing '%' followed by a class Xname. Class names can be any length and can consist of any combination Xof upper and lower case letters, and numbers. X XThe lines following are instances of the class, one per line. When a Xclass is invoked, one of these is picked at random. Most characters in Xthe line are just copied to the output. The newline at the end is not Xcopied. An instance may be continued onto the next line by ending the Xline with '\'. There is a limit of 1000 bytes on the total size of an Xinstance. An instance may begin with '%' if it is escaped: '\%'. A Xnewline may be written as '\!'. A backslash may be written as '\\'. X XThe following is a simple rules-file that prints out either 'foo' Xor bar, followed by a carriage-return: X X%MAIN Xfoo\! Xbar\! X%% X XThe program generates a random instance of the class 'MAIN', which in Xthis case selects 'foo' or 'bar', with a 50-50 chance. A newline is Xappended. X X WEIGHTS X XTo give 'foo' a 90% chance of happening, you can assign weights: X X%MAIN X(9)foo\! Xbar\! X%% X XThe weight of 'bar' is 1 by default. If an instance is to begin with '(' Xit must be escaped, or given an explicit weight: X X\(animal) X(1)(vegetable) X X INVOCATION X XClasses are normally invoked by writing their name immediately after a Xbackslash. Below is a rules-file which is equivalent to the foo-bar Xexample: X X%MAIN X\word\! X%word X(9)foo Xbar X%% X XIn this case, the class 'word' outputs either 'foo' or 'bar', and Xthe newline is appended after the invocation in 'MAIN'. X XIf you wish to immediately follow a class invokation by a letter or a number, Xyou must write it followed by a slash and a space: X X%MAIN X\word/ bar\! X%word Xfoo Xbar X%% X XThe above outputs either 'foobar' or 'barbar'. This method must also Xbe used if the invokation is to be immediately followed by a slash. X X VARIANTS X XA class may be defined with variants, and may then be invoked with Xvariants. The 's' variant defined for the 'fruit' class below Xallows correct plurals to be generated: X X%fruit{s} Xapple{|s} Xcherr{y|ies} Xpear{|s} Xmango{|es} X%MAIN XOne \fruit and two \fruit/s.\! X%% X XThe variant tag is a single letter or number. In an invocation, the Xclass name is followed by a slash which is followed by the tag. Every Xclass has a 'null' variant (tagged by a space) by default (thus the "/ " Xnotation). X XIn the class definition line, the class name is followed by a list Xof variant tags in curly brackets. The order of the tags is Xsignificant. X XIn an instance definition, variants may be created with the following Xnotation: X { <null-variant-text> | <1st-variant-text> | <2nd-variant-text } X XWhen a class is invoked with a null tag, or with a blank tag, the Xtext before the first '|' is used. If the first tag is used in the Xinvocation (i.e. the first tag listed in {}'s in the class definition), Xthe text between the first and second |'s is used, and so forth. All Xtext not in {}'s is copied regardless of the tag used. X XThere are normally as many |'s in these as there are tags defined. XIf there are too many tags, the excess ones select null strings, and Xif there are too many |'s, the excess strings are redundant. X XThe '{' character, if required literally, must always be escaped Xoutside the selector construction: '\{', even when no variants are Xdefined in a class. The '|' and '}' characters must likewise be Xescaped inside a constructor. X XInvocations may appear in a selector, but cannot span a selector. XI.e. you cannot select between invoking 'catwalk' and 'catfish' by X X \cat{walk|fish} X XYou must use {\catwalk|\catfish}. X XFinally, there is the & tag which may be used in an invocation and Xselects the same tag letter (or number) which the invoking Xclass was invoked with: X X%food{s} X\fruit/& <--- this is the same as X{\fruit|\fruit/s} <--- this. X XMAIN is initially invoked with the null tag (although it can be invoked Xrecursively with other tags). X XHere is a class with multiple tags that generates irregular verbs: X X%verb{sd} X{eat|eats|ate} X{be|is|was} X{see|sees|saw} Xlook{|s|ed} Xf{ind|inds|ound} X%% X XThus \verb/d generates a past-tense verb. X X PRUNING X XThere is one "special" pseudo-class, PRUNE. When PRUNE is invoked, no Xmore output is generated on that line, and control immediately reverts Xto the *end* of the last class invoked whose name ended with an '!'. XThis is useful when a certain series of choices can suddenly end Xthe phrase or whatever (such as an abrupt, "startler" terminator to a Xjoke). Currently prunestops (those classes ending with an '!' which Xstop the backtracking after a \PRUNE) can not be nested; a \PRUNE after Xan inner prunestop has been exited will cause an error message. This Xshould probably be fixed sometime, as well as making the prunestop Xspecification more elegant. Example: X X%MAIN XJoe got sick, \THENWHAT!/ . X%THENWHAT! X\MIDDLE \CONVALESCE X%MIDDLE Xwas sick for a while, Xate some magic herbs, Xand died\PRUNE X%CONVALESCE Xthen got better. Xand recovered. X%% X X In this case, if "and died" is chosen, text generation will resume Ximmediately after \THENWHAT!/ , producing "Joe got sick, and died.". X X COMMENTS: X XAt any point, '\*' may appear on a line and the rest of the line Xis ignored. Blank lines are ignored completely ( as are lines Xbeginning in \* ). XEmpty instances must therefore be given an explicit weight of one: X X%AllOrNothing\* 50% chance, 'All', or nothing. XAll X(1) X SHAR_EOF if test 5498 -ne "`wc -c < 'manual'`" then echo shar: "error transmitting 'manual'" '(should have been 5498 characters)' fi fi echo shar: "extracting 'spew.c'" '(22540 characters)' if test -f 'spew.c' then echo shar: "will not over-write existing file 'spew.c'" else sed 's/^X//' << \SHAR_EOF > 'spew.c' X/* X * SPEW.C X */ X X/* #define DOS Undef this if compiling under BSD UNIX */ X#define PRUNE /* Undef this if /PRUNE pseudoclass not used or X setjmp/longjmp not available (WML) */ X X X#ifndef lint Xstatic char *cpr[]={ X " Copyright 1987 Greg Smith", X " Permission is granted to freely use and distribute this software", X "provided this notice is left attached and no monetary gain is made." X}; X Xstatic char *mod_notice[] = { X " Modified for compilation under DOS with Borland Turbo C.", X "by Ti Kan 5-31-1988.", X " Other modifications, additions, and improvements", X "by Wim Lewis (WML) August 1990." X}; X#endif X X#include <stdio.h> X#include <ctype.h> X X#ifdef PRUNE X#include <setjmp.h> X#endif X X#ifdef DOS X X#include <stdlib.h> X#include <string.h> X#include <alloc.h> X#include <bios.h> X#define index(s,c) strchr(s,c) X#define rindex(s,c) strrchr(s,c) X X#else X X#include <strings.h> Xextern char *malloc(); Xextern int atoi(); X X#endif X Xchar *my_alloc(); Xchar *save(); X#define TRUE (1) X#define FALSE (0) X#define MAGIC 4 /* distinguish compressed file from normal */ X Xvoid print(), printc(); X X/*--------------- system configuration ------------------*/ X X/* define some parameters */ X X#define MAXCLASS 300 /* max # of classes */ X#define MAXLINE 256 /* max size of input line */ X#define MAXDEF 1000 /* max # bytes in a definition */ X X/* Define the default rulesfile */ X X#ifndef DEFFILE X#define DEFFILE "/b1/wiml/pub/headline" X#endif X X/* Define the environment variable which is to be interrogated for X name of rules file before DEFFILE is used. Delete this to X remove the code that calls getenv() */ X X#define ENVIRON "RULESFILE" X X/* Define the output line width. Lines are word-broken to this width. */ X X#define LINE_WIDTH (75) X X/* Define the random number generator */ X X#ifndef DOS Xextern long getpid(); Xextern int rand(), srand(); X#endif X X X /* SETRAND must be a complete statement: note semicolon */ X#ifdef DOS X#define SETRAND (void) srand((unsigned) biostime(0, 0L)); X#else X#define SETRAND (void)srand((int) getpid()); X#endif X X /* ROLL(n) returns integer 0..n-1 */ X#define ROLL(n) ((((long)rand()&0x7ffffff)>>5)%(n)) X X/* Enable '-d' dump debug option by defining DUMP */ X#define DUMP X X/*---------------------------------------------------*/ X XFILE *InFile; X Xtypedef struct def_struct{ X int cumul; /* cumulative weights */ X char *string; /* string which defines it */ X struct def_struct *next; /* link to next */ X} defn; Xdefn *process(); X/* X * within a definition, names of subdefinitions are bracketed in BSLASH X * and SLASH chars. The whole definition ends with a '\0'. X * The SLASH character is always follwed by a variant tag - default is ' '. X */ X#define BSLASH '\\' X#define SLASH '/' X#define VBAR '|' X Xtypedef struct{ X int weight; /* total weight of definitions in class */ X defn *list; /* list of them */ X char *name; /* name of this class */ X char *tags; /* pointer to list of tags */ X} class; X Xclass * Class; /* pointer to array of class records */ Xchar *NullTags = " "; /* default tags ( shared ) */ Xint Classes; /* number of them */ Xint HowMany = 1; Xint CompIn = FALSE; /* is input file in compressed format? */ Xint CompMain; /* class # of MAIN class when compressed */ X#ifdef PRUNE Xjmp_buf prunebuf; /* where to longjmp when PRUNE encountered */ Xint prune_ok; /* Whether prunebuf is still valid */ X#endif X Xchar InLine[MAXLINE]; X Xmain(argc, argv ) Xint argc; Xchar **argv; X{ X char *fname; X char main_class[20]; X int i, c_flag = FALSE; X#ifdef DUMP X int d_flag = FALSE; X#endif DUMP X#ifdef ENVIRON X extern char *getenv(); X fname = getenv( ENVIRON ); X#else X fname = NULL; X#endif ENVIRON X X while( argc > 1 ){ X if( isdigit(*argv[1]) ){ X HowMany = atoi(*++argv); X --argc; X }else if( strcmp( argv[1], "-c") == 0 ){ X c_flag = TRUE; /* 'compress' option */ X --argc; X ++argv; X#ifdef DUMP X }else if( strcmp( argv[1], "-d" )== 0 ){ X d_flag = TRUE; /* 'dump' option */ X --argc; X ++argv; X#endif DUMP X }else break; X } X if( argc > 1 ) fname = argv[1]; X if (fname == NULL ) fname = DEFFILE; X InFile = fopen( fname, "r" ); X if( InFile == NULL ){ X fprintf( stderr, "Can\'t open: %s\n", fname ); X exit(1); X } X init(); X#ifdef DUMP X if( d_flag ){ X dump(); X exit(0); X } X#endif DUMP X if( c_flag ){ X compress(); X }else{ X if( CompIn ) sprintf( main_class, "%d/ ", CompMain); X else strcpy( main_class, "MAIN/ "); X for(i=0; i<HowMany; ++ i) X { X#ifdef PRUNE X if(setjmp(prunebuf) == 0) X { X prune_ok = 1; X#endif X display(main_class,' '); X#ifdef PRUNE X } X#endif X } X } X exit(0); X} X Xinit(){ X int c; X X SETRAND /* spin random number gen */ X c = getc( InFile ); /* is compressed? */ X CompIn = ( c== MAGIC ); /* set flag */ X if( CompIn ){ X readcomp(); /* read compressed version */ X }else{ X ungetc(c, InFile ); X readtext(); X } X} Xreadtext(){ X register class *cp; X register defn *dp; X defn **update; X int clcomp(); X X Class = (class *)my_alloc( (unsigned)(MAXCLASS * sizeof(class)) ); X Classes = 0; X X cp = Class; X readline(); X if( InLine[0]!='%'){ X fprintf( stderr,"Class definition expected at: %s\n", InLine); X exit(1); X } X while( InLine[1] != '%' ){ X if( Classes == MAXCLASS ){ X fprintf(stderr,"Too many classes -- max = %d\n", MAXCLASS); X exit(1); X } X setup( cp ); /* set up the class struct */ X readline(); X if( InLine[0] == '%' ){ X fprintf( stderr, "Expected class instance at: %s\n", InLine); X exit(1); X } X update = &(cp->list); /* update pointer */ X do{ X dp = process(); X *update = dp; X cp->weight += dp->cumul; /* add new stuff */ X dp->cumul = cp->weight; /* set breakpoint */ X update = &(dp->next); X }while( readline(), InLine[0]!= '%' ); X ++Classes; /* count them */ X ++cp; X *update = NULL; X } X qsort( (char*)Class, Classes, sizeof( class ), clcomp); X} X/* X * display is given a class name ( delimited by SLASH, not '\0' ), X * and will (1) find its class descriptor, by calling lookup X * (2) pick a definition (3) output that definition, and X * recursively display any definitions in it, and convert any escapes. X * The variant tag after the SLASH is used to pick out the appropriate X * variants. If that variant tag is '&', the tag 'deftag' is used, which X * is the active variant of the containing activation. X */ Xdisplay(s,deftag) Xchar *s; Xint deftag; X{ X register class *cp; X register defn *dp; X register char *p; X class *lookup(); X int i,variant,incurly; X register int c,writing; X int weprune=0; /* if we set the prune stop here */ X X if( CompIn ){ /* input is compressed */ X cp = &Class[ atoi(s) ]; /* explicit class # */ X }else{ X#ifdef PRUNE X if(!strncmp(s, "PRUNE/", 6)) X { X if(!prune_ok) X { X print("\n -- Prune too late, aborting.\n"); X exit(2); X } X else longjmp(prunebuf, 1); X } X if(index(s, '!') == (index(s, '/')-1)) X { X if(setjmp(prunebuf)) X { X prune_ok = 0; X return; X } X weprune=1; X } X#endif X cp = lookup(s); X if( cp == NULL ) { /* none found */ X print("???"); X while( *s != SLASH ) printc( *s++ ); X print("???"); X#ifdef PRUNE X if(weprune) prune_ok = 0; X#endif X return; X } X X } X c = index(s,SLASH)[1]; /* get variant tag */ X if( c != '&' ) deftag=c; /* use given tag */ X p = index(cp->tags, deftag); /* look it up */ X if(p == NULL ){ X variant = 0; X print("??"); X printc(deftag); X print("??"); X deftag = ' '; /* for passing as deftag */ X }else variant = p - cp->tags; X X i = ROLL( cp->weight ); X dp = cp->list; X while(dp->cumul <= i){ /* pick one based on cumul. weights */ X dp = dp->next; X } X X incurly = 0; /* not in curlies */ X writing = 1; /* writing */ X p = dp->string; /* this is the string */ X for(;;)switch(c = *p++){ X case '\0': X#ifdef PRUNE X if(weprune) prune_ok = 0; X#endif X return; X case BSLASH: X if(( c = *p++) == '\0' ) X { X#ifdef PRUNE X if(weprune) prune_ok = 0; X#endif X return; /* ?? */ X } X else if( c == '!' ){ X if(writing)printc('\n'); /* \! = newline */ X }else if( isalnum(c) ){ /* reference */ X if(writing)display(p-1,deftag); /* recurse */ X while( *p!=SLASH )++p; X p += 2; /* skip variant tag */ X }else{ X if(writing) printc(c); X } X break; X case '{': X if( !incurly ){ X incurly = 1; X writing = (variant == 0 ); X }else{ X if( writing )printc('{'); X } X break; X case VBAR: X if( incurly ){ X writing = ( variant == incurly++ ); X }else{ X printc(VBAR); X } X break; X case '}': X if( incurly ){ X writing = 1; X incurly = 0; X }else printc('}'); X break; X default: X if( writing) printc(c); X } X /*NOTREACHED*/ X} Xclass * Xlookup( str ) /* delimited by SLASH, not '\0' */ Xchar *str; X{ X int first, last, try, comp; X int namecomp(); X X first = 0; X last = Classes-1; X while( first <= last ){ X try = (first+last)>>1; X comp = namecomp( str, Class[try].name ); X if( comp == 0 ) return &Class[try]; X if( comp > 0 ) first = try+1; X else last = try-1; X } X return NULL; X} Xint namecomp(a,b) /* 'a' is delim. by SLASH, 'b' by NULL */ Xregister char *a,*b; X{ X register int ac; X for(;;){ X ac = *a++; X if(ac == SLASH ) ac = '\0'; X if( ac < *b ) return -1; X if( ac > *b++ ) return 1; X if( ac == '\0' ) return 0; X } X} Xreadline(){ X register char *p; X do{ X if( fgets( InLine, MAXLINE, InFile ) == NULL ){ X InLine[0] = InLine[1] = '%'; X InLine[2] = '\0'; /* create EOF */ X }else if( (p=rindex( InLine, '\n'))!= NULL ) *p = '\0'; X p = InLine; X while( (p = index( p, BSLASH )) != NULL ){ X if(p[1] == '*' ){ X *p = 0; /* kill comment */ X break; X }else ++p; X } X }while( InLine[0] == '\0' ); X} X Xint clcomp(a,b) Xregister class *a,*b; X{ X if( a==b) return 0; X return strcmp( a->name, b->name ); X} Xchar *save(str) Xchar *str; X{ X register char *p; X p = my_alloc( (unsigned)((strlen(str)+1)*sizeof(char))); X return strcpy(p,str); X} X/* X * setup a class record. The 'class' line is in InLine. X */ Xsetup(cp) Xregister class *cp; X{ X char temp[100]; X register char *p,*p2; X X p = &InLine[1]; /* point after the % */ X while( *p == ' ' )++p; X if( !isalnum(*p) ) goto baddec; X p2 = temp; X do *p2++ = *p++; while( isalnum(*p) || (*p == '!')); X *p2 = '\0'; X cp->weight = 0; /* save the name of it */ X cp->name = save( temp ); X cp->list = NULL; X cp->tags = NullTags; /* by default */ X for(;;)switch(*p++){ X case '\0': X return; /* all done; */ X case ' ': X break; /* allowed those */ X case '{': /* tags list */ X if( cp->tags != NullTags ) goto baddec; /* already */ X p2 = temp; X *p2++ = ' '; /* provide null tag */ X while(*p!='}'){ X if( !isalnum(*p)) goto baddec; X *p2++ = *p++; X } X ++p; /* junk rh brace */ X *p2 = 0; X cp->tags = save(temp); X break; X default: goto baddec; X } X baddec: X fprintf(stderr,"Bad class header: %s\n", InLine ); X exit(1); X} X/* X * create a 'processed' version of the InLine, and return a pointer to X * the definition. The 'cumul' field is temporarily used to hold the X * assigned weight of the line. X */ Xdefn *process(){ X static char stuff[ MAXDEF ]; X register char *p,*pout; X register defn *dp; X register int c; X X dp = (defn *) my_alloc( (unsigned) sizeof( defn )); X X p = InLine; X pout = stuff; X if( *p == '(' ){ /* get a weight */ X while(*++p ==' '); /* scan */ X if(!isdigit(*p)) goto badweight; X c = *p - '0'; X while(isdigit(*++p)) c = c*10 + (*p - '0' ); X while( *p == ' ')++p; X if( *p != ')') goto badweight; X ++p; X dp->cumul = c; X }else{ X dp->cumul = 1; /* default weight */ X } X while((c = *p++)!='\0')switch(c){ X case BSLASH: X *pout++ = BSLASH; X if( isalnum(*p)){ /* is a ref */ X do{ *pout++ = *p++; X }while( isalnum(*p) || (*p == '!')); X *pout++ = SLASH; /* delimit */ X if( *p == SLASH ){ /* get variant char */ X ++p; X if( !isalnum(*p)&& *p!= ' ' && *p!= '&' ){ X *pout++ = ' '; X }else *pout++ = *p++; X }else *pout++ = ' '; X }else{ X *pout++ = *p; X if( *p!= '\0'){ X ++p; X }else{ X --pout; /* delete spurious '\' */ X readline(); /* get new line */ X p = InLine; /* point to it */ X } X } X break; X default: X *pout++ = c; X } X *pout = '\0'; X dp->string = save( stuff ); X return dp; X X badweight: X fprintf(stderr, "Bad line weight: %s\n", InLine ); X exit(1); X /*NOTREACHED*/ X} X#ifdef DUMP Xdump(){ X register class *cp; X register defn *dp; X register int i; X for( i=0, cp=Class; i<Classes; ++cp,++i ){ X if( CompIn) X printf("%d, {%s} %d:\n",i ,cp->tags, cp->weight ); X else X printf("%s, {%s} %d:\n", cp->name,cp->tags, cp->weight ); X for( dp = cp->list; dp!=NULL; dp=dp->next ){ X printf("(%d)%s\n",dp->cumul, dp->string ); X } X } X} X#endif DUMP X Xchar *my_alloc(n) Xunsigned n; X{ X register char *p; X p = malloc( n ); X if( p==NULL ){ X fprintf(stderr, "Out Of Memory\n"); X exit(1); X } X return p; X} X X/* X * write the file to the standard output in compressed form, prepending X * the MAGIC byte for identification. X */ Xcompress(){ X register class *cp; X register int i; X X putchar( MAGIC ); X putw( Classes, stdout ); /* write the number of classes */ X putw( -Classes, stdout ); /* write this to make sure */ X X if( !CompIn ){ X cp = lookup("MAIN/ "); /* get main */ X if( cp == NULL ){ X fprintf(stderr, "MAIN undefined\n"); X exit(1); X } X CompMain = cp - Class; X } X putw( CompMain, stdout ); X cp = Class; X i = Classes; X while(i--) comp1(cp++); X} X/* X * write a 'class' record in compressed format X */ Xcomp1(cp) Xregister class *cp; X{ X register char *p; X register defn *dp; X register int n; X X putw( cp->weight, stdout ); /* write total weight */ X p = cp->tags; X if( strcmp(p,NullTags) != 0 ) /* special case " " -> "" */ X fputs( p, stdout ); /* write tags */ X putchar(0); /* delimiter */ X n = 0; X dp = cp->list; X while( dp!= NULL ){ X ++n; /* count the defs */ X dp = dp->next; X } X putw( n, stdout ); /* write the count of them */ X dp = cp->list; X while( dp != NULL ){ X compdef(dp); X dp = dp->next; /* compress them */ X } X} Xcompdef(dp) Xregister defn *dp; X{ X register char *p; X register int c; X putw( dp-> cumul , stdout ); /* write its cumul weight */ X p = dp->string; X while( (c = *p++) != '\0' ){ X if( c==BSLASH){ X if(!CompIn && isalnum(*p) ){ /* a ref */ X class *cp; X cp = lookup(p); /* find it */ X if( cp == NULL ){ X fprintf( stderr, "Undefined class: "); X while( *p != SLASH ) fputc( *p++, stderr); X fputc('\n', stderr ); X exit(1); X }else{ X printf("%c%d", BSLASH, cp-Class ); X while( *p != SLASH ) ++p; X } X }else{ /* is escape seq */ X putchar( BSLASH ); X putchar( *p++ ); X } X }else{ X putchar(c); X } X } X putchar(0); X} X X/* X * readcomp reads the compressed format of the file into core. X * the MAGIC char has been read already. X */ Xreadcomp(){ X register class *cp; X register int i; X Classes = getw( InFile ); X if( Classes <= 0 || getw( InFile ) + Classes != 0 ) X badfile(); /* format check */ X CompMain = getw( InFile ); /* read that next */ X Class = (class*) my_alloc( (unsigned)(Classes*sizeof(class)) ); X for( i= Classes, cp = Class; i--; ++cp)readcclass(cp); X} X Xreadcclass(cp) Xregister class *cp; X{ X register int n; X register defn *dp; X defn **dput; X X char store[MAXDEF]; /* for tags */ X cp->weight = getw( InFile ); X instring(store,MAXDEF); X cp->tags = ( store[0] == '\0' )? NullTags: save( store ); X n = getw( InFile ); X if( n<=0 ) badfile(); X dput = &(cp->list); /* link on here */ X while(n--){ X dp = (defn *)my_alloc( (unsigned) sizeof( defn)); X *dput = dp; X dp->cumul = getw( InFile ); X instring(store, MAXDEF ); X dp->string = save( store ); X dput = &(dp->next); X } X *dput = NULL; /* last one */ X} X X X Xvoid print(line) char *line; /* output text, breaking on word bounds */ X{ X for( ; *line ; line++) X printc(*line); X} X Xstatic char linebuf [LINE_WIDTH+1]; /* text awaiting output */ Xstatic int col = 0; /* column position */ Xvoid printc(ch) char ch; X{ X if(isspace(ch)) /* think about flushing */ X { X if((ch == '\n') || (ch == '\r')) X { X puts(linebuf); X linebuf[0] = 0; X col = 0; X return; X } X if((col + strlen(linebuf) > LINE_WIDTH) && col) X { X putchar('\n'); X fputs(linebuf, stdout); X putchar(ch); X col = strlen(linebuf) + 1; X linebuf[0] = 0; X return; X } X if(col + strlen(linebuf) > LINE_WIDTH) X { X puts(linebuf); X linebuf[0] = 0; X return; X } X fputs(linebuf, stdout); X col += strlen(linebuf); X *linebuf = 0; X if(col < LINE_WIDTH) X { X col++; X putchar(' '); X } X } X else X { X char *cp; X cp = linebuf + strlen(linebuf); X *cp++ = ch; X *cp = (char)0; X } X return; X} X Xinstring( where, how_many ) Xregister char *where; Xregister int how_many; X{ X register int c; X do{ X c = getc( InFile ); X if( c == EOF ) badfile(); X *where++ = c; X if( c== '\0' ) return; X }while(--how_many); X badfile(); X} Xbadfile(){ X fprintf(stderr,"Bad file format\n"); X exit(1); X} SHAR_EOF if test 22540 -ne "`wc -c < 'spew.c'`" then echo shar: "error transmitting 'spew.c'" '(should have been 22540 characters)' fi fi exit 0 # End of shell archive -- wiml@blake.acs.washington.edu Seattle, Washington | No sig under (William Lewis) | 47 41' 15" N 122 42' 58" W |||||||| construction