OpenCOBOL 1.1pre-rel
error.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 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <stdarg.h>
00027 
00028 #include "cobc.h"
00029 #include "tree.h"
00030 
00031 static char     *errnamebuff = NULL;
00032 
00033 static void
00034 print_error (char *file, int line, const char *prefix, const char *fmt, va_list ap)
00035 {
00036         static struct cb_label *last_section = NULL;
00037         static struct cb_label *last_paragraph = NULL;
00038 
00039         file = file ? file : cb_source_file;
00040         line = line ? line : cb_source_line;
00041 
00042         /* print the paragraph or section name */
00043         if (current_section != last_section || current_paragraph != last_paragraph) {
00044                 if (current_paragraph &&
00045                     strcmp ((const char *)(current_paragraph->name), "MAIN PARAGRAPH")) {
00046                         fprintf (stderr, _("%s: In paragraph '%s':\n"),
00047                                  file, current_paragraph->name);
00048                 } else if (current_section &&
00049                            strcmp ((const char *)(current_section->name), "MAIN SECTION")) {
00050                                 fprintf (stderr, _("%s: In section '%s':\n"),
00051                                         file, current_section->name);
00052                 }
00053                 last_section = current_section;
00054                 last_paragraph = current_paragraph;
00055         }
00056 
00057         /* print the error */
00058         fprintf (stderr, "%s:%d: %s", file, line, prefix);
00059         vfprintf (stderr, fmt, ap);
00060         fputs ("\n", stderr);
00061 }
00062 
00063 char *
00064 check_filler_name (char *name)
00065 {
00066         if (!memcmp (name, "WORK$", 5)) {
00067                 name = (char *)"FILLER";
00068         }
00069         return name;
00070 }
00071 
00072 void
00073 cb_warning (const char *fmt, ...)
00074 {
00075         va_list ap;
00076 
00077         va_start (ap, fmt);
00078         print_error (NULL, 0, "Warning: ", fmt, ap);
00079         va_end (ap);
00080 
00081         warningcount++;
00082 }
00083 
00084 void
00085 cb_error (const char *fmt, ...)
00086 {
00087         va_list ap;
00088 
00089         va_start (ap, fmt);
00090         print_error (NULL, 0, "Error: ", fmt, ap);
00091         va_end (ap);
00092 
00093         errorcount++;
00094 
00095 }
00096 
00097 void
00098 cb_warning_x (cb_tree x, const char *fmt, ...)
00099 {
00100         va_list ap;
00101 
00102         va_start (ap, fmt);
00103         print_error ((char *)(x->source_file), x->source_line, "Warning: ", fmt, ap);
00104         va_end (ap);
00105 
00106         warningcount++;
00107 }
00108 
00109 void
00110 cb_error_x (cb_tree x, const char *fmt, ...)
00111 {
00112         va_list ap;
00113 
00114         va_start (ap, fmt);
00115         print_error ((char *)(x->source_file), x->source_line, "Error: ", fmt, ap);
00116         va_end (ap);
00117 
00118         errorcount++;
00119 }
00120 
00121 int
00122 cb_verify (const enum cb_support tag, const char *feature)
00123 {
00124         switch (tag) {
00125         case CB_OK:
00126                 return 1;
00127         case CB_WARNING:
00128                 return 1;
00129         case CB_ARCHAIC:
00130                 if (cb_warn_archaic) {
00131                         cb_warning (_("%s is archaic in %s"), feature, cb_config_name);
00132                 }
00133                 return 1;
00134         case CB_OBSOLETE:
00135                 if (cb_warn_obsolete) {
00136                         cb_warning (_("%s is obsolete in %s"), feature, cb_config_name);
00137                 }
00138                 return 1;
00139         case CB_SKIP:
00140                 return 0;
00141         case CB_IGNORE:
00142                 cb_warning (_("%s ignored"), feature);
00143                 return 0;
00144         case CB_ERROR:
00145                 return 0;
00146         case CB_UNCONFORMABLE:
00147                 cb_error (_("%s does not conform to %s"), feature, cb_config_name);
00148                 return 0;
00149         }
00150         return 0;
00151 }
00152 
00153 void
00154 redefinition_error (cb_tree x)
00155 {
00156         struct cb_word  *w;
00157 
00158         w = CB_REFERENCE (x)->word;
00159         cb_error_x (x, _("Redefinition of '%s'"), w->name);
00160         cb_error_x (CB_VALUE (w->items), _("'%s' previously defined here"), w->name);
00161 }
00162 
00163 void
00164 redefinition_warning (cb_tree x, cb_tree y)
00165 {
00166         struct cb_word  *w;
00167 
00168         w = CB_REFERENCE (x)->word;
00169         cb_warning_x (x, _("Redefinition of '%s'"), w->name);
00170         if (y) {
00171                 cb_warning_x (y, _("'%s' previously defined here"), w->name);
00172         } else {
00173                 cb_warning_x (CB_VALUE (w->items), _("'%s' previously defined here"), w->name);
00174         }
00175 }
00176 
00177 void
00178 undefined_error (cb_tree x)
00179 {
00180         struct cb_reference     *r;
00181         cb_tree                 c;
00182 
00183         if (!errnamebuff) {
00184                 errnamebuff = cobc_malloc (COB_NORMAL_BUFF);
00185         }
00186         r = CB_REFERENCE (x);
00187         snprintf (errnamebuff, COB_NORMAL_MAX, "'%s'", CB_NAME (x));
00188         for (c = r->chain; c; c = CB_REFERENCE (c)->chain) {
00189                 strcat (errnamebuff, " in '");
00190                 strcat (errnamebuff, CB_NAME (c));
00191                 strcat (errnamebuff, "'");
00192         }
00193         cb_error_x (x, _("%s undefined"), errnamebuff);
00194 }
00195 
00196 void
00197 ambiguous_error (cb_tree x)
00198 {
00199         struct cb_word  *w;
00200         struct cb_field *p;
00201         struct cb_label *l2;
00202         cb_tree         l;
00203         cb_tree         y;
00204 
00205         w = CB_REFERENCE (x)->word;
00206         if (w->error == 0) {
00207                 if (!errnamebuff) {
00208                         errnamebuff = cobc_malloc (COB_NORMAL_BUFF);
00209                 }
00210                 /* display error on the first time */
00211                 snprintf (errnamebuff, COB_NORMAL_MAX, "'%s'", CB_NAME (x));
00212                 for (l = CB_REFERENCE (x)->chain; l; l = CB_REFERENCE (l)->chain) {
00213                         strcat (errnamebuff, " in '");
00214                         strcat (errnamebuff, CB_NAME (l));
00215                         strcat (errnamebuff, "'");
00216                 }
00217                 cb_error_x (x, _("%s ambiguous; need qualification"), errnamebuff);
00218                 w->error = 1;
00219 
00220                 /* display all fields with the same name */
00221                 for (l = w->items; l; l = CB_CHAIN (l)) {
00222                         y = CB_VALUE (l);
00223                         snprintf (errnamebuff, COB_NORMAL_MAX, "'%s' ", w->name);
00224                         switch (CB_TREE_TAG (y)) {
00225                         case CB_TAG_FIELD:
00226                                 for (p = CB_FIELD (y)->parent; p; p = p->parent) {
00227                                         strcat (errnamebuff, "in '");
00228                                         strcat (errnamebuff, p->name);
00229                                         strcat (errnamebuff, "' ");
00230                                 }
00231                                 break;
00232                         case CB_TAG_LABEL:
00233                                 l2 = CB_LABEL (y);
00234                                 if (l2->section) {
00235                                         strcat (errnamebuff, "in '");
00236                                         strcat (errnamebuff, (const char *)(l2->section->name));
00237                                         strcat (errnamebuff, "' ");
00238                                 }
00239                                 break;
00240                         default:
00241                                 break;
00242                         }
00243                         strcat (errnamebuff, _("defined here"));
00244                         cb_error_x (y, errnamebuff);
00245                 }
00246         }
00247 }
00248 
00249 void
00250 group_error (cb_tree x, const char *clause)
00251 {
00252         cb_error_x (x, _("Group item '%s' cannot have %s clause"), check_filler_name (cb_name (x)), clause);
00253 }
00254 
00255 void
00256 level_redundant_error (cb_tree x, const char *clause)
00257 {
00258         cb_error_x (x, _("Level %02d item '%s' cannot have %s clause"),
00259                     cb_field (x)->level, check_filler_name (cb_name (x)), clause);
00260 }
00261 
00262 void
00263 level_require_error (cb_tree x, const char *clause)
00264 {
00265         cb_error_x (x, _("Level %02d item '%s' requires %s clause"),
00266                     cb_field (x)->level, check_filler_name (cb_name (x)), clause);
00267 }
00268 
00269 void
00270 level_except_error (cb_tree x, const char *clause)
00271 {
00272         cb_error_x (x, _("Level %02d item '%s' cannot have other than %s clause"),
00273                     cb_field (x)->level, check_filler_name (cb_name (x)), clause);
00274 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines