1 2SECTION code_clib 3SECTION code_l 4 5PUBLIC l_command_line_parse_in_place 6 7EXTERN asm_isspace 8 9l_command_line_parse_in_place: 10 11 ; * parse command line into words in place 12 ; * return argc and argv 13 ; * return pointer to redirector string if '>' or '<' found 14 ; * command line length capped at 255 chars 15 ; 16 ; enter : hl = & command line 17 ; bc = number of chars in command line 18 ; (limited to 255 chars here) 19 ; 20 ; note : *(hl+bc) will be set to 0 21 ; 22 ; exit : bc = int argc 23 ; hl = char *argv[] 24 ; hl' = & redirector in command line (0 if none) 25 ; bc' = num chars remaining in redirector (0 if none) 26 ; de' = address of empty string 27 ; 28 ; argv[] array is pushed onto the stack 29 ; 30 ; note : on exit if there is a redirector, must 0 the 31 ; redirector byte after examining it. 32 ; 33 ; uses : af, bc, de, hl, bc', de', hl', ix 34 35 pop ix ; ix = return address 36 37 ; initialize redirector pointers 38 39 xor a 40 41 exx 42 43 ld c,a 44 ld b,a ; bc'= chars remaining in redirector 45 46 push bc ; argv[argc] = NULL 47 48 ld l,a 49 ld h,a 50 add hl,sp 51 52 ex de,hl ; de'= & "" 53 54 ld l,a 55 ld h,a ; hl'= & redirector in command line 56 57 exx 58 59 inc b 60 dec b 61 62 jr z, sz_cont 63 64 ld b,a 65 ld c,255 66 67sz_cont: 68 69 ; find end of command line 70 71 ; hl = & command line 72 ; bc = num chars remaining in command line < 256 73 ; hl'= & redirector 74 ; bc'= num chars remaining in redirector 75 ; de'= address of empty string 76 ; ix = return address 77 78 ld e,a 79 ld d,a ; d = quote indicator 80 81 inc c 82 dec c 83 84 jr z, argv_finished ; if there is no command line 85 86find_end: 87 88 ld a,(hl) 89 90 inc d 91 dec d 92 93 jr z, outside_quote 94 95inside_quote: 96 97 cp d 98 jr nz, find_cont ; if end quote not seen 99 100 ld d,b ; quote ended 101 jr find_cont 102 103outside_quote: 104 105 cp '"' 106 jr z, start_quote 107 108 cp '|' 109 jr z, redirector 110 111 cp '>' 112 jr z, redirector 113 114 cp '<' 115 jr nz, find_cont 116 117redirector: 118 119 push bc 120 push hl 121 122 exx 123 124 pop hl ; hl'= & redirector 125 pop bc ; bc'= num chars remaining in redirector 126 127 exx 128 129 jr found_end 130 131start_quote: 132 133 ld d,a 134 135find_cont: 136 137 inc e 138 139 cpi ; hl++, bc-- 140 jp pe, find_end 141 142 ld (hl),b 143 144found_end: 145 146 ld c,e 147 148 ; hl = & last char in command line + 1 149 ; bc = number of chars in command line < 256 150 ; d = quote indicator 151 ; hl'= & redirector 152 ; bc'= num chars remaining in redirector 153 ; de'= address of empty string 154 ; ix = return address 155 156 ; work command line backwords 157 158 ld e,b ; e = word_count = 0 159 inc bc 160 161 inc d 162 dec d 163 164 jr nz, word_found ; if in an unterminated quote 165 166word_loop: 167 168 cpd ; hl--, bc-- 169 jp po, argv_finished ; if reached beginning of command line 170 171 ld a,(hl) 172 173 cp '"' 174 jr nz, word_ws_cont 175 176word_ws_quote: 177 178 ld d,a 179 ld (hl),b ; zero terminate over quote 180 181 jr word_found 182 183word_ws_cont: 184 185 call asm_isspace 186 jr c, word_found ; not space, end of word found 187 188word_terminate: 189 190 ld (hl),b 191 jr word_loop 192 193word_found: 194 195 inc e ; word_count++ 196 197word_begin_loop: 198 199 cpd ; hl--, bc-- 200 jp po, generate_last_argv ; if reached beginning of command line 201 202 ld a,(hl) 203 204 inc d 205 dec d 206 207 jr z, word_out_quote 208 209word_in_quote: 210 211 cp d 212 jr nz, word_begin_loop 213 214 ld d,b 215 jr word_end_quote 216 217word_out_quote: 218 219 cp '"' 220 jr nz, word_out_quote_cont 221 222 inc hl 223 push hl ; save start of word to argv[] 224 dec hl 225 226 jr word_ws_quote ; quote indicates new woed starting 227 228word_out_quote_cont: 229 230 call asm_isspace 231 jr c, word_begin_loop ; if next char is not space, word continues 232 233word_end_quote: 234 235 inc hl 236 push hl ; save start of word to argv[] 237 dec hl 238 239 jr word_terminate 240 241generate_last_argv: 242 243 inc hl 244 push hl ; save argv[] 245 246argv_finished: 247 248 ld c,e 249 250 ; bc = argc = word count 251 ; hl'= & redirector 252 ; bc'= num chars remaining in redirector 253 ; de'= address of empty string 254 ; ix = return address 255 ; stack = argv[] 256 257 ld l,b 258 ld h,b 259 add hl,sp ; hl = &argv[0] 260 261 jp (ix) 262