windows-nt/Source/XPSP1/NT/base/fs/utils/replace/argument.cxx

423 lines
13 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
Argument
Abstract:
Argument processing for the Replace utility
Author:
Ramon Juan San Andres (ramonsa) 01-May-1991
Notes:
The arguments accepted by the Replace utility are:
Source path.- Source path.
Destination path.- Destination path.
Add switch.- Adds new files to the target directory instead of
replacing existing one. Cannot use with Subdir
switch or CompareTime switch.
Prompt switch.- Prompts before adding/replacing a file.
ReadOnly switch.- Replaces red-only files as well as regular files.
Subdir switch.- Recurses along the destination path.
CompareTime switch.-Replaces only thos files on the target path that
are older than the corresponding file in the
source path.
Wait switch.- Waits for the user to type any key before starting.
Help switch.- Displays usage
Revision History:
--*/
#include "ulib.hxx"
#include "arg.hxx"
#include "arrayit.hxx"
#include "file.hxx"
#include "system.hxx"
#include "replace.hxx"
#define MATCH_ALL_PATTERN "*"
#define CURRENT_DIRECTORY (LPWSTR)L"."
//
// Global variables (global to the module)
//
PPATH_ARGUMENT SourcePathArgument = NULL;
PPATH_ARGUMENT DestinationPathArgument = NULL;
PFLAG_ARGUMENT AddArgument = NULL;
PFLAG_ARGUMENT PromptArgument = NULL;
PFLAG_ARGUMENT ReadOnlyArgument = NULL;
PFLAG_ARGUMENT SubdirArgument = NULL;
PFLAG_ARGUMENT CompareTimeArgument = NULL;
PFLAG_ARGUMENT WaitArgument = NULL;
PFLAG_ARGUMENT HelpArgument = NULL;
BOOLEAN HelpSwitch;
VOID
REPLACE::SetArguments(
)
/*++
Routine Description:
Obtains the arguments for the Replace utility
Arguments:
None.
Return Value:
None.
Notes:
--*/
{
//
// Allocate things
//
if (//
// Get the argument patterns
//
!_AddPattern.Initialize( (LPWSTR)L"/A" ) ||
!_PromptPattern.Initialize( (LPWSTR)L"/P" ) ||
!_ReadOnlyPattern.Initialize( (LPWSTR)L"/R" ) ||
!_SubdirPattern.Initialize( (LPWSTR)L"/S" ) ||
!_CompareTimePattern.Initialize( (LPWSTR)L"/U" ) ||
!_WaitPattern.Initialize( (LPWSTR)L"/W" ) ||
!_HelpPattern.Initialize( (LPWSTR)L"/?" ) ||
//
// Get our parsing preferences
//
!_Switches.Initialize( (LPWSTR)L"/-" ) ||
!_MultipleSwitch.Initialize( (LPWSTR)L"/APRSUW?" ) ||
//
// Create the arguments
//
((SourcePathArgument = NEW PATH_ARGUMENT) == NULL ) ||
((DestinationPathArgument = NEW PATH_ARGUMENT) == NULL ) ||
((AddArgument = NEW FLAG_ARGUMENT) == NULL ) ||
((PromptArgument = NEW FLAG_ARGUMENT) == NULL ) ||
((ReadOnlyArgument = NEW FLAG_ARGUMENT) == NULL ) ||
((SubdirArgument = NEW FLAG_ARGUMENT) == NULL ) ||
((CompareTimeArgument = NEW FLAG_ARGUMENT) == NULL ) ||
((WaitArgument = NEW FLAG_ARGUMENT) == NULL ) ||
((HelpArgument = NEW FLAG_ARGUMENT) == NULL )
) {
DisplayMessageAndExit ( REPLACE_ERROR_NO_MEMORY,
NULL,
EXIT_NO_MEMORY );
}
//
// Parse the arguments
//
GetArgumentsCmd();
//
// Verify the arguments
//
CheckArgumentConsistency();
//
// Clean up
//
DELETE( SourcePathArgument );
DELETE( DestinationPathArgument );
DELETE( AddArgument );
DELETE( PromptArgument );
DELETE( ReadOnlyArgument );
DELETE( SubdirArgument );
DELETE( CompareTimeArgument );
DELETE( WaitArgument );
DELETE( HelpArgument );
}
VOID
REPLACE::GetArgumentsCmd(
)
/*++
Routine Description:
Obtains the arguments from the Command line
Arguments:
None.
Return Value:
None
Notes:
--*/
{
ARRAY ArgArray;
PATH_ARGUMENT ProgramNameArgument;
DSTRING CmdLine;
//
// Prepare for parsing
//
if (//
// Initialize the arguments
//
!(CmdLine.Initialize( GetCommandLine() )) ||
!(ArgArray.Initialize( 10, 10 )) ||
!(ProgramNameArgument.Initialize( MATCH_ALL_PATTERN )) ||
!(SourcePathArgument->Initialize( MATCH_ALL_PATTERN, FALSE)) ||
!(DestinationPathArgument->Initialize( MATCH_ALL_PATTERN, TRUE )) ||
!(AddArgument->Initialize( &_AddPattern )) ||
!(PromptArgument->Initialize( &_PromptPattern )) ||
!(ReadOnlyArgument->Initialize( &_ReadOnlyPattern )) ||
!(SubdirArgument->Initialize( &_SubdirPattern )) ||
!(CompareTimeArgument->Initialize( &_CompareTimePattern )) ||
!(WaitArgument->Initialize( &_WaitPattern )) ||
!(HelpArgument->Initialize( &_HelpPattern )) ||
//
// Put the arguments in the argument array
//
!(ArgArray.Put( &ProgramNameArgument )) ||
!(ArgArray.Put( AddArgument )) ||
!(ArgArray.Put( PromptArgument )) ||
!(ArgArray.Put( ReadOnlyArgument )) ||
!(ArgArray.Put( SubdirArgument )) ||
!(ArgArray.Put( CompareTimeArgument )) ||
!(ArgArray.Put( WaitArgument )) ||
!(ArgArray.Put( HelpArgument )) ||
!(ArgArray.Put( SourcePathArgument )) ||
!(ArgArray.Put( DestinationPathArgument ))
) {
DisplayMessageAndExit( REPLACE_ERROR_NO_MEMORY,
NULL,
EXIT_NO_MEMORY );
}
//
// Parse the arguments
//
ParseArguments( &CmdLine, &ArgArray );
//
// Set the switches
//
_AddSwitch = AddArgument->QueryFlag();
_PromptSwitch = PromptArgument->QueryFlag();
_ReadOnlySwitch = ReadOnlyArgument->QueryFlag();
_SubdirSwitch = SubdirArgument->QueryFlag();
_CompareTimeSwitch = CompareTimeArgument->QueryFlag();
_WaitSwitch = WaitArgument->QueryFlag();
HelpSwitch = HelpArgument->QueryFlag();
//
// Set the source and destination paths.
//
if ( SourcePathArgument->IsValueSet() ) {
if ((_SourcePath = SourcePathArgument->GetPath()->QueryPath()) == NULL ) {
DisplayMessageAndExit( REPLACE_ERROR_NO_MEMORY, NULL, EXIT_NO_MEMORY );
}
} else {
_SourcePath = NULL;
}
if ( DestinationPathArgument->IsValueSet() ) {
if ((_DestinationPath = DestinationPathArgument->GetPath()->QueryFullPath()) == NULL ) {
DisplayMessageAndExit( REPLACE_ERROR_NO_MEMORY, NULL, EXIT_NO_MEMORY );
}
} else {
_DestinationPath = NULL;
}
}
VOID
REPLACE::ParseArguments(
IN PWSTRING CmdLine,
OUT PARRAY ArgArray
)
/*++
Routine Description:
Parses a group of arguments
Arguments:
CmdLine - Supplies pointer to a command line to parse
ArgArray - Supplies pointer to array of arguments
Return Value:
none
Notes:
--*/
{
ARGUMENT_LEXEMIZER ArgLex;
ARRAY LexArray;
//
// Initialize lexeme array and the lexemizer.
//
if ( !(LexArray.Initialize( 8, 8 )) ||
!(ArgLex.Initialize( &LexArray )) ) {
DisplayMessageAndExit( REPLACE_ERROR_NO_MEMORY,
NULL,
EXIT_NO_MEMORY );
}
//
// Set our parsing preferences
//
ArgLex.PutMultipleSwitch( &_MultipleSwitch );
ArgLex.PutSwitches( &_Switches );
ArgLex.SetCaseSensitive( FALSE );
ArgLex.PutSeparators( " /\t" );
ArgLex.PutStartQuotes( "\"" );
ArgLex.PutEndQuotes( "\"" );
//
// Parse the arguments
//
if ( !(ArgLex.PrepareToParse( CmdLine ))) {
DisplayMessageAndExit( REPLACE_ERROR_PARSE,
NULL,
EXIT_COMMAND_LINE_ERROR );
}
if ( !ArgLex.DoParsing( ArgArray ) ) {
DisplayMessageAndExit( REPLACE_ERROR_INVALID_SWITCH,
ArgLex.QueryInvalidArgument(),
EXIT_COMMAND_LINE_ERROR );
}
}
VOID
REPLACE::CheckArgumentConsistency (
)
/*++
Routine Description:
Checks the consistency of the arguments
Arguments:
none
Return Value:
none
Notes:
--*/
{
PFSN_FILE File = NULL;
if ( HelpSwitch ) {
//
// Help requested
//
Usage();
}
//
// Make sure that we have a source path
//
if ( _SourcePath == NULL ) {
DisplayMessageAndExit( REPLACE_ERROR_SOURCE_PATH_REQUIRED,
NULL,
EXIT_COMMAND_LINE_ERROR );
}
//
// The add switch cannot be specified together with the Subdir or the
// CompareTime switch.
//
if ( _AddSwitch && (_SubdirSwitch || _CompareTimeSwitch)) {
DisplayMessageAndExit( REPLACE_ERROR_INVALID_PARAMETER_COMBINATION,
NULL,
EXIT_COMMAND_LINE_ERROR );
}
//
// If destination path is null, then the destination path is the
// current directory
//
if ( _DestinationPath == NULL ) {
if ( ((_DestinationPath = NEW PATH) == NULL ) ||
!_DestinationPath->Initialize( CURRENT_DIRECTORY, TRUE ) ) {
DisplayMessageAndExit( REPLACE_ERROR_NO_MEMORY,
NULL,
EXIT_NO_MEMORY );
}
} else if ( (_DestinationPath->HasWildCard()) ||
((File = SYSTEM::QueryFile( _DestinationPath )) != NULL) ) {
DisplayMessageAndExit( REPLACE_ERROR_PATH_NOT_FOUND,
_DestinationPath->GetPathString(),
EXIT_PATH_NOT_FOUND );
}
DELETE( File );
}