… | |
… | |
22 | |
22 | |
23 | #include <stdlib.h> |
23 | #include <stdlib.h> |
24 | |
24 | |
25 | #include "parse_routines.h" |
25 | #include "parse_routines.h" |
26 | #include "error.h" |
26 | #include "error.h" |
|
|
27 | |
|
|
28 | #ifdef DMALLOC |
|
|
29 | #include <dmalloc.h> |
|
|
30 | #endif |
|
|
31 | |
27 | |
32 | |
28 | struct formula_element |
33 | struct formula_element |
29 | { |
34 | { |
30 | psiconv_formula_type_t formula_type; |
35 | psiconv_formula_type_t formula_type; |
31 | int number_of_args; |
36 | int number_of_args; |
… | |
… | |
286 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
291 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
287 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
292 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
288 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
293 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
289 | {psiconv_formula_unknown,0,"*UNKNOWN*"}}; |
294 | {psiconv_formula_unknown,0,"*UNKNOWN*"}}; |
290 | |
295 | |
291 | static psiconv_string_t psiconv_read_sheet_string(const psiconv_buffer buf, |
|
|
292 | int lev, |
|
|
293 | psiconv_u32 off,int *length, int *status) |
|
|
294 | { |
|
|
295 | int stringlen,i,len,localstatus; |
|
|
296 | psiconv_string_t result; |
|
|
297 | char *res_copy; |
|
|
298 | |
|
|
299 | psiconv_progress(lev+1,off,"Going to read a sheet string"); |
|
|
300 | |
|
|
301 | stringlen = psiconv_read_u8(buf,lev+2,off,&localstatus); |
|
|
302 | if (localstatus) |
|
|
303 | goto ERROR1; |
|
|
304 | psiconv_debug(lev+2,off,"Length: %i",stringlen); |
|
|
305 | len = 1; |
|
|
306 | |
|
|
307 | result = malloc(stringlen + 1); |
|
|
308 | if (!result) |
|
|
309 | goto ERROR1; |
|
|
310 | for (i = 0; (i < stringlen) && !localstatus; i++) |
|
|
311 | result[i] = psiconv_read_u8(buf,lev,off+i+len,&localstatus); |
|
|
312 | if (localstatus) |
|
|
313 | goto ERROR2; |
|
|
314 | result[stringlen] = 0; |
|
|
315 | len += stringlen; |
|
|
316 | |
|
|
317 | res_copy = psiconv_make_printable(result); |
|
|
318 | if (!res_copy) |
|
|
319 | goto ERROR2; |
|
|
320 | psiconv_debug(lev+2,off,"Contents: `%s'",res_copy); |
|
|
321 | free(res_copy); |
|
|
322 | |
|
|
323 | if (length) |
|
|
324 | *length = len; |
|
|
325 | |
|
|
326 | if (status) |
|
|
327 | *status = 0; |
|
|
328 | |
|
|
329 | psiconv_progress(lev+1,off+len-1,"End of sheet string (total length: %08x)", |
|
|
330 | len); |
|
|
331 | |
|
|
332 | return result; |
|
|
333 | |
|
|
334 | |
|
|
335 | ERROR2: |
|
|
336 | free(result); |
|
|
337 | ERROR1: |
|
|
338 | psiconv_warn(lev+1,off,"Reading of sheet string failed"); |
|
|
339 | if (status) |
|
|
340 | *status = localstatus; |
|
|
341 | if (length) |
|
|
342 | *length = 0; |
|
|
343 | return NULL; |
|
|
344 | } |
|
|
345 | |
|
|
346 | |
|
|
347 | static int psiconv_parse_sheet_ref(const psiconv_buffer buf,int lev, |
296 | static int psiconv_parse_sheet_ref(const psiconv_buffer buf,int lev, |
348 | psiconv_u32 off, int *length, |
297 | psiconv_u32 off, int *length, |
349 | psiconv_sheet_ref_t *result) |
298 | psiconv_sheet_ref_t *result) |
350 | { |
299 | { |
351 | int res; |
300 | int res; |
… | |
… | |
444 | { |
393 | { |
445 | int res=0; |
394 | int res=0; |
446 | int len=0; |
395 | int len=0; |
447 | int leng; |
396 | int leng; |
448 | int eof = 0; |
397 | int eof = 0; |
449 | psiconv_u8 marker,submarker; |
398 | psiconv_u8 marker,submarker,submarker2; |
450 | psiconv_formula_list formula_stack; |
399 | psiconv_formula_list formula_stack; |
451 | psiconv_formula formula,subformula,subformula1,subformula2, |
400 | psiconv_formula formula,subformula,subformula1,subformula2, |
452 | subformula3,subformula4; |
401 | subformula3,subformula4; |
453 | psiconv_u16 temp,nr_of_subs; |
402 | psiconv_u16 temp,nr_of_subs; |
454 | |
403 | |
… | |
… | |
546 | formula->type = psiconv_formula_unknown; |
495 | formula->type = psiconv_formula_unknown; |
547 | } else if (formula_elements[marker].formula_type == |
496 | } else if (formula_elements[marker].formula_type == |
548 | psiconv_formula_dat_string) { |
497 | psiconv_formula_dat_string) { |
549 | psiconv_progress(lev+3,off+len,"Next item: a string"); |
498 | psiconv_progress(lev+3,off+len,"Next item: a string"); |
550 | formula->data.dat_string = |
499 | formula->data.dat_string = |
551 | psiconv_read_sheet_string(buf,lev+2,off+len,&leng,&res); |
500 | psiconv_read_short_string(buf,lev+2,off+len,&leng,&res); |
552 | if (res) |
501 | if (res) |
553 | goto ERROR8; |
502 | goto ERROR8; |
554 | formula->type = formula_elements[marker].formula_type; |
503 | formula->type = formula_elements[marker].formula_type; |
555 | len += leng; |
504 | len += leng; |
556 | if ((res = psiconv_list_add(formula_stack,formula))) |
505 | if ((res = psiconv_list_add(formula_stack,formula))) |
557 | goto ERROR8; |
506 | goto ERROR8; |
558 | formula->type = psiconv_formula_unknown; |
507 | formula->type = psiconv_formula_unknown; |
559 | } else if ((formula_elements[marker].formula_type == |
508 | } else if ((formula_elements[marker].formula_type == |
560 | psiconv_formula_dat_var) || |
509 | psiconv_formula_dat_var)) { |
561 | (formula_elements[marker].formula_type == |
510 | psiconv_progress(lev+3,off+len,"Next item: a variable reference"); |
562 | psiconv_formula_dat_vcellblock)) { |
511 | formula->data.dat_variable = psiconv_read_u32(buf,lev+2,off+len,&res); |
563 | psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); |
512 | if (res) |
564 | goto ERROR8; |
513 | goto ERROR8; |
|
|
514 | formula->type = formula_elements[marker].formula_type; |
|
|
515 | len += 4; |
|
|
516 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
517 | goto ERROR8; |
|
|
518 | formula->type = psiconv_formula_unknown; |
565 | } else if (formula_elements[marker].number_of_args == -1) { |
519 | } else if (formula_elements[marker].number_of_args == -1) { |
566 | psiconv_progress(lev+3,off+len,"Going to parse a vararg function"); |
520 | psiconv_progress(lev+3,off+len,"Going to parse a vararg function"); |
567 | if (!(formula->data.fun_operands = |
521 | if (!(formula->data.fun_operands = |
568 | psiconv_list_new(sizeof(*formula)))) |
522 | psiconv_list_new(sizeof(*formula)))) |
569 | goto ERROR8; |
523 | goto ERROR8; |
… | |
… | |
585 | psiconv_progress(lev+4,off+len,"Going to read the next marker"); |
539 | psiconv_progress(lev+4,off+len,"Going to read the next marker"); |
586 | submarker = psiconv_read_u8(buf,lev+4,off+len,&res); |
540 | submarker = psiconv_read_u8(buf,lev+4,off+len,&res); |
587 | len ++; |
541 | len ++; |
588 | if (res) |
542 | if (res) |
589 | goto ERROR8; |
543 | goto ERROR8; |
|
|
544 | submarker2 = psiconv_read_u8(buf,lev+4,off+len,&res); |
|
|
545 | if (res) |
|
|
546 | goto ERROR8; |
590 | } while (formula_elements[submarker].formula_type |
547 | } while ((formula_elements[submarker].formula_type |
591 | == psiconv_formula_mark_opsep); |
548 | == psiconv_formula_mark_opsep) && |
|
|
549 | (formula_elements[submarker2].formula_type |
|
|
550 | != psiconv_formula_mark_opend)); |
|
|
551 | if ((formula_elements[submarker].formula_type == |
|
|
552 | psiconv_formula_mark_opsep) && |
|
|
553 | (formula_elements[submarker2].formula_type == |
|
|
554 | psiconv_formula_mark_opend)) { |
|
|
555 | submarker=submarker2; |
|
|
556 | len++; |
|
|
557 | } |
592 | if (formula_elements[submarker].formula_type |
558 | if (formula_elements[submarker].formula_type |
593 | != psiconv_formula_mark_opend) { |
559 | != psiconv_formula_mark_opend) { |
594 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
560 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
595 | psiconv_debug(lev+3,off+len,"Found unexpected marker %02x",submarker); |
561 | psiconv_debug(lev+3,off+len,"Found unexpected marker %02x",submarker); |
596 | goto ERROR8; |
562 | goto ERROR8; |