Introduction
Introduction Statistics Contact Development Disclaimer Help
add tests and cleanup I/O function - ics2txt - convert icalendar .ics file to p…
git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws…
Log
Files
Refs
Tags
README
---
commit a7b4ceeaf4a57476c0952e0da2def5f92bdfdb9f
parent 94bccd0b9ea7049ebeec4fcf2416f6f0b7d221b5
Author: Josuah Demangeon <[email protected]>
Date: Sun, 28 Jun 2020 10:34:46 +0200
add tests and cleanup I/O function
Diffstat:
M ics2tsv.c | 7 +++++--
M src/ical.c | 72 +++++++++--------------------…
M src/ical.h | 2 +-
M src/map.c | 6 ++++++
M src/map.h | 1 +
M src/util.c | 5 +++--
A test/map.c | 18 ++++++++++++++++++
A test/random-ics.awk | 40 +++++++++++++++++++++++++++++…
8 files changed, 94 insertions(+), 57 deletions(-)
---
diff --git a/ics2tsv.c b/ics2tsv.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <stdlib.h>
#include "ical.h"
#include "log.h"
@@ -8,17 +9,19 @@ int
print_ical_to_tsv(FILE *fp)
{
struct ical_contentline contentline;
- char *line = NULL;
+ char *line = NULL, *ln = NULL;
size_t sz = 0;
ssize_t r;
ical_init_contentline(&contentline);
- while ((r = ical_read_line(&line, &sz, fp)) > 0) {
+ while ((r = ical_read_line(&line, &ln, &sz, fp)) > 0) {
debug("readling line \"%s\"", line);
if (ical_parse_contentline(&contentline, line) < 0)
die("parsing line \"%s\"", line);
}
+ free(line);
+ free(ln);
return r;
}
diff --git a/src/ical.c b/src/ical.c
@@ -8,38 +8,28 @@
#include "util.h"
int
-ical_read_line(char **line, size_t *sz, FILE *fp)
+ical_read_line(char **line, char **ln, size_t *sz, FILE *fp)
{
- ssize_t r;
- char *tail = NULL;
- size_t tail_sz = 0;
- int c, ret = -1;
+ int c;
+ void *v;
- if ((r = getline(line, sz, fp)) <= 0)
- return r;
- strchomp(*line);
-
- for (;;) {
- if ((c = fgetc(fp)) == EOF) {
- ret = ferror(fp) ? -1 : 0;
- goto end;
- }
- if (c != ' ')
- break;
- if ((r = getline(&tail, &tail_sz, fp)) <= 0) {
- ret = r;
- goto end;
- }
- strchomp(tail);
- if (strappend(line, tail) < 0)
- goto end;
- }
+ if ((v = realloc(*line, 1)) == NULL)
+ return -1;
+ *line = v;
+ (*line)[0] = '\0';
+
+ do {
+ if (getline(ln, sz, fp) <= 0)
+ return ferror(fp) ? -1 : 0;
+ strchomp(*ln);
+ if (strappend(line, *ln) < 0)
+ return -1;
+ if ((c = fgetc(fp)) == EOF)
+ return ferror(fp) ? -1 : 1;
+ } while (c == ' ');
- ret = 1;
-end:
- free(tail);
ungetc(c, fp);
- return ret;
+ return 1;
}
int
@@ -48,48 +38,26 @@ ical_parse_contentline(struct ical_contentline *contentline…
char *column, *equal, *param, *cp;
size_t sz;
- debug("0");
-
if ((column = strchr(line, ':')) == NULL)
return -1;
*column = '\0';
-
- {
- size_t len;
-
- debug("1.1");
- len = strlen(column + 1);
- debug("1.2");
- }
-
-
if ((contentline->value = strdup(column + 1)) == NULL)
return -1;
- debug("2");
-
- cp = strchr(line, ';');
- cp = (cp == NULL) ? (NULL) : (cp + 1);
-
- debug("3");
-
+ if ((cp = strchr(line, ';')) != NULL)
+ cp++;
while ((param = strsep(&cp, ";")) != NULL) {
if ((equal = strchr(param, '=')) == NULL)
return -1;
*equal = '\0';
-
if (map_set(&contentline->param, param, equal + 1) < 0)
return -1;
}
- debug("4");
-
sz = sizeof(contentline->name);
if (strlcpy(contentline->name, line, sz) >= sz)
return errno=EMSGSIZE, -1;
- debug("5");
-
return 0;
}
diff --git a/src/ical.h b/src/ical.h
@@ -17,7 +17,7 @@ struct ical_contentline {
};
/** src/ical.c **/
-int ical_read_line(char **line, size_t *sz, FILE *fp);
+int ical_read_line(char **line, char **ln, size_t *sz, FILE *fp);
int ical_parse_contentline(struct ical_contentline *contentline, char *line);
void ical_init_contentline(struct ical_contentline *contentline);
void ical_free_contentline(struct ical_contentline *contentline);
diff --git a/src/map.c b/src/map.c
@@ -87,6 +87,12 @@ map_del(struct map *map, char *key)
}
void
+map_init(struct map *map)
+{
+ memset(map, 0, sizeof(*map));
+}
+
+void
map_free_values(struct map *map)
{
for (size_t i = 0; i < map->len; i++)
diff --git a/src/map.h b/src/map.h
@@ -17,6 +17,7 @@ struct map {
void * map_get(struct map *map, char *key);
int map_set(struct map *map, char *key, void *value);
int map_del(struct map *map, char *key);
+void map_init(struct map *map);
void map_free_values(struct map *map);
void map_free(struct map *map);
diff --git a/src/util.c b/src/util.c
@@ -10,7 +10,8 @@ strlcpy(char *buf, char const *str, size_t sz)
{
size_t len, cpy;
- cpy = ((len = strlen(str)) > sz) ? (sz) : (len);
+ len = strlen(str);
+ cpy = (len > sz) ? (sz) : (len);
memcpy(buf, str, cpy + 1);
buf[sz - 1] = '\0';
return len;
@@ -54,7 +55,7 @@ strappend(char **base_p, char const *s)
size_t base_len, s_len;
void *v;
- base_len = strlen(*base_p);
+ base_len = (*base_p == NULL) ? (0) : (strlen(*base_p));
s_len = strlen(s);
if ((v = realloc(*base_p, base_len + s_len + 1)) == NULL)
diff --git a/test/map.c b/test/map.c
@@ -0,0 +1,18 @@
+#include <string.h>
+#include <stdio.h>
+
+#include "map.h"
+
+int main(int argc, char **argv) {
+ struct map map;
+
+ memset(&map, 0, sizeof(map));
+
+ for (argv++; *argv != NULL; argv++)
+ if (map_set(&map, *argv, "abra") < 0)
+ return 1;
+
+ fprintf(stdout, ".");
+
+ return 0;
+}
diff --git a/test/random-ics.awk b/test/random-ics.awk
@@ -0,0 +1,40 @@
+#!/usr/bin/awk -f
+
+function random(n) {
+ "exec od -An </dev/urandom" | getline num
+ return num % n
+}
+
+BEGIN {
+ data = "exec tr -cd -- '-a-zA-Z0-9\n' </dev/urandom"
+
+ first = 1
+ while (data | getline) {
+ if (random(2) && !first) {
+ print(" " $0)
+ continue
+ }
+ first = 0
+
+ col = random(26) + 1
+ out = substr($0, 1, col)
+ $0 = substr($0, col + 1)
+ n = random(30)
+ for (i = 0; i <= n; i++) {
+ col = random(30) + 5
+ if (length($0) < col)
+ continue
+ eq = random(int(col / 2)) + 1
+ out = out substr($0, 1, eq) "=" substr($1, eq + 1, col…
+ $0 = substr($0, col + 1)
+ }
+ out = out $0 ":"
+ data | getline
+ out = out $0
+ if (out ~ "\n" || out !~ ":")
+ exit(1)
+ print(out)
+ }
+
+ close(cmd)
+}
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.