xref: /aosp_15_r20/external/libconfig/examples/c/example4.c (revision 2e9d491483b805f09ea864149eadd5680efcc72a)
1*2e9d4914SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------------
2*2e9d4914SAndroid Build Coastguard Worker    libconfig - A library for processing structured configuration files
3*2e9d4914SAndroid Build Coastguard Worker    Copyright (C) 2005-2018  Mark A Lindner
4*2e9d4914SAndroid Build Coastguard Worker 
5*2e9d4914SAndroid Build Coastguard Worker    This file is part of libconfig.
6*2e9d4914SAndroid Build Coastguard Worker 
7*2e9d4914SAndroid Build Coastguard Worker    This library is free software; you can redistribute it and/or
8*2e9d4914SAndroid Build Coastguard Worker    modify it under the terms of the GNU Lesser General Public License
9*2e9d4914SAndroid Build Coastguard Worker    as published by the Free Software Foundation; either version 2.1 of
10*2e9d4914SAndroid Build Coastguard Worker    the License, or (at your option) any later version.
11*2e9d4914SAndroid Build Coastguard Worker 
12*2e9d4914SAndroid Build Coastguard Worker    This library is distributed in the hope that it will be useful, but
13*2e9d4914SAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
14*2e9d4914SAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15*2e9d4914SAndroid Build Coastguard Worker    Lesser General Public License for more details.
16*2e9d4914SAndroid Build Coastguard Worker 
17*2e9d4914SAndroid Build Coastguard Worker    You should have received a copy of the GNU Library General Public
18*2e9d4914SAndroid Build Coastguard Worker    License along with this library; if not, see
19*2e9d4914SAndroid Build Coastguard Worker    <http://www.gnu.org/licenses/>.
20*2e9d4914SAndroid Build Coastguard Worker    ----------------------------------------------------------------------------
21*2e9d4914SAndroid Build Coastguard Worker */
22*2e9d4914SAndroid Build Coastguard Worker 
23*2e9d4914SAndroid Build Coastguard Worker #include <dirent.h>
24*2e9d4914SAndroid Build Coastguard Worker #include <fnmatch.h>
25*2e9d4914SAndroid Build Coastguard Worker #include <limits.h>
26*2e9d4914SAndroid Build Coastguard Worker #include <stdio.h>
27*2e9d4914SAndroid Build Coastguard Worker #include <stdlib.h>
28*2e9d4914SAndroid Build Coastguard Worker #include <string.h>
29*2e9d4914SAndroid Build Coastguard Worker #include <sys/stat.h>
30*2e9d4914SAndroid Build Coastguard Worker 
31*2e9d4914SAndroid Build Coastguard Worker #include <libconfig.h>
32*2e9d4914SAndroid Build Coastguard Worker 
33*2e9d4914SAndroid Build Coastguard Worker /* This example reads the configuration file 'example.cfg' and displays
34*2e9d4914SAndroid Build Coastguard Worker  * some of its contents.
35*2e9d4914SAndroid Build Coastguard Worker  */
36*2e9d4914SAndroid Build Coastguard Worker 
include_func(config_t * config,const char * include_dir,const char * path,const char ** error)37*2e9d4914SAndroid Build Coastguard Worker static const char **include_func(config_t *config,
38*2e9d4914SAndroid Build Coastguard Worker                                  const char *include_dir,
39*2e9d4914SAndroid Build Coastguard Worker                                  const char *path,
40*2e9d4914SAndroid Build Coastguard Worker                                  const char **error)
41*2e9d4914SAndroid Build Coastguard Worker {
42*2e9d4914SAndroid Build Coastguard Worker   char *p;
43*2e9d4914SAndroid Build Coastguard Worker   DIR *dp;
44*2e9d4914SAndroid Build Coastguard Worker   struct dirent *dir_entry;
45*2e9d4914SAndroid Build Coastguard Worker   struct stat stat_buf;
46*2e9d4914SAndroid Build Coastguard Worker   char include_path[PATH_MAX + 1];
47*2e9d4914SAndroid Build Coastguard Worker   size_t include_path_len = 0;
48*2e9d4914SAndroid Build Coastguard Worker   char file_path[PATH_MAX + 1];
49*2e9d4914SAndroid Build Coastguard Worker   char **result = NULL;
50*2e9d4914SAndroid Build Coastguard Worker   char **result_next = result;
51*2e9d4914SAndroid Build Coastguard Worker   int result_count = 0;
52*2e9d4914SAndroid Build Coastguard Worker   int result_capacity = 0;
53*2e9d4914SAndroid Build Coastguard Worker 
54*2e9d4914SAndroid Build Coastguard Worker   *include_path = 0;
55*2e9d4914SAndroid Build Coastguard Worker 
56*2e9d4914SAndroid Build Coastguard Worker   if(*path != '/')
57*2e9d4914SAndroid Build Coastguard Worker   {
58*2e9d4914SAndroid Build Coastguard Worker     if(include_dir)
59*2e9d4914SAndroid Build Coastguard Worker     {
60*2e9d4914SAndroid Build Coastguard Worker       strcat(include_path, include_dir);
61*2e9d4914SAndroid Build Coastguard Worker       include_path_len += strlen(include_dir);
62*2e9d4914SAndroid Build Coastguard Worker     }
63*2e9d4914SAndroid Build Coastguard Worker   }
64*2e9d4914SAndroid Build Coastguard Worker 
65*2e9d4914SAndroid Build Coastguard Worker   p = strrchr(path, '/');
66*2e9d4914SAndroid Build Coastguard Worker   if(p > path)
67*2e9d4914SAndroid Build Coastguard Worker   {
68*2e9d4914SAndroid Build Coastguard Worker     int len = p - path;
69*2e9d4914SAndroid Build Coastguard Worker 
70*2e9d4914SAndroid Build Coastguard Worker     if((include_path_len > 0)
71*2e9d4914SAndroid Build Coastguard Worker        && (*(include_path + include_path_len - 1) != '/'))
72*2e9d4914SAndroid Build Coastguard Worker     {
73*2e9d4914SAndroid Build Coastguard Worker       strcat(include_path, "/");
74*2e9d4914SAndroid Build Coastguard Worker       ++include_path_len;
75*2e9d4914SAndroid Build Coastguard Worker     }
76*2e9d4914SAndroid Build Coastguard Worker 
77*2e9d4914SAndroid Build Coastguard Worker     strncat(include_path, path, len);
78*2e9d4914SAndroid Build Coastguard Worker     include_path_len += len;
79*2e9d4914SAndroid Build Coastguard Worker   }
80*2e9d4914SAndroid Build Coastguard Worker 
81*2e9d4914SAndroid Build Coastguard Worker   if(include_path_len == 0)
82*2e9d4914SAndroid Build Coastguard Worker   {
83*2e9d4914SAndroid Build Coastguard Worker     strcpy(include_path, ".");
84*2e9d4914SAndroid Build Coastguard Worker     include_path_len = 1;
85*2e9d4914SAndroid Build Coastguard Worker   }
86*2e9d4914SAndroid Build Coastguard Worker 
87*2e9d4914SAndroid Build Coastguard Worker   dp = opendir(include_path);
88*2e9d4914SAndroid Build Coastguard Worker   if(dp)
89*2e9d4914SAndroid Build Coastguard Worker   {
90*2e9d4914SAndroid Build Coastguard Worker     while((dir_entry = readdir(dp)) != NULL)
91*2e9d4914SAndroid Build Coastguard Worker     {
92*2e9d4914SAndroid Build Coastguard Worker       snprintf(file_path, PATH_MAX, "%s/%s", include_path, dir_entry->d_name);
93*2e9d4914SAndroid Build Coastguard Worker       if(lstat(file_path, &stat_buf) != 0) continue;
94*2e9d4914SAndroid Build Coastguard Worker       if(!S_ISREG(stat_buf.st_mode)) continue;
95*2e9d4914SAndroid Build Coastguard Worker       if(fnmatch(path, file_path, FNM_PATHNAME) != 0) continue;
96*2e9d4914SAndroid Build Coastguard Worker 
97*2e9d4914SAndroid Build Coastguard Worker       if(result_count == result_capacity)
98*2e9d4914SAndroid Build Coastguard Worker       {
99*2e9d4914SAndroid Build Coastguard Worker         result_capacity += 16;
100*2e9d4914SAndroid Build Coastguard Worker         result = (char **)realloc(result, (result_capacity + 1) * sizeof(char *));
101*2e9d4914SAndroid Build Coastguard Worker         result_next = result + result_count;
102*2e9d4914SAndroid Build Coastguard Worker       }
103*2e9d4914SAndroid Build Coastguard Worker 
104*2e9d4914SAndroid Build Coastguard Worker       *result_next = strdup(file_path);
105*2e9d4914SAndroid Build Coastguard Worker       ++result_next;
106*2e9d4914SAndroid Build Coastguard Worker       ++result_count;
107*2e9d4914SAndroid Build Coastguard Worker 
108*2e9d4914SAndroid Build Coastguard Worker       printf("file: %s\n", file_path);
109*2e9d4914SAndroid Build Coastguard Worker     }
110*2e9d4914SAndroid Build Coastguard Worker     closedir(dp);
111*2e9d4914SAndroid Build Coastguard Worker   }
112*2e9d4914SAndroid Build Coastguard Worker 
113*2e9d4914SAndroid Build Coastguard Worker   *result_next = NULL;
114*2e9d4914SAndroid Build Coastguard Worker 
115*2e9d4914SAndroid Build Coastguard Worker   return((const char **)result);
116*2e9d4914SAndroid Build Coastguard Worker }
117*2e9d4914SAndroid Build Coastguard Worker 
main(int argc,char ** argv)118*2e9d4914SAndroid Build Coastguard Worker int main(int argc, char **argv)
119*2e9d4914SAndroid Build Coastguard Worker {
120*2e9d4914SAndroid Build Coastguard Worker   config_t cfg;
121*2e9d4914SAndroid Build Coastguard Worker 
122*2e9d4914SAndroid Build Coastguard Worker   config_init(&cfg);
123*2e9d4914SAndroid Build Coastguard Worker   config_set_include_func(&cfg, include_func);
124*2e9d4914SAndroid Build Coastguard Worker 
125*2e9d4914SAndroid Build Coastguard Worker   /* Read the file. If there is an error, report it and exit. */
126*2e9d4914SAndroid Build Coastguard Worker   if(! config_read_file(&cfg, "example4.cfg"))
127*2e9d4914SAndroid Build Coastguard Worker   {
128*2e9d4914SAndroid Build Coastguard Worker     fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
129*2e9d4914SAndroid Build Coastguard Worker             config_error_line(&cfg), config_error_text(&cfg));
130*2e9d4914SAndroid Build Coastguard Worker     config_destroy(&cfg);
131*2e9d4914SAndroid Build Coastguard Worker     return(EXIT_FAILURE);
132*2e9d4914SAndroid Build Coastguard Worker   }
133*2e9d4914SAndroid Build Coastguard Worker 
134*2e9d4914SAndroid Build Coastguard Worker   config_write(&cfg, stdout);
135*2e9d4914SAndroid Build Coastguard Worker 
136*2e9d4914SAndroid Build Coastguard Worker   return(EXIT_SUCCESS);
137*2e9d4914SAndroid Build Coastguard Worker }
138