Remove many valgrind-detected memory leaks. - sam - An updated version of the sam text editor.
 (HTM) git clone git://vernunftzentrum.de/sam.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 3a8f45f007849613466d20ed16760917bdb2bf9d
 (DIR) parent 569a1de5d7884bad2b30e9a2b5280a941ed228cf
 (HTM) Author: Rob King <jking@deadpixi.com>
       Date:   Thu, 20 Oct 2016 15:55:35 -0500
       
       Remove many valgrind-detected memory leaks.
       
       Diffstat:
         sam/buffer.c                        |       3 ++-
         sam/cmd.c                           |      46 +++++++++++++++++++++++++------
         sam/error.c                         |       2 ++
         sam/file.c                          |      16 +++++++++++++++-
         sam/mesg.c                          |       3 ++-
         sam/multi.c                         |       3 ++-
         sam/sam.c                           |      50 ++++++++++++++++++++++++++-----
         sam/sam.h                           |       5 ++++-
         sam/unix.c                          |      13 ++++---------
       
       9 files changed, 110 insertions(+), 31 deletions(-)
       ---
 (DIR) diff --git a/sam/buffer.c b/sam/buffer.c
       @@ -124,13 +124,14 @@ Bterm(Buffer *b)
            }
        }
        
       +/* XXX - modify at call sites to use the internal functions */
        int
        Bread(Buffer *b, wchar_t *c, int l, Posn p)
        {
            if (p + l > b->nrunes)
                l = b->nrunes - p;
        
       -    if (l == 0)
       +    if (l <= 0)
                return 0;
        
            size_t r = readbuffer(b->gb, p, l, c);
 (DIR) diff --git a/sam/cmd.c b/sam/cmd.c
       @@ -59,6 +59,22 @@ List    stringlist;
        bool eof;
        
        void
       +freecmdlists(void)
       +{
       +    if (cmdlist.listptr)
       +        free(cmdlist.listptr);
       +
       +    if (addrlist.listptr)
       +        free(addrlist.listptr);
       +
       +    if (relist.listptr)
       +        free(relist.listptr);
       +
       +    if (stringlist.listptr)
       +        free(stringlist.listptr);
       +}
       +
       +void
        resetcmd(void)
        {
            linep = line;
       @@ -71,8 +87,8 @@ int
        inputc(void)
        {
            int n, nbuf;
       -    char buf[3];
       -    wchar_t r;
       +    char buf[3] = {0};
       +    wchar_t r = 0;
        
            Again:
            nbuf = 0;
       @@ -203,7 +219,7 @@ cmdloop(void)
            for(;;){
                if(!downloaded && curfile && curfile->state==Unread)
                    load(curfile);
       -        if((cmdp = parsecmd(0))==0){
       +        if((cmdp = parsecmd(0)) == NULL){
                    if(downloaded){
                        rescue();
                        exit(EXIT_FAILURE);
       @@ -212,8 +228,10 @@ cmdloop(void)
                }
                ocurfile = curfile;
                loaded = curfile && curfile->state!=Unread;
       -        if(cmdexec(curfile, cmdp) == 0)
       +        if(cmdexec(curfile, cmdp) == 0){
       +            freecmd();
                    break;
       +        }
                freecmd();
                cmdupdate();
                update();
       @@ -274,8 +292,12 @@ freecmd(void)
        {
            int i;
        
       -    while(cmdlist.nused > 0)
       -        free(cmdlist.uint8_tpptr[--cmdlist.nused]);
       +    while(cmdlist.nused > 0){
       +        Cmd *c = (Cmd *)cmdlist.uint8_tpptr[--cmdlist.nused];
       +        /* XXX if (c->ctext)
       +            free(c->ctext); */
       +        free(c);
       +    }
            while(addrlist.nused > 0)
                free(addrlist.uint8_tpptr[--addrlist.nused]);
            while(relist.nused > 0){
       @@ -426,6 +448,8 @@ parsecmd(int nest)
                        okdelim(c);
                        cmd.re = getregexp(c);
                        if(ct->cmdc == 's'){
       +                    if (cmd.ctext)
       +                        free(cmd.ctext);
                            cmd.ctext = newstring();
                            getrhs(cmd.ctext, c, 's');
                            if(nextc() == c){
       @@ -446,11 +470,15 @@ parsecmd(int nest)
                        cmd.ccmd->cmdc = ct->defcmd;
                    }else if((cmd.ccmd = parsecmd(nest))==0)
                        panic("defcmd");
       -        }else if(ct->text)
       +        } else if(ct->text){
       +            if (cmd.ctext)
       +                free(cmd.ctext);
                    cmd.ctext = collecttext();
       -        else if(ct->token)
       +        } else if(ct->token){
       +            if (cmd.ctext)
       +                free(cmd.ctext);
                    cmd.ctext = collecttoken(ct->token);
       -        else
       +        } else
                    atnl();
            }else
                switch(cmd.cmdc){
 (DIR) diff --git a/sam/error.c b/sam/error.c
       @@ -128,6 +128,8 @@ termwrite(char *s)
                else
                    Strinsert(&cmdstr, p, cmdstr.n);
                cmdptadv += p->n;
       +        Strclose(p);
       +        free(p);
            }else
                Write(STDERR_FILENO, s, strlen(s));
        }
 (DIR) diff --git a/sam/file.c b/sam/file.c
       @@ -1,5 +1,6 @@
        /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
        #include "sam.h"
       +
        /*
         * Files are splayed out a factor of NDISC to reduce indirect block access
         */
       @@ -19,12 +20,22 @@ enum{
            MAXCACHE=STRSIZE    /* max length of cache. must be < 32K-BLOCKSIZE */
        };
        
       +static void
       +freebufs(void)
       +{
       +    Bterm(undobuf);
       +    Bterm(snarfbuf);
       +    Bterm(plan9buf);
       +}
       +
        void
        Fstart(void)
        {
            undobuf = Bopen();
            snarfbuf = Bopen();
            plan9buf = Bopen();
       +
       +    atexit(freebufs);
        }
        
        void
       @@ -75,8 +86,11 @@ Fopen(void)
        void
        Fclose(File *f)
        {
       +    if (!f)
       +        return;
       +
            if(f == lastfile)
       -        lastfile = 0;
       +        lastfile = NULL;
            Bterm(f->buf);
            Bterm(f->transcript);
            Strclose(&f->name);
 (DIR) diff --git a/sam/mesg.c b/sam/mesg.c
       @@ -465,7 +465,7 @@ inmesg(Tmesg type)
                    Write(1, c, i);
                    free(c);
                } else
       -            dprint("snarf buffer too int64_t\n");
       +            dprint("snarf buffer too long\n");
                break;
        
            case Tsetsnarf:
       @@ -491,6 +491,7 @@ inmesg(Tmesg type)
                break;
        
            case Texit:
       +        shutdown();
                exit(EXIT_SUCCESS);
            }
            return true;
 (DIR) diff --git a/sam/multi.c b/sam/multi.c
       @@ -95,7 +95,7 @@ lookfile(String *s, bool fuzzy)
                if (fuzzy){
                    char *ac = Strtoc(&file.filepptr[i]->name);
                    if (strcmp(basename(sc), ac) == 0)
       -                return free(ac), file.filepptr[i];
       +                return free(sc), free(ac), file.filepptr[i];
        
                    if (!b && strstr(ac, sc))
                        b = file.filepptr[i];
       @@ -103,5 +103,6 @@ lookfile(String *s, bool fuzzy)
                }
            }
        
       +    free(sc);
            return b;
        }
 (DIR) diff --git a/sam/sam.c b/sam/sam.c
       @@ -106,8 +106,9 @@ main(int argc, char *argv[])
            Strinit0(&genstr);
            Strinit0(&rhs);
            Strinit0(&wd);
       -    tempfile.listptr = emalloc(0);
            Strinit0(&plan9cmd);
       +
       +    tempfile.listptr = emalloc(0);
            home = getenv("HOME") ? getenv("HOME") : "/";
            shpath = getenv("SHELL") ? getenv("SHELL") : shpath;
            sh = basename(shpath);
       @@ -133,16 +134,50 @@ main(int argc, char *argv[])
            modnum++;
            if(file.nused)
                current(file.filepptr[0]);
       +
            setjmp(mainloop);
            cmdloop();
       +
            trytoquit();    /* if we already q'ed, quitok will be true */
       +
       +    shutdown();
            exit(EXIT_SUCCESS);
        }
        
        void
       +shutdown(void)
       +{
       +    freecmd();
       +    for (int i = 0; i < file.nused; i++)
       +        Fclose(file.filepptr[i]);
       +
       +    if (!downloaded)
       +        Fclose(cmd);
       +
       +    if (genc)
       +        free(genc);
       +
       +    Strclose(&cmdstr);
       +    Strclose(&lastpat);
       +    Strclose(&lastregexp);
       +    Strclose(&genstr);
       +    Strclose(&rhs);
       +    Strclose(&wd);
       +    Strclose(&plan9cmd);
       +
       +    if (file.listptr)
       +        free(file.listptr);
       +
       +    if (tempfile.listptr)
       +        free(tempfile.listptr);
       +
       +    freecmdlists();
       +}
       +
       +void
        usage(void)
        {
       -    dprint("usage: sam [-r machine] [-d] [-f] [-e] [-t samterm] [-s samname] FILE...\n");
       +    fprintf(stderr, "usage: sam [-r machine] [-d] [-f] [-e] [-t samterm] [-s samname] FILE...\n");
            exit(EXIT_FAILURE);
        }
        
       @@ -270,17 +305,16 @@ trytoquit(void)
            int c;
            File *f;
        
       -    if(!quitok)
       -{
       -        for(c = 0; c<file.nused; c++){
       +    if (!quitok){
       +        for(c = 0; c < file.nused; c++){
                    f = file.filepptr[c];
       -            if(f!=cmd && f->state==Dirty){
       +            if(f != cmd && f->state == Dirty){
                        quitok = true;
                        eof = false;
                        error(Echanges);
                    }
                }
       -}
       +    }
        }
        
        void
       @@ -720,7 +754,7 @@ settempfile(void)
        {
            if(tempfile.nalloc < file.nused){
                free(tempfile.listptr);
       -        tempfile.listptr = emalloc(sizeof(*tempfile.filepptr)*file.nused);
       +        tempfile.listptr = emalloc(sizeof(*tempfile.filepptr) * file.nused);
                tempfile.nalloc = file.nused;
            }
            tempfile.nused = file.nused;
 (DIR) diff --git a/sam/sam.h b/sam/sam.h
       @@ -207,6 +207,8 @@ void    error_s(Err, char*);
        int execute(File*, Posn, Posn);
        int filematch(File*, String*);
        void    filename(File*);
       +void    freecmd(void);
       +void    freecmdlists(void);
        File    *getfile(String*);
        int getname(File*, String*, bool);
        int64_t    getnum(void);
       @@ -237,7 +239,8 @@ void    resetxec(void);
        void    rgrow(List*, Posn, Posn);
        void    samerr(char*);
        void    settempfile(void);
       -int skipbl(void);
       +void    shutdown(void);
       +int     skipbl(void);
        void    snarf(File*, Posn, Posn, Buffer*, bool);
        void    sortname(File*);
        void    startup(char*, int, char**, char**);
 (DIR) diff --git a/sam/unix.c b/sam/unix.c
       @@ -125,14 +125,9 @@ waitfor(int pid)
        void*
        emalloc(uint64_t n)
        {
       -    void *p;
       -
       -    if (n < sizeof(int))
       -        n = sizeof(int);
       -    p = malloc(n);
       -    if(p == 0)
       -        panic("malloc fails");
       -    memset(p, 0, n);
       +    void *p = calloc(1, n < sizeof(int)? sizeof(int) : n);
       +    if (!p)
       +        panic("malloc failed");
            return p;
        }
        
       @@ -140,7 +135,7 @@ void*
        erealloc(void *p, uint64_t n)
        {
            p = realloc(p, n);
       -    if(p == 0)
       +    if(!p)
                panic("realloc fails");
            return p;
        }