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