[BACK]Return to log.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/log.c, Revision 1.13

1.13    ! jmc         1: /*     $OpenBSD: log.c,v 1.12 2021/03/02 13:06:50 lum Exp $    */
1.1       lum         2:
                      3: /*
                      4:  * This file is in the public domain.
                      5:  *
                      6:  * Author: Mark Lumsden <mark@showcomplex.com>
                      7:  *
                      8:  */
                      9:
                     10: /*
                     11:  * Record a history of an mg session for temporal debugging.
                     12:  * Sometimes pressing a key will set the scene for a bug only visible
                     13:  * dozens of keystrokes later. gdb has its limitations in this scenario.
1.4       lum        14:  *
                     15:  * Note this file is not compiled into mg by default, you will need to
                     16:  * amend the 'Makefile' for that to happen. Because of this, the code
1.8       lum        17:  * is subject to bit-rot. However, I know myself and others have
1.4       lum        18:  * written similar functionally often enough, that recording the below
1.13    ! jmc        19:  * in a code repository could aid the development efforts of mg, even
1.4       lum        20:  * if it requires a bit of effort to get working. The current code is
                     21:  * written in the spirit of debugging (quickly and perhaps not ideal,
                     22:  * but it does what is required well enough). Should debugging become
                     23:  * more formalised within mg, then I would expect that to change.
1.6       lum        24:  *
                     25:  * If you open a file with long lines to run through this debugging
                     26:  * code, you may run into problems with the 1st fprintf statement in
                     27:  * in the mglog_lines() function. mg sometimes segvs at a strlen call
                     28:  * in fprintf - possibly something to do with the format string?
                     29:  *     "%s%p b^%p f.%p %d %d\t%c|%s\n"
                     30:  * When I get time I will look into it. But since my debugging
                     31:  * generally revolves around a file like:
                     32:  *
                     33:  * abc
                     34:  * def
                     35:  * ghk
                     36:  *
                     37:  * I don't experience this bug. Just note it for future investigation.
1.1       lum        38:  */
                     39:
                     40: #include <sys/queue.h>
                     41: #include <sys/stat.h>
                     42: #include <ctype.h>
                     43: #include <fcntl.h>
                     44: #include <signal.h>
                     45: #include <stdio.h>
                     46: #include <stdlib.h>
                     47: #include <string.h>
                     48: #include <unistd.h>
1.12      lum        49: #include <stdarg.h>
1.1       lum        50:
                     51: #include "def.h"
1.9       lum        52: #include "key.h"
                     53: #include "kbd.h"
                     54: #include "funmap.h"
                     55: #include "chrdef.h"
                     56:
1.1       lum        57: #include "log.h"
                     58:
1.12      lum        59: static char    *mglogfiles_create(FILE **, char *);
1.11      lum        60: static int      mglog_lines(PF);
                     61: static int      mglog_undo(void);
                     62: static int      mglog_window(void);
                     63: static int      mglog_key(KEYMAP *map);
1.2       lum        64:
1.12      lum        65: const char     *mglogdir;
                     66: const char     *mglogpath_lines;
                     67: const char     *mglogpath_undo;
                     68: const char     *mglogpath_window;
                     69: const char     *mglogpath_key;
                     70: const char     *mglogpath_interpreter;
                     71: const char     *mglogpath_misc;
1.2       lum        72: int             mgloglevel;
1.1       lum        73:
1.12      lum        74: FILE           *fd_lines;
                     75: FILE           *fd_undo;
                     76: FILE           *fd_window;
                     77: FILE           *fd_key;
                     78: FILE           *fd_interpreter;
                     79: FILE           *fd_misc;
                     80:
1.1       lum        81: int
1.12      lum        82: mglog(PF funct, void *map)
1.1       lum        83: {
1.2       lum        84:        if(!mglog_lines(funct))
                     85:                ewprintf("Problem logging lines");
                     86:        if(!mglog_undo())
                     87:                ewprintf("Problem logging undo");
1.7       lum        88:        if(!mglog_window())
                     89:                ewprintf("Problem logging window");
1.9       lum        90:        if(!mglog_key(map))
                     91:                ewprintf("Problem logging key");
1.2       lum        92:
                     93:        return (TRUE);
                     94: }
                     95:
                     96:
