1 #ifndef NO_POSIX_SOURCE
2 #undef _POSIX_SOURCE
3 #define _POSIX_SOURCE 1
4 #undef _POSIX_C_SOURCE
5 #define _POSIX_C_SOURCE 2
6 #endif
7
8 #include <assert.h>
9 #include <ctype.h>
10 #include <stdlib.h>
11 #ifdef OLD_REALLOC
12 #define realloc(s,l) myrealloc(s,l)
13 #endif
14
15 #ifdef DMALLOC
16 #include "dmalloc.h"
17 #endif
18
19 #include "csv.h"
20
21 static int semicol=0;
22
23 /* csv_setopt -- set language */ /*{{{C}}}*//*{{{*/
csv_setopt(int sem)24 void csv_setopt(int sem)
25 {
26 semicol=sem;
27 }
28 /*}}}*/
29 #if 0
30 /* csv_date -- convert string "year<sep>month<sep>day<sep>" to date */ /*{{{*/
31 static struct CSV_Date csv_date(const char *s, const char **end)
32 {
33 struct CSV_Date date;
34
35 assert(s!=(const char*)0);
36 assert(end!=(const char**)0);
37 *end=s;
38 if (*s=='"')
39 {
40 ++s;
41 if (isdigit(*s))
42 {
43 for (date.year=0; isdigit(*s); date.year=10*date.year+(*s-'0'),++s);
44 if (*s)
45 {
46 ++s;
47 if (isdigit(*s))
48 {
49 for (date.month=0; isdigit(*s); date.month=10*date.month+(*s-'0'),++s);
50 if (*s)
51 {
52 ++s;
53 if (isdigit(*s))
54 {
55 for (date.day=0; isdigit(*s); date.day=10*date.day+(*s-'0'),++s);
56 if (*s=='"')
57 {
58 ++s;
59 *end=s;
60 }
61 }
62 }
63 }
64 }
65 }
66 }
67 return date;
68 }
69 /*}}}*/
70 #endif
71 /* csv_separator -- convert string \t to nothing */ /*{{{*/
csv_separator(const char * s,const char ** end)72 void csv_separator(const char *s, const char **end)
73 {
74 assert(s!=(const char*)0);
75 assert(end!=(const char**)0);
76 *end=s+(*s=='\t' || (semicol && *s==';') || (!semicol && *s==','));
77 }
78 /*}}}*/
79 /* csv_long -- convert string [0[x]]12345 to long */ /*{{{*/
csv_long(const char * s,const char ** end)80 long csv_long(const char *s, const char **end)
81 {
82 long value;
83 const char *t;
84
85 assert(s!=(const char*)0);
86 assert(end!=(const char**)0);
87 if (*s=='\t') { *end=s; return 0L; };
88 value=strtol(s,(char**)end,0);
89 if (s!=*end)
90 {
91 t=*end; csv_separator(t,end);
92 if (t!=*end || *t=='\0' || *t=='\n') return value;
93 }
94 *end=s; return 0L;
95 }
96 /*}}}*/
97 /* csv_double -- convert string 123.4e5 to double */ /*{{{*/
csv_double(const char * s,const char ** end)98 double csv_double(const char *s, const char **end)
99 {
100 double value;
101 const char *t;
102
103 assert(s!=(const char*)0);
104 assert(end!=(const char**)0);
105 if (*s=='\t') { *end=s; return 0.0; };
106 value=strtod(s,(char**)end);
107 if (s!=*end)
108 {
109 t=*end; csv_separator(t,end);
110 if (t!=*end || *t=='\0' || *t=='\n') return value;
111 }
112 *end=s; return 0.0;
113 }
114 /*}}}*/
115 /* csv_string -- convert almost any string to string */ /*{{{*/
csv_string(const char * s,const char ** end)116 char *csv_string(const char *s, const char **end)
117 {
118 static char *string;
119 static int strings,stringsz;
120
121 assert(s!=(const char*)0);
122 assert(end!=(const char**)0);
123 strings=0;
124 stringsz=0;
125 string=(char*)0;
126 if (!isprint((int)*s) || (!semicol && *s==',') || (semicol && *s==';')) return (char*)0;
127 if (*s=='"')
128 {
129 ++s;
130 while (*s!='\0' && *s!='\n' && *s!='"')
131 {
132 if ((strings+2)>=stringsz)
133 {
134 string=realloc(string,stringsz+=32);
135 }
136 string[strings]=*s;
137 ++strings;
138 ++s;
139 }
140 if (*s=='"') ++s;
141 }
142 else
143 {
144 while (*s!='\0' && *s!='\n' && *s!='\t' && ((!semicol && *s!=',') || (semicol && *s!=';')))
145 {
146 if ((strings+2)>=stringsz)
147 {
148 string=realloc(string,stringsz+=32);
149 }
150 string[strings]=*s;
151 ++strings;
152 ++s;
153 }
154 }
155 string[strings]='\0';
156 *end=s;
157 csv_separator(s,end);
158 return string;
159 }
160 /*}}}*/
161