Points&Forces (core)
Software tools facilitating the task of surveying architecture
SimpleOpt.h
Go to the documentation of this file.
1 
181 #ifndef INCLUDED_SimpleOpt
182 #define INCLUDED_SimpleOpt
183 
184 // Default the max arguments to a fixed value. If you want to be able to
185 // handle any number of arguments, then predefine this to 0 and it will
186 // use an internal dynamically allocated buffer instead.
187 #ifdef SO_MAX_ARGS
188 # define SO_STATICBUF SO_MAX_ARGS
189 #else
190 # include <stdlib.h> // malloc, free
191 # include <string.h> // memcpy
192 # define SO_STATICBUF 50
193 #endif
194 
195 //added P.Smars >
196 #ifndef _T
197 #define _T(s) (char*)s
198 #endif
199 
201 typedef enum _ESOError
202 {
205 
209 
213 
217 
221 
224 
227  SO_ARG_INVALID_DATA = -6
229 
232 {
234  SO_O_EXACT = 0x0001,
235 
238  SO_O_NOSLASH = 0x0002,
239 
242  SO_O_SHORTARG = 0x0004,
243 
246  SO_O_CLUMP = 0x0008,
247 
250  SO_O_USEALL = 0x0010,
251 
256  SO_O_NOERR = 0x0020,
257 
262  SO_O_PEDANTIC = 0x0040,
263 
265  SO_O_ICASE_SHORT = 0x0100,
266 
268  SO_O_ICASE_LONG = 0x0200,
269 
272  SO_O_ICASE_WORD = 0x0400,
273 
275  SO_O_ICASE = 0x0700
276 };
277 
283 typedef enum _ESOArgType {
287 
291 
295 
299 
303  SO_MULTI
305 
307 #define SO_END_OF_OPTIONS { -1, NULL, SO_NONE }
308 
309 #ifdef _DEBUG
310 # ifdef _MSC_VER
311 # include <crtdbg.h>
312 # define SO_ASSERT(b) _ASSERTE(b)
313 # else
314 # include <assert.h>
315 # define SO_ASSERT(b) assert(b)
316 # endif
317 #else
318 # define SO_ASSERT(b)
319 #endif
320 
321 // ---------------------------------------------------------------------------
322 // MAIN TEMPLATE CLASS
323 // ---------------------------------------------------------------------------
324 
326 template<class SOCHAR>
328 {
329 public:
331  struct SOption {
333  int nId;
334 
338  const SOCHAR * pszArg;
339 
342  };
343 
346  : m_rgShuffleBuf(NULL)
347  {
348  Init(0, NULL, NULL, 0);
349  }
350 
353  int argc,
354  SOCHAR * argv[],
355  const SOption * a_rgOptions,
356  int a_nFlags = 0
357  )
358  : m_rgShuffleBuf(NULL)
359  {
360  Init(argc, argv, a_rgOptions, a_nFlags);
361  }
362 
363 #ifndef SO_MAX_ARGS
365  ~CSimpleOptTempl() { if (m_rgShuffleBuf) free(m_rgShuffleBuf); }
366 #endif
367 
389  bool Init(
390  int a_argc,
391  SOCHAR * a_argv[],
392  const SOption * a_rgOptions,
393  int a_nFlags = 0
394  );
395 
400  inline void SetOptions(const SOption * a_rgOptions) {
401  m_rgOptions = a_rgOptions;
402  }
403 
411  inline void SetFlags(int a_nFlags) { m_nFlags = a_nFlags; }
412 
414  inline bool HasFlag(int a_nFlag) const {
415  return (m_nFlags & a_nFlag) == a_nFlag;
416  }
417 
434  bool Next();
435 
439  void Stop();
440 
446  inline ESOError LastError() const { return m_nLastError; }
447 
453  inline int OptionId() const { return m_nOptionId; }
454 
460  inline const SOCHAR * OptionText() const { return m_pszOptionText; }
461 
467  inline SOCHAR * OptionArg() const { return m_pszOptionArg; }
468 
481  SOCHAR ** MultiArg(int n);
482 
488  inline int FileCount() const { return m_argc - m_nLastArg; }
489 
495  inline SOCHAR * File(int n) const {
496  SO_ASSERT(n >= 0 && n < FileCount());
497  return m_argv[m_nLastArg + n];
498  }
499 
501  inline SOCHAR ** Files() const { return &m_argv[m_nLastArg]; }
502 
503 private:
504  CSimpleOptTempl(const CSimpleOptTempl &); // disabled
505  CSimpleOptTempl & operator=(const CSimpleOptTempl &); // disabled
506 
507  SOCHAR PrepareArg(SOCHAR * a_pszString) const;
508  bool NextClumped();
509  void ShuffleArg(int a_nStartIdx, int a_nCount);
510  int LookupOption(const SOCHAR * a_pszOption) const;
511  int CalcMatch(const SOCHAR *a_pszSource, const SOCHAR *a_pszTest) const;
512 
513  // Find the '=' character within a string.
514  inline SOCHAR * FindEquals(SOCHAR *s) const {
515  while (*s && *s != (SOCHAR)'=') ++s;
516  return *s ? s : NULL;
517  }
518  bool IsEqual(SOCHAR a_cLeft, SOCHAR a_cRight, int a_nArgType) const;
519 
520  inline void Copy(SOCHAR ** ppDst, SOCHAR ** ppSrc, int nCount) const {
521 #ifdef SO_MAX_ARGS
522  // keep our promise of no CLIB usage
523  while (nCount-- > 0) *ppDst++ = *ppSrc++;
524 #else
525  memcpy(ppDst, ppSrc, nCount * sizeof(SOCHAR*));
526 #endif
527  }
528 
529 private:
530  const SOption * m_rgOptions;
531  int m_nFlags;
532  int m_nOptionIdx;
533  int m_nOptionId;
534  int m_nNextOption;
535  int m_nLastArg;
536  int m_argc;
537  SOCHAR ** m_argv;
538  const SOCHAR * m_pszOptionText;
539  SOCHAR * m_pszOptionArg;
540  SOCHAR * m_pszClump;
541  SOCHAR m_szShort[3];
542  ESOError m_nLastError;
543  SOCHAR ** m_rgShuffleBuf;
544 };
545 
546 // ---------------------------------------------------------------------------
547 // IMPLEMENTATION
548 // ---------------------------------------------------------------------------
549 
550 template<class SOCHAR>
551 bool
553  int a_argc,
554  SOCHAR * a_argv[],
555  const SOption * a_rgOptions,
556  int a_nFlags
557  )
558 {
559  m_argc = a_argc;
560  m_nLastArg = a_argc;
561  m_argv = a_argv;
562  m_rgOptions = a_rgOptions;
563  m_nLastError = SO_SUCCESS;
564  m_nOptionIdx = 0;
565  m_nOptionId = -1;
566  m_pszOptionText = NULL;
567  m_pszOptionArg = NULL;
568  m_nNextOption = (a_nFlags & SO_O_USEALL) ? 0 : 1;
569  m_szShort[0] = (SOCHAR)'-';
570  m_szShort[2] = (SOCHAR)'\0';
571  m_nFlags = a_nFlags;
572  m_pszClump = NULL;
573 
574 #ifdef SO_MAX_ARGS
575  if (m_argc > SO_MAX_ARGS) {
576  m_nLastError = SO_ARG_INVALID_DATA;
577  m_nLastArg = 0;
578  return false;
579  }
580 #else
581  if (m_rgShuffleBuf) {
582  free(m_rgShuffleBuf);
583  }
584  if (m_argc > SO_STATICBUF) {
585  m_rgShuffleBuf = (SOCHAR**) malloc(sizeof(SOCHAR*) * m_argc);
586  if (!m_rgShuffleBuf) {
587  return false;
588  }
589  }
590 #endif
591 
592  return true;
593 }
594 
595 template<class SOCHAR>
596 bool
598 {
599 #ifdef SO_MAX_ARGS
600  if (m_argc > SO_MAX_ARGS) {
601  SO_ASSERT(!"Too many args! Check the return value of Init()!");
602  return false;
603  }
604 #endif
605 
606  // process a clumped option string if appropriate
607  if (m_pszClump && *m_pszClump) {
608  // silently discard invalid clumped option
609  bool bIsValid = NextClumped();
610  while (*m_pszClump && !bIsValid && HasFlag(SO_O_NOERR)) {
611  bIsValid = NextClumped();
612  }
613 
614  // return this option if valid or we are returning errors
615  if (bIsValid || !HasFlag(SO_O_NOERR)) {
616  return true;
617  }
618  }
619  SO_ASSERT(!m_pszClump || !*m_pszClump);
620  m_pszClump = NULL;
621 
622  // init for the next option
623  m_nOptionIdx = m_nNextOption;
624  m_nOptionId = -1;
625  m_pszOptionText = NULL;
626  m_pszOptionArg = NULL;
627  m_nLastError = SO_SUCCESS;
628 
629  // find the next option
630  SOCHAR cFirst;
631  int nTableIdx = -1;
632  int nOptIdx = m_nOptionIdx;
633  while (nTableIdx < 0 && nOptIdx < m_nLastArg) {
634  SOCHAR * pszArg = m_argv[nOptIdx];
635  m_pszOptionArg = NULL;
636 
637  // find this option in the options table
638  cFirst = PrepareArg(pszArg);
639  if (pszArg[0] == (SOCHAR)'-') {
640  // find any combined argument string and remove equals sign
641  m_pszOptionArg = FindEquals(pszArg);
642  if (m_pszOptionArg) {
643  *m_pszOptionArg++ = (SOCHAR)'\0';
644  }
645  }
646  nTableIdx = LookupOption(pszArg);
647 
648  // if we didn't find this option but if it is a short form
649  // option then we try the alternative forms
650  if (nTableIdx < 0
651  && !m_pszOptionArg
652  && pszArg[0] == (SOCHAR)'-'
653  && pszArg[1]
654  && pszArg[1] != (SOCHAR)'-'
655  && pszArg[2])
656  {
657  // test for a short-form with argument if appropriate
658  if (HasFlag(SO_O_SHORTARG)) {
659  m_szShort[1] = pszArg[1];
660  int nIdx = LookupOption(m_szShort);
661  if (nIdx >= 0
662  && (m_rgOptions[nIdx].nArgType == SO_REQ_CMB
663  || m_rgOptions[nIdx].nArgType == SO_OPT))
664  {
665  m_pszOptionArg = &pszArg[2];
666  pszArg = m_szShort;
667  nTableIdx = nIdx;
668  }
669  }
670 
671  // test for a clumped short-form option string and we didn't
672  // match on the short-form argument above
673  if (nTableIdx < 0 && HasFlag(SO_O_CLUMP)) {
674  m_pszClump = &pszArg[1];
675  ++m_nNextOption;
676  if (nOptIdx > m_nOptionIdx) {
677  ShuffleArg(m_nOptionIdx, nOptIdx - m_nOptionIdx);
678  }
679  return Next();
680  }
681  }
682 
683  // The option wasn't found. If it starts with a switch character
684  // and we are not suppressing errors for invalid options then it
685  // is reported as an error, otherwise it is data.
686  if (nTableIdx < 0) {
687  if (!HasFlag(SO_O_NOERR) && pszArg[0] == (SOCHAR)'-') {
688  m_pszOptionText = pszArg;
689  break;
690  }
691 
692  pszArg[0] = cFirst;
693  ++nOptIdx;
694  if (m_pszOptionArg) {
695  *(--m_pszOptionArg) = (SOCHAR)'=';
696  }
697  }
698  }
699 
700  // end of options
701  if (nOptIdx >= m_nLastArg) {
702  if (nOptIdx > m_nOptionIdx) {
703  ShuffleArg(m_nOptionIdx, nOptIdx - m_nOptionIdx);
704  }
705  return false;
706  }
707  ++m_nNextOption;
708 
709  // get the option id
710  ESOArgType nArgType = SO_NONE;
711  if (nTableIdx < 0) {
712  m_nLastError = (ESOError) nTableIdx; // error code
713  }
714  else {
715  m_nOptionId = m_rgOptions[nTableIdx].nId;
716  m_pszOptionText = m_rgOptions[nTableIdx].pszArg;
717 
718  // ensure that the arg type is valid
719  nArgType = m_rgOptions[nTableIdx].nArgType;
720  switch (nArgType) {
721  case SO_NONE:
722  if (m_pszOptionArg) {
723  m_nLastError = SO_ARG_INVALID;
724  }
725  break;
726 
727  case SO_REQ_SEP:
728  if (m_pszOptionArg) {
729  // they wanted separate args, but we got a combined one,
730  // unless we are pedantic, just accept it.
731  if (HasFlag(SO_O_PEDANTIC)) {
732  m_nLastError = SO_ARG_INVALID_TYPE;
733  }
734  }
735  // more processing after we shuffle
736  break;
737 
738  case SO_REQ_CMB:
739  if (!m_pszOptionArg) {
740  m_nLastError = SO_ARG_MISSING;
741  }
742  break;
743 
744  case SO_OPT:
745  // nothing to do
746  break;
747 
748  case SO_MULTI:
749  // nothing to do. Caller must now check for valid arguments
750  // using GetMultiArg()
751  break;
752  }
753  }
754 
755  // shuffle the files out of the way
756  if (nOptIdx > m_nOptionIdx) {
757  ShuffleArg(m_nOptionIdx, nOptIdx - m_nOptionIdx);
758  }
759 
760  // we need to return the separate arg if required, just re-use the
761  // multi-arg code because it all does the same thing
762  if ( nArgType == SO_REQ_SEP
763  && !m_pszOptionArg
764  && m_nLastError == SO_SUCCESS)
765  {
766  SOCHAR ** ppArgs = MultiArg(1);
767  if (ppArgs) {
768  m_pszOptionArg = *ppArgs;
769  }
770  }
771 
772  return true;
773 }
774 
775 template<class SOCHAR>
776 void
778 {
779  if (m_nNextOption < m_nLastArg) {
780  ShuffleArg(m_nNextOption, m_nLastArg - m_nNextOption);
781  }
782 }
783 
784 template<class SOCHAR>
785 SOCHAR
787  SOCHAR * a_pszString
788  ) const
789 {
790 #ifdef _WIN32
791  // On Windows we can accept the forward slash as a single character
792  // option delimiter, but it cannot replace the '-' option used to
793  // denote stdin. On Un*x paths may start with slash so it may not
794  // be used to start an option.
795  if (!HasFlag(SO_O_NOSLASH)
796  && a_pszString[0] == (SOCHAR)'/'
797  && a_pszString[1]
798  && a_pszString[1] != (SOCHAR)'-')
799  {
800  a_pszString[0] = (SOCHAR)'-';
801  return (SOCHAR)'/';
802  }
803 #endif
804  return a_pszString[0];
805 }
806 
807 template<class SOCHAR>
808 bool
810 {
811  // prepare for the next clumped option
812  m_szShort[1] = *m_pszClump++;
813  m_nOptionId = -1;
814  m_pszOptionText = NULL;
815  m_pszOptionArg = NULL;
816  m_nLastError = SO_SUCCESS;
817 
818  // lookup this option, ensure that we are using exact matching
819  int nSavedFlags = m_nFlags;
820  m_nFlags = SO_O_EXACT;
821  int nTableIdx = LookupOption(m_szShort);
822  m_nFlags = nSavedFlags;
823 
824  // unknown option
825  if (nTableIdx < 0) {
826  m_pszOptionText = m_szShort; // invalid option
827  m_nLastError = (ESOError) nTableIdx; // error code
828  return false;
829  }
830 
831  // valid option
832  m_pszOptionText = m_rgOptions[nTableIdx].pszArg;
833  ESOArgType nArgType = m_rgOptions[nTableIdx].nArgType;
834  if (nArgType == SO_NONE) {
835  m_nOptionId = m_rgOptions[nTableIdx].nId;
836  return true;
837  }
838 
839  if (nArgType == SO_REQ_CMB && *m_pszClump) {
840  m_nOptionId = m_rgOptions[nTableIdx].nId;
841  m_pszOptionArg = m_pszClump;
842  while (*m_pszClump) ++m_pszClump; // must point to an empty string
843  return true;
844  }
845 
846  // invalid option as it requires an argument
847  m_nLastError = SO_ARG_MISSING;
848  return true;
849 }
850 
851 // Shuffle arguments to the end of the argv array.
852 //
853 // For example:
854 // argv[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8" };
855 //
856 // ShuffleArg(1, 1) = { "0", "2", "3", "4", "5", "6", "7", "8", "1" };
857 // ShuffleArg(5, 2) = { "0", "1", "2", "3", "4", "7", "8", "5", "6" };
858 // ShuffleArg(2, 4) = { "0", "1", "6", "7", "8", "2", "3", "4", "5" };
859 template<class SOCHAR>
860 void
862  int a_nStartIdx,
863  int a_nCount
864  )
865 {
866  SOCHAR * staticBuf[SO_STATICBUF];
867  SOCHAR ** buf = m_rgShuffleBuf ? m_rgShuffleBuf : staticBuf;
868  int nTail = m_argc - a_nStartIdx - a_nCount;
869 
870  // make a copy of the elements to be moved
871  Copy(buf, m_argv + a_nStartIdx, a_nCount);
872 
873  // move the tail down
874  Copy(m_argv + a_nStartIdx, m_argv + a_nStartIdx + a_nCount, nTail);
875 
876  // append the moved elements to the tail
877  Copy(m_argv + a_nStartIdx + nTail, buf, a_nCount);
878 
879  // update the index of the last unshuffled arg
880  m_nLastArg -= a_nCount;
881 }
882 
883 // match on the long format strings. partial matches will be
884 // accepted only if that feature is enabled.
885 template<class SOCHAR>
886 int
888  const SOCHAR * a_pszOption
889  ) const
890 {
891  int nBestMatch = -1; // index of best match so far
892  int nBestMatchLen = 0; // matching characters of best match
893  int nLastMatchLen = 0; // matching characters of last best match
894 
895  for (int n = 0; m_rgOptions[n].nId >= 0; ++n) {
896  // the option table must use hyphens as the option character,
897  // the slash character is converted to a hyphen for testing.
898  SO_ASSERT(m_rgOptions[n].pszArg[0] != (SOCHAR)'/');
899 
900  int nMatchLen = CalcMatch(m_rgOptions[n].pszArg, a_pszOption);
901  if (nMatchLen == -1) {
902  return n;
903  }
904  if (nMatchLen > 0 && nMatchLen >= nBestMatchLen) {
905  nLastMatchLen = nBestMatchLen;
906  nBestMatchLen = nMatchLen;
907  nBestMatch = n;
908  }
909  }
910 
911  // only partial matches or no match gets to here, ensure that we
912  // don't return a partial match unless it is a clear winner
913  if (HasFlag(SO_O_EXACT) || nBestMatch == -1) {
914  return SO_OPT_INVALID;
915  }
916  return (nBestMatchLen > nLastMatchLen) ? nBestMatch : SO_OPT_MULTIPLE;
917 }
918 
919 // calculate the number of characters that match (case-sensitive)
920 // 0 = no match, > 0 == number of characters, -1 == perfect match
921 template<class SOCHAR>
922 int
924  const SOCHAR * a_pszSource,
925  const SOCHAR * a_pszTest
926  ) const
927 {
928  if (!a_pszSource || !a_pszTest) {
929  return 0;
930  }
931 
932  // determine the argument type
933  int nArgType = SO_O_ICASE_LONG;
934  if (a_pszSource[0] != '-') {
935  nArgType = SO_O_ICASE_WORD;
936  }
937  else if (a_pszSource[1] != '-' && !a_pszSource[2]) {
938  nArgType = SO_O_ICASE_SHORT;
939  }
940 
941  // match and skip leading hyphens
942  while (*a_pszSource == (SOCHAR)'-' && *a_pszSource == *a_pszTest) {
943  ++a_pszSource;
944  ++a_pszTest;
945  }
946  if (*a_pszSource == (SOCHAR)'-' || *a_pszTest == (SOCHAR)'-') {
947  return 0;
948  }
949 
950  // find matching number of characters in the strings
951  int nLen = 0;
952  while (*a_pszSource && IsEqual(*a_pszSource, *a_pszTest, nArgType)) {
953  ++a_pszSource;
954  ++a_pszTest;
955  ++nLen;
956  }
957 
958  // if we have exhausted the source...
959  if (!*a_pszSource) {
960  // and the test strings, then it's a perfect match
961  if (!*a_pszTest) {
962  return -1;
963  }
964 
965  // otherwise the match failed as the test is longer than
966  // the source. i.e. "--mant" will not match the option "--man".
967  return 0;
968  }
969 
970  // if we haven't exhausted the test string then it is not a match
971  // i.e. "--mantle" will not best-fit match to "--mandate" at all.
972  if (*a_pszTest) {
973  return 0;
974  }
975 
976  // partial match to the current length of the test string
977  return nLen;
978 }
979 
980 template<class SOCHAR>
981 bool
983  SOCHAR a_cLeft,
984  SOCHAR a_cRight,
985  int a_nArgType
986  ) const
987 {
988  // if this matches then we are doing case-insensitive matching
989  if (m_nFlags & a_nArgType) {
990  if (a_cLeft >= 'A' && a_cLeft <= 'Z') a_cLeft += 'a' - 'A';
991  if (a_cRight >= 'A' && a_cRight <= 'Z') a_cRight += 'a' - 'A';
992  }
993  return a_cLeft == a_cRight;
994 }
995 
996 // calculate the number of characters that match (case-sensitive)
997 // 0 = no match, > 0 == number of characters, -1 == perfect match
998 template<class SOCHAR>
999 SOCHAR **
1001  int a_nCount
1002  )
1003 {
1004  // ensure we have enough arguments
1005  if (m_nNextOption + a_nCount > m_nLastArg) {
1006  m_nLastError = SO_ARG_MISSING;
1007  return NULL;
1008  }
1009 
1010  // our argument array
1011  SOCHAR ** rgpszArg = &m_argv[m_nNextOption];
1012 
1013  // Ensure that each of the following don't start with an switch character.
1014  // Only make this check if we are returning errors for unknown arguments.
1015  if (!HasFlag(SO_O_NOERR)) {
1016  for (int n = 0; n < a_nCount; ++n) {
1017  SOCHAR ch = PrepareArg(rgpszArg[n]);
1018  if (rgpszArg[n][0] == (SOCHAR)'-') {
1019  rgpszArg[n][0] = ch;
1020  m_nLastError = SO_ARG_INVALID_DATA;
1021  return NULL;
1022  }
1023  rgpszArg[n][0] = ch;
1024  }
1025  }
1026 
1027  // all good
1028  m_nNextOption += a_nCount;
1029  return rgpszArg;
1030 }
1031 
1032 
1033 // ---------------------------------------------------------------------------
1034 // TYPE DEFINITIONS
1035 // ---------------------------------------------------------------------------
1036 
1039 
1042 
1043 #if defined(_UNICODE)
1045 # define CSimpleOpt CSimpleOptW
1046 #else
1048 # define CSimpleOpt CSimpleOptA
1049 #endif
1050 
1051 #endif // INCLUDED_SimpleOpt
_ESOFlags
Option flags.
Definition: SimpleOpt.h:232
@ SO_O_USEALL
Definition: SimpleOpt.h:250
@ SO_O_PEDANTIC
Definition: SimpleOpt.h:262
@ SO_O_NOSLASH
Definition: SimpleOpt.h:238
@ SO_O_NOERR
Definition: SimpleOpt.h:256
@ SO_O_SHORTARG
Definition: SimpleOpt.h:242
@ SO_O_ICASE_SHORT
Definition: SimpleOpt.h:265
@ SO_O_ICASE
Definition: SimpleOpt.h:275
@ SO_O_CLUMP
Definition: SimpleOpt.h:246
@ SO_O_ICASE_WORD
Definition: SimpleOpt.h:272
@ SO_O_ICASE_LONG
Definition: SimpleOpt.h:268
@ SO_O_EXACT
Definition: SimpleOpt.h:234
CSimpleOptTempl< wchar_t > CSimpleOptW
wchar_t version of CSimpleOpt
Definition: SimpleOpt.h:1041
enum _ESOArgType ESOArgType
CSimpleOptTempl< char > CSimpleOptA
ASCII/MBCS version of CSimpleOpt.
Definition: SimpleOpt.h:1038
_ESOError
Error values.
Definition: SimpleOpt.h:202
@ SO_ARG_INVALID
Definition: SimpleOpt.h:216
@ SO_SUCCESS
No error.
Definition: SimpleOpt.h:204
@ SO_OPT_MULTIPLE
Definition: SimpleOpt.h:212
@ SO_OPT_INVALID
Definition: SimpleOpt.h:208
@ SO_ARG_INVALID_TYPE
Definition: SimpleOpt.h:220
@ SO_ARG_MISSING
Required argument was not supplied.
Definition: SimpleOpt.h:223
@ SO_ARG_INVALID_DATA
Definition: SimpleOpt.h:227
enum _ESOError ESOError
Error values.
#define SO_STATICBUF
Definition: SimpleOpt.h:192
_ESOArgType
Definition: SimpleOpt.h:283
@ SO_MULTI
Definition: SimpleOpt.h:303
@ SO_REQ_SEP
Definition: SimpleOpt.h:290
@ SO_REQ_CMB
Definition: SimpleOpt.h:294
@ SO_NONE
Definition: SimpleOpt.h:286
@ SO_OPT
Definition: SimpleOpt.h:298
#define SO_ASSERT(b)
assertion used to test input data
Definition: SimpleOpt.h:318
Implementation of the SimpleOpt class.
Definition: SimpleOpt.h:328
int FileCount() const
Returned the number of entries in the Files() array.
Definition: SimpleOpt.h:488
bool Init(int a_argc, SOCHAR *a_argv[], const SOption *a_rgOptions, int a_nFlags=0)
Initialize the class in preparation for calling Next.
Definition: SimpleOpt.h:552
const SOCHAR * OptionText() const
Return the pszArg from the options array for the current option.
Definition: SimpleOpt.h:460
int OptionId() const
Return the nId value from the options array for the current option.
Definition: SimpleOpt.h:453
SOCHAR * OptionArg() const
Return the argument for the current option where one exists.
Definition: SimpleOpt.h:467
CSimpleOptTempl(int argc, SOCHAR *argv[], const SOption *a_rgOptions, int a_nFlags=0)
Initialize the class in preparation for use.
Definition: SimpleOpt.h:352
void SetOptions(const SOption *a_rgOptions)
Change the current options table during option parsing.
Definition: SimpleOpt.h:400
CSimpleOptTempl()
Initialize the class. Init() must be called later.
Definition: SimpleOpt.h:345
SOCHAR ** Files() const
Return the array of files.
Definition: SimpleOpt.h:501
ESOError LastError() const
Return the last error that occurred.
Definition: SimpleOpt.h:446
bool Next()
Advance to the next option if available.
Definition: SimpleOpt.h:597
SOCHAR ** MultiArg(int n)
Validate and return the desired number of arguments.
Definition: SimpleOpt.h:1000
void SetFlags(int a_nFlags)
Change the current flags during option parsing.
Definition: SimpleOpt.h:411
bool HasFlag(int a_nFlag) const
Query if a particular flag is set.
Definition: SimpleOpt.h:414
SOCHAR * File(int n) const
Return the specified file argument.
Definition: SimpleOpt.h:495
~CSimpleOptTempl()
Deallocate any allocated memory.
Definition: SimpleOpt.h:365
char buf[256]
Definition: copy.h:17
Structure used to define all known options.
Definition: SimpleOpt.h:331
const SOCHAR * pszArg
Definition: SimpleOpt.h:338