1.11      lum        97: static int
1.9       lum        98: mglog_key(KEYMAP *map)
                     99: {
                    100:        PF              *pfp;
                    101:
                    102:        if (ISWORD(*key.k_chars)) {
1.12      lum       103:                fprintf(fd_key, "k_count:%d k_chars:%hd\tchr:%c\t", key.k_count,
                    104:                    *key.k_chars, CHARMASK(*key.k_chars));
1.9       lum       105:        } else {
1.12      lum       106:                fprintf(fd_key, "k_count:%d k_chars:%hd\t\t", key.k_count,
                    107:                    *key.k_chars);
1.9       lum       108:        }
1.12      lum       109:        fprintf(fd_key, "map:%p %d %d %p %hd %hd\n",
1.9       lum       110:            map,
                    111:            map->map_num,
                    112:            map->map_max,
                    113:            map->map_default,
                    114:            map->map_element->k_base,
                    115:            map->map_element->k_num
1.12      lum       116:            );
                    117:        for (pfp = map->map_element->k_funcp; *pfp != NULL; pfp++)
                    118:                fprintf(fd_key, "%s ", function_name(*pfp));
1.9       lum       119:
1.12      lum       120:        fprintf(fd_key, "\n\n");
                    121:        fflush(fd_key);
1.9       lum       122:        return (TRUE);
                    123: }
                    124:
1.11      lum       125: static int
1.7       lum       126: mglog_window(void)
                    127: {
                    128:        struct mgwin    *wp;
                    129:        int              i;
                    130:
                    131:        for (wp = wheadp, i = 0; wp != NULL; wp = wp->w_wndp, ++i) {
1.12      lum       132:                fprintf(fd_window,
1.7       lum       133:                    "%d wh%p wlst%p wbfp%p wlp%p wdtp%p wmkp%p wdto%d wmko%d" \
                    134:                    " wtpr%d wntr%d wfrm%d wrfl%c wflg%c wwrl%p wdtl%d" \
                    135:                    " wmkl%d\n",
                    136:                    i,
                    137:                    wp,
                    138:                    &wp->w_list,
                    139:                    wp->w_bufp,
                    140:                    wp->w_linep,
                    141:                    wp->w_dotp,
                    142:                    wp->w_markp,
                    143:                    wp->w_doto,
                    144:                    wp->w_marko,
                    145:                    wp->w_toprow,
                    146:                    wp->w_ntrows,
                    147:                    wp->w_frame,
                    148:                    wp->w_rflag,
                    149:                    wp->w_flag,
                    150:                    wp->w_wrapline,
                    151:                    wp->w_dotline,
1.12      lum       152:                    wp->w_markline
                    153:                    );
1.7       lum       154:        }
1.12      lum       155:        fflush(fd_window);
1.7       lum       156:        return (TRUE);
                    157: }
                    158:
1.11      lum       159: static int
1.2       lum       160: mglog_undo(void)
                    161: {
                    162:        struct undo_rec *rec;
                    163:        char             buf[4096], tmp[1024];
                    164:        int              num;
                    165:        char            *jptr;
                    166:
                    167:        jptr = "^J"; /* :) */
                    168:        /*
                    169:         * From undo_dump()
                    170:         */
                    171:        num = 0;
                    172:        TAILQ_FOREACH(rec, &curbp->b_undo, next) {
                    173:                num++;
1.12      lum       174:                fprintf(fd_undo, "%d:\t %s at %d ", num,
1.2       lum       175:                    (rec->type == DELETE) ? "DELETE":
                    176:                    (rec->type == DELREG) ? "DELREGION":
                    177:                    (rec->type == INSERT) ? "INSERT":
                    178:                    (rec->type == BOUNDARY) ? "----" :
                    179:                    (rec->type == MODIFIED) ? "MODIFIED": "UNKNOWN",
1.12      lum       180:                    rec->pos
                    181:                    );
1.2       lum       182:                if (rec->content) {
                    183:                        (void)strlcat(buf, "\"", sizeof(buf));
                    184:                        snprintf(tmp, sizeof(tmp), "%.*s",
                    185:                            *rec->content == '\n' ? 2 : rec->region.r_size,
                    186:                            *rec->content == '\n' ? jptr : rec->content);
                    187:                        (void)strlcat(buf, tmp, sizeof(buf));
                    188:                        (void)strlcat(buf, "\"", sizeof(buf));
                    189:                }
                    190:                snprintf(tmp, sizeof(tmp), " [%d]", rec->region.r_size);
                    191:                if (strlcat(buf, tmp, sizeof(buf)) >= sizeof(buf)) {
                    192:                        dobeep();
                    193:                        ewprintf("Undo record too large. Aborted.");
                    194:                        return (FALSE);
                    195:                }
1.12      lum       196:                fprintf(fd_undo, "%s\n", buf);
1.2       lum       197:                tmp[0] = buf[0] = '\0';
                    198:        }
1.12      lum       199:        fprintf(fd_undo, "\t [end-of-undo]\n\n");
                    200:        fflush(fd_undo);
1.2       lum       201:
                    202:        return (TRUE);
                    203: }
                    204:
