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