/* -*- mode: c; c-basic-offset: 8 -*- */ /* Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya. Copyright (c) 1990, Giuseppe Attardi. Copyright (c) 2001, Juan Jose Garcia Ripoll. ECL is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See file '../../Copyright' for full details. */ #include #include #include #define basep(d) (d <= 36) cl_object ecl_parse_integer(cl_object str, cl_index start, cl_index end, cl_index *ep, unsigned int radix) { int sign, d; cl_object integer_part, output; cl_index i, c; if (start >= end || !basep(radix)) { *ep = start; return OBJNULL; } sign = 1; c = ecl_char(str, start); if (c == '+') { start++; } else if (c == '-') { sign = -1; start++; } integer_part = _ecl_big_register0(); _ecl_big_set_ui(integer_part, 0); for (i = start; i < end; i++) { c = ecl_char(str, i); d = ecl_digitp(c, radix); if (d < 0) { break; } _ecl_big_mul_ui(integer_part, integer_part, radix); _ecl_big_add_ui(integer_part, integer_part, d); } if (sign < 0) { _ecl_big_complement(integer_part, integer_part); } output = _ecl_big_register_normalize(integer_part); *ep = i; return (i == start)? OBJNULL : output; } @(defun parse_integer (strng &key (start MAKE_FIXNUM(0)) end (radix MAKE_FIXNUM(10)) junk_allowed &aux x) cl_index s, e, ep; cl_object rtbl = ecl_current_readtable(); @ { unlikely_if (!ECL_STRINGP(strng)) { FEwrong_type_nth_arg(@[parse-integer], 1, strng, @[string]); } unlikely_if (!FIXNUMP(radix) || ecl_fixnum_lower(radix, MAKE_FIXNUM(2)) || ecl_fixnum_greater(radix, MAKE_FIXNUM(36))) { FEerror("~S is an illegal radix.", 1, radix); } { cl_index_pair p = ecl_vector_start_end(@[parse-integer], strng, start, end); s = p.start; e = p.end; } while (s < e && ecl_readtable_get(rtbl, ecl_char(strng, s), NULL) == cat_whitespace) { s++; } if (s >= e) { if (junk_allowed != Cnil) @(return Cnil MAKE_FIXNUM(s)) else goto CANNOT_PARSE; } x = ecl_parse_integer(strng, s, e, &ep, fix(radix)); if (x == OBJNULL) { if (junk_allowed != Cnil) { @(return Cnil MAKE_FIXNUM(ep)); } else { goto CANNOT_PARSE; } } if (junk_allowed != Cnil) { @(return x MAKE_FIXNUM(ep)); } for (s = ep; s < e; s++) { unlikely_if (ecl_readtable_get(rtbl, ecl_char(strng, s), NULL) != cat_whitespace) { CANNOT_PARSE: FEparse_error("Cannot parse an integer in the string ~S.", Cnil, 1, strng); } } @(return x MAKE_FIXNUM(e)); } @)