1.11      lum       205: static int
1.2       lum       206: mglog_lines(PF funct)
                    207: {
1.1       lum       208:        struct line     *lp;
1.5       lum       209:        char            *curline, *tmp, o;
1.1       lum       210:        int              i;
                    211:
                    212:        i = 0;
                    213:
1.12      lum       214:        fprintf(fd_lines, "%s\n", function_name(funct));
1.1       lum       215:        lp = bfirstlp(curbp);
                    216:
                    217:        for(;;) {
                    218:                i++;
                    219:                curline = " ";
1.5       lum       220:                o = ' ';
                    221:                if (i == curwp->w_dotline) {
1.1       lum       222:                        curline = ">";
1.5       lum       223:                        if (lp->l_used > 0 && curwp->w_doto < lp->l_used)
                    224:                                o = lp->l_text[curwp->w_doto];
                    225:                        else
                    226:                                o = '-';
                    227:                }
                    228:                if (lp->l_size == 0)
                    229:                        tmp = " ";
                    230:                else
                    231:                        tmp = lp->l_text;
                    232:
1.6       lum       233:                /* segv on fprintf below with long lines */
1.12      lum       234:                fprintf(fd_lines, "%s%p b^%p f.%p %d %d\t%c|%s\n", curline,
1.1       lum       235:                    lp, lp->l_bp, lp->l_fp,
1.12      lum       236:                    lp->l_size, lp->l_used, o, tmp);
                    237:
1.1       lum       238:                lp = lforw(lp);
                    239:                if (lp == curbp->b_headp) {
1.12      lum       240:                        fprintf(fd_lines, " %p b^%p f.%p [bhead]\n(EOB)\n",
                    241:                            lp, lp->l_bp, lp->l_fp);
                    242:
                    243:                        fprintf(fd_lines, "lines:raw:%d buf:%d wdot:%d\n\n",
                    244:                            i, curbp->b_lines, curwp->w_dotline);
                    245:
1.1       lum       246:                        break;
                    247:                }
                    248:        }
1.12      lum       249:        fflush(fd_lines);
1.1       lum       250:
                    251:        return (TRUE);
                    252: }
                    253:
1.11      lum       254: /*
                    255:  * See what the eval variable code is up to.
                    256:  */
                    257: int
                    258: mglog_isvar(
                    259:        const char* const argbuf,
                    260:        const char* const argp,
                    261:        const int         sizof
                    262: )
                    263: {
                    264:
1.12      lum       265:        fprintf(fd_interpreter, " argbuf:%s,argp:%s,sizof:%d<\n",
1.11      lum       266:            argbuf,
                    267:            argp,
1.12      lum       268:            sizof);
                    269:
                    270:        fflush(fd_interpreter);
1.11      lum       271:        return (TRUE);
                    272: }
                    273:
                    274: /*
                    275:  * See what the eval line code is up to.
                    276:  */
                    277: int
                    278: mglog_execbuf(
                    279:        const char* const pre,
                    280:        const char* const excbuf,
                    281:        const char* const argbuf,
                    282:        const char* const argp,
                    283:        const int         last,
                    284:        const int         inlist,
                    285:        const char* const cmdp,
                    286:        const char* const p,
                    287:        const char* const contbuf
                    288: )
                    289: {
1.12      lum       290:        fprintf(fd_interpreter, "%sexcbuf:%s,argbuf:%s,argp:%s,last:%d,inlist:%d,"\
1.11      lum       291:            "cmdp:%s,p:%s,contbuf:%s<\n",
                    292:            pre,
                    293:            excbuf,
                    294:            argbuf,
                    295:            argp,
                    296:            last,
                    297:            inlist,
                    298:            cmdp,
                    299:            p,
                    300:            contbuf
1.12      lum       301:            );
                    302:        fflush(fd_interpreter);
                    303:        return (TRUE);
                    304: }
                    305:
                    306: /*
                    307:  * Misc. logging for various subsystems
                    308:  */
                    309: int
                    310: mglog_misc(
                    311:        const char *fmt,
                    312:        ...
                    313: )
                    314: {
                    315:        va_list         ap;
                    316:        int             rc;
                    317:
                    318:        va_start(ap, fmt);
                    319:        rc = vfprintf(fd_misc, fmt, ap);
                    320:        va_end(ap);
                    321:        fflush(fd_misc);
                    322:
                    323:        if (rc < 0)
1.11      lum       324:                return (FALSE);
1.12      lum       325:
1.11      lum       326:        return (TRUE);
                    327: }
