rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | LICENSE

commit 7c6671458b78219b689b61d8e0fd736d45a9e549
parent 56d7dc2f40c709b78b997c755a1766eb75e0b450
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(-)

diff --git a/ind.c b/ind.c @@ -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; @@ -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; } @@ -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; diff --git a/ind.h b/ind.h @@ -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); diff --git a/mark.c b/mark.c @@ -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 * @@ -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; } diff --git a/mark.h b/mark.h @@ -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 @@ -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); diff --git a/mime.c b/mime.c @@ -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'; @@ -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); @@ -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 '\'': @@ -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 { @@ -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; diff --git a/txtdb.c b/txtdb.c @@ -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);