Click here to Skip to main content
15,892,005 members
Articles / Desktop Programming / MFC

Another Enum Viewer

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
22 Oct 20015 min read 83K   1.3K   19  
An article on the usage and design of another Enum Viewer
// CPPParserSymPragma.cpp: Process #pragmas that are interesting,
// which is currently:
//       #pragma pack(...)

#include "CPPParserSym.h"
#include "CPPSymTable.h"

///////////////////////////////////////////////////////////////////////
// HandlePragma:  Process a #pragma directive
// Inputs:
//    None explicitly, but uses LT(i), where LT(1) is assumed to be
//    positioned at the PND_PRAGMA token
// Outputs: none
// Return: none
///////////////////////////////////////////////////////////////////////
// virtual 
void 
CPPParserSym::HandlePragma()
{
   JLStr pragmaText = LT(2)->getText();

   if (GetOption(OptPragmaMSPacking) && pragmaText == "pack")
   {
      HandleMSPacking();
   }
}


///////////////////////////////////////////////////////////////////////
// HandleMSPacking:  Process MS-specific packing pragma
// #pragma pack is one of the following forms, where nnn is an
// integer and id is an identifier
//     #pragma pack()
//     #pragma pack(nnn)
//     #pragma pack(push)
//     #pragma pack(push, nnn)
//     #pragma pack(push, id)
//     #pragma pack(push, id, nnn)
//     #pragma pack(pop)
//     #pragma pack(pop, id)
//
// Inputs:
//    None explicitly, but uses LT(i), where LT(1) is assumed to be
//    positioned at the PND_PRAGMA token
// Outputs: none
// Return: none
///////////////////////////////////////////////////////////////////////
void
CPPParserSym::HandleMSPacking()
{
   bool doPush = false;

   int idx = 3;
   // The next token must be a "("
   if (LT(idx)->getType() != TOK_LPAREN)
   {
      ReportError("Expected '(' after #pragma pack", LT(idx));
      return;
   }
   idx++;

   switch (LT(idx)->getType())
   {
      case TOK_RPAREN:
      {
         // #pragma pack()   - restore default packing
         symTable->SetDefaultPacking();
         break;
      }
   
      case TOK_DECIMALINT:
      {
         // #pragma pack(nnn)
         int newPacking = atoi(LT(idx)->getText());
         if (
            newPacking != 1 && newPacking != 2 &&
            newPacking != 4 && newPacking != 8 &&
            newPacking != 16
         )
         {
            ReportError(JLStr("Invalid packing value: ") + LT(idx)->getText(), LT(idx));
            return;
         }

         idx++;
         // Must have a closing ")"
         if (LT(idx)->getType() != TOK_RPAREN)
         {
            ReportError("Expected ')' after '#pragma pack(nnn' ", LT(idx));
            return;
         }

         symTable->SetPacking(newPacking);
         break;
      }

      case TOK_ID:
      {
         // Must be 'push' or 'pop'
         if (strcmp(LT(idx)->getText(), "push") == 0)
         {
            doPush = true;
         } else if (strcmp(LT(idx)->getText(), "pop") != 0)
         {
            ReportError("Expected 'push' or 'pop' after '#pragma pack(' ", LT(idx));
            return;
         }
         idx++;

         // If the next thing is 'comma identifier', skip it
         if (LT(idx)->getType() == TOK_COMMA && LT(idx+1)->getType() == TOK_ID)
         {
            idx += 2;
         }

         if (doPush)
         {
            bool hasNewPacking = false;
            int newPacking;

            // Optional 'comma integer' for push
            if (LT(idx)->getType() == TOK_COMMA && LT(idx+1)->getType()== TOK_DECIMALINT)
            {
               hasNewPacking = true;             
               idx++;
               newPacking = atoi(LT(idx)->getText());
               if (
                  newPacking != 1 && newPacking != 2 &&
                  newPacking != 4 && newPacking != 8 &&
                  newPacking != 16
               )
               {
                  ReportError(JLStr("Invalid packing value: ") + LT(idx)->getText(), LT(idx));
                  return;
               }
               idx++;
            }

            // Must have a closing ")"
            if (LT(idx)->getType() != TOK_RPAREN)
            {
               ReportError("Expected ')' after '#pragma pack(push,integer' ", LT(idx));
               return;
            }

            // Push the current packing value
            symTable->PushPacking(newPacking);

         } else {
            // pop
            if (symTable->GetPackingStackSize() < 2)
            {
               ReportError("'#pragma pack(pop' not matched with '#pragma pack(push'", LT(1));
               return;
            }

            // Must have a closing ")"
            if (LT(idx)->getType() != TOK_RPAREN)
            {
               ReportError("Expected ')' after '#pragma pack(pop' ", LT(idx));
               return;
            }

            symTable->PopPacking();
         }
         break;
      }

      default:
         ReportError("Expected 'push', 'pop', or integer after '#pragma pack(' ", LT(idx));
         return;
   }

   idx++;
   // Must not have more tokens
   if (LT(idx)->getType() != TOK_PRAGMA_END)
   {
      ReportError("Unexpected tokens after '#pragma pack...' ", LT(idx));
      return;
   }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions