windows-nt/Source/XPSP1/NT/base/win32/lz32/tools/compress/args.c
2020-09-26 16:20:57 +08:00

296 lines
8.3 KiB
C

/*
** args.c - Command-line argument manipulation functions.
**
** Author: DavidDi
**
** N.b., setargv.obj must be linked with this module for the command-line
** parsing to function properly.
*/
// Headers
///////////
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lz_common.h"
#include "lz_header.h"
#include "args.h"
#include "main.h"
#include "messages.h"
#include <diamondc.h>
#include "mydiam.h"
extern BOOL PathType(LPSTR lpszFileString); /* WIN32 MOD*/
// Globals
///////////
// All the globals defined in this module are set by ParseArguments().
BOOL bDoRename, // flag for performing compressed file renaming
bDisplayHelp, // flag for displaying help information
bTargetIsDir, // flag telling whether or not files are being
// compressed to a directory
bDirectives, // One or more directive files on command-line
bUpdateOnly, // flag for conditional compression based on
// existing target file's date/time stamp relative
// to source file.
bNoLogo; // flag to suppress printing copyright information
INT nNumFileSpecs, // number of non-switch, non-directory command-line
// arguments, assumed to be file specifications
iTarget; // argv[] index of target directory argument, or FAIL if
// none present
BYTE byteAlgorithm; // compression / expansion algorithm to use
TCOMP DiamondCompressionType; // 0 if not diamond (ie, LZ)
/*
** BOOL ParseArguments(int argc, char ARG_PTR *argv[]);
**
** Parse command-line arguments.
**
** Arguments: like arguments to main()
**
** Returns: TRUE if command-line arguments parsed successfully. FALSE if
** not.
**
** Globals: All globals defined in this module are set in this function,
** as described above.
*/
BOOL ParseArguments(INT argc, CHAR ARG_PTR *argv[])
{
INT i;
CHAR chSwitch;
TCOMP Level;
TCOMP Mem;
CHAR *p;
// Set up default values for globals.
bDoRename = FALSE;
bDisplayHelp = FALSE;
bTargetIsDir = FALSE;
bDirectives = FALSE;
bNoLogo = FALSE;
nNumFileSpecs = 0;
iTarget = FAIL;
byteAlgorithm = DEFAULT_ALG;
DiamondCompressionType = 0;
// Look at each command-line argument.
for (i = 1; i < argc; i++)
if (ISSWITCH(*(argv[i])))
{
// Get switch character.
chSwitch = *(argv[i] + 1);
//for bad DBCS argument
if( IsDBCSLeadByte(chSwitch) )
{
CHAR work[3];
lstrcpyn(work, argv[i] + 1, 3);
LoadString(NULL, SID_BAD_SWITCH2, ErrorMsg, 1024);
printf(ErrorMsg, work);
return(FALSE);
}
// Classify switch.
if (toupper(chSwitch) == toupper(chRENAME_SWITCH))
bDoRename = TRUE;
else if (toupper(chSwitch) == toupper(chHELP_SWITCH))
bDisplayHelp = TRUE;
else if (toupper(chSwitch) == toupper(chUPDATE_SWITCH))
bUpdateOnly = TRUE;
else if (toupper(chSwitch) == toupper(chNO_LOGO_SWITCH))
bNoLogo= TRUE;
else if (toupper(chSwitch) == toupper(chALG_SWITCH)) {
switch(*(argv[i] + 2)) {
case 'x':
case 'X':
//
// LZX. Also set memory.
//
Mem = (TCOMP)atoi(argv[i] + 3);
if((Mem < (tcompLZX_WINDOW_LO >> tcompSHIFT_LZX_WINDOW))
|| (Mem > (tcompLZX_WINDOW_HI >> tcompSHIFT_LZX_WINDOW))) {
Mem = (tcompLZX_WINDOW_LO >> tcompSHIFT_LZX_WINDOW);
}
byteAlgorithm = LZX_ALG;
DiamondCompressionType = TCOMPfromLZXWindow( Mem );
break;
case 'q':
case 'Q':
//
// Quantum. Also set level.
//
Level = (TCOMP)atoi(argv[i] + 3);
Mem = (p = strchr(argv[i]+3,',')) ? (TCOMP)atoi(p+1) : 0;
if((Level < (tcompQUANTUM_LEVEL_LO >> tcompSHIFT_QUANTUM_LEVEL))
|| (Level > (tcompQUANTUM_LEVEL_HI >> tcompSHIFT_QUANTUM_LEVEL))) {
Level = ((tcompQUANTUM_LEVEL_HI - tcompQUANTUM_LEVEL_LO) / 2)
+ tcompQUANTUM_LEVEL_LO;
Level >>= tcompSHIFT_QUANTUM_LEVEL;
}
if((Mem < (tcompQUANTUM_MEM_LO >> tcompSHIFT_QUANTUM_MEM))
|| (Mem > (tcompQUANTUM_MEM_HI >> tcompSHIFT_QUANTUM_MEM))) {
Mem = ((tcompQUANTUM_MEM_HI - tcompQUANTUM_MEM_LO) / 2)
+ tcompQUANTUM_MEM_LO;
Mem >>= tcompSHIFT_QUANTUM_MEM;
}
byteAlgorithm = QUANTUM_ALG;
DiamondCompressionType = TCOMPfromTypeLevelMemory(
tcompTYPE_QUANTUM,
Level,
Mem
);
break;
case 'l':
case 'L':
DiamondCompressionType = 0;
byteAlgorithm = DEFAULT_ALG;
break;
default:
DiamondCompressionType = tcompTYPE_MSZIP;
byteAlgorithm = MSZIP_ALG;
break;
}
} else
{
// Unrecognized switch.
LoadString(NULL, SID_BAD_SWITCH, ErrorMsg, 1024);
printf(ErrorMsg, chSwitch);
return(FALSE);
}
}
else
{
// Keep track of last non-switch command-line argument as
// destination argument.
iTarget = i;
// Determine if this is a directive file
if ( '@' == argv[i][0] )
bDirectives = TRUE;
else if (IsDir((LPSTR)argv[i]) == FALSE)
// Non-switch arguments are assumed to be file specifications.
nNumFileSpecs++;
}
// Set bTargetIsDir.
if (iTarget != FAIL)
bTargetIsDir = IsDir((LPSTR)argv[iTarget]);
// Command-line arguments parsed successsfully.
return(TRUE);
}
/*
** BOOL CheckArguments(void);
**
** Check command-line arguments for error conditions.
**
** Arguments: void
**
** Returns: BOOL - TRUE if no problems found. FALSE if problem found.
**
** Globals: none
*/
BOOL CheckArguments(VOID)
{
if (nNumFileSpecs < 1 && !bDirectives )
{
// No file specifications given.
LoadString(NULL, SID_NO_FILE_SPECS, ErrorMsg, 1024);
printf(ErrorMsg);
return(FALSE);
}
else if (nNumFileSpecs == 1 && bDoRename == FALSE && bTargetIsDir == FALSE)
{
// We don't want to process a source file on to itself.
LoadString(NULL, SID_NO_OVERWRITE, ErrorMsg, 1024);
printf(ErrorMsg, pszTargetName);
return(FALSE);
}
else if (nNumFileSpecs > 2 && bDoRename == FALSE && bTargetIsDir == FALSE)
{
// There are multiple files to process, and the destination
// specification argument is not a directory. But we weren't told to
// rename the output files. Bail out since we don't want to wipe out
// the input files.
LoadString(NULL, SID_NOT_A_DIR, ErrorMsg, 1024);
printf(ErrorMsg, pszTargetName);
return(FALSE);
}
else
// No problems encountered.
return(TRUE);
}
/*
** int GetNextFileArg(char ARG_PTR *argv[]);
**
** Find the next file name argument on the command-line.
**
** Arguments: like argument to main()
**
** Returns: int - Index in argv[] of next file name argument. FAIL if
** none found.
**
** Globals: none
*/
INT GetNextFileArg(CHAR ARG_PTR *argv[])
{
INT i;
static INT iLastArg = 0;
for (i = iLastArg + 1; i <= iTarget; i++)
if (! ISSWITCH(*(argv[i])) &&
(i < iTarget || bTargetIsDir == FALSE)
&& (! IsDir((LPSTR)argv[i])))
return(iLastArg = i);
return(FAIL);
}
/* WIN32 MODS */
/* returns 0 if not directory, 1 if so */
INT IsDir(LPSTR lpszTestString)
{
BOOL bRetVal;
bRetVal = PathType(lpszTestString);
if(bRetVal == 0){ /*assert*/
bRetVal++; /* this is because if lpszTestString file doesnt exist*/
/* API returns 0, so I increment to 1, cause is NOT directory*/
}
return(--bRetVal); /* because returns 2 if dir, 1 if not*/
}