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);