DIRECTORY Ascii USING [CR, LF, SP, TAB ], Commander USING [CommandProc, Register], IO, Loader USING [BCDBuildTime], LupineManager USING [ErrorHandlerProc, Language, Options, OptionsRec, ParamPassingMethod, String, TranslateRemoteInterface], Rope USING[ Equal, Fetch, Length, ROPE ]; LupineUserInterfaceImpl: CEDAR MONITOR IMPORTS Commander, IO, Loader, LupineManager, Rope = BEGIN inUse: BOOL _ FALSE; finished: CONDITION; Wait: ENTRY PROC[out: IO.STREAM] = BEGIN ENABLE UNWIND => NULL; wait: BOOL = inUse; IF wait THEN out.PutRope["Waiting for other use of Lupine to finish ... "]; WHILE inUse DO WAIT finished ENDLOOP; inUse _ TRUE; IF wait THEN out.PutRope["ok\n"]; END; Finish: ENTRY PROC = { inUse _ FALSE; NOTIFY finished }; DoIt: Commander.CommandProc--cmd: Commander.Handle-- = BEGIN in: IO.STREAM = cmd.in; out: IO.STREAM = cmd.out; targetLanguage: LupineManager.Language _ Cedar; defaultParamPassing: LupineManager.ParamPassingMethod _ Value; interMdsCalls: BOOL _ FALSE; freeServerArgs: BOOL _ TRUE; inlineDispatcherStubs: BOOL _ TRUE; inlineMarshal: BOOL _ TRUE; inlinePacketAllocateCount: INT _ 1000; inlineRopeMarshal: BOOL _ TRUE; declareSignals: BOOL _ TRUE; warnMDSAllocs: BOOL _ TRUE; importMultiple: BOOL _ TRUE; maxHeapAllocs: INT _ 50; maxMdsAllocs: INT _ 50; lineLength: INT _ 82; noClientModulesOut: INT _ 1; CheckAbort: PROC = {}; MyBreak: IO.BreakProc = BEGIN SELECT char FROM Ascii.SP, Ascii.CR, Ascii.TAB, Ascii.LF, ', => RETURN[sepr]; '[, '], ', => RETURN[break]; ENDCASE => RETURN[other]; END; SyntaxError: ERROR = CODE; ParseLine: PROC[commandStr: IO.STREAM] = BEGIN GetToken: PROC RETURNS[Rope.ROPE] = { RETURN[ commandStr.GetTokenRope[MyBreak].token ] }; nextToken: Rope.ROPE _ NIL; DO key: Rope.ROPE; args: LIST OF Rope.ROPE _ NIL; argCount: INT _ 0; IF nextToken = NIL THEN nextToken _ GetToken[ ! IO.EndOfStream => EXIT]; key _ nextToken; nextToken _ NIL; IF key.Equal[","] THEN LOOP; IF key.Length[] = 0 THEN EXIT -- end of stream! --; nextToken _ GetToken[ ! IO.EndOfStream => { nextToken _ NIL; CONTINUE } ]; IF nextToken.Equal["["] THEN BEGIN DO nextToken _ GetToken[ ! IO.EndOfStream => GOTO missingClose]; IF nextToken.Equal["]"] THEN EXIT; IF nextToken.Equal[","] THEN LOOP; IF args = NIL THEN args _ CONS[first: nextToken, rest: NIL] ELSE args.rest _ CONS[first: nextToken, rest: NIL]; argCount _ argCount+1; ENDLOOP; nextToken _ NIL; EXITS missingClose => { out.PutF["Missing \"]\"\n"]; ERROR SyntaxError[] }; END; DoCommand[key, args, argCount]; ENDLOOP; END; DoCommand: PROC[key: Rope.ROPE, args: LIST OF Rope.ROPE, argCount: INT] = BEGIN SELECT TRUE FROM key.Equal["Help", FALSE] => { Help[] }; key.Equal["TranslateInterface", FALSE] => { IF argCount # 1 THEN GOTO wrong; TranslateInterface[args.first] }; key.Equal["TargetLanguage", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetTargetLanguage[args.first] }; key.Equal["DefaultParameterPassing", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetParameterPassing[args.first] }; key.Equal["InterMdsCalls", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetInterMdsCalls[args.first] }; key.Equal["FreeServerArguments", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetFreeServerArgs[args.first] }; key.Equal["InlineDispatcherStubs", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetInlineStubs[args.first] }; key.Equal["InlineMarshal", TRUE] => { IF argCount # 1 THEN GOTO wrong; SetInlineMarshal[args.first] }; key.Equal["InlineRopeMarshal", TRUE] => { IF argCount # 1 THEN GOTO wrong; SetInlineRopeMarshal[args.first] }; key.Equal["DynamicHeapNEWs", FALSE] => { IF argCount # 2 THEN GOTO wrong; SetDynamicHeapNEWs[args.first, args.rest.first] }; key.Equal["LineLength", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetLineLength[args.first] }; key.Equal["DeclareSignals", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetDeclareSignals[args.first] }; key.Equal["WarnMDSAllocs", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetWarnMDSAllocs[args.first] }; key.Equal["ImportSingle", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetImportSingle[args.first] }; key.Equal["InlinePacketAllocate", TRUE] => { IF argCount # 1 THEN GOTO wrong; SetInlinePacketAllocate[args.first] }; argCount = 0 => TranslateInterface[key]; ENDCASE => { out.PutF["Unknown command \"%g\"\n", [rope[key]]]; ERROR SyntaxError[] }; EXITS wrong => { out.PutF["Wrong number of arguments to the \"%g\" command\n", [rope[key]]]; ERROR SyntaxError[] }; END; Help: PROC = BEGIN out.PutRope["Lupine accepts command lines of the form: Lupine command[args] command[args] command[args] . . . The following commands are available (\"TranslateInterface[module]\" may be shortened to \"module\"). Help[] -- prints this message TranslateInterface[interfaceName] -- produces the RPC stubs modules for that interface TargetLanguage[{Cedar,Mesa} _ Cedar] -- allows production of Pilot-compatible stubs -- (which can't be run under Cedar)"]; out.PutRope[" DefaultParameterPassing[{Var, Value, Result, Handle} _ Value] -- default parameter passing mode InterMdsCalls[BOOL _ FALSE] -- produces stubs for non-remote calls (archaic?) FreeServerArguments[BOOL _ TRUE] -- \"FALSE\" prevents de-allocation of POINTER -- referents after server procedure calls InlineDispatcherStubs[BOOL _ TRUE] -- \"FALSE\" is needed for large interfaces to prevent -- compiler storage overflow InlineMarshal[BOOL _ TRUE] -- \"FALSE\" produces a marshalling procedure per type. -- This can save code size at the expense of speed. InlineRopeMarshal[BOOL _ TRUE] -- \"FALSE\" produces prodedure calls for ROPE marshalling. -- This can save code size at the expense of speed. InlinePacketAllocate[BOOL _ TRUE | INT] -- \"FALSE\" does a procedure call to allocate packet buffers -- greater than 64 words, while \"TRUE\" does the normal case -- inline, and resorts to the procedure call for special cases. -- An INT is the count of inline allocates to do. DynamicHeapNEWs[long: INT _ 50, short: INT _ 50] -- limit on dynamic storage allocations for -- (LONG) POINTER referents. LineLength[INT _ 82] -- length of lines produced in stub sources ImportSingle[BOOL _ FALSE] -- \"TRUE\" means that this interface will always have a single \"instance\" on the client's machine DeclareSignals[BOOL _ TRUE] -- \"FALSE\" means someone else will declare -- (and export) the interface's signals WarnMDSAllocs[BOOL _ TRUE] -- \"FALSE\" means suppress warnings about -- short POINTER (\"MDS\") allocations (Mesa only) "]; END; TranslateInterface: PROCEDURE [interfaceFile: Rope.ROPE] = BEGIN aborted, errors, warnings: BOOLEAN _ FALSE; translateOptions: LupineManager.Options; HandleError: LupineManager.ErrorHandlerProc = BEGIN CheckAbort[]; out.PutChar['\n]; SELECT type FROM abort => { aborted _ TRUE; out.PutRope["\nFatal error"] }; error => { errors _ TRUE; out.PutRope["\nError"] }; warning => { warnings _ TRUE; out.PutRope["\nWarning"] }; ENDCASE => NULL; IF outputFileName.Length[] # 0 THEN out.PutF[" at %g[%g]", [rope[outputFileName]], [integer[outputFileCharPosition]]]; out.PutF[":\n %g", [rope[codeExplanation]]]; IF problemCausingText.Length[] # 0 THEN out.PutF["\n Problem-causing file, module, identifier, or type: %g", [rope[problemCausingText]] ]; RETURN [abortTranslation: FALSE]; END; -- HandleError. CheckAbort[]; out.PutF["Translating %g ... ", [rope[interfaceFile]] ]; translateOptions _ NEW [ LupineManager.OptionsRec _ [ targetLanguage: targetLanguage, defaultParamPassing: (IF interMdsCalls THEN InterMds ELSE defaultParamPassing), freeServerArguments: freeServerArgs, inlineServerDispatcherStubs: inlineDispatcherStubs, inlineMarshal: inlineMarshal, inlinePacketAllocateCount: inlinePacketAllocateCount, inlineRopeMarshal: inlineRopeMarshal, declareSignals: declareSignals, warnMDSAllocs: warnMDSAllocs, importMultiple: importMultiple, noClientModulesOut: noClientModulesOut, maxHeapAllocations: maxHeapAllocs, maxMdsAllocations: maxMdsAllocs ] ]; TRUSTED{ LupineManager.TranslateRemoteInterface[ interfaceBcdFilename: interfaceFile, errorHandler: HandleError, options: translateOptions, desiredLineLength: lineLength ] }; IF aborted OR errors OR warnings THEN out.PutChar['\n]; out.PutF["\nTranslation of %g %g.\n", [rope[interfaceFile]], [rope[SELECT TRUE FROM aborted => "aborted", errors => "finished with errors", warnings => "finished with warnings", ENDCASE => "complete"]] ]; END; -- TranslateInterface. Bool: PROC[arg: Rope.ROPE, complain: BOOL _ TRUE] RETURNS[BOOL] = BEGIN SELECT TRUE FROM Rope.Equal[arg, "TRUE", FALSE] => RETURN[TRUE]; Rope.Equal[arg, "FALSE", FALSE] => RETURN[FALSE]; ENDCASE => { IF complain THEN out.PutRope["\"TRUE\" or \"FALSE\" expected\n"]; ERROR SyntaxError[] }; END; Int: PROC[arg: Rope.ROPE, complain: BOOL _ TRUE] RETURNS[val: INT _ 0] = BEGIN FOR i: CARDINAL IN CARDINAL[0..arg.Length[]) DO c: CHAR = arg.Fetch[i]; IF c IN ['0..'9] THEN val _ val * 10 + (c-'0) ELSE { IF complain THEN out.PutRope["Decimal number expected\n"]; ERROR SyntaxError[]; }; ENDLOOP; END; SetTargetLanguage: PROCEDURE [language: Rope.ROPE] = BEGIN SELECT TRUE FROM Rope.Equal[language, "Cedar", FALSE] => targetLanguage _ Cedar; Rope.Equal[language, "Mesa", FALSE] => targetLanguage _ Mesa; ENDCASE => { out.PutRope["Unknown target language\n"]; ERROR SyntaxError[] }; END; SetParameterPassing: PROCEDURE [kind: Rope.ROPE] = BEGIN SELECT TRUE FROM Rope.Equal[kind, "VAR", FALSE] => defaultParamPassing _ Var; Rope.Equal[kind, "VALUE", FALSE] => defaultParamPassing _ Value; Rope.Equal[kind, "RESULT", FALSE] => defaultParamPassing _ Result; Rope.Equal[kind, "HANDLE", FALSE] => defaultParamPassing _ Handle; ENDCASE => { out.PutRope["Unknown parameter mode\n"]; ERROR SyntaxError[] }; END; SetInterMdsCalls: PROCEDURE [onOff: Rope.ROPE] = { interMdsCalls _ Bool[onOff] }; SetFreeServerArgs: PROCEDURE [onOff: Rope.ROPE] = { freeServerArgs _ Bool[onOff] }; SetInlineStubs: PROCEDURE [onOff: Rope.ROPE] = { inlineDispatcherStubs _ Bool[onOff] }; SetInlineMarshal: PROCEDURE [onOff: Rope.ROPE] = { inlineMarshal _ Bool[onOff] }; SetInlinePacketAllocate: PROCEDURE [onOff: Rope.ROPE] = { tryForInt: BOOL _ FALSE; inlinePacketAllocate: BOOL _ FALSE; inlinePacketAllocate _ Bool[onOff, FALSE ! SyntaxError => {tryForInt _ TRUE; CONTINUE}]; IF tryForInt THEN { intBad: BOOL _ FALSE; inlinePacketAllocateCount _ Int[onOff ! SyntaxError => {intBad _ TRUE; CONTINUE}]; IF intBad THEN inlinePacketAllocate _ Bool[onOff]; } ELSE inlinePacketAllocateCount _ IF inlinePacketAllocate THEN 1000 ELSE 0; }; SetInlineRopeMarshal: PROCEDURE [onOff: Rope.ROPE] = { inlineRopeMarshal _ Bool[onOff] }; SetDynamicHeapNEWs: PROCEDURE [heap, mds: Rope.ROPE] = { maxHeapAllocs _ Int[heap]; maxMdsAllocs _ Int[mds] }; SetLineLength: PROCEDURE [length: Rope.ROPE] = { lineLength _ Int[length] }; SetDeclareSignals: PROCEDURE [onOff: Rope.ROPE] = { declareSignals _ Bool[onOff] }; SetWarnMDSAllocs: PROCEDURE [onOff: Rope.ROPE] = { warnMDSAllocs _ Bool[onOff] }; SetImportSingle: PROCEDURE [onOff: Rope.ROPE] = { importMultiple _ ~Bool[onOff] }; TRUSTED{ out.PutF["Lupine version 1.2 of %g.\n\n", [time[Loader.BCDBuildTime[]]] ] }; Wait[out]; ParseLine[IO.RIS[cmd.commandLine] ! SyntaxError => CONTINUE; UNWIND => Finish[] ]; Finish[]; END; Commander.Register[key: "Lupine", proc: DoIt, doc: "Produces stub modules for Cedar RPC; type \"Lupine Help\" for details"]; END. ²LupineUserInterfaceImpl.mesa. Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by BZM on 2-May-82 23:18:33. Last Edited by: Birrell, September 14, 1983 8:22 am Last Edited by: Swinehart, July 3, 1984 1:50:25 pm PDT Bob Hagmann February 8, 1985 5:06:48 pm PST key.Equal["GeneratedClientModules", FALSE] => { IF argCount # 1 THEN GOTO wrong; SetGeneratedClientModules[args.first] }; From failed attempt to all multiple output modules to rpcclientimpl GeneratedClientModules[CARDINAL [1..9] _ 1], -- split generated client module (e.g., TargetRpcClientImpl) -- If more than one, imbed digit after \"Client\" in name. PROCEDURE [type: ErrorType, code: ErrorCode, codeExplanation: String, outputFileName: String_StringNIL, outputFileCharPosition: LONG INTEGER, problemCausingText: String_NIL ] RETURNS [abortTranslation: BOOLEAN_FALSE]; SetGeneratedClientModules: PROCEDURE [number: Rope.ROPE] = { num: INT; num _ Convert.IntFromRope[number ! Convert.Error => GOTO wrong]; IF num < 1 OR num > 9 THEN GOTO wrong; noClientModulesOut _ num ; EXITS wrong => { out.PutRope["GeneratedClientModules must be in [0..9]"]; ERROR SyntaxError[]; }; }; Module Initialization. Κ z˜headšœ™Icodešœ Οmœ1™<—Jšœ)™)J™3™6L™+—J˜šΟk ˜ Jš œžœžœžœžœžœ˜Jšœ žœ˜(Jšžœ˜Jšœžœ˜Jšœžœi˜|Jšœžœžœ˜)J˜J˜—šœžœž˜&Jšžœ žœ˜4—J˜šž˜J˜—Jšœžœžœ˜Jšœ ž œ˜J˜š Οnœžœžœžœžœ˜"Jšž˜Jšžœžœžœ˜Jšœžœ ˜Jšžœžœ?˜KJšžœžœžœ žœ˜%Jšœžœ˜ Jšžœžœ˜!Jšžœ˜—J˜šŸœžœžœ˜Jšœ žœžœ ˜#—J˜šŸœΟcœ˜6Jšž˜Jšœžœžœ ˜Jšœžœžœ ˜J˜J˜/J˜>Jšœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜#Jšœžœžœ˜Jšœžœ˜&Jšœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜Jšœžœ˜Jšœžœ˜Jšœ žœ˜Jšœžœ˜J˜šŸ œžœ˜Jšœ˜—J˜šŸœžœ ˜Jšž˜šžœž˜Jš œžœžœžœžœžœ˜