1 #ifndef _CMDLINE_CODE
2 #define _CMDLINE_CODE
3 
4 // $Id: cmdline.cpp,v 1.26 2021/01/08 23:22:26 tom Exp $
5 // Program C(++) Beautifier Written By Steven De Toni ACBC 11 12/94
6 // Revised 1999 - Thomas Dickey
7 //
8 // This module contains methods to parse the command line.
9 
10 #include <stdlib.h>   // atoi()
11 #include <ctype.h>
12 #include <string.h>   // strcmp()
13 
14 #include "bcpp.h"
15 #include "cmdline.h"  // prototypes
16 
17 // Function converts a lower case string into upper case, any special
18 // characters remain the same (i.e "$", "%" ...)
StrUpr(char * pUpCase)19 void StrUpr (char* pUpCase)
20 {
21      while (*pUpCase != '\0')
22      {
23           if (isalpha(*pUpCase) && islower(*pUpCase))
24                   *pUpCase = toupper(*pUpCase);
25           pUpCase++;
26      }
27 }
28 
29 // This function displays brief command line help to the user.
30 // Parameters:
31 // char* argv[]     : Pointer to command line parameter pointer array
32 //
PrintProgramHelp(void)33 void PrintProgramHelp (void)
34 {
35     static const char *help[] = {
36         "C(++) Beautifier     " VERSION,
37         "",
38         "Program Was Written By Steven De Toni, December 1995",
39         "Modified/revised by Thomas E. Dickey 1996-2003,2004",
40         "All Parts Of This Program Are Freely Distributable.",
41         "",
42         "Usage: bcpp [Parameters] [Input File Name] [Output File Name]",
43         "",
44         "Options:",
45         "",
46         "[-bcl] [-bnl] [-cc <num>] [-f <num>] [-fi <string>] [-fnc <string>]",
47         "[-fo <string>] [-h] [-i <num>] [-lg]",
48         "[-na] [-nb] [-nbbi] [-nbi] [-nc] [-nkcwc] [-nlcnc] [-no] [-nq]",
49         "[-qb] [-s] [-t]",
50         "[-ya] [-yb] [-ybbi] [-ybi] [-ykcwc] [-ylcnc] [-yo] [-yq]",
51         "[<string>] [<string>]",
52         "",
53         "[] = Optional <> = Parameter Requirement",
54         "",
55         "* Support For I/O Redirection Is Provided *",
56     };
57     unsigned n;
58     for (n = 0; n < TABLESIZE(help); n++)
59         verbose("%s\n", help[n]);
60 
61     if (prompt("More Detail"))
62     {
63         static const char *details[] = {
64             "-bcl          : Open braces on code line",
65             "-bnl          : Open braces on new line",
66             "-cc  <num>    : Column to align comments with code",
67             "-f   <num>    : Function line spacing",
68             "-fi <string>  : Input file name",
69             "-fnc <string> : Load custom configuration file",
70             "-fo <string>  : Output file name",
71             "-h    or   -? : This help message",
72             "-i   <num>    : Indent space length",
73             "-lg           : Leave graphic chars",
74             "-nc  <num>    : Column to align comments with no code",
75             "-qb  <num>    : Define internal queue buffer size",
76             "-s            : Use spaces in indenting",
77             "-t            : Use tabs in indenting",
78             "-tbcl         : Top-level open braces on code line",
79             "-tbnl         : Top-level open braces on new line",
80             "",
81             "Options beginning with -n or -y disable/enable functions:",
82             "  a           : Remove non-ASCII chars",
83             "  b           : Backup input file with .bac extension",
84             "  bbi         : Indent both braces of a block",
85             "  bi          : Indent trailing brace of block",
86             "  kcwc        : Keep comments with Code",
87             "  lcnc        : Leave comments with NoCode",
88             "  o           : Program output",
89             "  q           : Change non-ASCII chars in quotes to octal",
90         };
91         for (n = 0; n < TABLESIZE(details); n++)
92             verbose("%s\n", details[n]);
93     }
94 }
95 
96 // integer assignment
intOption(int & cmdCount,int argc,char * argv[],int & result)97 static void intOption (int& cmdCount, int argc, char* argv[], int &result )
98 {
99     if (++cmdCount <= (argc-1))
100     {
101         result = atoi (argv[cmdCount]);
102     }
103     else
104     {
105         warning ("Expected Another Integer Parameter For Command Directive %s\n", argv[cmdCount]);
106         PrintProgramHelp ();
107     }
108 }
109 
110 // string assignment
strOption(int & cmdCount,int argc,char * argv[],char * & result)111 static void strOption (int& cmdCount, int argc, char* argv[], char * &result)
112 {
113     if (++cmdCount <= (argc-1))
114     {
115         result = argv[cmdCount];
116     }
117     else
118     {
119         warning ("Expected Another String Parameter For Command Directive %s\n", argv[cmdCount]);
120         PrintProgramHelp ();
121     }
122 }
123 
124 #define DecodeFlg(option, flag, value) \
125             if (strcmp (option, cmdRead) == 0) \
126             { \
127                 flag = value; \
128                 continue; \
129             }
130 
131 #define DecodeInt(option, flag) \
132             if (strcmp (option, cmdRead) == 0) \
133             { \
134                 intOption (cmdCount, argc, argv, flag); \
135                 continue; \
136             }
137 
138 #define DecodeStr(option, flag) \
139             if (strcmp (option, cmdRead) == 0) \
140             { \
141                 strOption (cmdCount, argc, argv, flag); \
142                 continue; \
143             }
144 
145 // Function processes command line parameters
ProcessCommandLine(int argc,char * argv[],Config & settings,char * & pInFile,char * & pOutFile,char * & pConfig)146 int ProcessCommandLine (int argc, char* argv[], Config& settings,
147                         char*& pInFile, char*& pOutFile, char*& pConfig)
148 {
149 
150     int   cmdCount = 0;
151     char* cmdRead;
152 
153     while (cmdCount < argc-1)
154     {
155         // command line error
156         if (cmdCount < 0)
157            return cmdCount;
158 
159         // next command to process!
160         cmdCount++;
161         cmdRead = argv[cmdCount];
162 
163         // this is a command directive
164         if (cmdRead[0] == '-')
165         {
166             // upcase the command parameter
167             StrUpr (cmdRead);
168 
169             cmdRead++;
170 
171             // miscellaneous flags, "sort +1"
172             DecodeFlg ("BCL",   settings.braceLoc,        false);
173             DecodeFlg ("BNL",   settings.braceLoc,        true);
174             DecodeInt ("CC",    settings.posOfCommentsWC);
175             DecodeInt ("F",     settings.numOfLineFunc);
176             DecodeStr ("FI",    pInFile);
177             DecodeStr ("FNC",   pConfig);
178             DecodeStr ("FO",    pOutFile);
179             DecodeInt ("I",     settings.tabSpaceSize);
180             DecodeFlg ("LG",    settings.deleteHighChars, 3);
181             DecodeInt ("NC",    settings.posOfCommentsNC);
182             DecodeInt ("QB",    settings.queueBuffer);
183             DecodeFlg ("S",     settings.useTabs,         false);
184             DecodeFlg ("T",     settings.useTabs,         true);
185             DecodeFlg ("TBCL",  settings.topBraceLoc,     false);
186             DecodeFlg ("TBNL",  settings.topBraceLoc,     true);
187 
188             // "No" flags
189             DecodeFlg ("NA",    settings.deleteHighChars, 0);
190             DecodeFlg ("NB",    settings.backUp,          false);
191             DecodeFlg ("NBBI",  settings.braceIndent2,    false);
192             DecodeFlg ("NBI",   settings.braceIndent,     false);
193             DecodeFlg ("NLCNC", settings.leaveCommentsNC, false);
194             DecodeFlg ("NO",    settings.output,          false);
195             DecodeFlg ("NQ",    settings.quoteChars,      false);
196 
197             // "Yes" flags
198             DecodeFlg ("YA",    settings.deleteHighChars, 1);
199             DecodeFlg ("YB",    settings.backUp,          true);
200             DecodeFlg ("YBBI",  settings.braceIndent2,    true);
201             DecodeFlg ("YBI",   settings.braceIndent,     true);
202             DecodeFlg ("YLCNC", settings.leaveCommentsNC, true);
203             DecodeFlg ("YO",    settings.output,          true);
204             DecodeFlg ("YQ",    settings.quoteChars,      true);
205 
206             // ### display help ###
207             if( (strcmp ("?", cmdRead) == 0) ||
208                 (strcmp ("H", cmdRead) == 0) )
209             {
210                 verbose ("*** Displaying Brief Help ***\n");
211                 PrintProgramHelp ();
212                 return -1;
213             }
214 
215             warning ("Unknown Command Directive %s \n", cmdRead);
216             PrintProgramHelp ();
217             return -1;
218         }
219         else if (pInFile == NULL)
220                 pInFile  = argv [cmdCount];
221         else if (pOutFile == NULL)
222                 pOutFile = argv [cmdCount];
223         else
224         {
225             warning ("Command Line Error : Expected Command Directive, Not %s\n", argv[cmdCount]);
226             PrintProgramHelp ();
227             return -1;
228         }
229     }
230 
231     if (settings.queueBuffer < 2)
232         settings.queueBuffer = 2;
233     return 0;
234 }
235 
236 #endif //_CMDLINE_CODE
237