瀏覽代碼

Merge branch 'master' of klarke.webfactional.com:webapps/git/repos/libcm

master
kevin 11 年之前
父節點
當前提交
7bfa8a109e
共有 7 個檔案被更改,包括 441 行新增120 行删除
  1. 59
    0
      cmFile.c
  2. 4
    0
      cmFile.h
  3. 51
    6
      cmFileSys.c
  4. 12
    10
      cmFileSys.h
  5. 238
    72
      cmPgmOpts.c
  6. 51
    26
      cmPgmOpts.h
  7. 26
    6
      cmRpt.c

+ 59
- 0
cmFile.c 查看文件

193
   return sr.st_size;
193
   return sr.st_size;
194
 }
194
 }
195
 
195
 
196
+cmFileRC_t   cmFileByteCountFn( const cmChar_t* fn, cmRpt_t* rpt, unsigned* fileByteCntPtr )
197
+{
198
+  assert( fileByteCntPtr != NULL );
199
+  cmFileRC_t rc;
200
+  cmFileH_t h = cmFileNullHandle;
201
+  if((rc = cmFileOpen(&h,fn,kReadFileFl,rpt)) != kOkFileRC )
202
+    return rc;
203
+
204
+  if( fileByteCntPtr != NULL)
205
+    *fileByteCntPtr = cmFileByteCount(h);
206
+
207
+  cmFileClose(&h);
208
+
209
+  return rc;    
210
+}
211
+
212
+cmFileRC_t cmFileCompare( const cmChar_t* fn0, const cmChar_t* fn1, cmRpt_t* rpt, bool* isEqualPtr )
213
+{
214
+  cmFileRC_t rc         = kOkFileRC;
215
+  unsigned   bufByteCnt = 2048;
216
+  cmFileH_t  h0         = cmFileNullHandle;
217
+  cmFileH_t  h1         = cmFileNullHandle;
218
+
219
+  char       b0[ bufByteCnt ];
220
+  char       b1[ bufByteCnt ];
221
+
222
+  assert(isEqualPtr != NULL );
223
+  *isEqualPtr = true;
224
+
225
+  if((rc = cmFileOpen(&h0,fn0,kReadFileFl,rpt)) != kOkFileRC )
226
+    goto errLabel;
227
+
228
+  if((rc = cmFileOpen(&h1,fn1,kReadFileFl,rpt)) != kOkFileRC )
229
+    goto errLabel;
230
+
231
+  cmFile_t*   p0 = _cmFileHandleToPtr(h0);
232
+  cmFile_t*   p1 = _cmFileHandleToPtr(h1);
233
+
234
+  while(1)
235
+  {
236
+    size_t n0 = fread(b0,1,bufByteCnt,p0->fp);
237
+    size_t n1 = fread(b1,1,bufByteCnt,p1->fp);
238
+    if( n0 != n1 || memcmp(b0,b1,n0)!=0 )
239
+    {
240
+      *isEqualPtr = false;
241
+      break;
242
+    }
243
+
244
+    if( n0 != bufByteCnt || n1 != bufByteCnt )
245
+      break;
246
+  }
247
+
248
+ errLabel:
249
+  cmFileClose(&h0);
250
+  cmFileClose(&h1);
251
+  return rc;
252
+}
253
+
254
+
196
 const cmChar_t* cmFileName( cmFileH_t h )
255
 const cmChar_t* cmFileName( cmFileH_t h )
197
 {
256
 {
198
   cmFile_t* p = _cmFileHandleToPtr(h);
257
   cmFile_t* p = _cmFileHandleToPtr(h);

+ 4
- 0
cmFile.h 查看文件

89
 
89
 
90
   // Return the length of the file in bytes
90
   // Return the length of the file in bytes
91
   unsigned   cmFileByteCount(  cmFileH_t h );
91
   unsigned   cmFileByteCount(  cmFileH_t h );
92
+  cmFileRC_t cmFileByteCountFn( const cmChar_t* fn, cmRpt_t* rpt, unsigned* fileByteCntPtr );
93
+
94
+  // Set *isEqualPtr=true if the two files are identical.
95
+  cmFileRC_t cmFileCompare( const cmChar_t* fn0, const cmChar_t* fn1, cmRpt_t* rpt, bool* isEqualFlPtr );
92
 
96
 
93
   // Return the file name associated with a file handle.
97
   // Return the file name associated with a file handle.
94
   const cmChar_t* cmFileName( cmFileH_t h );
98
   const cmChar_t* cmFileName( cmFileH_t h );

+ 51
- 6
cmFileSys.c 查看文件

273
   struct stat s;
273
   struct stat s;
274
   errno = 0;
274
   errno = 0;
275
 
275
 
276
-  if( stat(fnStr,&s)  != 0 )
276
+  if( lstat(fnStr,&s)  != 0 )
277
   {
277
   {
278
 
278
 
279
     // if the file does not exist
279
     // if the file does not exist
294
   return _cmFileSysIsLink(p,fnStr);
294
   return _cmFileSysIsLink(p,fnStr);
295
 }
295
 }
296
 
296
 
297
+bool _cmFileSysIsSocket( cmFs_t* p, const cmChar_t* fnStr )
298
+{
299
+  struct stat s;
300
+  errno = 0;
301
+
302
+  if( stat(fnStr,&s)  != 0 )
303
+  {
304
+
305
+    // if the file does not exist
306
+    if( errno == ENOENT )
307
+      return false;
308
+
309
+    _cmFileSysError( p, kStatFailFsRC, errno, "'stat' failed on '%s'.",fnStr);
310
+    return false;
311
+  }
312
+ 
313
+  return S_ISSOCK(s.st_mode);
314
+}
315
+
316
+
297
 bool _cmFileSysConcat( cmChar_t* rp, unsigned rn, char sepChar, const cmChar_t* suffixStr )
317
 bool _cmFileSysConcat( cmChar_t* rp, unsigned rn, char sepChar, const cmChar_t* suffixStr )
298
 {
318
 {
299
   unsigned m = strlen(rp);
319
   unsigned m = strlen(rp);
777
   cmFs_t*              p;
797
   cmFs_t*              p;
778
   unsigned             filterFlags;
798
   unsigned             filterFlags;
779
   cmFileSysDirEntry_t* rp;
799
   cmFileSysDirEntry_t* rp;
780
-  cmChar_t*                dataPtr;
781
-  cmChar_t*                endPtr;
800
+  cmChar_t*            dataPtr;
801
+  cmChar_t*            endPtr;
782
   unsigned             entryCnt;
802
   unsigned             entryCnt;
783
   unsigned             entryIdx;
803
   unsigned             entryIdx;
784
   unsigned             dataByteCnt;
804
   unsigned             dataByteCnt;
798
   if( dirStr == NULL || strlen(dirStr) == 0 )
818
   if( dirStr == NULL || strlen(dirStr) == 0 )
799
     dirStr = curDirPtr;
819
     dirStr = curDirPtr;
800
 
820
 
821
+  if( _cmFileSysIsDir(drp->p,dirStr) == false )
822
+    return rc;
823
+
801
   unsigned       fnCharCnt= strlen(dirStr) + PATH_MAX;
824
   unsigned       fnCharCnt= strlen(dirStr) + PATH_MAX;
802
   char           fn[ fnCharCnt + 1 ];
825
   char           fn[ fnCharCnt + 1 ];
803
 
826
 
821
   if((dirp = opendir(dirStr)) == NULL)
844
   if((dirp = opendir(dirStr)) == NULL)
822
   {
845
   {
823
     rc = _cmFileSysError(drp->p,kOpenDirFailFsRC,errno,"Unable to open the directory:'%s'.",dirStr);
846
     rc = _cmFileSysError(drp->p,kOpenDirFailFsRC,errno,"Unable to open the directory:'%s'.",dirStr);
847
+
824
     goto errLabel;
848
     goto errLabel;
825
   }
849
   }
826
 
850
 
827
-
828
   // get the next directory entry
851
   // get the next directory entry
829
   while((dp = readdir(dirp)) != NULL )
852
   while((dp = readdir(dirp)) != NULL )
830
   {
853
   {
873
         goto errLabel;
896
         goto errLabel;
874
       }
897
       }
875
 
898
 
899
+
876
       // is the entry a file
900
       // is the entry a file
877
       if( _cmFileSysIsFile(drp->p,fn) )
901
       if( _cmFileSysIsFile(drp->p,fn) )
878
       {
902
       {
895
             if((rc = _cmFileSysDirGetEntries(drp,fn)) != kOkFsRC )
919
             if((rc = _cmFileSysDirGetEntries(drp,fn)) != kOkFsRC )
896
               goto errLabel;
920
               goto errLabel;
897
         }
921
         }
922
+        else
923
+        {
924
+          if( _cmFileSysIsLink(drp->p,fn) )
925
+          {
926
+            if( cmIsFlag(drp->filterFlags,kLinkFsFl) == false )
927
+              continue;
928
+
929
+            flags |= kLinkFsFl;
930
+
931
+            if( cmIsFlag(drp->filterFlags,kRecurseLinksFsFl) )
932
+              if((rc = _cmFileSysDirGetEntries(drp,fn)) != kOkFsRC )
933
+                goto errLabel;
934
+          }
935
+          else
936
+          {
937
+            continue;
938
+          }
939
+        }
898
       }
940
       }
899
 
941
 
900
-      assert(flags != 0);
942
+      //assert(flags != 0);
901
 
943
 
902
       if( drp->passIdx == 0 )
944
       if( drp->passIdx == 0 )
903
       {
945
       {
941
   }
983
   }
942
 
984
 
943
  errLabel:
985
  errLabel:
986
+  if( dirp != NULL )
987
+    closedir(dirp);
988
+
944
   return rc;
989
   return rc;
945
 }
990
 }
