$include (..\lib\compStch.ext) /* *============================================================================ * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE * * Permission to use for any purpose, modify, copy, and make enhancements * and derivative works of the software is granted if attribution is given to * R.M. Gillmore, dba the ACME Software Deli, as the author * * While the ACME Software Deli does not work for money, there is nonetheless * a significant amount of work involved. The ACME Software Deli maintains the * rights to all code written, though it may be used and distributed as long as * the following conditions are maintained. * * 1. The copyright statement at the top of each code block is maintained in * your distribution. * 2. You do not identify yourself as the ACME Software Deli * 3. Any changes made to the software are sent to the ACME Software Deli *============================================================================ */ plmStartModule: do; $if not noID declare IDString (*) byte data ( '@(#)plmStart.p86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 ); $endif $include (..\lib\comnDefs.ext) $include (..\lib\sysCalls.ext) $include (..\lib\shrt2lng.ext) $include (..\lib\string.ext) /* * since the command arguments are limited to 127 bytes, even if each argument * were only 1 byte, there could not be more than 64 arguments */ declare argStrs ( 64 ) pointer; declare argsLength word; declare savedCommandTail ( 128 ) char, envCommandName ( MAX_PATH ) char, savedCommandName ( MAX_PATH ) char; commandName: procedure ( envPtr ) pointer reentrant public; declare envPtr pointer; declare envStrPtr pointer, envStr based envStrPtr (*) byte; envStrPtr = envPtr; envStrPtr = @envStr( 0 ); /* the command name search starts here */ do while ( envStr( 0 ) <> NUL ); envStrPtr = @envStr( findb( envStrPtr, 0, 07fffh ) + 1 ); end; envStrPtr = @envStr( 3 ); call strcpy( @envCommandName( 0 ), envStrPtr ); /* * the command name is now using the short filename and mangled directory * for the names. Convert this to the longer (starting with Win95) filename * specifications */ call convertToLongName( @envCommandName, @savedCommandName ); envStrPtr = @savedCommandName; return envStrPtr; end commandName; getArgv: procedure ( numArgsPtr, argStrsPtr, envPtr, pspAddress ) reentrant public; declare numArgsPtr pointer, /* pointer to an integer */ numArgs based numArgsPtr integer, argStrsPtr pointer, /* pointer to a pointer */ argsArrayPtr based argStrsPtr pointer; declare pspAddress pointer, pspStruct based pspAddress pspStructure; declare envPtr pointer; declare dosCommandTail structure ( commandTailLength byte, commandTailStr ( 127 ) byte ); declare cmdTailIndex word, argIndex word; /* * copy the command line arguments to a safe place */ dosCommandTail.commandTailLength = pspStruct.commandTailLength; call memcpy( @dosCommandTail.commandTailStr, @pspStruct.commandTail, size( dosCommandTail.commandTailStr ) ); if ( dosCommandTail.commandTailLength < 1 ) then do; numArgs = 1; argsArrayPtr = @argStrs; end; else do; argsLength = double( dosCommandTail.commandTailLength ); call memcpy( @savedCommandTail, @dosCommandTail.commandTailStr( 0 ), argsLength ); savedCommandTail( argsLength ) = 0; /* * The command tail is in a safe place. Now we can break it * into "segments" (each nul terminated, of course) */ numArgs = 0; argIndex = 0; cmdTailIndex = 0; do while ( cmdTailIndex < argsLength ); if ( savedCommandTail( cmdTailIndex ) = SPACE ) then do; savedCommandTail( cmdTailIndex ) = NUL; cmdTailIndex = cmdTailIndex + 1; do while ( savedCommandTail( cmdTailIndex ) = SPACE ); cmdTailIndex = cmdTailIndex + 1; end; if ( savedCommandTail( cmdTailIndex ) <> SGL_QUOTE ) and ( savedCommandTail( cmdTailIndex ) <> DBL_QUOTE ) then do; argIndex = argIndex + 1; argStrs( argIndex ) = @savedCommandTail( cmdTailIndex ); end; end; else if ( savedCommandTail( cmdTailIndex ) = SGL_QUOTE ) or ( savedCommandTail( cmdTailIndex ) = DBL_QUOTE ) then do; declare quoteChar byte; quoteChar = savedCommandTail( cmdTailIndex ); cmdTailIndex = cmdTailIndex + 1; argIndex = argIndex + 1; argStrs( argIndex ) = @savedCommandTail( cmdTailIndex ); cmdTailIndex = cmdTailIndex + 1; do while ( savedCommandTail( cmdTailIndex ) <> quoteChar ); cmdTailIndex = cmdTailIndex + 1; end; savedCommandTail( cmdTailIndex ) = NUL; cmdTailIndex = cmdTailIndex + 1; end; else do; cmdTailIndex = cmdTailIndex + 1; end; end; /* while not at the end of the command tail */ numArgs = signed( argIndex ) + 1; argsArrayPtr = @argStrs; end; /* there was a command tail to parse */ /* * Get the fully-qualified name of the command. This exists even when * there is no command tail to parse */ argStrs( 0 ) = commandName( envPtr ); end getArgv; /* * This the common definition of a program's entry point. Since the calling * convention is 'C', the number of parameters (in the implementation) may * be 0-3 parameters. */ main: procedure ( numArgs, argPtrs, envPtr ) integer external; declare numArgs integer, argPtrs pointer, envPtr pointer; end main; plmStart: procedure ( pspAddress ) integer reentrant public; declare pspAddress pointer; declare numArgs integer, args pointer; declare pspStruct based pspAddress pspStructure; declare envP pointer; envP = build$ptr( pspStruct.environmentBlock, 0 ); call getArgv( @numArgs, @args, envP, pspAddress ); pspAddress = getPsp; envP = build$ptr( pspStruct.environmentBlock, 0 ); return ( main( numArgs, args, envP ) ); end plmStart; end plmStartModule;