busybox/libbb/xatonum.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * ascii-to-numbers implementations for busybox
   4 *
   5 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
   6 *
   7 * Licensed under GPLv2, see file LICENSE in this source tree.
   8 */
   9#include "libbb.h"
  10
  11#define type long long
  12#define xstrtou(rest) xstrtoull##rest
  13#define xstrto(rest) xstrtoll##rest
  14#define xatou(rest) xatoull##rest
  15#define xato(rest) xatoll##rest
  16#define XSTR_UTYPE_MAX ULLONG_MAX
  17#define XSTR_TYPE_MAX LLONG_MAX
  18#define XSTR_TYPE_MIN LLONG_MIN
  19#define XSTR_STRTOU strtoull
  20#include "xatonum_template.c"
  21
  22#if ULONG_MAX != ULLONG_MAX
  23#define type long
  24#define xstrtou(rest) xstrtoul##rest
  25#define xstrto(rest) xstrtol##rest
  26#define xatou(rest) xatoul##rest
  27#define xato(rest) xatol##rest
  28#define XSTR_UTYPE_MAX ULONG_MAX
  29#define XSTR_TYPE_MAX LONG_MAX
  30#define XSTR_TYPE_MIN LONG_MIN
  31#define XSTR_STRTOU strtoul
  32#include "xatonum_template.c"
  33#endif
  34
  35#if UINT_MAX != ULONG_MAX
  36static ALWAYS_INLINE
  37unsigned bb_strtoui(const char *str, char **end, int b)
  38{
  39        unsigned long v = strtoul(str, end, b);
  40        if (v > UINT_MAX) {
  41                errno = ERANGE;
  42                return UINT_MAX;
  43        }
  44        return v;
  45}
  46#define type int
  47#define xstrtou(rest) xstrtou##rest
  48#define xstrto(rest) xstrtoi##rest
  49#define xatou(rest) xatou##rest
  50#define xato(rest) xatoi##rest
  51#define XSTR_UTYPE_MAX UINT_MAX
  52#define XSTR_TYPE_MAX INT_MAX
  53#define XSTR_TYPE_MIN INT_MIN
  54/* libc has no strtoui, so we need to create/use our own */
  55#define XSTR_STRTOU bb_strtoui
  56#include "xatonum_template.c"
  57#endif
  58
  59/* A few special cases */
  60
  61int FAST_FUNC xatoi_positive(const char *numstr)
  62{
  63        return xatou_range(numstr, 0, INT_MAX);
  64}
  65
  66uint16_t FAST_FUNC xatou16(const char *numstr)
  67{
  68        return xatou_range(numstr, 0, 0xffff);
  69}
  70
  71const struct suffix_mult bkm_suffixes[] ALIGN_SUFFIX = {
  72        { "b", 512 },
  73        { "k", 1024 },
  74        { "m", 1024*1024 },
  75        { "", 0 }
  76};
  77
  78const struct suffix_mult cwbkMG_suffixes[] ALIGN_SUFFIX = {
  79        { "c", 1 },
  80        { "w", 2 },
  81        { "b", 512 },
  82        { "kB", 1000 },
  83        { "kD", 1000 },
  84        { "k", 1024 },
  85        { "KB", 1000 }, /* compat with coreutils dd */
  86        { "KD", 1000 }, /* compat with coreutils dd */
  87        { "K", 1024 },  /* compat with coreutils dd */
  88        { "MB", 1000000 },
  89        { "MD", 1000000 },
  90        { "M", 1024*1024 },
  91        { "GB", 1000000000 },
  92        { "GD", 1000000000 },
  93        { "G", 1024*1024*1024 },
  94        /* "D" suffix for decimal is not in coreutils manpage, looks like it's deprecated */
  95        /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */
  96        { "", 0 }
  97};
  98
  99const struct suffix_mult kmg_i_suffixes[] ALIGN_SUFFIX = {
 100        { "KiB", 1024 },
 101        { "kiB", 1024 },
 102        { "K", 1024 },
 103        { "k", 1024 },
 104        { "MiB", 1048576 },
 105        { "miB", 1048576 },
 106        { "M", 1048576 },
 107        { "m", 1048576 },
 108        { "GiB", 1073741824 },
 109        { "giB", 1073741824 },
 110        { "G", 1073741824 },
 111        { "g", 1073741824 },
 112        { "KB", 1000 },
 113        { "MB", 1000000 },
 114        { "GB", 1000000000 },
 115        { "", 0 }
 116};
 117