946
 
991
 
962
     if((rc = _cmFileSysDirGetEntries( &r, dirStr )) != kOkFsRC )
1007
     if((rc = _cmFileSysDirGetEntries( &r, dirStr )) != kOkFsRC )
963
       goto errLabel;
1008
       goto errLabel;
964
 
1009
 
965
-    if( r.passIdx == 0 )
1010
+    if( r.passIdx == 0 && r.dataByteCnt>0 )
966
     {
1011
     {
967
       // allocate memory to hold the return values
1012
       // allocate memory to hold the return values
968
       if(( r.rp = (cmFileSysDirEntry_t *)cmLHeapAllocZ( r.p->heapH, r.dataByteCnt )) == NULL )
1013
       if(( r.rp = (cmFileSysDirEntry_t *)cmLHeapAllocZ( r.p->heapH, r.dataByteCnt )) == NULL )

+ 12
- 10
cmFileSys.h 查看文件

146
   // Flags used by cmFileSysDirEntries 'includeFlags' parameter.
146
   // Flags used by cmFileSysDirEntries 'includeFlags' parameter.
147
   enum
147
   enum
148
   {
148
   {
149
-    kFileFsFl      = 0x01,  //< include all visible files
150
-    kDirFsFl       = 0x02,  //< include all visible directory 
151
-    kInvisibleFsFl = 0x04,  //< include file/dir name beginning with a '.'
152
-    kCurDirFsFl    = 0x08,  //< include '.' directory
153
-    kParentDirFsFl = 0x10,  //< include '..' directory
154
-
155
-    kAllFsFl       = 0x1f,  //< all type flags
156
-
157
-    kFullPathFsFl = 0x40, //< return the full path in the 'name' field of cmFileSysDirEntry_t;
158
-    kRecurseFsFl  = 0x80  //< recurse into directories
149
+    kFileFsFl         = 0x001,   //< include all visible files
150
+    kDirFsFl          = 0x002,   //< include all visible directory 
151
+    kLinkFsFl         = 0x004,   //< include all symbolic links
152
+    kInvisibleFsFl    = 0x008,   //< include file/dir name beginning with a '.'
153
+    kCurDirFsFl       = 0x010,   //< include '.' directory
154
+    kParentDirFsFl    = 0x020,   //< include '..' directory
155
+
156
+    kAllFsFl          = 0x02f,   //< all type flags
157
+
158
+    kFullPathFsFl     = 0x040,   //< return the full path in the 'name' field of cmFileSysDirEntry_t;
159
+    kRecurseFsFl      = 0x080,   //< recurse into directories
160
+    kRecurseLinksFsFl = 0x100    //< recurse into symbol link directories 
159
 
161
 
160
   };
162
   };
161
 
163
 

+ 238
- 72
cmPgmOpts.c 查看文件

6
 #include "cmMallocDebug.h"
6
 #include "cmMallocDebug.h"
7
 #include "cmLinkedHeap.h"
7
 #include "cmLinkedHeap.h"
8
 #include "cmPgmOpts.h"
8
 #include "cmPgmOpts.h"
9
+#include "cmText.h"
9
 #include "config.h"
10
 #include "config.h"
10
 
11
 
12
+enum { 
13
+  kFlagPoFl  = 0x001,
14
+  kBoolPoFl  = 0x002,  // this parameter does not take a value
15
+  kCharPoFl  = 0x004,  // parm. value is a character
16
+  kIntPoFl   = 0x008,  // parm. value is a decimal int
17
+  kUIntPoFl  = 0x010,  // parm. value is a decimal unsigned int
18
+  kDblPoFl   = 0x040,  // parm. value is a decimal double
19
+  kStrPoFl   = 0x080,  // parm. value is a string (default)
20
+  kEnumPoFl  = 0x100,  // parm. valus is a enum type (automatically set by a non-zero enumId)
21
+
22
+  kTypeMaskPoFl = 0x1ff
23
+};
24
+
11
 cmPgmOptH_t cmPgmOptNullHandle = cmSTATIC_NULL_HANDLE;
25
 cmPgmOptH_t cmPgmOptNullHandle = cmSTATIC_NULL_HANDLE;
12
 
26
 
13
 struct _cmPoArg_str;
27
 struct _cmPoArg_str;
39
   unsigned              numId;      // 
53
   unsigned              numId;      // 
40
   cmChar_t              charId;     // 
54
   cmChar_t              charId;     // 
41
   cmChar_t*             wordId;     //
55
   cmChar_t*             wordId;     //
42
-  unsigned              flags;      // 
43
-  unsigned              enumId;     //
44
-  struct _cmPoOpt_str*  enumPtr;    // pointer to mast enum recd
56
+  unsigned              sflags;     // state flags (type flags)
57
+  unsigned              cflags;     // cfg flags (user settable cfg flag)
58
+  unsigned              enumId;     // enumerated set element id (numId is the group id)
59
+  struct _cmPoOpt_str*  enumPtr;    // pointer to mast enum recd (the master is the first param. rcvd for a given enum set - so this field is NULL for the master record)
45
   unsigned              maxInstCnt; //
60
   unsigned              maxInstCnt; //
46
   _cmPoValue_t          dfltVal;    // default value for this parm 
61
   _cmPoValue_t          dfltVal;    // default value for this parm 
47
   _cmPoValPtr_t         retVal;     // client supplied variable which recieves the value of the last arg. parsed for this parm.
62
   _cmPoValPtr_t         retVal;     // client supplied variable which recieves the value of the last arg. parsed for this parm.
48
   cmChar_t*             helpStr;    //
63
   cmChar_t*             helpStr;    //
64
+  cmChar_t*             mstrStr;
49
   struct _cmPoOpt_str*  link;       // link used by the _cmPo_t.list linked list
65
   struct _cmPoOpt_str*  link;       // link used by the _cmPo_t.list linked list
50
   struct _cmPoArg_str*  inst;       // arg's belonging to this opt record formed by _cmPoArg_t.inst links
66
   struct _cmPoArg_str*  inst;       // arg's belonging to this opt record formed by _cmPoArg_t.inst links
51
 } _cmPoOpt_t;
67
 } _cmPoOpt_t;
73
   bool        execFl;       // set to false in cmPgmOptParse() if only built-in options were selected
89
   bool        execFl;       // set to false in cmPgmOptParse() if only built-in options were selected
74
 } _cmPo_t;
90
 } _cmPo_t;
75
 
91
 
