[The following is a code listing from the article "Error Messages and Documentation", by S. L. Sanders]
//============================ tstfmhdr ================================
// The following sequences are recognized as function or macro headers;
//   where the spaces stand for zero or more whitespace characters,
//   comments, and/or strings, and the .. stands for any sequence of
//   characters:
//     prevname currname {         macro, iff prevname is "define"
//     prevname currname (..) {    macro, iff prevname is "define"
//     prevname currname (..) {    function, iff prevname not "define",
//                                        and currname not "if", "for",
//                                        "while", or "switch"
//    Return: 0=Normal
//            1=Error
//            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.
short tstfmhdr(void)

{ //BEGIN tstfmhdr

//Restore position to char that ended currname (or the first non-junk
//after it), copy currname to prevname for later comparison, and return.
#define NOFMHDR{\
short i,j;       //General index
char  prvdefin;  //Boolean: TRUE iff prevname equal to "define"

currname[morfndx]=kNUL; //Terminate currname string
morfndx=0; //Reset currname index for next possible function name

              /*--See if endname followed by '{' or '('--*/
//ASSERT: csi indexes the first non-junk following an "endname" char.
//          (An endname char is one that is not a valid C identifier.)
if(feof(inf)) //endname is EOF, so do normal return.
SAVPOS //Save position at endname (past junk) in case need to go back
if(currline[csi]!='{'&&currline[csi]!='(') //endname not { or (
  NOFMHDR; //Not a function or macro header-- normal return
if((!prvdefin)&&currline[csi]!='(') //prevname!=define and currline[csi]!=(
  NOFMHDR; /* Not a function or macro header-- normal return */
//ASSERT: Either prevname=="define" or currline[csi]=='('

            /*--Check for reserved word preceding '{' or '('--*/
for(i=0;i0){ //Inside a function definition-- got a local macro
      strcpy(locmacro,"Function "); //Initialize local macro label
      morf=strcat(strcat(locmacro,fnamhold),", Macro");
      locmacro[IDSZ-1]=kNUL; //Ensure string termination
      } //END Inside a function definition-- got a local macro
    } //END prevname is "define", so it's a macro name
  else{ //It's a function name
    funcbrce=1; //Initialize to find 0-level '}' at end of function
    strcpy(fnamhold,currname); //Hold the function name
    } //END It's a function name
  strcpy(curmorf,currname); //Store current macro or functn name
  printf("\n%s %s",morf,curmorf);
  fprintf(wrkf,"\n%s %s",morf,curmorf);

  //ASSERT: csi indexes the opening brace of a function or macro.

  { //Print the first string encountered in the function or macro.
  char        bracecur[LINESZ]; //Current line at opening brace
  fpos_t      bracfpos;         //File position at opening brace
  short       bracelin;         //Line counter at opening brace
  short       bracendx;         //Character-scan index opening brace
  fgetpos(inf,&bracfpos);                 //Save file position
  memccpy(bracecur,currline,'\n',LINESZ); //Save current line
  bracelin=linectr;                       //Save line counter
  bracendx=csi;                           //Save char-scan index
  MATCHDLM(1) //Print first string encountered before matching brace
  fsetpos(inf,&bracfpos);                 //Restore file position
  memccpy(currline,bracecur,'\n',LINESZ); //Restore current line
  linectr=bracelin;                       //Restore line counter
  csi=bracendx;                           //Restore char-scan index                      
  } //END Print the first string encountered in the function or macro.

  csi++; //Skip the opening brace to continue scan of source file
  } //END Got a function or macro header
  //ASSERT: csi indexes char after currname (..), which is not '{'
  RSTPOS  //Not a function or macro header, so go back to endname pos
strcpy(prevname,currname); //Save the name for later comparison

                         /*--Normal return--*/
return(0); //Normal return
} //END tstfmhdr
Back to main article.