tAdding slicing to seq and removing functions. - rohrpost - A commandline mail client to change the world as we see it.
 (HTM) git clone git://r-36.net/rohrpost
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 7c6671458b78219b689b61d8e0fd736d45a9e549
 (DIR) parent 56d7dc2f40c709b78b997c755a1766eb75e0b450
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Sun, 22 Apr 2012 20:01:44 +0200
       
       Adding slicing to seq and removing functions.
       
       Diffstat:
         ind.c                               |      26 ++++++--------------------
         ind.h                               |       2 +-
         mark.c                              |     217 ++++++++++++++++++++++++++++++-
         mark.h                              |       5 +++--
         mime.c                              |      12 ++++++------
         txtdb.c                             |       8 ++++----
       
       6 files changed, 230 insertions(+), 40 deletions(-)
       ---
 (DIR) diff --git a/ind.c b/ind.c
       t@@ -451,23 +451,7 @@ sgetuntil(char *str, char **p, char *max, int *len)
        }
        
        char *
       -strcsh(char *p, char *chars)
       -{
       -        for (; strchr(chars, p[0]); p++);
       -
       -        return p;
       -}
       -
       -char *
       -strncsh(char *p, char *chars)
       -{
       -        for(; (!strchr(chars, p[0]) && p[0] != '\0'); p++);
       -
       -        return p;
       -}
       -
       -char *
       -strrlncsh(char *p, char *chars, int limit)
       +strrlnspn(char *p, char *chars, int limit)
        {
                char *np;
        
       t@@ -483,9 +467,11 @@ strisascii(char *str)
                int len, i;
        
                len = strlen(str);
       -        for (i = 0; i < len; i++)
       -                if(!isascii(str[i]))
       +        for (i = 0; i < len; i++) {
       +                if (!isascii(str[i]))
                                return 0;
       +        }
       +
                return 1;
        }
        
       t@@ -499,7 +485,7 @@ findlimitws(char *str, int limit)
                if (len < limit)
                        return NULL;
        
       -        ptr = strrlncsh(str, "\t\r\v\f ", limit);
       +        ptr = strrlnspn(str, "\t\r\v\f ", limit);
                if (ptr == str)
                        return &str[limit-1];
                return ptr;
 (DIR) diff --git a/ind.h b/ind.h
       t@@ -46,7 +46,7 @@ char *sgets(char *s, int size, char **p);
        char *sgetuntil(char *str, char **p, char *max, int *len);
        char *strcsh(char *p, char *chars);
        char *strncsh(char *p, char *chars);
       -char *strrlncshr(char *p, char *chars);
       +char *strrlnspn(char *p, char *chars, int limit);
        int strisascii(char *str);
        char *findlimitws(char *str, int limit);
        
 (DIR) diff --git a/mark.c b/mark.c
       t@@ -89,16 +89,218 @@ mark_stop(mark_t *marks)
                mark_free(marks);
        }
        
       -llist_t *
       -mark_getlist(mark_t *marks, char *seq)
       +llistelem_t *
       +mark_set(mark_t *marks, char *seq, char *value)
       +{
       +        if (strcspn(seq, "[]:") != strlen(seq))
       +                die("'[]:' not allowed in sequence name.");
       +
       +        return txtdb_set(marks, seq, value);
       +}
       +
       +void *
       +mark_internget(mark_t *marks, char *seq, int llist)
        {
                llistelem_t *elem;
       +        llist_t *elist, *rlist;
       +        int lseq, begin, end, step, rdir, sdir, nargs, i;
       +        char *cseq, *pbegin, *pend, *pstep, *ppend;
       +
       +        lseq = strlen(seq);
       +        if (strcspn(seq, "[]:") != lseq) {
       +                elist = NULL;
       +                nargs = 0;
       +                //printf("Found a slicing sequence.\n");
       +                cseq = memdup(seq, lseq+1);
       +                pbegin = strchr(cseq, '[');
       +                if (pbegin == NULL)
       +                        die("Sequence slicing should begin with '['.\n");
       +                pbegin[0] = '\0';
       +                pbegin++;
       +
       +                ppend = strchr(pbegin, ']');
       +                if (ppend == NULL)
       +                        die("Sequence slicing has to end in ']'.\n");
       +                if (ppend[1] != '\0') {
       +                        die("No characters allowed after ']' in"
       +                                        " sequence slicing.\n");
       +                }
       +                ppend[0] = '\0';
       +                //printf("pbegin = %s\n", pbegin);
       +
       +                pend = strchr(pbegin, ':');
       +                if (pend != NULL) {
       +                        pend[0] = '\0';
       +                        pend++;
       +                        //printf("pend = %s\n", pend);
       +
       +                        pstep = strchr(pend, ':');
       +                        if (pstep != NULL) {
       +                                pstep[0] = '\0';
       +                                pstep++;
       +                                //printf("pstep = %s\n", pstep);
       +                        }
       +                } else {
       +                        pstep = NULL;
       +                }
        
       -        elem = mark_get(marks, seq);
       -        if (elem == NULL || elem->data == NULL)
       -                return NULL;
       +                //printf("Getting elist for %s\n", cseq);
       +                elist = (llist_t *)mark_internget(marks, cseq, 1);
       +                if (elist == NULL) {
       +                        free(cseq);
       +                        return NULL;
       +                }
       +
       +                if (elist->len < 1) {
       +                        rlist = elist;
       +                        elist = NULL;
       +                        goto slicingreturn;
       +                }
       +
       +                //printf("Checking nargs = 3\n");
       +                step = 1;
       +                if (pstep != NULL) {
       +                        nargs++;
       +                        if (pstep[0] != '\0')
       +                                step = atoi(pstep);
       +                        //printf("pstep = %s\n", pstep);
       +                }
       +                //printf("step = %d\n", step);
       +                if (step == 0) {
       +                        die("Step size cannot be zero in sequence "
       +                                        "slicing.\n");
       +                }
       +                sdir = (step > 0)? 1 : -1;
       +                //printf("sdir = %d\n", sdir);
        
       -        return llist_splitstr((char *)elem->data, " ");
       +                //printf("Checking nargs = 1\n");
       +                nargs = 1;
       +                if (pbegin[0] == '\0' && sdir < 0) {
       +                        begin = elist->len - 1;
       +                } else {
       +                        begin = atoi(pbegin);
       +                }
       +                //printf("begin = %d\n", begin);
       +
       +                //printf("Checking nargs = 2\n");
       +                if (pend != NULL) {
       +                        nargs++;
       +                        if (pend[0] == '\0') {
       +                                if (sdir < 0) {
       +                                        end = 0;
       +                                } else {
       +                                        end = elist->len - 1;
       +                                }
       +                        } else {
       +                                end = atoi(pend);
       +                                if (pbegin[0] == '\0')
       +                                        end++;
       +                        }
       +                        //printf("end = %d\n", end);
       +                }
       +
       +                if (nargs >= 2) {
       +                        if (end < 0)
       +                                end = elist->len + end;
       +                        if (end < 0 || end > elist->len)
       +                                die("End is out of range.\n");
       +                }
       +                if (begin < 0)
       +                        begin = elist->len + begin;
       +                if (begin < 0 || begin > elist->len)
       +                        die("Begin is out of range.\n");
       +
       +                //printf("len = %d\n", elist->len);
       +                //printf("begin = %d\n", begin);
       +                //printf("end = %d\n", end);
       +
       +                rlist = llist_new();
       +                /*
       +                 * [0]
       +                 */
       +                //printf("nargs = %d\n", nargs);
       +                if (nargs == 1) {
       +                        if (pbegin[0] == '\0') {
       +                                die("Syntax error in begin in "
       +                                        "sequence slicing.\n");
       +                        }
       +
       +                        //printf("getn\n");
       +                        elem = llist_getn(elist, begin);
       +                        //printf("add\n");
       +                        llist_add(rlist, elem->key, elem->data,
       +                                        elem->datalen);
       +                        goto slicingreturn;
       +                }
       +
       +                /*
       +                 * [0:1:1]
       +                 */
       +                rdir = ((end - begin) > 0)? 1 : -1;
       +                //printf("rdir = %d; sdir = %d;\n", rdir, sdir);
       +                if (rdir != sdir)
       +                        goto slicingreturn;
       +
       +                i = 0;
       +                elem = llist_getn(elist, begin);
       +                llist_add(rlist, elem->key, elem->data, elem->datalen);
       +                for (;;) {
       +                        //printf("begin = %d; step = %d; sdir = %d;"
       +                        //        " end = %d\n", begin, step, sdir, end);
       +                        begin += step;
       +                        if (begin * sdir > end * sdir)
       +                                break;
       +
       +                        for (i = abs(step); i > 0; i--) {
       +                                if (sdir > 0) {
       +                                        elem = elem->next;
       +                                } else {
       +                                        elem = elem->prev;
       +                                }
       +                        }
       +
       +                        llist_add(rlist, elem->key, elem->data,
       +                                        elem->datalen);
       +                }
       +slicingreturn:
       +                free(cseq);
       +                //printf("slicing return\n");
       +                if (elist != NULL)
       +                        llist_free(elist);
       +                //printf("elist freed\n");
       +                if (!llist) {
       +                        //printf("llist\n");
       +                        pbegin = llist_joinstr(rlist, " ");
       +                        llist_free(rlist);
       +                        //printf("%s = %s\n", seq, pbegin);
       +                        elem = llistelem_rawnew(seq, pbegin,
       +                                (pbegin != NULL)? strlen(pbegin) : 0);
       +                        return elem;
       +                }
       +
       +                return rlist;
       +        } else {
       +                //printf("Non-slicing sequence.\n");
       +                elem = txtdb_get(marks, seq);
       +                if (elem == NULL || elem->data == NULL)
       +                        return NULL;
       +        }
       +
       +        if (llist)
       +                return llist_splitstr((char *)elem->data, " ");
       +        return elem;
       +}
       +
       +llistelem_t *
       +mark_get(mark_t *marks, char *seq)
       +{
       +        return (llistelem_t *)mark_internget(marks, seq, 0);
       +}
       +
       +llist_t *
       +mark_getlist(mark_t *marks, char *seq)
       +{
       +        return (llist_t *)mark_internget(marks, seq, 1);
        }
        
        char *
       t@@ -283,7 +485,8 @@ markmain(int argc, char *argv[])
                        result = mark_get(marks, argv[0]);
                        if (result == NULL)
                                die("No such sequence found.\n");
       -                mark_printelem(result, status & ONLYNAMES, status & ONLYVALUE);
       +                mark_printelem(result, status & ONLYNAMES,
       +                                status & ONLYVALUE);
                        free(selected);
                        return 0;
                }
 (DIR) diff --git a/mark.h b/mark.h
       t@@ -15,9 +15,7 @@
        #define mark_new txtdb_new
        #define mark_add txtdb_add
        #define mark_del txtdb_del
       -#define mark_get txtdb_get
        #define mark_find txtdb_find
       -#define mark_set txtdb_set
        #define mark_len txtdb_len
        #define mark_read txtdb_read
        #define mark_write txtdb_write
       t@@ -27,6 +25,9 @@ mark_t *mark_init(char *mailbox);
        void mark_free(mark_t *marks);
        mark_t *mark_cfg(config_t *cfg);
        void mark_stop(mark_t *marks);
       +
       +llistelem_t *mark_set(mark_t *marks, char *seq, char *value);
       +llistelem_t *mark_get(mark_t *marks, char *seq);
        llist_t *mark_getlist(mark_t *marks, char *seq);
        char *mark_getstr(mark_t *marks, char *seq);
        
 (DIR) diff --git a/mime.c b/mime.c
       t@@ -513,12 +513,12 @@ mime_parseheader(char *field)
                        /*
                         * 1.) ([\t\r\v\f ]*)key
                         */
       -                key = strcsh(tok, "\t\r\v\f ");
       +                key = tok + strspn(tok, "\t\r\v\f ");
        
                        /*
                         * 2.) key
                         */
       -                tok = strncsh(key, "\t\r\v\f =;");
       +                tok = key + strcspn(key, "\t\r\v\f =;");
                        if (tok[0] == ';' || tok[0] == '\0') {
                                quot = tok[0];
                                tok[0] = '\0';
       t@@ -536,7 +536,7 @@ mime_parseheader(char *field)
                                 * 3.) key([\t\r\v\f ]*)=
                                 */
                                tok[0] = '\0';
       -                        eq = strcsh(tok+1, "\t\r\v\f ;");
       +                        eq = tok + 1 + strspn(tok+1, "\t\r\v\f ;");
                                if (eq[0] == ';') {
                                        if (strlen(key) > 0)
                                                llist_add(ret, key, NULL, 0);
       t@@ -558,7 +558,7 @@ mime_parseheader(char *field)
                        /*
                         * 4.) key=([\t\r\v\f ]*)("|)value
                         */
       -                tok = strcsh(eq+1, "\t\r\v\f ");
       +                tok = eq + 1 + strspn(eq+1, "\t\r\v\f ");
                        switch (tok[0]) {
                        case '"':
                        case '\'':
       t@@ -575,7 +575,7 @@ mime_parseheader(char *field)
                                value = &tok[1];
                                tok = sep;
        
       -                        sep = strncsh(tok, ";");
       +                        sep = tok + strcspn(tok, ";");
                                if (sep[0] == ';') {
                                        tok = sep + 1;
                                } else {
       t@@ -587,7 +587,7 @@ mime_parseheader(char *field)
                                 * 4.1.) value
                                 */
                                value = tok;
       -                        sep = strncsh(tok, "\t\r\v\f ;");
       +                        sep = tok + strcspn(tok, "\t\r\v\f ;");
                                if (sep[0] == ';') {
                                        sep[0] = '\0';
                                        tok = sep + 1;
 (DIR) diff --git a/txtdb.c b/txtdb.c
       t@@ -111,16 +111,16 @@ txtdb_read(char *file)
                                continue;
                        line[strlen(line)-1] = '\0';
        
       -                p = strcsh(line, "\t\r\v\f ");
       +                p = line + strspn(line, "\t\r\v\f ");
                        key = p;
       -                p = strncsh(p, "\t\r\v\f =");
       +                p = p + strcspn(p, "\t\r\v\f =");
                        p[0] = '\0';
        
       -                p = strcsh(p+1, "\t\r\v\f ");
       +                p = p + 1 + strspn(p+1, "\t\r\v\f ");
                        if (p[0] != '=')
                                continue;
        
       -                p = strcsh(p+1, "\t\r\v\f ");
       +                p = p + 1 + strspn(p+1, "\t\r\v\f ");
                        value = p;
        
                        txtdb_add(txtdb, key, value);