92
+typedef struct
93
+{
94
+  unsigned        id;
95
+  const cmChar_t* label;
96
+} _cmPoMap_t;
97
+
98
+_cmPoMap_t _cmPoTypeMap[] = 
99
+{
100
+  { kFlagPoFl, "" },
101
+  { kBoolPoFl, "" },
102
+  { kCharPoFl, "<char>" },
103
+  { kIntPoFl,  "<int>" },
104
+  { kUIntPoFl, "<uint>" },
105
+  { kDblPoFl,  "<real>" },
106
+  { kStrPoFl,  "<text>" },
107
+  { kEnumPoFl, "<enum>" },
108
+  { 0,         "<unknown>"}
109
+};
110
+
111
+const cmChar_t* _cmPoTypeFlagToLabel( unsigned flag, unsigned cflags )
112
+{
113
+  if( cmIsFlag(cflags,kHexPoFl) )
114
+    return "<hex>";
115
+
116
+  const _cmPoMap_t* m = _cmPoTypeMap;
117
+  for(; m->id != 0; ++m)
118
+    if( m->id == flag )
119
+      break;
120
+  return m->label;
121
+}
122
+
123
+bool _cmPoOptUsesValue( const _cmPoOpt_t* r )
124
+{ 
125
+  return 
126
+    cmIsNotFlag(r->sflags,kEnumPoFl) && 
127
+    cmIsNotFlag(r->sflags,kBoolPoFl) && 
128
+    cmIsNotFlag(r->sflags,kFlagPoFl);
129
+}
130
+
76
 _cmPo_t* _cmPoHandleToPtr( cmPgmOptH_t h )
131
 _cmPo_t* _cmPoHandleToPtr( cmPgmOptH_t h )
77
 {
132
 {
78
   _cmPo_t* p = (_cmPo_t*)h.h;
133
   _cmPo_t* p = (_cmPo_t*)h.h;
107
 
162
 
108
   hp->h = p;
163
   hp->h = p;
109
 
164
 
110
-  cmPgmOptInstallBool(*hp, kPrintHelpPoId, 'h', "help",    0, false, NULL,0,"Print this usage information." );
111
-  cmPgmOptInstallBool(*hp, kVersionPoId,   'v', "version", 0, false, NULL,0,"Print version information." );
112
-  cmPgmOptInstallBool(*hp, kPrintParmsPoId,'p', "parms",   0, false, NULL,0,"Print the parameter information."); 
113
-
114
   return cmErrLastRC(&p->err);
165
   return cmErrLastRC(&p->err);
115
 }
166
 }
116
 
167
 
138
     if( r->numId == numId )
189
     if( r->numId == numId )
139
     {
190
     {
140
 
191
 
141
-      if( cmIsFlag(r->flags,kEnumPoFl) && r->enumPtr!=NULL )
192
+      if( cmIsFlag(r->sflags,kEnumPoFl) && r->enumPtr!=NULL )
142
         r = r->enumPtr;
193
         r = r->enumPtr;
143
 
194
 
144
       return r;
195
       return r;
190
 }
241
 }
191
 
242
 
192
 
243
 
193
-cmPoRC_t _cmPgmOptInstall( _cmPo_t* p, unsigned numId, const cmChar_t charId, const cmChar_t* wordId, unsigned flags, unsigned enumId, unsigned cnt, const cmChar_t* helpStr, _cmPoOpt_t** rpp )
244
+cmPoRC_t _cmPgmOptInstall( _cmPo_t* p, unsigned numId, const cmChar_t charId, const cmChar_t* wordId, unsigned cflags, unsigned sflags, unsigned enumId, unsigned cnt, const cmChar_t* helpStr, _cmPoOpt_t** rpp )
194
 {
245
 {
195
   // validate the num. id
246
   // validate the num. id
196
-  if( enumId==0 && _cmPgmOptNumIdToOptRecd(p,numId) != NULL )
247
+  if( cmIsNotFlag(sflags,kEnumPoFl) && _cmPgmOptNumIdToOptRecd(p,numId) != NULL )
197
     return cmErrMsg(&p->err,kDuplicateIdPoRC,"The numeric id '%i' was already used by another parameter.",numId);
248
     return cmErrMsg(&p->err,kDuplicateIdPoRC,"The numeric id '%i' was already used by another parameter.",numId);
198
 
249
 
199
   // validate the char. id
250
   // validate the char. id
204
   if( _cmPgmOptWordIdToOptRecd(p,wordId) != NULL )
255
   if( _cmPgmOptWordIdToOptRecd(p,wordId) != NULL )
205
     return cmErrMsg(&p->err,kDuplicateIdPoRC,"The word id --'%s' was already used by another parameter.",wordId);
256
     return cmErrMsg(&p->err,kDuplicateIdPoRC,"The word id --'%s' was already used by another parameter.",wordId);
206
 
257
 
258
+  // clear the kHexPoFl if this is not an int or uint.
259
+  if( cmIsNotFlag(sflags,kFlagPoFl) && cmIsNotFlag(sflags,kIntPoFl) && cmIsNotFlag(sflags,kUIntPoFl) )
260
+    cflags = cmClrFlag(cflags,kHexPoFl);
207
 
261
 
208
   // allocate the new parm recd
262
   // allocate the new parm recd
209
   _cmPoOpt_t* r = cmLhAllocZ( p->lH, _cmPoOpt_t, 1 );
263
   _cmPoOpt_t* r = cmLhAllocZ( p->lH, _cmPoOpt_t, 1 );
210
 
264
 
211
 
265
 
212
-  // if enumId != 0 then this is automatically an enum type.
213
-  if( enumId != 0 )
266
+  // if this is an enum type.
267
+  if( cmIsFlag(sflags,kEnumPoFl) )
214
   {
268
   {
215
-    flags = cmClrFlag(flags,kTypeMaskPoFl) | kEnumPoFl;
269
+    sflags = cmClrFlag(sflags,kTypeMaskPoFl) | kEnumPoFl;
216
 
270
 
217
     // set the master recd for this enum ptr
271
     // set the master recd for this enum ptr
218
     _cmPoOpt_t* erp;
272
     _cmPoOpt_t* erp;
221
       r->enumPtr = erp->enumPtr==NULL ? erp : erp->enumPtr;  
275
       r->enumPtr = erp->enumPtr==NULL ? erp : erp->enumPtr;  
222
 
276
 
223
       // if this child enum has it's required flags set 
277
       // if this child enum has it's required flags set 
224
-      if( cmIsFlag(flags,kReqPoFl) )
278
+      if( cmIsFlag(cflags,kReqPoFl) )
225
       {
279
       {
226
         // then set the required flag in the parent and clear it in the child
280
         // then set the required flag in the parent and clear it in the child
227
         // (this way both the parent and child will not be required (which would be impossible for an enum))
281
         // (this way both the parent and child will not be required (which would be impossible for an enum))
228
-        r->enumPtr->flags = cmSetFlag(r->enumPtr->flags,kReqPoFl);
229
-        flags = cmClrFlag(flags,kReqPoFl);
282
+        r->enumPtr->cflags = cmSetFlag(r->enumPtr->cflags,kReqPoFl);
283
+        cflags = cmClrFlag(cflags,kReqPoFl);
230
       }
284
       }
231
     }
285
     }
232
   }
286
   }
233
 
287
 
234
-  r->flags      = flags; 
288
+  r->cflags     = cflags; 
289
+  r->sflags     = sflags;
235
   r->numId      = numId;
290
   r->numId      = numId;
236
   r->charId     = charId;
291
   r->charId     = charId;
237
   r->wordId     = cmLhAllocStr( p->lH, wordId );
292
   r->wordId     = cmLhAllocStr( p->lH, wordId );
238
   r->enumId     = enumId;
293
   r->enumId     = enumId;
239
   r->maxInstCnt = cnt;
294
   r->maxInstCnt = cnt;
240
   r->helpStr    = helpStr==NULL ? NULL : cmLhAllocStr( p->lH, helpStr );
295
   r->helpStr    = helpStr==NULL ? NULL : cmLhAllocStr( p->lH, helpStr );
241
-  r->link       = p->list;
242
-  p->list       = r;
296
+
297
+
298
+  _cmPoOpt_t* rp = p->list;
299
+  while( rp != NULL && rp->link != NULL )
300
+    rp = rp->link;
301
+
302
+  if( rp == NULL )
303
+    p->list = r;
304
+  else
305
+    rp->link = r;
306
+
307
+  //r->link       = p->list;
308
+  //p->list       = r;
243
 
309
 
244
   *rpp = r;
