OpenCOBOL 1.1pre-rel
|
00001 /* 00002 * Copyright (C) 2003-2009 Keisuke Nishida 00003 * Copyright (C) 2007-2009 Roger While 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2, or (at your option) 00008 * any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this software; see the file COPYING. If not, write to 00017 * the Free Software Foundation, 51 Franklin Street, Fifth Floor 00018 * Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include "config.h" 00022 #include "defaults.h" 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <ctype.h> 00028 00029 #include "cobc.h" 00030 00031 #undef CB_CONFIG_ANY 00032 #undef CB_CONFIG_INT 00033 #undef CB_CONFIG_STRING 00034 #undef CB_CONFIG_BOOLEAN 00035 #undef CB_CONFIG_SUPPORT 00036 #define CB_CONFIG_ANY(type,var,name) type var; 00037 #define CB_CONFIG_INT(var,name) int var; 00038 #define CB_CONFIG_STRING(var,name) const char *var; 00039 #define CB_CONFIG_BOOLEAN(var,name) int var; 00040 #define CB_CONFIG_SUPPORT(var,name) enum cb_support var; 00041 #include "config.def" 00042 00043 enum cb_config_type { 00044 ANY, 00045 INT, /* integer */ 00046 STRING, /* "..." */ 00047 BOOLEAN, /* 'yes', 'no' */ 00048 SUPPORT /* 'ok', 'archaic', 'obsolete', 00049 'skip', 'ignore', 'unconformable' */ 00050 }; 00051 00052 struct noreserve *norestab = NULL; 00053 00054 static struct { 00055 const enum cb_config_type type; 00056 const char *name; 00057 void *var; 00058 char *val; 00059 } config_table[] = { 00060 {STRING, "include", NULL, NULL}, 00061 {STRING, "not-reserved", NULL, NULL}, 00062 #undef CB_CONFIG_ANY 00063 #undef CB_CONFIG_INT 00064 #undef CB_CONFIG_STRING 00065 #undef CB_CONFIG_BOOLEAN 00066 #undef CB_CONFIG_SUPPORT 00067 #define CB_CONFIG_ANY(type,var,name) {ANY, name, &var, NULL}, 00068 #define CB_CONFIG_INT(var,name) {INT, name, &var, NULL}, 00069 #define CB_CONFIG_STRING(var,name) {STRING, name, &var, NULL}, 00070 #define CB_CONFIG_BOOLEAN(var,name) {BOOLEAN, name, &var, NULL}, 00071 #define CB_CONFIG_SUPPORT(var,name) {SUPPORT, name, &var, NULL}, 00072 #include "config.def" 00073 {0, NULL, NULL, NULL} 00074 }; 00075 00076 static char * 00077 read_string (const char *text) 00078 { 00079 char *p; 00080 char *s = strdup (text); 00081 00082 if (*s == '\"') { 00083 s++; 00084 } 00085 for (p = s; *p; p++) { 00086 if (*p == '\"') { 00087 *p = '\0'; 00088 } 00089 } 00090 return s; 00091 } 00092 00093 static void 00094 invalid_value (const char *fname, const int line, const char *name) 00095 { 00096 fprintf (stderr, _("%s:%d: invalid value for '%s'\n"), fname, line, name); 00097 } 00098 00099 static void 00100 unsupported_value (const char *fname, const int line, const char *val) 00101 { 00102 fprintf (stderr, _("%s:%d: '%s' not supported\n"), fname, line, val); 00103 } 00104 00105 int 00106 cb_load_std (const char *name) 00107 { 00108 return cb_load_conf (name, 1, 1); 00109 } 00110 00111 int 00112 cb_load_conf (const char *fname, const int check_nodef, const int prefix_dir) 00113 { 00114 char *s; 00115 char *e; 00116 const char *name; 00117 const char *val; 00118 void *var; 00119 FILE *fp; 00120 char *nores; 00121 struct noreserve *noresptr; 00122 int i; 00123 int j; 00124 int ret; 00125 int saveret; 00126 int line; 00127 char buff[COB_SMALL_BUFF]; 00128 00129 /* initialize the config table */ 00130 if (check_nodef) { 00131 for (i = 0; config_table[i].name; i++) { 00132 config_table[i].val = NULL; 00133 } 00134 } 00135 00136 if (prefix_dir) { 00137 snprintf (buff, COB_SMALL_MAX, "%s/%s", cob_config_dir, fname); 00138 name = buff; 00139 } else { 00140 name = fname; 00141 } 00142 /* open the config file */ 00143 fp = fopen (name, "r"); 00144 if (fp == NULL) { 00145 perror (name); 00146 return -1; 00147 } 00148 00149 /* read the config file */ 00150 ret = 0; 00151 line = 0; 00152 while (fgets (buff, COB_SMALL_BUFF, fp)) { 00153 line++; 00154 00155 /* skip comments */ 00156 if (buff[0] == '#') { 00157 continue; 00158 } 00159 00160 /* skip blank lines */ 00161 for (s = buff; *s; s++) { 00162 if (isgraph (*s)) { 00163 break; 00164 } 00165 } 00166 if (!*s) { 00167 continue; 00168 } 00169 00170 /* get the tag */ 00171 s = strpbrk (buff, " \t:="); 00172 if (!s) { 00173 fprintf (stderr, "%s:%d: invalid line\n", fname, line); 00174 ret = -1; 00175 continue; 00176 } 00177 *s = 0; 00178 00179 /* find the entry */ 00180 for (i = 0; config_table[i].name; i++) { 00181 if (strcmp (buff, config_table[i].name) == 0) { 00182 break; 00183 } 00184 } 00185 if (!config_table[i].name) { 00186 fprintf (stderr, "%s:%d: unknown tag '%s'\n", fname, line, buff); 00187 ret = -1; 00188 continue; 00189 } 00190 00191 /* get the value */ 00192 for (s++; *s && strchr (" \t:=", *s); s++) { 00193 ; 00194 } 00195 e = s + strlen (s) - 1; 00196 for (; e >= s && strchr (" \t\r\n", *e); e--) { 00197 ; 00198 } 00199 e[1] = 0; 00200 config_table[i].val = s; 00201 00202 /* set the value */ 00203 name = config_table[i].name; 00204 var = config_table[i].var; 00205 val = config_table[i].val; 00206 switch (config_table[i].type) { 00207 case ANY: 00208 if (strcmp (name, "assign-clause") == 0) { 00209 if (strcmp (val, "cobol2002") == 0) { 00210 unsupported_value (fname, line, val); 00211 ret = -1; 00212 } else if (strcmp (val, "mf") == 0) { 00213 cb_assign_clause = CB_ASSIGN_MF; 00214 } else if (strcmp (val, "ibm") == 0) { 00215 cb_assign_clause = CB_ASSIGN_IBM; 00216 } else { 00217 invalid_value (fname, line, name); 00218 ret = -1; 00219 } 00220 } else if (strcmp (name, "binary-size") == 0) { 00221 if (strcmp (val, "2-4-8") == 0) { 00222 cb_binary_size = CB_BINARY_SIZE_2_4_8; 00223 } else if (strcmp (val, "1-2-4-8") == 0) { 00224 cb_binary_size = CB_BINARY_SIZE_1_2_4_8; 00225 } else if (strcmp (val, "1--8") == 0) { 00226 cb_binary_size = CB_BINARY_SIZE_1__8; 00227 } else { 00228 invalid_value (fname, line, name); 00229 ret = -1; 00230 } 00231 } else if (strcmp (name, "binary-byteorder") == 0) { 00232 if (strcmp (val, "native") == 0) { 00233 cb_binary_byteorder = CB_BYTEORDER_NATIVE; 00234 } else if (strcmp (val, "big-endian") == 0) { 00235 cb_binary_byteorder = CB_BYTEORDER_BIG_ENDIAN; 00236 } else { 00237 invalid_value (fname, line, name); 00238 ret = -1; 00239 } 00240 } 00241 break; 00242 case INT: 00243 for (j = 0; val[j]; j++) { 00244 if (!isdigit (val[j])) { 00245 invalid_value (fname, line, name); 00246 ret = -1; 00247 break; 00248 } 00249 } 00250 *((int *)var) = atoi (val); 00251 break; 00252 case STRING: 00253 val = read_string (val); 00254 00255 if (strcmp (name, "include") == 0) { 00256 /* include another conf file */ 00257 saveret = ret; 00258 if (cb_load_conf (val, 0, 1) != 0) { 00259 return -1; 00260 } 00261 ret = saveret; 00262 } else if (strcmp (name, "not-reserved") == 0) { 00263 nores = read_string (val); 00264 noresptr = cobc_malloc (sizeof (struct noreserve)); 00265 noresptr->noresword = cobc_malloc (strlen (nores) + 1); 00266 strcpy (noresptr->noresword, nores); 00267 noresptr->next = norestab; 00268 norestab = noresptr; 00269 } else { 00270 *((const char **)var) = val; 00271 } 00272 break; 00273 case BOOLEAN: 00274 if (strcmp (val, "yes") == 0) { 00275 *((int *)var) = 1; 00276 } else if (strcmp (val, "no") == 0) { 00277 *((int *)var) = 0; 00278 } else { 00279 invalid_value (fname, line, name); 00280 ret = -1; 00281 } 00282 break; 00283 case SUPPORT: 00284 if (strcmp (val, "ok") == 0) { 00285 *((enum cb_support *)var) = CB_OK; 00286 } else if (strcmp (val, "warning") == 0) { 00287 *((enum cb_support *)var) = CB_WARNING; 00288 } else if (strcmp (val, "archaic") == 0) { 00289 *((enum cb_support *)var) = CB_ARCHAIC; 00290 } else if (strcmp (val, "obsolete") == 0) { 00291 *((enum cb_support *)var) = CB_OBSOLETE; 00292 } else if (strcmp (val, "skip") == 0) { 00293 *((enum cb_support *)var) = CB_SKIP; 00294 } else if (strcmp (val, "ignore") == 0) { 00295 *((enum cb_support *)var) = CB_IGNORE; 00296 } else if (strcmp (val, "error") == 0) { 00297 *((enum cb_support *)var) = CB_ERROR; 00298 } else if (strcmp (val, "unconformable") == 0) { 00299 *((enum cb_support *)var) = CB_UNCONFORMABLE; 00300 } else { 00301 invalid_value (fname, line, name); 00302 ret = -1; 00303 } 00304 break; 00305 default: 00306 fprintf (stderr, _("%s:%d: invalid type for '%s'\n"), 00307 fname, line, name); 00308 ret = -1; 00309 break; 00310 } 00311 } 00312 fclose (fp); 00313 00314 /* checks for no definition */ 00315 if (check_nodef) { 00316 for (i = 2; config_table[i].name; i++) { 00317 if (config_table[i].val == NULL) { 00318 fprintf (stderr, "%s: no definition of '%s'\n", 00319 fname, config_table[i].name); 00320 ret = -1; 00321 } 00322 } 00323 } 00324 00325 return ret; 00326 }