home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assembly / talinasm.lha / xcli_parse.asm < prev   
Encoding:
Assembly Source File  |  1990-06-06  |  5.3 KB  |  174 lines

  1. ********************************************************************************
  2. * cli_parse.asm - asm replacement for cli_parse - by Talin                     *
  3. ********************************************************************************
  4. ; function
  5. ;    Copy cmdline into argline, expanding and seperating all arguments, with
  6. ;    the pointer to each argument in an array.
  7.  
  8. ; register usage:
  9. ;    d0 = process BPTR, Command Name BPTR, argument to/from AllocMem
  10. ;    d1 = current parse character, also arg to AllocMem
  11. ;    d2 = lengh of cmdline argument, also 'toupper' version of escape character
  12. ;    d3 = argc
  13. ;    d4 = max argument length
  14. ;    d5 = max slot number
  15.  
  16. ;    a0 = process ptr, command name ptr, end of cmdline ptr
  17. ;    a1 = arglin buffer
  18. ;    a2 = cmdline buffer
  19. ;    a3 = temporary argv array
  20.  
  21.             INCLUDE    "exec/types.i"
  22.             INCLUDE    "exec/alerts.i"
  23.             INCLUDE    "exec/memory.i"
  24.             INCLUDE    "libraries/dos.i"
  25.             INCLUDE    "libraries/dosextens.i"
  26.             INCLUDE    "workbench/startup.i"
  27.  
  28.             xdef    __xcli_parse
  29.  
  30. ; slotsused = xcli_parse(process, cmdline, cmdlen, buffer, maxbuf, slotarray, maxslots)
  31.  
  32. ; returns 0 if error
  33. ; note that too many args is not an error -- it simply ignores the extra args.
  34.  
  35. __xcli_parse:                ; (process, cmdlen, cmdline);
  36.             movem.l        a2/a3/d2-d5,-(sp)        ; push 6 regs = 24 bytes
  37.  
  38. ;------ get arguments from stack
  39.             move.l         4+24(sp),a0            ; get process pointer
  40.             move.l         8+24(sp),a2            ; get command buffer
  41.             move.l        12+24(sp),d2            ; get command length
  42.             move.l        16+24(sp),a1            ; get destination buffer
  43.             move.l        20+24(sp),d4            ; get size of dest buffer
  44.             move.l        24+24(sp),a3            ; get slot array
  45.             move.l        28+24(sp),d5            ; get max number of slots
  46.             add.l        a1,d4                    ; d4 = last dest address
  47.             subq.l        #1,d4                    ; don't count terminating NULL
  48.  
  49. ;------ find command name
  50.             move.l        pr_CLI(a0),d0            ; get pr_CLI field
  51.             lsl.l        #2,d0                    ; pr_CLI bcpl pointer conversion
  52.             move.l        d0,a0                    ; a0 <-- process pointer
  53.             move.l        cli_CommandName(a0),d0    ; get command name
  54.             lsl.l        #2,d0                    ; bcpl pointer conversion
  55.  
  56. ;-- copy command name
  57.             move.l        d0,a0                    ; a0 <-- commandname
  58.             moveq.l        #0,d0                    ; BCPL string length = 0
  59.             move.b        (a0)+,d0                ; size of command name
  60.             clr.b        0(a0,d0.l)                ; terminate the command name
  61.             move.l        a0,(a3)+                ; argv[0] <-- command name address
  62.             moveq        #1,d3                    ; start counting arguments
  63.  
  64. ;------ null terminate the arguments, eat trailing control characters
  65.             lea            0(a2,d2.l),a0            ; start at end of command line
  66. stripjunk:
  67.             cmp.b        #' ',-(a0)                ; if less than space
  68.             dbhi        d2,stripjunk            ; decrement
  69.  
  70.             clr.b        1(a0)                    ; null terminate command line.
  71.  
  72. ;------ start gathering arguments into buffer
  73. newarg:
  74. ;-- skip spaces
  75.             move.b        (a2)+,d1                ; get next char in command line
  76.             beq.s        parmExit                ; if zero, no more arguments.
  77.             cmp.b        #' ',d1                    ; if space
  78.             beq.s        newarg                    ;    then loop
  79.             cmp.b        #9,d1                    ; if tab
  80.             beq.s        newarg                    ;    then loop
  81.  
  82. ;-- check for argument count overflow, if d3 >= d5
  83.             cmp.w        d5,d3                    ; compare argc with ARGVSLOTS
  84.             bhs.s        parmExit                ; if overflow, then quit
  85.  
  86. ;-- push address of the next parameter
  87.             move.l        a1,(a3)+                ; argv[argc] = next argbuf loc
  88.             addq.w        #1,d3                    ; arc++
  89.  
  90. ;-- process quotes
  91.             cmp.b        #'"',d1                    ; if it's a quote
  92.             beq.s        doquote                    ; then do special
  93.  
  94. ;-- copy the parameter in
  95.             cmp.l        d4,a1
  96.             bhs.s        problem
  97.             move.b        d1,(a1)+                ; copy first character to argbuf
  98.  
  99. nextchar:
  100. ;------ null termination check
  101.             move.b        (a2)+,d1                ; get next arg char
  102.             beq.s        parmExit                ; if char == '\0' then done
  103.             cmp.b        #' ',d1                    ; if char == ' ' then
  104.             beq.s        endarg                    ; we're done with this arg.
  105.  
  106.             cmp.l        d4,a1
  107.             bhs.s        problem
  108.             move.b        d1,(a1)+                ; else move cmdline to argbuf
  109.             bra.s        nextchar                ; and do next char.
  110.  
  111. endarg:
  112.             cmp.l        d4,a1
  113.             bhs.s        problem
  114.             clr.b        (a1)+                    ; null terminate argument
  115.             bra.s        newarg                    ; and get another argument
  116.  
  117. doquote:
  118. ;------ process quoted strings
  119.             move.b        (a2)+,d1                ; get next char in quoted string
  120.             beq.s        parmExit                ; if char == '\0' then all done
  121.             cmp.b        #'"',d1                    ; if char == '"' then done
  122.             beq.s        endarg                    ; do next argument
  123.  
  124. ;-- '*' is the BCPL escape character
  125.             cmp.b        #'*',d1                    ; if it's not a '*'
  126.             bne.s        addquotechar            ; then add it to the arg
  127.  
  128.             move.b        (a2)+,d1                ; get character after '*'
  129.             move.b        d1,d2                    ; convert to upper case
  130.             and.b        #$df,d2                    ; d2 is temp toupper'd d1
  131.  
  132.             cmp.b        #'N',d2                    ; check for dos newline char
  133.             bne.s        checkEscape
  134.  
  135. ;--    got a *N -- turn into a newline
  136.             moveq        #10,d1                    ; d1 <-- newline
  137.             bra.s        addquotechar            ; add to arg
  138.  
  139. checkEscape:
  140.             cmp.b        #'E',d2                    ; check for escape
  141.             bne.s        addquotechar            ; if not, just add in char
  142.  
  143. ;--    got a *E -- turn into a escape
  144.             moveq        #27,d1                    ; else char <-- ESC
  145.  
  146. addquotechar:
  147.             cmp.l        d4,a1
  148.             bhs.s        problem
  149.             move.b        d1,(a1)+                ; add character to arg
  150.             bra.s        doquote                    ; and continue
  151.  
  152. parmExit:
  153. ;------ all done -- null terminate the arguments
  154.             clr.b        (a1)                    ; null terminate last arg
  155.             clr.l        (a3)                    ; clear argv[argc]
  156.  
  157.             move.l        d3,d0                    ; return number of args in d0
  158.  
  159. * now, copy argbuf to argv, for argc+1 items
  160.  
  161. ;            move.l        sp,a3                    ; address of temp argv array
  162. ;1$            move.l        (a3)+,(a1)+                ; copy 1 argument
  163. ;2$            dbf            d3,1$                    ; and loop
  164.  
  165.             movem.l        (sp)+,a2/a3/d2-d5
  166.             rts
  167.  
  168. problem:
  169.             moveq        #0,d0
  170.             movem.l        (sp)+,a2/a3/d2-d5
  171.             rts
  172.  
  173.             end
  174.