/** * sexpr_cons: * @car: the left operand * @cdr: the right operand * * Implement the CONS operation assembling 2 existing S-Expressions. * Note that in case of error the input data are not freed. * * Returns the resulting S-Expression pointer or NULL in case of error. */ struct sexpr * sexpr_cons(const struct sexpr *car, const struct sexpr *cdr) { struct sexpr *ret = sexpr_new(); if (ret == NULL) return ret; ret->kind = SEXPR_CONS; ret->u.s.car = (struct sexpr *) car; ret->u.s.cdr = (struct sexpr *) cdr; return ret; }
/** * sexpr_string: * @str: the input string, assumed to be UTF-8 * @len: the length in bytes of the input * * Parse the input S-Expression and return a pointer to the result * * Returns the S-Expression pointer or NULL in case of error */ struct sexpr * sexpr_string(const char *str, ssize_t len) { struct sexpr *ret = sexpr_new(); if (ret == NULL) return ret; ret->kind = SEXPR_VALUE; if (VIR_STRNDUP(ret->u.value, str, len) < 0) VIR_FREE(ret); return ret; }
/** * sexpr_string: * @str: the input string, assumed to be UTF-8 * @len: the length in bytes of the input * * Parse the input S-Expression and return a pointer to the result * * Returns the S-Expression pointer or NULL in case of error */ struct sexpr * sexpr_string(const char *str, ssize_t len) { struct sexpr *ret = sexpr_new(); if (ret == NULL) return ret; ret->kind = SEXPR_VALUE; if (len > 0) { ret->u.value = strndup(str, len); } else { ret->u.value = strdup(str); } if (ret->u.value == NULL) { VIR_FREE(ret); return NULL; } return ret; }
/** * sexpr_nil: * * Provide a NIL S-Expression (the pointer is not shared so NIL equality * testing won't work at the pointer level). * * Returns a new NIL S-Expression of NULL in case of error. */ struct sexpr * sexpr_nil(void) { return sexpr_new(); }
/** * _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; }