Diffstat (limited to 'noncore/todayplugins/stockticker/libstocks/csv.c') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/csv.c | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/noncore/todayplugins/stockticker/libstocks/csv.c b/noncore/todayplugins/stockticker/libstocks/csv.c new file mode 100644 index 0000000..99a44e4 --- a/dev/null +++ b/noncore/todayplugins/stockticker/libstocks/csv.c | |||
@@ -0,0 +1,402 @@ | |||
1 | /* libstocks - Library to get current stock quotes from Yahoo Finance | ||
2 | * | ||
3 | * Copyright (C) 2000 Eric Laeuffer | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Library General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Library General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Library General Public | ||
16 | * License along with this library; if not, write to the | ||
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | * Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #define __CSV_C__ | ||
22 | |||
23 | #include <string.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <stdio.h> | ||
26 | |||
27 | #ifdef __WINDOWS__ | ||
28 | #include <mbstring.h> | ||
29 | #endif | ||
30 | |||
31 | #include "csv.h" | ||
32 | #include "stocks.h" | ||
33 | #include "lists.h" | ||
34 | |||
35 | #define DATE_LENGTH 7 /*YYMMDD*/ | ||
36 | |||
37 | const char *months[12]= | ||
38 | { | ||
39 | "Jan", | ||
40 | "Feb", | ||
41 | "Mar", | ||
42 | "Apr", | ||
43 | "May", | ||
44 | "Jun", | ||
45 | "Jul", | ||
46 | "Aug", | ||
47 | "Sep", | ||
48 | "Oct", | ||
49 | "Nov", | ||
50 | "Dec" | ||
51 | }; | ||
52 | |||
53 | /*****************************************************************************/ | ||
54 | /* Replacement of the strtok function. This one forgets "delim" when it is */ | ||
55 | /* between two commas. */ | ||
56 | /* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */ | ||
57 | /*****************************************************************************/ | ||
58 | char *csv_strtok(char *s, char *delim) | ||
59 | { | ||
60 | static char *next=NULL; | ||
61 | char *temp, *first; | ||
62 | int comma=0; | ||
63 | |||
64 | if (s!=NULL) first=s; | ||
65 | else first=next; | ||
66 | |||
67 | temp=first; | ||
68 | if (*temp=='\0') return NULL; | ||
69 | |||
70 | while (*temp!='\0' && ((*temp!=*delim) || comma)) | ||
71 | { | ||
72 | if (*temp=='"') comma ^= 1; | ||
73 | temp++; | ||
74 | } | ||
75 | |||
76 | if (*temp=='\0') next=temp; | ||
77 | else | ||
78 | { | ||
79 | *temp='\0'; | ||
80 | next=temp+1; | ||
81 | } | ||
82 | |||
83 | return first; | ||
84 | } | ||
85 | |||
86 | /*****************************************************************************/ | ||
87 | /* Parses the csv file and return a list of stocks structure. */ | ||
88 | /* *csv points on the csv file in memory */ | ||
89 | /* count defines the country, because csv depends on the country */ | ||
90 | /*****************************************************************************/ | ||
91 | stock *parse_csv_file(char *csv) | ||
92 | { | ||
93 | char *line; | ||
94 | char *end_line; | ||
95 | |||
96 | char *ptr; | ||
97 | |||
98 | char *date; | ||
99 | char *time; | ||
100 | char *name; | ||
101 | char *symbol; | ||
102 | |||
103 | stock *StockPtr=NULL; | ||
104 | stock *LastStockPtr=NULL; | ||
105 | |||
106 | /* Used to return the pointer to the list */ | ||
107 | stock *FirstStockPtr=NULL; | ||
108 | |||
109 | /* used to see if symbol is valid */ | ||
110 | int valid; | ||
111 | char *test; | ||
112 | |||
113 | line = csv; | ||
114 | end_line = csv; | ||
115 | |||
116 | while ((end_line = strstr(line, "\n"))) | ||
117 | { | ||
118 | *end_line = 0; | ||
119 | |||
120 | /* Check if symbol valid */ | ||
121 | /* if 1 "N/A" then ok because Indices have N/A for volume */ | ||
122 | /* if 4 "N/A" then ok because Mutual funds have */ | ||
123 | /* if 5 "N/A" then ok because currencies have */ | ||
124 | /* So if >5 then stock not valid */ | ||
125 | |||
126 | test = line; | ||
127 | valid = 0; | ||
128 | while ( (test = strstr(test, "N/A")) ) | ||
129 | { | ||
130 | valid ++; | ||
131 | test = test +3; | ||
132 | } | ||
133 | |||
134 | if (valid < 6) | ||
135 | { | ||
136 | /* This Symbol is valid */ | ||
137 | |||
138 | StockPtr = malloc_stock(); | ||
139 | |||
140 | ptr = csv_strtok(line, ","); | ||
141 | if (!ptr) return 0; | ||
142 | |||
143 | symbol = (char *)malloc(strlen(ptr)+1); | ||
144 | if (symbol==NULL) | ||
145 | { | ||
146 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | ||
147 | ,__FILE__, __LINE__); | ||
148 | exit(1); | ||
149 | } | ||
150 | strcpy((char *)(symbol), ptr); | ||
151 | StockPtr->Symbol = symbol; | ||
152 | |||
153 | ptr = csv_strtok(NULL, ","); | ||
154 | if (!ptr) return 0; | ||
155 | |||
156 | name = (char *)malloc(strlen(ptr)+1); | ||
157 | if (name==NULL) | ||
158 | { | ||
159 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | ||
160 | ,__FILE__, __LINE__); | ||
161 | exit(1); | ||
162 | } | ||
163 | strcpy((char *)(name), ptr); | ||
164 | StockPtr->Name = name; | ||
165 | |||
166 | ptr = csv_strtok(NULL, ","); | ||
167 | if (!ptr) return 0; | ||
168 | sscanf(ptr,"%f",&(StockPtr->CurrentPrice)); | ||
169 | |||
170 | ptr = csv_strtok(NULL, ","); | ||
171 | if (!ptr) return 0; | ||
172 | |||
173 | date = (char *)malloc(strlen(ptr)+1); | ||
174 | if (date==NULL) | ||
175 | { | ||
176 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | ||
177 | ,__FILE__, __LINE__); | ||
178 | exit(1); | ||
179 | } | ||
180 | strcpy((char *)(date), ptr); | ||
181 | StockPtr->Date = date; | ||
182 | |||
183 | ptr = csv_strtok(NULL, ","); | ||
184 | if (!ptr) return 0; | ||
185 | |||
186 | time = (char *)malloc(strlen(ptr)+1); | ||
187 | if (time==NULL) | ||
188 | { | ||
189 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | ||
190 | ,__FILE__, __LINE__); | ||
191 | exit(1); | ||
192 | } | ||
193 | strcpy((char *)(time), ptr); | ||
194 | StockPtr->Time = time; | ||
195 | |||
196 | ptr = csv_strtok(NULL, ","); | ||
197 | if (!ptr) return 0; | ||
198 | sscanf(ptr,"%f",&(StockPtr->Variation)); | ||
199 | |||
200 | StockPtr->Pourcentage = 100 * StockPtr->Variation / | ||
201 | (StockPtr->CurrentPrice - StockPtr->Variation); | ||
202 | |||
203 | StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation; | ||
204 | |||
205 | ptr = csv_strtok(NULL, ","); | ||
206 | if (!ptr) return 0; | ||
207 | sscanf(ptr,"%f",&(StockPtr->OpenPrice)); | ||
208 | |||
209 | ptr = csv_strtok(NULL, ","); | ||
210 | if (!ptr) return 0; | ||
211 | sscanf(ptr,"%f",&(StockPtr->MaxPrice)); | ||
212 | |||
213 | ptr = csv_strtok(NULL, ","); | ||
214 | if (!ptr) return 0; | ||
215 | sscanf(ptr,"%f",&(StockPtr->MinPrice)); | ||
216 | |||
217 | ptr = csv_strtok(NULL, ","); | ||
218 | if (!ptr) return 0; | ||
219 | StockPtr->Volume = atoi(ptr); | ||
220 | |||
221 | if( !FirstStockPtr ) | ||
222 | { | ||
223 | FirstStockPtr = StockPtr; | ||
224 | StockPtr->PreviousStock = 0; | ||
225 | } | ||
226 | |||
227 | StockPtr->NextStock = 0; | ||
228 | |||
229 | if (LastStockPtr) | ||
230 | { | ||
231 | LastStockPtr->NextStock = StockPtr; | ||
232 | StockPtr->PreviousStock = LastStockPtr; | ||
233 | } | ||
234 | |||
235 | LastStockPtr = StockPtr; | ||
236 | |||
237 | } | ||
238 | else | ||
239 | { | ||
240 | /* this symbol is not valid */ | ||
241 | /* Set the stock struct just with Symbol, all other are NULL */ | ||
242 | /* This can be used to see if the symbol has been reached are not */ | ||
243 | |||
244 | StockPtr = malloc_stock(); | ||
245 | |||
246 | ptr = csv_strtok(line, ","); | ||
247 | if (!ptr) return 0; | ||
248 | |||
249 | symbol = (char *)malloc(strlen(ptr)+1); | ||
250 | if (symbol==NULL) | ||
251 | { | ||
252 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | ||
253 | ,__FILE__, __LINE__); | ||
254 | exit(1); | ||
255 | } | ||
256 | strcpy((char *)(symbol), ptr); | ||
257 | StockPtr->Symbol = symbol; | ||
258 | |||
259 | if( !FirstStockPtr ) | ||
260 | { | ||
261 | FirstStockPtr = StockPtr; | ||
262 | StockPtr->PreviousStock = 0; | ||
263 | } | ||
264 | |||
265 | StockPtr->NextStock = 0; | ||
266 | |||
267 | if (LastStockPtr) | ||
268 | { | ||
269 | LastStockPtr->NextStock = StockPtr; | ||
270 | StockPtr->PreviousStock = LastStockPtr; | ||
271 | } | ||
272 | |||
273 | LastStockPtr = StockPtr; | ||
274 | } | ||
275 | |||
276 | end_line++; | ||
277 | line = end_line; | ||
278 | |||
279 | } | ||
280 | |||
281 | return (FirstStockPtr); | ||
282 | } | ||
283 | |||
284 | /*****************************************************************************/ | ||
285 | /* Parses the history quotes file and return a stock structure list. */ | ||
286 | /*****************************************************************************/ | ||
287 | stock *parse_csv_history_file(char *csv_file) | ||
288 | { | ||
289 | |||
290 | char *line; | ||
291 | char *end_line; | ||
292 | char *ptr; | ||
293 | |||
294 | int day; | ||
295 | char smonth[10]; | ||
296 | int month; | ||
297 | int year; | ||
298 | |||
299 | char *date; | ||
300 | |||
301 | int i; | ||
302 | int test; | ||
303 | |||
304 | stock *StockPtr=NULL; | ||
305 | stock *LastStockPtr=NULL; | ||
306 | |||
307 | /* Used to return the pointer to the list */ | ||
308 | stock *FirstStockPtr=NULL; | ||
309 | |||
310 | line = csv_file; | ||
311 | end_line = csv_file; | ||
312 | |||
313 | /* do not use the first line */ | ||
314 | end_line = strstr(line, "\n"); | ||
315 | *end_line = 0; | ||
316 | end_line++; | ||
317 | line = end_line; | ||
318 | |||
319 | while ((end_line = strstr(line, "\n"))) | ||
320 | { | ||
321 | *end_line = 0; | ||
322 | |||
323 | StockPtr = malloc_stock(); | ||
324 | |||
325 | /* Date */ | ||
326 | ptr = strtok(line, ","); | ||
327 | if (!ptr) return 0; | ||
328 | |||
329 | sscanf(ptr,"%d-%3s-%d",&day,smonth,&year); | ||
330 | |||
331 | i=0; | ||
332 | |||
333 | #ifdef __UNIX__ | ||
334 | while((test=strcasecmp(months[i], smonth))) i++; | ||
335 | #elif __WINDOWS__ | ||
336 | while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++; | ||
337 | #endif | ||
338 | |||
339 | month = i+1; | ||
340 | |||
341 | date = (char *)malloc(DATE_LENGTH); | ||
342 | if (date==NULL) | ||
343 | { | ||
344 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | ||
345 | ,__FILE__, __LINE__); | ||
346 | exit(1); | ||
347 | } | ||
348 | sprintf(date,"%.2d%.2d%.2d", year, month, day); | ||
349 | StockPtr->Date = date; | ||
350 | |||
351 | /* Open */ | ||
352 | ptr = strtok(NULL, ","); | ||
353 | if (!ptr) return 0; | ||
354 | sscanf(ptr,"%f",&(StockPtr->OpenPrice)); | ||
355 | |||
356 | /* High */ | ||
357 | ptr = strtok(NULL, ","); | ||
358 | if (!ptr) return 0; | ||
359 | sscanf(ptr,"%f",&(StockPtr->MaxPrice)); | ||
360 | |||
361 | /* Low */ | ||
362 | ptr = strtok(NULL, ","); | ||
363 | if (!ptr) return 0; | ||
364 | sscanf(ptr,"%f",&(StockPtr->MinPrice)); | ||
365 | |||
366 | /* Close */ | ||
367 | ptr = strtok(NULL, ","); | ||
368 | if (!ptr) return 0; | ||
369 | sscanf(ptr,"%f",&(StockPtr->LastPrice)); | ||
370 | |||
371 | /* Volume */ | ||
372 | |||
373 | ptr = strtok(NULL, ","); | ||
374 | if (!ptr) | ||
375 | /* It seems to be an indice */ | ||
376 | /* No volume for indices */ | ||
377 | StockPtr->Volume = 0; | ||
378 | else | ||
379 | StockPtr->Volume = atoi(ptr); | ||
380 | |||
381 | if( !FirstStockPtr ) | ||
382 | { | ||
383 | FirstStockPtr = StockPtr; | ||
384 | StockPtr->PreviousStock = 0; | ||
385 | } | ||
386 | |||
387 | StockPtr->NextStock = 0; | ||
388 | |||
389 | if (LastStockPtr) | ||
390 | { | ||
391 | LastStockPtr->NextStock = StockPtr; | ||
392 | StockPtr->PreviousStock = LastStockPtr; | ||
393 | } | ||
394 | |||
395 | LastStockPtr = StockPtr; | ||
396 | |||
397 | end_line++; | ||
398 | line = end_line; | ||
399 | } | ||
400 | |||
401 | return (FirstStockPtr); | ||
402 | } | ||