Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
8.3 KiB

  1. /*
  2. ** args.c - Command-line argument manipulation functions.
  3. **
  4. ** Author: DavidDi
  5. **
  6. ** N.b., setargv.obj must be linked with this module for the command-line
  7. ** parsing to function properly.
  8. */
  9. // Headers
  10. ///////////
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include "lz_common.h"
  16. #include "lz_header.h"
  17. #include "args.h"
  18. #include "main.h"
  19. #include "messages.h"
  20. #include <diamondc.h>
  21. #include "mydiam.h"
  22. extern BOOL PathType(LPSTR lpszFileString); /* WIN32 MOD*/
  23. // Globals
  24. ///////////
  25. // All the globals defined in this module are set by ParseArguments().
  26. BOOL bDoRename, // flag for performing compressed file renaming
  27. bDisplayHelp, // flag for displaying help information
  28. bTargetIsDir, // flag telling whether or not files are being
  29. // compressed to a directory
  30. bDirectives, // One or more directive files on command-line
  31. bUpdateOnly, // flag for conditional compression based on
  32. // existing target file's date/time stamp relative
  33. // to source file.
  34. bNoLogo; // flag to suppress printing copyright information
  35. INT nNumFileSpecs, // number of non-switch, non-directory command-line
  36. // arguments, assumed to be file specifications
  37. iTarget; // argv[] index of target directory argument, or FAIL if
  38. // none present
  39. BYTE byteAlgorithm; // compression / expansion algorithm to use
  40. TCOMP DiamondCompressionType; // 0 if not diamond (ie, LZ)
  41. /*
  42. ** BOOL ParseArguments(int argc, char ARG_PTR *argv[]);
  43. **
  44. ** Parse command-line arguments.
  45. **
  46. ** Arguments: like arguments to main()
  47. **
  48. ** Returns: TRUE if command-line arguments parsed successfully. FALSE if
  49. ** not.
  50. **
  51. ** Globals: All globals defined in this module are set in this function,
  52. ** as described above.
  53. */
  54. BOOL ParseArguments(INT argc, CHAR ARG_PTR *argv[])
  55. {
  56. INT i;
  57. CHAR chSwitch;
  58. TCOMP Level;
  59. TCOMP Mem;
  60. CHAR *p;
  61. // Set up default values for globals.
  62. bDoRename = FALSE;
  63. bDisplayHelp = FALSE;
  64. bTargetIsDir = FALSE;
  65. bDirectives = FALSE;
  66. bNoLogo = FALSE;
  67. nNumFileSpecs = 0;
  68. iTarget = FAIL;
  69. byteAlgorithm = DEFAULT_ALG;
  70. DiamondCompressionType = 0;
  71. // Look at each command-line argument.
  72. for (i = 1; i < argc; i++)
  73. if (ISSWITCH(*(argv[i])))
  74. {
  75. // Get switch character.
  76. chSwitch = *(argv[i] + 1);
  77. //for bad DBCS argument
  78. if( IsDBCSLeadByte(chSwitch) )
  79. {
  80. CHAR work[3];
  81. lstrcpyn(work, argv[i] + 1, 3);
  82. LoadString(NULL, SID_BAD_SWITCH2, ErrorMsg, 1024);
  83. printf(ErrorMsg, work);
  84. return(FALSE);
  85. }
  86. // Classify switch.
  87. if (toupper(chSwitch) == toupper(chRENAME_SWITCH))
  88. bDoRename = TRUE;
  89. else if (toupper(chSwitch) == toupper(chHELP_SWITCH))
  90. bDisplayHelp = TRUE;
  91. else if (toupper(chSwitch) == toupper(chUPDATE_SWITCH))
  92. bUpdateOnly = TRUE;
  93. else if (toupper(chSwitch) == toupper(chNO_LOGO_SWITCH))
  94. bNoLogo= TRUE;
  95. else if (toupper(chSwitch) == toupper(chALG_SWITCH)) {
  96. switch(*(argv[i] + 2)) {
  97. case 'x':
  98. case 'X':
  99. //
  100. // LZX. Also set memory.
  101. //
  102. Mem = (TCOMP)atoi(argv[i] + 3);
  103. if((Mem < (tcompLZX_WINDOW_LO >> tcompSHIFT_LZX_WINDOW))
  104. || (Mem > (tcompLZX_WINDOW_HI >> tcompSHIFT_LZX_WINDOW))) {
  105. Mem = (tcompLZX_WINDOW_LO >> tcompSHIFT_LZX_WINDOW);
  106. }
  107. byteAlgorithm = LZX_ALG;
  108. DiamondCompressionType = TCOMPfromLZXWindow( Mem );
  109. break;
  110. case 'q':
  111. case 'Q':
  112. //
  113. // Quantum. Also set level.
  114. //
  115. Level = (TCOMP)atoi(argv[i] + 3);
  116. Mem = (p = strchr(argv[i]+3,',')) ? (TCOMP)atoi(p+1) : 0;
  117. if((Level < (tcompQUANTUM_LEVEL_LO >> tcompSHIFT_QUANTUM_LEVEL))
  118. || (Level > (tcompQUANTUM_LEVEL_HI >> tcompSHIFT_QUANTUM_LEVEL))) {
  119. Level = ((tcompQUANTUM_LEVEL_HI - tcompQUANTUM_LEVEL_LO) / 2)
  120. + tcompQUANTUM_LEVEL_LO;
  121. Level >>= tcompSHIFT_QUANTUM_LEVEL;
  122. }
  123. if((Mem < (tcompQUANTUM_MEM_LO >> tcompSHIFT_QUANTUM_MEM))
  124. || (Mem > (tcompQUANTUM_MEM_HI >> tcompSHIFT_QUANTUM_MEM))) {
  125. Mem = ((tcompQUANTUM_MEM_HI - tcompQUANTUM_MEM_LO) / 2)
  126. + tcompQUANTUM_MEM_LO;
  127. Mem >>= tcompSHIFT_QUANTUM_MEM;
  128. }
  129. byteAlgorithm = QUANTUM_ALG;
  130. DiamondCompressionType = TCOMPfromTypeLevelMemory(
  131. tcompTYPE_QUANTUM,
  132. Level,
  133. Mem
  134. );
  135. break;
  136. case 'l':
  137. case 'L':
  138. DiamondCompressionType = 0;
  139. byteAlgorithm = DEFAULT_ALG;
  140. break;
  141. default:
  142. DiamondCompressionType = tcompTYPE_MSZIP;
  143. byteAlgorithm = MSZIP_ALG;
  144. break;
  145. }
  146. } else
  147. {
  148. // Unrecognized switch.
  149. LoadString(NULL, SID_BAD_SWITCH, ErrorMsg, 1024);
  150. printf(ErrorMsg, chSwitch);
  151. return(FALSE);
  152. }
  153. }
  154. else
  155. {
  156. // Keep track of last non-switch command-line argument as
  157. // destination argument.
  158. iTarget = i;
  159. // Determine if this is a directive file
  160. if ( '@' == argv[i][0] )
  161. bDirectives = TRUE;
  162. else if (IsDir((LPSTR)argv[i]) == FALSE)
  163. // Non-switch arguments are assumed to be file specifications.
  164. nNumFileSpecs++;
  165. }
  166. // Set bTargetIsDir.
  167. if (iTarget != FAIL)
  168. bTargetIsDir = IsDir((LPSTR)argv[iTarget]);
  169. // Command-line arguments parsed successsfully.
  170. return(TRUE);
  171. }
  172. /*
  173. ** BOOL CheckArguments(void);
  174. **
  175. ** Check command-line arguments for error conditions.
  176. **
  177. ** Arguments: void
  178. **
  179. ** Returns: BOOL - TRUE if no problems found. FALSE if problem found.
  180. **
  181. ** Globals: none
  182. */
  183. BOOL CheckArguments(VOID)
  184. {
  185. if (nNumFileSpecs < 1 && !bDirectives )
  186. {
  187. // No file specifications given.
  188. LoadString(NULL, SID_NO_FILE_SPECS, ErrorMsg, 1024);
  189. printf(ErrorMsg);
  190. return(FALSE);
  191. }
  192. else if (nNumFileSpecs == 1 && bDoRename == FALSE && bTargetIsDir == FALSE)
  193. {
  194. // We don't want to process a source file on to itself.
  195. LoadString(NULL, SID_NO_OVERWRITE, ErrorMsg, 1024);
  196. printf(ErrorMsg, pszTargetName);
  197. return(FALSE);
  198. }
  199. else if (nNumFileSpecs > 2 && bDoRename == FALSE && bTargetIsDir == FALSE)
  200. {
  201. // There are multiple files to process, and the destination
  202. // specification argument is not a directory. But we weren't told to
  203. // rename the output files. Bail out since we don't want to wipe out
  204. // the input files.
  205. LoadString(NULL, SID_NOT_A_DIR, ErrorMsg, 1024);
  206. printf(ErrorMsg, pszTargetName);
  207. return(FALSE);
  208. }
  209. else
  210. // No problems encountered.
  211. return(TRUE);
  212. }
  213. /*
  214. ** int GetNextFileArg(char ARG_PTR *argv[]);
  215. **
  216. ** Find the next file name argument on the command-line.
  217. **
  218. ** Arguments: like argument to main()
  219. **
  220. ** Returns: int - Index in argv[] of next file name argument. FAIL if
  221. ** none found.
  222. **
  223. ** Globals: none
  224. */
  225. INT GetNextFileArg(CHAR ARG_PTR *argv[])
  226. {
  227. INT i;
  228. static INT iLastArg = 0;
  229. for (i = iLastArg + 1; i <= iTarget; i++)
  230. if (! ISSWITCH(*(argv[i])) &&
  231. (i < iTarget || bTargetIsDir == FALSE)
  232. && (! IsDir((LPSTR)argv[i])))
  233. return(iLastArg = i);
  234. return(FAIL);
  235. }
  236. /* WIN32 MODS */
  237. /* returns 0 if not directory, 1 if so */
  238. INT IsDir(LPSTR lpszTestString)
  239. {
  240. BOOL bRetVal;
  241. bRetVal = PathType(lpszTestString);
  242. if(bRetVal == 0){ /*assert*/
  243. bRetVal++; /* this is because if lpszTestString file doesnt exist*/
  244. /* API returns 0, so I increment to 1, cause is NOT directory*/
  245. }
  246. return(--bRetVal); /* because returns 2 if dir, 1 if not*/
  247. }