static char *find_space(char *str) { while(*str != 0 && c_isspace(*str) == 0) { str++; } if (c_isspace(*str)) return str; return NULL; }
static void test_ctype(void) { int c; for (c = -1; c < 256; c++) { /* Test blank. */ if (c == '\t' || c == ' ') test_pass(c_isblank(c)); else test_fail(c_isblank(c)); /* Test white. */ if (c == '\t' || c == ' ' || c == '\n') test_pass(c_iswhite(c)); else test_fail(c_iswhite(c)); /* Test space. */ if (c == '\t' || c == '\v' || c == '\f' || c == '\r' || c == '\n' || c == ' ') test_pass(c_isspace(c)); else test_fail(c_isspace(c)); /* Test digit. */ if (c >= '0' && c <= '9') test_pass(c_isdigit(c)); else test_fail(c_isdigit(c)); /* Test lower case. */ if (c >= 'a' && c <= 'z') test_pass(c_islower(c)); else test_fail(c_islower(c)); /* Test upper case. */ if (c >= 'A' && c <= 'Z') test_pass(c_isupper(c)); else test_fail(c_isupper(c)); /* Test alpha. */ if (c_islower(c) || c_isupper(c)) test_pass(c_isalpha(c)); else test_fail(c_isalpha(c)); /* Test alphanumeric. */ if (c_isdigit(c) || c_isalpha(c)) test_pass(c_isalnum(c)); else test_fail(c_isalnum(c)); } }
/* Find value of given key. This is intended for Link header, but will work with any header that uses ';' as field separator and '=' as key-value separator. Link = "Link" ":" #link-value link-value = "<" URI-Reference ">" *( ";" link-param ) link-param = ( ( "rel" "=" relation-types ) | ( "anchor" "=" <"> URI-Reference <"> ) | ( "rev" "=" relation-types ) | ( "hreflang" "=" Language-Tag ) | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) ) | ( "title" "=" quoted-string ) | ( "title*" "=" ext-value ) | ( "type" "=" ( media-type | quoted-mt ) ) | ( link-extension ) ) link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] ) | ( ext-name-star "=" ext-value ) ext-name-star = parmname "*" ; reserved for RFC2231-profiled ; extensions. Whitespace NOT ; allowed in between. ptoken = 1*ptokenchar ptokenchar = "!" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*" | "+" | "-" | "." | "/" | DIGIT | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~" media-type = type-name "/" subtype-name quoted-mt = <"> media-type <"> relation-types = relation-type | <"> relation-type *( 1*SP relation-type ) <"> relation-type = reg-rel-type | ext-rel-type reg-rel-type = LOALPHA *( LOALPHA | DIGIT | "." | "-" ) ext-rel-type = URI See more: rfc5988 */ bool find_key_value (const char *start, const char *end, const char *key, char **value) { const char *eq; size_t key_len = strlen (key); const char *val_beg, *val_end; const char *key_beg; key_beg = start; while (key_beg + key_len + 1 < end) { /* Skip whitespaces. */ while (key_beg + key_len + 1 < end && c_isspace (*key_beg)) key_beg++; if (strncmp (key_beg, key, key_len)) { /* Find next token. */ while (key_beg + key_len + 1 < end && *key_beg != ';') key_beg++; key_beg++; continue; } else { /* Find equals sign. */ eq = key_beg + key_len; while (eq < end && c_isspace (*eq)) eq++; if (eq == end) return false; if (*eq != '=') { key_beg++; continue; } val_beg = eq + 1; while (val_beg < end && c_isspace (*val_beg)) val_beg++; if (val_beg == end) return false; val_end = val_beg + 1; while (val_end < end && *val_end != ';' && !c_isspace (*val_end)) val_end++; *value = xstrndup (val_beg, val_end - val_beg); return true; } } *value = NULL; return false; }
static void _atom_get_url(void *context, int flags, const char *dir, const char *attr, const char *val, size_t len, size_t pos G_GNUC_WGET_UNUSED) { struct atom_context *ctx = context; wget_string_t url; if (!val || !len) return; url.p = NULL; if ((flags & XML_FLG_ATTRIBUTE)) { if (!wget_strcasecmp_ascii(attr, "href") || !wget_strcasecmp_ascii(attr, "uri") || !wget_strcasecmp_ascii(attr, "src") || !wget_strcasecmp_ascii(attr, "scheme") || !wget_strcasecmp_ascii(attr, "xmlns") || !wget_strncasecmp_ascii(attr, "xmlns:", 6)) { for (;len && c_isspace(*val); val++, len--); // skip leading spaces for (;len && c_isspace(val[len - 1]); len--); // skip trailing spaces url.p = val; url.len = len; if (!ctx->urls) ctx->urls = wget_vector_create(32, -2, NULL); wget_vector_add(ctx->urls, &url, sizeof(url)); } } else if ((flags & XML_FLG_CONTENT)) { const char *elem = strrchr(dir, '/'); if (elem) { elem++; if (!wget_strcasecmp_ascii(elem, "icon") || !wget_strcasecmp_ascii(elem, "id") || !wget_strcasecmp_ascii(elem, "logo")) { for (;len && c_isspace(*val); val++, len--); // skip leading spaces for (;len && c_isspace(val[len - 1]); len--); // skip trailing spaces // debug_printf("#2 %02X %s %s '%.*s' %zd\n", flags, dir, attr, (int) len, val, len); url.p = val; url.len = len; if (!ctx->urls) ctx->urls = wget_vector_create(32, -2, NULL); wget_vector_add(ctx->urls, &url, sizeof(url)); } } } }
/* Print FUNCTION in a context header. */ static void print_context_function (FILE *out, char const *function) { int i, j; putc (' ', out); for (i = 0; c_isspace ((unsigned char) function[i]) && function[i] != '\n'; i++) continue; for (j = i; j < i + 40 && function[j] != '\n'; j++) continue; while (i < j && c_isspace ((unsigned char) function[j - 1])) j--; fwrite (function + i, sizeof (char), j - i, out); }
/* Breaks a list of "xxx", "yyy", to a character array, of * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified. */ static void break_group_list(void *pool, char *text, char *broken_text[MAX_GROUPS], unsigned *elements) { char *p = talloc_strdup(pool, text); char *p2; unsigned len; *elements = 0; if (p == NULL) return; do { broken_text[*elements] = p; (*elements)++; p = strchr(p, ','); if (p) { *p = 0; len = p - broken_text[*elements-1]; /* remove any trailing space */ p2 = p-1; while (c_isspace(*p2)) { *p2 = 0; p2--; } p++; /* move to next entry and skip white * space. */ while (c_isspace(*p)) p++; if (len == 1) { /* skip the group */ (*elements)--; } } else { p2 = strrchr(broken_text[(*elements)-1], ' '); if (p2 != NULL) { while (c_isspace(*p2)) { *p2 = 0; p2--; } } } } while (p != NULL && *elements < MAX_GROUPS); }
/** * virUUIDParse: * @uuidstr: zero terminated string representation of the UUID * @uuid: array of VIR_UUID_BUFLEN bytes to store the raw UUID * * Parses the external string representation, allowing spaces and '-' * character in the sequence, and storing the result as a raw UUID * * Returns 0 in case of success and -1 in case of error. */ int virUUIDParse(const char *uuidstr, unsigned char *uuid) { const char *cur; size_t i; /* * do a liberal scan allowing '-' and ' ' anywhere between character * pairs, and surrounding whitespace, as long as there are exactly * 32 hexadecimal digits the end. */ cur = uuidstr; while (c_isspace(*cur)) cur++; for (i = 0; i < VIR_UUID_BUFLEN;) { uuid[i] = 0; if (*cur == 0) goto error; if ((*cur == '-') || (*cur == ' ')) { cur++; continue; } if (!c_isxdigit(*cur)) goto error; uuid[i] = virHexToBin(*cur); uuid[i] *= 16; cur++; if (*cur == 0) goto error; if (!c_isxdigit(*cur)) goto error; uuid[i] += virHexToBin(*cur); i++; cur++; } while (*cur) { if (!c_isspace(*cur)) goto error; cur++; } return 0; error: return -1; }
static uint32_t virNetDevVPortProfileGetLldpadPid(void) { int fd; uint32_t pid = 0; fd = open(LLDPAD_PID_FILE, O_RDONLY); if (fd >= 0) { char buffer[10]; if (saferead(fd, buffer, sizeof(buffer)) <= sizeof(buffer)) { unsigned int res; char *endptr; if (virStrToLong_ui(buffer, &endptr, 10, &res) == 0 && (*endptr == '\0' || c_isspace(*endptr)) && res != 0) { pid = res; } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("error parsing pid of lldpad")); } } } else { virReportSystemError(errno, _("Error opening file %s"), LLDPAD_PID_FILE); } VIR_FORCE_CLOSE(fd); return pid; }
/* Given a string containing "charset=XXX", return the encoding if found, or NULL otherwise */ char * parse_charset (const char *str) { const char *end; char *charset; if (!str || !*str) return NULL; str = c_strcasestr (str, "charset="); if (!str) return NULL; str += 8; end = str; /* sXXXav: which chars should be banned ??? */ while (*end && !c_isspace (*end)) end++; /* sXXXav: could strdupdelim return NULL ? */ charset = strdupdelim (str, end); /* Do a minimum check on the charset value */ if (!check_encoding_name (charset)) { xfree (charset); return NULL; } /*logprintf (LOG_VERBOSE, "parse_charset: %s\n", quote (charset));*/ return charset; }
/* Find all key=value pairs delimited with ';' or ','. This is intended for Digest header parsing. The usage is: const char *pos; for (pos = header_beg; pos = find_key_values (pos, header_end, &key, &val); pos++) { ... } */ const char * find_key_values (const char *start, const char *end, char **key, char **value) { const char *key_start, *key_end; const char *eq; const char *val_start, *val_end; eq = start; while (eq < end && *eq != '=') { /* Skip tokens without =value part. */ if (*eq == ';' || *eq == ',') start = eq + 1; eq++; } if (eq >= end) return NULL; key_start = start; while (key_start < eq && c_isspace (*key_start)) key_start++; key_end = eq - 1; while (key_end > key_start && c_isspace (*key_end)) key_end--; key_end++; val_start = eq + 1; while (val_start < end && c_isspace (*val_start)) val_start++; val_end = val_start; while (val_end < end && *val_end != ';' && *val_end != ',' && !c_isspace (*val_end)) val_end++; *key = xstrndup (key_start, key_end - key_start); *value = xstrndup (val_start, val_end - val_start); /* Skip trailing whitespaces. */ while (val_end < end && c_isspace (*val_end)) val_end++; return val_end; }
/** * virSkipSpaces: * @str: pointer to the char pointer used * * Skip potential blanks, this includes space tabs, line feed, * carriage returns. */ void virSkipSpaces(const char **str) { const char *cur = *str; while (c_isspace(*cur)) cur++; *str = cur; }
/** * virSkipSpacesAndBackslash: * @str: pointer to the char pointer used * * Like virSkipSpaces, but also skip backslashes erroneously emitted * by xend */ void virSkipSpacesAndBackslash(const char **str) { const char *cur = *str; while (c_isspace(*cur) || *cur == '\\') cur++; *str = cur; }
/* Skip leading and trailing whitespace, updating the original string * in-place. */ void trim (char *str) { size_t len = strlen (str); while (len > 0 && c_isspace (str[len-1])) { str[len-1] = '\0'; len--; } const char *p = str; while (*p && c_isspace (*p)) { p++; len--; } memmove (str, p, len+1); }
static char *check_str(char *line, size_t line_size, const char *needle, size_t needle_size) { char *p; unsigned n; while (c_isspace(*line)) { line++; line_size--; } if (line[0] == '#' || needle_size >= line_size) return NULL; if (memcmp(line, needle, needle_size) == 0) { p = &line[needle_size]; while (c_isspace(*p)) { p++; } if (*p != '=') { return NULL; } else p++; while (c_isspace(*p)) { p++; } n = strlen(p); if (n > 1 && p[n-1] == '\n') { n--; p[n] = 0; } if (n > 1 && p[n-1] == '\r') { n--; p[n] = 0; } return p; } return NULL; }
/* Assume that every ASCII character starts a new grapheme, which is often true, except that CR-LF is a single grapheme. */ static void ascii_grapheme_breaks (const char *s, size_t n, char *p) { size_t i; p[0] = 1; for (i = 1; i < n; i++) { bool is_ascii = c_isprint (s[i]) || c_isspace (s[i]); p[i] = is_ascii && (s[i] != '\n' || s[i - 1] != '\r'); } }
/* Tests whether a string is entirely ASCII. Returns 1 if yes. Returns 0 if the string is in an 8-bit encoding or an ISO-2022 encoding. */ int is_all_ascii (const char *s, size_t n) { for (; n > 0; s++, n--) { unsigned char c = (unsigned char) *s; if (!(c_isprint (c) || c_isspace (c))) return 0; } return 1; }
/* Does the current line match the regexp /^\s*filter\s*=/ */ static int is_filter_line (const char *line) { while (*line && c_isspace (*line)) line++; if (!*line) return 0; if (! STRPREFIX (line, "filter")) return 0; line += 6; while (*line && c_isspace (*line)) line++; if (!*line) return 0; if (*line != '=') return 0; return 1; }
/* This is to check if given token exists in HTTP header. Tokens are separated by ';'. */ bool has_key (const char *start, const char *end, const char *key) { const char *pos; /* Here would the token start. */ size_t key_len = strlen (key); pos = start; while (pos + key_len <= end) { /* Skip whitespaces at beginning. */ while (pos + key_len <= end && c_isspace (*pos)) pos++; /* Does the prefix of pos match our key? */ if (strncmp (key, pos, key_len)) { /* This was not a match. Skip all characters until beginning of next token. */ while (pos + key_len <= end && *pos != ';') pos++; pos++; continue; } /* key is prefix of pos. Is it the exact token or just a prefix? */ pos += key_len; while (pos < end && c_isspace (*pos)) pos++; if (pos == end || *pos == ';') return true; /* This was not a match (just a prefix). Skip all characters until beginning of next token. */ while (pos + key_len <= end && *pos != ';') pos++; pos++; } return false; }
static char * munge_param(const char *datain, size_t *params, size_t paramnum, int *type) { char *dataout; const char *sol; const char *eol; const char *eq; const char *tmp; size_t dataoutlen; const char *replace = NULL; sol = datain + params[paramnum]; eq = strchr(sol, '='); eol = strchr(sol, '\n'); for (tmp = eq + 1; tmp < eol && !replace; tmp++) { if (c_isspace(*tmp)) continue; if (c_isdigit(*tmp)) { *type = VIR_CONF_LONG; replace = "\"foo\""; } else if (*tmp == '[') { *type = VIR_CONF_LIST; replace = "666"; } else { *type = VIR_CONF_STRING; replace = "666"; } } dataoutlen = (eq - datain) + 1 + strlen(replace) + strlen(eol) + 1; if (VIR_ALLOC_N(dataout, dataoutlen) < 0) { virReportOOMError(); return NULL; } memcpy(dataout, datain, (eq - datain) + 1); memcpy(dataout + (eq - datain) + 1, replace, strlen(replace)); memcpy(dataout + (eq - datain) + 1 + strlen(replace), eol, strlen(eol) + 1); return dataout; }
/* Take string which must look like "key = value" and find the value. * There may or may not be spaces before and after the equals sign. * This function is used by both check_fedora_installer_root and * check_w2k3_installer_root. */ static const char * find_value (const char *kv) { const char *p; p = strchr (kv, '='); if (!p) abort (); do { ++p; } while (c_isspace (*p)); return p; }
static char *nextline(char **ripp, const char *fn, const char *what) { char *newline, *rip; rip= *ripp; if (!rip) ohshit(_("file '%.250s' is corrupt - %.250s missing"), fn, what); newline= strchr(rip,'\n'); if (!newline) ohshit(_("file '%.250s' is corrupt - missing newline after %.250s"), fn, what); *ripp= newline+1; while (newline > rip && c_isspace(newline[-1])) newline--; *newline = '\0'; return rip; }
/* Basic check of an encoding name. */ bool check_encoding_name (const char *encoding) { const char *s = encoding; while (*s) { if (!c_isascii (*s) || c_isspace (*s)) { logprintf (LOG_VERBOSE, _("Encoding %s isn't valid\n"), quote (encoding)); return false; } s++; } return true; }
/** * virTrimSpaces: * @str: string to modify to remove all trailing spaces * @endp: track the end of the string * * If @endp is NULL on entry, then all spaces prior to the trailing * NUL in @str are removed, by writing NUL into the appropriate * location. If @endp is non-NULL but points to a NULL pointer, * then all spaces prior to the trailing NUL in @str are removed, * NUL is written to the new string end, and endp is set to the * location of the (new) string end. If @endp is non-NULL and * points to a non-NULL pointer, then that pointer is used as * the end of the string, endp is set to the (new) location, but * no NUL pointer is written into the string. */ void virTrimSpaces(char *str, char **endp) { char *end; if (!endp || !*endp) end = str + strlen(str); else end = *endp; while (end > str && c_isspace(end[-1])) end--; if (endp) { if (!*endp) *end = '\0'; *endp = end; } else { *end = '\0'; } }
int virPidFileReadPath(const char *path, pid_t *pid) { int fd; int rc; ssize_t bytes; long long pid_value = 0; char pidstr[INT_BUFSIZE_BOUND(pid_value)]; char *endptr = NULL; *pid = 0; if ((fd = open(path, O_RDONLY)) < 0) { rc = -errno; goto cleanup; } bytes = saferead(fd, pidstr, sizeof(pidstr)); if (bytes < 0) { rc = -errno; VIR_FORCE_CLOSE(fd); goto cleanup; } pidstr[bytes] = '\0'; if (virStrToLong_ll(pidstr, &endptr, 10, &pid_value) < 0 || !(*endptr == '\0' || c_isspace(*endptr)) || (pid_t) pid_value != pid_value) { rc = -1; goto cleanup; } *pid = pid_value; rc = 0; cleanup: if (VIR_CLOSE(fd) < 0) rc = -errno; return rc; }
static void discover_caps(unsigned int *caps) { char line[512]; char *p, *savep = NULL, *p2; FILE *fp = fopen("/proc/cpuinfo", "r"); if (fp == NULL) return; /* this is most likely linux-only */ while(fgets(line, sizeof(line), fp) != NULL) { if (strncmp(line, "Features", 8) == 0) { p = strchr(line, ':'); if (p) { p++; while (c_isspace(*p)) p++; while((p2 = strtok_r(p, " ", &savep)) != NULL) { if (strncmp(p2, "sha2", 4) == 0) *caps |= ARMV8_SHA256; else if (strncmp(p2, "sha1", 4) == 0) *caps |= ARMV8_SHA1; else if (strncmp(p2, "pmull", 5) == 0) *caps |= ARMV8_PMULL; else if (strncmp(p2, "aes", 3) == 0) *caps |= ARMV8_AES; p = NULL; } } break; } } fclose(fp); }
void c_gets(){ char c; unsigned char len; len = 0; while((c = c_getch()) != KEY_ENTER){ if( c == 9) c = ' '; // TAB exchange Space if(((c == 8) || (c == 127)) && (len > 0)){ // Backspace manipulation len--; c_putch(8); c_putch(' '); c_putch(8); } else if(c_isprint(c) && (len < (SIZE_LINE - 1))){ lbuf[len++] = c; c_putch(c); } } newline(); lbuf[len] = 0; // Put NULL if(len > 0){ while(c_isspace(lbuf[--len])); // Skip space lbuf[++len] = 0; // Put NULL } }
/** * Check if conffiles contains sane information. */ static void check_conffiles(const char *ctrldir, const char *rootdir) { FILE *cf; struct varbuf controlfile = VARBUF_INIT; char conffilename[MAXCONFFILENAME + 1]; struct file_info *conffiles_head = NULL; struct file_info *conffiles_tail = NULL; varbuf_printf(&controlfile, "%s/%s", ctrldir, CONFFILESFILE); cf = fopen(controlfile.buf, "r"); if (cf == NULL) { if (errno == ENOENT) return; ohshite(_("error opening conffiles file")); } while (fgets(conffilename, MAXCONFFILENAME + 1, cf)) { struct stat controlstab; int n; n = strlen(conffilename); if (!n) ohshite(_("empty string from fgets reading conffiles")); if (conffilename[n - 1] != '\n') ohshit(_("conffile name '%s' is too long, or missing final newline"), conffilename); conffilename[n - 1] = '\0'; varbuf_reset(&controlfile); varbuf_printf(&controlfile, "%s/%s", rootdir, conffilename); if (lstat(controlfile.buf, &controlstab)) { if (errno == ENOENT) { if ((n > 1) && c_isspace(conffilename[n - 2])) warning(_("conffile filename '%s' contains trailing white spaces"), conffilename); ohshit(_("conffile '%.250s' does not appear in package"), conffilename); } else ohshite(_("conffile '%.250s' is not stattable"), conffilename); } else if (!S_ISREG(controlstab.st_mode)) { warning(_("conffile '%s' is not a plain file"), conffilename); } if (file_info_find_name(conffiles_head, conffilename)) { warning(_("conffile name '%s' is duplicated"), conffilename); } else { struct file_info *conffile; conffile = file_info_new(conffilename); file_info_list_append(&conffiles_head, &conffiles_tail, conffile); } } file_info_list_free(conffiles_head); varbuf_destroy(&controlfile); if (ferror(cf)) ohshite(_("error reading conffiles file")); fclose(cf); }
void wget_css_parse_buffer( const char *buf, void(*callback_uri)(void *user_ctx, const char *url, size_t len, size_t pos), void(*callback_encoding)(void *user_ctx, const char *url, size_t len), void *user_ctx) { int token; size_t length, pos = 0; char *text; yyscan_t scanner; // let flex operate on buf as a 0 terminated string // we could give buflen to this function and use yy_scan_bytes or yy_scan_buffer yylex_init(&scanner); yy_scan_string(buf, scanner); while ((token = yylex(scanner)) != CSSEOF) { if (token == IMPORT_SYM) { // e.g. @import "http:example.com/index.html" pos += yyget_leng(scanner); // skip whitespace before URI/STRING while ((token = yylex(scanner)) == S) pos += yyget_leng(scanner); // now token should be STRING or URI if (token == STRING) token = URI; } if (token == URI && callback_uri) { // e.g. url(http:example.com/index.html) text = yyget_text(scanner); length = yyget_leng(scanner); if (*text == '\'' || *text == '\"') { // a string - remove the quotes callback_uri(user_ctx, text + 1, length - 2, pos + 1); } else { // extract URI from url(...) if (!wget_strncasecmp_ascii(text, "url(", 4)) { char *otext = text; // remove trailing ) and any spaces before for (length--; c_isspace(text[length - 1]); length--); // remove leading url( and any spaces after for (length -= 4, text += 4; c_isspace(*text); text++, length--); // remove quotes if (*text == '\'' || *text == '\"') { text++; length -= 2; } callback_uri(user_ctx, text, length, pos + (text - otext)); } } } else if (token == CHARSET_SYM && callback_encoding) { // e.g. @charset "UTF-8" pos += yyget_leng(scanner); // skip whitespace before charset name while ((token = yylex(scanner)) == S) pos += yyget_leng(scanner); // now token should be STRING if (token == STRING) { text = yyget_text(scanner); length = yyget_leng(scanner); if (*text == '\'' || *text == '\"') { // a string - remove the quotes callback_encoding(user_ctx, text + 1, length - 2); } else { // a string without quotes callback_encoding(user_ctx, text, length); } } else { error_printf(_("Unknown token after @charset: %d\n"), token); } } pos += yyget_leng(scanner); } yylex_destroy(scanner); }
/** * _string2sexpr: * @buffer: a zero terminated buffer containing an S-Expression in UTF-8 * @end: pointer to an index in the buffer for the already parsed bytes * * Internal routine implementing the parse of S-Expression * Note that failure in this function is catastrophic. If it returns * NULL, you've leaked memory and you're currently OOM. It will always * parse an SEXPR given a buffer * * Returns a pointer to the resulting parsed S-Expression, or NULL in case of * hard error. */ static struct sexpr * _string2sexpr(const char *buffer, size_t * end) { const char *ptr = buffer + *end; struct sexpr *ret = sexpr_new(); if (ret == NULL) return NULL; ptr = trim(ptr); if (ptr[0] == '(') { ret->kind = SEXPR_NIL; ptr = trim(ptr + 1); while (*ptr && *ptr != ')') { struct sexpr *tmp; size_t tmp_len = 0; tmp = _string2sexpr(ptr, &tmp_len); if (tmp == NULL) goto error; if (append(ret, tmp) < 0) { sexpr_free(tmp); goto error; } ptr = trim(ptr + tmp_len); } if (*ptr == ')') { ptr++; } } else { const char *start; if (*ptr == '\'') { ptr++; start = ptr; while (*ptr && *ptr != '\'') { if (*ptr == '\\' && ptr[1]) ptr++; ptr++; } ret->u.value = strndup(start, ptr - start); if (ret->u.value == NULL) { virReportOOMError(); goto error; } if (*ptr == '\'') ptr++; } else { start = ptr; while (*ptr && !c_isspace(*ptr) && *ptr != ')' && *ptr != '(') { ptr++; } ret->u.value = strndup(start, ptr - start); if (ret->u.value == NULL) { virReportOOMError(); goto error; } } ret->kind = SEXPR_VALUE; if (ret->u.value == NULL) goto error; } *end = ptr - buffer; return ret; error: sexpr_free(ret); return NULL; }
bool portable_isspace(char c) { return c_isnewline(c) || c_isspace(c); }