diff options
Diffstat (limited to 'v4.0/src/CMD/COMMAND/TBATCH2.ASM')
| -rw-r--r-- | v4.0/src/CMD/COMMAND/TBATCH2.ASM | 753 |
1 files changed, 753 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/TBATCH2.ASM b/v4.0/src/CMD/COMMAND/TBATCH2.ASM new file mode 100644 index 0000000..501c637 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TBATCH2.ASM | |||
| @@ -0,0 +1,753 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tbatch2.asm 4.2 85/07/22 | ||
| 3 | ; SCCSID = @(#)tbatch2.asm 4.2 85/07/22 | ||
| 4 | TITLE Batch processing routines part II | ||
| 5 | |||
| 6 | INCLUDE comsw.asm | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE comequ.asm | ||
| 13 | .list | ||
| 14 | .cref | ||
| 15 | |||
| 16 | |||
| 17 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 18 | EXTRN BATCH:WORD | ||
| 19 | EXTRN Batch_Abort:byte | ||
| 20 | EXTRN call_batch_flag:byte | ||
| 21 | EXTRN call_flag:byte | ||
| 22 | EXTRN IFFlag:BYTE | ||
| 23 | EXTRN In_Batch:byte | ||
| 24 | EXTRN Nest:word | ||
| 25 | EXTRN PIPEFILES:BYTE | ||
| 26 | EXTRN RETCODE:WORD | ||
| 27 | EXTRN SINGLECOM:WORD | ||
| 28 | DATARES ENDS | ||
| 29 | |||
| 30 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 31 | EXTRN BADLAB_PTR:WORD | ||
| 32 | EXTRN BatBufLen:WORD | ||
| 33 | EXTRN IFTAB:BYTE | ||
| 34 | EXTRN SYNTMES_PTR:WORD | ||
| 35 | TRANDATA ENDS | ||
| 36 | |||
| 37 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 38 | EXTRN arg:byte ; the arg structure! | ||
| 39 | EXTRN BatBuf:BYTE | ||
| 40 | EXTRN BatBufEnd:WORD | ||
| 41 | EXTRN BatBufPos:WORD | ||
| 42 | EXTRN BATHAND:WORD | ||
| 43 | EXTRN COMBUF:BYTE | ||
| 44 | EXTRN DIRBUF:BYTE | ||
| 45 | EXTRN GOTOLEN:WORD | ||
| 46 | EXTRN if_not_count:word | ||
| 47 | EXTRN IFNOTFLAG:BYTE | ||
| 48 | EXTRN RESSEG:WORD | ||
| 49 | TRANSPACE ENDS | ||
| 50 | |||
| 51 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 52 | |||
| 53 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 54 | |||
| 55 | EXTRN cerror:near | ||
| 56 | EXTRN docom1:near | ||
| 57 | EXTRN tcommand:near | ||
| 58 | |||
| 59 | public $if,iferlev,goto,shift,ifexists,ifnot,forerror,$call | ||
| 60 | |||
| 61 | |||
| 62 | Break <GetBatByt - retrieve a byte from the batch file> | ||
| 63 | |||
| 64 | ; Get one byte from the batch file and return it in AL. End-of-file returns | ||
| 65 | ; <CR> and ends batch mode. DS must be set to resident segment. | ||
| 66 | ; AH, DX destroyed. | ||
| 67 | |||
| 68 | Procedure GETBATBYT,NEAR | ||
| 69 | |||
| 70 | ASSUME DS:RESGROUP | ||
| 71 | |||
| 72 | SaveReg <BX,CX,DS> | ||
| 73 | test byte ptr [Batch_Abort],-1 | ||
| 74 | jnz BatEOF | ||
| 75 | TEST Batch,-1 | ||
| 76 | JZ BatEOF | ||
| 77 | PUSH ES | ||
| 78 | MOV ES,Batch | ||
| 79 | ASSUME ES:NOTHING | ||
| 80 | ADD WORD PTR ES:[BatSeek],1 | ||
| 81 | ADC WORD PTR ES:[BatSeek+2],0 | ||
| 82 | POP ES | ||
| 83 | ; | ||
| 84 | ; See if we have bytes buffered... | ||
| 85 | ; | ||
| 86 | MOV AX,CS | ||
| 87 | MOV DS,AX | ||
| 88 | ASSUME DS:TranGroup | ||
| 89 | MOV BX,BatBufPos | ||
| 90 | CMP BX,-1 | ||
| 91 | JNZ UnBuf | ||
| 92 | ; | ||
| 93 | ; There are no bytes in the buffer. Let's try to fill it up. | ||
| 94 | ; | ||
| 95 | MOV DX,OFFSET TranGROUP:BatBuf | ||
| 96 | MOV CX,BatBufLen ; max to read. | ||
| 97 | MOV BX,BatHand | ||
| 98 | MOV AH,READ | ||
| 99 | INT int_command ; Get one more byte from batch file | ||
| 100 | jnc bat_read_ok ;AN022; if no error - continue | ||
| 101 | invoke get_ext_error_number ;AN022; get the error | ||
| 102 | push ds ;AN022; save local segment | ||
| 103 | mov ds,[resseg] ;AN022; get resident segment | ||
| 104 | assume ds:resgroup ;AN022; | ||
| 105 | mov dx,ax ;AN022; put error in DX | ||
| 106 | invoke output_batch_name ;AN022; set up to print the error | ||
| 107 | pop ds ;AN022; | ||
| 108 | assume ds:trangroup ;AN022; | ||
| 109 | invoke std_eprintf ;AN022; print out the error | ||
| 110 | mov byte ptr combuf+2,end_of_line_in;AN022; terminate the batch line for parsing | ||
| 111 | mov byte ptr combuf+3,end_of_line_out ;AN022; terminate the batch line for output | ||
| 112 | jmp bateof ;AN022; terminate the batch file | ||
| 113 | |||
| 114 | bat_read_ok: ;AN022; | ||
| 115 | MOV CX,AX | ||
| 116 | JCXZ BATEOFDS | ||
| 117 | MOV BatBufEnd,CX | ||
| 118 | XOR BX,BX | ||
| 119 | MOV BatBufPos,BX | ||
| 120 | ; | ||
| 121 | ; Buffered bytes! | ||
| 122 | ; | ||
| 123 | UnBuf: | ||
| 124 | MOV AL,BatBuf[BX] ; get next byte | ||
| 125 | INC BX | ||
| 126 | CMP BX,BatBufEnd ; beyond end of buffer? | ||
| 127 | JB SetBufPos | ||
| 128 | MOV BX,-1 | ||
| 129 | |||
| 130 | SetBufPos: | ||
| 131 | MOV BatBufPos,BX | ||
| 132 | CMP AL,1AH ; ^Z for termination? | ||
| 133 | jnz GetByteDone | ||
| 134 | |||
| 135 | BatEOFDS: | ||
| 136 | ASSUME DS:TranGroup | ||
| 137 | MOV DS,ResSeg | ||
| 138 | ASSUME DS:ResGroup | ||
| 139 | |||
| 140 | BATEOF: | ||
| 141 | invoke BatchOff | ||
| 142 | CALL BATCLOSE | ||
| 143 | MOV AL,0DH ; If end-of-file, then end of line | ||
| 144 | test byte ptr [Batch_Abort],-1 | ||
| 145 | mov byte ptr [Batch_Abort],0 | ||
| 146 | jz Cont_Get_Byt | ||
| 147 | mov di,offset TRANGROUP:COMBUF+2 ; reset pointer to beginning of buffer | ||
| 148 | xor cx,cx ; zero line length | ||
| 149 | jmp short GetByteDone | ||
| 150 | |||
| 151 | Cont_Get_Byt: | ||
| 152 | CMP [SINGLECOM],0FFF0H ; See if we need to set SINGLECOM | ||
| 153 | JNZ GetByteDone | ||
| 154 | CMP NEST,0 ;G See if we have nested batch files | ||
| 155 | JNZ GETBYTEDONE ;G Yes - don't exit just yet | ||
| 156 | MOV [SINGLECOM],-1 ; Cause termination | ||
| 157 | |||
| 158 | GetByteDone: | ||
| 159 | RestoreReg <DS,CX,BX> | ||
| 160 | |||
| 161 | return | ||
| 162 | |||
| 163 | EndProc GetBatByt | ||
| 164 | |||
| 165 | break <$If - conditional execution> | ||
| 166 | assume ds:trangroup,es:trangroup | ||
| 167 | |||
| 168 | IFERRORP: | ||
| 169 | POP AX | ||
| 170 | IFERROR: | ||
| 171 | FORERROR: | ||
| 172 | MOV DX,OFFSET TRANGROUP:SYNTMES_ptr | ||
| 173 | JMP CERROR | ||
| 174 | |||
| 175 | $IF: | ||
| 176 | ; | ||
| 177 | ; Turn off any pipes in progress. | ||
| 178 | ; | ||
| 179 | push ds ;AN004; save local DS | ||
| 180 | mov ds,[resseg] ;AN004; get resident segment | ||
| 181 | assume ds:resgroup ;AN004; | ||
| 182 | cmp [PIPEFILES],0 ;AN004; Only turn off if present. | ||
| 183 | jz IFNoPipe ;AN004; no pipe - continue | ||
| 184 | invoke PipeDel ;AN004; turn off piping | ||
| 185 | |||
| 186 | IFNoPipe: ;AN004; | ||
| 187 | pop ds ;AN004; get local DS back | ||
| 188 | assume ds:trangroup ;AN004; | ||
| 189 | MOV [IFNOTFLAG],0 | ||
| 190 | mov [if_not_count], 0 | ||
| 191 | MOV SI,81H | ||
| 192 | |||
| 193 | IFREENT: | ||
| 194 | invoke SCANOFF | ||
| 195 | CMP AL,0DH | ||
| 196 | JZ IFERROR | ||
| 197 | MOV BP,SI | ||
| 198 | MOV DI,OFFSET TRANGROUP:IFTAB ; Prepare to search if table | ||
| 199 | MOV CH,0 | ||
| 200 | |||
| 201 | IFINDCOM: | ||
| 202 | MOV SI,BP | ||
| 203 | MOV CL,[DI] | ||
| 204 | INC DI | ||
| 205 | JCXZ IFSTRING | ||
| 206 | JMP SHORT FIRSTCOMP | ||
| 207 | |||
| 208 | IFCOMP: | ||
| 209 | JNZ IF_DIF ;AC000; | ||
| 210 | |||
| 211 | FIRSTCOMP: | ||
| 212 | LODSB | ||
| 213 | MOV AH,ES:[DI] | ||
| 214 | INC DI | ||
| 215 | CMP AL,AH | ||
| 216 | JZ IFLP | ||
| 217 | OR AH,20H ; Try lower case | ||
| 218 | CMP AL,AH | ||
| 219 | |||
| 220 | IFLP: | ||
| 221 | LOOP IFCOMP | ||
| 222 | |||
| 223 | IF_DIF: ;AC000; | ||
| 224 | LAHF | ||
| 225 | ADD DI,CX ; Bump to next position without affecting flags | ||
| 226 | MOV BX,[DI] ; Get handler address | ||
| 227 | INC DI | ||
| 228 | INC DI | ||
| 229 | SAHF | ||
| 230 | JNZ IFINDCOM | ||
| 231 | LODSB | ||
| 232 | CMP AL,0DH | ||
| 233 | |||
| 234 | IFERRORJ: | ||
| 235 | JZ IFERROR | ||
| 236 | invoke DELIM | ||
| 237 | JNZ IFINDCOM | ||
| 238 | invoke SCANOFF | ||
| 239 | JMP BX | ||
| 240 | |||
| 241 | IFNOT: | ||
| 242 | NOT [IFNOTFLAG] | ||
| 243 | inc [if_not_count] | ||
| 244 | JMP IFREENT | ||
| 245 | |||
| 246 | ; | ||
| 247 | ; We are comparing two strings for equality. First, find the end of the | ||
| 248 | ; first string. | ||
| 249 | ; | ||
| 250 | |||
| 251 | IFSTRING: | ||
| 252 | PUSH SI ; save away pointer for later compare | ||
| 253 | XOR CX,CX ; count of chars in first string | ||
| 254 | |||
| 255 | FIRST_STRING: | ||
| 256 | LODSB ; get character | ||
| 257 | CMP AL,0DH ; end of line? | ||
| 258 | JZ IFERRORP ; yes => error | ||
| 259 | invoke DELIM ; is it a delimiter? | ||
| 260 | JZ EQUAL_CHECK ; yes, go find equal sign | ||
| 261 | INC CX ; remember 1 byte for the length | ||
| 262 | JMP FIRST_STRING ; go back for more | ||
| 263 | ; | ||
| 264 | ; We have found the end of the first string. Unfortunately, we CANNOT use | ||
| 265 | ; scanoff to find the next token; = is a valid separator and will be skipped | ||
| 266 | ; over. | ||
| 267 | ; | ||
| 268 | |||
| 269 | EQUAL_CHECK: | ||
| 270 | CMP AL,'=' ; is char we have an = sign? | ||
| 271 | JZ EQUAL_CHECK2 ; yes, go find second one. | ||
| 272 | CMP AL,0DH ; end of line? | ||
| 273 | JZ IFERRORPj ;AC004; yes, syntax error | ||
| 274 | LODSB ; get next char | ||
| 275 | JMP EQUAL_CHECK | ||
| 276 | ; | ||
| 277 | ; The first = has been found. The next char had better be an = too. | ||
| 278 | ; | ||
| 279 | |||
| 280 | EQUAL_CHECK2: | ||
| 281 | LODSB ; get potential = char | ||
| 282 | CMP AL,'=' ; is it good? | ||
| 283 | jnz iferrorpj ; no, error | ||
| 284 | ; | ||
| 285 | ; Find beginning of second string. | ||
| 286 | ; | ||
| 287 | invoke SCANOFF | ||
| 288 | CMP AL,0DH | ||
| 289 | jz iferrorpj | ||
| 290 | POP DI | ||
| 291 | ; | ||
| 292 | ; DS:SI points to second string | ||
| 293 | ; CX has number of chars in first string | ||
| 294 | ; ES:DI points to first string | ||
| 295 | ; | ||
| 296 | ; Perform compare to elicit match | ||
| 297 | ; | ||
| 298 | REPE CMPSB | ||
| 299 | JZ MATCH ; match found! | ||
| 300 | ; | ||
| 301 | ; No match. Let's find out what was wrong. The character that did not match | ||
| 302 | ; has been advanced over. Let's back up to it. | ||
| 303 | ; | ||
| 304 | DEC SI | ||
| 305 | ; | ||
| 306 | ; If it is EOL, then syntax error | ||
| 307 | ; | ||
| 308 | CMP BYTE PTR [SI],0DH | ||
| 309 | JZ IFERRORJ | ||
| 310 | ; | ||
| 311 | ; Advance pointer over remainder of unmatched text to next delimiter | ||
| 312 | ; | ||
| 313 | |||
| 314 | SKIPSTRINGEND: | ||
| 315 | LODSB | ||
| 316 | |||
| 317 | NOTMATCH: | ||
| 318 | CMP AL,0DH | ||
| 319 | |||
| 320 | IFERRORJ2: | ||
| 321 | JZ IFERRORJ | ||
| 322 | invoke DELIM | ||
| 323 | JNZ SKIPSTRINGEND | ||
| 324 | ; | ||
| 325 | ; Signal that we did NOT have a match | ||
| 326 | ; | ||
| 327 | MOV AL,-1 | ||
| 328 | JMP SHORT IFRET | ||
| 329 | |||
| 330 | iferrorpj: | ||
| 331 | jmp iferrorp | ||
| 332 | ; | ||
| 333 | ; The compare succeeded. Was the second string longer than the first? We | ||
| 334 | ; do this by seeing if the next char is a delimiter. | ||
| 335 | ; | ||
| 336 | |||
| 337 | MATCH: | ||
| 338 | LODSB | ||
| 339 | invoke DELIM | ||
| 340 | JNZ NOTMATCH ; not same. | ||
| 341 | XOR AL,AL | ||
| 342 | JMP SHORT IFRET | ||
| 343 | |||
| 344 | IFEXISTS: | ||
| 345 | ifexist_attr EQU attr_hidden+attr_system | ||
| 346 | |||
| 347 | moredelim: | ||
| 348 | lodsb ; move command line pointer over | ||
| 349 | invoke delim ; pathname -- have to do it ourselves | ||
| 350 | jnz moredelim ; 'cause parse_file_descriptor is dumb | ||
| 351 | mov DX, OFFSET TRANGROUP:dirbuf | ||
| 352 | trap set_dma | ||
| 353 | mov BX, 2 ; if(0) [|not](|1) exist[1|2] file(2|3) | ||
| 354 | add BX, [if_not_count] | ||
| 355 | mov AX, OFFSET TRANGROUP:arg.argv | ||
| 356 | invoke argv_calc ; convert arg index to pointer | ||
| 357 | mov DX, [BX].argpointer ; get pointer to supposed filename | ||
| 358 | mov CX, ifexist_attr ; filetypes to search for | ||
| 359 | trap Find_First ; request first match, if any | ||
| 360 | jc if_ex_c ; carry is how to determine error | ||
| 361 | xor AL, AL | ||
| 362 | jmp ifret | ||
| 363 | |||
| 364 | if_ex_c: | ||
| 365 | mov AL, -1 ; false 'n' fall through... | ||
| 366 | |||
| 367 | IFRET: | ||
| 368 | TEST [IFNOTFLAG],-1 | ||
| 369 | JZ REALTEST | ||
| 370 | NOT AL | ||
| 371 | |||
| 372 | REALTEST: | ||
| 373 | OR AL,AL | ||
| 374 | JZ IFTRUE | ||
| 375 | JMP TCOMMAND | ||
| 376 | |||
| 377 | IFTRUE: | ||
| 378 | invoke SCANOFF | ||
| 379 | MOV CX,SI | ||
| 380 | SUB CX,81H | ||
| 381 | SUB DS:[80H],CL | ||
| 382 | MOV CL,DS:[80H] | ||
| 383 | MOV [COMBUF+1],CL | ||
| 384 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 385 | CLD | ||
| 386 | REP MOVSB | ||
| 387 | MOV AL,0DH | ||
| 388 | STOSB | ||
| 389 | ; | ||
| 390 | ; Signal that an IF was done. This prevents the redirections from getting | ||
| 391 | ; lost. | ||
| 392 | ; | ||
| 393 | PUSH DS | ||
| 394 | MOV DS,ResSeg | ||
| 395 | ASSUME DS:RESGROUP | ||
| 396 | MOV IFFlag,-1 | ||
| 397 | POP DS | ||
| 398 | ASSUME DS:TRANGROUP | ||
| 399 | ; | ||
| 400 | ; Go do the command | ||
| 401 | ; | ||
| 402 | JMP DOCOM1 | ||
| 403 | |||
| 404 | iferrorj3: | ||
| 405 | jmp iferrorj2 | ||
| 406 | |||
| 407 | IFERLEV: | ||
| 408 | MOV BH,10 | ||
| 409 | XOR BL,BL | ||
| 410 | |||
| 411 | GETNUMLP: | ||
| 412 | LODSB | ||
| 413 | CMP AL,0DH | ||
| 414 | jz iferrorj3 | ||
| 415 | invoke DELIM | ||
| 416 | JZ GOTNUM | ||
| 417 | SUB AL,'0' | ||
| 418 | XCHG AL,BL | ||
| 419 | MUL BH | ||
| 420 | ADD AL,BL | ||
| 421 | XCHG AL,BL | ||
| 422 | JMP SHORT GETNUMLP | ||
| 423 | |||
| 424 | GOTNUM: | ||
| 425 | PUSH DS | ||
| 426 | MOV DS,[RESSEG] | ||
| 427 | ASSUME DS:RESGROUP | ||
| 428 | MOV AH,BYTE PTR [RETCODE] | ||
| 429 | POP DS | ||
| 430 | ASSUME DS:TRANGROUP | ||
| 431 | XOR AL,AL | ||
| 432 | CMP AH,BL | ||
| 433 | JAE IFRET | ||
| 434 | DEC AL | ||
| 435 | JMP SHORT IFRET | ||
| 436 | |||
| 437 | |||
| 438 | break <Shift - advance arguments> | ||
| 439 | assume ds:trangroup,es:trangroup | ||
| 440 | |||
| 441 | ; | ||
| 442 | ; Shift the parameters in the batch structure by 1 and set up the new argument. | ||
| 443 | ; This is a NOP if no batch in progress. | ||
| 444 | ; | ||
| 445 | |||
| 446 | Procedure Shift,NEAR | ||
| 447 | |||
| 448 | MOV DS,[RESSEG] | ||
| 449 | ASSUME DS:RESGROUP | ||
| 450 | MOV AX,[BATCH] ; get batch pointer | ||
| 451 | OR AX,AX ; in batch mode? | ||
| 452 | retz ; no, done. | ||
| 453 | MOV ES,AX ; operate in batch segment | ||
| 454 | MOV DS,AX | ||
| 455 | |||
| 456 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 457 | |||
| 458 | ; | ||
| 459 | ; Now move the batch args down by 1 word | ||
| 460 | ; | ||
| 461 | MOV DI,BatParm ; point to parm table | ||
| 462 | LEA SI,[DI+2] ; make source = dest + 2 | ||
| 463 | MOV CX,9 ; move 9 parameters | ||
| 464 | REP MOVSW ; SHIFT down | ||
| 465 | ; | ||
| 466 | ; If the last parameter (the one not moved) is empty (= -1) then we are done. | ||
| 467 | ; We have copied it into the previous position | ||
| 468 | ; | ||
| 469 | CMP WORD PTR [DI],-1 ; if last one was not in use then | ||
| 470 | retz ; No new parm | ||
| 471 | ; | ||
| 472 | ; This last pointer is NOT nul. Get it and scan to find the next argument. | ||
| 473 | ; Assume, first, that there is no next argument | ||
| 474 | ; | ||
| 475 | MOV SI,[DI] | ||
| 476 | MOV WORD PTR [DI],-1 ; Assume no parm | ||
| 477 | ; | ||
| 478 | ; The parameters are CR separated. Scan for end of this parm | ||
| 479 | ; | ||
| 480 | SKIPCRLP: | ||
| 481 | LODSB | ||
| 482 | CMP AL,0DH | ||
| 483 | JNZ SKIPCRLP | ||
| 484 | ; | ||
| 485 | ; We are now pointing at next arg. If it is 0 (end of original line) then we | ||
| 486 | ; are finished. There ARE no more parms and the pointer has been previously | ||
| 487 | ; initialized to indicate it. | ||
| 488 | ; | ||
| 489 | CMP BYTE PTR [SI],0 | ||
| 490 | retz ; End of parms | ||
| 491 | MOV [DI],SI ; Pointer to next parm as %9 | ||
| 492 | |||
| 493 | return | ||
| 494 | |||
| 495 | EndProc Shift | ||
| 496 | |||
| 497 | ; | ||
| 498 | ; Skip delim reads bytes from the batch file until a non-delimiter is seen. | ||
| 499 | ; returns char in AL, carry set -> eof | ||
| 500 | ; | ||
| 501 | |||
| 502 | Procedure SkipDelim,NEAR | ||
| 503 | |||
| 504 | ASSUME DS:ResGroup,ES:NOTHING | ||
| 505 | TEST Batch,-1 | ||
| 506 | JZ SkipErr ; batch file empty. OOPS! | ||
| 507 | CALL GetBatByt ; get a char | ||
| 508 | invoke Delim ; check for ignoreable chars | ||
| 509 | JZ SkipDelim ; ignore this char. | ||
| 510 | clc | ||
| 511 | return | ||
| 512 | |||
| 513 | SkipErr: | ||
| 514 | stc | ||
| 515 | return | ||
| 516 | |||
| 517 | EndProc SkipDelim | ||
| 518 | |||
| 519 | break $Call | ||
| 520 | |||
| 521 | ; CALL is an internal command that transfers control to a .bat, .exe, or | ||
| 522 | ; .com file. This routine strips the CALL off the command line, sets | ||
| 523 | ; the CALL_FLAG to indicate a call in progress, and returns control to | ||
| 524 | ; DOCOM1 in TCODE to reprocess the command line and execute the file | ||
| 525 | ; being CALLed. | ||
| 526 | |||
| 527 | $CALL: | ||
| 528 | |||
| 529 | ; strip off CALL from command line | ||
| 530 | |||
| 531 | ASSUME DS:trangroup,ES:trangroup | ||
| 532 | push si | ||
| 533 | push di | ||
| 534 | push ax | ||
| 535 | push cx | ||
| 536 | mov si,offset trangroup:combuf+2 | ||
| 537 | invoke scanoff ;get to first non-delimeter | ||
| 538 | add si,length_call ;point to char past CALL | ||
| 539 | mov di,offset trangroup:combuf+2 | ||
| 540 | mov cx,combuflen-length_call ;get length of buffer | ||
| 541 | rep movsb ;move it | ||
| 542 | pop cx | ||
| 543 | pop ax | ||
| 544 | pop di | ||
| 545 | pop si | ||
| 546 | |||
| 547 | |||
| 548 | ; set call flag to indicate call in progress | ||
| 549 | |||
| 550 | push ds | ||
| 551 | mov ds,[resseg] | ||
| 552 | ASSUME DS:resgroup,ES:resgroup | ||
| 553 | mov call_flag, call_in_progress | ||
| 554 | mov call_batch_flag, call_in_progress | ||
| 555 | ; | ||
| 556 | ; Turn off any pipes in progress. | ||
| 557 | ; | ||
| 558 | cmp [PIPEFILES],0 ; Only turn off if present. | ||
| 559 | jz NoPipe | ||
| 560 | invoke PipeDel | ||
| 561 | NoPipe: | ||
| 562 | pop ds | ||
| 563 | |||
| 564 | ret | ||
| 565 | |||
| 566 | break Goto | ||
| 567 | |||
| 568 | GOTO: | ||
| 569 | |||
| 570 | assume ds:trangroup,es:trangroup | ||
| 571 | MOV DS,[RESSEG] | ||
| 572 | ASSUME DS:RESGROUP | ||
| 573 | TEST [BATCH],-1 | ||
| 574 | retz ; If not in batch mode, a nop | ||
| 575 | XOR DX,DX | ||
| 576 | PUSH DS | ||
| 577 | MOV DS,Batch | ||
| 578 | MOV WORD PTR DS:[BatSeek],DX ; Back to start | ||
| 579 | MOV WORD PTR DS:[BatSeek+2],DX ; Back to start | ||
| 580 | POP DS | ||
| 581 | |||
| 582 | GotoOpen: | ||
| 583 | invoke promptBat | ||
| 584 | MOV DI,FCB+1 ; Get the label | ||
| 585 | MOV CX,11 | ||
| 586 | MOV AL,' ' | ||
| 587 | REPNE SCASB | ||
| 588 | JNZ NOINC | ||
| 589 | INC CX | ||
| 590 | |||
| 591 | NOINC: | ||
| 592 | SUB CX,11 | ||
| 593 | NEG CX | ||
| 594 | MOV [GOTOLEN],CX | ||
| 595 | ; | ||
| 596 | ; At beginning of file. Skip to first non-delimiter char | ||
| 597 | ; | ||
| 598 | CALL SkipDelim | ||
| 599 | JC BadGoto | ||
| 600 | CMP AL,':' | ||
| 601 | JZ CHKLABEL | ||
| 602 | |||
| 603 | LABLKLP: ; Look for the label | ||
| 604 | CALL GETBATBYT | ||
| 605 | CMP AL,0AH | ||
| 606 | JNZ LABLKTST | ||
| 607 | ; | ||
| 608 | ; At beginning of line. Skip to first non-delimiter char | ||
| 609 | ; | ||
| 610 | CALL SkipDelim | ||
| 611 | JC BadGoto | ||
| 612 | CMP AL,':' | ||
| 613 | JZ CHKLABEL | ||
| 614 | |||
| 615 | LABLKTST: | ||
| 616 | TEST [BATCH],-1 | ||
| 617 | JNZ LABLKLP | ||
| 618 | |||
| 619 | BadGoto: | ||
| 620 | CALL BATCLOSE | ||
| 621 | PUSH CS | ||
| 622 | POP DS | ||
| 623 | MOV DX,OFFSET TRANGROUP:BADLAB_ptr | ||
| 624 | JMP CERROR | ||
| 625 | |||
| 626 | ; | ||
| 627 | ; Found the :. Skip to first non-delimiter char | ||
| 628 | ; | ||
| 629 | |||
| 630 | CHKLABEL: | ||
| 631 | CALL SkipDelim | ||
| 632 | JC BadGoto | ||
| 633 | MOV DI,FCB+1 | ||
| 634 | MOV CX,[GOTOLEN] | ||
| 635 | JMP SHORT GotByte | ||
| 636 | |||
| 637 | NEXTCHRLP: | ||
| 638 | PUSH CX | ||
| 639 | CALL GETBATBYT | ||
| 640 | POP CX | ||
| 641 | |||
| 642 | GotByte: | ||
| 643 | INVOKE TESTKANJ ;AN000; 3/3/KK | ||
| 644 | JZ NOTKANJ1 ;AN000; 3/3/KK | ||
| 645 | CMP AL, ES:[DI] ;AN000; 3/3/KK | ||
| 646 | JNZ LABLKTST ;AN000; 3/3/KK | ||
| 647 | INC DI ;AN000; 3/3/KK | ||
| 648 | DEC CX ;AN000; 3/3/KK | ||
| 649 | JCXZ LABLKTST ;AN000; 3/3/KK | ||
| 650 | PUSH CX ;AN000; 3/3/KK | ||
| 651 | CALL GETBATBYT ;AN000; 3/3/KK | ||
| 652 | POP CX ;AN000; 3/3/KK | ||
| 653 | CMP AL, ES:[DI] ;AN000; 3/3/KK | ||
| 654 | JMP SHORT KNEXTLABCHR ;AN000; 3/3/KK | ||
| 655 | |||
| 656 | NOTKANJ1: ;AN000; 3/3/KK | ||
| 657 | OR AL,20H | ||
| 658 | CMP AL,ES:[DI] | ||
| 659 | JNZ TRYUPPER | ||
| 660 | JMP SHORT NEXTLABCHR | ||
| 661 | |||
| 662 | TRYUPPER: | ||
| 663 | SUB AL,20H | ||
| 664 | CMP AL,ES:[DI] | ||
| 665 | |||
| 666 | KNEXTLABCHR: ;AN000; 3/3/KK | ||
| 667 | JNZ LABLKTST | ||
| 668 | |||
| 669 | NEXTLABCHR: | ||
| 670 | INC DI | ||
| 671 | LOOP NEXTCHRLP | ||
| 672 | CALL GETBATBYT | ||
| 673 | cmp [GOTOLEN],8 ; Is the label atleast 8 chars long? | ||
| 674 | jge gotocont ; Yes, then the next char doesn't matter | ||
| 675 | CMP AL,' ' | ||
| 676 | JA LABLKTST | ||
| 677 | |||
| 678 | gotocont: | ||
| 679 | CMP AL,0DH | ||
| 680 | JZ SKIPLFEED | ||
| 681 | |||
| 682 | TONEXTBATLIN: | ||
| 683 | CALL GETBATBYT | ||
| 684 | CMP AL,0DH | ||
| 685 | JNZ TONEXTBATLIN | ||
| 686 | |||
| 687 | SKIPLFEED: | ||
| 688 | CALL GETBATBYT | ||
| 689 | CALL BatClose | ||
| 690 | |||
| 691 | return | ||
| 692 | |||
| 693 | Procedure BatClose,NEAR | ||
| 694 | |||
| 695 | MOV BX,CS:[BATHAND] | ||
| 696 | CMP BX,5 | ||
| 697 | JB CloseReturn | ||
| 698 | MOV AH,CLOSE | ||
| 699 | INT int_command | ||
| 700 | |||
| 701 | CloseReturn: | ||
| 702 | mov byte ptr [In_Batch],0 ; reset flag | ||
| 703 | return | ||
| 704 | |||
| 705 | EndProc BatClose | ||
| 706 | |||
| 707 | ; | ||
| 708 | ; Open the BATCH file, If open fails, AL is drive of batch file (A=1) | ||
| 709 | ; Also, fills internal batch buffer. If access denied, then AX = -1 | ||
| 710 | ; | ||
| 711 | |||
| 712 | Procedure BatOpen,NEAR | ||
| 713 | |||
| 714 | ASSUME DS:RESGROUP,ES:TRANGROUP | ||
| 715 | |||
| 716 | PUSH DS | ||
| 717 | MOV DS,[BATCH] | ||
| 718 | ASSUME DS:NOTHING | ||
| 719 | |||
| 720 | MOV DX,BatFile | ||
| 721 | MOV AX,OPEN SHL 8 | ||
| 722 | INT int_command ; Open the batch file | ||
| 723 | JC SETERRDL | ||
| 724 | MOV DX,WORD PTR DS:[BatSeek] | ||
| 725 | MOV CX,WORD PTR DS:[BatSeek+2] | ||
| 726 | POP DS | ||
| 727 | ASSUME DS:RESGROUP | ||
| 728 | |||
| 729 | MOV [BATHAND],AX | ||
| 730 | MOV BX,AX | ||
| 731 | MOV AX,LSEEK SHL 8 ; Go to the right spot | ||
| 732 | INT int_command | ||
| 733 | MOV BatBufPos,-1 ; nuke batch buffer position | ||
| 734 | |||
| 735 | return | ||
| 736 | |||
| 737 | SETERRDL: | ||
| 738 | MOV BX,DX | ||
| 739 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 740 | mov dx,ax ;AN022; save extended error in DX | ||
| 741 | MOV AL,[BX] ; Get drive spec | ||
| 742 | SUB AL,'@' ; A = 1 | ||
| 743 | POP DS | ||
| 744 | STC ; SUB mucked over carry | ||
| 745 | |||
| 746 | return | ||
| 747 | |||
| 748 | EndProc BatOpen | ||
| 749 | |||
| 750 | |||
| 751 | TRANCODE ENDS | ||
| 752 | END | ||
| 753 | \ No newline at end of file | ||