[The following is a code listing from the article "Error Messages and Documentation", by S. L. Sanders]
//============================== exstrng.h =============================
// Global declarations and definitions for exstrng.c, a program that
// illustrates string extraction from C source files.
//
//            Copyright (c) Sanders-Indev, Inc, 1997:
// Commercial use of any kind is prohibited without written consent of
// the owner. Personal and teaching use is permitted.
//======================================================================

//----------------------- Duplication Prevention -----------------------
#if !defined(XSTRh) //If exstrng.h has not already been processed,
#define XSTRh       //define "already processed" flag, then go ahead

//------------------------- Required Headers ---------------------------
#include "parse2.h" //Includes stdio.h, stddef.h, string.h
#include 


/* ------------------------ Global Variables ------------------------ */
FILE        *wrkf;            //Work file (output)
short       linectr;          //Line counter
char        infnam[FFNSZ];    //Input file name
char        currline[LINESZ]; //Current-line buffer
short       csi;              //Character-scan index
fpos_t      linepos;          //Input position just prior to curr line
char        trigcurr[LINESZ]; //Current line at trigger event
fpos_t      trigfpos;         //File position at trigger event
short       trigline;         //Line counter at trigger event
short       trigindx;         //Character-scan index at trigger event
short       beginlin;         //Char-scan index of 1st non-blank on line
char        prevname[IDSZ];   //Previous name
char        currname[IDSZ];   //Potential function or macro name
short       morfndx;          //Macro or function name index
char        curmorf[IDSZ];    //Name of current macro or function
char        *morf;            //Pointer to label "Macro" or "Function"
short       macrbrce;         //To find 0-level '}' at end of macro def
short       funcbrce;         //To find 0-level '}' at end of functn def
char        fnamhold[IDSZ];   //Fn name hold for restore after loc macro
char        locmacro[IDSZ];   //Local macro label
short       fmcount;          //Count of function or macro headers found
short       err;              //Error code: 0=none, 1=error, -1=warning
char        *errexpl;         //Pointer to error explanation
FILE        *inf;             //Input file descriptor structure
short       csisav;           //Saved char-scan index
short       lctsav;           //Saved line counter

//------------------------- Global Constants ---------------------------
#define FALSE   0        //Boolean value FALSE
#define TRUE    (!FALSE) //Boolean value TRUE
#define SKIP    1        //Skip string
#define NOSKIP  0        //Do not skip string
#define kNUL    0        //ASCII NUL character
#define kHT     9        //ASCII HORIZONTAL TAB character
static const char pfmttype[]="dscufegxXpnoEGi\""; //printf type chars
static const char octdigit[]="01234567";        //Octal digits

//Array of pointers to four reserved words
#define NRESERWD 4       //Number of pointers in reslist array
static const char *reslist[NRESERWD]={"if","for","while","switch"};

//-------------------------- Shared Macros -----------------------------

                            /*--CKENDRTN--*/
// If currline[csi] isn't a char literal, check for end of routine,
// adjusting the brace-level counts if currline[csi] is { or }.
#define CKENDRTN{\
  if(currline[csi-1]!='\'')\
    if(currline[csi]=='}'){\
      if(funcbrce>0)\
        if(macrbrce>0){\
          /*Inside a local macro*/\
          if(--macrbrce==0){\
            /*End of local macro reached, so restore*/\
            /*the enclosing function's name.        */\
            strcpy(curmorf,fnamhold);\
            morf="Function";\
            }\
          }\
        else\
          /*Inside a function*/\
          funcbrce--;\
      else\
        if(macrbrce>0)\
          /*Inside a global macro*/\
          macrbrce--;\
      }\
    else\
      if(currline[csi]=='{'){\
        if(funcbrce>0)\
          /*Inside a function*/\
          funcbrce++;\
        if(macrbrce>0)\
          /*Inside a local or global macro*/\
          macrbrce++;\
        }\
    }
                            /*--CIDSTORE--*/
//Store currline[csi] as next char in currname array.
#define CIDSTORE{\
  err=0;\
  if(morfndx0&&currline[csi-1]!='\''&&currline[csi]=='"'){\
        nstrings--;\
        if(qstring(NOSKIP)!=0)\
          return(1);\
          /*qstring has written an error message.*/\
        }\
      else\
        if(currline[csi]==opn&&(!CHARCON))\
          lev++;\
        else\
          if(currline[csi]==cls&&(!CHARCON))\
            lev--;\
      }\
    }\
  }
                           /*--CHARCON--*/
//Expression true if and only if currline[csi] is a character
//constant, that is; currline[csi-1] is an escape backslash or
//an apostrophe, and currline[csi+1} is an apostrophe.
#define CHARCON ((csi>0&&currline[csi-1]=='\\'||currline[csi-1]=='\'')\
          &&(currline[csi+1]=='\''))

                           /*--STRNGDLM--*/
//Expression true if and only if currline[csi] is a string delimiter;
//that is, a quotation mark not immediately preceded by apostrophe nor
//backslash.
#define STRNGDLM ((csi==0&&currline[0]=='"')\
          ||(csi>0&&currline[csi]=='"'\
          &&currline[csi-1]!='\''&&currline[csi-1]!='\\'))

                            /*--COMMOPEN--*/
//Expression true if and only if currline[csi] is an opening comment
//delimiter; that is, a slash followed immediately by an asterisk or
//slash.
#define COMMOPEN(csi) (currline[csi]=='/'\
          &&(currline[csi+1]=='*'||currline[csi+1]=='/'))

                            /*--COMMCLOS--*/
//Expression true if and only if currline[csi] is an closing comment
//delimiter; that is, an asterisk followed immediately by a slash.
#define COMMCLOS (currline[csi]=='*'&&currline[csi+1]=='/')

//------------------------- Function Prototypes ------------------------
extern short tstfmhdr(void);
extern short qstring(char strnact);
extern short skipcomm(void);

//---------------------------------------------------------------------
#endif       //exstrng.h has not already been processed
//=====================================================================
Back to main article.