310
   *rpp = r;
245
 
311
 
252
   _cmPoOpt_t* r     = NULL;
318
   _cmPoOpt_t* r     = NULL;
253
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
319
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
254
 
320
 
255
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kCharPoFl;
256
-
257
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, 0, cnt, helpStr, &r )) != kOkPoRC )
321
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kCharPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
258
     return rc;
322
     return rc;
259
 
323
 
260
   r->dfltVal.c = dfltVal;
324
   r->dfltVal.c = dfltVal;
272
   _cmPoOpt_t* r     = NULL;
336
   _cmPoOpt_t* r     = NULL;
273
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
337
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
274
 
338
 
275
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kBoolPoFl;
276
-
277
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, 0, cnt, helpStr, &r )) != kOkPoRC )
339
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kBoolPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
278
     return rc;
340
     return rc;
279
 
341
 
280
   r->dfltVal.b = dfltVal;
342
   r->dfltVal.b = dfltVal;
292
   _cmPoOpt_t* r     = NULL;
354
   _cmPoOpt_t* r     = NULL;
293
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
355
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
294
 
356
 
295
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kIntPoFl;
296
-
297
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, 0, cnt, helpStr, &r )) != kOkPoRC )
357
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kIntPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
298
     return rc;
358
     return rc;
299
 
359
 
300
   r->dfltVal.i = dfltVal;
360
   r->dfltVal.i = dfltVal;
312
   _cmPoOpt_t* r     = NULL;
372
   _cmPoOpt_t* r     = NULL;
313
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
373
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
314
 
374
 
315
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kUIntPoFl;
316
-
317
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, 0, cnt, helpStr, &r )) != kOkPoRC )
375
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kUIntPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
318
     return rc;
376
     return rc;
319
 
377
 
320
   r->dfltVal.u = dfltVal;
378
   r->dfltVal.u = dfltVal;
332
   _cmPoOpt_t* r     = NULL;
390
   _cmPoOpt_t* r     = NULL;
333
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
391
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
334
 
392
 
335
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kDblPoFl;
336
-
337
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, 0, cnt, helpStr, &r )) != kOkPoRC )
393
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kDblPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
338
     return rc;
394
     return rc;
339
 
395
 
340
   r->dfltVal.d = dfltVal;
396
   r->dfltVal.d = dfltVal;
352
   _cmPoOpt_t* r     = NULL;
408
   _cmPoOpt_t* r     = NULL;
353
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
409
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
354
 
410
 
355
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kStrPoFl;
356
 
411
 
357
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, 0, cnt, helpStr, &r )) != kOkPoRC )
412
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kStrPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
358
     return rc;
413
     return rc;
359
 
414
 
360
   r->dfltVal.s = dfltVal;
415
   r->dfltVal.s = dfltVal;
366
   return rc;
421
   return rc;
367
 }
422
 }
368
 
423
 
369
-cmPoRC_t cmPgmOptInstallEnum(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* wordId, unsigned flags, unsigned enumId, unsigned dfltVal, unsigned* retValPtr, unsigned cnt, const cmChar_t* helpStr  )
424
+cmPoRC_t cmPgmOptInstallEnum(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* wordId, unsigned flags, unsigned enumId, unsigned dfltVal, unsigned* retValPtr, unsigned cnt, const cmChar_t* helpStr, const cmChar_t* mstrHelpStr  )
370
 {
425
 {
371
   cmPoRC_t    rc;
426
   cmPoRC_t    rc;
372
   _cmPoOpt_t* r     = NULL;
427
   _cmPoOpt_t* r     = NULL;
373
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
428
   _cmPo_t*    p     = _cmPoHandleToPtr(h);
374
 
429
 
375
-  flags = cmClrFlag(flags,kTypeMaskPoFl) | kEnumPoFl;
376
-
377
-  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, enumId, cnt, helpStr, &r )) != kOkPoRC )
430
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kEnumPoFl, enumId, cnt, helpStr, &r )) != kOkPoRC )
378
     return rc;
431
     return rc;
379
 
432
 
380
   r->dfltVal.u = dfltVal;
433
   r->dfltVal.u = dfltVal;
383
     r->retVal.u  = retValPtr;
436
     r->retVal.u  = retValPtr;
384
     *r->retVal.u = dfltVal;
437
     *r->retVal.u = dfltVal;
385
   }
438
   }
439
+
440
+  if( mstrHelpStr != NULL )
441
+  {
442
+    _cmPoOpt_t* rp = r->enumPtr == NULL ? r : r->enumPtr;
443
+    rp->mstrStr = cmLhAllocStr(p->lH,mstrHelpStr);
444
+  }
445
+  return rc;
446
+}
447
+
448
+cmPoRC_t cmPgmOptInstallFlag(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* wordId, unsigned flags, unsigned         dfltVal, unsigned*       retValPtr, unsigned cnt, const cmChar_t* helpStr )
449
+{
450
+  cmPoRC_t    rc;
451
+  _cmPoOpt_t* r     = NULL;
452
+  _cmPo_t*    p     = _cmPoHandleToPtr(h);
453
+
454
+  if((rc= _cmPgmOptInstall(p, numId, charId, wordId, flags, kFlagPoFl, 0, cnt, helpStr, &r )) != kOkPoRC )
455
+    return rc;
456
+
457
+  r->dfltVal.u = dfltVal;
458
+  if( retValPtr != NULL )
459
+  {
460
+    r->retVal.u  = retValPtr;
461
+    // Unlike other parameters we don't set the initial value of flag parameter 
462
+    // because we don't want to destroy any default flag that may be set there
463
+  }
464
+
386
   return rc;
465
   return rc;
387
 }
466
 }
388
 
467
 
411
   //  a->u.b = true;
490
   //  a->u.b = true;
412
 
491
 
413
   // if this is an enumerated type
492
   // if this is an enumerated type
414
-  if( cmIsFlag(r->flags,kEnumPoFl) )
493
+  if( cmIsFlag(r->sflags,kEnumPoFl) )
415
   {
494
   {
416
     a->u.u = enumId;
495
     a->u.u = enumId;
417
 
496
 
421
     if( e->retVal.u != NULL )
500
     if( e->retVal.u != NULL )
422
       *e->retVal.u = enumId;
501
       *e->retVal.u = enumId;
423
   }
502
   }
503
+
504
+  // if this is a flag type
505
+  if( cmIsFlag(r->sflags,kFlagPoFl) )
506
+  {
507
+    a->u.u = r->dfltVal.u;
508
+    if( r->retVal.u != NULL )
509
+      *r->retVal.u |= a->u.u;
510
+  }
424
   return a;
511
   return a;
425
 }
512
 }
426
 
513
 
453
   a->valStr = valStr;
540
   a->valStr = valStr;
454
 
541
 
455
   errno = 0;
542
   errno = 0;
456
-  switch( r->flags & kTypeMaskPoFl )
543
+  switch( r->sflags & kTypeMaskPoFl )
457
   {
544
   {
545
+    // case kFlagPoFl: 
546
+    // enum values get set in _cmPgmOptInsertArg()
547
+
548
+
458
     case kBoolPoFl: 
549
     case kBoolPoFl: 
459
       //rc = _cmPgmOptParseBool(p,valStr,&a->u.b); 
550
       //rc = _cmPgmOptParseBool(p,valStr,&a->u.b); 
460
       a->u.b = true;
551
       a->u.b = true;
469
       break;
560
       break;
470
 
561
 
471
     case kIntPoFl:  
562
     case kIntPoFl:  
472
-      a->u.i = strtol(valStr,NULL,10); 
563
+      a->u.i = strtol(valStr,NULL, cmIsFlag(r->cflags,kHexPoFl) ? 16 : 10); 
473
       if( r->retVal.i != NULL )
564
       if( r->retVal.i != NULL )
474
         *r->retVal.i = a->u.i;
565
         *r->retVal.i = a->u.i;
475
       break;
566
       break;
476
 
567
 
477
     case kUIntPoFl: 
568
     case kUIntPoFl: 
478
-      a->u.u = strtol(valStr,NULL,10); 
569
+      a->u.u = strtol(valStr,NULL, cmIsFlag(r->cflags,kHexPoFl) ? 16 : 10); 
479
       if( r->retVal.u != NULL )
570
       if( r->retVal.u != NULL )
480
         *r->retVal.u = a->u.u;
571
         *r->retVal.u = a->u.u;
481
       break;
572
       break;
483
       // case kEnumPoFl: 
574
       // case kEnumPoFl: 
484
       // enum values get set in _cmPgmOptInsertArg()
575
       // enum values get set in _cmPgmOptInsertArg()
485
 
576
 
486
-    case kHexPoFl:  
487
-      a->u.u = strtol(valStr,NULL,16); 
488
-      if( r->retVal.u != NULL )
489
-        *r->retVal.u = a->u.u;
490
-      break;
491
-
492
     case kDblPoFl:  
577
     case kDblPoFl:  
493
       a->u.d = strtod(valStr,NULL);    
578
       a->u.d = strtod(valStr,NULL);    
494
       if( r->retVal.d != NULL )
579
       if( r->retVal.d != NULL )
500
       if( r->retVal.s != NULL )
585
       if( r->retVal.s != NULL )
501
         *r->retVal.s = a->u.s;
586
         *r->retVal.s = a->u.s;
502
       break;
587
       break;
588
+
589
+    default:
590
+      { assert(0); }
503
   }
591
   }
