home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / pegase_src / argscontrolclass.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-14  |  14.9 KB  |  499 lines

  1. /*
  2. **
  3. ** ArgsControlClass.cpp
  4. **
  5. ** (c) 1998 Didier Levet
  6. **
  7. ** $Revision: 1.3 $
  8. ** $State: Exp $
  9. ** $Date: 1998/10/21 13:52:17 $
  10. **
  11. ** $Log: ArgsControlClass.cpp $
  12. ** Revision 1.3  1998/10/21 13:52:17  kakace
  13. ** Use CStrArray class for ToolTypes strings
  14. **
  15. ** Revision 1.2  1998/10/17 16:21:46  kakace
  16. ** Quickly tested. Seems OK.
  17. **
  18. ** Revision 1.1  1998/10/03 14:32:31  kakace
  19. ** Initial revision
  20. **
  21. **
  22. */
  23.  
  24.  
  25. //----------------------------------------------------------------------------------------------------
  26.  
  27. /// Includes
  28.  
  29. // C/C++
  30.  
  31. #ifndef  _ARGSCONTROL_CLASS_HPP
  32. #include "ArgsControlClass.hpp"
  33. #endif
  34.  
  35. #ifndef  _INCLUDE_STDLIB_H
  36. #include <stdlib.h>
  37. #endif
  38.  
  39. #ifndef  _INCLUDE_STRING_H
  40. #include <string.h>
  41. #endif
  42.  
  43. ///
  44.  
  45.  
  46. //----------------------------------------------------------------------------------------------------
  47. //========================================== Class CStartup ==========================================
  48. //----------------------------------------------------------------------------------------------------
  49.  
  50. //==================================================================================================
  51. //
  52. //   SYNOPSIS                                                                     CStartup::CStartup
  53. //   CStartup::CStartup(control[], array[], errorOutput, extendedHelp)
  54. //   CStartup::CStartup(const CArgsControl, LONG, CInterface *, STRING);
  55. //
  56. //   FUNCTION (Instance constructor)
  57. //      Initialize parameters handling.
  58. //      The commande line template used by ReadArgs() is created, the LONG array filled by
  59. //      ReadArgs() is initialized with default values, and a RDArgs structure is created to provide
  60. //      an extended help string to ReadArgs().
  61. //      An array is allocated to hold all ToolTypes strings.
  62. //
  63. //   INPUTS
  64. //   control[]    - Control array. It defines each argument.
  65. //   array[]      - Where to store these arguments.
  66. //   errorOutput  - Object that provide an API to display errors.
  67. //   extendedHelp - Extended help provides by ReadArgs(). Default to NULL.
  68. //
  69. //   PRECONDITIONS
  70. //      - errorOutput must not be NULL.
  71. //      - Control array must be initialized properly.
  72. //      - 'array' must not be NULL.
  73. //
  74. //   POSTCONDITIONS
  75. //      - Command line pattern is created (for later use by ReadArgs()).
  76. //      - iStatus == NO_ERROR if init was done successfully.
  77. //
  78. //   NOTES
  79. //      - extendedHelp string is not copied. Thus, this pointer must remain valid.
  80. //
  81. //   SEE ALSO
  82. //      Instance destructor.
  83. //      CInterface
  84. //
  85. //   HISTORY
  86. //
  87. //==================================================================================================
  88. /// CStartup::CONSTRUCTOR
  89.  
  90.  
  91. CStartup::CStartup(const CArgsControl control[], LONG array[], STRING extendedHelp)
  92.     : piArgsArray(array), poArgsControl(control), oTTStrings(), piTTNumbers(NULL), iStatus(CStartup::NO_ERROR)
  93. {
  94.     // Create the template for ReadArgs(), and allocate a vector for ToolTypes strings.
  95.  
  96.     InitCLITemplate();
  97.     InitArrays();
  98.  
  99.     // Allocate our own RDArgs structure needed for extended help.
  100.  
  101.     if ( (pOwnArgs = (RDArgs *) oRDArgs.Allocate(CDOSObject::RDARGS)) != NULL)
  102.     {
  103.         pOwnArgs->RDA_ExtHelp = (char *) extendedHelp;
  104.     }
  105.     else iStatus = NO_MEMORY;
  106. }
  107. ///
  108.  
  109. //==================================================================================================
  110. //
  111. //   SYNOPSIS                                                                    CStartup::~CStartup
  112. //   CStartup::~CStartup()
  113. //   CStartup::~CStartup();
  114. //
  115. //   FUNCTION (Instance destructor)
  116. //      Free all resources allocated by the constructor, or member functions.
  117. //
  118. //   POSTCONDITIONS
  119. //      - CLITemplate string buffer freed.
  120. //      - DOS object (RDArgs) is freed if already allocated.
  121. //      - RDArgs structure returned by ReadArgs() is freed.
  122. //      - Vector and buffers allocated for ToolTypes strings copies are also freed.
  123. //
  124. //   SEE ALSO
  125. //      Instance constructor, CStartup::ParseCLIArgs(), CStartup::InitCLITemplate()
  126. //
  127. //   HISTORY
  128. //
  129. //==================================================================================================
  130. /// CStartup::DESTRUCTOR
  131.  
  132.  
  133. CStartup::~CStartup()
  134. {
  135.     delete [] piTTNumbers;
  136.     delete [] pcCLITemplate;        // delete [] NULL is safe.
  137. }
  138. ///
  139.  
  140. //==================================================================================================
  141. //
  142. //   SYNOPSIS                                                                    CStartup::ParseArgs
  143. //   ErrorCode = CStartup::ParseArgs()
  144. //   Errors CStartup::ParseArgs();
  145. //
  146. //   FUNCTION
  147. //      Fetch settings from the icon's ToolTypes to alter default settings, then parse command line
  148. //      parameters.
  149. //
  150. //   RESULT
  151. //   ErrorCode : NO_ERROR on success.
  152. //
  153. //   POSTCONDITIONS
  154. //      - LONG array is initialized with ToolTypes and CLI parameters values.
  155. //
  156. //   SEE ALSO
  157. //      CStartup::ParseToolTypes(), CStartup::ParseCLIArgs()
  158. //
  159. //   HISTORY
  160. //
  161. //==================================================================================================
  162. /// CStartup::ParseArgs()
  163.  
  164.  
  165. CStartup::Errors CStartup::ParseArgs()
  166. {
  167.     Errors err_code = iStatus;
  168.  
  169.     if (err_code == NO_ERROR)   err_code = ParseToolTypes();
  170.     if (err_code == NO_ERROR)   err_code = ParseCLIArgs();
  171.  
  172.     return err_code;
  173. }
  174. ///
  175.  
  176. //==================================================================================================
  177. //
  178. //   SYNOPSIS                                                                 CStartup::ParseCLIArgs
  179. //   ErrorCode = CStartup::ParseCLIArgs()
  180. //   Errors CStartup::ParseCLIArgs();
  181. //
  182. //   FUNCTION
  183. //      Fetch settings from the CLI command line using ReadArgs(). Numeric parameters are checked
  184. //      against their respective bounds, if any. Further controls HAVE to be made by the client.
  185. //
  186. //   RESULT
  187. //   ErrorCode : NO_ERROR on success, READARGS_ERROR if ReadArgs() failed, or BAD_ARGUMENT if a
  188. //      number is out of range.
  189. //
  190. //   PRECONDITIONS
  191. //      - pcCLITemplate is constructed properly (constructor's job).
  192. //      - piArgsArray is initialized with default values (constructor's job).
  193. //      - pOwnRDArgs is valid, or NULL.
  194. //
  195. //   POSTCONDITIONS
  196. //      - piArgsArray is filled with CLI parameters, unless an error occured.
  197. //
  198. //   NOTES
  199. //      - RDArgs structure is not freed here. This will be done by the destructor.
  200. //
  201. //   SEE ALSO
  202. //      Instance destructor.
  203. //
  204. //   HISTORY
  205. //
  206. //==================================================================================================
  207. /// CStartup::ParseCLIArgs()
  208.  
  209.  
  210. CStartup::Errors CStartup::ParseCLIArgs()
  211. {
  212.     if (DOSArgs.ReadArgs(pcCLITemplate, piArgsArray, pOwnArgs) != NULL)
  213.     {
  214.         int  i;
  215.         LONG value, lower_bound, upper_bound;
  216.  
  217.         for (i = 0; poArgsControl[i].pcArgName != NULL; i++)
  218.         {
  219.             if (piArgsArray[i] != 0
  220.                 && poArgsControl[i].bArgType == ARG_NUMBER
  221.                 && (poArgsControl[i].bArgFlags & ARGF_CHECKLIMITS) != 0)
  222.             {
  223.                 value = *( (LONG *) piArgsArray[i] );
  224.  
  225.                 lower_bound = (LONG) poArgsControl[i].iControl;
  226.                 upper_bound = (LONG) poArgsControl[i].iUpperBound;
  227.  
  228.                 if (value < lower_bound || value > upper_bound)
  229.                 {
  230.                     iStatus = BAD_ARGUMENT;
  231.                     break;
  232.                 }
  233.             }
  234.         }
  235.     }
  236.     else iStatus = READARGS_ERROR;
  237.  
  238.     return iStatus;
  239. }
  240. ///
  241.  
  242. //==================================================================================================
  243. //
  244. //   SYNOPSIS                                                               CStartup::ParseToolTypes
  245. //   ErrorCode = CStartup::ParseToolTypes(progName)
  246. //   Errors CStartup::ParseToolTypes(STRING);
  247. //
  248. //   FUNCTION
  249. //      Fetch global settings from the icon's ToolTypes.
  250. //
  251. //   INPUTS
  252. //   progName - Program name or NULL.
  253. //
  254. //   RESULT
  255. //   ErrorCode : NO_ERROR on success, or NO_MEMORY.
  256. //
  257. //   NOTES
  258. //      Incorrect values are ignored.
  259. //
  260. //   HISTORY
  261. //
  262. //==================================================================================================
  263. /// CStartup::ParseToolTypes()
  264.  
  265.  
  266. CStartup::Errors CStartup::ParseToolTypes(STRING progName)
  267. {
  268.     CDiskObject icon;
  269.  
  270.     // Load the icon then check all possible tool types.
  271.  
  272.     if (icon.Load(progName) != NULL)
  273.     {
  274.         int      i;
  275.         STRING   TT_name;                                   // ToolType name.
  276.         STRING   TT_value;                                  // ToolType value.
  277.  
  278.         // Loop for all possible ToolTypes, unless an error occurs.
  279.  
  280.         for (i = 0; (TT_name = poArgsControl[i].pcArgName) != NULL && iStatus == NO_ERROR; i++)
  281.         {
  282.             if (   (poArgsControl[i].bArgFlags & ARGF_WB) != 0
  283.                 && (TT_value = icon.FindToolType(TT_name)) != NULL)
  284.             {
  285.                 ULONG offset = poArgsControl[i].wOffset;
  286.  
  287.                 // Handle the current ToolType according to its type.
  288.  
  289.                 switch(poArgsControl[i].bArgType)
  290.                 {
  291.                     // The current ToolType hold a string. It must be copied
  292.                     // because we will free the icon upon exit.
  293.  
  294.                     case ARG_STRING:
  295.                         AllocateNewString(i, TT_value);
  296.                         break;
  297.  
  298.                     // The current ToolType hold a number. If ARGF_CHECKLIMITS is specified
  299.                     // in the control structure, this number is checked against the specified
  300.                     // bounds. Out of bounds number are discarded.
  301.  
  302.                     case ARG_NUMBER:
  303.                         {
  304.                             LONG value = atoi(TT_value);
  305.                             LONG check = poArgsControl[i].bArgFlags & ARGF_CHECKLIMITS;
  306.  
  307.                             if ( check == 0 || (check != 0 && value >= (LONG) poArgsControl[i].iControl
  308.                                                 && value <= (LONG) poArgsControl[i].iUpperBound) )
  309.                             {
  310.                                 piTTNumbers[iCurrentNumIndex] = value;
  311.                                 piArgsArray[offset] = (LONG) &piTTNumbers[iCurrentNumIndex];
  312.                                 ++iCurrentNumIndex;
  313.                             }
  314.                         }
  315.                         break;
  316.  
  317.                     // The current ToolType is a boolean one.
  318.  
  319.                     case ARG_BOOL:
  320.                         piArgsArray[offset] = -1;
  321.                         break;
  322.  
  323.                     default:
  324.                         break;
  325.                 }
  326.             }
  327.         }
  328.     }
  329.  
  330.     return iStatus;
  331. }
  332. ///
  333.  
  334. //==================================================================================================
  335. //
  336. //   SYNOPSIS                                                            CStartup::AllocateNewString
  337. //   CStartup::AllocateNewString(ctrlIdx, str)
  338. //   void CStartup::AllocateNewString(ULONG, STRING);
  339. //
  340. //   FUNCTION
  341. //      Allocate a new buffer to hold a copy of the string passed to this function.
  342. //
  343. //   INPUTS
  344. //   ctrlIdx - Index in the LONG array to whitch save the string pointer.
  345. //   str     - String to copy.
  346. //
  347. //   PRECONDITIONS
  348. //      String must not be NULL.
  349. //
  350. //   INVARIANTS
  351. //      iMaxStrings != 0
  352. //
  353. //   POSTCONDITIONS
  354. //      A new string buffer is available, otherwise iStatus is set to NO_MEMORY.
  355. //
  356. //   HISTORY
  357. //
  358. //==================================================================================================
  359. /// CStartup::AllocateNewString()   [PRIVATE]
  360.  
  361.  
  362. void CStartup::AllocateNewString(ULONG ctrlIdx, STRING str)
  363. {
  364.     if (oTTStrings.Add(str) != FALSE)
  365.     {
  366.         piArgsArray[ctrlIdx] = (LONG) oTTStrings[oTTStrings.CurrentIndex() - 1].string();
  367.     }
  368.     else iStatus = NO_MEMORY;
  369. }
  370. ///
  371.  
  372. //==================================================================================================
  373. //
  374. //   SYNOPSIS                                                                   CStartup::InitArrays
  375. //   CStartup::InitArrays()
  376. //   void CStartup::InitArrays();
  377. //
  378. //   FUNCTION
  379. //      Allocate a vector to hold all ToolTypes string pointers and numbers.
  380. //
  381. //   POSTCONDITIONS
  382. //      Arrays are allocated, or iStatus is set to NO_MEMORY.
  383. //
  384. //   SEE ALSO
  385. //      CStartup::DeleteArrays()
  386. //
  387. //   HISTORY
  388. //
  389. //==================================================================================================
  390. /// CStartup::InitArrays()          [PRIVATE]
  391.  
  392.  
  393. void CStartup::InitArrays()
  394. {
  395.     ULONG max_strings = 0;
  396.  
  397.     iCurrentNumIndex  = 0;
  398.     iMaxNumbers       = 0;
  399.  
  400.     for (int i = 0; poArgsControl[i].pcArgName != NULL; i++)
  401.     {
  402.         if ( (poArgsControl[i].bArgFlags & ARGF_WB) != 0)
  403.         {
  404.             if (poArgsControl[i].bArgType == ARG_NUMBER)
  405.             {
  406.                 ++iMaxNumbers;
  407.             }
  408.  
  409.             if (poArgsControl[i].bArgType == ARG_STRING)
  410.             {
  411.                 ++max_strings;
  412.             }
  413.         }
  414.     }
  415.  
  416.     if (max_strings > 0)
  417.     {
  418.         oTTStrings.extend(max_strings);
  419.     }
  420.  
  421.     if (iMaxNumbers > 0)
  422.     {
  423.         if ( (piTTNumbers = new LONG[iMaxNumbers]) == NULL)
  424.         {
  425.             iStatus = NO_MEMORY;
  426.         }
  427.     }
  428. }
  429. ///
  430.  
  431. //==================================================================================================
  432. //
  433. //   SYNOPSIS                                                              CStartup::InitCLITemplate
  434. //   CStartup::InitCLITemplate()
  435. //   void CStartup::InitCLITemplate();
  436. //
  437. //   FUNCTION
  438. //      Create the template for ReadArgs() and initialize the LONG array with default values.
  439. //
  440. //   PRECONDITIONS
  441. //      - poArgsControl must point to an initialized CArgsControl structure.
  442. //      - piArgsArray must not be NULL
  443. //      These conditions are checked by the constructor (which call this function).
  444. //
  445. //   POSTCONDITIONS
  446. //      - pcCLITemplate is created, or iStatus is set to NO_MEMORY.
  447. //
  448. //   NOTES
  449. //      pcCLITemplate will be freed by the destructor.
  450. //
  451. //   HISTORY
  452. //
  453. //==================================================================================================
  454. /// CStartup::InitCLITemplate()     [PRIVATE]
  455.  
  456.  
  457. void CStartup::InitCLITemplate()
  458. {
  459.     // Determine CLITemplate string size.
  460.  
  461.     int   i;
  462.     ULONG cli_pattern_size = 0;
  463.  
  464.     for (i = 0; poArgsControl[i].pcArgName != NULL; i++)
  465.     {
  466.         if ( (poArgsControl[i].bArgFlags & ARGF_CLI) != 0)
  467.         {
  468.             cli_pattern_size += 1 + strlen(poArgsControl[i].pcArgName) + strlen(poArgsControl[i].pcCLIModifier);
  469.             // (+1 because of the coma between args, or string ending NULL).
  470.         }
  471.     }
  472.  
  473.     // Construct the CLI template string.
  474.  
  475.     if (cli_pattern_size != 0 && (pcCLITemplate = new char[cli_pattern_size]) != NULL)
  476.     {
  477.         for (i = 0; poArgsControl[i].pcArgName != NULL; i++)
  478.         {
  479.             if ( (poArgsControl[i].bArgFlags & ARGF_CLI) != 0)
  480.             {
  481.                 if (i != 0) strcat(pcCLITemplate, ",");
  482.  
  483.                 strcat(pcCLITemplate, poArgsControl[i].pcArgName);
  484.                 strcat(pcCLITemplate, poArgsControl[i].pcCLIModifier);
  485.             }
  486.  
  487.             // Copy the default value (if any) to our array.
  488.  
  489.             if ( (poArgsControl[i].bArgFlags & ARGF_DEFAULTVALUE) != 0)
  490.             {
  491.                 piArgsArray[i] = poArgsControl[i].iDefaultValue;
  492.             }
  493.         }
  494.     }
  495.     else iStatus = NO_MEMORY;
  496. }
  497. ///
  498.  
  499.