return 0;
}
-int safe_atolu(const char *s, long unsigned *ret_lu) {
- char *x = NULL;
- unsigned long l;
-
- assert(s);
- assert(ret_lu);
-
- errno = 0;
- l = strtoul(s, &x, 0);
-
- if (!x || *x || errno)
- return errno ? -errno : -EINVAL;
-
- *ret_lu = l;
- return 0;
-}
-
-int safe_atoli(const char *s, long int *ret_li) {
- char *x = NULL;
- long l;
-
- assert(s);
- assert(ret_li);
-
- errno = 0;
- l = strtol(s, &x, 0);
-
- if (!x || *x || errno)
- return errno ? -errno : -EINVAL;
-
- *ret_li = l;
- return 0;
-}
-
int safe_atollu(const char *s, long long unsigned *ret_llu) {
char *x = NULL;
unsigned long long l;
/* Split a string into words, but consider strings enclosed in '' and
* "" as words even if they include spaces. */
char *split_quoted(const char *c, size_t *l, char **state) {
- char *current;
+ char *current, *e;
+ bool escaped = false;
current = *state ? *state : (char*) c;
if (*current == '\'') {
current ++;
- *l = strcspn(current, "'");
- *state = current+*l;
- if (**state == '\'')
- (*state)++;
+ for (e = current; *e; e++) {
+ if (escaped)
+ escaped = false;
+ else if (*e == '\\')
+ escaped = true;
+ else if (*e == '\'')
+ break;
+ }
+
+ *l = e-current;
+ *state = *e == 0 ? e : e+1;
} else if (*current == '\"') {
current ++;
- *l = strcspn(current, "\"");
- *state = current+*l;
- if (**state == '\"')
- (*state)++;
+ for (e = current; *e; e++) {
+ if (escaped)
+ escaped = false;
+ else if (*e == '\\')
+ escaped = true;
+ else if (*e == '\"')
+ break;
+ }
+
+ *l = e-current;
+ *state = *e == 0 ? e : e+1;
} else {
- *l = strcspn(current, WHITESPACE);
- *state = current+*l;
+ for (e = current; *e; e++) {
+ if (escaped)
+ escaped = false;
+ else if (*e == '\\')
+ escaped = true;
+ else if (strchr(WHITESPACE, *e))
+ break;
+ }
+ *l = e-current;
+ *state = e;
}
- /* FIXME: Cannot deal with strings that have spaces AND ticks
- * in them */
-
return (char*) current;
}
return r;
}
-char *cunescape(const char *s) {
+char *cunescape_length(const char *s, size_t length) {
char *r, *t;
const char *f;
/* Undoes C style string escaping */
- if (!(r = new(char, strlen(s)+1)))
+ if (!(r = new(char, length+1)))
return r;
- for (f = s, t = r; *f; f++) {
+ for (f = s, t = r; f < s + length; f++) {
if (*f != '\\') {
*(t++) = *f;
*(t++) = '\'';
break;
+ case 's':
+ /* This is an extension of the XDG syntax files */
+ *(t++) = ' ';
+ break;
+
case 'x': {
/* hexadecimal encoding */
int a, b;
default:
/* Invalid escape code, let's take it literal then */
*(t++) = '\\';
- *(t++) = 'f';
+ *(t++) = *f;
break;
}
}
return r;
}
+char *cunescape(const char *s) {
+ return cunescape_length(s, strlen(s));
+}
char *xescape(const char *s, const char *bad) {
char *r, *t;