ror_t gcry_sexp_create (gcry_sexp_t *retsexp,
                               void *buffer, size_t length,
                               int autodetect, void (*freefnc) (void *));

/* Scan BUFFER and return a new S-expression object in RETSEXP.  This
   function expects a printf like string in BUFFER.  */
gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
                              const char *buffer, size_t length);

/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
   only be used for certain encodings.  */
gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
                              const char *format, ...);

/* 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);

/* Release the S-expression object SEXP */
void gcry_sexp_release (gcry_sexp_t sexp);

/* Calculate the length of an canonized S-expression in BUFFER and
   check for a valid encoding. */
size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
                            size_t *erroff, gcry_error_t *errcode);

/* Copies the S-expression object SEXP into BUFFER using the format
   specified in MODE.  */
size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
                         size_t maxlength);

/* Dumps the S-expression object A in a format suitable for debugging
   to Libgcrypt's logging stream.  */
void gcry_sexp_dump (const gcry_sexp_t a);

gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);

/* Scan the S-expression for a sublist with a type (the car of the
   list) matching the string TOKEN.  If TOKLEN is not 0, the token is
   assumed to be raw memory of this length.  The function returns a
   newly allocated S-expression consisting of the found sublist or
   `NULL' when not found.  */
gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
                                const char *tok, size_t toklen);
/* Return the length of the LIST.  For a valid S-expression this
   should be at least 1.  */
int gcry_sexp_length (const gcry_sexp_t list);

/* Create and return a new S-expression from the element with index
   NUMBER in LIST.  Note that the first element has the index 0.  If
   there is no such element, `NULL' is returned.  */
gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);

/* Create and return a new S-expression from the first element in
   LIST; this called the "type" and should always exist and be a
   string. `NULL' is returned in case of a problem.  */
gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);

/* Create and return a new list form all elements except for the first
   one.  Note, that this function may return an invalid S-expression
   because it is not guaranteed, that the type exists and is a string.
   However, for parsing a complex S-expression it might be useful for
   intermediate lists.  Returns `NULL' on error.  */
gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);

gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);


/* This function is used to get data from a LIST.  A pointer to the
   actual data with index NUMBER is returned and the length of this
   data will be stored to DATALEN.  If there is no data at the given
   index or the index represents another list, `NULL' is returned.
   *Note:* The returned pointer is valid as long as LIST is not
   modified or released.  */
const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
                                size_t *datalen);

/* This function is used to get data from a LIST.  A malloced buffer to the
   data with index NUMBER is returned and the length of this
   data will be stored to RLENGTH.  If there is no data at the given
   index or the index represents another list, `NULL' is returned.  */
void *gcry_sexp_nth_buffer (const gcry_sexp_t list, int number,
                            size_t *rlength);

/* This function is used to get and convert data from a LIST.  The
   data is assumed to be a Nul terminated string.  The caller must
   release the returned value using `gcry_free'.  If there is no data
   at the given index, the index represents a list or the value can't
   be converted to a string, `NULL' is returned.  */
char *gcry_sexp_nth_string (gcry_sexp_t list, int number);

/* This function is used to get and convert data from a LIST. This
   data is assumed to be an MPI stored in the format described by
   MPIFMT and returned as a standard Libgcrypt MPI.  The caller must
   release this returned value using `gcry_mpi_release'.  If there is
   no data at the given index, the index represents a list or the
   value can't be converted to an MPI, `NULL' is returned.  */
gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);

/* Extract MPIs from an s-expression using a list of parameters.  The
 * names of these parameters are given by the string LIST.  Some
 * special characters may be given to control the conversion:
 *
 *    + :: Switch to unsigned integer format (default).
 *    - :: Switch to standard signed format.
 *    / :: Switch to opaque format.
 *    & :: Switch to buffer descriptor mode - see below.
 *    ? :: The previous parameter is optional.
 *
 * In general parameter names are single letters.  To use a string for
 * a parameter name, enclose the name in single quotes.
 *
 * Unless in gcry_buffer_t mode for each parameter name a pointer to
 * an MPI variable is expected that must be set to NULL prior to
 * invoking this function, and finally a NULL is expected.  Example:
 *
 *   _gcry_sexp_extract_param (key, NULL, "n/x+ed",
 *                             &mpi_n, &mpi_x, &mpi_e, NULL)
 *
 * This stores the parameter "N" from KEY as an unsigned MPI into
 * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
 * parameter "E" again as an unsigned MPI into MPI_E.
 *
 * If in buffer descriptor mode a pointer to gcry_buffer_t descriptor
 * is expected instead of a pointer to an MPI.  The caller may use two
 * different operation modes: If the DATA field of the provided buffer
 * descriptor is NULL, the function allocates a new buffer and stores
 * it at DATA; the other fields are set accordingly with OFF being 0.
 * If DATA is not NULL, the function assumes that DATA, SIZE, and OFF
 * describe a buffer where to but the data; on return the LEN field
 * receives the number of bytes copied to that buffer; if the buffer
 * is too small, the function immediately returns with an error code
 * (and LEN set to 0).
 *
 * PATH is an optional string used to locate a token.  The exclamation
 * mark separated tokens are used to via gcry_sexp_find_token to find
 * a start point inside SEXP.
 *
 * The function returns 0 on success.  On error an error code is
 * returned, all passed MPIs that might have been allocated up to this
 * point are deallocated and set to NULL, and all passed buffers are
 * either truncated if the caller supplied the buffer, or deallocated
 * if the function allocated the buffer.
 */
gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
                                     const char *path,
                                     const char *list,
                                     ...) _GCRY_GCC_ATTR_SENTINEL(0);

