|
|
1.1 ! root 1: % run this through LaTeX with the appropriate wrapper ! 2: ! 3: \chapter {Compiling Data-Structures}\label{pepy} ! 4: The \man pepy(1) program is a compiler for the presentation ! 5: elements discussed in Chapter~\ref{libpsap} in \volone/. ! 6: Although experimental in previous releases, ! 7: the \pgm{pepy} program has now stabilized. ! 8: ! 9: For those interested in trivia, ! 10: \pgm{pepy} stands for ! 11: \underbar{P}resentation ! 12: \underbar{E}lement ! 13: \underbar{P}arser ! 14: (\underbar{Y}ACC-based). ! 15: The \man yacc(1) program, ! 16: of course, ! 17: is a compiler-compiler.% ! 18: \footnote{This abbreviation is now strictly incorrect, as the \pgm{pepy} ! 19: program can now generate presentation elements as well as parse them.} ! 20: ! 21: \section {Warning} ! 22: Please read the following important message. ! 23: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 24: \bf NOTE:& Users of {\em The Cookbook\/} emply the \man posy(1) program ! 25: program as the front-end to \pgm{pepy}. ! 26: Hence, this chapter may be safely skipped. ! 27: It is included only for those misguided individuals who do not ! 28: \pgm{posy}. ! 29: This behavior is not recommended. ! 30: \end{tabular}}\] ! 31: ! 32: \section {Syntax Rules} ! 33: The \pgm{pepy} program reads a description of an {\em abstract syntax ! 34: module\/} ! 35: and produces a {\em C\/} program ! 36: which recognizes the objects described in the module, ! 37: or generates those objects, ! 38: or prints those objects. ! 39: The syntax of the input file corresponds almost exactly to the Abstract ! 40: Syntax Notation (ASN.1) discussed in Section~\ref{pepy:reading} on ! 41: page~\pageref{pepy:reading}. ! 42: ! 43: \subsection {ASN.1 Notation}\label{asn1:notation} ! 44: To summarize the ASN.1 syntax: ! 45: \begin{itemize} ! 46: \item Comments start with two adjacent dashes (`\verb"--"') and are ! 47: terminated by either new-line or another two adjacent dashes, ! 48: whichever comes first. ! 49: ! 50: \item Whitespace between tokens is ignored. ! 51: ! 52: \item Keywords are entirely in uppercase. ! 53: ! 54: \item The names of rules (types and values) start with an uppercase ! 55: character and may use either upper- or lowercase characters afterwards. ! 56: ! 57: \item The names of context-specific tags start with a lowercase character ! 58: and may use either upper- or lowercase characters afterwards. ! 59: ! 60: \item A name is an alphabetic character followed by zero or more ! 61: alphanumerics or dashes (except `\verb"--"', of course). ! 62: ! 63: \item Literal strings are surrounded by double-quotes (`\verb|"|'). ! 64: ! 65: \item Numbers take on one of two forms: ! 66: \begin{itemize} ! 67: \item a string of digits, optionally preceded by a minus sign, ! 68: which is interpreted in decimal; ! 69: and, ! 70: \item a string surrounded by single-quotes (`\verb"'"') and ! 71: immediately followed by one of \verb"B", \verb"b", ! 72: \verb"H", or \verb"h", which is interpreted as either ! 73: a binary (\verb"B" or \verb"b") or hexadecimal (\verb"H" ! 74: or \verb"h") number. ! 75: \end{itemize} ! 76: \end{itemize} ! 77: ! 78: An example of a specification using ASN.1 can be found in ! 79: Figure~\ref{ASNexample}. ! 80: {\let\small=\scriptsize %%% yikes! ! 81: \tagrind[tp]{grind4-1}{Example of a specification using ASN.1}{ASNexample}} ! 82: ! 83: \subsection {ASN.1 Extensions} ! 84: The \pgm{pepy} program recognizes several extensions to the ASN.1 syntax: ! 85: {\em compiler directives}, {\em action statements}, ! 86: {\em control statements}, and, {\em value passing statements}. ! 87: ! 88: \subsubsection {Compiler Directives} ! 89: The compiler directives control the type of {\em C\/} routines ! 90: that are produced. The \pgm{pepy} program can generate ! 91: routines to parse, create, and print presentation elements. ! 92: The directives may occur after the \verb"BEGIN" keyword; ! 93: and anywhere an \verb"END" keyword may occur. Each occurrence specifies ! 94: the type of {\em C\/} routine to generate for successive ! 95: type definitions and applies until the next directive. ! 96: ! 97: \newpage %%% hack ! 98: The directives are: ! 99: \begin{describe} ! 100: \item[\verb"ENCODER" build] --- directs \pgm{pepy} to create ! 101: routines for the construction of presentation elements; ! 102: ! 103: \item[\verb"DECODER" parse] --- directs \pgm{pepy} to create ! 104: routines to parse presentation elements; ! 105: ! 106: \item[\verb"PRINTER" print] --- directs \pgm{pepy} to create ! 107: routines which print the contents of presentation elements; ! 108: or, ! 109: ! 110: \item[\verb"SECTIONS" build parse print] --- directs \pgm{pepy} ! 111: to create multiple forms of above. ! 112: \end{describe} ! 113: The \verb"build", \verb"parse", and \verb"print" strings are used to construct ! 114: the name of the routine and are described later. ! 115: ! 116: With the \verb"SECTIONS" directive, ! 117: the value \verb"none" may be used as a null-valued place-holder. ! 118: For example: ! 119: \begin{quote}\small\begin{verbatim} ! 120: SECTIONS none undo pp ! 121: \end{verbatim}\end{quote} ! 122: indicates that \pgm{pepy} should generate decoding and printing routines ! 123: (using prefixes \verb"undo" and \verb"pp" respectively), ! 124: and that no encoding routines should be generated. ! 125: ! 126: There is also another directive, ! 127: which must occur immediately {\em before\/} the \verb"BEGIN" keyword: ! 128: \begin{describe} ! 129: \item[\verb"PREFIXES" build parse print] --- tells \pgm{pepy} ! 130: what \verb"SECTIONS" were used in other modules. ! 131: \end{describe} ! 132: ! 133: \subsubsection {Action Statements} ! 134: The lexemes \verb"%{" and \verb"}%" surround {\em C\/} code which the ! 135: resulting program should execute at the appropriate time. ! 136: The code may be of arbitrary length, ! 137: spanning many lines in the input file. ! 138: ! 139: Actions may occur in several places in the input file. ! 140: Depending on the position of the actions, ! 141: slightly different semantics are associated with the code. ! 142: There are four types of actions: ! 143: {\em verbatim actions}, {\em type actions}, {\em tag actions}, and, ! 144: {\em declaration actions}. ! 145: ! 146: The first type of actions are {\em verbatim\/} actions which occur in two ! 147: places in the input file: ! 148: \begin{itemize} ! 149: \item immediately before the \verb"BEGIN" keyword; and, ! 150: ! 151: \item after the \verb"END" keyword in the input file. ! 152: \end{itemize} ! 153: These actions are copied strictly verbatim, ! 154: being intended for definitions, subroutines, and the like. ! 155: ! 156: The second type of actions are {\em type\/} actions which are placed after a ! 157: type or sub-type definition, and after each element in a ``named number''. ! 158: In the former case, ! 159: please note that the action must be placed before the \verb"OPTIONAL" ! 160: and \verb"DEFAULT" lexemes. ! 161: During the copy, ! 162: the lexeme \verb"$$" is expanded to represent the object currently being ! 163: examined. The exact expansion depends upon the element being processed ! 164: and what sort of processing is being done. In decoding and printing routines, ! 165: \verb"$$" will expand to a \verb"PE" in actions before the element is ! 166: recognized and to the actual data after the processing. In the case of ! 167: encoding routines, the opposite is true. The precise ! 168: nature of the data is shown below. ! 169: \[\begin{tabular}{|l|l|} ! 170: \hline ! 171: \multicolumn{1}{|c|}{\bf Type}& ! 172: \multicolumn{1}{|c|}{\bf C declaration}\\ ! 173: \hline ! 174: \verb"BOOLEAN"& \verb"int"\\ ! 175: \verb"INTEGER"& \verb"int"\\ ! 176: \verb"BITSTRING"& \verb"PE" (a bitvector)\\ ! 177: \verb"OCTETSTRING"& \verb"char *" (length is \verb"$$_len")\\ ! 178: \verb"REAL"& \verb"double"\\ ! 179: any \verb"SEQUENCE"& \verb"PE" (a sequence)\\ ! 180: any \verb"SET"& \verb"PE" (a set)\\ ! 181: \verb*"OBJECT IDENTIFIER"& \verb"OID"\\ ! 182: \hline ! 183: \end{tabular}\] ! 184: ! 185: Consider the type definition in Figure~\ref{PEPYtype}: ! 186: \begin{itemize} ! 187: \item \verb"action1" will be executed only if the object being recognized ! 188: is a \verb"document"; ! 189: ! 190: \item \verb"action2" will be executed only if the object being recognized is ! 191: a \verb"paragraph"; ! 192: and, ! 193: ! 194: \item \verb"action3" will always be executed afterwards. ! 195: \end{itemize} ! 196: \tagrind[tp]{grind4-2}{Example of a TYPE action}{PEPYtype} ! 197: ! 198: The third type of actions are {\em tag\/} actions which are placed after ! 199: the tag for a tagged type or after the name for a named type. ! 200: Consider the type definition in Figure~\ref{PEPYtag}: ! 201: \begin{itemize} ! 202: \item \verb"action1" is executed after \verb"textUnit" has been fully ! 203: processed as a \verb"TextUnit"; ! 204: but, ! 205: ! 206: \item \verb"action2" is executed after \verb"specificLogicalDescriptor" ! 207: has been recognized, ! 208: but before it has been processed as a \verb"LogicalDescriptor". ! 209: This type has both a name (\verb"specificLogicalDescriptor") ! 210: and a tag (\verb"[5]"). ! 211: Although two actions are present, ! 212: one only action is honored, ! 213: and this action should be specified after the tag. ! 214: \end{itemize} ! 215: \tagrind[tp]{grind4-3}{Example of a TAG action}{PEPYtag} ! 216: ! 217: A tag action may also be specified for \verb*"SET {", \verb*"SEQUENCE {" ! 218: and \verb*"CHOICE {" -- even when they are not tagged. The action is ! 219: placed before the left brace, and is executed when the ! 220: \verb"SET", \verb"SEQUENCE", or \verb"CHOICE" is recognized but before any of ! 221: its members are processed. ! 222: ! 223: A tag action may additionally be specified directly after the ! 224: ``\verb"::="'' lexeme, even when not tagged. This has the same effect as ! 225: the tagged rule. This is the only way to provide a pre-action for ! 226: untagged single rules. ! 227: ! 228: Finally, ! 229: a tag action may occur after the phrase \verb*"SET OF" or \verb*"SEQUENCE OF". ! 230: This action is executed before processing each instance of the base ! 231: type of the \verb"SEQUENCE" or \verb"SET". ! 232: This is useful for allocating memory for each of the member elements. ! 233: ! 234: The final type of actions are declaration actions. ! 235: These are designed to ! 236: allow the declaration of variables specific to a generated function. ! 237: Such actions occur between the type name and the ``\verb"::="'' lexeme. ! 238: The statements placed here are appended to the declaration section of ! 239: the generated routine. Only variable definitions should be placed ! 240: here, as in: ! 241: \begin{quote}\small\begin{verbatim} ! 242: X400 %{ char cp[100]; %} ::= ! 243: SET { ! 244: X4001984 %{ strcpy(cp, "1984"); %}, ! 245: X4001988 %{ strcat(cp, " 1988"); %} OPTIONAL, ! 246: X4001992 %{ strcat(cp, " 1992"); %} OPTIONAL ! 247: } ! 248: %{ puts(cp); %} ! 249: \end{verbatim}\end{quote} ! 250: ! 251: \subsubsection {Control Statements} ! 252: When constructing routines for encoding presentation elements, ! 253: additional constructs are required at certain points to control ! 254: the choices available. The control constructs are specified between ! 255: the lexemes ! 256: \verb"<<" and \verb">>". The control itself consists of an appropriate ! 257: {\em C\/} statement which takes a different form for each of the constructs. ! 258: The affected types are listed below. ! 259: \begin{itemize} ! 260: \item \verb"CHOICE" --- to decide which of the selection to choose. ! 261: The statement consists of an expression of integer value that chooses ! 262: the {\em n\/}'th value. For example in ! 263: \begin{quote}\small\begin{verbatim} ! 264: NewDef ::= ! 265: CHOICE << 2 >> { ! 266: [0] FirstElement, ! 267: [1] SecondElement, ! 268: [2] ThirdElement ! 269: } ! 270: \end{verbatim}\end{quote} ! 271: the control \verb"<< 2 >>" would choose the second ! 272: type in a choice, which is not necessarily the element tagged with ! 273: \verb"[2]", as in this case. ! 274: The statement always precedes the opening brace of the \verb"CHOICE". ! 275: ! 276: \item \verb*"SEQUENCE OF" and \verb*"SET OF" --- to indicate the ! 277: number of elements require. This construct has the syntax of a for ! 278: loop in C. Elements are added to the \verb"SEQUENCE/SET" while the second ! 279: expression yields \verb"TRUE". The sequence ! 280: \begin{quote}\small\begin{verbatim} ! 281: SeqDef ::= ! 282: SET OF << count = 0; count < 10; count ++ >> ! 283: MatchingAccessories ! 284: \end{verbatim}\end{quote} ! 285: would produce ten elements in the set. ! 286: The statement follows the \verb"OF" and any optional actions. ! 287: ! 288: \item \verb"OPTIONAL" --- to decide whether the optional element ! 289: should be included. This statement follows the \verb"OPTIONAL" ! 290: keyword. ! 291: It is a simple boolean expression. ! 292: If the value returned is \verb"TRUE" then the element is included. ! 293: ! 294: \item \verb"DEFAULT" --- to decide whether the optional element ! 295: should be included. This statement follows the \verb"DEFAULT" ! 296: keyword/value pair. ! 297: It is a simple boolean expression. ! 298: If the value returned is \verb"TRUE" then the element is included. ! 299: ! 300: Arguably, this should be unnecessary~---~\pgm{pepy} should ! 301: look at the value immediately following \verb"DEFAULT" to decide if the ! 302: element need be encoded. ! 303: ! 304: \end{itemize} ! 305: The example in Figure~\ref{PEPYcontrol} should make this a little ! 306: clearer. ! 307: \tagrind[tp]{grind4-4}{Examples of CONTROL actions}{PEPYcontrol} ! 308: ! 309: \subsubsection {Value Passing Statements} ! 310: A number of extensions are available to assist in passing values ! 311: between the generated routines. ! 312: The generated routines pass these values between rules as ! 313: parameters to each routine. This can obviate the need for ! 314: much of the {\em C\/} code associated with each type. ! 315: ! 316: To allow values to be passed to and obtained from these parameters, ! 317: value tokens can be associated with the type definitions. These tokens ! 318: are incorporated in the lexemes \verb"[[" and \verb"]]". ! 319: The tokens come in two types. The first is a key letter followed ! 320: by a expression. The second is the same with an additional parameter ! 321: to specify the length of the first parameter. These formats are shown ! 322: below. ! 323: \begin{itemize} ! 324: \item \verb"[[b expression]]" --- a boolean. ! 325: For encoding, ! 326: this is the value that the presentation element will take. ! 327: For decoding and printing, ! 328: the value of the presentation element is assigned to this variable. ! 329: ! 330: \item \verb"[[i expression]]" --- an integer. ! 331: For encoding, ! 332: this is the value that the presentation element will take. ! 333: For decoding and printing, ! 334: the value of the presentation element is assigned to this variable. ! 335: ! 336: \item \verb"[[s expression]]" --- a string. ! 337: For encoding, ! 338: this is the value that the presentation element will take, ! 339: a null-terminated string. ! 340: For decoding and printing, ! 341: the string value of the presentation element is assigned to this variable; ! 342: the user is responsible for freeing the storage assigned with \verb"free". ! 343: ! 344: \item \verb"[[O expression]]" --- an object identifier. ! 345: For encoding, ! 346: this is the value that the presentation element will take, ! 347: an \verb"OID" value ! 348: (see Section~\ref{psap:oid} on page~\pageref{psap:oid} in \volone/). ! 349: For decoding and printing, ! 350: the \verb"OID" value of the presentation element is assigned to this ! 351: variable; ! 352: the user is responsible for freeing the storage assigned with \verb"oid_free". ! 353: ! 354: \item \verb"[[p expression]]" --- a user supplied parameter, \verb"parm". ! 355: This parameter is of type \verb"PEPYPARM", which can be \verb"#define"'d by the ! 356: user to a suitable value. If not defined, it defaults to a \verb*"char *". ! 357: Most commonly this type is defined to be a union of all parameter ! 358: types that need to be passed (but see the next item). ! 359: ! 360: \item \verb"[[P type]]" --- a {\em C} type which defines the type of ! 361: the parameter for this definition. If present, this construct must ! 362: occur directly after the definition name. ! 363: ! 364: \item \verb"[[o expression1 $ expression2]]" --- a byte pointer/length pair. ! 365: For encoding, ! 366: these indicate the byte value and length of the presentation element, ! 367: which needn't be null-terminated. ! 368: For decoding and printing, ! 369: the byte value and length are assigned to these variables; ! 370: the user is responsible for freeing the storage assigned with \verb"free". ! 371: ! 372: \item \verb"[[q expression]]" --- a \verb"qbuf". ! 373: For encoding, ! 374: this is a pointer to a \verb"qbuf" ! 375: (described in Section~\ref{psap:qbuf} in \volone/) which is used to build the ! 376: presentation element. ! 377: If the \verb"qbuf" contains only one element in the linked list, ! 378: then a primitive element is built, ! 379: otherwise a constructed type is built. ! 380: which needn't be null-terminated. ! 381: For decoding and printing, ! 382: this value is undefined. ! 383: ! 384: \item \verb"[[x expression1 $ expression2]]" --- a bit pointer/length pair. ! 385: For encoding, ! 386: the value of the presentation element is derived by supplying ! 387: \verb"expression1" and \verb"expression2" ! 388: as the first two arguments to \verb"strb2bitstr" ! 389: (described in Section~\ref{psap:bits} in \volone/). ! 390: For decoding and printing, ! 391: the bitstring value and length are assigned to these variables; ! 392: the user is responsible for freeing the storage assigned with \verb"free". ! 393: ! 394: \item \verb"[[a expression]]" --- a presentation element. ! 395: For encoding, ! 396: this is the value that the presentation element will take. ! 397: For decoding and printing, ! 398: the presentation element is assigned to this variable. ! 399: ! 400: \item \verb"[[r expression]]" --- a real number. For encoding this ! 401: is a floating point number that will be encoded. For decoding this ! 402: represents a floating point number variable in double format. ! 403: \end{itemize} ! 404: ! 405: The example in Figure~\ref{PEPYparm} should demonstrate these features. ! 406: \clearpage ! 407: \tagrind[tp]{grind4-5a}{Examples of Parameters in Pepy}{PEPYparm} ! 408: \clearpage ! 409: \tagrind[tp]{grind4-5b}{Examples of Parameters in Pepy (continued)}\empty ! 410: ! 411: \section {Known Deficiencies} ! 412: The \pgm{pepy} program started as a prototype. ! 413: Although the approach is promising, some of the rough edges remain. ! 414: ! 415: \subsection {ASN.1 Syntax}\label{pepy:syntax} ! 416: The ASN.1 syntax is followed exactly except that: ! 417: \begin{itemize} ! 418: \item No {\em macro\/} syntax is recognized. ! 419: \end{itemize} ! 420: ! 421: \subsection {ASN.1 Semantics} ! 422: \verb"COMPONENTS OF" and \verb"CHOICE" types are often ``pulled up'' into the ! 423: type which references them. ! 424: This can cause anomalous behavior when things like value passing statements ! 425: (e.g., \verb"[[p expr]]") ! 426: are present in the definition of a \verb"COMPONENTS OF" or \verb"CHOICE" type ! 427: which is pulled into another type definition. ! 428: ! 429: \section {PEPY Environment} ! 430: A program generated by \pgm{pepy} expects certain things. ! 431: ! 432: \subsection {Starting Things Off} ! 433: To invoke a decoding or printing routine: ! 434: \begin{quote}\small\begin{verbatim} ! 435: PREFIX_MODULE_TYPE (pe, 1, len, buffer, parm) ! 436: \end{verbatim}\end{quote} ! 437: where -- ! 438: \begin{describe} ! 439: \item[\verb"PREFIX\_MODULE\_TYPE":] indicates that the type ! 440: \verb"TYPE" in module ! 441: \verb"MODULE" should be parsed -- the prefix \verb"PREFIX" is supplied from ! 442: the \verb"DECODER" or \verb"PRINTER" directive ! 443: (or the corresponding prefix in the \verb"SECTIONS" directive). ! 444: ! 445: \item[\verb"pe":] is the presentation-element that is to be examined. ! 446: ! 447: \item[\verb"1":] is a magic argument. ! 448: ! 449: \item[\verb"len":] is the integer parameter supplied for routines that ! 450: decode values into integer parameters, or have a length associated ! 451: with them. The address of an integer can be placed here if the element ! 452: being parsed is a primitive type, otherwise use \verb"NULLIP". ! 453: ! 454: \item[\verb"buffer":] is the string parameter for routines that decode ! 455: values into string objects. The address of a character pointer can be placed ! 456: here if the element being parsed is a primitive type, otherwise use ! 457: \verb"NULLVP". ! 458: ! 459: \item[\verb"parm":] is the user supplied parameter. This should be a variable ! 460: of type \verb"PEPYPARM" if supplied, ! 461: otherwise use \verb"NULLCP". ! 462: \end{describe} ! 463: ! 464: To invoke an encoding routine, the call is similar: ! 465: \begin{quote}\small\begin{verbatim} ! 466: PREFIX_MODULE_TYPE (&pe, 1, len, buffer, parm) ! 467: \end{verbatim}\end{quote} ! 468: the values are the same as above, except that the first parameter ! 469: is a reference higher and the third and fourth parameters are a reference ! 470: lower, ! 471: hence -- ! 472: \begin{describe} ! 473: \item[\verb"PREFIX\_MODULE\_TYPE":] indicates that the type ! 474: \verb"TYPE" in module ! 475: \verb"MODULE" should be parsed -- the prefix \verb"PREFIX" is supplied from ! 476: the \verb"ENCODER" directive ! 477: (or the corresponding prefix in the \verb"SECTIONS" directive). ! 478: ! 479: \item[\verb"pe":] is a pointer to the presentation-element that is to be ! 480: constructed. ! 481: ! 482: \item[\verb"1":] is a magic argument. ! 483: ! 484: \item[\verb"len":] is the integer parameter supplied for routines that ! 485: encode booleans or integers, or have a length associated with them. ! 486: If not present, use \verb"NULL". ! 487: ! 488: \item[\verb"buffer":] is the string parameter for routines that encode ! 489: string values. ! 490: If not present, use \verb"NULLCP". ! 491: ! 492: \item[\verb"parm":] is the user supplied parameter. This should be a variable ! 493: of type \verb"PEPYPARM" if supplied, ! 494: otherwise use \verb"NULLCP". ! 495: \end{describe} ! 496: ! 497: These routines return the manifest constant \verb"NOTOK" on error, ! 498: or \verb"OK" on success. ! 499: ! 500: \subsection {Diagnostic Output}\label{pepy:advise} ! 501: When the program generated by \pgm{pepy} detects an error, ! 502: it calls the routine \verb"advise" with some diagnostic information. ! 503: This routine, which should be declared \verb"void" is defined by the user. ! 504: The routine takes a variable number of arguments, ! 505: similar to a \man printf(3s) routine, ! 506: with the exception that the first argument is a string for \man perror(3), ! 507: the second argument is the format string, ! 508: and any following arguments are referenced by the format string. ! 509: Consult Figure~\ref{PPdone} on page~\pageref{PPdone} for an example of the ! 510: \verb"advise" procedure. ! 511: ! 512: Alternately, ! 513: the standard routine, \verb"PY_advise"\index{PY\_advise} can be used. ! 514: It simply records the information to: ! 515: \begin{quote}\index{PY\_pepy}\small\begin{verbatim} ! 516: char PY_pepy[BUFSIZ]; ! 517: \end{verbatim}\end{quote} ! 518: for easy access. ! 519: Note that the routines in the \man libpepy(3) library are generated to use ! 520: the \verb"PY_advise" routine. This routine is also encouraged for use ! 521: when building \pgm{rosy} encoder/decoder routines. ! 522: ! 523: \subsection {Debug Output} ! 524: If a program generated by \pgm{pepy} is compiled with the \verb"-DEBUG" option, ! 525: then prior to fiddling with each instance of a type, ! 526: the routine \verb"testdebug" is called. ! 527: \begin{quote}\index{testdebug}\small\begin{verbatim} ! 528: int testdebug (pe, s) ! 529: PE pe; ! 530: char *s; ! 531: \end{verbatim}\end{quote} ! 532: The parameters to this procedure are: ! 533: \begin{itemize} ! 534: \item the presentation element being examined; and, ! 535: ! 536: \item a short null-terminated diagnostic string describing the instance ! 537: of the type. ! 538: \end{itemize} ! 539: ! 540: By convention, ! 541: if the program was compiled with \verb"-DDEBUG", ! 542: then the \verb"testdebug" routine (supplied by the user) ! 543: should examine the \verb"$PEPYDEBUG" environment variable. ! 544: If this variable is set to a non-zero decimal number, ! 545: then it should print out debugging information. ! 546: Consult Figure~\ref{PPdone} on page~\pageref{PPdone} for an example of the ! 547: \verb"testdebug" procedure. ! 548: ! 549: In addition, ! 550: the static character pointer \verb"pepyid" contains ! 551: information on the version of \pgm{pepy} which generated the program. ! 552: ! 553: \section {Pretty-printers}\label{pepy:pretty} ! 554: To facilitate the automatic generation of pretty-printers, ! 555: the routine \verb"PY_pp" is included in the \man libpepy(3) library. ! 556: Given an invocation from a simple main routine, ! 557: \verb"PY_pp" will parse invocation arguments, ! 558: build presentation elements ! 559: (from either a presentation stream or presentation list), ! 560: and then invoke the pretty-printer routine for each presentation element. ! 561: By simply invoking pepy with the \switch"S PRINT" option. ! 562: the pretty-printer routine can be generated automatically. ! 563: Figure~\ref{PP2init} shows the required initialization code for the ! 564: pretty-printer. ! 565: \tagrind[tp]{grind4-10}{Simpler Pretty-Printer initialization}{PP2init} ! 566: ! 567: \section {Compiling and Loading} ! 568: Programs generated by \pgm{pepy} automatically include ! 569: \verb"<isode/psap.h>". ! 570: Typically, ! 571: these programs should also be loaded with \verb"-lisode", ! 572: although only the libraries \verb"-lpepy", ! 573: \verb"-lpsap", and \verb"-licompat" are referenced. ! 574: ! 575: \subsection {External Modules} ! 576: When an external module, \verb"MODULE", is referenced, ! 577: \pgm{pepy} reads a file which is named \verb"MODULE.ph" for various ! 578: information. ! 579: The \pgm{pepy} program will consult the environment variable \verb"$PEPYPATH" ! 580: as a search-list of directories to search to find this file. ! 581: The components in the path are separated by a colon (`\verb":"'). ! 582: If this environment variable is not set, ! 583: then \pgm{pepy} consults the user's current directory followed by a ! 584: system-wide area defined at compile-time. ! 585: ! 586: Similarly, ! 587: in addition to producing a \verb".c" file, ! 588: \pgm{pepy} will also generate a \verb".ph" file containing information ! 589: describing the module. ! 590: ! 591: \subsection {Options} ! 592: The \pgm{pepy} program has many options to modify its behavior: ! 593: ! 594: The \switch"a" switch sets the name of the routine used by the \verb"advise" ! 595: facility (see page~\pageref{pepy:advise}). ! 596: ! 597: The \switch"d" switch directs \pgm{pepy} to ignore any action statements in ! 598: the input. ! 599: ! 600: The \switch"h" switch enables additional heuristics when \pgm{pepy} generates ! 601: a printer. ! 602: ! 603: The \switch"o" switch sets the name of the output file, ! 604: which is normally derived from the name of the input file. ! 605: The distinguished file ``\verb"-"'' can be used to force the use of the ! 606: standard output. ! 607: ! 608: If the \switch"o" switch is not used, ! 609: then \verb*"-b prefix" can be used to direct \pgm{pepy} to produce multiple ! 610: output files, each starting with \verb"prefix". ! 611: ! 612: The \switch"P" switch directs \pgm{pepy} not to include \pgm{cpp}-type line ! 613: number information in the output. ! 614: This is useful for debugging \pgm{pepy} (gasp!). ! 615: ! 616: The \switch"p" switch directs \pgm{pepy} to remove the action states from the ! 617: input file and print the resulting information on the standard output. ! 618: This typically results in a file suitable for pretty-printing. ! 619: ! 620: The \switch"r" switch enables the generation of ``robust'' code. ! 621: If this option is given, ! 622: then the {\em C\/} code generated will not check for unknown or extraneous ! 623: objects. ! 624: This is used for extensibility purposes. ! 625: ! 626: Normally, \pgm{pepy} prints the name of each type as it works. ! 627: The \switch"s" switch disables this behavior. ! 628: ! 629: Finally, ! 630: the \switch"S" switch sets the initial section-processing mode for \pgm{pepy}. ! 631: The default is \verb*"-S DECODE", ! 632: which causes \pgm{pepy} to generate a decoder. ! 633: Other values are \verb*"-S ENCODE" to generate an encoder; ! 634: or, ! 635: \verb*"-S PRINT" to generate a printer. ! 636: The \switch"A" switch is used to set the initial mode to generate encoder, ! 637: decoder, and printer routines. ! 638: ! 639: \subsection {Makefiles} ! 640: By convention, ! 641: input files to \pgm{pepy} have the extension \verb".py". ! 642: The rules for \man make(1) are: ! 643: \begin{quote}\small\begin{verbatim} ! 644: .SUFFIXES: .py .c .o ! 645: ! 646: .py.o:; pepy $(PYFLAGS) $< ! 647: $(CC) $(CFLAGS) -c $*.c ! 648: -rm -f $*.c ! 649: ! 650: .py.c:; pepy $(PYFLAGS) $< ! 651: \end{verbatim}\end{quote} ! 652: ! 653: \subsection {Grinding} ! 654: Figure~\ref{PepyGrind} contains an entry for the \man vgrindefs(5) file, ! 655: which may be used by the \man vgrind(1) or \man tgrind(1) facility. ! 656: While this entry is not perfect, ! 657: it has proven to be adequate for most purposes; ! 658: e.g., ! 659: the examples in this chapter were pretty-printed using this entry. ! 660: \tagdiagram[tp]{4-1}{Grind Entry for pretty-printing PEPY programs}{PepyGrind} ! 661: ! 662: In addition, ! 663: if you want to get an ASN.1 specification ! 664: by removing all of the {\em C\/} augmentations from the \pgm{pepy} input file, ! 665: use the \switch"p" switch. ! 666: For example, ! 667: \begin{quote}\small\begin{verbatim} ! 668: pepy -p < myfile.py ! 669: \end{verbatim}\end{quote} ! 670: can be used to view the ASN.1 specification in the file \verb"myfile.py". ! 671: ! 672: \section {An Example} ! 673: Let's consider how one might construct a pretty-printer for the personnel ! 674: records described in Figure~\ref{ASNexample} on page~\pageref{ASNexample}. ! 675: (Of course, earlier in Section~\ref{pepy:pretty} the preferred method of ! 676: generating pretty-printers was described.) ! 677: ! 678: First, ! 679: we start the module off by defining the usual prefactory {\em C\/} code ! 680: as verbatim actions. ! 681: This is shown in Figure~\ref{PPinit}. ! 682: Next, ! 683: we define the \verb"PersonnelRecord" types. ! 684: The rest of the types are then defined. ! 685: This is shown in Figures~\ref{PPtop} and~\ref{PPbottom} respectively. ! 686: Finally, ! 687: the usual closing {\em C\/} code is included as verbatim actions, ! 688: as shown in Figure~\ref{PPdone}. ! 689: ! 690: \clearpage ! 691: \tagrind[tp]{grind4-6a}{Pretty-Printer initialization}{PPinit} ! 692: \clearpage ! 693: \tagrind[tp]{grind4-6b}{Pretty-Printer initialization (continued)}\empty ! 694: {\let\small=\smaller ! 695: \clearpage ! 696: \tagrind[tp]{grind4-7}{Pretty-Printer top-level}{PPtop}} ! 697: \clearpage ! 698: \tagrind[tp]{grind4-8a}{Pretty-Printer type definitions}{PPbottom} ! 699: \clearpage ! 700: \tagrind[tp]{grind4-8b}{Pretty-Printer type definitions (continued)}\empty ! 701: \clearpage ! 702: \tagrind[tp]{grind4-9a}{Pretty-Printer finalization}{PPdone} ! 703: \clearpage ! 704: \tagrind[tp]{grind4-9b}{Pretty-Printer finalization (continued)}\empty ! 705: \clearpage ! 706: ! 707: \section {For Further Reading}\label{pepy:reading} ! 708: The Abstract Syntax Notation One is specified in \cite{ISO.PP.Syntax}. ! 709: The corresponding CCITT recommendation is defined in \cite{CCITT.PP.Syntax}. ! 710: ! 711: %%% \section {Changes Since the Last Release}\label{pepy:changes} ! 712: %%% A brief summary of the major changes between v~\pepyprevrsn/ and ! 713: %%% v~\pepyvrsn/ are now presented. ! 714: %%% These are the user-visible changes only; ! 715: %%% changes of a strictly internal nature are not discussed. ! 716:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.