(* ---------------------- begin argument module --------------------------- *) (* ArgLib.pas 11 October 84. TURBO PASCAL version *) (* Get arguments from CP/M or MS-DOS Command Line, using UNIX conventions. *) (* Runs in 16-bit or 8-bit Turbo Pascal; must compile to disk (not memory) *) (* Allows writing portable and/or UNIX-compatable programs on your micro. *) (* All compiler-dependencies are marked with the word "Turbo". *) (* CAUTION: Under CP/M or MS-DOS, ALL argc and argv calls must be finished before doing ANY file operations. (Not required under UNIX.) *) (* Most pascal systems will require this to be placed after the last variable and before the first procedure of the main program. *) (* Tradeoffs: Execution speed sacrificed for compact code. Standard Pascal (ISO standard) used whenever possible (no 'string', etc.). *) (* Example use: User calls program "cp" with two files: CP FILEA FILEB * * argc --> 3 * argv(1, ) --> 'FILEA ' * argv(2, ) --> 'FILEB ' * * Note 1: The last file is argc-1, not argc. In the example, * argv(3, ) is undefined--returns all blanks. * Note 2: Under UNIX, argv(0, ) would be 'CP', but here it is blank. *) (* EXPORT: ArgStrType, argc, argv, resetOK *) (* W. Kempton, Michigan State University *) const MaxArgStrLen = 16; (* maximum characters per argument *) type ArgStrType = packed array [1..MaxArgStrLen] of char (* file name argument *); procedure argv( argn : integer; (* requesting Nth argument *) var image : ArgStrType); (* returning its char image *) (* ARGument Value. Valid argn for files are 1..(argc-1). *) (* Note: argv(0, ) incorrectly returns blank; UNIX returns program name *) const MaxCmdLineLength = 122; (* bug: 8-bit Turbo v1 & v2 chops to 31 chars *) type CmdLineType = packed array [0..MaxCmdLineLength] of char; (* System command line. Zeroth position is size.*) charset = set of char; var i, nextch, Start, ArgLen, CmdLen : integer; SYSdelim : charset; (* system file separators *) CmdLine : CmdLineType { 16-bit Turbo } { absolute DSeg : $80 ; } { 8-bit Turbo } absolute $80 ; procedure skip (delims:charset); (* skip past (via advancing "nextch") either delimiters or arguments. *) begin while (CmdLine[nextch] in delims) and (nextch <= CmdLen) do nextch := nextch + 1 end (* skip *); begin (* argv *) CmdLen := ord(CmdLine[0]); (* length of command line *) SYSdelim := { CP/M } [' ',',',';','[',']','=','<','>' {,'/','_'} ]; { MS-DOS } { [' ',',',';','[',']','=','<','>' ]; } (* more?? *) nextch := 1; Start := 1; for i := 1 to argn do begin skip(SYSdelim) (* skip leading delimiters *); Start := nextch (* overwriting all but last value *); skip([chr(0)..chr(127)]-SYSdelim) (* skip argument *); { Turbo bug prohibits [chr(0)..chr(255)]; thus 8-bit chars disallowed } end; ArgLen := nextch-Start; (* now use Start and ArgLen to set the string *) if ArgLen > MaxArgStrLen then ArgLen := MaxArgStrLen; (* image[0] := chr(ArgLen); *) (* only if string type *) for i:= 1 to ArgLen do image[i] := CmdLine[Start-1+i]; for i:= (ArgLen+1) to MaxArgStrLen do image[i] := ' '; (* blank fill *) end (* argv *); function argc : integer; (* ARGument Count, the number of parameters on the command line. *) (* This is slow, so call it just once and set an integer variable. *) var c: integer; ArgStr: ArgStrType; begin c := 0; repeat c := c+1; argv(c, ArgStr); until (ArgStr[1] = ' '); argc := c; end (* argc *); function resetOK (var f: text; name: ArgStrType) : boolean; (* Associate name with file variable. Return true if file is nonempty. *) (* This parallels the Berkeley UNIX Pascal procedure: reset(f, name). This function is not needed for UNIX compatability, but allows keeping this highly nonstandard Turbo garbage out of any programs. *) begin assign(f,name); { Turbo, non-standard } {$I- Turbo: turn off I/O checks, or reset and eof() can cause crash. } reset(f); resetOK := (IOresult = 0); { Turbo, non-standard } {$I+ Turbo: restore I/O checks } end (* resetOK *); (* ------------------------ end argument module ------------------------- *)