504
 
592
 
505
 
593
 
540
   return false;
628
   return false;
541
 }
629
 }
542
 
630
 
631
+cmPoRC_t  _cmPgmOptMissingEnumError( _cmPo_t* p, _cmPoOpt_t* r )
632
+{
633
+  _cmPoOpt_t* mstr = r->enumPtr==NULL ? r : r->enumPtr;
634
+  _cmPoOpt_t* rp  = p->list;
635
+  cmChar_t*   msg = cmTsPrintfP(NULL,"No argument was supplied for the required enumerated parameter containing the following set of possible flags: { ");
636
+  
637
+  for(; rp!=NULL; rp=rp->link)
638
+    if( cmIsFlag(rp->sflags,kEnumPoFl) && (rp==mstr || rp->enumPtr==mstr) )
639
+    {
640
+      msg = cmTextAppendSS(msg,rp->wordId);
641
+      msg = cmTextAppendSS(msg," ");
642
+    }
643
+
644
+  msg = cmTextAppendSS(msg,"}");
645
+  
646
+  cmPoRC_t rc = cmErrMsg(&p->err,kNoReqArgPoRC,msg);
647
+
648
+  cmMemFree(msg);
649
+  
650
+  return rc;
651
+}
652
+
543
 // check that all required arg.s were actually given and that the actual
653
 // check that all required arg.s were actually given and that the actual
544
 // number of instances does not exceed the defined limit
654
 // number of instances does not exceed the defined limit
545
 cmPoRC_t _cmPgmOptCheckReqArgs( _cmPo_t* p )
655
 cmPoRC_t _cmPgmOptCheckReqArgs( _cmPo_t* p )
549
   _cmPoOpt_t* r = p->list;
659
   _cmPoOpt_t* r = p->list;
550
   while( r != NULL )
660
   while( r != NULL )
551
   {
661
   {
552
-    if( cmIsFlag(r->flags, kReqPoFl ) )
662
+    if( cmIsFlag(r->cflags, kReqPoFl ) )
553
     {
663
     {
554
       _cmPoArg_t* a = p->args;
664
       _cmPoArg_t* a = p->args;
555
       while( a != NULL )
665
       while( a != NULL )
560
       }
670
       }
561
     
671
     
562
       if( a == NULL )
672
       if( a == NULL )
563
-        rc = cmErrMsg(&p->err,kNoReqArgPoRC,"No argument was supplied for the required parameter '%s'.",r->wordId);
673
+      {
674
+        if( cmIsFlag(r->sflags, kEnumPoFl ) )
675
+          rc =  _cmPgmOptMissingEnumError(p,r);
676
+        else
677
+          rc = cmErrMsg(&p->err,kNoReqArgPoRC,"No argument was supplied for the required parameter '%s'.",r->wordId);
678
+      }
564
 
679
 
565
     }
680
     }
566
 
681
 
585
   _cmPoArg_t* a     = NULL;
700
   _cmPoArg_t* a     = NULL;
586
   int         i     = 0; // arg index
701
   int         i     = 0; // arg index
587
   int         j     = 0; // arg label character index
702
   int         j     = 0; // arg label character index
703
+
704
+
705
+  if( _cmPgmOptNumIdToOptRecd(p,kPrintHelpPoId) == NULL )
706
+    cmPgmOptInstallBool(h, kPrintHelpPoId, 'h', "help",    0, false, NULL,0,"Print this usage information." );
707
+
708
+  if( _cmPgmOptNumIdToOptRecd(p,kVersionPoId) == NULL )
709
+    cmPgmOptInstallBool(h, kVersionPoId,   'v', "version", 0, false, NULL,0,"Print version information." );
710
+
711
+  if( _cmPgmOptNumIdToOptRecd(p,kPrintParmsPoId) == NULL )
712
+    cmPgmOptInstallBool(h, kPrintParmsPoId,'p', "parms",   0, false, NULL,0,"Print the arguments."); 
713
+
588
   
714
   
589
   while(i<argCnt)
715
   while(i<argCnt)
