home *** CD-ROM | disk | FTP | other *** search
- #ifndef __FORMATTING__
- #define __FORMATTING__ 1
-
- #ifndef __CSCANNER__
- #include "CScanner.h"
- #endif
-
- #ifndef __DATAAREA__
- #include "DataArea.h"
- #endif
-
- #ifndef __FORMATSTRINGS__
- #include "FormatStrings.h"
- #endif
-
- #ifndef __DFILE__
- #include "DFile.h"
- #endif
-
- #ifndef __NEW__
- #include <new.h>
- #endif
-
- #ifndef __STRING__
- #include <string.h>
- #endif
-
-
- /*
- ** Formatting:
- ** Controls the formatting and output of a text item
- */
-
-
- #pragma segment Formatting
-
-
- /*
- ** Enum defining various formatting registers
- */
- enum {
- kRegIndentDelta = 0, //
- kRegWidth, //
- kRegIndent, //
- kRegCurrentColumn, //
- kRegTempIndent, //
- kNRegisters = 10
- };
-
-
- /*µ struct FContext
- ** Define the structure of a context
- */
- struct FContext {
- short fReg[kNRegisters]; // Registers used during formatting
- short fDeclWidth; // Minimum width of a declaration
- short fWhatToSqueeze; // What squeezing is being done
- Boolean fDeclLeft; // True if "*" and "&" associate left
- Boolean fIsGroup; // True if this context begins a group
- FormatString fComma;
- FormatString fSemi;
- FormatString fLCurly;
- FormatString fRCurly;
- FormatString fLParen;
- FormatString fRParen;
- FormatString fName;
- FormatString fOperator;
- FormatString fAssign;
- };
-
-
- /*
- ** Pointers to classes
- */
- class Syntactic;
- class FormatLog;
-
-
- //µ class Formatting
- class Formatting : public SingleObject {
- public:
- short IFormatting();
- short IFormatting(const Formatting *aFormat);
-
- static void SetOutput(DFile *anOutput);
- // Set the output file to write to. Shared by all instances
-
- void SetFormatLog(FormatLog *aFormatLog);
- // Set the FormatLog that records all commands. Shared by all instances
-
-
- static void DebugFormatting(Boolean aFlag);
-
- short &CurrentColumn();
-
- short GetIndent() const;
- void SetIndent(short anIndent);
- void AddIndent(short aDelta);
- void IncrIndent();
-
- static void CommentColumn(short aColumn);
- static short CommentColumn();
-
- static void TabSize(short n);
- static short TabSize();
-
- static void LineLength(short aColumn);
- static short LineLength();
-
- static void ReformatComments(Boolean aFlag);
- static Boolean ReformatComments();
-
- static void PassSourceNewLines(Boolean aFlag);
- static Boolean PassSourceNewLines();
-
- static void PassConsecutiveNewLines(Boolean aFlag);
- static Boolean PassConsecutiveNewLines();
-
-
- /*
- ** High level output operations. The parser calls these routines to
- ** set desired behavior or to inquire about what should be done with
- ** a particular character.
- */
- void SetGlue(FormatString aGlue);
- void ExecuteGlue(FormatString aGlue);
- void Display(Syntactic *aToken);
-
- Boolean DeclLeft() const;
-
- void DeclPadStart(int nOperators);
- void DeclPadEnd();
- /*
- ** These two methods are called around the "*" in an "int *foo"
- ** declaration. nOperators is the number of "*"/"&" operators
- ** in the declaration. DeclPadStart is called prior to Display()ing
- ** each operator, DeclPadEnd is called afterwards. The function
- ** is to associate the operators with either the type or object,
- ** as defined by fContext.fDeclLeft, and to pad the declaration to
- ** the proper length, as defined by fContext.fDeclWidth
- */
-
- void DeclWidth(Boolean goLeft, int aWidth);
- /*
- ** Set the width of the type part of a declaration. goLeft is
- ** true if "*" and "&" associate with the type, false if they
- ** associate with the object being declared. aWidth is the
- ** width of the declaration. If 0, then the width is accumulated
- ** across declarations
- */
-
-
- /*
- ** Language specific formatting routines. These routines are invoked
- ** by the parser. Specify the glue to use when Display() is called.
- */
- void Comma();
- void Semi();
- void LCurly();
- void RCurly();
- void LParen();
- void RParen();
- void Name();
- void Operator();
- void Assign();
-
-
- /*
- ** Low level output operations. Strings and characters which are output
- ** should not contain tabs unless SetCurrentColumn is called afterwards
- ** to fix up the column position. Furthermore, these operations should
- ** not be called except by token display routines as their actions are
- ** not recorded for playback when line lengths overflow.
- */
- void Print(const char *aString);
- void Puts(const char *aString);
- void Putc(int aChar);
- void NewLine();
- void Write(const void *aString, size_t n);
- void Flush();
-
- void Comment(const char *start, const char *end);
- /*
- ** Output the comment in the proper format
- */
-
-
- void OpenContext(Boolean isGroup = false);
- void CloseContext();
- void RestoreIndent();
- /*
- ** Create and restore contexts, areas where particular formats are
- ** in effect along with different settings for the permanent and
- ** temporary indents. RestoreIndent restores the settings for the
- ** permanent and temporary indents. For now, do nothing
- */
-
- void SetRegister(int aRegister, const unsigned char *&aFormat);
- void SetRegister(int dstReg, int aValue);
- int GetRegister(int srcReg) const;
- // Set and fetch context registers. The first form of SetRegister
- // evaluates the formatting string to yield the expression.
-
-
- void SetComma(FormatString aString);
- void SetSemi(FormatString aString);
- void SetLCurly(FormatString aString);
- void SetRCurly(FormatString aString);
- void SetLParen(FormatString aString);
- void SetRParen(FormatString aString);
- void SetName(FormatString aString);
- void SetOperator(FormatString aString);
- void SetAssign(FormatString aString);
- // Set the format strings for the current context
-
- private:
- static Boolean NewLineWanted();
- static Boolean SpaceWanted();
- static Boolean NewLineNeeded();
- static Boolean SpaceNeeded();
- static void WantNewLine(short n = 1);
- static void WantSpace(short n = 1);
- static void NeedNewLine(short n = 1);
- static void NeedSpace(short n = 1);
- // Sometimes the parser needs newlines and whitespace to appear before
- // or after tokens are displayed. These methods control the desire.
- // These methods are called prior to any new displays. The distinction
- // between 'want' and 'need' is that 'want'ed items are optional; they
- // can be removed to squeeze more items on the line. 'Need'ed items
- // are never removed.
-
- void FreshLine();
- /*
- ** Make sure the cursor is at the beginning of a line, emit a newline
- ** if not so.
- */
-
- void IndentTo(short aColumn);
- void IndentTo();
-
- void IndentLine(short aColumn);
- void IndentLine();
- /*
- ** IndentTo postcondition is CurrentColumn() >= aColumn.
- ** IndentLine does a FreshLine()/IndentTo(aColumn)
- */
-
-
- static Boolean IsBOL();
- static void AtBOL();
- // Indicate that if a new line is required, it can be put here.
- // Return true if we are the beginning of the line.
- // Set the beginning of line state, require beginning of line
- // Assure that we are at the beginning of the line, IsBOL() will
- // return true after RequireBOL() is called.
-
-
- void CheckWanted();
- /*
- ** Called by internal routines to check that whitespace will be
- ** emitted prior to emitting other data
- */
-
- void SetSqueeze(short whatToSqueeze);
- /*
- ** Set the squeeze option. When re-doing formats, the squeeze option
- ** is copied to all saved items on the stack.
- */
-
- short WhatToSqueeze() const;
- void SetWhatToSqueeze(short what);
- // Return what is currently being squeezed.
-
- void UseSourceNewLine();
- /*
- ** This method is called when the output line would be too long. It
- ** is inserted into gFormatLog when an unused source newline is
- ** encountered. During gFormatLog->Redo(), if WhatToSqueeze says
- ** to use source new lines, the newline will be emitted into the
- ** output.
- */
-
- void LogicalSpace();
- void LogicalNewLine();
- // These methods maintain desires by updating them from reality. When
- // a space (or equivalent) has been emitted, we no longer want a space
- // and the last character emitted was a space. When a newline is
- // emitted, we no longer desire one. Also, we indicate that a space
- // has also been emitted.
-
- void _Putc(int aChar);
- void _Write(const void *aString, size_t n);
-
- FormatString Interpret(FormatString aFormat);
- int GetExpr(FormatString &aFormat, int defaultValue = 1);
- /*
- ** Special interpreter of format strings
- */
-
- static Boolean IsIdentifierType(short aType);
- static Boolean IsOperatorType(short aType);
- /*
- ** Methods returning true if the types should be treated as ids or ops
- ** for the purposes of formatting
- */
-
- private:
- // Variables common to all instances of Formatting
- static DFile *gOutput; // The output stream
- static FormatLog *gFormatLog; // Where we remember our commands
-
-
- private:
- // Formatting parameters set by command line
- static short gTabSize; // The tab sizes to apply
- static short gCommentColumn; // The end-of-line comment level
- static short gLineLength; // The length of an output line
- static Boolean gDebug; // Flag to control debug displays
-
- static Boolean gReformatComments; // True if comments can be word wrapped
- static Boolean gPassSourceNewLines; // True if source newlines are emitted
- static Boolean gPassConsecutiveNewLines; // True if two or more newlines get through
-
-
- private:
- // Values for Checkpoint() and Rollback() to worry about. These values
- // are copied to local
- struct RollbackVars {
- short fLastTokenType; // Type of last displayed token
-
- short fIndent; // The indent for the next line
- short fCurDeclStart; // Start column of the current declaration
-
- short fWantNewLine; // # of new lines wanted
- short fWantSpace; // # of spaces wanted
- short fNeedNewLine; // # of new lines needed
- short fNeedSpace; // # of spaces needed
-
- FormatString fFormatString; // String currently being interpreted.
- FormatString fGlueString; // The current glue
- };
-
-
- static struct RollbackVars gV; // The Values used by Formatting
- static struct RollbackVars gC; // The Checkpointed values
-
- static Boolean gFromSource; // True if data coming from source
- static size_t gOutputOffset; // Offset of line start in gOutput
-
- static short gSourceNewLines; // # of source newlines not yet emitted
- static Boolean gLastNewLineFromSource; // True if the last new line was from the source
-
-
- private:
- FContext fContext; // The current context
- DataArea fSavedContexts; // Saved context items
- };
-
-
- //µ Formatting::SetOutput
- #pragma segment Formatting
- inline void Formatting::SetOutput(DFile *anOutput)
- {
- gOutput = anOutput;
- }
-
-
- //µ Formatting::DebugFormatting
- #pragma segment Formatting
- inline void Formatting::DebugFormatting(Boolean aFlag)
- {
- gDebug = aFlag;
- }
-
-
- //µ Formatting::SetRegister
- #pragma segment Formatting
- inline void Formatting::SetRegister(int dstReg, int aValue)
- {
- fContext.fReg[dstReg] = aValue;
- }
-
-
- //µ Formatting::GetRegister
- #pragma segment Formatting
- inline int Formatting::GetRegister(int srcReg) const
- {
- return (fContext.fReg[srcReg]);
- }
-
-
- //µ Formatting::CurrentColumn
- #pragma segment Formatting
- inline short &Formatting::CurrentColumn()
- {
- return (fContext.fReg[kRegCurrentColumn]);
- }
-
-
- //µ Formatting::GetIndent
- #pragma segment Formatting
- inline short Formatting::GetIndent() const
- {
- return (GetRegister(kRegIndent));
- }
-
-
- //µ Formatting::SetIndent
- #pragma segment Formatting
- inline void Formatting::SetIndent(short anIndent)
- {
- SetRegister(kRegIndent, anIndent);
- }
-
-
- //µ Formatting::AddIndent
- #pragma segment Formatting
- inline void Formatting::AddIndent(short aDelta)
- {
- SetIndent(GetIndent() + aDelta);
- }
-
-
- //µ Formatting::IncrIndent
- #pragma segment Formatting
- inline void Formatting::IncrIndent()
- {
- AddIndent(GetRegister(kRegIndentDelta));
- }
-
-
- //µ Formatting::CommentColumn
- #pragma segment Formatting
- inline void Formatting::CommentColumn(short aColumn)
- {
- gCommentColumn = aColumn;
- }
-
-
- //µ Formatting::CommentColumn
- #pragma segment Formatting
- inline short Formatting::CommentColumn()
- {
- return (gCommentColumn);
- }
-
-
- //µ Formatting::TabSize
- #pragma segment Formatting
- inline void Formatting::TabSize(short n)
- {
- gTabSize = n;
- }
-
-
- //µ Formatting::TabSize
- #pragma segment Formatting
- inline short Formatting::TabSize()
- {
- return (gTabSize);
- }
-
-
- //µ Formatting::LineLength
- #pragma segment Formatting
- inline void Formatting::LineLength(short aColumn)
- {
- gLineLength = aColumn;
- }
-
-
- //µ Formatting::LineLength
- #pragma segment Formatting
- inline short Formatting::LineLength()
- {
- return (gLineLength);
- }
-
-
- //µ Formatting::ReformatComments
- #pragma segment Formatting
- inline void Formatting::ReformatComments(Boolean aFlag)
- {
- gReformatComments = aFlag;
- }
-
-
- //µ Formatting::ReformatComments
- #pragma segment Formatting
- inline Boolean Formatting::ReformatComments()
- {
- return (gReformatComments);
- }
-
-
- //µ Formatting::PassSourceNewLines
- #pragma segment Formatting
- inline void Formatting::PassSourceNewLines(Boolean aFlag)
- {
- gPassSourceNewLines = aFlag;
- }
-
-
- //µ Formatting::PassSourceNewLines
- #pragma segment Formatting
- inline Boolean Formatting::PassSourceNewLines()
- {
- return (gPassSourceNewLines);
- }
-
-
- //µ Formatting::PassConsecutiveNewLines
- #pragma segment Formatting
- inline void Formatting::PassConsecutiveNewLines(Boolean aFlag)
- {
- gPassConsecutiveNewLines = aFlag;
- }
-
-
- //µ Formatting::PassConsecutiveNewLines
- #pragma segment Formatting
- inline Boolean Formatting::PassConsecutiveNewLines()
- {
- return (gPassConsecutiveNewLines);
- }
-
-
- //µ Formatting::DeclLeft
- #pragma segment Formatting
- inline Boolean Formatting::DeclLeft() const
- {
- return (fContext.fDeclLeft);
- }
-
-
- //µ Formatting::Comma
- #pragma segment Formatting
- inline void Formatting::Comma()
- {
- SetGlue(fContext.fComma);
- }
-
-
- //µ Formatting::Semi
- #pragma segment Formatting
- inline void Formatting::Semi()
- {
- SetGlue(fContext.fSemi);
- }
-
-
- //µ Formatting::LCurly
- #pragma segment Formatting
- inline void Formatting::LCurly()
- {
- SetGlue(fContext.fLCurly);
- }
-
-
- //µ Formatting::RCurly
- #pragma segment Formatting
- inline void Formatting::RCurly()
- {
- SetGlue(fContext.fRCurly);
- }
-
-
- //µ Formatting::LParen
- #pragma segment Formatting
- inline void Formatting::LParen()
- {
- SetGlue(fContext.fLParen);
- }
-
-
- //µ Formatting::RParen
- #pragma segment Formatting
- inline void Formatting::RParen()
- {
- SetGlue(fContext.fRParen);
- }
-
-
- //µ Formatting::Name
- #pragma segment Formatting
- inline void Formatting::Name()
- {
- SetGlue(fContext.fName);
- }
-
-
- //µ Formatting::Operator
- #pragma segment Formatting
- inline void Formatting::Operator()
- {
- SetGlue(fContext.fOperator);
- }
-
-
- //µ Formatting::Assign
- #pragma segment Formatting
- inline void Formatting::Assign()
- {
- SetGlue(fContext.fAssign);
- }
-
-
- //µ Formatting::Flush
- #pragma segment Formatting
- inline void Formatting::Flush()
- {
- gOutput->Flush();
- }
-
-
- //µ Formatting::SetComma
- #pragma segment Formatting
- inline void Formatting::SetComma(FormatString aString)
- {
- fContext.fComma = aString;
- }
-
-
- //µ Formatting::SetSemi
- #pragma segment Formatting
- inline void Formatting::SetSemi(FormatString aString)
- {
- fContext.fSemi = aString;
- }
-
-
- //µ Formatting::SetLCurly
- #pragma segment Formatting
- inline void Formatting::SetLCurly(FormatString aString)
- {
- fContext.fLCurly = aString;
- }
-
-
- //µ Formatting::SetRCurly
- #pragma segment Formatting
- inline void Formatting::SetRCurly(FormatString aString)
- {
- fContext.fRCurly = aString;
- }
-
-
- //µ Formatting::SetLParen
- #pragma segment Formatting
- inline void Formatting::SetLParen(FormatString aString)
- {
- fContext.fLParen = aString;
- }
-
-
- //µ Formatting::SetRParen
- #pragma segment Formatting
- inline void Formatting::SetRParen(FormatString aString)
- {
- fContext.fRParen = aString;
- }
-
-
- //µ Formatting::SetName
- #pragma segment Formatting
- inline void Formatting::SetName(FormatString aString)
- {
- fContext.fName = aString;
- }
-
-
- //µ Formatting::SetOperator
- #pragma segment Formatting
- inline void Formatting::SetOperator(FormatString aString)
- {
- fContext.fOperator = aString;
- }
-
-
- //µ Formatting::SetAssign
- #pragma segment Formatting
- inline void Formatting::SetAssign(FormatString aString)
- {
- fContext.fAssign = aString;
- }
-
-
- //µ Formatting::NewLineWanted
- #pragma segment Formatting
- inline static Boolean Formatting::NewLineWanted()
- {
- return (gV.fWantNewLine > 0);
- }
-
-
- //µ Formatting::SpaceWanted
- #pragma segment Formatting
- inline Boolean Formatting::SpaceWanted()
- {
- return (gV.fWantSpace > 0);
- }
-
-
- //µ Formatting::NewLineNeeded
- #pragma segment Formatting
- inline Boolean Formatting::NewLineNeeded()
- {
- return (gV.fNeedNewLine > 0);
- }
-
-
- //µ Formatting::SpaceNeeded
- #pragma segment Formatting
- inline Boolean Formatting::SpaceNeeded()
- {
- return (gV.fNeedSpace > 0);
- }
-
-
- //µ Formatting::WantNewLine
- #pragma segment Formatting
- inline void Formatting::WantNewLine(short n)
- {
- gV.fWantNewLine += n;
- }
-
-
- //µ Formatting::WantSpace
- #pragma segment Formatting
- inline void Formatting::WantSpace(short n)
- {
- gV.fWantSpace += n;
- }
-
-
- //µ Formatting::NeedNewLine
- #pragma segment Formatting
- inline void Formatting::NeedNewLine(short n)
- {
- gV.fNeedNewLine += n;
- }
-
-
- //µ Formatting::NeedSpace
- #pragma segment Formatting
- inline void Formatting::NeedSpace(short n)
- {
- gV.fNeedSpace += n;
- }
-
-
- //µ Formatting::IndentTo
- #pragma segment Formatting
- inline void Formatting::IndentTo()
- {
- IndentTo(GetIndent());
- }
-
-
- //µ Formatting::IndentLine
- #pragma segment Formatting
- inline void Formatting::IndentLine()
- {
- IndentLine(GetIndent());
- }
-
-
- //µ Formatting::AtBOL
- #pragma segment Formatting
- inline void Formatting::AtBOL()
- {
- gV.fLastTokenType = kSLex_NewLine;
- }
-
-
- //µ Formatting::WhatToSqueeze
- #pragma segment Formatting
- inline short Formatting::WhatToSqueeze() const
- {
- return (fContext.fWhatToSqueeze);
- }
-
-
- //µ Formatting::SetWhatToSqueeze
- #pragma segment Formatting
- inline void Formatting::SetWhatToSqueeze(short what)
- {
- fContext.fWhatToSqueeze = what;
- }
-
-
- //µ Formatting::_Putc
- #pragma segment Formatting
- inline void Formatting::_Putc(int aChar)
- {
- gOutput->Putc(aChar);
- ++CurrentColumn();
- }
-
-
- //µ Formatting::_Write
- #pragma segment Formatting
- inline void Formatting::_Write(const void *aString, size_t n)
- {
- gOutput->Write(aString, n);
- CurrentColumn() += n;
- }
-
-
- #endif
-
-
-