This is an OS-independent module common for all EuroTools which recognizes program arguments retrieved from the command line or from the configuration file.
Each argument starts with a slash / or hyphen - or double hyphen --.
Then follows the long or short key name terminated with equal sign = or colon :,
finally appended with the key value. The key value may be in quotes ".
The key name is case-insensitive, as well as boolean and enumerated values.
Example: euroconv /InputFile=input.txt /OutputFile=output.txt /InputEncoding=UTF-16LE /OutputEncoding=UTF-8
This example may use short key names and lower or mixed case:
euroconv /IF=input.txt /of=output.txt /ie=Utf-16le /OE=utf-8
Exception: The two arguments which specify input and output files
may be alternatively defined as ordinal operands, i. e. without the keyword and without the equal sign
=. The first ordinal specifies the InputFile and the second one specifies the OutputFile.
euroconv input.txt output.txt /InputEncoding=Utf-16LE /oe=UTF-8
is equvivalent to
euroconv.exe /InputFile="input.txt" /of=Output.txt /IE=Utf-16LE /oe=UTF-8
Each argument value can be one of four types:
eurosort /InputFile="C:\My documents\My dictionary.txt" /OF=SortedDictionary.txteurodirs /MaxDays=60
eurodirs /ScanNow=Yeseuroconv /IE=UTF-16LE /OE=UTF-8The order of keyword arguments on command-line and in the configuration file is not important. They may start with a slash / or hyphen - or double hyphen --, so they are acceptable no matter if you are used to DOS, Windows, Linux or Posix.
You will prefer short names when using the EuroTools interactively in a terminal window. On the other hand, long names should be prefered in configuration files, as they are selfdocumenting.
In the configuration file the leading character(s) / or - may be omitted. Use a new line for each argument.
Lines which begin with semicolon ; or hash # are treated as comments and ignored.Configuration files are encoded in UTF-8 both in Linux and in Windows.
| Long key name | Short key name | Type | Default value | Relevant in these EuroTools | Remark |
|---|---|---|---|---|---|
| InputFile | if | string | (not specified) | all | Also the 1st ordinal if key name is omitted. |
| OutputFile | of | string | (not specified) | all | Also the 2nd ordinal if key name is omitted. |
| ScanDir | sd | string | . (current directory) | EuroDirs | A directory where the scan files are located. |
| ExcludeDirs | ed | string | (none) | EuroDirs | Semicolon-separated dirs which should not be scanned. |
| IncludeDirs | id | string | (all) | EuroDirs | Semicolon-separated dirs which should be scanned. |
| LeaveTemporary | lt | boolean | false | EuroView, EuroText | Do not erase temporary files when the program ends (for debugging). |
| ByteOrderMark | bom | boolean | false | EuroConv | Insert BOM to the OutputFile. |
| InputEncoding | ie | enum | 0 (=autodetect) | EuroConv,EuroSort,EuroText | May be specified by number or by name. Specify /ie=? to display the list. |
| OutputEncoding | oe | enum | 65001 (=UTF-8) | EuroConv | May be specified by number or by name. |
| HeaderLength | hl | integer | 0 | EuroConv,EuroSort | Number of lines to omit at the begining of InputFile. |
| HeaderSize | hs | integer | 0 | EuroConv,EuroSort | Number of bytes to omit at the begining of InputFile. |
| FooterLength | fl | integer | 0 | EuroConv,EuroSort | Number of lines to omit at the end of InputFile. |
| FooterSize | fs | integer | 0 | EuroConv,EuroSort | Number of bytes to omit at the end of InputFile. |
| RecordSize | rs | integer | 0 (=variable) | EuroSort | Fixed size of each record in bytes, otherwise LineFeed-terminated variable size applies. |
| MaxDays | md | integer | 35 | EuroDirs | Erase scans older than MaxDays. |
| TimeZone | tz | integer | 0 | EuroDirs | Time zone in hours. /TZ=0 UTC, /TZ=1 Prague, /TX=2 Moscow etc. |
| KeyOffset | ko | integer | 0 | EuroSort | Offset of the sorting key in characters from the start of record. |
| KeyLength | kl | integer | -1 (=use entire RecordSize) | EuroSort | Length of the sorting key in characters. By default use up till the end of the record. |
| KeyReverse | kr | boolean | false | EuroSort | Sorting direction of the key is descending. |
| ScanNow | sn | boolean | false | EuroDirs | Perform the scan instead of directories compare. |
| WrapLines | wl | boolean | false | EuroText | Wrap long lines in the TEXT view.. |
| HtmlEntities | he | string | "Ignore" | EuroConv | How to treat input HTML entities: I:ignore all; C:Convert all; N:convert all but & < > " |
| InvalidCharacter | ic | string | "Question-mark" | EuroConv | How to treat invalid characters: Q:replace with ?; T:translit to ASCII; C:convert to HTML entity; O: omit |
| FileFormat | ff | enum | bin | EuroView | Select the format to interpret. Specify /ff=? to display the list. |
| ViewDirs | vd | enum | inc | EuroDirs | Select a category to display: ins|inc|unch|dec|del. |
| Locale | loc | enum | -- | EuroSort | Select national sorting preferences. Specify /loc=? to display the list. |
| UpperFirst | uf | boolean | false | EuroSort | Sort uppercase letters before lowercase ones. |
| DigitFirst | df | boolean | true | EuroSort | Sort digits before letters. |
| PunctuationFirst | pf | boolean | true | EuroSort | Sort nonalphanumeric characters before letters and digits. |
| MergeSpaces | ms | boolean | false | EuroSort | Treat multiple white spaces as a single space. |
EUROASM CPU=x64, Unicode=No
INCLUDE cpuext.htm,cpuext64.htm,string64.htm,status32.htm
argument PROGRAM Format=COFF,Width=64
Const HEAD ; HEAD..ENDHEAD section is included in all EuroTool sources.
; Boolean arguments kept in the DWORD Status::. ArgCUI EQU 0000_0001h ; Use console-mode interface (reports on standard output). ArgGUI EQU 0000_0002h ; Use graphic-mode interface. ArgScanNow EQU 0000_0004h ; Perform the scan of directories. ArgBOM EQU 0000_0008h ; Include Byte-Order-Marker in the output file. ArgKeyReverse EQU 0000_0010h ; Descending sort order. ArgWrapLines EQU 0000_0020h ; Wrap long lines in the TEXT view. ArgLeaveTemporary EQU 0000_0080h ; Do not erase temporary files. ArgPunctuationFirst EQU 0000_1000h ; Sort nonalphanumeric characters first. ArgUpperFirst EQU 0000_2000h ; Sort uppercase characters first. ArgDigitFirst EQU 0000_4000h ; Sort digits first. ArgMergeSpaces EQU 0000_8000h ; Treat multiple white spaces as s single one. ArgCalculated:: EQU 0002_0000h ; The result was just calculated. ; Internal flags in the Status::. ArgSwappedDates:: EQU 0004_0000h ; Older and newer files are swapped. ArgDescending:: EQU 0008_0000h ; Direction of EuroDirs buffer. ArgWidth16 EQU 0010_0000h ; Viewed program width=16. ArgWidth32 EQU 0020_0000h ; Viewed program width=32. ArgWidth64 EQU 0040_0000h ; Viewed program width=64. ArgWidthMask:: EQU ArgWidth16|ArgWidth32|ArgWidth64 ArgEXP:: EQU 0010_0000h ; Display E+-exponent in the result of EuroCalc. ArgDP:: EQU 0020_0000h ; Display decimal point in the result of EuroCalc. ArgPostfix:: EQU 0040_0000h ; Parsed number has a postfix. ArgDynamicLibrary:: EQU 0080_0000h ; Viewed program is DLL or ELFSO. ArgMouseCaptured:: EQU 0100_0000h ; Between WM_LBUTTONDOWN and WM_LBUTTONUP. ArgLoc? EQU 0200_0000h ; Do not output Help after a list of locales. ArgFF? EQU 0400_0000h ; Do not output Help after a list of fileformats. ArgEnc? EQU 0800_0000h ; Do not output Help after a list of encodings. ArgFromFile EQU 1000_0000h ; ArgParse will tolerate arguments not starting with / or -. ArgBigEndian:: EQU 2000_0000h ; Select UTF-16BE or UTF32BE rather than LE. ArgCancel:: EQU 4000_0000h ; Pressed [Cancel] instead of [Exec]. ArgHelpRequired EQU 8000_0000h ; Help should be printed after ErrorMessage. ; Selection of ViewDirs. ArgViewDirsIns EQU 1 ; Inserted. ArgViewDirsInc EQU 2 ; Increased. ArgViewDirsUnch EQU 3 ; Unchanged. ArgViewDirsDec EQU 4 ; Decreased. ArgViewDirsDel EQU 5 ; Deleted. ; Locales according to ISO 3166-1. ArgLocaleNone EQU ' ' ; Not specified. ArgLocaleAZ EQU 'AZ' ; Azerbaijan. ArgLocaleCZ EQU 'CZ' ; Czechia. ArgLocaleDE EQU 'DE' ; Germany. ArgLocaleDK EQU 'DK' ; Denmark. ArgLocaleEE EQU 'EE' ; Estonia. ArgLocaleES EQU 'ES' ; Spain. ArgLocaleFI EQU 'FI' ; Finland. ArgLocaleHU EQU 'HU' ; Hungary. ArgLocaleIS EQU 'IS' ; Iceland. ArgLocaleLT EQU 'LT' ; Lithuania. ArgLocaleLV EQU 'LV' ; Latvia. ArgLocaleNO EQU 'NO' ; Norway. ArgLocalePL EQU 'PL' ; Poland. ArgLocaleSE EQU 'SE' ; Sweden. ArgLocaleSK EQU 'SK' ; Slovakia. ArgLocaleTR EQU 'TR' ; Turkey.
ENDHEAD Const
[.data] ; Numeric and enumerated arguments parsed to a binary format. Status:: DD ArgCUI|ArgDigitFirst|ArgPunctuationFirst ; Default values of boolean arguments. ArgTimeZone:: DD 0 ; Default:0 (in hours). 0=UTC, 1=Prague, 2=Moscow,..23 ArgRecordSize:: DD 0 ; Default: variable size, terminated with LineFeed. ArgHeaderSize:: DD 0 ; Default: no header. ArgHeaderLength:: DD 0 ; Default: no header. ArgFooterSize:: DD 0 ; Default: no footer. ArgFooterLength:: DD 0 ; Default: no footer. ArgKeyOffset:: DD 0 ; Default: sorting key starts with the record. ArgKeyLength:: DD -1 ; Default: sorting key ends with the record. ArgMaxDays:: DD 35 ; Default: erase scans older than 35 days. ArgInputEncoding:: DD 0 ; Default: /IE=0 (no encoding specified), use autodetection. ArgOutputEncoding:: DD 65001 ; Default: use UTF-8. ArgViewDirs:: DD ArgViewDirsInc ; Default: show increased directories. ArgLocale:: DD ArgLocaleNone ; Default: do not apply any locales. ArgFileFormat:: DD 0 ; Default: /FF=0 (no format specified), use autodetection. [.bss] ; String arguments in UTF-8 encoding. ErrorMessage:: DB 2K * BYTE ; Error report when ArgParse detected wrong syntax. ArgInputFile:: DB 264 * BYTE ; Input file name in UTF-8. ArgOutputFile:: DB 264 * BYTE ; Output file name in UTF-8. ArgScanDir:: DB 264 * BYTE ; Directory name for scan files in UTF-8. ArgIncludeDirs:: DB 2K * BYTE ; Semicolons-separated directory names in UTF-8. ArgExcludeDirs:: DB 2K * BYTE ; Semicolons-separated directory names in UTF-8. ArgHtmlEntities:: DB 16 * BYTE ; Default: /HE=I. Only 1st letter I|C|N is important. ArgInvalidCharacter::DB 16 * BYTE ; Default: /IC=T. Only 1st letter T|C|Q|O is important.
[.rodata] ; Lowercase ASCII tokens.
TypeString EQU 1
TypeInteger EQU 2
TypeBoolean EQU 3
TypeEnum EQU 4
HEAD
KEY STRUC ; Description of one possible argument, e. g. the string /InputFile="Input.txt"
.KeyName D 16*BYTE ; ASCIIZ lowercase key name, e. g. inputfile.
.KeyNameSize D DWORD ; Number of bytes in key name, e. g. 9.
.KeyType D DWORD ; String=1, Integer=2, Boolean=3, Enum=4.
.KeyValue D QWORD ; Name of the argument, e. g. ArgInputFile or ArgRecordSize or ArgScanNow etc.
ENDSTRUC KEY
ENDHEAD
DeclareKey %MACRO Name,Type,Value ; Macro used for declaration of possible KEY records.
%KeyNameSize %SETS %Name ; Count the bytes of %Name at asm-time.
DS KEY, .KeyName="%Name", .KeyNameSize=%KeyNameSize, .KeyType=Type%Type, .KeyValue=%Value
%ENDMACRO DeclareKey
KEYs: ; A list of KEY objects with declaration of keyword parameters.
DeclareKey inputfile, String, ArgInputFile
DeclareKey if, String, ArgInputFile
DeclareKey outputfile, String, ArgOutputFile
DeclareKey of, String, ArgOutputFile
DeclareKey scandir, String, ArgScanDir
DeclareKey sd, String, ArgScanDir
DeclareKey includedirs, String, ArgIncludeDirs
DeclareKey id, String, ArgIncludeDirs
DeclareKey excludedirs, String, ArgExcludeDirs
DeclareKey ed, String, ArgExcludeDirs
DeclareKey htmlentities, String, ArgHtmlEntities
DeclareKey he, String, ArgHtmlEntities
DeclareKey invalidcharacter,String, ArgInvalidCharacter
DeclareKey ic, String, ArgInvalidCharacter
DeclareKey timezone, Integer,ArgTimeZone
DeclareKey tz, Integer,ArgTimeZone
DeclareKey headerlength, Integer,ArgHeaderLength
DeclareKey hl, Integer,ArgHeaderLength
DeclareKey footerlength, Integer,ArgFooterLength
DeclareKey fl, Integer,ArgFooterLength
DeclareKey headersize, Integer,ArgHeaderSize
DeclareKey hs, Integer,ArgHeaderSize
DeclareKey footersize, Integer,ArgFooterSize
DeclareKey fs, Integer,ArgFooterSize
DeclareKey recordsize, Integer,ArgRecordSize
DeclareKey rs, Integer,ArgRecordSize
DeclareKey maxdays, Integer,ArgMaxDays
DeclareKey md, Integer,ArgMaxDays
DeclareKey keyoffset, Integer,ArgKeyOffset
DeclareKey ko, Integer,ArgKeyOffset
DeclareKey keylength, Integer,ArgKeyLength
DeclareKey kl, Integer,ArgKeyLength
DeclareKey keyreverse, Boolean,ArgKeyReverse
DeclareKey kr, Boolean,ArgKeyReverse
DeclareKey scannow, Boolean,ArgScanNow
DeclareKey sn, Boolean,ArgScanNow
DeclareKey punctuationfirst,Boolean,ArgPunctuationFirst
DeclareKey pf, Boolean,ArgPunctuationFirst
DeclareKey upperfirst, Boolean,ArgUpperFirst
DeclareKey uf, Boolean,ArgUpperFirst
DeclareKey digitfirst, Boolean,ArgDigitFirst
DeclareKey df, Boolean,ArgDigitFirst
DeclareKey mergespaces, Boolean,ArgMergeSpaces
DeclareKey ms, Boolean,ArgMergeSpaces
DeclareKey leavetemporary, Boolean,ArgLeaveTemporary
DeclareKey lt, Boolean,ArgLeaveTemporary
DeclareKey gui, Boolean,ArgGUI
DeclareKey win, Boolean,ArgGUI
DeclareKey cui, Boolean,ArgCUI
DeclareKey con, Boolean,ArgCUI
DeclareKey byteordermark, Boolean,ArgBOM
DeclareKey bom, Boolean,ArgBOM
DeclareKey wraplines, Boolean,ArgWrapLines
DeclareKey wl, Boolean,ArgWrapLines
DeclareKey locale, Enum, ArgLocale
DeclareKey loc, Enum, ArgLocale
DeclareKey viewdirs, Enum, ArgViewDirs
DeclareKey vd, Enum, ArgViewDirs
DeclareKey fileformat, Enum, ArgFileFormat
DeclareKey ff, Enum, ArgFileFormat
DeclareKey inputencoding, Enum, ArgInputEncoding
DeclareKey ie, Enum, ArgInputEncoding
DeclareKey outputencoding, Enum, ArgOutputEncoding
DeclareKey oe, Enum, ArgOutputEncoding
EndKEYs:
HEAD
VAL STRUC ; Description of possible boolean or enumerated value.
.ValName D 16*BYTE ; ASCIIZ lowercase value name, e. g. true.
.ValNameSize D DWORD ; Number of bytes in value name, e. g. 4.
.ValValue D DWORD ; Numeric|boolean value, e. g. -1.
ENDSTRUC VAL
ENDHEAD
DeclareVal %MACRO Name,Value ; Macro used for declaration of VAL records.
%ValNameSize %SETS %Name ; Count the bytes in %Name at asm-time.
DS VAL, .ValName="%Name", .ValNameSize=%ValNameSize, .ValValue=%Value
%ENDMACRO DeclareVal
Bool: ; Possible boolean values.
DeclareVal true,-1
DeclareVal yes,-1
DeclareVal on,-1
DeclareVal enable,-1
DeclareVal enabled,-1
DeclareVal 1,-1
DeclareVal false,0
DeclareVal no,0
DeclareVal off,0
DeclareVal disable,0
DeclareVal disabled,0
DeclareVal 0,0
EndBool:
; Possible enumerated values.
ViewDirs:
DeclareVal ins,ArgViewDirsIns
DeclareVal inc,ArgViewDirsInc
DeclareVal unch,ArgViewDirsUnch
DeclareVal dec,ArgViewDirsDec
DeclareVal del,ArgViewDirsDel
EndViewDirs:
Locales::
DeclareVal --,ArgLocaleNone
DeclareVal az,ArgLocaleAZ
DeclareVal cz,ArgLocaleCZ
DeclareVal de,ArgLocaleDE
DeclareVal dk,ArgLocaleDK
DeclareVal ee,ArgLocaleEE
DeclareVal es,ArgLocaleES
DeclareVal fi,ArgLocaleFI
DeclareVal hu,ArgLocaleHU
DeclareVal is,ArgLocaleIS
DeclareVal lt,ArgLocaleLT
DeclareVal lv,ArgLocaleLV
DeclareVal no,ArgLocaleNO
DeclareVal pl,ArgLocalePL
DeclareVal se,ArgLocaleSE
DeclareVal sk,ArgLocaleSK
DeclareVal tr,ArgLocaleTR
EndLocales::
HEAD
%FileFormats %SET \ List of recognizable file formats:
OMF,LIBOMF, \ OMF object and library,
COFF16,COFF32,COFF64,LIBCOF, \ COFF object and library,
ELF32,ELF64,ELFSO32,ELFSO64, \ ELF object and library,
ELFX32,ELFX64, \ Linux executable,
PE32,PE64,DLL32,DLL64, \ Windows executable and library,
MZ, \ DOS executable,
WAV,MIDI,MP3, \ sound files,
CUR,ICO,BMP,GIF,PNG,JPG, \ various graphic,
BIN ; otherwise view as a plain dump (BIN).
%i %SETA 1 ; MZ and BIN formats should be the last.
FF %FOR %FileFormats
ArgFileFormat%FF EQU %i ; Assign a number to each format.
%i %SETA %i+1
%ENDFOR FF
ENDHEAD
; Declaration of VAL members with file format is made in the %FOR loop. Examples:
; DeclareVal coff32,ArgFileFormatCOFF32
; DeclareVal mz ,ArgFileFormatMZ etc.
FileFormat::
FF %FOR %FileFormats
%Size %SETS %FF ; Number of characters in FileFormat name.
%LoCase %SET
c %FOR 1..%Size
%CHAR %SET %FF[%c]
%char %SETC "%CHAR" | 0x20 ; Convert to lower case.
%LoCase %SET %LoCase%char
%ENDFOR c
DeclareVal %LoCase,ArgFileFormat%FF
%ENDFOR FF
EndFileFormat::
; Declaration of encodings is special: DeclareVal is automatically using the third item of
; CodePages declaration, such as "ASCII", "IBM437" etc.
; Macro CP will be used to read the file codepage.htm
and to feed the macro DeclareVal.
CP %MACRO Value,Name ; Ad-hoc declaration of macro CP uses only the first two arguments of CodePages definitions.
%NameSize %SETS %Name ; Number of characters in Name, including two quotes.
%LoCase %SET ; Start with an empty name.
i %FOR 2..%NameSize-1 ; Omit both quotes.
%ch %SETC "%Name[%i]"|0x20 ; %ch is now the lower case of %i-th character in %Name.
%LoCase %SET %LoCase%ch ; Append the lower case character.
%ENDFOR i
DeclareVal %Value,%Value ; Declare by the numeric identificator, e. g. "20127", "437" etc.
DeclareVal %LoCase,%Value ; Declare by the main codepage name, e. g. "ascii", "ibm437" etc.
%ENDMACRO CP
Encodings::
INCLUDE "codepage.htm" ; DeclareVal for code pages.
EndEncodings::
[.data] ; Temporary local working variables of this module used for parsing of arguments.
ALIGN QWORD
InpPtr D QWORD
InpSize D QWORD
ValPtr D QWORD
ValSize D QWORD
OneKey D 32*BYTE
OneVal D 16*BYTE
LineFeed DB 13,10,0
argument.objwhose name begin with Arg*. Arguments are stored as a zero-terminated string in UTF8 encoding (both for Linux and Windows) or as a 32bit integer number or as a flag in Status::.
[.text]
ArgParse:: PROC ; RSI,RCX is the line with one argument in UTF-8.
MOVB [ErrorMessage],0
StripSpaces RSI,RCX ; Get rid of white spaces at the beginning.
TEST RCX
JZ .90:
MOV [InpPtr],RSI
MOV [InpSize],RCX
LEA RDX,[RSI+RCX]
MOV RDI,RSI
MOV AL,[RSI]
Dispatch AL,2Fh,2Dh,22h,3Bh,23h; Jump to the labels / - " ; #
; Argument starts with ordinary letter, it might be input/output file name.
JSt [Status],ArgFromFile,.16: ; Arguments from cfg file need not start with / or -.
.10: LEA RDI,[ArgInputFile] ; Argument does not start with / or -. It must be an I/O file.
CMPB [RDI],0 ; Input file was not specified yet?
JZ .13:
LEA RDI,[ArgOutputFile]
CMPB [RDI],0 ; Output file was not specified yet?
JNE .ErrorFiles:
.13: REPE MOVSB ; Store the file name.
JMP .90: ; CF=0.
.22h: StripQuotes RSI,RCX ; Argument starts with quote, get rid of it.
JMP .10:
.2Dh: ; - / ; Argument starts with - or /.
.2Fh: LODSB ; Swallow the first - or /.
DEC ECX
CMPB [RSI],'-'
JNE .16:
LODSB ; Swallow the second -.
DEC ECX
.16: MOV AL,'=' ; A keyname is expected, search for = or :.
MOV RDI,RSI ; First letter of the keyname.
PUSH RCX
REPNE SCASB
POP RCX
JE .20:
MOV AL,':'
MOV RDI,RSI
REPNE SCASB
JNE .ErrorEqual:
.20: LEA RCX,[RDI-1] ; RCX at the equal sign.
MOV [ValPtr],RDI
PUSH RSI
MOV RSI,RDI ; Value may be in quotes.
.23: CMP RSI,RDX
JNB .36:
MOV [ValPtr],RSI
LODSB
CMP AL,' ' ; Value may start with space(s).
JBE .23:
CMP AL,';'
JNE .24:
XOR ESI,ESI ; ValSize=0.
JMP .40:
.24: CMP AL,'"'
JNE .30:
MOV [ValPtr],RSI ; Argument value was in quotes.
.26: CMP RSI,RDX
JAE .36:
LODSB
CMP AL,'"'
JNE .26:
DEC RSI
JMP .36:
.30: DEC RSI
MOV [ValPtr],RSI ; Value is ordinary, e.g. Key=Value.
.33: CMP RSI,RDX
JNB .36:
LODSB
CMP AL,';'
JE .35:
CMP AL,' '
JA .33:
.35: DEC RSI
.36: SUB RSI,[ValPtr]
.40: MOV [ValSize],RSI
POP RSI
SUB RCX,RSI
MOV EDX,ECX ; EDX=RCX=key size, RSI=key pointer.
LEA RDI,[OneKey]
AND ECX,0x0000_001F
.43: LODSB
OR AL,0010_0000b ; Convert to lower case.
STOSB
LOOP .43:
LEA RBX,[KEYs:]
LEA RAX,[EndKEYs]
SUB RBX,SIZE# KEY
.46: ADD RBX,SIZE# KEY
CMP RBX,RAX
CMC
JC .ErrorWrongKey: ; End of KEYs and still not found.
CMP EDX,[RBX+KEY.KeyNameSize]
JNE .46:
LEA RSI,[RBX+KEY.KeyName]
LEA RDI,[OneKey]
MOV ECX,EDX
REPE CMPSB
JNE .46:
MOV EAX,[RBX+KEY.KeyType] ; A key was found.
MOV RSI,[ValPtr]
MOV ECX,[ValSize] ; RSI,RCX is the netto value, e. g. input.txt or IBM437 or 0 etc.
TEST ECX
JZ .90:
Dispatch EAX,TypeInteger,TypeBoolean,TypeEnum
;.TypeString:
MOV RDI,[RBX+KEY.KeyValue]
Dispatch RDI,ArgInputFile, ArgOutputFile, ArgHtmlEntities, ArgInvalidCharacter
REP MOVSB ; Copy the string to the Arg* destination.
XOR EAX,EAX
STOSB ; NUL-terminate.
JMP .90:
.ArgHtmlEntities:
REP MOVSB ; Copy the string to the Arg* destination.
XOR EAX,EAX
STOSB
MOV AL,[ArgHtmlEntities]
AND AL,~('i'^'I') ; Convert to upper case.
MOV [ArgHtmlEntities],AL
Dispatch AL,'I','C','N'
JMP .ErrorWrongKey:
.ArgInvalidCharacter:
REP MOVSB ; Copy the string to the Arg* destination.
XOR EAX,EAX
STOSB
MOV AL,[ArgInvalidCharacter]
AND AL,~('i'^'I') ; Convert to upper case.
MOV [ArgInvalidCharacter],AL
Dispatch AL,'T','C','Q','O'
JMP .ErrorWrongKey:
.I:
.N:
.T:
.C:
.Q:
.O:
JMP .90:
.ArgInputFile:
LEA RDI,[ArgInputFile]
CMPB [RDI+0],0
JNZ .ErrorInput:
.50: REP MOVSB
XOR EAX,EAX
STOSB
JMP .90:
.ArgOutputFile:
LEA RDI,[ArgOutputFile]
CMPB [RDI+0],0
JNZ .ErrorOutput:
JMP .50:
.TypeInteger:
LodD RSI ; Convert to binary.
JC .ErrorWrongNumber:
MOV RDI,[RBX+KEY.KeyValue]
MOV [RDI],EAX ; Store the number.
JMP .90:
.TypeBoolean:
MOV EDX,ECX
TEST RCX
JZ .ErrorWrongBool:
AND ECX,0x0000_000F ; Limit the value size.
LEA RDI,[OneVal]
.55: LODSB
OR AL,0010_0000b ; Convert to lower case ASCII.
STOSB
LOOP .55:
PUSH RBX ; Save pointer to KEY record.
LEA RBX,[Bool]
LEA RAX,[EndBool]
CALL .FindOneVal:
MOV EAX,[RBX+VAL.ValValue] ; Set to 0 or -1.
POP RBX
JC .ErrorWrongBool:
TEST EAX
MOV RAX,[RBX+KEY.KeyValue] ; KeyValue is a small constant specifying the bit number in Status, e. g. ArgScanNow=4, ArgBOM=10h etc.
JZ .60: ; Jump if FALSE.
OR [Status],EAX ; Set the bit to TRUE.
JMP .90: ; Return with CF=0.
.60: NOT EAX ; Invert the value.
AND [Status],EAX ; Set the bit to FALSE.
JMP .90: ; Return with CF=0.
NOP
.TypeEnum:
NOP
LEA RDI,[OneVal]
MOV EDX,ECX
MOV EAX,[RBX+KEY.KeyValue]
TEST ECX
JNZ .64:
MOV [EAX],ECX
JMP .90:
.64: AND ECX,0x0000_000F ; Limit the value size.
.65: LODSB
OR AL,0010_0000b ; Convert to lower case ASCII.
STOSB
LOOP .65:
MOV RAX,[RBX+KEY.KeyValue]
MOV RDI,RAX
Dispatch EAX,ArgViewDirs,ArgFileFormat,ArgLocale,ArgInputEncoding,ArgOutputEncoding
JMP .90:
.ArgViewDirs:
PUSH RBX ; Pointer to KEY.
LEA RBX,[ViewDirs]
LEA RAX,[EndViewDirs]
CALL .FindOneVal:
MOV EAX,[RBX+VAL.ValValue]
POP RBX
JC .ErrorWrongView:
MOV [RDI],EAX
JMP .90:
.ArgFileFormat:
PUSH RBX ; Pointer to KEY.
LEA RBX,[FileFormat]
LEA RAX,[EndFileFormat]
CALL .FindOneVal:
MOV EAX,[RBX+VAL.ValValue]
POP RBX
JC .ErrorWrongFormat:
MOV [RDI],EAX
JMP .90:
.ArgLocale:
PUSH RBX ; Pointer to KEY.
LEA RBX,[Locales]
LEA RAX,[EndLocales]
CALL .FindOneVal:
MOV EAX,[RBX+VAL.ValValue]
POP RBX
JC .ErrorWrongLocale:
MOV [RDI],EAX
JMP .90:
.ArgInputEncoding:
.ArgOutputEncoding:
PUSH RBX ; Pointer to KEY.
LEA RBX,[Encodings]
LEA RAX,[EndEncodings]
CALL .FindOneVal:
MOV EAX,[RBX+VAL.ValValue]
POP RBX
JC .ErrorWrongEncoding:
MOV [RDI],EAX
JMP .90:
.FindOneVal: PROC ; Subprocedure to find a value of boolean or enumerated argument.
; Input: RBX..RAX point to an array of VAL records. OneVal,RDX is the value.
; Output: CF=0, RBX=^VAL with the found value. CF=1 if not found. Clobbers: RCX,RSI.
PUSH RDI
SUB RBX,SIZE# VAL
.F5::ADD RBX,SIZE# VAL
CMP RBX,RAX ; At the end of VAL records?
CMC
JC .F9: ; End of VAL records and still not found: error.
CMP EDX,[RBX+VAL.ValNameSize]
JNE .F5::
LEA RSI,[RBX+VAL.ValName]
LEA RDI,[OneVal] ; Here is the value from argument.
MOV ECX,EDX
REPE CMPSB
JNE .F5:: ; If not found, search further.
.F9:POP RDI
RET
ENDP .FindOneVal:
.ErrorFiles:
LEA RSI,[=B'input and output files were already specified. Unexpected ']
JMP .80:
.ErrorEqual:
LEA RSI,[=B'missing equal sign ']
JMP .80:
.ErrorWrongKey:
LEA RSI,[=B'unknown key ']
SetSt [Status],ArgHelpRequired
JMP .80:
.ErrorInput:
LEA RSI,[=B'wrong input file ']
JMP .80:
.ErrorOutput:
LEA RSI,[=B'wrong output file ']
JMP .80:
.ErrorWrongNumber:
LEA RSI,[=B'wrong number ']
JMP .80:
.ErrorWrongBool:
LEA RSI,[=B'wrong boolean value ']
JMP .80:
.ErrorWrongLocale:
LEA RSI,[=B'wrong locale value ']
SetSt [Status],ArgLoc?
JMP .80:
.ErrorWrongFormat:
LEA RSI,[=B'wrong file format specification ']
SetSt [Status],ArgFF?
JMP .80:
.ErrorWrongView:
LEA RSI,[=B'wrong view ']
SetSt [Status],ArgHelpRequired
JMP .80:
.ErrorWrongEncoding:
LEA RSI,[=B'wrong encoding ']
SetSt [Status],ArgEnc?
; JMP .80:
.80: LEA RDI,[ErrorMessage]
Concat$ RDI,Size=SIZE#ErrorMessage,LineFeed,=B"Error: ",RSI
XOR EAX,EAX
MOV ECX,SIZE#ErrorMessage
REPNE SCASB
DEC RDI
MOV RSI,[InpPtr]
MOV RCX,[InpSize]
CMP RCX,264
JB .E1:
MOV ECX,264
.E1: REP MOVSB
MOV EAX,0x0000_0A0D
STOSD
LEA RDI,[ErrorMessage]
XOR EAX,EAX
MOV ECX,SIZE#ErrorMessage
REPNE SCASB
DEC RDI
JNSt [Status],ArgLoc?,.E4:
LEA RSI,[=B'Valid locales: ']
MOV ECX,15
REP MOVSB
LEA RBX,[Locales:]
LEA RDX,[EndLocales:]
.E2: CMP RBX,RDX
JNB .E3:
LEA RSI,[RBX+VAL.ValName]
MOV ECX,[RBX+VAL.ValNameSize]
REP MOVSB
MOV AX,', '
STOSW
ADD RBX,SIZE# VAL
JMP .E2:
.E3: SUB RDI,2
MOV EAX,0x0000_0A0D
STOSD
JMP .E9:
.E4: JNSt [Status],ArgFF?,.E6:
LEA RSI,[=B'Valid file formats: ']
MOV ECX,20
REP MOVSB
LEA RBX,[FileFormat:]
LEA EDX,[EndFileFormat:]
.E5: CMP RBX,RDX
JNB .E6:
LEA RSI,[RBX+VAL.ValName]
MOV ECX,[RBX+VAL.ValNameSize]
REP MOVSB
MOV AX,', '
STOSW
ADD RBX,SIZE# VAL
JMP .E5:
.E6: JNSt [Status],ArgEnc?,.E9:
LEA RSI,[=B'Valid encodings: ']
MOV ECX,17
REP MOVSB
LEA RBX,[Encodings]
LEA EDX,[EndEncodings]
.E7: CMP RBX,RDX
JNB .E8:
LEA RSI,[RBX+VAL.ValName]
MOV ECX,[RBX+VAL.ValNameSize]
REP MOVSB
MOV AX,', '
STOSW
ADD RBX,SIZE# VAL
JMP .E7:
.E8: SUB RDI,2
MOV EAX,0x0000_0A0D
STOSD
.E9: STC ; Return from ArgParse with CF=1. ErrorMessage is set.
.23h: ; # ; Line begins with #, it is a comment. Return CF=0.
.3Bh: ; Line begins with semicolon, it is a comment.
.90: RET ; Return with CF=0.
ENDP ArgParse
ENDPROGRAM argument