gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, const char *buffer, size_t length) { /* We don't need the va_list because it is controlled by the following flag, however we have to pass it but can't initialize it as there is no portable way to do so. volatile is needed to suppress the compiler warning */ volatile va_list dummy_arg_ptr; return sexp_sscan (retsexp, erroff, buffer, length, 0, dummy_arg_ptr, NULL); }
gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...) { gcry_error_t rc; va_list arg_ptr; va_start (arg_ptr, format); rc = sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_ptr, NULL); va_end (arg_ptr); return rc; }
/* Like gcry_sexp_build, but uses an array instead of variable function arguments. */ gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, const char *format, void **arg_list) { /* We don't need the va_list because it is controlled by the following flag, however we have to pass it but can't initialize it as there is no portable way to do so. volatile is needed to suppress the compiler warning */ volatile va_list dummy_arg_ptr; gcry_error_t rc; rc = sexp_sscan (retsexp, erroff, format, strlen(format), 1, dummy_arg_ptr, arg_list); return rc; }
/* Create a new S-expression object by reading LENGTH bytes from BUFFER, assuming it is canonilized encoded or autodetected encoding when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of the buffer is transferred to tyhe newle created object. FREEFNC should be the freefnc used to release BUFFER; there is no guarantee at which point this function is called; most likey you want to use free() or gcry_free(). Passing LENGTH and AUTODETECT as 0 is allowed to indicate that BUFFER points to a valid canonical encoded S-expression. A LENGTH of 0 and AUTODETECT 1 indicates that buffer points to a null-terminated string. This function returns 0 and and the pointer to the new object in RETSEXP or an error code in which case RETSEXP is set to NULL. */ gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length, int autodetect, void (*freefnc)(void*) ) { gcry_error_t errcode; gcry_sexp_t se; volatile va_list dummy_arg_ptr; if (!retsexp) return gcry_error (GPG_ERR_INV_ARG); *retsexp = NULL; if (autodetect < 0 || autodetect > 1 || !buffer) return gcry_error (GPG_ERR_INV_ARG); if (!length && !autodetect) { /* What a brave caller to assume that there is really a canonical encoded S-expression in buffer */ length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode); if (!length) return errcode; } else if (!length && autodetect) { /* buffer is a string */ length = strlen ((char *)buffer); } errcode = sexp_sscan (&se, NULL, buffer, length, 0, dummy_arg_ptr, NULL); if (errcode) return errcode; *retsexp = se; if (freefnc) { /* For now we release the buffer immediately. As soon as we have changed the internal represenation of S-expression to the canoncial format - which has the advantage of faster parsing - we will use this function as a closure in our GCRYSEXP object and use the BUFFER directly */ freefnc (buffer); } return gcry_error (GPG_ERR_NO_ERROR); }
gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, const char *buffer, size_t length) { return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL); }
/* Like gcry_sexp_build, but uses an array instead of variable function arguments. */ gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, const char *format, void **arg_list) { return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list); }