Skip to content

Commit

Permalink
del get_uint32()
Browse files Browse the repository at this point in the history
  • Loading branch information
gitgjogh committed Feb 2, 2017
1 parent c8a0d31 commit f124b83
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 81 deletions.
54 changes: 19 additions & 35 deletions libsim/sim_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ char *get_argv(int argc, char *argv[], int i, const char *name)

int arg_parse_range(int i, int argc, char *argv[], int i_range[2])
{
char *flag=0;
char *last=0;
SCAN_RET_e ret = 0;
const char *flag=0;
const char *last=0;
char *arg = GET_ARGV(i, "range");
if (!arg) {
return -1;
Expand All @@ -138,8 +139,11 @@ int arg_parse_range(int i, int argc, char *argv[], int i_range[2])

/* parse argv : `$base[~$last]` or `$base[+$count]` */
//i_range[0] = strtoul (arg, &flag, 10);
flag = get_uint32 (arg, &i_range[0]);
if (flag==0 || *flag == 0) { /* no `~$last` or `+$count` */
ret = str_2_int(arg, &i_range[0], &flag);
if (ret != SCAN_OK) {
xerr("<cmdl> Err : Invalid range start\n");
return -1;
} else if (*flag == 0) { /* no `~$last` or `+$count` */
return ++i;
}

Expand All @@ -150,7 +154,7 @@ int arg_parse_range(int i, int argc, char *argv[], int i_range[2])
}

//i_range[1] = strtoul (flag + 1, &last, 10);
last = get_uint32 (flag + 1, &i_range[1]);
ret = str_2_int (flag + 1, &i_range[1], &last);
if (last == 0 || *last != 0 ) {
xerr("<cmdl> Err : Invalid count/end\n");
i_range[1] = INT_MAX;
Expand Down Expand Up @@ -187,7 +191,7 @@ int arg_parse_int(int i, int argc, char *argv[], int *p)
{
char *arg = GET_ARGV(i, "int");
if (arg) {
int b_err = str_2_int(arg, p);
int b_err = str_2_int(arg, p, 0);
return (++i) * (b_err ? -1 : 1);
} else {
return -1;
Expand All @@ -198,7 +202,7 @@ int opt_parse_int(int i, int argc, char *argv[], int *p, int default_val)
{
char *arg = GET_ARGV(i, "int");
if (arg) {
int b_err = str_2_int(arg, p);
int b_err = str_2_int(arg, p, 0);
return (++i) * (b_err ? -1 : 1);
} else {
*p = default_val;
Expand Down Expand Up @@ -409,8 +413,6 @@ int cmdl_parse_range (cmdl_iter_t *iter, void* dst, CMDL_ACT_e act, cmdl_opt_t *
{
if (act == CMDL_ACT_PARSE)
{
char *flag=0;
char *last=0;
char *arg = cmdl_peek_next(iter);
if (!arg || arg[0] == '-') {
xerr("%s has no arg\n", cmdl_iter_curr(iter));
Expand All @@ -420,32 +422,14 @@ int cmdl_parse_range (cmdl_iter_t *iter, void* dst, CMDL_ACT_e act, cmdl_opt_t *
}

int *i_range = dst;
i_range[0] = 0;
i_range[1] = INT_MAX;

if (arg[0] != '~' && arg[1] != '+') {
/* parse argv : `$start[~$last]` or `$start[+$count]` */
flag = get_uint32 (arg, &i_range[0]);
if (flag==0 || *flag == 0) { /* no `~$last` or `+$count` */
return 2;
}
}

/* get `~$last` or `+$count` */
if (*flag != '~' && *flag != '+') {
xerr("<cmdl> Err : Invalid flag\n");
return CMDL_RET_ERROR;
}

last = get_uint32 (flag + 1, &i_range[1]);
if (last == 0 || *last != 0 ) {
xerr("<cmdl> Err : Invalid count/end\n");
i_range[1] = INT_MAX;
return -1;
}
//i_range[0] = 0;
//i_range[1] = INT_MAX;

if (*flag == '+') {
i_range[1] += i_range[0];
int i = arg_parse_range(iter->idx, iter->argc, iter->argv, i_range);
if (i < 0) {
xerr("<cmdl> Err : Invalid range\n");
return CMDL_RET_ERROR;
}

return 2;
Expand Down Expand Up @@ -529,7 +513,7 @@ int cmdl_parse_int (cmdl_iter_t *iter, void* dst, CMDL_ACT_e act, cmdl_opt_t *
} else {
cmdl_iter_next(iter);
}
int b_err = str_2_int(arg, dst);
int b_err = str_2_int(arg, dst, 0);
return b_err ? CMDL_RET_ERROR : 2;
}
else if (act == CMDL_PRI_RESULT)
Expand Down Expand Up @@ -559,7 +543,7 @@ int cmdl_parse_ints (cmdl_iter_t *iter, void* dst, CMDL_ACT_e act, cmdl_opt_t *
{
for (i=0; i<opt->narg; ++i) {
char *arg = cmdl_iter_next(iter);
if (!arg || /*b_err=*/str_2_int(arg, &((int*)dst)[i])) {
if (!arg || /*b_err=*/str_2_int(arg, &((int*)dst)[i], 0)) {
xerr(arg ? "str2i() failed\n" : "noarg\n");
cmdl_iter_dbg (iter);
return CMDL_RET_ERROR;
Expand Down
6 changes: 4 additions & 2 deletions libsim/sim_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ int cmdl_test(int argc, char **argv)
{
typedef struct cmdl_param {
pet_t cat, dog;
int range[2];
} cmdl_param_t;

#define CMDL_OPT_M(member) offsetof(cmdl_param_t, member)
cmdl_opt_t cmdl_opt[] =
{
{ 0, "h,help", 0, cmdl_parse_help, 0, 0, "show help"},
{ 1, "dog", 1, cmdl_pet_parser, CMDL_OPT_M(dog), 0, "dog's prop...", },
{ 1, "cat", 1, cmdl_pet_parser, CMDL_OPT_M(cat), 0, "cat's prop...", },
{ 0, "dog", 1, cmdl_pet_parser, CMDL_OPT_M(dog), 0, "dog's prop...", },
{ 0, "cat", 1, cmdl_pet_parser, CMDL_OPT_M(cat), 0, "cat's prop...", },
{ 1, "r", 1, cmdl_parse_range, CMDL_OPT_M(range),0, "just for range test", },
{ 0, SIM_NULL_END, },
};

Expand Down
51 changes: 18 additions & 33 deletions libsim/sim_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,6 @@ int clip(int v, int minv, int maxv)
else return v;
}

/**
* simple atoi(/[0-9]+/) with the 1st non-digit pointer returned
* @see str_2_uint() which is more delicate
*/
char* get_uint32 (char *str, uint32_t *out)
{
char *curr = str;

if ( curr ) {
int c, sum;
for (sum=0, curr=str; (c = *curr) && c >= '0' && c <= '9'; ++ curr) {
sum = sum * 10 + ( c - '0' );
}
if (out) { *out = sum; }
}

return curr;
}

/**
* \brief return the pos for 1st-char not in @jumpset
*/
Expand Down Expand Up @@ -322,12 +303,12 @@ const char *field_in_record(const char *field, const char *record)
/**
* @brief scan for uint64_t without numerical base prefix.
*
* @param [i] _str
* @param [o] ret_
* @param [o] end_
* @param [in] max scaned value check (@ret_ < max), 0 for UINT64_MAX
* @return error flag during scanning
*/
int scan_for_uint64_npre(const char *_str, uint32_t base, uint64_t max, uint64_t *ret_, const char **end_)
static
int scan_for_uint64_npre(const char *_str, uint32_t base, uint64_t max,
uint64_t *ret_, const char **end_)
{
uint64_t acc = 0;
uint32_t c, v;
Expand Down Expand Up @@ -380,6 +361,14 @@ int scan_for_uint64_npre(const char *_str, uint32_t base, uint64_t max, uint64_t
return b_err;
}

/**
* @brief scan for uint64_t number start by diff. base-prefix
* base-10 without prefix
* base-16 start by '0x'/0X'
* base-2 start by '0b'/'0B'
* base-8 start by '0'
*/
static
int scan_for_uint64_pre(const char *_str, uint64_t max, uint64_t *ret_, const char **end_)
{
uint32_t base = 10;
Expand Down Expand Up @@ -449,6 +438,8 @@ static int scan_for_intN(const char *_str, int Nbit, int64_t *ret_, const char *
Nbit == 16 ? INT16_MAX : (
Nbit == 8 ? INT8_MAX : 0))));

// since abs(INTx_MIN) = (INTx_MAX) + 1,
// under flow would never happen.
b_err = scan_for_uint64_pre(_str, max, &ret, &end);

if (ret_) { *ret_ = b_neg ? -(int64_t)ret : ret; }
Expand Down Expand Up @@ -564,31 +555,25 @@ int scan_for_float(const char *_str, float *ret_, const char **end_)
return b_err;
}

unsigned int str_2_uint(const char *_str, unsigned int *ret_)
int str_2_uint(const char *_str, unsigned int *ret_, const char **end_)
{
uint64_t ret;
const char *end;
int N = sizeof(unsigned int) * 8;
int b_err = scan_for_uintN(_str, N, &ret, &end);
if (!b_err && (*end != 0)) {
xerr("str_2_uint(%s) not nul ending\n", _str);
b_err |= SCAN_ERR_NNULEND;
}
if (ret_) { *ret_ = (unsigned int)ret; }
if (end_) { *end_ = end; }

return b_err;
}
int str_2_int(const char *_str, int *ret_)
int str_2_int(const char *_str, int *ret_, const char **end_)
{
int64_t ret;
const char *end;
int N = sizeof(unsigned int) * 8;
int b_err = scan_for_intN(_str, N, &ret, &end);
if (!b_err && (*end != 0)) {
xerr("str_2_int(%s) not nul ending\n", _str);
b_err |= SCAN_ERR_NNULEND;
}
if (ret_) { *ret_ = (int)ret; }
if (end_) { *end_ = end; }

return b_err;
}
Expand Down
21 changes: 10 additions & 11 deletions libsim/sim_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ int num_leading_zero_bits_u32(uint32_t val);
#define NLZB32(val) (num_leading_zero_bits_u32(val))
#define NLZB64(val) (num_leading_zero_bits_u64(val))

char* get_uint32(char *str, uint32_t *out);
int jump_front(const char* str, const char* jumpset);

/**
Expand Down Expand Up @@ -222,26 +221,26 @@ typedef enum {
SCAN_ERR_NOBEGIN = (1<<3),
SCAN_ERR_NOCLOSE = (1<<5),
SCAN_ERR_NNULEND = (1<<6),
}scan_ret_t;
} SCAN_RET_e;

/**
* @param [i] max
* @param [o] ret_ only useful if (@return == 0)
* @param [o] end_
* @return: 0 if success, else @see scan_ret_t
* atoi() alias, prefix white space would be skip
* @param [in] _str input string to parse()
* @param [out] ret_ only useful if (@return == 0)
* @param [out] end_ the first char that is not part of the number
* @return: 0 if success, else @see SCAN_RET_e
*/
int scan_for_uint64_npre(const char *_str, uint32_t base, uint64_t max, uint64_t *ret_, const char **end_);
int scan_for_uint64_pre(const char *_str, uint64_t max, uint64_t *ret_, const char **end_);
int scan_for_uint64(const char *_str, uint64_t *ret_, const char **end_);
int scan_for_uint32(const char *_str, uint32_t *ret_, const char **end_);
int scan_for_uint16(const char *_str, uint16_t *ret_, const char **end_);
int scan_for_int64(const char *_str, int64_t *ret_, const char **end_);
int scan_for_int32(const char *_str, int32_t *ret_, const char **end_);
int scan_for_int16(const char *_str, int16_t *ret_, const char **end_);
int scan_for_float(const char *_str, float *ret_, const char **end_);
unsigned int str_2_uint(const char *_str, unsigned int *ret_);
int str_2_int(const char *_str, int *ret_);
int str_2_uint(const char *_str, unsigned int *ret_, const char **end_);
int str_2_int(const char *_str, int *ret_, const char **end_);

/** atof() alias */
int scan_for_float(const char *_str, float *ret_, const char **end_);

/**
* Free a memory block and set the pointer pointing to it to NULL.
Expand Down

0 comments on commit f124b83

Please sign in to comment.