root/library/bdm/base/libconfig/lib/scanctx.c @ 766

Revision 691, 4.2 kB (checked in by mido, 15 years ago)

the real update of libconfig with an addaptation of its directories
all cfg files added directly into VS solution (this change is actually concerning only the \tests directory)

Line 
1/* ----------------------------------------------------------------------------
2   libconfig - A library for processing structured configuration files
3   Copyright (C) 2005-2009  Mark A Lindner
4
5   This file is part of libconfig.
6
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public License
9   as published by the Free Software Foundation; either version 2.1 of
10   the License, or (at your option) any later version.
11
12   This library is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Library General Public
18   License along with this library; if not, see
19   <http://www.gnu.org/licenses/>.
20   ----------------------------------------------------------------------------
21*/
22
23#include "scanctx.h"
24
25#include <stddef.h>
26#include <stdlib.h>
27#include <string.h>
28
29#define STRING_BLOCK_SIZE 64
30#define CHUNK_SIZE 32
31
32/* ------------------------------------------------------------------------- */
33
34static const char *err_bad_include = "cannot open include file";
35static const char *err_include_too_deep = "include file nesting too deep";
36
37/* ------------------------------------------------------------------------- */
38
39static const char *__scanctx_add_filename(struct scan_context *ctx,
40                                          const char *filename)
41{
42  unsigned int count = ctx->num_filenames;
43  const char **f;
44
45  for(f = ctx->filenames; count > 0; ++f, --count)
46  {
47    if(!strcmp(*f, filename))
48    {
49      free((void *)filename);
50      return(*f); /* already in list */
51    }
52  }
53
54  if((ctx->num_filenames % CHUNK_SIZE) == 0)
55  {
56    ctx->filenames = (const char **)realloc(
57      (void *)ctx->filenames,
58      (ctx->num_filenames + CHUNK_SIZE) * sizeof(const char *));
59  }
60
61  ctx->filenames[ctx->num_filenames] = filename;
62  ++ctx->num_filenames;
63  return(filename);
64}
65
66/* ------------------------------------------------------------------------- */
67
68void scanctx_init(struct scan_context *ctx, const char *top_filename)
69{
70  memset(ctx, 0, sizeof(struct scan_context));
71  if(top_filename)
72    ctx->top_filename = __scanctx_add_filename(ctx, strdup(top_filename));
73}
74
75/* ------------------------------------------------------------------------- */
76
77const char **scanctx_cleanup(struct scan_context *ctx,
78                             unsigned int *num_filenames)
79{
80  int i;
81
82  for(i = 0; i < ctx->depth; ++i)
83    fclose(ctx->streams[i]);
84
85  free((void *)(strbuf_release(&(ctx->string))));
86
87  *num_filenames = ctx->num_filenames;
88  return(ctx->filenames);
89}
90
91/* ------------------------------------------------------------------------- */
92
93FILE *scanctx_push_include(struct scan_context *ctx, void *buffer,
94                           const char **error)
95{
96  FILE *fp = NULL;
97  const char *file;
98
99  *error = NULL;
100
101  if(ctx->depth == MAX_INCLUDE_DEPTH)
102  {
103    *error = err_include_too_deep;
104    return(NULL);
105  }
106
107  file = scanctx_take_string(ctx);
108  fp = fopen(file, "rt");
109  if(fp)
110  {
111    ctx->streams[ctx->depth] = fp;
112    ctx->files[ctx->depth] = __scanctx_add_filename(ctx, file);
113    ctx->buffers[ctx->depth] = buffer;
114    ++(ctx->depth);
115  }
116  else
117  {
118    free((void *)file);
119    *error = err_bad_include;
120  }
121
122  return(fp);
123}
124
125/* ------------------------------------------------------------------------- */
126
127void *scanctx_pop_include(struct scan_context *ctx)
128{
129  void *buffer;
130
131  if(ctx->depth == 0)
132    return(NULL); /* stack underflow */
133
134  --(ctx->depth);
135  buffer = ctx->buffers[ctx->depth];
136  fclose(ctx->streams[ctx->depth]);
137
138  return(buffer);
139}
140
141/* ------------------------------------------------------------------------- */
142
143char *scanctx_take_string(struct scan_context *ctx)
144{
145  char *r = strbuf_release(&(ctx->string));
146
147  return(r ? r : strdup(""));
148}
149
150/* ------------------------------------------------------------------------- */
151
152const char *scanctx_current_filename(struct scan_context *ctx)
153{
154  return((ctx->depth == 0) ? ctx->top_filename : ctx->files[ctx->depth - 1]);
155}
156
157/* ------------------------------------------------------------------------- */
158/* eof */
Note: See TracBrowser for help on using the browser.