home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / bcpp1611.zip / BCPP / BCPP.CPP < prev    next >
C/C++ Source or Header  |  1996-12-18  |  86KB  |  2,433 lines

  1. // C(++) Beautifer V1.61 Unix/MS-DOS update !
  2. // -----------------------------------------
  3. //
  4. // Program was written by Steven De Toni 1994 (CBC, ACBC).
  5. // This program attempts to alter C, C++ code so that it fits to a
  6. // format that the user wants.
  7. // This is program is the result of a project that needed to be written
  8. // for a module that I was doing at the Waikato Polytech.
  9. // Course     : Advanced Certificate In Business Computing (ACBC)
  10. // Module     : PR-300.
  11. // Assignment : Project 1, approx 60 hours.
  12. //
  13. // The program reads a configuration file that has the user's settings.
  14. // Input, and output files are via the command line.
  15. //
  16. // If compiling under DOS, use Large memory model, any other
  17. // type of system (i.e Unix, Amiga), use default.
  18. // I have tryed to use all standard Unix functions for I/O to keep
  19. // the Unix programmers happy.
  20. //
  21. // NOTE:
  22. // This code has never been tested under any other system other than MS-DOS.
  23. // All program code is public domain, you can use any part of this
  24. // code on the condition that my name be placed somewhere within documentation,
  25. // or program. However, all rights are reserved as to the program logic, that
  26. // is to say, you can change it, give it to people, but my name must still
  27. // exist within the credits of the old, or newly altered program (Programmers Ethics).
  28. //
  29. // ###################################################################################
  30. //
  31. // Program Update : 14/11/94 V1.5
  32. //
  33. // Remove a couple more bugs, optimised code (not that you notice it),
  34. // added the following features:
  35. //     - Able to decode lines fully (uses recursion)
  36. //     - Able to handle unlimited depth handling for single indent code.
  37. //     - Added command line parameter processing (able use i/o redirection)
  38. //     - Added variable internal buffer length (used for repositioning of braces)
  39. //
  40. // ###################################################################################
  41. //
  42. // Program Update : 21/11/94 V1.55
  43. //
  44. // Compiling done using GNU G++, brilliant compiler ...
  45. // Dos debugger (debug32) sucked totally compared to Borlands programming
  46. // environment, ended up using a series of printf statements in debugging !
  47. //
  48. // Program functions perfectly under Sun SPARCstation running SunOs V??,
  49. // compiled using GNU G++ V2.6.?. Version 1.05 of the GNU running under
  50. // DOS functions brilliantly, except for input redirection fails. I think this
  51. // could be due to fseek() failing to move back, and forward within the input
  52. // stream. Under Unix, this isn't a problem as pipes/redirections are handled
  53. // properly !
  54. //
  55. // Removed/fixed segmentation violations picked up by G++ within code!
  56. //
  57. //     - Removed non-existing enum constant out of fseek() (I didn't know)
  58. //     - Wrote my own string upper case routine as standard string.h
  59. //       didn't have it (again I didn't know).
  60. //     - Fix a couple of string constants, and few other odds and ends.
  61. //
  62. // ###################################################################################
  63. //
  64. // Program Update : 24/11/94 V1.6 <Final>
  65. //
  66. // Final version update of this program.
  67. //
  68. //      - Added a time feature to show long processing of the input
  69. //        data stream took ... just because I could.
  70. //
  71. //      - Fixed tab space size so that code lines are calculated at correct
  72. //        lengths according to indent spacing.
  73. //
  74. //      - Implemented a backup feature for the input file, and changed the
  75. //        selection of input/output file to the Unix standard.
  76. //
  77. //      - fix the following decode problems
  78. //        if (strcmp (pAString, "A String") == 0) // test for "A String"
  79. //                                                ^
  80. //                                                |
  81. //  Not recoginised as a comment becuase of the quotes chars!
  82. //
  83. //      - struct a { int b, c, d; } as;
  84. //        The above now gets decoded properly.
  85. //
  86. //      - able to indent multiple depthed switch like structures properly.
  87. //
  88. // ###################################################################################
  89. //
  90. // Program Update : 9/1/95 V1.61 <User Patch>
  91. //
  92. //      - Able to set indentation of comments with no code the same as normal code,
  93. //        this results in the comments lining up with the code.
  94. //
  95. //      This option was brought to you by a Candian user Justin Slootsky.
  96. #include <time.h>                                 // time()
  97. #include <string.h>                               // strlen(), strstr(), strcpy(), strcmp()
  98. #include <stdio.h>                                // NULL constant, printf(), getc(),stdin, stdout, stderr
  99. #include <dos.h>                                  // NULL constant, printf(), getc(),stdin, stdout, stderr
  100. #include "anyobj.h"                               // Use ANYOBJECT base class
  101. #include "baseq.h"                                // QueueList class to store Output structures
  102. #include "stacklis.h"                             // StackList class to store indentStruct
  103. #include "cmdline.h"                              // ProcessCommandLine()
  104. #include "config.h"                               // SetConfig()
  105. // default configuration file name
  106. char *pConfig                = "bcpp.cfg";
  107. char pConfigAlternate[ 256 ];
  108. //char pConfig[ MAXPATH + 1 ]                 = "bcpp.cfg";
  109. // ----------------------------------------------------------------------------
  110. const int IndentWordLen  = 9;                     // number of indent words in pIndentWords
  111. const int MultiIndent    = 4;                     // pos in pIndentWords where multi-line indent starts
  112. const char pIndentWords [IndentWordLen][10] =
  113. {
  114.     // single line indentation
  115.     "if", "while", "for", "else",
  116.     // multi-line indentation
  117.     "case", "default", "public", "protected", "private"
  118. };
  119.  
  120.  
  121. enum  DataTypes
  122. {
  123.     CCom = 1,   CppCom = 2, Code = 3,
  124.     OBrace = 4, CBrace = 5, ELine = 6
  125. };
  126.  
  127.  
  128. // ----------------------------------------------------------------------------
  129. // ----------------------------------------------------------------------------
  130. // This structure is used to store line data that is de-constructed from the
  131. // user's input file.
  132. class InputStruct : public ANYOBJECT
  133. {
  134.     public:
  135.         DataTypes dataType;                       // i.e "/*" or "*/"                  (1)
  136.         //     "//"                          (2)
  137.         //     Code (a = 5; , if (a == b) .. (3)
  138.         //     "{"                           (4)
  139.         //     "}"                           (5)
  140.         //     SPACES (nothing, blank line)  (6)
  141.         Boolean attrib;
  142.         //       -1 : True,  comment with code (for comment dataType)
  143.         //        0 : False, comment with no Code
  144.         char* pData;                              // pointer to queue data !
  145. };
  146.  
  147.  
  148. // ----------------------------------------------------------------------------
  149. // The output structure is used to hold an entire output line. The structure is
  150. // expanded with it's real tabs/spaces within the output function of the program.
  151. class OutputStruct : public ANYOBJECT
  152. {
  153.     public:
  154.         int   indentSpace;                        // num of spaces
  155.         char* pCode;
  156.         char* pBrace;                             // "}" or "{" + code if any
  157.         int   filler;                             // num of spaces
  158.         char* pComment;
  159.         // Constructor
  160.         // Automate initalisation
  161.         inline  OutputStruct  (void)
  162.             {
  163.             pCode = pBrace = pComment = NULL;
  164.             indentSpace    = filler   = 0;
  165.             }
  166.         // Destructor
  167.         // Automate destruction
  168.         inline ~OutputStruct (void)
  169.             {
  170.             delete pCode;
  171.             delete pBrace;
  172.             delete pComment;
  173.             }
  174. };
  175.  
  176.  
  177. // This structure is used to hold indent data on non-brace code.
  178. // This includes case statements, single line if's, while's, for statements...
  179. class IndentStruct : public ANYOBJECT
  180. {
  181.     public:
  182.         // attribute values ...
  183.         // value 1 = indent one position!
  184.         //       2 = end on close brace, and at a position
  185.         unsigned char attrib;
  186.         int           pos;
  187.         // constructor
  188.         inline IndentStruct (void)
  189.             {
  190.             attrib = pos = 0;
  191.             }
  192. };
  193.  
  194.  
  195. // ----------------------------------------------------------------------------
  196. // Function expands tabs to the spaces; the number of spaces to expand to is
  197. // dependant upon the tabSpaceSize parameter within user settings, and
  198. // tab column positions.
  199. //
  200. // Parameters:
  201. //      pString     : Pointer to the string to process !
  202. //      tabLen      : How muchs a tab is worth in spaces.
  203. //
  204. // Return Values:
  205. //      char*       : Pointer to newly constructed string, return NULL
  206. //                    if memory allocation problems.
  207. //
  208. char* ExpandTabs (char* pString, int tabLen)
  209. {
  210.     int   count = 0;
  211.     char* pSTab = pString;
  212.     while (*pSTab != NULLC)
  213.         {
  214.         count++;
  215.         if (*pSTab == TAB)                        // calculate tab positions !
  216.             {
  217.             int tabAmount = 0;
  218.             // tab is first character !!!!
  219.             if (count == 1)
  220.                 tabAmount = tabLen;
  221.             else
  222.                 tabAmount = (((count / tabLen)+1) * tabLen) - count;
  223.             if (tabAmount > 0)
  224.                 {
  225.                 // create newString, remove tab !
  226.                 char* pNewString = new char[strlen (pString) + tabAmount + 1];
  227.                 char* pAddSpc    = NULL;
  228.                 if (pNewString == NULL)
  229.                     {
  230.                     delete pString;
  231.                     return NULL;
  232.                     }
  233.                 // remove tab from string !
  234.                 *pSTab = NULLC;
  235.                 // copy first part
  236.                 strcpy (pNewString, pString);
  237.                 // add spaces
  238.                 pAddSpc = pNewString + strlen (pNewString);
  239.                 while (tabAmount > 0)
  240.                     {
  241.                     *pAddSpc = ' ';
  242.                     pAddSpc++;
  243.                     tabAmount--;
  244.                     }
  245.                 // add original trailing spaces
  246.                 strcpy (pAddSpc, pSTab+1);
  247.                 // remove old string from memory
  248.                 delete pString;
  249.                 pString = pNewString;
  250.                 pSTab   = pString;
  251.                 count   = 0;
  252.                 continue;                         // restart the operation!
  253.                 }
  254.             else
  255.                 *pSTab = ' ';
  256.             }
  257.         pSTab++;
  258.         }
  259.     return pString;
  260. }
  261.  
  262.  
  263. // ----------------------------------------------------------------------------
  264. // Function returns a True/False value according if a word/character is
  265. // contained within quotes within a string.
  266. // examples: hello "world"        : world lies within quotes (returns True)
  267. //           hello 'world'        : same as above
  268. //           "hello" world        : world no long lies within quotes (returns false)
  269. //
  270. // Parameters:
  271. // pLeftLoc      : Pointer in the string of the left most starting position to
  272. //                 start searching.
  273. // pRightLoc     : Pointer in the string of the right most starting position to
  274. //                 start searching.
  275. // pStartOfString: Pointer to the actual start location of the string that is
  276. //                 going to be searched.
  277. //
  278. // Return Values :
  279. // Boolean       : Returns True if sub-string is within quotes, else returns
  280. //                 False.
  281. //
  282. Boolean CheckCharsWithinQuotes (char* pLeftLoc, char* pRightLoc, char* pStartOfString)
  283. {
  284.     char* pDQuote   = "\"";
  285.     char* pSQuote   = "'";
  286.     char* pTQuote   = NULL;
  287.     while (  (pLeftLoc >= pStartOfString) && ((*pLeftLoc != '"') && (*pLeftLoc != '\'')) )
  288.         pLeftLoc--;
  289.     while ( (*pRightLoc != NULLC) && ((*pRightLoc != '"') && (*pRightLoc != '\'')) )
  290.         pRightLoc++;
  291.     if  ((*pLeftLoc == '"') && (*pRightLoc == '"'))
  292.         pTQuote = pDQuote;
  293.     else if  ((*pLeftLoc == '\'') && (*pRightLoc == '\''))
  294.         pTQuote = pSQuote;
  295.     if  (pTQuote != NULL)
  296.         {
  297.         // scan from left to right testing for multiple "quotes !"
  298.         char* pTLeft  = pStartOfString;
  299.         char* pTRight = pStartOfString;
  300.         for (;;)
  301.             {
  302.             pTLeft = strstr (pTLeft, pTQuote);
  303.             if (pTLeft == NULL)
  304.                 return False;
  305.             // a constant !
  306.             else if (*(pTLeft-1) == '\\')
  307.                 {
  308.                 pTLeft++;
  309.                 continue;                         // continue next search !
  310.                 }
  311.             char* pBackup = pTLeft;
  312.             do
  313.                 {
  314.                 pTRight = strstr (pTLeft+1, pTQuote);
  315.                 if (pTRight == NULL)
  316.                     return False;
  317.                 else if (*(pTRight-1) == '\\')
  318.                     pTLeft = pTRight;
  319.                 } while (*(pTRight-1) == '\\');
  320.             pTLeft = pBackup;
  321.             if ((pLeftLoc >= pTLeft) && (pRightLoc <= pTRight))
  322.                 return True;
  323.             pTLeft = pTRight+1;
  324.             }
  325.         }
  326.     return False;
  327. }
  328.  
  329.  
  330. // ----------------------------------------------------------------------------
  331. // Function is used to test if characters found on a line arn't just
  332. // C++ comments in disguise. This is used to test C comments.
  333. // example // /* C comment*/              : returns True
  334. //         /* C comment*/ // C++ comment  : returns False
  335. //
  336. // Parameters:
  337. // pLeftLoc       : Pointer to the start of the sub-string to start searching
  338. //                  left for a C++ comment
  339. // pStartOfString : Pointer to the actual start location of the whole string
  340. //                  that is going to be searched.
  341. //
  342. // Return Values:
  343. // Boolean      : Returns True if sub-string is within a C++ comment,
  344. //                else returns False
  345. //
  346. Boolean CheckCharsNotCppComments (char* pLeftLoc, char* pStartOfString)
  347. {
  348.     char* pCppCommentLoc = strstr (pStartOfString, "//");
  349.     if ((pCppCommentLoc != NULL) && (pCppCommentLoc < pLeftLoc))
  350.         return True;
  351.     else
  352.         return False;
  353. }
  354.  
  355.  
  356. // ----------------------------------------------------------------------------
  357. // Function removes leading, trailing, both leading/trailing characters
  358. // that are less than or equal to a space character (includes spaces, tabs etc)
  359. //
  360. // Parameters:
  361. // pLineData : Pointer to the start location of the string that's going to be processed
  362. // mode      : Bit values that define the removal of characters from the string...
  363. //             1 = remove spaces from left
  364. //             2 = remove spaces from right
  365. //             3 = remove spaces from left, and right
  366. //
  367. // Return Values:
  368. // char*     : Returns a pointer to the newly reformated string.
  369. //
  370. char* StripSpacingLeftRight (char* pLineData, int mode = 3)
  371. {
  372.     int   counter   = strlen (pLineData);
  373.     unsigned char* pLeftPos  = (unsigned char*) pLineData;
  374.     unsigned char* pRightPos = (unsigned char*) pLineData + counter;
  375.     // find left start of code !
  376.     // over chars that are greater than 32 !
  377.     if ((mode & 1) == 1)
  378.         {
  379.         while ((*pLeftPos <= 32) && (counter > 0))
  380.             {
  381.             pLeftPos++;
  382.             counter--;
  383.             }
  384.         }
  385.     // find right start of code !
  386.     // over chars that are greater than 32 !
  387.     if ((mode & 2) == 2)
  388.         {
  389.         while ((*pRightPos <= 32)  && (pRightPos > pLeftPos))
  390.             pRightPos--;
  391.         }
  392.     // copy that part of the code to the start of the string
  393.     if (counter == 0)
  394.         pRightPos[0] = NULLC;                     // create null string
  395.     else
  396.         pRightPos[1] = NULLC;                     // create a shortened string
  397.     pLineData = strcpy (pLineData, (char*) pLeftPos);
  398.     return pLineData;
  399. }
  400.  
  401.  
  402. // ----------------------------------------------------------------------------
  403. // Function takes a unsigned char and converts it to a C type string that
  404. // contains the char's value, but in octal (i.e "\000" = null char).
  405. //
  406. // Parameters:
  407. // value     : The value that wishes to be converted
  408. //
  409. // Return Values:
  410. // char*     : Returns a pointer to the string that was convert.
  411. // Memory is allocated via the new command, and once string has been used,
  412. // memory should be returned to the system.
  413. //
  414. char* ConvertCharToOctal (unsigned char value)
  415. {
  416.     const char octalVals[] = {'0', '1', '2', '3', '4', '5', '6', '7'};
  417.     // \000 digits plus null terminator
  418.     char* pOctalValue = new char[5];
  419.     if (pOctalValue != NULL)
  420.         {
  421.         for (int pos = 3; pos >= 1; pos--)
  422.             {
  423.             pOctalValue[pos] = octalVals[(value & 7)];
  424.             value >>= 3;                          // left shift to next three bits
  425.             }
  426.         pOctalValue[0] = '\\';
  427.         pOctalValue[4] = '\0';
  428.         }
  429.     return pOctalValue;
  430. }
  431.  
  432.  
  433. // ----------------------------------------------------------------------------
  434. // This function will strip any non-printable characters from a string,
  435. // any characters between quotes are converted to octal character notation,
  436. // if quoteChar parameter set.
  437. //
  438. // Parameters:
  439. // pLineData  : Pointer to the string to process
  440. // mode       : The type of characters to strip, and move over ...
  441. //          1 : Remove non-printing chars (i.e control chars, non-ASCII chars).
  442. //          3 : Same as above cept leave graphic chars alone.
  443. // quoteChars : Boolean char used to change non-ascii chars that lie within
  444. //            : quotes to character/octal notation if set to True.
  445. //
  446. // Return Values:
  447. // char*      : Returns a pointer to the newly altered string (if any chars removed).
  448. //
  449. char* StripNonPrintables (char* pLineData, int mode, Boolean quoteChars)
  450. {
  451.     unsigned char* pCheckByte = (unsigned char*) pLineData;
  452.     while (*pCheckByte != NULLC)
  453.         {
  454.         Boolean removeChar = False;
  455.         // type cast unsigned chars to ints to stop compiler wingeing.
  456.         switch (mode)
  457.             {
  458.             case (1):
  459.                 {
  460.                 // remove chars below a space, but not if char is a TAB.
  461.                 // Remove chars if greater than 127 (non ascii ... IBM)
  462.                 if ( ((( (int) *pCheckByte > 0)   && ((int) *pCheckByte <= 31) ) && ((int) *pCheckByte != 9)) ||
  463.                     (( (int) *pCheckByte >= 127) && ( (int) *pCheckByte <= 255)) )
  464.                 removeChar = True;
  465.                 break;
  466.                 }
  467.             case (3):
  468.                 {
  469.                 if ( ((( (int) *pCheckByte > 0)   && ((int) *pCheckByte <= 31) ) && ((int) *pCheckByte != 9)) ||
  470.                     (( (int) *pCheckByte >= 127) && ( (int) *pCheckByte <= 175)) )
  471.                     {
  472.                     // check for non graph chars
  473.                     if (( (int) *pCheckByte >= 224) && ( (int) *pCheckByte <= 255))
  474.                         // graphic char
  475.                         removeChar = False;
  476.                     else
  477.                         // a non-graphic char !
  478.                         removeChar = True;
  479.                     }
  480.                 break;
  481.                 }
  482.             }                                         // switch
  483.         // remove char from string
  484.         if (removeChar != False)
  485.             {
  486.             Boolean shuffleChars = True;
  487.             // test to see if char lies within quotes, if true then covert it to
  488.             // octal !
  489.             // Do test if not CPP comment !!!
  490.             if ((CheckCharsWithinQuotes   ((char*)pCheckByte, (char*)pCheckByte, pLineData) != False) &&
  491.                 (quoteChars == True))
  492.                 {
  493.                 // try find first type of quote in string
  494.                 char* pStartQuote = strstr (pLineData, "\"");
  495.                 // find other type of quote if other doesn't exist
  496.                 if (pStartQuote == NULL)
  497.                     pStartQuote = strstr (pLineData, "'");
  498.                 // char isn't within a cpp comment !
  499.                 if (CheckCharsNotCppComments (pStartQuote, pLineData) == False)
  500.                     {
  501.                     char* pOctalVal  = ConvertCharToOctal (*pCheckByte);
  502.                     // include length of octal, plus null terminator
  503.                     char* pTempStore = new char[strlen(pLineData)+strlen(pOctalVal)+1];
  504.                     // memory allocation failed
  505.                     if ((pTempStore == NULL) || (pOctalVal == NULL))
  506.                         {
  507.                         delete pOctalVal;
  508.                         delete pTempStore;
  509.                         delete pLineData;
  510.                         return NULL;
  511.                         }
  512.                     // terminate offending char
  513.                     *pCheckByte     = NULLC;
  514.                     // concatinate orignal string, octal string, and remaining original string!
  515.                     // copy first part of string
  516.                     strcpy (pTempStore, pLineData);
  517.                     strcpy (pTempStore + strlen(pTempStore), pOctalVal);
  518.                     strcpy (pTempStore + strlen(pTempStore), (char*)pCheckByte+1);
  519.                     delete pLineData;
  520.                     delete pOctalVal;
  521.                     pLineData       = pTempStore;
  522.                     // rescan line !
  523.                     pCheckByte      = (unsigned char*) pLineData;
  524.                     // bypass removing char !
  525.                     shuffleChars    = False;
  526.                     }                                 // if chars not within a cpp comment !
  527.                 }
  528.             // remove char from string, so long it's not within a quote !
  529.             if ((shuffleChars != False) &&
  530.                 (CheckCharsWithinQuotes   ((char*)pCheckByte, (char*)pCheckByte, pLineData) == False))
  531.                 {
  532.                 // shuffle next char over offending non-printg char !
  533.                 unsigned char* pShuff = pCheckByte;
  534.                 while (*pShuff != NULLC)
  535.                     {
  536.                     pShuff[0] = pShuff[1];
  537.                     pShuff++;
  538.                     }
  539.                 pCheckByte--;                     //recheck copied char over original!
  540.                 }
  541.             }                                         // remove/alter char from/in string !
  542.         pCheckByte++;
  543.         }                                             // while
  544.     return pLineData;
  545. }
  546.  
  547.  
  548. // ----------------------------------------------------------------------------
  549. // Function returns a Boolean value that shows where code is contained within
  550. // a string. Any chars within a string above space are consided code.
  551. //
  552. // Parameters:
  553. // pLineData : Pointer to a string to process.
  554. //
  555. // Return Values:
  556. // Boolean   : False = line has no code
  557. //             True  = line has some sort of code
  558. //
  559. Boolean TestLineHasCode (char* pLineData)
  560. {
  561.     // save on segmentation error !
  562.     if (pLineData == NULL)
  563.         return False;
  564.     unsigned char* pTest = (unsigned char*) pLineData;
  565.     int      len         = strlen (pLineData);
  566.     while ((*pTest < 33) && (*pTest > 0))
  567.         pTest++;
  568.     // if not null ending char, and char has length
  569.     if ((*pTest != 0) && (len > 0))
  570.         return True;
  571.     else
  572.         return False;
  573. }
  574.  
  575.  
  576. // ----------------------------------------------------------------------------
  577. // This function is used within function DecodeLine(), it creates a new
  578. // InputStructure and stores whats is contained in pLineData string in
  579. // the newly created structure.
  580. //
  581. // Parameters:
  582. // pLineData  : Pointer to the string to store within the InputStructure.
  583. // dataType   : Type of data that is to be stored within the InputStructure
  584. //              see DataTypes enum.
  585. //
  586. // Return Values:
  587. // InputStruct* : Returns a pointer to the newly constructed InputStructure,
  588. //                returns a NULL value is unable to allocate memory.
  589. //
  590. InputStruct* ExtractCode (char* pLineData, DataTypes dataType = Code)
  591. {
  592.     char* pNewCode =  new char[strlen (pLineData)+1];
  593.     // ############## test memory #############
  594.     if (pNewCode == NULL)
  595.         return NULL;
  596.     pNewCode = strcpy (pNewCode, pLineData);
  597.     // create new queue structure !
  598.     InputStruct* pItem = new InputStruct();
  599.     if (pItem != NULL)
  600.         {
  601.         // strip spacing in new string before storing
  602.         pItem -> pData    = StripSpacingLeftRight (pNewCode);
  603.         pItem -> dataType = dataType;
  604.         // no applicable
  605.         pItem -> attrib   = False;
  606.         }
  607.     else
  608.         delete pNewCode;
  609.     return pItem;
  610. }
  611.  
  612.  
  613. // ----------------------------------------------------------------------------
  614. // This Function is used to de-allocate memory in a InputStructure.
  615. // A destructor wasn't used becuase other objects may also own the
  616. // same memory.
  617. //
  618. // Parameters:
  619. // pDelStruct : Pointer to a dynamically allocated InputStructure within
  620. //              string data allocated.
  621. //
  622. inline void CleanInputStruct (InputStruct* pDelStruct)
  623. {
  624.     if (pDelStruct != NULL)
  625.         {
  626.         delete pDelStruct -> pData;
  627.         delete pDelStruct;
  628.         }
  629. }
  630.  
  631.  
  632. // ----------------------------------------------------------------------------
  633. // Function is used within function DecodeLine() to de-allocate memory
  634. // that it is currently using. This function is called upon a memory
  635. // allocation failure.
  636. //
  637. // Parameters:
  638. // PDelQueue : Pointer to a QueueList object which in general will contain
  639. //             InputStructures.
  640. // pLineData : Pointer to a string will contain a line of a users input file.
  641. //
  642. void DecodeLineCleanUp (QueueList* pDelQueue, char* pLineData)
  643. {
  644.     // Don't implement destructor as other objects may be using the same
  645.     // memory when using structure in output line processing (simple garbage collection)
  646.     while (pDelQueue->status() > 0)
  647.         CleanInputStruct ( ((InputStruct*)pDelQueue -> takeNext()) );
  648.     delete pLineData;
  649. }
  650.  
  651.  
  652. // ----------------------------------------------------------------------------
  653. // This function is a single pass decoder for a line of input code that
  654. // is read from the users file. The function stores each part of a line,
  655. // be it a comment (with is attributes), code, open brace, close brace, or
  656. // blank line as a InputStructure, each InputStructure is stored within
  657. // a Queue Object.
  658. //
  659. // Parameters:
  660. // pLineData  : Pointer to a line of a users input file (string).
  661. // CComments  : This variable is used to test if the current line is
  662. //              a C type comment (i.e multi-line comment). True value
  663. //              indicated Currently in C comment extraction mode, else
  664. //              in normal extraction mode.
  665. // QueueList* : Pointer to a QueueList object will contains all of
  666. //              a lines basic elements. If this object doesn't contain
  667. //              any elements, then it sugguests there was a processing
  668. //              problem.
  669. //
  670. // Return Values:
  671. // int        : returns a error code.
  672. //              -1 : Memory allocation failure
  673. //               0 : No Worries
  674. //
  675. int DecodeLine (char* pLineData, Boolean& CComments, QueueList* pInputQueue)
  676. {
  677.     // define block seperator chars
  678.     const char* pOpenBrace     = "{";
  679.     const char* pCloseBrace    = "}";
  680.     char*      pSChar = NULL;                     // used to find the starting location of certain elements in a string
  681.     char*      pEChar = NULL;                     // used as a terminator of an element in a string !
  682.     // remove unwanted space chars ????
  683.     pLineData = StripSpacingLeftRight (pLineData);
  684.     // @@@@@@ C Comment processing, if over multiple lines @@@@@@
  685.     if (CComments == True)
  686.         {
  687.         //#### Test to see if end terminating C comment has arrived !
  688.         pSChar = strstr (pLineData, "*/");
  689.         if (pSChar != NULL)
  690.             {
  691.             pSChar[1] = NULLC;                    //#### make temp string !
  692.             char* pNewComment =  new char[strlen (pLineData) + 2];
  693.             //#### Test if memory allocated
  694.             if (pNewComment == NULL)
  695.                 {
  696.                 DecodeLineCleanUp (pInputQueue, pLineData);
  697.                 return -1;
  698.                 }
  699.             pNewComment        = strcpy (pNewComment, pLineData);
  700.             int len            = strlen (pNewComment);
  701.             pNewComment[len]   = '/';
  702.             pNewComment[len+1] = NULLC;
  703.             pSChar += 2;                          //##### Advance two mem locations to the right
  704.             //##### Shift left string from current pos
  705.             strcpy (pLineData, pSChar);
  706.             //#### create new queue structure !
  707.             InputStruct* pItem = new InputStruct();
  708.             //#### Test if memory allocated
  709.             if (pItem != NULL)
  710.                 {
  711.                 pItem -> pData    = pNewComment;
  712.                 // comment
  713.                 pItem -> dataType = CCom;
  714.                 // comment without code, even if it has some !
  715.                 pItem -> attrib   = False;
  716.                 pInputQueue->putLast (pItem);
  717.                 }
  718.             else
  719.                 {
  720.                 DecodeLineCleanUp (pInputQueue, pLineData);
  721.                 return -1;
  722.                 }
  723.             CComments = False;                    //##### No more C like comments
  724.             }
  725.         else                                      //##### Place output as comment without code (C comment terminator not found)
  726.             {
  727.             InputStruct* pTemp = ExtractCode (pLineData, CCom);
  728.             //#### Test if memory allocated
  729.             if (pTemp != NULL)
  730.                 {
  731.                 pInputQueue->putLast (pTemp);
  732.                 delete pLineData;
  733.                 }
  734.             else
  735.                 {
  736.                 DecodeLineCleanUp (pInputQueue, pLineData);
  737.                 return -1;
  738.                 }
  739.             return 0;
  740.             }
  741.         }                                             // if multi-line C style comments
  742.     // N.B Place this function here as to sure not to currupt relative pointer
  743.     // settings that may be used within pLinedata, and become altered through
  744.     // using this routine.
  745.     pLineData = StripSpacingLeftRight (pLineData);
  746.     //@@@@@@ Extract /* comment */ C type comments on one line
  747.     // find start of C Comment
  748.     pSChar = strstr (pLineData, "/*");
  749.     if (pSChar != NULL)
  750.         {
  751.         //##### Check is "/*" arn't within quotes
  752.         if ((CheckCharsWithinQuotes (pSChar, pSChar+1, pLineData) == False) &&
  753.             (CheckCharsNotCppComments (pSChar, pLineData) == False))
  754.             {
  755.             //##### Check if there is a ending "*/" C terminator comment string
  756.             pEChar = strstr (pLineData, "*/");
  757.             //##### If NULL then comments are on multiple lines !
  758.             if (pEChar == NULL)
  759.                 {
  760.                 //##### Set multi-line comment variable on
  761.                 CComments = True;
  762.                 char* pNewComment = new char[strlen (pSChar)+1];
  763.                 //#### Test if memory allocated
  764.                 if (pNewComment == NULL)
  765.                     {
  766.                     DecodeLineCleanUp (pInputQueue, pLineData);
  767.                     return -1;
  768.                     }
  769.                 pNewComment = strcpy (pNewComment, pSChar);
  770.                 //##### Make it NULL so that comment is removed, from Line
  771.                 *pSChar  = NULLC;
  772.                 InputStruct* pItem = new InputStruct();
  773.                 //#### Test if memory allocated
  774.                 if (pItem != NULL)
  775.                     {
  776.                     pItem -> pData    = pNewComment;
  777.                     // Comment
  778.                     pItem -> dataType = CCom;
  779.                     // Comment without code ?
  780.                     pItem -> attrib   = TestLineHasCode (pLineData);
  781.                     pInputQueue->putLast (pItem);
  782.                     }
  783.                 else
  784.                     {
  785.                     DecodeLineCleanUp (pInputQueue, pLineData);
  786.                     return -1;
  787.                     }
  788.                 }
  789.             else
  790.                 {
  791.                 //##### make temp string !
  792.                 pEChar[1] = NULLC;
  793.                 char* pNewComment =  new char[strlen (pSChar) + 2];
  794.                 //#### Test if memory allocated
  795.                 if (pNewComment == NULL)
  796.                     {
  797.                     DecodeLineCleanUp (pInputQueue, pLineData);
  798.                     return -1;
  799.                     }
  800.                 pNewComment        = strcpy (pNewComment, pSChar);
  801.                 int len            = strlen (pNewComment);
  802.                 pNewComment[len]   = '/';
  803.                 pNewComment[len+1] = NULLC;
  804.                 pEChar += 2;                      //##### Advance two memory locs to the right
  805.                 strcpy (pSChar, pEChar);
  806.                 InputStruct* pItem = new InputStruct();
  807.                 //#### Test if memory allocated
  808.                 if (pItem != NULL)
  809.                     {
  810.                     pItem -> pData    = pNewComment;
  811.                     // Comment
  812.                     pItem -> dataType = CCom;
  813.                     // Comment without code ?
  814.                     pItem -> attrib   = TestLineHasCode (pLineData);
  815.                     pInputQueue->putLast (pItem);
  816.                     }
  817.                 else
  818.                     {
  819.                     DecodeLineCleanUp (pInputQueue, pLineData);
  820.                     return -1;
  821.                     }
  822.                 }                                     //##### else
  823.             }                                         //##### If comment not within quotes
  824.         }                                             //##### If "/*" C comments pressent
  825.     //##### Remove blank spacing from left & right of string
  826.     pLineData = StripSpacingLeftRight (pLineData);
  827.     //@@@@@@ C++ Comment Processing !
  828.     pSChar = strstr (pLineData, "//");
  829.     if (pSChar != NULL)
  830.         {
  831.         //##### Check if "//" arn't within quotes, if false then it's a comment
  832.         if (CheckCharsWithinQuotes (pSChar, pSChar+1, pLineData) == False)
  833.             {
  834.             char* pNewComment =  new char[strlen (pSChar) + 1];
  835.             //#### Test if memory allocated
  836.             if (pNewComment == NULL)
  837.                 {
  838.                 DecodeLineCleanUp (pInputQueue, pLineData);
  839.                 return -1;
  840.                 }
  841.             // copy comment into allocated memory
  842.             strcpy (pNewComment, pSChar);
  843.             *pSChar  = NULLC;                     //##### Terminate original string !
  844.             //#### create new queue structure !
  845.             InputStruct* pItem = new InputStruct();
  846.             //#### Test if memory allocated
  847.             if (pItem != NULL)
  848.                 {
  849.                 pItem -> pData    = pNewComment;
  850.                 // Comment
  851.                 pItem -> dataType = CppCom;
  852.                 // Comment without code ?
  853.                 pItem -> attrib   = TestLineHasCode (pLineData);
  854.                 pInputQueue->putLast (pItem);
  855.                 }
  856.             else
  857.                 {
  858.                 DecodeLineCleanUp (pInputQueue, pLineData);
  859.                 return -1;
  860.                 }
  861.             }
  862.         }
  863.     //################# Actual Code Extraction #################
  864.     pLineData = StripSpacingLeftRight (pLineData);
  865.     //@@@@@@ Test whats left in line for "{", and "}" braces
  866.     pSChar = pLineData-1;
  867.     for (;;)
  868.         {
  869.         pSChar = strstr (pSChar+1, pOpenBrace);
  870.         if (pSChar != NULL)
  871.             {
  872.             if (CheckCharsWithinQuotes (pSChar, pSChar, pLineData) == False)
  873.                 break;
  874.             // else continue and try and find next one after comment !
  875.             }
  876.         else
  877.             break;
  878.         }
  879.     pEChar = pLineData -1;
  880.     for (;;)
  881.         {
  882.         pEChar = strstr (pEChar+1, pCloseBrace);
  883.         if (pEChar != NULL)
  884.             {
  885.             if (CheckCharsWithinQuotes (pEChar, pEChar, pLineData) == False)
  886.                 break;
  887.             // else continue and try and find next one after comment !
  888.             }
  889.         else
  890.             break;
  891.         }
  892.     //##### check if braces arn't within quotes, if so .. then ignore!
  893.     Boolean testEnumType = False;
  894.     if ( ((pSChar != NULL) && (pEChar != NULL)) && (pSChar < pEChar))
  895.         {
  896.         // test to see if there are multiple open/ close braces in enum
  897.         // select tive range
  898.         // i.e. { if ( a == b ) { b = c } else { d = e } }
  899.         char* pOBrace = pSChar;
  900.         for (;;)
  901.             {
  902.             pOBrace = strstr (pOBrace+1, pOpenBrace);
  903.             if (pOBrace != NULL)
  904.                 {
  905.                 if (CheckCharsWithinQuotes (pOBrace, pOBrace, pLineData) == False)
  906.                     break;
  907.                 // else continue and try and find next one after comment !
  908.                 }
  909.             else
  910.                 break;
  911.             }
  912.         if ( (pOBrace == NULL) || ((pOBrace > pEChar) && (pOBrace != NULL)) )
  913.             testEnumType = True;
  914.         }
  915.     //##### If condition correct, then make rest of line just code ! (e.g enum)
  916.     // if no items in input queue, and no multiple open, close braces in
  917.     // line then .... extract as enum.
  918.     if ( (testEnumType != False) && (pInputQueue -> status () <= 0) )
  919.         {
  920.         //store code as enum type if follow if condition is true
  921.         pEChar++;
  922.         if (*pEChar == ';')                       // advance another char
  923.             pEChar++;
  924.         char BackUp = *pEChar;
  925.         *pEChar     = NULLC;
  926.         InputStruct* pTemp = ExtractCode(pLineData);
  927.         if (pTemp == NULL)
  928.             {
  929.             DecodeLineCleanUp (pInputQueue, pLineData);
  930.             return -1;
  931.             }
  932.         pInputQueue->putLast (pTemp);
  933.         *pEChar   = BackUp;
  934.         strcpy (pLineData, pEChar);
  935.         // restart decoding line !
  936.         return DecodeLine (pLineData, CComments, pInputQueue);
  937.         // end of recursive call !
  938.         }                                             // if '{' and '}' exit on same line
  939.     //##### Determine extraction precedence !
  940.     if ((pSChar != NULL) && (pEChar != NULL))
  941.         {
  942.         if (pSChar > pEChar)
  943.             pSChar = NULL;
  944.         else
  945.             pEChar = NULL;
  946.         }
  947.     //##### Place whatever is before the open brace "{", or "}" as code
  948.     if ((pSChar != NULL) || (pEChar != NULL))
  949.         {
  950.         char backUp;
  951.         if (pSChar != NULL)
  952.             {
  953.             backUp         = *pSChar;
  954.             *pSChar        = NULLC;
  955.             }
  956.         else
  957.             {
  958.             backUp = *pEChar;
  959.             *pEChar        = NULLC;
  960.             }
  961.         //#### Store leading code if any
  962.         if (TestLineHasCode (pLineData) != False)
  963.             {
  964.             char* pTemp = new char [strlen (pLineData) +1];
  965.             if (pTemp == NULL)
  966.                 {
  967.                 DecodeLineCleanUp (pInputQueue, pLineData);
  968.                 return -1;
  969.                 }
  970.             //#### strip spacing is handled within extractCode routine. This
  971.             //#### means that pointers that are calculated before stripSpacing function
  972.             //#### remain valid.
  973.             pTemp = strcpy (pTemp, pLineData);
  974.             InputStruct* pLeadCode = ExtractCode (pTemp);
  975.             if (pLeadCode == NULL)
  976.                 {
  977.                 DecodeLineCleanUp (pInputQueue, pLineData);
  978.                 return -1;
  979.                 }
  980.             pInputQueue->putLast (pLeadCode);
  981.             delete pTemp;
  982.             }
  983.         //##### Update main string
  984.         if (pSChar != NULL)
  985.             {
  986.             *pSChar        = backUp;
  987.             pLineData      = strcpy (pLineData, pSChar);
  988.             }
  989.         else
  990.             {
  991.             *pEChar        = backUp;
  992.             pLineData      = strcpy (pLineData, pEChar);
  993.             }
  994.         // extract open/closing brace from code, and place brace as seperate
  995.         // line from code. And create new structure for code
  996.         InputStruct* pTemp;
  997.         int          extractMode;
  998.         if (pLineData[0] == '{')
  999.             extractMode = 1;                      // remove open brace
  1000.         else
  1001.             extractMode = 2;                      // remove close brace
  1002.         do
  1003.             {
  1004.             switch (extractMode)
  1005.                 {
  1006.                 case (1):                         // remove open brace
  1007.                     {
  1008.                     // contain a char, or NULLC char
  1009.                     backUp       = pLineData[1];
  1010.                     pLineData[1] = NULLC;
  1011.                     //##### Define data type before storing
  1012.                     pTemp        = ExtractCode (pLineData, OBrace);
  1013.                     //#### update string
  1014.                     pLineData[1] = backUp;
  1015.                     strcpy (pLineData, pLineData+1);
  1016.                     // apply recursive extraction
  1017.                     extractMode  = 3;
  1018.                     break;
  1019.                     }
  1020.                 case (2):                         // remove close brace
  1021.                     {
  1022.                     // test the type of close brace extraction !
  1023.                     // check for following code ...
  1024.                     // struct { int a, b, } aStructure;
  1025.                     //@@@@@@ Test whats left in line for "{", and "}" braces
  1026.                     // start one after first char !
  1027.                     pSChar = pLineData;
  1028.                     for (;;)
  1029.                         {
  1030.                         pSChar = strstr (pSChar+1, pOpenBrace);
  1031.                         if (pSChar != NULL)
  1032.                             {
  1033.                             if (CheckCharsWithinQuotes (pSChar, pSChar, pLineData) == False)
  1034.                                 break;
  1035.                             // else continue and try and find next one after comment !
  1036.                             }
  1037.                         else
  1038.                             break;
  1039.                         }
  1040.                     pEChar = pLineData;
  1041.                     for (;;)
  1042.                         {
  1043.                         pEChar = strstr (pEChar+1, pCloseBrace);
  1044.                         if (pEChar != NULL)
  1045.                             {
  1046.                             if (CheckCharsWithinQuotes (pEChar, pEChar, pLineData) == False)
  1047.                                 break;
  1048.                             // else continue and try and find next one after comment !
  1049.                             }
  1050.                         else
  1051.                             break;
  1052.                         }
  1053.                     if ((pSChar != NULL) || (pEChar != NULL))
  1054.                         {
  1055.                         // if true, extract after char
  1056.                         if (pLineData[1] == ';')
  1057.                             pEChar        = pLineData+2;
  1058.                         else
  1059.                             pEChar        = pLineData+1;
  1060.                         backUp            = *pEChar;
  1061.                         *pEChar           = NULLC;
  1062.                         pTemp = ExtractCode (pLineData, CBrace);
  1063.                         // #### update string;
  1064.                         *pEChar           = backUp;
  1065.                         strcpy (pLineData, pEChar);
  1066.                         // apply recursive extraction
  1067.                         extractMode       = 3;
  1068.                         }
  1069.                     else                          // rest of data is considered as code !
  1070.                         {
  1071.                         pTemp     = ExtractCode (pLineData, CBrace);
  1072.                         // leave processing !
  1073.                         pLineData = NULL;
  1074.                         }
  1075.                     break;
  1076.                     }
  1077.                 case (3):                         // remove what is left on line as code.
  1078.                     {
  1079.                     return DecodeLine (pLineData, CComments, pInputQueue);
  1080.                     // end of recursive call !
  1081.                     }
  1082.                 }                                     // switch;
  1083.             //#### Test if memory allocated
  1084.             if (pTemp == NULL)
  1085.                 {
  1086.                 DecodeLineCleanUp (pInputQueue, pLineData);
  1087.                 return -1;
  1088.                 }
  1089.             // store Item
  1090.             pInputQueue->putLast (pTemp);
  1091.             } while ((TestLineHasCode (pLineData) != False) && (pTemp != NULL));
  1092.         }
  1093.     else                                          //##### Line contains either code, or spacing
  1094.         {
  1095.         //##### If nothing in string, and nothing stored in queue, then blank line
  1096.         if ((pLineData[0] == NULLC) && ((pInputQueue->status()) <= 0))
  1097.             {
  1098.             //##### implement blank space
  1099.             InputStruct* pTemp = ExtractCode (pLineData, ELine);
  1100.             if (pTemp != NULL)
  1101.                 pInputQueue->putLast (pTemp);
  1102.             else
  1103.                 {
  1104.                 DecodeLineCleanUp (pInputQueue, pLineData);
  1105.                 return -1;
  1106.                 }
  1107.             }
  1108.         //##### If line has more than spacing/tabs then code
  1109.         else if (TestLineHasCode (pLineData) != False)
  1110.             {
  1111.             // implement blank space
  1112.             InputStruct* pTemp = ExtractCode (pLineData);
  1113.             if (pTemp != NULL)
  1114.                 pInputQueue->putLast (pTemp);
  1115.             else
  1116.                 {
  1117.                 DecodeLineCleanUp (pInputQueue, pLineData);
  1118.                 return -1;
  1119.                 }
  1120.             }
  1121.         }
  1122.     //##### Final cleanup before returning queue with line elements
  1123.     delete pLineData;
  1124.     return 0;                                     // no worries
  1125. }
  1126.  
  1127.  
  1128. // ----------------------------------------------------------------------------
  1129. // Function takes a QueueList object that contains InputStructure items, and
  1130. // uses these items to reconstuct a compressed version of a output line of
  1131. // code, comment, or both.
  1132. //
  1133. // Parameters:
  1134. // indentStack : Variable used to show how many spaces/tabs to indent when
  1135. //           creating a new OutputStructure.
  1136. // pInputQueue : Pointer to the InputStructure queue object.
  1137. // pOutputQueue: Pointer to the OutputStructure queue object.
  1138. // userS       : Structure that contains the users config settings.
  1139. //
  1140. // Return Values:
  1141. // int        : Return values of ...
  1142. //      0 = No problems
  1143. //     -1 = Memory allocation failure
  1144. //     -2 = Line construction error, unexpected type found.
  1145. int ConstructLine (int& indentStack, QueueList* pInputQueue, QueueList* pOutputQueue, Config userS)
  1146. {
  1147.     InputStruct* pTestType = NULL;
  1148.     while ( pInputQueue->status() > 0 )
  1149.         {
  1150.         pTestType = (InputStruct*) pInputQueue -> takeNext();
  1151.         switch (pTestType -> dataType)
  1152.             {
  1153.             //@@@@@@@ Processing of C type comments /* comment */
  1154.             case (CCom):
  1155.                 //@@@@@@@ Processing of C++ type comments // comment
  1156.             case (CppCom):
  1157.                 {
  1158.                 //##### If true then comment has code
  1159.                 if (pTestType -> attrib == True)
  1160.                     {
  1161.                     OutputStruct* pOut = new OutputStruct;
  1162.                     // ##### Memory allocation test
  1163.                     if (pOut != NULL)
  1164.                         {
  1165.                         // ##### store current comment in output structure
  1166.                         pOut -> pComment      = pTestType -> pData;
  1167.                         //#### free memory
  1168.                         delete pTestType;
  1169.                         // ##### getnext Item
  1170.                         pTestType = (InputStruct*) pInputQueue -> takeNext();
  1171.                         // ##### Type Checking !!!!!
  1172.                         // if nothing in queue, or next item isn't code then some sort of error
  1173.                         if ((pTestType == NULL) || ((pTestType -> dataType <= CppCom) || (pTestType -> dataType >= ELine)))
  1174.                             {
  1175.                             fprintf (stderr, "\n#### ERROR ! Error In Line Construction !");
  1176.                             fprintf (stderr, "\nExpected Some Sort Of Code ! Data Type Found = ");
  1177.                             if (pTestType == NULL)
  1178.                                 fprintf (stderr, "NULL");
  1179.                             else
  1180.                                 fprintf (stderr, "%d", pTestType -> dataType);
  1181.                             // ##### incorrect dataType expected!
  1182.                             return -2;
  1183.                             }
  1184.                         else                      // place code in line structure, calculate indenting !
  1185.                             {
  1186.                             // if pData length overwrites comments then place comments on newline
  1187.                             if ( (indentStack + strlen (pTestType -> pData)) > (userS.posOfCommentsWC) )
  1188.                                 {
  1189.                                 pOut -> filler = userS.posOfCommentsWC;
  1190.                                 pOutputQueue -> putLast (pOut);
  1191.                                 // create new output line structure
  1192.                                 pOut = new OutputStruct();
  1193.                                 if (pOut == NULL)
  1194.                                     //##### Memory Allocation error
  1195.                                     return -1;
  1196.                                 }
  1197.                             switch (pTestType -> dataType)
  1198.                                 {
  1199.                                 case (Code):
  1200.                                     {
  1201.                                     pOut -> indentSpace = indentStack;
  1202.                                     pOut -> pCode  = pTestType -> pData;
  1203.                                     // if comment wasn't placed on a newline due to code overwriting comment
  1204.                                     if (pOut -> pComment != NULL)
  1205.                                         pOut -> filler = (userS.posOfCommentsWC - (indentStack + strlen (pTestType -> pData)));
  1206.                                     break;
  1207.                                     }
  1208.                                 case (OBrace):
  1209.                                 case (CBrace):
  1210.                                     {
  1211.                                     // indent back before adding brace, some error checking
  1212.                                     if ((pTestType -> dataType == CBrace) && (indentStack > 0))
  1213.                                         {
  1214.                                         indentStack -= userS.tabSpaceSize;
  1215.                                         // if comment wasn't placed on a newline due to code overwriting comment
  1216.                                         if (pOut -> pComment != NULL)
  1217.                                             pOut -> filler = (userS.posOfCommentsWC - (indentStack + strlen (pTestType -> pData)));
  1218.                                         }
  1219.                                     // load input data into the approiate place in output structure
  1220.                                     pOut -> indentSpace = indentStack;
  1221.                                     pOut -> pBrace = pTestType -> pData;
  1222.                                     // adjust indentation if next output line is a open Brace
  1223.                                     if (pTestType -> dataType == OBrace)
  1224.                                         {
  1225.                                         // if comment wasn't placed on a newline due to code overwriting comment
  1226.                                         if (pOut -> pComment != NULL)
  1227.                                             pOut -> filler = (userS.posOfCommentsWC - (indentStack + strlen (pTestType -> pData)));
  1228.                                         indentStack += userS.tabSpaceSize;
  1229.                                         }
  1230.                                     break;
  1231.                                     }
  1232.                                 // switch
  1233.                                 }
  1234.                             pOutputQueue -> putLast (pOut);
  1235.                             }                         // else
  1236.                         }
  1237.                     else
  1238.                         //##### Memory allocation error
  1239.                         return -1;
  1240.                     }
  1241.                 else
  1242.                     {
  1243.                     OutputStruct* pOut = new OutputStruct();
  1244.                     // ##### Memory allocation test
  1245.                     if (pOut != NULL)
  1246.                         {
  1247.                         // JZAS Start
  1248.                         if (userS.leaveCommentsNC != False)
  1249.                             pOut -> indentSpace   = indentStack;
  1250.                         else
  1251.                             pOut -> indentSpace   = userS.posOfCommentsNC;
  1252.                         // JZAS End
  1253.                         pOut -> pComment          = pTestType -> pData;
  1254.                         pOutputQueue -> putLast (pOut);
  1255.                         }
  1256.                     else
  1257.                         //##### Memory allocation error
  1258.                         return -1;
  1259.                     }                                 // else a comment without code !
  1260.                 break;
  1261.                 }                                     // case
  1262.             // @@@@@@ Processing of code (i.e k = 1; enum show {one, two};)
  1263.             case (Code):
  1264.                 {
  1265.                 OutputStruct* pOut = new OutputStruct();
  1266.                 if (pOut != NULL)
  1267.                     {
  1268.                     pOut -> indentSpace     = indentStack;
  1269.                     pOut -> pCode           = pTestType -> pData;
  1270.                     pOutputQueue -> putLast (pOut);
  1271.                     }
  1272.                 else
  1273.                     return -1;                    //##### Memory allocation error
  1274.                 break;
  1275.                 }
  1276.             // @@@@@@ Processing of open brackets "{ k = 1;"
  1277.             case (OBrace):
  1278.                 // @@@@@@ Processing of closed brackets "} k = 1;"
  1279.             case (CBrace):
  1280.                 {
  1281.                 OutputStruct* pOut = new OutputStruct();
  1282.                 if (pOut != NULL)
  1283.                     {
  1284.                     // indent back before adding brace, some error checking
  1285.                     if ((pTestType -> dataType == CBrace) && (indentStack > 0))
  1286.                         indentStack -= userS.tabSpaceSize;
  1287.                     pOut -> indentSpace     = indentStack;
  1288.                     pOut -> pBrace          = pTestType -> pData;
  1289.                     pOutputQueue -> putLast (pOut);
  1290.                     // ##### advance to the left, adjust indentation !
  1291.                     if (pTestType -> dataType == OBrace)
  1292.                         indentStack += userS.tabSpaceSize;
  1293.                     }
  1294.                 else
  1295.                     return -1;                    //##### Memory allocation error
  1296.                 break;
  1297.                 }
  1298.             // @@@@@@ Blank Line spacing
  1299.             case (ELine):
  1300.                 {
  1301.                 OutputStruct* pOut = new OutputStruct();
  1302.                 if (pOut != NULL)
  1303.                     //#### Place NULL line in output queue
  1304.                     pOutputQueue -> putLast (pOut);
  1305.                 else
  1306.                     //##### Memory allocation error
  1307.                     return NULL;
  1308.                 break;
  1309.                 }
  1310.             }                                         // switch
  1311.         delete pTestType;                         // ##### Remove structure from memory, not it's data
  1312.         // ##### it contained (i.e char* pData), this is stored
  1313.         // ##### in the output queue.
  1314.         }                                             // while there are items to construct !
  1315.     return 0;
  1316. }
  1317.  
  1318.  
  1319. // ----------------------------------------------------------------------------
  1320. // This function is used to allocate memory for indentation within function
  1321. // OutputToOutFile(). Once the memory needed is allocated, it fills the memory
  1322. // with spaces, or tabs depending upon the fill mode.
  1323. //
  1324. // Parameters:
  1325. // Mode         : Defines the fill mode of the memory that it allocate
  1326. //             1 = tabs only
  1327. //             2 = spaces only
  1328. //             3 = both
  1329. // len       : Number of bytes needed to be allocated
  1330. // spaceIndent:Number of memory locations a tab character take up
  1331. //
  1332. // Return Values:
  1333. // char*     : Returns a pointer to the memory/string that was allocated
  1334. //
  1335. char* TabSpacing (int mode, int len, int spaceIndent)
  1336. {
  1337.     char* pOutTab = NULL;
  1338.     char* pOutSpc = NULL;
  1339.     if ((mode & 1) == 1)
  1340.         {
  1341.         int numOfTabs = 0;
  1342.         // bypass exception error
  1343.         if (spaceIndent > 0)
  1344.             numOfTabs = len / spaceIndent;
  1345.         pOutTab = new char[numOfTabs+1];
  1346.         if (pOutTab != NULL)
  1347.             {
  1348.             for (int fillTabs = 0; fillTabs < numOfTabs; fillTabs++)
  1349.                 pOutTab[fillTabs] = TAB;
  1350.             pOutTab[numOfTabs] = NULLC;
  1351.             }
  1352.         else
  1353.             return NULL;                          // memory allocation failed
  1354.         // If not in both tab, and space concatination.
  1355.         if ((mode & 2) == 0)
  1356.             return pOutTab;
  1357.         }                                             //bit 0 set !
  1358.     if ((mode & 2) == 2)
  1359.         {
  1360.         if (pOutTab == NULL)                      //##### normal space allocation !
  1361.             {
  1362.             pOutSpc = new char[len+1];
  1363.             if (pOutSpc != NULL)
  1364.                 {
  1365.                 for (int fillSpcs = 0; fillSpcs < len; fillSpcs++)
  1366.                     pOutSpc[fillSpcs] = ' ';
  1367.                 pOutSpc[len] = NULLC;
  1368.                 //##### return end product
  1369.                 return pOutSpc;
  1370.                 }
  1371.             else
  1372.                 return NULL;                      // memory allocation failed
  1373.             }
  1374.         else                                      // else a mix of spaces & tabs
  1375.             {
  1376.             int numOfSpcs = 0;
  1377.             if (spaceIndent > 0)
  1378.                 numOfSpcs = len % spaceIndent;
  1379.             pOutSpc = new char[numOfSpcs+1];
  1380.             if (pOutSpc != NULL)
  1381.                 {
  1382.                 for (int fillSpcs = 0; fillSpcs < numOfSpcs; fillSpcs++)
  1383.                     pOutSpc[fillSpcs] = ' ';
  1384.                 pOutSpc[numOfSpcs] = NULLC;
  1385.                 }
  1386.             else
  1387.                 return NULL;                      // memory allocation failed
  1388.             }
  1389.         }                                             // bit 1 set
  1390.     //##### Concatinate tabs & spaces
  1391.     if ( ((mode & 1) == 1) && ((mode & 2) == 2) )
  1392.         {
  1393.         char* pConCat = new char[(strlen (pOutTab) + strlen (pOutSpc) + 1)];
  1394.         // #### Check memory allocation
  1395.         if (pConCat == NULL)
  1396.             {
  1397.             delete pOutTab;
  1398.             delete pOutSpc;
  1399.             return NULL;
  1400.             }
  1401.         strcpy (pConCat, pOutTab);
  1402.         strcpy (pConCat + strlen (pConCat), pOutSpc);
  1403.         delete pOutTab;
  1404.         delete pOutSpc;
  1405.         return pConCat;
  1406.         }
  1407.     return NULL;                                  //##### illegal mode passed !
  1408. }
  1409.  
  1410.  
  1411. // ----------------------------------------------------------------------------
  1412. // Function is used to indent single indented code such is found in if, while,
  1413. // else statements. Also handles case like statements within switchs'.
  1414. //
  1415. // Parameters:
  1416. // pLines     : Pointer to the output queue.
  1417. // pIMode     : Pointer to indent type stack.
  1418. // userS      : User configuration (i.e indent spacing, position of comments)
  1419. //
  1420. // Return Values:
  1421. // QueueList*    : Pointer to the output queue (may have been reconstructed),
  1422. //                 returns NULL if failed to allocate memory
  1423. //
  1424. QueueList* IndentNonBraceCode (QueueList* pLines, StackList* pIMode, Config& userS)
  1425. {
  1426.     // if there are items to check !
  1427.     if ((pLines != NULL) && (pLines -> status () <= 0))
  1428.         return pLines;
  1429.     // If There are indent items to process !
  1430.     if (pIMode -> status() <= 0)
  1431.         return pLines;
  1432.     IndentStruct* pIndentItem = (IndentStruct*) pIMode -> pop();
  1433.     OutputStruct* pAlterLine  = (OutputStruct*) pLines -> peek (1);
  1434.     if ( ((pAlterLine -> pCode != NULL)     || ((pAlterLine -> pBrace != NULL) && (pIndentItem -> attrib == 2)) ) ||
  1435.         ((userS.leaveCommentsNC != False)  && ((pAlterLine -> pCode == NULL)  && (pAlterLine -> pComment != NULL))) )
  1436.         {
  1437.         switch (pIndentItem -> attrib)
  1438.             {
  1439.             // single indent
  1440.             case (1):
  1441.                 {
  1442.                 pAlterLine -> indentSpace += userS.tabSpaceSize;
  1443.                 break;
  1444.                 }
  1445.             // indent of a case statement !
  1446.             case (2):
  1447.                 {
  1448.                 // determine how many case like items are stored within
  1449.                 // list to determine how much to indent !
  1450.                 int Icount  = MultiIndent;
  1451.                 char* pTest = NULL;
  1452.                 pAlterLine -> indentSpace += (userS.tabSpaceSize * (pIMode -> status()));
  1453.                 // test if not another case, or default, if so, dont indent !
  1454.                 // possiblity of a NULL here
  1455.                 if (pAlterLine -> pCode != NULL)
  1456.                     {
  1457.                     do
  1458.                         {
  1459.                         pTest = strstr (pAlterLine -> pCode, pIndentWords[Icount]);
  1460.                         Icount++;
  1461.                         } while ((pTest == NULL) && (Icount < IndentWordLen));
  1462.                     }
  1463.                 // check for closing braces to end case indention
  1464.                 if ((pTest == NULL) && (pAlterLine -> pBrace != NULL))
  1465.                     {
  1466.                     if ((*(pAlterLine -> pBrace) == '}') && (pAlterLine -> indentSpace == pIndentItem -> pos))
  1467.                         {
  1468.                         delete pIndentItem;
  1469.                         pIndentItem = NULL;
  1470.                         }
  1471.                     }
  1472.                 // indent as per normal !
  1473.                 if ((pIndentItem != NULL) && (pTest == NULL))
  1474.                     {
  1475.                     // ok to indent next item !
  1476.                     pIMode -> push (pIndentItem);
  1477.                     pAlterLine -> indentSpace += userS.tabSpaceSize;
  1478.                     }
  1479.                 else if (pIndentItem != NULL)
  1480.                     {
  1481.                     // if end single indent keyword found, check to see
  1482.                     // whether it is the correct one before removing it !
  1483.                     if ((pTest != NULL) && (pIndentItem -> pos+userS.tabSpaceSize < pAlterLine -> indentSpace))
  1484.                         {
  1485.                         // ok to indent next item !
  1486.                         pIMode -> push (pIndentItem);
  1487.                         pAlterLine -> indentSpace += userS.tabSpaceSize;
  1488.                         }
  1489.                     else
  1490.                         {
  1491.                         delete pIndentItem;
  1492.                         pIndentItem = NULL;
  1493.                         }
  1494.                     }
  1495.                 break;
  1496.                 }
  1497.             }                                         // switch
  1498.         // test if code has started to overwrite comments, and
  1499.         // not a case, or default statement ... if so, adjust queue !
  1500.         if ( ((pAlterLine -> pComment != NULL) && (pIndentItem != NULL)) &&
  1501.             ((pAlterLine -> pCode    != NULL) || (pAlterLine -> pBrace != NULL)) )
  1502.             {
  1503.             // alter filler size for comment spacing !
  1504.             pAlterLine -> filler -= userS.tabSpaceSize;
  1505.             // if less than 0, then code is overwriting comments !
  1506.             if (pAlterLine -> filler < 0)
  1507.                 {
  1508.                 // reconstruct queue !
  1509.                 QueueList*    pNewQueue = new QueueList();
  1510.                 OutputStruct* pNewItem  = new OutputStruct();
  1511.                 pAlterLine              = (OutputStruct*) pLines -> takeNext();
  1512.                 if (pNewItem == NULL)
  1513.                     {
  1514.                     delete pNewQueue;
  1515.                     delete pIMode;
  1516.                     delete pLines;
  1517.                     // out of memory
  1518.                     return NULL;
  1519.                     }
  1520.                 // load new structure
  1521.                 pNewItem   -> filler      = userS.posOfCommentsWC;
  1522.                 pNewItem   -> pComment    = pAlterLine -> pComment;
  1523.                 // set this to zero as not to create filler
  1524.                 pAlterLine -> filler      = 0;
  1525.                 // spaces at line output time.
  1526.                 pAlterLine -> pComment    = NULL;
  1527.                 // reconstruct queue !
  1528.                 pNewQueue -> putLast (pNewItem);
  1529.                 pNewQueue -> putLast (pAlterLine);
  1530.                 // copy existing lines from old queue, into the newly created queue !
  1531.                 while (pLines -> status () > 0)
  1532.                     pNewQueue -> putLast ( pLines -> takeNext() );
  1533.                 delete pLines;
  1534.                 // reassign new queue object
  1535.                 pLines = pNewQueue;
  1536.                 }                                     // if over writting comments
  1537.             }                                         // if comments exist on same line as code
  1538.         // Remove single line indentation from memory, if current line
  1539.         // does contain a if, else, while ... type keyowrd
  1540.         if ((pIndentItem != NULL) && (pIndentItem -> attrib == 1))
  1541.             {
  1542.             // recursive function call !
  1543.             if (pIMode -> status() > 0)
  1544.                 pLines = IndentNonBraceCode (pLines, pIMode, userS);
  1545.             pIMode -> push (pIndentItem);
  1546.             pIndentItem = NULL;
  1547.             }
  1548.         }                                             // if code to process
  1549.     else if (pIndentItem != NULL)
  1550.         // no indentation yet, maybe only blank line, or comment in case
  1551.         pIMode -> push (pIndentItem);
  1552.     return pLines;
  1553. }
  1554.  
  1555.  
  1556. // ----------------------------------------------------------------------------
  1557. // Function allocates indent structures used to indent code that don't lie
  1558. // within braces, but should still be indented.
  1559. //
  1560. // Parameters:
  1561. // pIMode     : Pointer to a indent stack. Contains indent structures used to
  1562. //              indent code without braces
  1563. // pLines     : Pointer to output queue, stores semi-finished output code.
  1564. // userS      : User settings.
  1565. //
  1566. // Return Values:
  1567. // QueueList*    : Pointer to the output queue (may have been reconstructed),
  1568. //                 returns NULL if failed to allocate memory
  1569. //
  1570. QueueList* IndentNonBraces (StackList* pIMode, QueueList* pLines, Config userS)
  1571. {
  1572.     const int minLimit = 2;                       // used in searching output queue
  1573.     // for open braces
  1574.     // indent Items contained !
  1575.     if (pIMode -> status () > 0)
  1576.         {
  1577.         //#### Indent code if code available, in a case statement
  1578.         pLines = IndentNonBraceCode (pLines, pIMode, userS);
  1579.         }
  1580.     if (pLines -> status () < minLimit)
  1581.         return pLines;
  1582.     // determine if current line has a single line keyword ! (if, else, while, for, do)
  1583.     if ( ((OutputStruct*) pLines -> peek (1)) -> pCode     != NULL)
  1584.         {
  1585.         // test the exisitance of a key word !
  1586.         int     findWord = 0;
  1587.         char*   pTestCode = ((OutputStruct*) pLines -> peek (1)) -> pCode;
  1588.         while (findWord < IndentWordLen)
  1589.             {
  1590.             char* pTest = strstr (pTestCode, pIndentWords[findWord]);
  1591.             // word found, and at start location of string, else some funny code !
  1592.             if (pTest == pTestCode)
  1593.                 break;
  1594.             findWord++;
  1595.             }
  1596.         // if keyword found, check if next line not a brace or, comment !
  1597.         pTestCode = ((OutputStruct*) pLines -> peek (1)) -> pCode ;
  1598.         // Test if code not NULL, and No Hidden Open Braces
  1599.         if ( (pTestCode != NULL) &&
  1600.             ((pTestCode [strlen (pTestCode) - 1] == '{') || (pTestCode [strlen (pTestCode) - 1] == ';')) )
  1601.         pTestCode = NULL;
  1602.         // Test if open brace not located on next line
  1603.         if ((pTestCode != NULL) && (findWord < IndentWordLen))
  1604.             {
  1605.             pTestCode = ((OutputStruct*) pLines -> peek (minLimit)) -> pBrace;
  1606.             if ((pTestCode != NULL) && (pTestCode[0] == '{'))
  1607.                 // Dont process line as a single indentation !
  1608.                 pTestCode = NULL;
  1609.             else
  1610.                 // make sure pointer is not null !
  1611.                 pTestCode = "E";
  1612.             }
  1613.         if ((findWord < IndentWordLen) && (pTestCode != NULL))
  1614.             // create new structure !
  1615.             {
  1616.                 IndentStruct* pIndent = new IndentStruct();
  1617.             // #### memory allocation error
  1618.             if (pIndent == NULL)
  1619.                 {
  1620.                 delete pLines;
  1621.                 delete pIMode;
  1622.                 return NULL;
  1623.                 }
  1624.             // do indent mode for (if, while, for, else)
  1625.             if ((findWord >= 0) && (findWord < MultiIndent))
  1626.                 {
  1627.                 // single indent !
  1628.                 pIndent -> attrib = 1;
  1629.                 }
  1630.             else                                  // it's a case statement !
  1631.                 {
  1632.                 // multiple indent !
  1633.                 pIndent -> attrib = 2;
  1634.                 pIndent -> pos    = (((OutputStruct*) pLines -> peek (1)) -> indentSpace) - userS.tabSpaceSize;
  1635.                 }
  1636.             // place item on stack !
  1637.             pIMode -> push (pIndent);
  1638.             }
  1639.         else
  1640.             {
  1641.             // update pIMode indent queue, throw out single indents if
  1642.             // not needed (i.e multi line single if conditions)
  1643.             IndentStruct* pThrowOut = NULL;
  1644.             for (;;)
  1645.                 {
  1646.                 if (pIMode -> status () > 0)
  1647.                     pThrowOut = (IndentStruct*) pIMode -> pop();
  1648.                 else
  1649.                     break;                        // leave loop
  1650.                 if (pThrowOut -> attrib >= 2)
  1651.                     {
  1652.                     pIMode -> push (pThrowOut);
  1653.                     break;
  1654.                     }
  1655.                 else
  1656.                     // throw out the single indent item
  1657.                     delete pThrowOut;
  1658.                 }
  1659.             }
  1660.         }
  1661.     return pLines;
  1662. }
  1663.  
  1664.  
  1665. // ----------------------------------------------------------------------------
  1666. // Function reformats open braces to be on the same lines as the
  1667. // code that it's assigned (if possible).
  1668. //
  1669. // Parameters:
  1670. // pLines     : Pointer to a OutputStructure queue object
  1671. // userS      : Users configuration settings.
  1672. //
  1673. // Return Values:
  1674. // QueueList* : Returns a pointer to a newly constructed OutputStructure
  1675. //              queue.
  1676. //
  1677. QueueList* ReformatBraces (QueueList* pLines, Config userS)
  1678. {
  1679.     QueueList*    pNewLines     = new QueueList();
  1680.     // get queue number
  1681.     int           queueNum      = pLines -> status ();
  1682.     int           findBrace;                      // position in queue where first brace line is located
  1683.     int           findCode ;                      // position in queue where next code line is located
  1684.     OutputStruct* pBraceLine    = NULL;
  1685.     OutputStruct* pCodeLine     = NULL;
  1686.     if (pNewLines == NULL)
  1687.         {
  1688.         delete pLines;
  1689.         return NULL;                              // out of memory
  1690.         }
  1691.     // Cant process less than two items (i.e. move brace from one line to next line to make one line )
  1692.     if (queueNum  < 2)
  1693.         {
  1694.         delete pNewLines;                         // free object that wasn't used !
  1695.         return pLines;
  1696.         }
  1697.     // search forward through queue to find the first appearance of a brace !
  1698.     findBrace = 1;
  1699.     while (findBrace <= queueNum)
  1700.         {
  1701.         pBraceLine = (OutputStruct*) pLines -> peek (findBrace);
  1702.         if ((pBraceLine -> pBrace != NULL) && (pBraceLine -> pBrace[0] == '{'))
  1703.             break;                                // leave queue search !
  1704.         else
  1705.             findBrace++;
  1706.         }
  1707.     if (findBrace > queueNum)                     // open brace not found in queue !
  1708.         {
  1709.         delete pNewLines;
  1710.         return pLines;
  1711.         }
  1712.     // find out if there is a place to place the brace in the code that
  1713.     // is currently stored !
  1714.     for (findCode = findBrace-1; findCode >= 1; findCode--)
  1715.         {
  1716.         if (((OutputStruct*) pLines -> peek (findCode)) -> pCode != NULL)
  1717.             break;                                // found a code Line !
  1718.         }
  1719.     if (findCode > 0)                             // o.k found a line that has code !
  1720.         {
  1721.         OutputStruct* pNewItem   = NULL;
  1722.         char*         pNewMem    = NULL;
  1723.         // load newQueue with lines up to code line found !
  1724.         for (int loadNew = 1; loadNew < findCode; loadNew++)
  1725.             pNewLines -> putLast (pLines -> takeNext());
  1726.         // take code line that is going to be altered !
  1727.         pCodeLine  = (OutputStruct*) pLines -> takeNext ();
  1728.         // calculate new brace position in queue
  1729.         findBrace                = findBrace - (queueNum - pLines -> status ());
  1730.         // get a pointer to the brace line, this is because of code lines that may still
  1731.         // exist within queue.
  1732.         pBraceLine = (OutputStruct*) pLines -> peek (findBrace);
  1733.         // if code has comments, then it's placed on a new line !
  1734.         if (pCodeLine -> pComment != NULL)
  1735.             {
  1736.             // len of indent + code + space + brace
  1737.             int overWrite = pCodeLine -> indentSpace + strlen (pCodeLine -> pCode) + 1 + strlen (pBraceLine -> pBrace);
  1738.             // if true then place comment on new line !
  1739.             if (overWrite >= userS.posOfCommentsWC)
  1740.                 {
  1741.                 pNewItem                = new OutputStruct();
  1742.                 if (pNewItem == NULL)
  1743.                     return NULL;
  1744.                 pNewItem  -> filler      = userS.posOfCommentsWC;
  1745.                 pNewItem  -> pComment    = pCodeLine -> pComment;
  1746.                 // make this NULL as not to be delete when
  1747.                 pCodeLine -> pComment    = NULL;
  1748.                 // object destructor is called.
  1749.                 pNewLines -> putLast (pNewItem);
  1750.                 }
  1751.             }
  1752.         // place brace code onto new output structure !
  1753.         pNewItem = new OutputStruct();
  1754.         // code + space + brace + nullc
  1755.         pNewMem  = new char [strlen (pCodeLine -> pCode) + strlen (pBraceLine -> pBrace) + 1 + 1];
  1756.         if ((pNewItem == NULL) || (pNewMem == NULL))
  1757.             {
  1758.             delete pCodeLine;
  1759.             delete pBraceLine;
  1760.             delete pLines;
  1761.             delete pNewLines;
  1762.             return NULL;                          // out of memory
  1763.             }
  1764.         // concatinate code + space + brace // ### CHECK IT
  1765.         // copy code
  1766.         pNewMem = strcpy  (pNewMem, pCodeLine -> pCode);
  1767.         // copy space
  1768.         strcpy (pNewMem + strlen (pNewMem), " ");
  1769.         // copy brace
  1770.         strcpy (pNewMem + strlen (pNewMem), pBraceLine -> pBrace);
  1771.         // place attributes into queue
  1772.         pNewItem -> indentSpace = pCodeLine -> indentSpace;
  1773.         pNewItem -> pCode       = pNewMem;
  1774.         // Add comments to new code line if they exist
  1775.         if (pCodeLine -> pComment != NULL)
  1776.             {
  1777.             pNewItem  -> pComment = pCodeLine -> pComment;
  1778.             // make this NULL as not to be delete when
  1779.             pCodeLine -> pComment = NULL;
  1780.             // object destructor is called.
  1781.             // calculate filler spacing!
  1782.             pNewItem  -> filler   = userS.posOfCommentsWC - (pCodeLine -> indentSpace + strlen (pNewItem -> pCode));
  1783.             }
  1784.         // store newly constructed output structure
  1785.         pNewLines -> putLast (pNewItem);
  1786.         // process brace Line !, create new output structure for brace comment
  1787.         if (pBraceLine -> pComment != NULL)
  1788.             {
  1789.             pNewItem = new OutputStruct();
  1790.             if (pNewItem == NULL)
  1791.                 {
  1792.                 delete pCodeLine;
  1793.                 delete pBraceLine;
  1794.                 delete pLines;
  1795.                 delete pNewLines;
  1796.                 return NULL;                      // out of memory
  1797.                 }
  1798.             // load comment
  1799.             pNewItem   -> pComment = pBraceLine -> pComment;
  1800.             pBraceLine -> pComment = NULL;
  1801.             // positioning comment, use filler no indentSpace as this
  1802.             // will become screw when using tabs ... fillers use spaces!
  1803.             pNewItem   -> filler  = userS.posOfCommentsWC;
  1804.             pNewLines  -> putLast (pNewItem);
  1805.             }
  1806.         delete pCodeLine;
  1807.         // delete pBraceLine; // dont implement this, use queue object to delete it
  1808.         // copy existing lines from old queue, into the newly created queue !
  1809.         // copy one all objects on pLines up to pBraceLine
  1810.         // read ahead rule
  1811.         pCodeLine = (OutputStruct*) pLines -> takeNext();
  1812.         while (pCodeLine != pBraceLine)
  1813.             {
  1814.             pNewLines -> putLast (pCodeLine);
  1815.             pCodeLine = (OutputStruct*) pLines -> takeNext();
  1816.             }
  1817.         delete pCodeLine;                         // remove brace lines (indisguise)
  1818.         // code whats left in pLines queue to pNewLines !
  1819.         while ((pLines -> status ()) > 0 )
  1820.             pNewLines -> putLast (pLines -> takeNext ());;
  1821.         // remove old queue object from memory, return newly constructed one
  1822.         delete pLines;
  1823.         // Test if there are any more '{' open brace lines in pNewLine queue,
  1824.         // do a recursive call to check ! :-)
  1825.         pLines = ReformatBraces (pNewLines, userS);
  1826.         return pLines;
  1827.         }
  1828.     else
  1829.         delete pNewLines;                         // couldn't find a code line in queue buffer!
  1830.     return pLines;
  1831. }
  1832.  
  1833.  
  1834. // ----------------------------------------------------------------------------
  1835. // Function reformats the spacing between functions, structures, unions, classes.
  1836. //
  1837. // Parameters:
  1838. // pOutFile : Pointer to the ouput FILE structure.
  1839. // pLines   : Pointer to the OuputStructure queue object.
  1840. // userS    : Users configuration settings.
  1841. // FuncVar  : Defines what type of mode the function is operating in.
  1842. //
  1843. // Return Values:
  1844. // QueueList*   : Pointer to the OuputStructure (sometimes altered)
  1845. // FuncVar      : Defines what mode function is currently in
  1846. //                0 = dont delete blank lines
  1847. //                1 = output blank lines
  1848. //                2 = delete blank OutputStructures in queue until code is reached.
  1849. //
  1850. QueueList* FunctionSpacing (FILE* pOutFile, QueueList* pLines, const Config& userS, int& FuncVar )
  1851. {
  1852.     // if there are items in the queue !
  1853.     if (pLines -> status () > 0)
  1854.         {
  1855.         OutputStruct* pTestLine      =  (OutputStruct*) pLines -> peek (1);
  1856.         // check is end of fuction, structure, class has been reached !
  1857.         if ( ((FuncVar == 0) && (pTestLine -> indentSpace <= 0 )) &&
  1858.             (pTestLine -> pBrace != NULL) )
  1859.             {
  1860.             if (pTestLine -> pBrace[0] == '}')
  1861.                 {
  1862.                 FuncVar = 1;                      // add function spacing !
  1863.                 return pLines;
  1864.                 }
  1865.             }
  1866.         if (FuncVar == 1)
  1867.             {
  1868.             // go into blank line output mode between functions!
  1869.             for (int outBlank = 0; outBlank < userS.numOfLineFunc; outBlank++)
  1870.                 {
  1871.                 // output line feed!
  1872.                 ////////////////////////////////////////////////////////////////////////
  1873.                 // Fixed for DOS CR/LF
  1874.                 // nitin@poboxes.com
  1875.                 ////////////////////////////////////////////////////////////////////////
  1876.                 if ( userS.dosLines == True )
  1877.                     fputc (CR, pOutFile);
  1878.                 // output line feed!
  1879.                 fputc (LF, pOutFile);
  1880.                 }
  1881.             FuncVar = 2;
  1882.             }
  1883.         if ( (FuncVar == 2) &&
  1884.             (((pTestLine -> pCode != NULL ) || (pTestLine -> pBrace != NULL)) || (pTestLine -> pComment != NULL)) )
  1885.         FuncVar = 0;
  1886.         else if (FuncVar == 2)
  1887.             {
  1888.             // dump line from queue!
  1889.             OutputStruct* dump = (OutputStruct*) pLines -> takeNext();
  1890.             delete dump;
  1891.             }
  1892.         }
  1893.     return pLines;
  1894. }
  1895.  
  1896.  
  1897. // ----------------------------------------------------------------------------
  1898. // Function is used to expand OutputStructures contained within a queue to the
  1899. // users output file. Function also reformats braces, function spacing,
  1900. // braces indenting.
  1901. //
  1902. // Parameters:
  1903. // pOutFile  : Pointer to the users output FILE structure/handle
  1904. // pLines    : Pointer to the OutputStructures queue object
  1905. // FuncVar   : See FunctionSpacing()
  1906. // userS     : Users configuration settings.
  1907. // stopLimit : Defines how many OutputStructures remain within the Queue not
  1908. //             processed.
  1909. //
  1910. // Return Values:
  1911. // FuncVar   : See FunctionSpacing()
  1912. // QueueList*: Pointer to the Output queue object (sometimes modified!)
  1913. //
  1914. // returns NULL if memory allocation failed
  1915. //
  1916. QueueList* OutputToOutFile (FILE* pOutFile, QueueList* pLines, StackList* pIMode, int& FuncVar, const Config& userS, int stopLimit)
  1917. {
  1918.     OutputStruct* pOut         = NULL;
  1919.     char*         pIndentation = NULL;
  1920.     char*         pFiller      = NULL;
  1921.     int           fillMode     = 0;
  1922.     // determin fill mode
  1923.     if (userS.useTabs == True)
  1924.         fillMode = 1;                             // set bit 0, tabs
  1925.     else
  1926.         fillMode = 2;                             // set bit 1, spaces
  1927.     // stopLimit is used to search backward for "{"
  1928.     while (pLines -> status() > stopLimit)
  1929.         {
  1930.         // process function spacing !!!!!
  1931.         int testProcessing = pLines -> status();
  1932.         pLines = FunctionSpacing (pOutFile, pLines, userS, FuncVar );
  1933.         // line removed, test next line in buffer
  1934.         if (pLines -> status () < testProcessing)
  1935.             continue;
  1936.         // check indentation on case statements etc
  1937.         pLines = IndentNonBraces (pIMode, pLines, userS);
  1938.         if (pLines == NULL)
  1939.             return NULL;                          //#### Memory Allocation Failure
  1940.         // reformat open braces if user option set !
  1941.         // place open braces on same line as code
  1942.         if (userS. braceLoc == False)
  1943.             {
  1944.             pLines = ReformatBraces (pLines, userS);
  1945.             if (pLines == NULL)
  1946.                 return NULL;
  1947.             }
  1948.         pOut = (OutputStruct*) pLines -> takeNext();
  1949.         // ######## debug
  1950.         //gotoxy (1,1);
  1951.         //printf ("%d Indent    %d  Filler   \n", pOut -> indentSpace, pOut -> filler);
  1952.         // expand pOut structure to print to the output file
  1953.         pIndentation = TabSpacing (fillMode, pOut -> indentSpace, userS.tabSpaceSize );
  1954.         pFiller      = TabSpacing (2, pOut -> filler, userS.tabSpaceSize);
  1955.         // Output data
  1956.         if (pIndentation != NULL)
  1957.             {
  1958.             fprintf (pOutFile, "%s", pIndentation);
  1959.             delete pIndentation;
  1960.             }
  1961.         if (pOut -> pCode != NULL)
  1962.             fprintf (pOutFile, "%s", pOut -> pCode);
  1963.  
  1964.         ////////////////////////////////////////////////////////////////////////
  1965.         // Fixed for my kinda indenting, with the option not to indent function
  1966.         // blocks as well as code blocks
  1967.         // nitin@poboxes.com
  1968.         ////////////////////////////////////////////////////////////////////////
  1969.         if (pOut -> pBrace != NULL)
  1970.             {
  1971.             if ( userS.formatStyle == True )
  1972.                 {
  1973.                 if ( userS.functionIndent )
  1974.                     fprintf (pOutFile, "%s%s", "\t", pOut->pBrace );
  1975.                 else
  1976.                     fprintf (pOutFile, "%s%s", pOut->indentSpace?"\t":"", pOut->pBrace );
  1977.                 }
  1978.             else
  1979.                 fprintf (pOutFile, "%s", pOut -> pBrace);
  1980.             }
  1981.         if (pFiller != NULL)
  1982.             {
  1983.             fprintf (pOutFile, "%s", pFiller);
  1984.             delete pFiller;
  1985.             }
  1986.         if (pOut -> pComment != NULL)
  1987.             fprintf (pOutFile, "%s", pOut -> pComment);
  1988.         //        fputc (LF, pOutFile); // output line feed!
  1989.         ////////////////////////////////////////////////////////////////////////
  1990.         // Fixed for DOS CR/LF
  1991.         // nitin@poboxes.com
  1992.         ////////////////////////////////////////////////////////////////////////
  1993.         if ( userS.dosLines == True )
  1994.             fputc (CR, pOutFile);                 // output line feed!
  1995.         fputc (LF, pOutFile);                     // output line feed!
  1996.         // fprintf ( pOutFile, "\r\n" );
  1997.         // free memory
  1998.         delete pOut;
  1999.         }
  2000.     return pLines;
  2001. }
  2002.  
  2003.  
  2004. // ----------------------------------------------------------------------------
  2005. // ----------------------------------------------------------------------------
  2006. // ----------------------------------------------------------------------------
  2007. // Function will backspace the desired characters length according to
  2008. // numeric size.
  2009. void backSpaceIt (unsigned long int num)
  2010. {
  2011.     unsigned long int size = 1;
  2012.     while (num >= size)
  2013.         {
  2014.         printf ("\b");
  2015.         size = size * 10;
  2016.         }
  2017.     printf ("\b");                                // remove the trail zero, or space !
  2018. }
  2019.  
  2020.  
  2021. // Parameters:
  2022. // mode      : 1 = set new time, 2 = compare current time with now time
  2023. unsigned long int GetStartEndTime (int mode)
  2024. {
  2025.     static time_t newTime;
  2026.     switch (mode)
  2027.         {
  2028.         case (1):
  2029.             newTime = time (NULL);
  2030.             return 0;
  2031.         case (2):
  2032.             return (time (NULL) - newTime);
  2033.         }
  2034.     return 0;
  2035. }
  2036.  
  2037.  
  2038. // ----------------------------------------------------------------------------
  2039. // Function is used to bundle all of the input, and output line processing
  2040. // functions together to create a final output file.
  2041. //
  2042. // Parameters:
  2043. // pInFile    : Pointer to the user's input FILE structure/handle.
  2044. // pOutFile   : Pointer to the user's output FILE structure/handle.
  2045. // userS      : User's configuration settings.
  2046. //
  2047. // Return Values:
  2048. // int        : Returns a value indicating whether there were any problems
  2049. //              in processing the input/output files.
  2050. //               0 = no worries.
  2051. //              -1 = memory allocation failure, or line construction failure
  2052. //
  2053. int ProcessFile (FILE* pInFile, FILE* pOutFile, const Config& userS)
  2054. {
  2055.     const    char* errorMsg = "\n\n#### ERROR ! Memory Allocation Failed\n";
  2056.     // line number update period (show every 10 lines)
  2057.     const    int        lineStep     = 10;
  2058.     unsigned long int   lineNo       = 0;
  2059.     // Var used by readline() to show eof has been reached
  2060.     int                 EndOfFile    = 0;
  2061.     char*               pData;
  2062.     // var used to test existance of multiline C Comments
  2063.     Boolean             CComments    = False;
  2064.     // var used for brace spacing
  2065.     int                 indentStack  = 0;
  2066.     QueueList*          pOutputQueue = new QueueList();
  2067.     StackList*          pIMode       = new StackList();
  2068.     QueueList*          pInputQueue  = new QueueList();
  2069.     // variable used in processing function spacing !
  2070.     int                 FuncVar      = 0;
  2071.     // Check memory allocated !
  2072.     if (((pOutputQueue == NULL) || (pIMode == NULL)) || (pInputQueue == NULL))
  2073.         {
  2074.         delete pOutputQueue;
  2075.         delete pInputQueue;
  2076.         delete pIMode;
  2077.         printf ("%s", errorMsg);
  2078.         return -1;
  2079.         }
  2080.     if (userS.output != False)
  2081.         {
  2082.         printf ("\nFeed Me, Feed Me Code ...\n");
  2083.         printf ("Number Of Lines Processed :  ");
  2084.         }
  2085.     GetStartEndTime (1);                          // lets time the operation !
  2086.     while (! EndOfFile)
  2087.         {
  2088.         pData = ReadLine (pInFile, EndOfFile);
  2089.         ////////////////////////////////////////////////////////////////////////
  2090.         // Fell into this Bad Trap, after the CR/LF hacks :)
  2091.         // Added specific check for EOF
  2092.         // nitin@poboxes.com
  2093.         ////////////////////////////////////////////////////////////////////////
  2094.         if ((pData != NULL) && (EndOfFile != EOF) )
  2095.             {
  2096.             lineNo++;
  2097.             if ( (lineNo % lineStep == 0) && (userS.output != False) )
  2098.                 {
  2099.                 if (lineNo > 0)
  2100.                     // reposition cursor ! Don't used gotoxy() for Unix compatibility
  2101.                     backSpaceIt (lineNo - lineStep);
  2102.                 printf ("%ld ", lineNo);
  2103.                 }
  2104.             if (userS.deleteHighChars != 0)
  2105.                 pData = StripNonPrintables (pData, userS.deleteHighChars, userS.quoteChars);
  2106.             pData = ExpandTabs (pData, userS.tabSpaceSize);
  2107.             if (pData == NULL)
  2108.                 {
  2109.                 printf ("%s", errorMsg);
  2110.                 delete pIMode;
  2111.                 delete pInputQueue;
  2112.                 delete pOutputQueue;
  2113.                 return -1;
  2114.                 }
  2115.             // if there are input items to process
  2116.             if (DecodeLine (pData, CComments, pInputQueue) == 0)
  2117.                 {
  2118.                 int errorCode = ConstructLine (indentStack, pInputQueue, pOutputQueue, userS);
  2119.                 switch (errorCode)
  2120.                     {
  2121.                     case (0)  : break;
  2122.                     case (-1) :
  2123.                         {
  2124.                         fprintf (stderr, "%s", errorMsg);
  2125.                         delete pIMode;
  2126.                         delete pInputQueue;
  2127.                         delete pOutputQueue;
  2128.                         return errorCode;
  2129.                         }
  2130.                     case (-2):                    // Construct line failed !
  2131.                         {
  2132.                         // output final line position
  2133.                         fprintf (stderr, "\nLast Line Read %d", lineNo);
  2134.                         delete pIMode;
  2135.                         delete pInputQueue;
  2136.                         delete pOutputQueue;
  2137.                         return errorCode;
  2138.                         }
  2139.                     default:
  2140.                         {
  2141.                         fprintf (stderr, "\nSomething Weird %d\n", errorCode);
  2142.                         return errorCode;
  2143.                         }
  2144.                     }
  2145.                 pOutputQueue = OutputToOutFile (pOutFile, pOutputQueue,
  2146.                 pIMode  , FuncVar,
  2147.                 userS   , userS.queueBuffer );
  2148.                 if (pOutputQueue == NULL)
  2149.                     {
  2150.                     fprintf (stderr, "%s", errorMsg);
  2151.                     delete pIMode;
  2152.                     delete pInputQueue;
  2153.                     return -1;                    // memory allocation error !
  2154.                     }
  2155.                 }
  2156.             }                                         // if there's data available
  2157.         }                                             // while data
  2158.     // flush queue ...
  2159.     pOutputQueue = OutputToOutFile (pOutFile, pOutputQueue,
  2160.     pIMode,   FuncVar,
  2161.     userS,    0);
  2162.     // output final line position
  2163.     if (userS.output != False)
  2164.         {
  2165.         if ((lineNo > 0) && (lineNo > lineStep))
  2166.             // reposition cursor
  2167.             backSpaceIt (lineNo - (lineNo % lineStep));
  2168.         printf ("%ld ", lineNo);
  2169.         }
  2170.     delete pIMode;
  2171.     delete pOutputQueue;
  2172.     delete pInputQueue;
  2173.     delete pData;
  2174.     if (userS.output != False)
  2175.         {
  2176.         unsigned long int t = GetStartEndTime (2);
  2177.         int    hours = (t / 60) / 60,
  2178.         mins  = (t / 60),
  2179.         secs  = (t % 60);
  2180.         printf ("(In %d Hours %d Minutes %d Seconds)", hours, mins, secs);
  2181.         }
  2182.     return 0;
  2183. }
  2184.  
  2185.  
  2186. // Function creates a backup of pInFile, by opening a
  2187. // new file with a ".bac" extenstion and copying the original
  2188. // data into it.
  2189. //
  2190. int BackupFile (char*& pInFile, char*& pOutFile)
  2191. {
  2192.     const char* pBackUp    = ".bac";
  2193.     pOutFile               = pInFile;
  2194.     pInFile                = new char[strlen(pOutFile)+5];
  2195.     char*    pLook         = NULL;
  2196.     FILE*    pInputFile    = NULL;
  2197.     FILE*    pOutputFile   = NULL;
  2198.     if (pInFile == NULL)
  2199.         return -1;
  2200.     strcpy (pInFile, pOutFile);
  2201.     // change input filename !
  2202.     pLook = pInFile + (strlen (pInFile)-1);
  2203.     while ( ((*pLook != '.')  && (pLook > pInFile)) &&
  2204.         ((*pLook != '\\') && (*pLook != '/')) )
  2205.     pLook--;
  2206.     if  ((pLook <= pInFile) || ((*pLook == '\\') || (*pLook == '/')))
  2207.         strcpy (pInFile + (strlen (pInFile) - 1), pBackUp);
  2208.     else
  2209.         strcpy (pLook, pBackUp);
  2210.     // implement custom backup routine as one is NOT provided as standard !
  2211.     pInputFile  = fopen(pInFile,  "wb");
  2212.     pOutputFile = fopen(pOutFile, "rb");
  2213.     if ((pInputFile == NULL) || (pOutputFile == NULL))
  2214.         {
  2215.         fclose (pInputFile);
  2216.         fclose (pOutputFile);
  2217.         return -1;
  2218.         }
  2219.     int inChar = fgetc (pOutputFile);
  2220.     while (inChar >= 0)
  2221.         {
  2222.         fputc (inChar, pInputFile);
  2223.         inChar = fgetc (pOutputFile);
  2224.         }
  2225.     fclose (pInputFile);
  2226.     fclose (pOutputFile);
  2227.     return 0;
  2228. }
  2229.  
  2230.  
  2231. // ----------------------------------------------------------------------------
  2232. // Front-end to the program, it reads in the configuration file, checks if there
  2233. // were any errors, and starts processing of the files.
  2234. //
  2235. // Parameters:
  2236. // argc       : comand line parameter count
  2237. // argv[]     : array of pointers to command line parameters
  2238. //
  2239. // Return Values:
  2240. // int        : A non zero value indicates processing problem.
  2241. //
  2242. int LoadnRun (int argc, char* argv[])
  2243. {
  2244.     const char* choices[2] = { "Yes", "No" };
  2245.     const char* pNoFile    = "Couldn't Open, or Create File";
  2246.     char* pInFile          = NULL;
  2247.     char* pOutFile         = NULL;
  2248.     FILE* pInputFile       = NULL;
  2249.     FILE* pOutputFile      = NULL;
  2250.     FILE* pConfigFile      = NULL;
  2251.     int   errorNum         = 0;
  2252.     int   errorCode        = 0;
  2253. //    Config settings        = {2, 4, False, 50, 0, False, False, 3, True, True, 10, False};
  2254.     ////////////////////////////////////////////////////////////////////////
  2255.     // Now defaults for my kinda style and DOS CR/LF pairs nitin@poboxes.com
  2256.     ////////////////////////////////////////////////////////////////////////
  2257.     Config settings        = {2, 4, True, 50, 0, True, False, 0, True, True, 50, True, True, False, True };
  2258.     /* ************************************************************************************
  2259.     // set defaults
  2260.     settings.numOfLineFunc    = 2;    // number of lines between functions
  2261.     settings.tabSpaceSize     = 4;    // number of spaces a tab takes up
  2262.     settings.useTabs          = False;// use tabs to indents rather than spaces
  2263.     settings.posOfCommentsWC  = 50;   // position of comments on line with code
  2264.     settings.posOfCommentsNC  = 0;    // position of comments on line
  2265.     settings.leaveCommentsNC  = False;// True = don't change the indentation of comments with code.
  2266.     settings.quoteChars       = False;// use tabs to indents rather than spaces
  2267.     settings.deleteHighChars  = 3;    // 0  = no check         , 1 = delete high chars,
  2268.     // 3  = delete high chars, but not graphics
  2269.     settings.braceLoc         = True; // Start open braces on new line
  2270.     settings.output           = True; // Set this true for normal program output
  2271.     settings.queueBuffer      = 10;   // Set the number if lines to store in memory at a time !
  2272.     settings.backUp           = False;// backup the original file, have output file become input file name !
  2273.     ************************************************************************************ */
  2274.     // Function processes command line parameters
  2275.     // FIRST read of the command line will search for the -fnc option to
  2276.     // read the configuration file, default is bcpp.cfg at current directory
  2277.     if (ProcessCommandLine (argc, argv, settings, pInFile, pOutFile, pConfig) != 0)
  2278.         return -1;                                // problems
  2279.     // *********************************************************************
  2280.     //#### Check if want to read from configuration file !
  2281.     ////////////////////////////////////////////////////////////////////////
  2282.     // Fixed to pick up the CFG file from the program load path if it is not
  2283.     // present in the current directory
  2284.     // nitin@poboxes.com
  2285.     ////////////////////////////////////////////////////////////////////////
  2286.     if (pConfig != NULL)
  2287.         {
  2288.         pConfigFile = fopen(pConfig, "rb");
  2289.         if (pConfigFile == NULL)
  2290.             {
  2291.             strcpy( pConfigAlternate, argv[ 0 ] );
  2292.             char *pBasePath = strrchr( pConfigAlternate, '\\' );
  2293.             if ( pBasePath == NULL )
  2294.                 pBasePath = strrchr( pConfigAlternate, '/' );
  2295.             else
  2296.                 {
  2297.                 *(pBasePath+1) = 0;
  2298.                 strcat( pConfigAlternate, "bcpp.cfg" );
  2299.                 pConfig = pConfigAlternate;
  2300.                 pConfigFile = fopen(pConfig, "rb");
  2301.                 }
  2302.             }
  2303.         // LOAD CONFIG FILE !
  2304.         if ( pConfigFile )
  2305.             errorNum = SetConfig (pConfigFile, settings);
  2306.         else
  2307.             {
  2308.             fprintf (stderr, "\nCouldn't Open Config File %s\n", pConfig );
  2309.             fprintf (stderr, "Read Docs For Configuration Settings\n");
  2310.             // errorCode = -1; // dont quit as use command line settings !
  2311.             }
  2312.         // If output is via stdout, then turn out program output if it's
  2313.         // set within config file !
  2314.         if (pOutputFile == stdout)
  2315.             settings.output = False;
  2316.         if (settings.output != False)
  2317.             fprintf (stderr, "\n%d Errors In %s Config File.\n\n", errorNum, pConfig );
  2318.         }
  2319.     // *********************************************************************
  2320.     // SECOND read of the command line will overwrite seetings that may will
  2321.     // to be changed by the command. Lots of processing to over this process,
  2322.     // but hey it's a easy solution !
  2323.     pInFile = pOutFile = NULL;                    // reset these so they can re-assigned again !
  2324.     if (ProcessCommandLine (argc, argv, settings, pInFile, pOutFile, pConfig) != 0)
  2325.         return -1;                                // problems
  2326.     // *********************************************************************
  2327.     // backup original filename!
  2328.     if ((settings.backUp != False) && (pInFile != NULL))
  2329.         {
  2330.         if (settings.output != False)
  2331.             printf ("Please Wait, Backing Up Data ... ");
  2332.         if (BackupFile (pInFile, pOutFile) != 0)
  2333.             return -1;
  2334.         if (settings.output != False)
  2335.             printf ("Done!\n\n");
  2336.         }
  2337.     // **************************************************************
  2338.     // assign I/O streams
  2339.     if (pInFile == NULL)
  2340.         pInputFile = stdin;
  2341.     else
  2342.         pInputFile = fopen(pInFile, "rb");
  2343.     if (pOutFile == NULL)
  2344.         {
  2345.         pOutputFile     = stdout;
  2346.         // if using standard out, don't currupt output
  2347.         settings.output = False;
  2348.         }
  2349.     else
  2350.         pOutputFile = fopen(pOutFile, "wb");
  2351.     // Check user defined I/O streams
  2352.     if (pInputFile == NULL)
  2353.         {
  2354.         fprintf (stderr, "%s %s\n", pNoFile, pInFile);
  2355.         errorCode = -1;
  2356.         }
  2357.     if (pOutputFile == NULL)
  2358.         {
  2359.         fprintf (stderr, "%s %s\n", pNoFile, pOutFile);
  2360.         errorCode = -1;
  2361.         }
  2362.     // **************************************************************
  2363.     if ((settings.output != False) && (errorCode == 0))
  2364.         {
  2365.         printf ("Function Line Spacing              : %d\n", settings.numOfLineFunc);
  2366.         printf ("Use Tabs In Indenting              : %s\n", choices[settings.useTabs+1]);
  2367.         printf ("Indent Spacing Length              : %d\n", settings.tabSpaceSize);
  2368.         printf ("Comments With Code                 : %d\n", settings.posOfCommentsWC);
  2369.         if (settings.leaveCommentsNC != False)
  2370.             printf ("Comments With No Code              : Indented According To Code\n");
  2371.         else
  2372.             printf ("Comments With No Code              : %d\n", settings.posOfCommentsNC);
  2373.         printf ("Remove Non-ASCII Chars             : ");
  2374.         switch (settings.deleteHighChars)
  2375.             {
  2376.             case (0):
  2377.                 printf ("No\n");
  2378.                 break;
  2379.             case (1):
  2380.                 printf ("Yes\n");
  2381.                 break;
  2382.             case (3):
  2383.                 printf ("Yes But Not Graphic Chars\n");
  2384.                 break;
  2385.             default:
  2386.                 fprintf (stderr, "#### ERROR : Unexpected Value %d", settings.deleteHighChars);
  2387.                 errorNum++;
  2388.             }
  2389.         printf ("Non-Ascii Chars In Quotes To Octal : %s\n", choices[settings.quoteChars+1]);
  2390.         printf ("Open Braces On New Line            : %s\n", choices[settings.braceLoc+1]);
  2391.         printf ("Program Output                     : %s\n", choices[settings.output+1]);
  2392.         printf ("Internal Queue Buffer Size         : %d\n", settings.queueBuffer);
  2393.         if (errorNum > 0)
  2394.             {
  2395.             fprintf (stderr, "\nDo You Wish To Continue To Process %s File [Y/N] ?", pInFile);
  2396.             int userKey = 0;
  2397.             do
  2398.                 {
  2399.                 userKey = getc(stdin);
  2400.                 // change key to upper case!
  2401.                 userKey = (userKey & 223);
  2402.                 if (userKey == 'Y')
  2403.                     errorNum = 0;
  2404.                 } while ((userKey != 'Y') && (userKey != 'N'));
  2405.             }
  2406.         }                                             // display user settings !
  2407.     if (pConfigFile != NULL)
  2408.         fclose (pConfigFile);
  2409.     // #### Lets do some code crunching !
  2410.     if ((errorNum == 0) && (errorCode == 0))
  2411.         errorCode = ProcessFile (pInputFile, pOutputFile, settings);
  2412.     if (settings.output != False)
  2413.         printf ("\nCleaning Up Dinner ... ");
  2414.     if (pInputFile != NULL)
  2415.         fclose (pInputFile);
  2416.     if (pOutputFile != NULL)
  2417.         fclose (pOutputFile);
  2418.     if (settings.output != False)
  2419.         printf ("Done !\n");
  2420.     return errorCode;
  2421. }
  2422.  
  2423.  
  2424. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  2425. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  2426. int main (int argc, char* argv[])
  2427. {
  2428.     return LoadnRun (argc, argv);
  2429. }
  2430.  
  2431.  
  2432. // The End :-).
  2433.