Annotation of freem/src/merr.c, revision 1.7
1.1 snw 1: /*
1.7 ! snw 2: * $Id: merr.c,v 1.6 2025/04/30 17:19:16 snw Exp $
1.1 snw 3: * stuff for handling program bogosity
4: *
5: *
1.2 snw 6: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 7: * Copyright (C) 1998 MUG Deutschland
1.3 snw 8: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1 snw 9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
1.4 snw 26: * $Log: merr.c,v $
1.7 ! snw 27: * Revision 1.6 2025/04/30 17:19:16 snw
! 28: * Improve backtraces in debugger
! 29: *
1.6 snw 30: * Revision 1.5 2025/04/13 04:22:43 snw
31: * Fix snprintf calls
32: *
1.5 snw 33: * Revision 1.4 2025/04/09 19:52:02 snw
34: * Eliminate as many warnings as possible while building with -Wall
35: *
1.4 snw 36: * Revision 1.3 2025/03/09 19:50:47 snw
37: * Second phase of REUSE compliance and header reformat
38: *
1.3 snw 39: *
40: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
41: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 42: **/
43:
44: #include <string.h>
45: #include <stdlib.h>
46:
47: #include "mpsdef.h"
48: #include "merr.h"
49: #include "jobtab.h"
50:
51: merr_stackent merr_stack[NESTLEVLS + 1];
52: char etrap[256];
53: char ecode[256];
54: char user_ecode[256];
55: int estack;
56: int etrap_lvl = 0;
57: int merr_topstk = 0;
58:
59: typedef struct err_lut {
60: int ecode;
61: const char *canonical_name;
62: } err_lut;
63:
64: err_lut errtab[] = {
65: {0, "ZOK"},
66: {1, "ZINRPT"},
67: {2, "ZBKERR"},
68: {3, "ZNOSTAND"},
69: {4, "ZUNDEF"},
70: {5, "ZLBLUNDEF"},
71: {6, "ZMISSOPD"},
72: {7, "ZMISSOP"},
73: {8, "ZILLOP"},
74: {9, "ZQUOTER"},
75: {10, "ZCOMMAER"},
76: {11, "ZASSIGNER"},
77: {12, "ZARGER"},
78: {13, "ZSPACER"},
79: {14, "ZBRAER"},
80: {15, "ZLVLERR"},
81: {16, "ZDIVER"},
82: {17, "ZILLFUN"},
83: {18, "ZFUNARG"},
84: {19, "ZZTERR"},
85: {20, "ZNEXTER"},
86: {21, "ZSELER"},
87: {22, "ZCMMND"},
88: {23, "ZARGLIST"},
89: {24, "ZINVEXPR"},
90: {25, "ZINVREF"},
91: {26, "ZMXSTR"},
92: {27, "ZTOOPARA"},
93: {28, "ZNOPEN"},
94: {29, "ZNODEVICE"},
95: {30, "ZPROTECT"},
96: {31, "ZGLOBER"},
97: {32, "ZFILERR"},
98: {33, "ZPGMOV"},
99: {34, "ZSTKOV"},
100: {35, "ZSTORE"},
101: {36, "ZNOREAD"},
102: {37, "ZNOWRITE"},
103: {38, "ZNOPGM"},
104: {39, "ZNAKED"},
105: {40, "ZSBSCR"},
106: {41, "ZISYNTX"},
107: {42, "ZDBDGD"},
108: {43, "ZKILLER"},
109: {44, "ZHUPER"},
110: {45, "ZMXNUM"},
111: {46, "ZNOVAL"},
112: {47, "ZTYPEMISMATCH"},
113: {48, "ZMEMOV"},
114: {49, "ZNAMERES"},
115: {50, "ZSCKCREAT"},
116: {51, "ZSCKIFAM"},
117: {52, "ZSCKITYP"},
118: {53, "ZSCKIPRT"},
119: {54, "ZSCKCERR"},
120: {55, "ZSCKAERR"},
121: {56, "ZSCKACON"},
122: {57, "ZSCKNCON"},
123: {58, "ZSCKEOPT"},
124: {59, "ZSCKERCV"},
125: {60, "ZSCKESND"},
126: {61, "ZNORPI"},
127: {62, "ZCREDEF"},
128: {63, "ZCMODIFY"},
129: {64, "ZFILEXWR"},
130: {65, "ZINEWMUL"},
131: {66, "ZINVHORO"},
132: {67, "ZTYPMISMATCH"},
133: {68, "ZINVTYPE"},
134: {69, "ZINVLIBOPT"},
135: {80, "ZECODEINV"},
136: {81, "ZASSERT"},
137: {82, "ZUSERERR"},
138: {83, "ZOBJFLDACCV"},
139: {84, "ZOBJCONFLICT"},
140: {85, "ZOBJPRIVOVFL"},
141: {86, "ZOBJACINVALID"},
142: {128, "ZSYNTERR"},
143: {140, "M1"},
144: {141, "M2"},
145: {142, "M3"},
146: {143, "M4"},
147: {144, "M5"},
148: {145, "M6"},
149: {146, "M7"},
150: {147, "M8"},
151: {148, "M9"},
152: {149, "M10"},
153: {150, "M11"},
154: {151, "M12"},
155: {152, "M13"},
156: {153, "M14"},
157: {154, "M15"},
158: {155, "M16"},
159: {156, "M17"},
160: {157, "M18"},
161: {158, "M19"},
162: {159, "M20"},
163: {160, "M21"},
164: {161, "M22"},
165: {162, "M23"},
166: {163, "M24"},
167: {164, "M25"},
168: {165, "M26"},
169: {166, "M27"},
170: {167, "M28"},
171: {168, "M29"},
172: {169, "M30"},
173: {170, "M31"},
174: {171, "M32"},
175: {172, "M33"},
176: {173, "M34"},
177: {174, "M35"},
178: {175, "M36"},
179: {176, "M37"},
180: {177, "M38"},
181: {178, "M39"},
182: {179, "M40"},
183: {180, "M41"},
184: {181, "M42"},
185: {182, "M43"},
186: {183, "M44"},
187: {184, "M45"},
188: {185, "M46"},
189: {186, "M47"},
190: {187, "M48"},
191: {188, "M49"},
192: {189, "M50"},
193: {190, "M51"},
194: {191, "M52"},
195: {192, "M53"},
196: {193, "M54"},
197: {194, "M55"},
198: {195, "M56"},
199: {196, "M57"},
200: {197, "M58"},
201: {198, "M59"},
202: {199, "M60"},
203: {214, "M75"},
204: {240, "M101"},
205: {241, "M102"},
206: {242, "M103"},
207: {243, "M104"},
208: {254, "ZASYNC"},
209: {255, "ZCTRLB"},
210: {-1, NULL}
211: };
212:
213: inline int merr_raise(int num)
214: {
1.6 snw 215: char placebuf[256];
216: char lref[256];
217:
218: if (num != OK) {
219: lasterr[nstx] = ierr;
220: }
1.1 snw 221:
222: if (merr_in_break ()) {
223: ierr = num - CTRLB;
224: }
225: else {
226: ierr = num;
227: }
228:
229: if (num != OK) {
230: merr_set_ecode_ierr ();
231:
232: stcpy (merr_stack[nstx].ECODE, ecode);
233:
234: if (direct_mode == 1 && nstx == 0) {
235: stcpy (merr_stack[nstx].PLACE, "@\201\0");
1.6 snw 236: stcpy (merr_stack[nstx].MCODE, " \201\0");
1.1 snw 237: }
1.7 ! snw 238: else {
1.6 snw 239: getraddress (placebuf, nstx);
240: stcpy (merr_stack[nstx].PLACE, &(placebuf[3]));
241: stcpy (lref, merr_stack[nstx].PLACE);
242: stcnv_m2c (lref);
1.7 ! snw 243: if (routine_get_line (lref, merr_stack[nstx].MCODE) == NULL) {
1.6 snw 244: sprintf (merr_stack[nstx].MCODE, "???\201");
1.1 snw 245: }
1.7 ! snw 246: else {
! 247: stcnv_c2m (merr_stack[nstx].MCODE);
! 248: }
1.1 snw 249: }
1.6 snw 250:
1.1 snw 251: if (nstx > merr_topstk) merr_topstk = nstx;
1.6 snw 252: }
1.1 snw 253:
254: return ierr;
255: }
256:
257: inline int merr(void)
258: {
259: return ierr < OK ? ierr + CTRLB : ierr;
260: }
261:
262: short merr_in_break(void)
263: {
264: if (ierr < OK) {
265: return TRUE;
266: }
267: else {
268: return FALSE;
269: }
270: }
271:
272: void merr_set_break(void)
273: {
274: if (!merr_in_break ()) {
275: ierr = ierr - CTRLB;
276: }
277: }
278:
279: void merr_clear_break(void)
280: {
281: if (merr_in_break ()) {
282: ierr = ierr + CTRLB;
283: }
284: }
285:
286: int merr_num_to_code (int num, char *code)
287: {
288:
289: err_lut *p;
290:
291: for (p = errtab; p->canonical_name != NULL; ++p) {
292:
293: if (p->ecode == num) {
294: strcpy (code, p->canonical_name);
295: return 1;
296: }
297:
298: }
299:
300: return -1;
301:
302: }
303:
304: int merr_code_to_num (char *code)
305: {
306:
307: err_lut *p;
308:
309: for (p = errtab; p->canonical_name != NULL; ++p) {
310:
311: if (strcmp (p->canonical_name, code) == 0) {
312: return p->ecode;
313: }
314:
315: }
316:
317: return -1;
318:
319: }
320:
321: void merr_set_ecode_ierr (void)
322: {
323: char *cod;
324: char *t;
325:
1.5 snw 326: cod = (char *) malloc (MERR_COD_LENGTH * sizeof (char));
1.1 snw 327: NULLPTRCHK(cod,"merr_set_ecode_ierr");
328:
1.5 snw 329: t = (char *) malloc (MERR_COD_LENGTH * sizeof (char));
1.1 snw 330: NULLPTRCHK(t,"merr_set_ecode_ierr");
331:
332: if ((merr_num_to_code (merr (), cod)) == -1) goto done;
333:
1.5 snw 334: snprintf (t, MERR_COD_LENGTH - 1, ",%s,\201", cod);
1.1 snw 335: merr_set_ecode (t);
336:
337: job_set_ecode (pid, cod);
338:
339: done:
340:
341: free (cod);
342: free (t);
343: return;
344:
345: }
346:
347: int merr_set_ecode (char *t_code)
348: {
349: int ec;
350: char *tmp;
351:
352: if (t_code[0] == '\201') {
353: stcpy (ecode, "\201");
354: return 0;
355: }
356:
357: if (t_code[1] != 'M' && t_code[1] != 'Z' && t_code[1] != 'U') {
358: return M101;
359: }
360:
361: stcpy (ecode, t_code);
362:
363: if (stcmp (t_code, "") == 0) {
364: merr_clear ();
365: stcpy (t_code, ",ZOK,");
366: stcpy (user_ecode, t_code);
367: }
368:
369: tmp = strtok (t_code, ",");
370:
371: /* caller may set ierr with return value */
372: if (ecode[1] == 'U') {
373: stcpy (user_ecode, ecode);
374: return USERERR;
375: }
376: else {
377: ec = merr_code_to_num (tmp);
378: return (ec);
379: }
380: }
381:
382: void merr_dump (int num, char *rtn, char *nsn, char *tcod, int tpos)
383: {
384: char *tbuf;
385: char *dbuf;
386: char *nem;
387: char *nrt;
388: char *real_ecode;
389: err_lut *p;
390:
391: tbuf = (char *) malloc (STRLEN * sizeof (char));
392: NULLPTRCHK(tbuf,"merr_dump");
393:
394: dbuf = (char *) malloc (STRLEN * sizeof (char));
395: NULLPTRCHK(dbuf,"merr_dump");
396:
397: nem = (char *) malloc (STRLEN * sizeof (char));
398: NULLPTRCHK(nem,"merr_dump");
399:
400: nrt = (char *) malloc (STRLEN * sizeof (char));
401: NULLPTRCHK(nrt,"merr_dump");
402:
403: real_ecode = (char *) malloc (STRLEN * sizeof (char));
404: NULLPTRCHK(real_ecode,"merr_dump");
405:
406: stcpy (nrt, rtn);
407: stcnv_m2c (nrt);
408:
409: stcpy (nem, errmes[num]);
410: stcnv_m2c (nem);
411:
412: for (p = errtab; p->canonical_name != NULL; ++p) {
413:
414: if (p->ecode == num) {
415:
416: if (strcmp (p->canonical_name, "ZUSERERR") == 0) {
417: stcpy (real_ecode, &user_ecode[1]);
418: stcnv_m2c (real_ecode);
419: real_ecode [strlen (real_ecode) - 1] = NUL;
420:
1.5 snw 421: snprintf (tbuf, STRLEN - 1, "^$JOB\202%d\202USER_ERRORS\202%s\201", pid, &user_ecode[1]);
1.1 snw 422: tbuf [stlen (tbuf) - 1] = '\201';
423:
424: global (get_sym, tbuf, dbuf);
425:
426: if (merr () == OK) {
427: stcpy (nem, dbuf);
428: stcnv_m2c (nem);
429: }
430: else {
431: merr_clear ();
432: }
433:
434: }
435: else {
436: strcpy (real_ecode, p->canonical_name);
437: }
438:
1.4 snw 439:
440:
1.1 snw 441: if (!stlen (err_suppl)) {
1.5 snw 442: snprintf (tbuf, STRLEN - 1, "\r\n>> Error %s: %s in %s.%s::%s [$STACK = %d]\r\n\201", real_ecode, nem, shm_env, nsn, nrt, nstx);
1.1 snw 443: }
444: else {
445: stcnv_m2c (err_suppl);
1.5 snw 446: snprintf (tbuf, STRLEN - 1, "\r\n>> Error %s: %s (%s) in %s::%s [$STACK = %d]\r\n\201", real_ecode, nem, err_suppl, nsn, nrt, nstx);
1.1 snw 447: err_suppl[0] = EOL;
448: }
449: write_m (tbuf);
450: write_m (">> \201");
451: write_m (tcod);
452: write_m ("\r\n\201");
453: write_t (tpos);
454: write_m ("^\201");
455:
456: goto done;
457: }
458:
459: }
460:
461:
462: done:
463:
464: free (tbuf);
465: free (dbuf);
466: free (nem);
467: free (nrt);
468: free (real_ecode);
469:
470: return;
471: }
472:
473:
474: void merr_set_iochan_err(int channel, short frm_err, char *err_text)
475: {
476: if (channel > MAXDEV || channel < 0) {
477: merr_raise (ARGLIST);
478: return;
479: }
480:
481: devstat[channel].mdc_err = 1;
482: devstat[channel].frm_err = frm_err;
483:
484: strncpy (devstat[channel].err_txt, err_text, 79);
485:
486: return;
487: }
488:
489: void merr_clear_iochan_err(int channel)
490: {
491: if (channel > MAXDEV || channel < 0) {
492: merr_raise (ARGLIST);
493: return;
494: }
495:
496: devstat[channel].mdc_err = 1;
497: devstat[channel].frm_err = OK;
498: devstat[channel].err_txt[0] = '\0';
499:
500: return;
501:
502: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>