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