// Bcpl PrinterPList.bcpl // Property list routines for Printer status //Extracted and modified from FtpPListProt //last modified: //Rick Tiberi July 27, 1979 3:07 PM get "Time.d" get "Streams.d" external [ //outgoing procedures ScanPList; InitPListStream WriteStringProp; WriteDateProp; WriteNumberProp WriteKeywordProp; WriteBooleanProp Nin; WriteDT; ParseDate //incoming procedures Puts; Gets; Endofs; Wss; Zero; Allocate; Free ExtractSubstring; PutTemplate; MoveBlock MyFrame; CoReturn; GotoFrame; MulPlus32x16 PACKDT; UNPACKDT; WRITEUDT; FINDMONTH //incoming statics sysZone ] manifest [ maxPropItemChars = 127 maxPropItemWords = maxPropItemChars rshift 1 +1 QuoteChar = $' ] //---------------------------------------------------- structure String: [ length byte; char↑1,255 byte ] //---------------------------------------------------- //---------------------------------------------------- structure Time [ h word; l word ] //---------------------------------------------------- //---------------------------------------------------- structure [ bytes↑1,1 byte ] //---------------------------------------------------- //---------------------------------------------------- let ScanPList(stream, routine,param) = valof //---------------------------------------------------- //Expects to find a pList as the next thing in stream. //Scans the pList, calling routine(name,value,param) for each item, which // should return true to continue scanning and false to abort. //Returns true if all goes well. //Returns false if the list had bad syntax. [ let char = IgnoreBlanks(stream) if char ne $( then [ resultis false ] let name = Allocate(sysZone,maxPropItemWords) let value = Allocate(sysZone,maxPropItemWords) let ok = valof [ switchon IgnoreBlanks(stream) into [ case $): resultis true case $(: break default: resultis false ] repeat unless GetPListItem(stream, name, $*S) resultis false unless GetPListItem(stream, value, $)) resultis false unless routine(name, value, param) resultis false ] repeat Free(sysZone, name) Free(sysZone, value) resultis ok ] //---------------------------------------------------- and IgnoreBlanks(stream) = valof //---------------------------------------------------- [ if Endofs(stream) resultis -1 let char = Gets(stream) if char ne $*S resultis char ] repeat //---------------------------------------------------- and GetPListItem(stream, lvDest, termChar) = valof //---------------------------------------------------- //Reads stream assembling a string at lvDest. //Unquotes characters. Returns true if all is well. //Terminates when it reads termChar. [ lvDest>>String.length = 0 let quotePending = false let char = IgnoreBlanks(stream) [ if char eq -1 resultis false if char eq termChar & not quotePending resultis true if char ne QuoteChar % quotePending then [ if lvDest>>String.length eq maxPropItemChars resultis false lvDest>>String.length = lvDest>>String.length + 1 lvDest>>String.char↑(lvDest>>String.length) = char ] quotePending = char eq QuoteChar & not quotePending char = Gets(stream) ] repeat ] //---------------------------------------------------- let WriteStringProp(stream,name,string) be //---------------------------------------------------- [ let QuotedWss(stream,string) be for i = 1 to string>>String.length do [ let char = string>>String.char↑i if char eq $) % char eq $( % char eq QuoteChar then Puts(stream,QuoteChar) Puts(stream,char) ] PutTemplate(stream,"($S $P)",name,QuotedWss,string) ] //---------------------------------------------------- and WriteDateProp(stream,name,lvDate) be //---------------------------------------------------- [ if lvDate>>Time.h ne 0 then PutTemplate(stream,"($S $P)",name,WriteDT,lvDate) ] //---------------------------------------------------- and WriteNumberProp(stream,name,number,double;numargs N) be //---------------------------------------------------- [ if N ls 4 then double = false test double //true if double precision ifnot PutTemplate(stream,"($S $UD)",name,number) ifso PutTemplate(stream,"($S $EUD)",name,number) ] //---------------------------------------------------- and WriteBooleanProp(stream,name,boolean) be //---------------------------------------------------- [ PutTemplate(stream,"($S $S)",name,(boolean?"TRUE","FALSE")) ] //---------------------------------------------------- and WriteKeywordProp(stream,name) be //---------------------------------------------------- [ PutTemplate(stream,"($S)",name) ] //---------------------------------------------------- and ParseDate(string,lvRes) = valof //---------------------------------------------------- //parses the string format date in string into an Alto //format date which it puts in the two word vector at lvRes. //returns true if successful, false if not. //"day-month-year hour:minute:second" [ let uv = vec lenUTV; Zero(uv,lenUTV) let frame = InterpretDate(uv) for i = 1 to string>>String.length do GotoFrame(frame,string>>String.char↑i) GotoFrame(frame,0) //flush out the last token resultis PACKDT(uv,lvRes) eq 0 ] //---------------------------------------------------- and InterpretDate(uv) be //---------------------------------------------------- [ let token = 1 manifest maxChars = 19 let temp = vec (maxChars rshift 1) let AlphaNumeric(char) = (char ge $0 & char le $9) % (char ge $A & char le $Z) % (char ge $a & char le $z) [ temp!0 = 0 let char = CoReturn(MyFrame()) test AlphaNumeric(char) ifnot loop //ignore punctuation separating tokens ifso [ let length = temp>>String.length if length ls maxChars then [ temp>>String.length = length+1 temp>>String.char↑(length+1) = char ] char = CoReturn() if AlphaNumeric(char) loop switchon token into [ case 1: [ Nin(temp,lv uv>>UTV.day); break ] case 2: [ uv>>UTV.month = FINDMONTH(temp); break ] case 3: [ Nin(temp,lv uv>>UTV.year) uv>>UTV.year = uv>>UTV.year+1900 break ] case 4: [ Nin(temp,lv uv>>UTV.hour); break ] case 5: [ Nin(temp,lv uv>>UTV.minute); break ] case 6: [ Nin(temp,lv uv>>UTV.second); break ] default: break ] ] repeat token = token+1 ] repeat ] //---------------------------------------------------- and WriteDT(stream,dt) be //---------------------------------------------------- [ let uv = vec 7 if dt!0 ne 0 then [ UNPACKDT(dt,uv) WRITEUDT(stream,uv) ] ] //---------------------------------------------------- and Nin(string,lvDest,double; numargs na) = valof //---------------------------------------------------- [ if na ls 3 then double = false let start = 1 for i = 1 to string>>String.length do if string>>String.char↑i ne $*S then [ start = i; break ] let number = vec 1; Zero(number,2) for i = start to string>>String.length do [ let char = string>>String.char↑i if char ls $0 % char gr $9 then resultis false MulPlus32x16(char-$0,10,number) ] test double ifnot lvDest!0 = number!1 ifso MoveBlock(lvDest,number,2) resultis true ] and // --------------------------------------------- let InitPListStream(s, buf, len) = valof // --------------------------------------------- [ Zero(s, lST) s>>ST.par1 = buf s>>ST.par2 = 0 s>>ST.par3 = len s>>ST.gets = PListGets s>>ST.puts = PListPuts s>>ST.endof = PListEndofs s>>ST.stateof = PListStateofs ] and // --------------------------------------------- let PListGets(s) = valof // --------------------------------------------- [ if Endofs(s) resultis -1 s>>ST.par2 = s>>ST.par2 + 1 resultis (s>>ST.par1)>>bytes↑(s>>ST.par2) ] and // --------------------------------------------- let PListPuts(s, char) = valof // --------------------------------------------- [ if Endofs(s) resultis -1 s>>ST.par2 = s>>ST.par2 + 1 let buf = s>>ST.par1 buf>>bytes↑(s>>ST.par2) = char ] and // --------------------------------------------- let PListEndofs(s) = s>>ST.par2 ge s>>ST.par3 // --------------------------------------------- and // --------------------------------------------- let PListStateofs(s) = s>>ST.par2 // ---------------------------------------------