; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. ; ; int strtol(const char *str, int base) ; ; rax = integer extracted from str ; rdx = pointer to first invalid byte ; strtol: mov ax2, 1 jmp strtoq ; ; int strtoul(const char *str, int base) ; ; rax = integer extracted from str ; rdx = pointer to first invalid byte ; strtoul: mov ax2, zero jmp strtoq ; ; int strtoq(const char *str, int base, bool signed) ; ; guesses base when 'base'=0 ; strtoq: mov rax, zero mov rdx, ax0 ; make sure base is in [2, 32] b.z ax1, 1, .bad b.a ax1, 36, .bad ; empty string? b.z b[rdx], zero, .done .skip_spc: cmp b[rdx], ' ' add.z rdx, rdx, 1 jmp.z .skip_spc ; skip + cmp b[rdx], '+' add.z rdx, rdx, 1 ; signed? cmp ax2, zero mov.z rsi, zero jmp.z .unsigned ; parse '-' cmp b[rdx], '-' add.z rdx, rdx, 1 mov.z rsi, 1 mov.nz rsi, zero .unsigned: ; base 0 b.z ax1, 0, .base_0 ; base prefix? b.nz b[rdx], '0', .main_loop add rdx, rdx, 1 movzx rcx, b[rdx] ; "0x"/"0b" prefix jmp.cxz .done ; "0" b.z rcx, 'x', .parsed_0x b.z rcx, 'b', .parsed_0b ; may be octal, but we don't care ; we accept "0110101010" (despite base=2) for instance jmp .main_loop .parsed_0x: ; are we in base 16? ; if not, leave rax = 0 and *rdx = 'x' b.nz ax1, 16, .done ; else add rdx, rdx, 1 jmp .main_loop .parsed_0b: ; are we in base 2? ; if not, leave rax = 0 and *rdx = 'b' b.nz ax1, 2, .done ; else add rdx, rdx, 1 jmp .main_loop .base_0: ; guess base cmp b[rdx], '0' mov.nz ax1, 10 jmp.nz .main_loop add rdx, rdx, 1 cmp b[rdx], 'x' add.z rdx, rdx, 1 mov.z ax1, 16 jmp.z .main_loop cmp b[rdx], 'b' add.z rdx, rdx, 1 mov.z ax1, 2 jmp.z .main_loop mov ax1, 8 .main_loop: movzx rcx, b[rdx] add rdx, rdx, 1 cmp rcx, '0' jmp.b .done cmp.ae rcx, '9' sub.be rcx, rcx, '0' jmp.be .next cmp rcx, 'A' cmp.ae rcx, 'Z' sub.be rcx, rcx, 55 ; 'A' - 10 jmp.be .next cmp rcx, 'a' jmp.b .next cmp.ae rcx, 'z' sub.be rcx, rcx, 87 ; 'a' - 10 jmp.be .next .next: ; too large for base? b.ae rcx, ax1, .done mul rax, rax, ax1 add rax, rax, rcx jmp .main_loop .done: ; negative? cmp rsi, zero ret.z ; yes sub rax, zero, rax ret .bad: mov q[errno], EINVAL ret