Annotation of os2sdk/startup/os2/stdargv.asm, revision 1.1.1.1

1.1       root        1:        TITLE   stdargv.asm - OS/2 standard & wildcard _setargv routine
                      2: ;***
                      3: ;5stdargv.asm - OS/2 standard & wildcard _setargv routine
                      4: ;
                      5: ;      Copyright (c) 1985-1987, Microsoft Corporation.  All rights reserved.
                      6: ;
                      7: ;Purpose:
                      8: ;      processes program command line, with or without wildcard expansion
                      9: ;
                     10: ;*******************************************************************************
                     11: 
                     12: ifdef  WILDCARD
                     13:        name    _setargv        ; wildcard _setargv routine
                     14: else
                     15:        name    stdargv         ; standard _setargv routine
                     16: endif
                     17: 
                     18: include        version.inc
                     19:        .xlist
                     20: include        cmacros.inc
                     21: include        msdos.inc
                     22:        .list
                     23: 
                     24: sBegin data
                     25: assumes        ds,data
                     26: 
                     27: C_BLANK        equ     ' '             ; ASCII space character
                     28: C_TAB  equ     09h             ; ASCII horizontal tab character
                     29: 
                     30: C_QUOTE        equ     '"'             ; ASCII (double) Quote Charater
                     31: C_BACKSLASH equ        '\'             ; ASCII backward slash character
                     32: 
                     33: externDP __argv                        ; argument string array address
                     34: externW        __argc                  ; count of argument strings
                     35: externW        _aenvseg                ; environment segment
                     36: externW        _acmdln                 ; offset of command line in env. seg.
                     37: externD        _pgmptr                 ; far pointer to program name
                     38: 
                     39: staticW        cmdstart,0              ; start of command line string
                     40: staticCP retadr,0              ; return address
                     41: 
                     42: ifdef  WILDCARD
                     43: 
                     44: staticW        findhandle,1            ; handle used for wildcard matching
                     45: 
                     46: FileFindBuf struc
                     47: create_date dw ?               ;* date of file creation
                     48: create_time dw ?               ;* time of file creation
                     49: access_date dw ?               ;* date of last access
                     50: access_time dw ?               ;* time of last access
                     51: write_date dw  ?               ;* date of last write
                     52: write_time dw  ?               ;* time of last write
                     53: file_size dd   ?               ;* file size (end of data)
                     54: falloc_size dd ?               ;* file allocated size
                     55: attributes dw  ?               ;* attributes of the file
                     56: string_len db  ?               ;* returned length of ascii name str.
                     57: file_name db   13 dup (?)      ;* name string
                     58: FileFindBuf ends
                     59: 
                     60: findbuf        FileFindBuf <>          ;* struct FileFindBuf findbuf;
                     61: 
                     62: endif                          ;       WILDCARD
                     63: 
                     64: sEnd   data
                     65: 
                     66: ;=========================================
                     67: 
                     68: ifdef  WILDCARD
                     69:        extrn   DOSFINDFIRST:far
                     70:        extrn   DOSFINDNEXT:far
                     71:        externP _cwild          ; Wildcard Expander
                     72: endif
                     73: 
                     74: ;=========================================
                     75: 
                     76: jmps   MACRO   target
                     77:        jmp     short target
                     78:        ENDM
                     79: 
                     80: lje    MACRO   target
                     81:        LOCAL   temp
                     82:        jne     temp
                     83:        jmp     target
                     84: temp:
                     85:        ENDM
                     86: 
                     87: DELIM  MACRO
                     88:        or      al,al           ;; Test for end-of-line character (null)
                     89:        ENDM
                     90: 
                     91: ;=========================================
                     92: 
                     93: 
                     94: sBegin code
                     95: 
                     96: externNP _stdalloc             ; routine to allocate heap memory
                     97: externNP _amsg_exit            ; error handler (unable to allocate)
                     98: 
                     99: assumes        ds,data
                    100: assumes        ss,data
                    101: assumes        cs,code
                    102: 
                    103: page
                    104: ;***
                    105: ;_setargv, __setargv - set up "argc" and "argv" for C programs
                    106: ;
                    107: ;Purpose:
                    108: ;      Read the command line and create the argv array for C
                    109: ;      programs.
                    110: ;
                    111: ;Entry:
                    112: ;      Arguments are retrieved from the program command line.
                    113: ;
                    114: ;Exit:
                    115: ;      "argv" points to a null-terminated list of pointers to ASCIZ
                    116: ;      strings, each of which is an argument from the command line.
                    117: ;      "argc" is the number of arguments.  The strings are copied from
                    118: ;      the environment segment into space allocated on the heap/stack.
                    119: ;      The list of pointers is also located on the heap or stack.
                    120: ;
                    121: ;Uses:
                    122: ;
                    123: ;Exceptions:
                    124: ;
                    125: ;*******************************************************************************
                    126: 
                    127: 
                    128: ifdef  WILDCARD                ; **********************************************
                    129: 
                    130: labelP <PUBLIC,__setargv>
                    131: 
                    132: else                           ; **********************************************
                    133: 
                    134: labelP <PUBLIC,_setargv>
                    135: 
                    136: endif                          ; WILDCARD      ; **********************************************
                    137: 
                    138:        pop     word ptr [retadr] ; get return address (offset)
                    139: 
                    140: if     sizeC
                    141:        pop     word ptr [retadr+2] ; get return address (segment)
                    142: endif
                    143:        mov     ax,_acmdln
                    144:        mov     ds,_aenvseg
                    145:        assumes ds,nothing
                    146: 
                    147:        mov     si,ax
                    148: ;
                    149: ;      If there is no argument string, use the
                    150: ;      program name for the command line string.
                    151: ;      Scan back for the null before "PgmPtr"
                    152: ;
                    153: find_argv0:
                    154:        dec     si
                    155:        jz      found_argv0
                    156:        cmp     byte ptr ds:[si-1],0
                    157:        jne     find_argv0
                    158: found_argv0:
                    159:        mov     word ptr [_pgmptr],si
                    160:        mov     word ptr [_pgmptr+2],ds
                    161:        xchg    ax,si           ; restore SI to [_acmdln]
                    162:        test    byte ptr ds:[si],-1
                    163:        jnz     store_cmdstart
                    164:        xchg    ax,si           ; use PgmPtr instead of ArgPtr
                    165: store_cmdstart:
                    166:        mov     [cmdstart],si
                    167: 
                    168:        xor     dx,dx           ; Start with zero bytes
                    169:        mov     di,1            ; Start with one arguments
                    170: count_argv0:
                    171:        lodsb
                    172:        inc     dx              ; count each byte in argv[0]
                    173:        or      al,al           ; including the terminator
                    174:        jnz     count_argv0
                    175: ;*
                    176: ;*     Count the command line arguments
                    177: ;*
                    178: ;*             ... previous environment strings ...
                    179: ;*             null byte       (end of last environment string)
                    180: ;*             null byte       (end of environment)
                    181: ;*             program name string
                    182: ;*             null byte
                    183: ;*    DS:SI ==>        raw command line string
                    184: ;*             null byte
                    185: ;*             null byte
                    186: ;*
                    187: ;*     DI      will count the number of arguments
                    188: ;*
                    189: ;*     DX      will count the number of bytes needed to
                    190: ;*             store the arguments themselves, incl. final nulls
                    191: ;*
                    192: ;*
                    193: ;*     Count the command tail arguments
                    194: ;*
                    195: ;
                    196: ;      DI will count the number of arguments
                    197: ;      DX will count the number of bytes needed for the arguments
                    198: ;              (not including the null terminators)
                    199: ;
                    200: arg100:
                    201: arg110:
                    202:        lodsb
                    203:        cmp     al,C_BLANK
                    204:        je      arg110
                    205:        cmp     al,C_TAB
                    206:        je      arg110
                    207: 
                    208:        DELIM
                    209:        je      arg400
                    210: 
                    211:        inc     di              ; Another argument
                    212: ;
                    213: ; Parse an argument
                    214: ;
                    215: arg200:
                    216:        dec     si              ; back up to reload character
                    217: arg210:
                    218:        lodsb
                    219: 
                    220:        cmp     al,C_BLANK
                    221:        je      arg100
                    222:        cmp     al,C_TAB
                    223:        je      arg100          ; white space terminates argument
                    224: 
                    225:        DELIM
                    226:        je      arg400
                    227: 
                    228:        cmp     al,C_QUOTE
                    229:        je      arg310
                    230: 
                    231:        cmp     al,C_BACKSLASH
                    232:        je      arg220
                    233: 
                    234:        inc     dx
                    235:        jmps    arg210
                    236: ;
                    237: ; Count backslashes
                    238: ;
                    239: arg220:
                    240:        xor     cx,cx
                    241: arg221:
                    242:        inc     cx              ; CX counts the backslashes
                    243:        lodsb
                    244:        cmp     al,C_BACKSLASH
                    245:        je      arg221
                    246: ;
                    247:        cmp     al,C_QUOTE
                    248:        je      arg230
                    249: 
                    250:        add     dx,cx           ; not followed by `"' -- treat `\'s normally
                    251:        jmp     arg200
                    252: ;
                    253: arg230:
                    254:        mov     ax,cx
                    255:        shr     cx,1
                    256:        adc     dx,cx           ; add 1 for every pair of backslashes
                    257:        test    al,1            ; plus 1 for the " if odd number of \
                    258:        jnz     arg210          ; " was escaped with a \
                    259:        jmps    arg310          ; " opens a quoted substring
                    260: ;
                    261: ; Enter a quoted string
                    262: ;
                    263: arg300:
                    264:        dec     si              ; back up to reload character
                    265: arg310:
                    266:        lodsb
                    267: 
                    268:        DELIM
                    269:        je      arg400
                    270: 
                    271:        cmp     al,C_QUOTE
                    272:        je      arg210          ; end of quoted portion of string
                    273: 
                    274:        cmp     al,C_BACKSLASH
                    275:        je      arg320
                    276: 
                    277:        inc     dx
                    278:        jmp     arg310
                    279: ;
                    280: ; Count backslashes
                    281: ;
                    282: arg320:
                    283:        xor     cx,cx
                    284: arg321:
                    285:        inc     cx              ; CX counts the backslashes
                    286:        lodsb
                    287:        cmp     al,C_BACKSLASH
                    288:        je      arg321
                    289: ;
                    290:        cmp     al,C_QUOTE
                    291:        je      arg330
                    292: 
                    293:        add     dx,cx           ; not followed by `"' -- treat `\'s normally
                    294:        jmp     arg300
                    295: ;
                    296: arg330:
                    297:        mov     ax,cx
                    298:        shr     cx,1
                    299:        adc     dx,cx           ; add 1 for every pair of backslashes
                    300:        test    al,1            ; plus 1 for the " if odd number of \
                    301:        jnz     arg310          ; " was escaped with a \
                    302:        jmps    arg210          ; " closes a quoted substring
                    303: ;
                    304: ; Command line is fully parsed - compute number of bytes needed
                    305: ;
                    306: arg400:
                    307: ;
                    308: ;      Number of bytes needed =
                    309: ;              Number of bytes used to make strings +
                    310: ;              Number of bytes used to terminate strings +
                    311: ;              sizeof(DATAPTR) * ( number of arguments + 1 )
                    312: ;
                    313:        push    ss
                    314:        pop     ds              ; Restore DS = DGROUP
                    315:        assumes ds,data
                    316: 
                    317:        mov     __argc,di       ; Store number of arguments
                    318: 
                    319:        add     dx,di           ; add in terminator bytes
                    320: ifdef  WILDCARD
                    321:        add     dx,di           ; add in Wildcard flag bytes
                    322: endif
                    323:        inc     di              ; add one for NULL pointer
                    324:        shl     di,1
                    325: if     sizeD
                    326:        shl     di,1
                    327: endif
                    328:        mov     ax,di
                    329:        add     ax,dx           ; add space for pointers to space for chars
                    330: 
                    331:        and     al,not 1        ; Round up to an even number of bytes
                    332: ;
                    333: ;      Allocate space on the heap (or the stack)
                    334: ;
                    335: ;      AX is the total number of bytes needed for strings and pointers
                    336: ;      DI is the number of bytes needed for the pointers
                    337: ;
                    338:        call    _stdalloc
                    339:        jnc     args_ok
                    340: arg_error:
                    341:        mov     ax,8            ;Out of heap/stack space.
                    342:        jmp     _amsg_exit
                    343: 
                    344: args_ok:
                    345:        mov     word ptr (__argv),ax
                    346: if     sizeD
                    347:        mov     word ptr (__argv+2),ds
                    348: endif
                    349: ;
                    350: ;      Copy argument strings and addresses onto heap/stack
                    351: ;              Address table is on the top, strings below that
                    352: ;
                    353:        mov     bx,ax
                    354:        add     di,ax
                    355: 
                    356:        push    ss              ; ES=SS
                    357:        pop     es              ; ES:DI is where the string copies will go
                    358:        assumes es,data
                    359: ;
                    360: ;      DS:SI   points to the argv[0]
                    361: ;
                    362: ;      ES:BX   points to where argv[0],argv[1],argv[2],... go
                    363: ;      ES:DI   points to where *argv[0],*argv[1],*argv[2],... go
                    364: ; For wildcard version only:
                    365: ;      ES:DX   points to the wildcard flag character (prepended to argument)
                    366: ;              during the creation of each argument
                    367: ;
                    368: 
                    369:        mov     ss:[bx],di      ; argv[i] - offset part
                    370: if     sizeD
                    371:        mov     ss:[bx+2],ss    ; argv[i] - segment part
                    372:        add     bx,4
                    373: else
                    374:        inc     bx
                    375:        inc     bx
                    376: endif
                    377: 
                    378:        mov     si,cmdstart     ; Get pointer to argv[0]
                    379:        mov     ds,_aenvseg
                    380:        assumes ds,nothing
                    381: 
                    382: ifdef  WILDCARD
                    383:        movsb
                    384:        dec     si              ; copy first character as quote flag
                    385: endif
                    386: 
                    387: copy_argv0:
                    388:        lodsb
                    389:        stosb
                    390:        or      al,al
                    391:        jnz     copy_argv0
                    392: ;
                    393: ;      DS:SI   points to the raw command tail string
                    394: ;
                    395: 
                    396:        jmps    arg510
                    397: ;
                    398: ;      Skip blanks
                    399: ;
                    400: arg500:
                    401:        xor     ax,ax
                    402:        stosb
                    403: arg510:
                    404:        lodsb
                    405:        cmp     al,C_BLANK
                    406:        je      arg510
                    407:        cmp     al,C_TAB
                    408:        je      arg510
                    409: 
                    410:        DELIM
                    411:        lje     arg810
                    412: 
                    413:        mov     ss:[bx],di
                    414: if     sizeD
                    415:        mov     ss:[bx+2],ss
                    416:        add     bx,4
                    417: else
                    418:        inc     bx
                    419:        inc     bx
                    420: endif
                    421: 
                    422: ifdef  WILDCARD
                    423:        mov     dx,di
                    424:        stosb                   ; initialize wildcard flag
                    425: endif
                    426: ;
                    427: ;
                    428: ; Parse an argument
                    429: ;
                    430: arg600:
                    431:        dec     si              ; back up to reload character
                    432: arg610:
                    433:        lodsb
                    434: 
                    435:        cmp     al,C_BLANK
                    436:        je      arg500
                    437:        cmp     al,C_TAB
                    438:        je      arg500          ; white space terminates argument
                    439: 
                    440:        DELIM
                    441:        je      arg800
                    442: 
                    443:        cmp     al,C_QUOTE
                    444:        je      arg710x
                    445: 
                    446:        cmp     al,C_BACKSLASH
                    447:        je      arg620
                    448: 
                    449:        stosb
                    450:        jmps    arg610
                    451: ;
                    452: ; Count backslashes
                    453: ;
                    454: arg620:
                    455:        xor     cx,cx
                    456: arg621:
                    457:        inc     cx              ; CX counts the backslashes
                    458:        lodsb
                    459:        cmp     al,C_BACKSLASH
                    460:        je      arg621
                    461: ;
                    462:        cmp     al,C_QUOTE
                    463:        je      arg630
                    464: 
                    465:        mov     al,C_BACKSLASH
                    466:        rep     stosb           ; not followed by `"' -- treat `\'s normally
                    467:        jmp     arg600
                    468: ;
                    469: arg630:
                    470:        mov     al,C_BACKSLASH
                    471:        shr     cx,1
                    472:        rep     stosb
                    473:        jnc     arg710x         ; " opens a quoted substring
                    474:        mov     al,C_QUOTE
                    475:        stosb
                    476:        jmp     arg610          ; " was escaped with a \
                    477: ;
                    478: ; Enter a quoted string
                    479: ;
                    480: ifdef  WILDCARD
                    481: arg710x:
                    482:        inc     si              ; undoes the "DEC SI" between arg700 and arg710
                    483: endif
                    484: 
                    485: arg700x:
                    486: 
                    487: ifdef  WILDCARD
                    488:        xchg    dx,di           ; set the wildcard flag character to `"'
                    489:        mov     al,C_QUOTE
                    490:        stosb
                    491:        dec     di
                    492:        xchg    dx,di
                    493: endif
                    494: 
                    495: arg700:
                    496:        dec     si              ; back up to reload character
                    497: 
                    498: ifndef WILDCARD
                    499: arg710x:
                    500: endif
                    501: 
                    502: arg710:
                    503:        lodsb
                    504: 
                    505:        DELIM
                    506:        je      arg800
                    507: 
                    508:        cmp     al,C_QUOTE
                    509:        je      arg610          ; end of quoted portion of string
                    510: 
                    511:        cmp     al,C_BACKSLASH
                    512:        je      arg720
                    513: 
                    514:        stosb
                    515:        jmp     arg710
                    516: ;
                    517: ; Count backslashes
                    518: ;
                    519: arg720:
                    520:        xor     cx,cx
                    521: arg721:
                    522:        inc     cx              ; CX counts the backslashes
                    523:        lodsb
                    524:        cmp     al,C_BACKSLASH
                    525:        je      arg721
                    526: ;
                    527:        cmp     al,C_QUOTE
                    528:        je      arg730
                    529: 
                    530:        mov     al,C_BACKSLASH
                    531:        rep     stosb           ; not followed by `"' -- treat `\'s normally
                    532:        jmp     arg700x
                    533: ;
                    534: arg730:
                    535:        mov     al,C_BACKSLASH
                    536:        shr     cx,1
                    537:        rep     stosb           ; store 1 for every pair of backslashes
                    538:        jnc     arg610          ; " closes a quoted substring
                    539:        mov     al,C_QUOTE      ; " was escaped with a \
                    540:        stosb
                    541:        jmps    arg710x
                    542: ;
                    543: ; Terminate last argument string, terminate list of argument pointers
                    544: ;
                    545: arg800:
                    546:        xor     ax,ax
                    547:        stosb                   ; null-terminate final argument
                    548: arg810:
                    549:        push    ss
                    550:        pop     ds
                    551:        assumes ds,data
                    552: 
                    553:        mov     word ptr [bx],0 ; add null pointer to __argv[]
                    554: if     sizeD
                    555:        mov     word ptr [bx+2],0
                    556: endif
                    557: 
                    558: ifndef WILDCARD
                    559:        jmp     [retadr]        ; THE END
                    560: else
                    561:        call    _cwild
                    562:        test    ax,ax
                    563:        jnz     to_arg_error
                    564:        jmp     [retadr]        ; THE END
                    565: 
                    566: to_arg_error:
                    567:        jmp     arg_error
                    568: 
                    569: page
                    570: ;***
                    571: ;_find(pattern) - find matching filename
                    572: ;
                    573: ;Purpose:
                    574: ;      if argument is non-null, do a DosFindFirst on that pattern
                    575: ;      otherwise do a DosFindNext call.  Return matching filename
                    576: ;      or NULL if no more matches.
                    577: ;
                    578: ;      char *_find(pattern)
                    579: ;             char *pattern;
                    580: ;      {
                    581: ;      static struct  FileFindBuf     findbuf;
                    582: ;      static unsigned findhandle=1;
                    583: ;                     unsigned findcount=1;
                    584: ;                     int rc;
                    585: ;
                    586: ;             if(pattern)
                    587: ;                     rc = DOSFINDFIRST((char far *) pattern,
                    588: ;                             (unsigned far *) &findhandle, A_D,
                    589: ;                             (struct FileFindBuf far *) &findbuf, sizeof(findbuf),
                    590: ;                             (unsigned far *) &findcount, 0L);
                    591: ;             else
                    592: ;                     rc = DOSFINDNEXT(findhandle,
                    593: ;                             (struct FileFindBuf far *) &findbuf, sizeof(findbuf),
                    594: ;                             (unsigned far *) &findcount);
                    595: ;
                    596: ;             return(rc ? NULL : findbuf.file_name);
                    597: ;      }
                    598: ;
                    599: ;Entry:
                    600: ;      pattern = pointer to pattern or NULL
                    601: ;                (NULL means find next matching filename)
                    602: ;
                    603: ;Exit:
                    604: ;      AX (or DX:AX) = pointer to matching file name
                    605: ;                      or NULL if no more matches.
                    606: ;
                    607: ;Uses:
                    608: ;
                    609: ;Exceptions:
                    610: ;
                    611: ;*******************************************************************************
                    612: 
                    613: cProc  _find,<PUBLIC>,<>
                    614:        parmDP  pattern
                    615: ;      localW  findcount
                    616: findcount equ  (word ptr [bp-2])
                    617: cBegin
                    618:        mov     ax,1
                    619:        push    ax              ; mov   [findcount],1
                    620:        mov     bx,dataOFFSET findbuf
                    621:        mov     dx,size findbuf
                    622:        lea     ax,findcount
                    623: ;
                    624: ;      DS:BX = &findbuf
                    625: ;      DX = sizeof(findbuf)
                    626: ;      SS:AX = &findcount
                    627: ;      CX = FP_OFF(pattern)
                    628: ;
                    629: if     sizeD
                    630:        les     cx,pattern
                    631:        cmp     word ptr [pattern+2],0
                    632:        jz      find_next
                    633: else
                    634:        mov     cx,pattern
                    635:        jcxz    find_next
                    636: endif
                    637: ;
                    638: ;      Make first call to DOSFINDFIRST
                    639: ;
                    640: if     sizeD
                    641:        push    es
                    642: else
                    643:        push    ds
                    644: endif
                    645:        push    cx              ; (char far *) pattern
                    646:        mov     cx,dataOFFSET findhandle
                    647:        mov     [findhandle],1  ; always use handle 1
                    648:        push    ds
                    649:        push    cx              ; (unsigned far *) & findhandle
                    650:        mov     cx,A_D
                    651:        push    cx              ; match attribute: normal files + directories
                    652:        push    ds
                    653:        push    bx              ; (struct FileFindBuf far *) &findbuf
                    654:        push    dx              ; sizeof(findbuf)
                    655:        push    ss
                    656:        push    ax              ; (unsigned far *) &findcount
                    657:        xor     ax,ax
                    658:        push    ax
                    659:        push    ax              ; 0L (reserved)
                    660:        call    DOSFINDFIRST
                    661:        jmp     short   check_rc
                    662: ;
                    663: ;      get next match
                    664: ;
                    665: find_next:
                    666:        push    [findhandle]    ; findhandle
                    667:        push    ds
                    668:        push    bx              ; (struct FileFindBuf far *) &findbuf
                    669:        push    dx              ; sizeof(findbuf)
                    670:        push    ss
                    671:        push    ax
                    672:        call    DOSFINDNEXT
                    673: ;
                    674: check_rc:
                    675:        add     bx,offset file_name ; BX = findbuf.file_name
                    676: if     sizeD
                    677:        mov     dx,ds
                    678: endif
                    679:        test    ax,ax           ; check for error in system call
                    680:        xchg    ax,bx           ; return findbuf.file_name if successful
                    681:        jz      rc_zero
                    682: ;
                    683:        xor     ax,ax           ; return NULL for error
                    684: if     sizeD
                    685:        cwd
                    686: endif
                    687: rc_zero:
                    688: 
                    689: cEnd
                    690: 
                    691: endif                          ;       WILDCARD
                    692: 
                    693: sEnd   code
                    694: 
                    695:        end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.