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 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 }