OpenCOBOL 1.1pre-rel
config.c
Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines