/* ---------------------------------------------------------------------------- libconfig - A library for processing structured configuration files Copyright (C) 2005-2020 Mark A Lindner This file is part of libconfig. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, see . ---------------------------------------------------------------------------- */ #ifndef __libconfig_scanctx_h #define __libconfig_scanctx_h #include #include #include #include "libconfig.h" #include "strbuf.h" #include "strvec.h" #define MAX_INCLUDE_DEPTH 10 struct include_stack_frame { /* * Member strings are not owned; they are pointers into scan_context's * filenames vector. */ const char **files; const char **current_file; FILE *current_stream; void *parent_buffer; }; struct scan_context { config_t *config; const char *top_filename; struct include_stack_frame include_stack[MAX_INCLUDE_DEPTH]; int stack_depth; strbuf_t string; strvec_t filenames; }; extern void libconfig_scanctx_init(struct scan_context *ctx, const char *top_filename); extern const char **libconfig_scanctx_cleanup(struct scan_context *ctx); /* * Pushes a new frame onto the include stack, and returns an open stream to the * first file in the include list, if any. * * ctx - The scan context * prev_buffer - The current input buffer, to be restored when this frame is * popped * path - The string argument to the @include directive, to be expanded into a * list of zero or more filenames using the function ctx->config->include_fn * error - A pointer at which to store a static error message, if any. * * On success, the new frame will be pushed and the stream to the first file * will be returned. * * On failure, the frame will not be pushed and NULL will be returned. If * *error is NULL, it means there are no files in the list. Otherwise, it * points to an error and parsing should be aborted. */ extern FILE *libconfig_scanctx_push_include(struct scan_context *ctx, void *prev_buffer, const char *path, const char **error); /* * Returns the next include file in the current include stack frame. * * Returns NULL on failure or if there are no more files left in the current * frame. If there was an error, sets *error. */ extern FILE *libconfig_scanctx_next_include_file(struct scan_context *ctx, const char **error); /* * Pops a frame off the include stack. */ extern void *libconfig_scanctx_pop_include(struct scan_context *ctx); #define libconfig_scanctx_append_string(C, S) \ libconfig_strbuf_append_string(&((C)->string), (S)) #define libconfig_scanctx_append_char(C, X) \ libconfig_strbuf_append_char(&((C)->string), (X)) extern char *libconfig_scanctx_take_string(struct scan_context *ctx); extern const char *libconfig_scanctx_current_filename(struct scan_context *ctx); #endif /* __libconfig_scanctx_h */