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>