/* * Note that this implementation does not (and should not!) obey * locale settings; you cannot simply substitute strtol here, since * it does obey locale. */ static int64_t mtree_atol(char **p, int base) { int64_t l, limit; int digit, last_digit_limit; if (base == 0) { if (**p != '0') base = 10; else if ((*p)[1] == 'x' || (*p)[1] == 'X') { *p += 2; base = 16; } else { base = 8; } } if (**p == '-') { limit = INT64_MIN / base; last_digit_limit = INT64_MIN % base; ++(*p); l = 0; digit = parsedigit(**p); while (digit >= 0 && digit < base) { if (l < limit || (l == limit && digit > last_digit_limit)) return INT64_MIN; l = (l * base) - digit; digit = parsedigit(*++(*p)); } return l; } else { limit = INT64_MAX / base; last_digit_limit = INT64_MAX % base; l = 0; digit = parsedigit(**p); while (digit >= 0 && digit < base) { if (l > limit || (l == limit && digit > last_digit_limit)) return INT64_MAX; l = (l * base) + digit; digit = parsedigit(*++(*p)); } return l; } }
int universalargument(char **args) { int digcnt = 0, pref = 0, minus = 1, gotk; if (*args) { zmod.mult = atoi(*args); zmod.flags |= MOD_MULT; return 0; } /* * TODO: this is quite tricky to do when trying to maintain * compatibility between the old input system and Unicode. * We don't know what follows the digits, so if we try to * read wide characters we may fail (e.g. we may come across an old * \M-style binding). * * If we assume individual bytes are either explicitly ASCII or * not (a la UTF-8), we get away with it; we can back up individual * bytes and everything will work. We may want to relax this * assumption later. ("Much later" - (C) Steven Singer, * CSR BlueCore firmware, ca. 2000.) * * Hence for now this remains byte-by-byte. */ while ((gotk = getbyte(0L, NULL)) != EOF) { if (gotk == '-' && !digcnt) { minus = -1; digcnt++; } else { int newdigit = parsedigit(gotk); if (newdigit >= 0) { pref = pref * zmod.base + newdigit; digcnt++; } else { ungetbyte(gotk); break; } } } if (digcnt) zmod.tmult = minus * (pref ? pref : 1); else zmod.tmult *= 4; zmod.flags |= MOD_TMULT; prefixflag = 1; return 0; }
int digitargument(UNUSED(char **args)) { int sign = (zmult < 0) ? -1 : 1; int newdigit = parsedigit(lastchar); if (newdigit < 0) return 1; if (!(zmod.flags & MOD_TMULT)) zmod.tmult = 0; if (zmod.flags & MOD_NEG) { /* If we just had a negative argument, this is the digit, * * rather than the -1 assumed by negargument() */ zmod.tmult = sign * newdigit; zmod.flags &= ~MOD_NEG; } else zmod.tmult = zmod.tmult * zmod.base + sign * newdigit; zmod.flags |= MOD_TMULT; prefixflag = 1; return 0; }