Add parseoffset()
This is a utility function to allow easy parsing of file or other offsets, automatically taking in regard suffixes, proper bases and so on, for instance used in split(1) -b or od -j, -N(1). Of course, POSIX is very arbitrary when it comes to defining the parsing rules for different tools. The main focus here lies on being as flexible and consistent as possible. One central utility-function handling the parsing makes this stuff a lot more trivial.
This commit is contained in:
parent
7132473947
commit
007df69fc5
1
Makefile
1
Makefile
|
@ -56,6 +56,7 @@ LIBUTILSRC =\
|
||||||
libutil/md5.c\
|
libutil/md5.c\
|
||||||
libutil/mkdirp.c\
|
libutil/mkdirp.c\
|
||||||
libutil/mode.c\
|
libutil/mode.c\
|
||||||
|
libutil/parseoffset.c\
|
||||||
libutil/putword.c\
|
libutil/putword.c\
|
||||||
libutil/reallocarray.c\
|
libutil/reallocarray.c\
|
||||||
libutil/recurse.c\
|
libutil/recurse.c\
|
||||||
|
|
59
libutil/parseoffset.c
Normal file
59
libutil/parseoffset.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
off_t
|
||||||
|
parseoffset(const char *str)
|
||||||
|
{
|
||||||
|
off_t res;
|
||||||
|
size_t scale;
|
||||||
|
int base = 10;
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
/* bases */
|
||||||
|
if (!strncasecmp(str, "0x", strlen("0x"))) {
|
||||||
|
base = 16;
|
||||||
|
} else if (*str == '0') {
|
||||||
|
str++;
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = strtol(str, &end, base);
|
||||||
|
if (res < 0) {
|
||||||
|
weprintf("invalid file offset: %s\n", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* suffix */
|
||||||
|
if (*end) {
|
||||||
|
switch (toupper((int)*end)) {
|
||||||
|
case 'B':
|
||||||
|
scale = 512L;
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
scale = 1024L;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
scale = 1024L * 1024L;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
scale = 1024L * 1024L * 1024L;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
weprintf("invalid file offset suffix: %s\n", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prevent overflow */
|
||||||
|
if (res > (SIZE_MAX / scale)) {
|
||||||
|
weprintf("file offset out of range: %s\n", str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
1
util.h
1
util.h
|
@ -68,6 +68,7 @@ void fnck(const char *, const char *, int (*)(const char *, const char *, int),
|
||||||
mode_t getumask(void);
|
mode_t getumask(void);
|
||||||
char *humansize(off_t);
|
char *humansize(off_t);
|
||||||
mode_t parsemode(const char *, mode_t, mode_t);
|
mode_t parsemode(const char *, mode_t, mode_t);
|
||||||
|
off_t parseoffset(const char *);
|
||||||
void putword(FILE *, const char *);
|
void putword(FILE *, const char *);
|
||||||
#undef strtonum
|
#undef strtonum
|
||||||
long long strtonum(const char *, long long, long long, const char **);
|
long long strtonum(const char *, long long, long long, const char **);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user