1.1       lum       328:
1.12      lum       329:
                    330:
1.1       lum       331: /*
1.2       lum       332:  * Make sure logging to log files can happen.
1.1       lum       333:  */
                    334: int
                    335: mgloginit(void)
                    336: {
                    337:        struct stat      sb;
                    338:        mode_t           dir_mode, f_mode, oumask;
1.7       lum       339:        char            *mglogfile_lines, *mglogfile_undo, *mglogfile_window;
1.12      lum       340:        char            *mglogfile_key, *mglogfile_interpreter, *mglogfile_misc;
1.1       lum       341:
                    342:        mglogdir = "./log/";
1.2       lum       343:        mglogfile_lines = "line.log";
                    344:        mglogfile_undo = "undo.log";
1.7       lum       345:        mglogfile_window = "window.log";
1.9       lum       346:        mglogfile_key = "key.log";
1.11      lum       347:        mglogfile_interpreter = "interpreter.log";
1.12      lum       348:        mglogfile_misc = "misc.log";
1.2       lum       349:
                    350:        /*
                    351:         * Change mgloglevel for desired level of logging.
                    352:         * log.h has relevant level info.
                    353:         */
                    354:        mgloglevel = 1;
1.1       lum       355:
                    356:        oumask = umask(0);
                    357:        f_mode = 0777& ~oumask;
                    358:        dir_mode = f_mode | S_IWUSR | S_IXUSR;
                    359:
                    360:        if(stat(mglogdir, &sb)) {
                    361:                if (mkdir(mglogdir, dir_mode) != 0)
                    362:                        return (FALSE);
1.10      deraadt   363:                if (chmod(mglogdir, f_mode) == -1)
1.1       lum       364:                        return (FALSE);
                    365:        }
1.12      lum       366:        mglogpath_lines = mglogfiles_create(&fd_lines, mglogfile_lines);
1.2       lum       367:        if (mglogpath_lines == NULL)
1.1       lum       368:                return (FALSE);
1.12      lum       369:        mglogpath_undo = mglogfiles_create(&fd_undo, mglogfile_undo);
1.2       lum       370:        if (mglogpath_undo == NULL)
1.7       lum       371:                return (FALSE);
1.12      lum       372:        mglogpath_window = mglogfiles_create(&fd_window, mglogfile_window);
1.7       lum       373:        if (mglogpath_window == NULL)
1.1       lum       374:                return (FALSE);
1.12      lum       375:        mglogpath_key = mglogfiles_create(&fd_key, mglogfile_key);
1.9       lum       376:        if (mglogpath_key == NULL)
                    377:                return (FALSE);
1.12      lum       378:        mglogpath_interpreter = mglogfiles_create(&fd_interpreter,
                    379:            mglogfile_interpreter);
1.11      lum       380:        if (mglogpath_interpreter == NULL)
                    381:                return (FALSE);
1.12      lum       382:        mglogpath_misc = mglogfiles_create(&fd_misc, mglogfile_misc);
                    383:        if (mglogpath_misc == NULL)
                    384:                return (FALSE);
1.1       lum       385:
1.2       lum       386:        return (TRUE);
                    387: }
                    388:
                    389:
1.11      lum       390: static char *
1.12      lum       391: mglogfiles_create(FILE ** fd, char *mglogfile)
1.2       lum       392: {
1.11      lum       393:        char             tmp[NFILEN], *tmp2;
1.2       lum       394:
                    395:        if (strlcpy(tmp, mglogdir, sizeof(tmp)) >
                    396:            sizeof(tmp))
                    397:                return (NULL);
                    398:        if (strlcat(tmp, mglogfile, sizeof(tmp)) >
                    399:            sizeof(tmp))
                    400:                return (NULL);
1.11      lum       401:        if ((tmp2 = strndup(tmp, NFILEN)) == NULL)
1.2       lum       402:                return (NULL);
                    403:
1.12      lum       404:        if ((*fd = fopen(tmp2, "w")) == NULL)
1.2       lum       405:                return (NULL);
1.1       lum       406:
1.2       lum       407:        return (tmp2);
1.1       lum       408: }