!4R4      !"#$%&'()*+,-./0123 2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllSafe 4cpphsMacro expansion text is divided into sections, each of which is classified as one of three kinds: a formal argument (Arg), plain text (Text), or a stringised formal argument (Str).5cpphssmart: constructor to avoid warnings from ghc (undefined fields)6cpphsNExpand an instance of a macro. Precondition: got a match on the macro name.7cpphs7Parse a #define, or #undef, ignoring other # directives8cpphsBPretty-print hash defines to a simpler format, as key-value pairs.49:;<=>?@ABCDEF6782006 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllSafeGcpphsoRaw command-line options. This is an internal intermediate data structure, used during option parsing only.cpphs"Options representable as Booleans.cpphs,Leave #define and #undef in output of ifdef?cpphs Place #line droppings in output?cpphsWrite #line or {-# LINE #-} ?cpphsKeep #pragma in final output?cpphs&Remove C eol (//) comments everywhere?cpphs+Remove C inline (/**/) comments everywhere?cpphsLex input as Haskell code? cpphs-Permit stringise # and catenate ## operators? cpphs$Retain newlines in macro expansions? cpphsRemove literate markup? cpphsIssue warnings? cpphsCpphs options structure.cpphs&Files to #include before anything elsecpphsDefault options.cpphs$Default settings of boolean options.HcpphsYParse a single raw command-line option. Parse failure is indicated by result Nothing.IcpphsTrim trailing elements of the second list that match any from the first list. Typically used to remove trailing forward/back slashes from a directory path.Jcpphs7Convert a list of RawOption to a BoolOptions structure.cpphsParse all command-line options.  I2000-2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllSafe/cpphsSource positions contain a filename, line, column, and an inclusion point, which is itself another source position, recursively.cpphs#Constructor. Argument is filename.cpphs*Increment column number by given quantity.cpphs(Increment row number, reset column to 1.cpphs5Increment column number, tab stops are every 8 chars.cpphs'Increment row number by given quantity.cpphs6Update position with a new row, and possible filename. cpphsProject the line number.!cpphsProject the filename."cpphs&Project the directory of the filename.#cpphs#cpp-style printing of file position$cpphs'haskell-style printing of file position%cpphs<Conversion from a cpp-style "#line" to haskell-style pragma.Kcpphs_Strip non-directory suffix from file name (analogous to the shell command of the same name).&cpphsdSigh. Mixing Windows filepaths with unix is bad. Make sure there is a canonical path separator. !"#$%&2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllSafe7LcpphsAttempt to read the given file from any location within the search path. The first location found is returned, together with the file content. (The directory of the calling file is always searched first, then the current directory, finally any specified search path.)Lcpphsfilenamecpphsinclusion pointcpphs search pathcpphsreport warnings?cpphs&discovered filepath, and file contentsLMN2000-2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk>StableAllSafe;Ocpphs'Index Trees (storing indexes at nodes).PcpphsQSymbol Table. Stored values are polymorphic, but the keys are always strings.OPQRSTUV2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllSafeS4'cpphsEach token is classified as one of Ident, Other, or Cmd: * Ident is a word that could potentially match a macro name. * Cmd is a complete cpp directive (#define etc). * Other is anything else.WcpphsNSubmodes are required to deal correctly with nesting of lexical structures.XcpphsA Mode value describes whether to tokenise a la Haskell, or a la Cpp. The main difference is that in Cpp mode we should recognise line continuation characters.YcpphslinesCpp is, broadly speaking, Prelude.lines, except that on a line beginning with a #, line continuation characters are recognised. In a line continuation, the newline character is preserved, but the backslash is not.Zcpphs*Put back the line-continuation characters.+cpphs1tokenise is, broadly-speaking, Prelude.words, except that: * the input is already divided into lines * each word-like "token" is categorised as one of {Ident,Other,Cmd} * #define's are parsed and returned out-of-band using the Cmd variant * All whitespace is preserved intact as tokens. * C-comments are converted to white-space (depending on first param) * Parens and commas are tokens in their own right. * Any cpp line continuations are respected. No errors can be raised. The inverse of tokenise is (concatMap deWordStyle).[cpphsHParse a possible macro call, returning argument list and remaining input '()*YZ\+[ 2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllNonem0,cpphsKWalk through the document, replacing calls of macros with the expanded RHS.]cpphs auxiliary-cpphsWalk through the document, replacing calls of macros with the expanded RHS. Additionally returns the active symbol table after processing.^cpphs$Turn command-line definitions (from -D) into <s._cpphs5Turn a string representing a macro definition into a <.`cpphsfTrundle through the document, one word at a time, using the WordStyle classification introduced by + to decide whether to expand a word or macro. Encountering a #define or #undef causes that symbol to be overwritten in the symbol table. Any other remaining cpp directives are discarded and replaced with blanks, except for #line markers. All valid identifiers are checked for the presence of a definition of that name in the symbol table, and if so, expanded appropriately. (Bool arguments are: keep pragmas? retain layout? haskell language?) The result lazily intersperses output text with symbol tables. Lines are emitted as they are encountered. A symbol table is emitted after each change to the defined symbols, and always at the end of processing.acpphsUseful helper function.bcpphsUseful helper function.,cpphs$Pre-defined symbols and their valuescpphs#Options that alter processing stylecpphsThe input file contentcpphsThe file after processing-cpphs$Pre-defined symbols and their valuescpphs#Options that alter processing stylecpphsThe input file contentcpphs*The file and symbol table after processing,-^_ 1999-2004 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllNoneQ ccpphsBInternal state for whether lines are being kept or dropped. In  Drop n b ps, n is the depth of nesting, bP is whether we have already succeeded in keeping some lines in a chain of elif's, and ps# is the stack of positions of open #ifF contexts, used for error messages in case EOF is reached too soon..cpphsRun a first pass of cpp, evaluating #ifdef's and processing #include's, whilst taking account of #define's and #undef's as we encounter them.dcpphsEReturn just the list of lines that the real cpp would decide to keep.ecpphsAuxiliary IO functionsfcpphs[The preprocessor must expand all macros (recursively) before evaluating the conditional.gcpphsExpansion of symbols.hcpphs5Return the expansion of the symbol (if there is one).icpphsHThe standard "parens" parser does not work for us here. Define our own.jcpphsDetermine filename in #include.cpphsFile for error reportscpphs$Pre-defined symbols and their valuescpphsSearch path for #includescpphs Options controlling output stylecpphsThe input file contentcpphs$The file after processing (in lines).Safe/cpphs/ takes a filename (for error reports), and transforms the given string, to eliminate the literate comments from the program text.// None01232000-2006 Malcolm WallaceLGPL/Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> experimentalAllNone3   !"#$%&'()*+,-.012330123.+'()*,-   #$%! "&k    !"#$%&'()*+,-./012345 6 7 89 : ; < =>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdef g h i j k l m n o p q r s tu#cpphs-1.20.9-5Kx03xQF9uUHrepM8nnTCGLanguage.Preprocessor.CpphsLanguage.Preprocessor.Unlit&Language.Preprocessor.Cpphs.HashDefine#Language.Preprocessor.Cpphs.Options$Language.Preprocessor.Cpphs.Position%Language.Preprocessor.Cpphs.ReadFirst"Language.Preprocessor.Cpphs.SymTab$Language.Preprocessor.Cpphs.Tokenise%Language.Preprocessor.Cpphs.MacroPass$Language.Preprocessor.Cpphs.CppIfdef$Language.Preprocessor.Cpphs.RunCpphs BoolOptionsmacros locationshashlinepragmastripEolstripC89langansilayoutliteratewarnings CpphsOptionsinfilesoutfilesdefinesincludes preIncludebooloptsdefaultCpphsOptionsdefaultBoolOptions parseOptionsPosnPnnewfileaddcolnewlinetabnewlinesnewposlinenofilename directorycpplinehasklinecpp2hask cleanPath WordStyleIdentOtherCmdtokenise macroPassmacroPassReturningSymTabcppIfdefunlitrunCpphs runCpphsPass1 runCpphsPass2runCpphsReturningSymTab ArgOrTextsymbolReplacement expandMacroparseHashDefinesimplifyHashDefinesTextArgStr HashDefineLineDropPragma AntiDefinedSymbolReplacementMacroExpansionname linebreaks replacement arguments expansion RawOption rawOptiontrailingboolOptsdirname readFirst readFileUTF8 writeFileUTF8IndTreeSymTabemptySTinsertSTdeleteSTlookupST definedST flattenSTSubModeModelinesCppreslashparseMacroCall deWordStyle onlyRights preDefine defineMacro macroProcessemit emitSymTab KeepStatecppemitOne preExpandexpandSymOrCallparseSymOrCall parenthesisfile