590
   {
716
   {
628
           if((r = _cmPgmOptCharIdToOptRecd(p,argArray[i][j])) == NULL )
754
           if((r = _cmPgmOptCharIdToOptRecd(p,argArray[i][j])) == NULL )
629
             return cmErrMsg(&p->err,kSyntaxErrPoRC,"The program option selector char '%c' is not valid.",argArray[i][j]);
755
             return cmErrMsg(&p->err,kSyntaxErrPoRC,"The program option selector char '%c' is not valid.",argArray[i][j]);
630
 
756
 
631
-          // if this charId is not a bool or enum then it must be followed by a value.
632
-          if( cmIsFlag(r->flags,kBoolPoFl)==false && cmIsFlag(r->flags,kEnumPoFl)==false )
757
+          // if this charId is not a flag,bool or enum then it must be followed by a value.
758
+          if( _cmPoOptUsesValue(r) )
633
             ++i;
759
             ++i;
634
           else // otherwise process the next char id in this charId token            
760
           else // otherwise process the next char id in this charId token            
635
             ++j;
761
             ++j;
669
         // create an arg record for the cur char or word id.
795
         // create an arg record for the cur char or word id.
670
         a = _cmPgmOptInsertArg(p, r );
796
         a = _cmPgmOptInsertArg(p, r );
671
 
797
 
672
-        // and the value type is not 'bool' or 'enum'
673
-        if( cmIsFlag(r->flags,kBoolPoFl)== false && cmIsFlag(r->flags,kEnumPoFl)==false )
798
+        // and the value type is not 'flag','bool' or 'enum'
799
+        if( _cmPoOptUsesValue(r) )
674
           state = kArgVal;
800
           state = kArgVal;
675
 
801
 
676
         switch(state)
802
         switch(state)
718
   unsigned          n = 0;
844
   unsigned          n = 0;
719
   const _cmPoArg_t* a = p->args;
845
   const _cmPoArg_t* a = p->args;
720
 
846
 
721
-  while( a != NULL && idx < n )
847
+  while( a != NULL && n < idx )
722
   {
848
   {
723
     ++n;
849
     ++n;
724
     a = a->link;
850
     a = a->link;
732
   return kOkPoRC;
858
   return kOkPoRC;
733
 }
859
 }
734
   
860
   
735
-unsigned cmPgmOptSelId( cmPgmOptH_t h, unsigned argIdx )
861
+unsigned cmPgmOptNumId( cmPgmOptH_t h, unsigned argIdx )
736
 {
862
 {
737
   const _cmPoArg_t* a;
863
   const _cmPoArg_t* a;
738
   cmPoRC_t          rc;
864
   cmPoRC_t          rc;
741
   return a->opt->numId;
867
   return a->opt->numId;
742
 }
868
 }
743
 
869
 
870
+unsigned cmPgmOptCharId( cmPgmOptH_t h, unsigned argIdx )
871
+{
872
+  const _cmPoArg_t* a;
873
+  cmPoRC_t          rc;
874
+  if((rc = _cmPgmOptIndexToPtr(_cmPoHandleToPtr(h),argIdx,&a)) != kOkPoRC )
875
+    return cmInvalidId;
876
+  return a->opt->charId;
877
+}
878
+
879
+const cmChar_t* cmPgmOptWordId( cmPgmOptH_t h, unsigned argIdx )
880
+{
881
+  const _cmPoArg_t* a;
882
+  cmPoRC_t          rc;
883
+  if((rc = _cmPgmOptIndexToPtr(_cmPoHandleToPtr(h),argIdx,&a)) != kOkPoRC )
884
+    return NULL;
885
+  return a->opt->wordId;
886
+}
887
+
744
 cmPoRC_t  _cmPgmOptArgPtr( _cmPo_t* p, unsigned argIdx, const _cmPoArg_t** app )
888
 cmPoRC_t  _cmPgmOptArgPtr( _cmPo_t* p, unsigned argIdx, const _cmPoArg_t** app )
745
 {
889
 {
746
   cmPoRC_t rc;
890
   cmPoRC_t rc;
903
   if(_cmPgmOptInstPtr(p,numId,instIdx,&rp,&vp) != kOkPoRC )
1047
   if(_cmPgmOptInstPtr(p,numId,instIdx,&rp,&vp) != kOkPoRC )
904
     return 0;
1048
     return 0;
905
 
1049
 
906
-  if( cmIsFlag(rp->flags,kCharPoFl) )
1050
+  if( cmIsFlag(rp->sflags,kCharPoFl) )
907
   {
1051
   {
908
     cmErrMsg(&p->err,kTypeErrPoRC,"The parameter '%s' is not a 'char'.",rp->wordId);
1052
     cmErrMsg(&p->err,kTypeErrPoRC,"The parameter '%s' is not a 'char'.",rp->wordId);
909
     return 0;
1053
     return 0;
938
   if((rc = _cmPgmOptInstPtr(p,numId,instIdx,&rp,&vp)) != kOkPoRC )
1082
   if((rc = _cmPgmOptInstPtr(p,numId,instIdx,&rp,&vp)) != kOkPoRC )
939
     return rc;
1083
     return rc;
940
  
1084
  
941
-  switch( rp->flags & kTypeMaskPoFl )
1085
+  switch( rp->sflags & kTypeMaskPoFl )
942
   {
1086
   {
1087
+    case kFlagPoFl: v = vp->u; break;
943
     case kBoolPoFl: v = vp->b; break;
1088
     case kBoolPoFl: v = vp->b; break;
944
     case kCharPoFl: v = vp->c; break;
1089
     case kCharPoFl: v = vp->c; break;
945
     case kIntPoFl:
1090
     case kIntPoFl:
946
     case kEnumPoFl: v = vp->i; break;
1091
     case kEnumPoFl: v = vp->i; break;
947
     case kUIntPoFl:
1092
     case kUIntPoFl:
948
-    case kHexPoFl:  v = vp->u; break;
949
     case kDblPoFl:  v = roundl(vp->d); break;
1093
     case kDblPoFl:  v = roundl(vp->d); break;
950
     case kStrPoFl:  
1094
     case kStrPoFl:  
951
       cmErrMsg(&p->err,kTypeErrPoRC,"The string parameter '%s' cannot be converted to an integer.",rp->wordId);
1095
       cmErrMsg(&p->err,kTypeErrPoRC,"The string parameter '%s' cannot be converted to an integer.",rp->wordId);
972
   if((rc = _cmPgmOptInstPtr(p,numId,instIdx,&rp,&vp)) != kOkPoRC )
1116
   if((rc = _cmPgmOptInstPtr(p,numId,instIdx,&rp,&vp)) != kOkPoRC )
973
     return rc;
1117
     return rc;
974
  
1118
  
975
-  switch( rp->flags & kTypeMaskPoFl )
1119
+  switch( rp->sflags & kTypeMaskPoFl )
976
   {
1120
   {
1121
+    case kFlagPoFl: v = vp->u; break;
977
     case kBoolPoFl: v = vp->b; break;
1122
     case kBoolPoFl: v = vp->b; break;
978
     case kCharPoFl: v = vp->c; break;
1123
     case kCharPoFl: v = vp->c; break;
979
     case kEnumPoFl:
1124
     case kEnumPoFl:
980
     case kIntPoFl:  v = vp->i; break;
1125
     case kIntPoFl:  v = vp->i; break;
981
-    case kHexPoFl:  
982
     case kUIntPoFl: v = vp->u; break;
1126
     case kUIntPoFl: v = vp->u; break;
983
     case kDblPoFl:  v = vp->d; break;
1127
     case kDblPoFl:  v = vp->d; break;
984
     case kStrPoFl:  
1128
     case kStrPoFl:  
1003
     return NULL;
1147
     return NULL;
1004
 
1148
 
1005
   // if the requested param is a defined as a string
1149
   // if the requested param is a defined as a string
1006
-  if( cmIsFlag(rp->flags,kStrPoFl) )
1150
+  if( cmIsFlag(rp->sflags,kStrPoFl) )
1007
     return vp->s;
1151
     return vp->s;
1008
 
1152
 
1009
   // otherwise the requested param is not defined as a string - so try to return the instance string value
1153
   // otherwise the requested param is not defined as a string - so try to return the instance string value
1065
   if( p->helpBegStr != NULL )
1209
   if( p->helpBegStr != NULL )
1066
     cmRptPrintf(rpt,"%s\n",p->helpBegStr);
1210
     cmRptPrintf(rpt,"%s\n",p->helpBegStr);
1067
 
1211
 
1068
-  while( r != NULL )
1212
+  for(; r != NULL; r=r->link )
1069
   {
1213
   {
1070
-    cmRptPrintf(rpt,"-%c --%-20s ",r->charId,r->wordId);
1214
+    const cmChar_t* reqStr = "(required)";
1215
+    const cmChar_t* valueTypeLabel = "";
1216
+    const cmChar_t* reqLabel = "";
1217
+    const cmChar_t* indentStr = "";
1218
+
1219
+    const _cmPoOpt_t* mstr = NULL;
1220
+
1221
+    if( cmIsFlag(r->sflags,kEnumPoFl) )
1222
+    {
1223
+      if( r->enumPtr == NULL )
1224
+        mstr     = r;
1225
+      indentStr = "    ";
1226
+    }
1227
+
1228
+    if( _cmPoOptUsesValue(r) ) 
1229
+      valueTypeLabel = _cmPoTypeFlagToLabel(r->sflags & kTypeMaskPoFl,r->cflags);
1230
+
1231
+    if( cmIsNotFlag(r->sflags,kEnumPoFl)  && cmIsFlag(r->sflags,kReqPoFl) )
1232
+      reqLabel = reqStr;
1233
+
1234
+    if( mstr != NULL )
1235
+      cmRptPrintf(rpt,"Enumerated group: %s %s",mstr->mstrStr==NULL ? "" : mstr->mstrStr, cmIsFlag(mstr->cflags,kReqPoFl) ? reqStr : "" );
1236
+   
1237
+    cmRptPrintf(rpt,"%s-%c --%s %s %s",indentStr,r->charId,r->wordId,valueTypeLabel,reqLabel);
1071
 
1238
 
1072
     if( r->helpStr != NULL )
1239
     if( r->helpStr != NULL )
1073
       cmRptPrintf(rpt,"    %s\n",r->helpStr);
1240
       cmRptPrintf(rpt,"    %s\n",r->helpStr);
1074
 
1241
 
1075
-    r = r->link;
1076
   }
1242
   }
1077
   
1243
   
1078
 
1244
 
1090
 bool _cmPgmOptPrint( _cmPo_t* p, cmRpt_t* rpt, const _cmPoOpt_t* r, const _cmPoValue_t* v, const cmChar_t* valStr )
1256
 bool _cmPgmOptPrint( _cmPo_t* p, cmRpt_t* rpt, const _cmPoOpt_t* r, const _cmPoValue_t* v, const cmChar_t* valStr )
1091
 {
1257
 {
1092
   const _cmPoOpt_t* e = r;
1258
   const _cmPoOpt_t* e = r;
1093
-  if( cmIsFlag(r->flags,kEnumPoFl) )
1259
+  if( cmIsFlag(r->sflags,kEnumPoFl) )
1094
   {
1260
   {
1095
     if( r->enumPtr != NULL )
1261
     if( r->enumPtr != NULL )
1096
       return false;
1262
       return false;
1103
   }
1269
   }
1104
 
1270
 
1105
   cmRptPrintf(rpt,"-%c --%-20s %i ",e->charId,e->wordId, _cmPgmOptInstCount(r));
1271
   cmRptPrintf(rpt,"-%c --%-20s %i ",e->charId,e->wordId, _cmPgmOptInstCount(r));
1106
-  switch(r->flags & kTypeMaskPoFl)
1272
+  switch(r->sflags & kTypeMaskPoFl)
1107
   {
1273
   {
1274
+    case kFlagPoFl: cmRptPrintf(rpt,r->cflags & kHexPoFl ? "0x%x ": "%u ",v->u ); break;
1108
     case kBoolPoFl: cmRptPrintf(rpt,"%c ",  v->b ? 'T' : 'F'); break;
1275
     case kBoolPoFl: cmRptPrintf(rpt,"%c ",  v->b ? 'T' : 'F'); break;
1109
     case kCharPoFl: cmRptPrintf(rpt,"%c ",  v->c); break;
1276
     case kCharPoFl: cmRptPrintf(rpt,"%c ",  v->c); break;
1110
-    case kIntPoFl:  cmRptPrintf(rpt,"%i ",  v->i); break;
1111
-    case kUIntPoFl: cmRptPrintf(rpt,"%u ",  v->u); break;
1112
-    case kHexPoFl:  cmRptPrintf(rpt,"0x%x ",v->u); break;
1277
+    case kIntPoFl:  cmRptPrintf(rpt,r->cflags & kHexPoFl ? "0x%x ": "%i ",  v->i); break;
1278
+    case kUIntPoFl: cmRptPrintf(rpt,r->cflags & kHexPoFl ? "0x%x ": "%u ",  v->u); break;
1113
     case kDblPoFl:  cmRptPrintf(rpt,"%f ",  v->d); break;
1279
     case kDblPoFl:  cmRptPrintf(rpt,"%f ",  v->d); break;
1114
     case kStrPoFl:  cmRptPrintf(rpt,"%s ",  v->s); break;
1280
     case kStrPoFl:  cmRptPrintf(rpt,"%s ",  v->s); break;
1115
     case kEnumPoFl: cmRptPrintf(rpt,"%i ",  v->u); break;
1281
     case kEnumPoFl: cmRptPrintf(rpt,"%i ",  v->u); break;

+ 51
- 26
cmPgmOpts.h 查看文件

72
 
72
 
73
   // Flag used by the 'flags' arg. to cmPgmOptInstall().
73
   // Flag used by the 'flags' arg. to cmPgmOptInstall().
74
   enum { 
74
   enum { 
75
-    kNoPoFlags = 0x000, 
76
-    kReqPoFl   = 0x001,  // this is a required parameter
77
-    kBoolPoFl  = 0x002,  // this parameter takes a value
78
-    kCharPoFl  = 0x004,  // parm. value is a character
79
-    kIntPoFl   = 0x008,  // parm. value is a decimal int
80
-    kUIntPoFl  = 0x010,  // parm. value is a decimal unsigned int
81
-    kHexPoFl   = 0x020,  // parm. value is a hex. unsigned int 
82
-    kDblPoFl   = 0x040,  // parm. value is a decimal double
83
-    kStrPoFl   = 0x080,  // parm. value is a string (default)
84
-    kEnumPoFl  = 0x100,  // parm. valus is a enum type (automatically set by a non-zero enumId)
85
-
86
-    kTypeMaskPoFl = 0x1f6
75
+    kReqPoFl   = 0x01,  // this is a required parameter
76
+    kHexPoFl   = 0x02   // this integer must be given in hexidecimal or output an integer in hex.
87
   };
77
   };
88
 
78
 
89
 
79
 
90
   // Define a parameter.
80
   // Define a parameter.
91
   //
81
   //
92
-  // unsigned        numId,   - numeric id used to identify this parameter 
93
-  // const cmChar_t  charId,  - a character used to identify this parameter
94
-  // const cmChar_t* wordId,  - a label used to identify this parameter
82
+  // unsigned        numId,   - Numeric id used to identify this parameter. The min. numId should be kPoBaseId.
83
+  // const cmChar_t  charId,  - A character used to identify this parameter.
84
+  // const cmChar_t* wordId,  - A label used to identify this parameter.
95
   // unsigned        flags,   - kNoPoFlags | kReqPoFl (the type flags are automatically assigned)
85
   // unsigned        flags,   - kNoPoFlags | kReqPoFl (the type flags are automatically assigned)
96
   // unsigned        enumId,  - non-zero value used to group enumerated parameter values  (ignored for non-enum types)
86
   // unsigned        enumId,  - non-zero value used to group enumerated parameter values  (ignored for non-enum types)
87
+  //                 dfltVal  - The default value for this parameter.
88
+  //                 retValPtr- Optional pointer to a variable to receive the argument value for this parameter.
97
   // unsigned        cnt,     - count of times this parameter may repeated or 0 for an unlimited repetitions
89
   // unsigned        cnt,     - count of times this parameter may repeated or 0 for an unlimited repetitions
98
   // const cmChar_t* helpStr  - a textual description of this parameter
90
   // const cmChar_t* helpStr  - a textual description of this parameter
99
   //
91
   //
100
   // Notes
92
   // Notes
101
-  // 1) 'numId','charId', and 'wordId' must all be unique among all parameter definitions.
102
-  // 2) If no  parameter value type flag is given then the type is assumed to be of type bool.
103
-  // 3) For all parameter value types except the string type arguments are automatically parsed to the
93
+  // 1) 'numId','charId', and 'wordId' must all be unique among all parameter definitions.  
94
+  //    An error will be generated if they are not.
95
+  // 2) For all parameter value types except the string type arguments are automatically parsed to the
104
   //    defined type. To avoid automatic parsing simply define the type as a string (using cmPgmOptInstallStr()).
96
   //    defined type. To avoid automatic parsing simply define the type as a string (using cmPgmOptInstallStr()).
105
-  // 4) All expected parameters must be defined prior to calling cmPgmOptParse().
106
-  // 5) One call to cmPgmOPtInstallEnum() is made for each possible enumeration value - where the 'enumId' gives the value.
107
-  //    A given set of associated enum values is grouped by giving a common 'numId'.
97
+  // 3) All expected parameters must be defined prior to calling cmPgmOptParse().
98
+  // 4) One call to cmPgmOptInstallEnum() is made for each possible enumeration value - where the 'enumId' gives the value.
99
+  //    A given set of associated enum values is grouped by giving a common 'numId'. 
100
+  //    Include a master help string in one of the enumerated elements to give documentation 
101
+  //    text for the entire set of values.
108
   //    Example:
102
   //    Example:
109
-  //     cmPgmOptInstallEnum(h,colorId,...,redId,...); 
110
-  //     cmPgmOptInstallEnum(h,colorId,...,greenId,...); 
111
-  //     cmPgmOptInstallEnum(h,colorId,...,blueId,...);   
103
+  //     cmPgmOptInstallEnum(h,colorId,...,redId,...,"Red","Select a color"); 
104
+  //     cmPgmOptInstallEnum(h,colorId,...,greenId,..."Green",NULL); 
105
+  //     cmPgmOptInstallEnum(h,colorId,...,blueId,...,"Blue",NULL);   
112
   //
106
   //
113
-  // 6) The following id's are used for built-in actions and are therefore restricted from use by the client:
107
+  // 5) The following id's are used for built-in actions and are therefore restricted from use by the client:
114
   //    a. -h --help    Print the program usage information.
108
   //    a. -h --help    Print the program usage information.
115
   //    b. -v --version Print the program version informatoin.
109
   //    b. -v --version Print the program version informatoin.
116
   //    c. -p --parms   Print the program parameter values.
110
   //    c. -p --parms   Print the program parameter values.
117
   //
111
   //
112
+  // 6) If a retValPtr is specified then *retValPtr it is assigned 'dfltVal' as part of the
113
+  //    call to cmPgmOptInstXXX().
114
+  // 
115
+  // 7) The default value of 'Flag' type parameters is always zero. 
116
+  //    If the 'char' or 'word' id of the Flag parameter appears in the
117
+  //    actual argument list then the value of the argument is 'onValue'.
118
+  //    Unlike other parameters Flag parameters do not initialize *regValPtr. 
119
+  //    If the retValPtr is given and the flag is set in the arg. list then
120
+  //    the retValPtr is set by bitwise assignment (i.e. *retValPtr |= dfltFlagValue).
121
+  //    This allows multiple Flag parameters to use the same retValPtr and
122
+  //    set independent bit fields in it.
118
   cmPoRC_t cmPgmOptInstallChar(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, cmChar_t        dfltVal, cmChar_t*        retValPtr, unsigned cnt, const cmChar_t* helpStr );
123
   cmPoRC_t cmPgmOptInstallChar(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, cmChar_t        dfltVal, cmChar_t*        retValPtr, unsigned cnt, const cmChar_t* helpStr );
119
   cmPoRC_t cmPgmOptInstallBool(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, bool            dfltVal, bool*            retValPtr, unsigned cnt, const cmChar_t* helpStr );
124
   cmPoRC_t cmPgmOptInstallBool(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, bool            dfltVal, bool*            retValPtr, unsigned cnt, const cmChar_t* helpStr );
120
   cmPoRC_t cmPgmOptInstallInt( cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, int             dfltVal, int*             retValPtr, unsigned cnt, const cmChar_t* helpStr );
125
   cmPoRC_t cmPgmOptInstallInt( cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, int             dfltVal, int*             retValPtr, unsigned cnt, const cmChar_t* helpStr );
121
   cmPoRC_t cmPgmOptInstallUInt(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, unsigned        dfltVal, unsigned*        retValPtr, unsigned cnt, const cmChar_t* helpStr );
126
   cmPoRC_t cmPgmOptInstallUInt(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, unsigned        dfltVal, unsigned*        retValPtr, unsigned cnt, const cmChar_t* helpStr );
122
   cmPoRC_t cmPgmOptInstallDbl( cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, double          dfltVal, double*          retValPtr, unsigned cnt, const cmChar_t* helpStr );
127
   cmPoRC_t cmPgmOptInstallDbl( cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, double          dfltVal, double*          retValPtr, unsigned cnt, const cmChar_t* helpStr );
123
   cmPoRC_t cmPgmOptInstallStr( cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, const cmChar_t* dfltVal, const cmChar_t** retValPtr, unsigned cnt, const cmChar_t* helpStr );
128
   cmPoRC_t cmPgmOptInstallStr( cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, const cmChar_t* dfltVal, const cmChar_t** retValPtr, unsigned cnt, const cmChar_t* helpStr );
124
-  cmPoRC_t cmPgmOptInstallEnum(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, unsigned enumId, unsigned dfltVal, unsigned* retValPtr, unsigned cnt, const cmChar_t* helpStr  );
129
+  cmPoRC_t cmPgmOptInstallEnum(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, unsigned enumId, unsigned dfltVal, unsigned* retValPtr, unsigned cnt, const cmChar_t* helpStr, const cmChar_t* mstrHelpStr  );
130
+  cmPoRC_t cmPgmOptInstallFlag(cmPgmOptH_t h, unsigned numId, cmChar_t charId, const cmChar_t* worldId, unsigned flags, unsigned         onValue, unsigned*       retValPtr, unsigned cnt, const cmChar_t* helpStr );
125
 
131
 
126
   // Parse a set of command line arguments.
132
   // Parse a set of command line arguments.
133
+  //
134
+  // 1) If only built-in parameters were specified then the NO check is done 
135
+  //    to verify that required arguments were provided.  However, if any non-built-in
136
+  //    arguments are provided then a check is performed to be sure that any 
137
+  //    parameters specified with the kPoReqFl have associated argument values.
138
+  //
139
+  // 2) If a parameter was specified with a 'retValPtr' then *retValPtr is
140
+  //    set to the value of the last argument associated with the given parameter.
141
+  //    This means that 'retValPtr' is generally only useful when the
142
+  //    parameter instance count limit (the 'cnt' param to cmPgmOptInstallXXX())
143
+  //    was set to 1.
144
+  //
145
+  //    
127
   cmPoRC_t cmPgmOptParse( cmPgmOptH_t h, unsigned argCnt, char* argArray[] );
146
   cmPoRC_t cmPgmOptParse( cmPgmOptH_t h, unsigned argCnt, char* argArray[] );
128
   
147
   
129
   // Get the total count of arguments passed to cmPgmOptParse().
148
   // Get the total count of arguments passed to cmPgmOptParse().
132
   // Get the numeric id associated with each argument.
151
   // Get the numeric id associated with each argument.
133
   unsigned cmPgmOptNumId( cmPgmOptH_t h, unsigned argIdx );
152
   unsigned cmPgmOptNumId( cmPgmOptH_t h, unsigned argIdx );
134
 
153
 
154
+  // Get the character id associated with this argument.
155
+  unsigned cmPgmOptCharId( cmPgmOptH_t h, unsigned argIdx );
156
+
157
+  // Get the word id associated with this argument.
158
+  const cmChar_t* cmPgmOptWordId( cmPgmOptH_t h, unsigned argIdx );
159
+
135
   // Manually convert each argument string into the specified type.
160
   // Manually convert each argument string into the specified type.
136
   // These functions are useful if all of the parameters were defined using cmPgmOptInstallStr().
161
   // These functions are useful if all of the parameters were defined using cmPgmOptInstallStr().
137
   // Use cmPgmOptRC() to check for errors.
162
   // Use cmPgmOptRC() to check for errors.

+ 26
- 6
cmRpt.c 查看文件

1
 #include "cmPrefix.h"
1
 #include "cmPrefix.h"
2
 #include "cmGlobal.h"
2
 #include "cmGlobal.h"
3
 #include "cmRpt.h"
3
 #include "cmRpt.h"
4
+#include "cmErr.h"
5
+#include "cmCtx.h"
6
+#include "cmMem.h"
7
+#include "cmMallocDebug.h"
4
 
8
 
5
 cmRpt_t cmRptNull = { NULL, NULL, NULL };
9
 cmRpt_t cmRptNull = { NULL, NULL, NULL };
6
 
10
 
26
 
30
 
27
 void _cmVOut( cmRptPrintFunc_t printFunc, void* userData, const cmChar_t* fmt, va_list vl )
31
 void _cmVOut( cmRptPrintFunc_t printFunc, void* userData, const cmChar_t* fmt, va_list vl )
28
 {
32
 {
29
-  unsigned bufN = 511;
30
- 
31
-  cmChar_t buf[bufN+1];
32
-  buf[0]=0;
33
+  va_list vl1;
34
+  va_copy(vl1,vl);
35
+  unsigned  n    = vsnprintf(NULL,0,fmt,vl1);
36
+  va_end(vl1);
37
+
38
+  unsigned  bufN = 511;
39
+  cmChar_t  buf[bufN+1];
40
+  cmChar_t* b    = buf;
41
+  unsigned  bn   = bufN;
42
+
43
+  if( n > bufN )
44
+  {
45
+    b  = cmMemAllocZ(cmChar_t,n+1); 
46
+    bn = n;
47
+  }
48
+
49
+  b[0]=0;
33
   if( fmt != NULL )
50
   if( fmt != NULL )
34
-    if( vsnprintf(buf,bufN,fmt,vl) > bufN )
51
+    if( vsnprintf(b,bn,fmt,vl) > bn )
35
     _cmOut(printFunc,userData,"The following error message was truncated because the character buffer in cmRpt::_cmVOut() was too small.");
52
     _cmOut(printFunc,userData,"The following error message was truncated because the character buffer in cmRpt::_cmVOut() was too small.");
36
 
53
 
37
-  _cmOut(printFunc,userData,buf);
54
+  _cmOut(printFunc,userData,b);
55
+
56
+  if( n > bufN )
57
+    cmMemFree(b);
38
 }
58
 }
39
 
59
 
40
 void cmRptSetup( cmRpt_t* rpt, cmRptPrintFunc_t printFunc, cmRptPrintFunc_t errorFunc, void* userPtr )
60
 void cmRptSetup( cmRpt_t* rpt, cmRptPrintFunc_t printFunc, cmRptPrintFunc_t errorFunc, void* userPtr )

Loading…
取消
儲存