… | |
… | |
46 | {psiconv_formula_op_mul,2,"*"}, |
46 | {psiconv_formula_op_mul,2,"*"}, |
47 | {psiconv_formula_op_div,2,"/"}, |
47 | {psiconv_formula_op_div,2,"/"}, |
48 | {psiconv_formula_op_pow,2,"^"}, |
48 | {psiconv_formula_op_pow,2,"^"}, |
49 | {psiconv_formula_op_pos,1,"+"}, |
49 | {psiconv_formula_op_pos,1,"+"}, |
50 | {psiconv_formula_op_neg,1,"-"}, |
50 | {psiconv_formula_op_neg,1,"-"}, |
51 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
51 | {psiconv_formula_op_not,1,"NOT"}, |
52 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
52 | {psiconv_formula_op_and,2,"AND"}, |
53 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, /* 10 */ |
53 | {psiconv_formula_op_or,2,"OR"}, /* 10 */ |
54 | {psiconv_formula_op_con,2,"&"}, |
54 | {psiconv_formula_op_con,2,"&"}, |
55 | {psiconv_formula_op_bra,1,"{}"}, |
55 | {psiconv_formula_op_bra,1,"()"}, |
56 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
56 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
57 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
57 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
58 | {psiconv_formula_mark_eof,0,"End of formula"}, |
58 | {psiconv_formula_mark_eof,0,"End of formula"}, |
59 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
59 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
60 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
60 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
… | |
… | |
284 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
284 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
285 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
285 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
286 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
286 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
287 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
287 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
288 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
288 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
289 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
|
|
290 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
|
|
291 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
|
|
292 | {psiconv_formula_unknown,0,"*UNKNOWN*"}}; |
289 | {psiconv_formula_unknown,0,"*UNKNOWN*"}}; |
293 | |
|
|
294 | static psiconv_string_t psiconv_read_sheet_string(const psiconv_buffer buf, |
|
|
295 | int lev, |
|
|
296 | psiconv_u32 off,int *length, int *status) |
|
|
297 | { |
|
|
298 | int stringlen,i,len,localstatus; |
|
|
299 | psiconv_string_t result; |
|
|
300 | char *res_copy; |
|
|
301 | |
|
|
302 | psiconv_progress(lev+1,off,"Going to read a sheet string"); |
|
|
303 | |
|
|
304 | stringlen = psiconv_read_u8(buf,lev+2,off,&localstatus); |
|
|
305 | if (localstatus) |
|
|
306 | goto ERROR1; |
|
|
307 | psiconv_debug(lev+2,off,"Length: %i",stringlen); |
|
|
308 | len = 1; |
|
|
309 | |
|
|
310 | result = malloc(stringlen + 1); |
|
|
311 | if (!result) |
|
|
312 | goto ERROR1; |
|
|
313 | for (i = 0; (i < stringlen) && !localstatus; i++) |
|
|
314 | result[i] = psiconv_read_u8(buf,lev,off+i+len,&localstatus); |
|
|
315 | if (localstatus) |
|
|
316 | goto ERROR2; |
|
|
317 | result[stringlen] = 0; |
|
|
318 | len += stringlen; |
|
|
319 | |
|
|
320 | res_copy = psiconv_make_printable(result); |
|
|
321 | if (!res_copy) |
|
|
322 | goto ERROR2; |
|
|
323 | psiconv_debug(lev+2,off,"Contents: `%s'",res_copy); |
|
|
324 | free(res_copy); |
|
|
325 | |
|
|
326 | if (length) |
|
|
327 | *length = len; |
|
|
328 | |
|
|
329 | if (status) |
|
|
330 | *status = 0; |
|
|
331 | |
|
|
332 | psiconv_progress(lev+1,off+len-1,"End of sheet string (total length: %08x)", |
|
|
333 | len); |
|
|
334 | |
|
|
335 | return result; |
|
|
336 | |
|
|
337 | |
|
|
338 | ERROR2: |
|
|
339 | free(result); |
|
|
340 | ERROR1: |
|
|
341 | psiconv_warn(lev+1,off,"Reading of sheet string failed"); |
|
|
342 | if (status) |
|
|
343 | *status = localstatus; |
|
|
344 | if (length) |
|
|
345 | *length = 0; |
|
|
346 | return NULL; |
|
|
347 | } |
|
|
348 | |
|
|
349 | |
290 | |
350 | static int psiconv_parse_sheet_ref(const psiconv_buffer buf,int lev, |
291 | static int psiconv_parse_sheet_ref(const psiconv_buffer buf,int lev, |
351 | psiconv_u32 off, int *length, |
292 | psiconv_u32 off, int *length, |
352 | psiconv_sheet_ref_t *result) |
293 | psiconv_sheet_ref_t *result) |
353 | { |
294 | { |
… | |
… | |
438 | if (length) |
379 | if (length) |
439 | *length = 0; |
380 | *length = 0; |
440 | return res; |
381 | return res; |
441 | } |
382 | } |
442 | |
383 | |
443 | int psiconv_parse_formula(const psiconv_buffer buf, int lev, |
384 | static int psiconv_parse_formula_element_list(const psiconv_buffer buf, int lev, |
444 | psiconv_u32 off, int *length, |
385 | psiconv_u32 off, int *length, |
445 | psiconv_formula *result) |
386 | psiconv_formula *result, |
|
|
387 | psiconv_u32 maxlen) |
446 | { |
388 | { |
447 | int res=0; |
389 | int res=0; |
448 | int len=0; |
390 | int len=0; |
449 | int leng; |
391 | int leng; |
450 | int eof = 0; |
392 | int eof = 0; |
451 | psiconv_u8 marker; |
393 | psiconv_u8 marker,submarker; |
452 | psiconv_u32 bytelen; |
|
|
453 | psiconv_formula_list formula_stack; |
394 | psiconv_formula_list formula_stack; |
454 | psiconv_formula formula,subformula1,subformula2,subformula3,subformula4; |
395 | psiconv_formula formula,subformula,subformula1,subformula2, |
|
|
396 | subformula3,subformula4; |
|
|
397 | psiconv_u16 temp,nr_of_subs; |
455 | |
398 | |
456 | psiconv_progress(lev+1,off,"Going to read a formula"); |
399 | psiconv_progress(lev+1,off,"Going to read a formula element list"); |
457 | if (!(*result = malloc(sizeof(**result)))) |
400 | if (!(*result = malloc(sizeof(**result)))) |
458 | goto ERROR1; |
401 | goto ERROR1; |
459 | if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) |
402 | if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) |
460 | goto ERROR2; |
403 | goto ERROR2; |
461 | if (!(formula = malloc(sizeof(*formula)))) |
404 | if (!(formula = malloc(sizeof(*formula)))) |
… | |
… | |
473 | subformula3->type = psiconv_formula_unknown; |
416 | subformula3->type = psiconv_formula_unknown; |
474 | if (!(subformula4 = malloc(sizeof(*subformula4)))) |
417 | if (!(subformula4 = malloc(sizeof(*subformula4)))) |
475 | goto ERROR7; |
418 | goto ERROR7; |
476 | subformula4->type = psiconv_formula_unknown; |
419 | subformula4->type = psiconv_formula_unknown; |
477 | |
420 | |
478 | psiconv_progress(lev+2,off+len, |
|
|
479 | "Going to read the formula byte length"); |
|
|
480 | bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); |
|
|
481 | if (res) |
|
|
482 | goto ERROR8; |
|
|
483 | psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); |
|
|
484 | len += leng; |
|
|
485 | bytelen += len; |
|
|
486 | |
|
|
487 | psiconv_progress(lev+2,off+len,"Going to read the formula items"); |
|
|
488 | while (!eof && len < bytelen) { |
421 | while (!eof && len+off < maxlen) { |
489 | psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); |
422 | psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); |
490 | marker = psiconv_read_u8(buf,lev+2,off+len,&res); |
423 | marker = psiconv_read_u8(buf,lev+2,off+len,&res); |
491 | if (res) |
424 | if (res) |
492 | goto ERROR8; |
425 | goto ERROR8; |
493 | psiconv_debug(lev+3,off+len,"Marker: %02x (%s)",marker, |
426 | psiconv_debug(lev+3,off+len,"Marker: %02x (%s)",marker, |
… | |
… | |
495 | len ++; |
428 | len ++; |
496 | |
429 | |
497 | if (formula_elements[marker].formula_type == psiconv_formula_unknown) { |
430 | if (formula_elements[marker].formula_type == psiconv_formula_unknown) { |
498 | psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); |
431 | psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); |
499 | goto ERROR8; |
432 | goto ERROR8; |
500 | } else if (formula_elements[marker].formula_type == |
433 | } else if ((formula_elements[marker].formula_type == |
501 | psiconv_formula_mark_eof) { |
434 | psiconv_formula_mark_eof) || |
|
|
435 | (formula_elements[marker].formula_type == |
|
|
436 | psiconv_formula_mark_opend) || |
|
|
437 | (formula_elements[marker].formula_type == |
|
|
438 | psiconv_formula_mark_opsep)) { |
|
|
439 | len--; |
502 | psiconv_progress(lev+3,off+len,"End of formula"); |
440 | psiconv_progress(lev+3,off+len,"End of this formula list"); |
503 | eof = 1; |
441 | eof = 1; |
504 | } else if (formula_elements[marker].formula_type == |
442 | } else if (formula_elements[marker].formula_type == |
505 | psiconv_formula_dat_int) { |
443 | psiconv_formula_dat_int) { |
506 | psiconv_progress(lev+3,off+len,"Next item: an integer"); |
444 | psiconv_progress(lev+3,off+len,"Next item: an integer"); |
507 | formula->data.dat_int = psiconv_read_u32(buf,lev+2,off+len,&res); |
445 | formula->data.dat_int = psiconv_read_u32(buf,lev+2,off+len,&res); |
… | |
… | |
535 | formula->type = formula_elements[marker].formula_type; |
473 | formula->type = formula_elements[marker].formula_type; |
536 | len += leng; |
474 | len += leng; |
537 | if ((res = psiconv_list_add(formula_stack,formula))) |
475 | if ((res = psiconv_list_add(formula_stack,formula))) |
538 | goto ERROR8; |
476 | goto ERROR8; |
539 | formula->type = psiconv_formula_unknown; |
477 | formula->type = psiconv_formula_unknown; |
540 | } else if (formula_elements[marker].formula_type == |
478 | } else if ((formula_elements[marker].formula_type == |
|
|
479 | psiconv_formula_dat_cellblock) || |
|
|
480 | (formula_elements[marker].formula_type == |
541 | psiconv_formula_dat_cellblock) { |
481 | psiconv_formula_dat_vcellblock)) { |
542 | psiconv_progress(lev+3,off+len,"Next item: a cell block"); |
482 | psiconv_progress(lev+3,off+len,"Next item: a cell block"); |
543 | if ((res = psiconv_parse_sheet_cell_block(buf,lev+2,off+len,&leng, |
483 | if ((res = psiconv_parse_sheet_cell_block(buf,lev+2,off+len,&leng, |
544 | &formula->data.dat_cellblock))) |
484 | &formula->data.dat_cellblock))) |
545 | goto ERROR8; |
485 | goto ERROR8; |
546 | formula->type = formula_elements[marker].formula_type; |
486 | formula->type = formula_elements[marker].formula_type; |
… | |
… | |
550 | formula->type = psiconv_formula_unknown; |
490 | formula->type = psiconv_formula_unknown; |
551 | } else if (formula_elements[marker].formula_type == |
491 | } else if (formula_elements[marker].formula_type == |
552 | psiconv_formula_dat_string) { |
492 | psiconv_formula_dat_string) { |
553 | psiconv_progress(lev+3,off+len,"Next item: a string"); |
493 | psiconv_progress(lev+3,off+len,"Next item: a string"); |
554 | formula->data.dat_string = |
494 | formula->data.dat_string = |
555 | psiconv_read_sheet_string(buf,lev+2,off+len,&leng,&res); |
495 | psiconv_read_short_string(buf,lev+2,off+len,&leng,&res); |
556 | if (res) |
496 | if (res) |
557 | goto ERROR8; |
497 | goto ERROR8; |
558 | formula->type = formula_elements[marker].formula_type; |
498 | formula->type = formula_elements[marker].formula_type; |
559 | len += leng; |
499 | len += leng; |
560 | if ((res = psiconv_list_add(formula_stack,formula))) |
500 | if ((res = psiconv_list_add(formula_stack,formula))) |
561 | goto ERROR8; |
501 | goto ERROR8; |
562 | formula->type = psiconv_formula_unknown; |
502 | formula->type = psiconv_formula_unknown; |
563 | } else if ((formula_elements[marker].formula_type == |
503 | } else if ((formula_elements[marker].formula_type == |
564 | psiconv_formula_dat_var) || |
504 | psiconv_formula_dat_var) || |
565 | (formula_elements[marker].formula_type == |
505 | (formula_elements[marker].formula_type == |
566 | psiconv_formula_dat_vcellblock) || |
506 | psiconv_formula_dat_vcellblock)) { |
567 | (formula_elements[marker].formula_type == |
|
|
568 | psiconv_formula_mark_opsep) || |
|
|
569 | (formula_elements[marker].formula_type == |
|
|
570 | psiconv_formula_mark_opend)) { |
|
|
571 | psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); |
507 | psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); |
572 | goto ERROR8; |
508 | goto ERROR8; |
573 | } else if (formula_elements[marker].number_of_args == -1) { |
509 | } else if (formula_elements[marker].number_of_args == -1) { |
574 | psiconv_warn(lev+3,off+len,"Vararg functions not yet supported!"); |
510 | psiconv_progress(lev+3,off+len,"Going to parse a vararg function"); |
|
|
511 | if (!(formula->data.fun_operands = |
|
|
512 | psiconv_list_new(sizeof(*formula)))) |
|
|
513 | goto ERROR8; |
|
|
514 | formula->type = formula_elements[marker].formula_type; |
|
|
515 | nr_of_subs = 0; |
|
|
516 | do { |
|
|
517 | nr_of_subs ++; |
|
|
518 | psiconv_progress(lev+4,off+len,"Going to read vararg argument %d", |
|
|
519 | nr_of_subs); |
|
|
520 | if ((res = psiconv_parse_formula_element_list(buf,lev+4,off+len,&leng, |
|
|
521 | &subformula,maxlen))) |
|
|
522 | goto ERROR8; |
|
|
523 | len += leng; |
|
|
524 | if ((res = psiconv_list_add(formula->data.fun_operands,subformula))) { |
|
|
525 | psiconv_free_formula(subformula); |
|
|
526 | goto ERROR8; |
|
|
527 | } |
|
|
528 | free(subformula); |
|
|
529 | psiconv_progress(lev+4,off+len,"Going to read the next marker"); |
|
|
530 | submarker = psiconv_read_u8(buf,lev+4,off+len,&res); |
|
|
531 | len ++; |
|
|
532 | if (res) |
|
|
533 | goto ERROR8; |
|
|
534 | } while (formula_elements[submarker].formula_type |
|
|
535 | == psiconv_formula_mark_opsep); |
|
|
536 | if (formula_elements[submarker].formula_type |
|
|
537 | != psiconv_formula_mark_opend) { |
|
|
538 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
539 | psiconv_debug(lev+3,off+len,"Found unexpected marker %02x",submarker); |
575 | goto ERROR8; |
540 | goto ERROR8; |
|
|
541 | } |
|
|
542 | psiconv_progress(lev+3,off+len,"Going to read the repeated marker %02x", |
|
|
543 | marker); |
|
|
544 | submarker = psiconv_read_u8(buf,lev+3,off+len,&res); |
|
|
545 | if (res) |
|
|
546 | goto ERROR8; |
|
|
547 | if (submarker != marker) { |
|
|
548 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
549 | psiconv_debug(lev+3,off+len,"Expected marker %02x, found %02x", |
|
|
550 | marker,submarker); |
|
|
551 | goto ERROR8; |
|
|
552 | } |
|
|
553 | len++; |
|
|
554 | psiconv_progress(lev+3,off+len, |
|
|
555 | "Going to read the number of arguments (%d expected)", |
|
|
556 | nr_of_subs); |
|
|
557 | temp = psiconv_read_u16(buf,lev+3,off+len,&res); |
|
|
558 | if (res) |
|
|
559 | goto ERROR8; |
|
|
560 | if (temp != nr_of_subs) { |
|
|
561 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
562 | psiconv_debug(lev+3,off+len, |
|
|
563 | "Read %d arguments, but formula says there are %d", |
|
|
564 | nr_of_subs,temp); |
|
|
565 | goto ERROR8; |
|
|
566 | } |
|
|
567 | len += 2; |
|
|
568 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
569 | goto ERROR8; |
|
|
570 | formula->type = psiconv_formula_unknown; |
576 | } else { |
571 | } else { |
577 | if (formula_elements[marker].number_of_args > 0) |
572 | if (formula_elements[marker].number_of_args > 0) |
578 | if ((res = psiconv_list_pop(formula_stack,subformula1))) |
573 | if ((res = psiconv_list_pop(formula_stack,subformula1))) |
579 | goto ERROR8; |
574 | goto ERROR8; |
580 | if (formula_elements[marker].number_of_args > 1) |
575 | if (formula_elements[marker].number_of_args > 1) |
… | |
… | |
606 | goto ERROR8; |
601 | goto ERROR8; |
607 | subformula4->type = subformula3->type = subformula2->type = |
602 | subformula4->type = subformula3->type = subformula2->type = |
608 | subformula1->type = formula->type = psiconv_formula_unknown; |
603 | subformula1->type = formula->type = psiconv_formula_unknown; |
609 | } |
604 | } |
610 | } |
605 | } |
611 | if ((len != bytelen) || !eof) { |
606 | if ((len+off > maxlen) || !eof) { |
612 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
607 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
613 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
608 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
614 | bytelen,len); |
609 | maxlen,len+off); |
615 | goto ERROR8; |
610 | goto ERROR8; |
616 | } |
611 | } |
617 | if ((psiconv_list_length(formula_stack)) != 1) { |
612 | if ((psiconv_list_length(formula_stack)) != 1) { |
618 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
613 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
619 | psiconv_debug(lev+2,off+len,"More than one item left on the stack (%d)", |
614 | psiconv_debug(lev+2,off+len,"More than one item left on the stack (%d)", |
… | |
… | |
627 | |
622 | |
628 | if (length) |
623 | if (length) |
629 | *length = len; |
624 | *length = len; |
630 | |
625 | |
631 | psiconv_progress(lev,off+len-1, |
626 | psiconv_progress(lev,off+len-1, |
632 | "End of formula (total length: %08x)", len); |
627 | "End of formula element list (total length: %08x)", len); |
633 | return 0; |
628 | return 0; |
634 | |
629 | |
635 | ERROR8: |
630 | ERROR8: |
636 | psiconv_free_formula(subformula4); |
631 | psiconv_free_formula(subformula4); |
637 | ERROR7: |
632 | ERROR7: |
… | |
… | |
645 | ERROR3: |
640 | ERROR3: |
646 | psiconv_free_formula_list(formula_stack); |
641 | psiconv_free_formula_list(formula_stack); |
647 | ERROR2: |
642 | ERROR2: |
648 | free (*result); |
643 | free (*result); |
649 | ERROR1: |
644 | ERROR1: |
650 | psiconv_warn(lev+1,off,"Reading of formula failed"); |
645 | psiconv_warn(lev+1,off,"Reading of formula element list failed"); |
651 | if (length) |
646 | if (length) |
652 | *length = 0; |
647 | *length = 0; |
653 | if (!res) |
648 | if (!res) |
654 | return -PSICONV_E_NOMEM; |
649 | return -PSICONV_E_NOMEM; |
655 | else |
650 | else |
656 | return res; |
651 | return res; |
657 | } |
652 | } |
658 | |
653 | |
|
|
654 | |
|
|
655 | |
|
|
656 | |
|
|
657 | int psiconv_parse_formula(const psiconv_buffer buf, int lev, |
|
|
658 | psiconv_u32 off, int *length, |
|
|
659 | psiconv_formula *result) |
|
|
660 | { |
|
|
661 | int res=0; |
|
|
662 | int len=0; |
|
|
663 | int leng; |
|
|
664 | psiconv_u32 bytelen,formula_end; |
|
|
665 | psiconv_u8 temp; |
|
|
666 | |
|
|
667 | psiconv_progress(lev+1,off,"Going to read a formula"); |
|
|
668 | |
|
|
669 | psiconv_progress(lev+2,off+len, |
|
|
670 | "Going to read the formula byte length"); |
|
|
671 | bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); |
|
|
672 | if (res) |
|
|
673 | goto ERROR1; |
|
|
674 | psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); |
|
|
675 | len += leng; |
|
|
676 | bytelen += len; |
|
|
677 | formula_end = off + bytelen; |
|
|
678 | |
|
|
679 | psiconv_progress(lev+2,off+len,"Going to read the formula elements list"); |
|
|
680 | if ((res = psiconv_parse_formula_element_list(buf,lev+2,off+len,&leng, |
|
|
681 | result,formula_end))) |
|
|
682 | goto ERROR1; |
|
|
683 | len += leng; |
|
|
684 | |
|
|
685 | psiconv_progress(lev+2,off+len,"Going to read the eof marker"); |
|
|
686 | temp = psiconv_read_u8(buf,lev+2,off+len,&res); |
|
|
687 | if (res) |
|
|
688 | goto ERROR2; |
|
|
689 | if (formula_elements[temp].formula_type != psiconv_formula_mark_eof) { |
|
|
690 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
|
|
691 | psiconv_debug(lev+2,off+len,"Expected marker: %02x, found byte: %02x", |
|
|
692 | 0x15,temp); |
|
|
693 | goto ERROR2; |
|
|
694 | } |
|
|
695 | len ++; |
|
|
696 | |
|
|
697 | if (off+len != formula_end) { |
|
|
698 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
|
|
699 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
|
|
700 | formula_end,len+off); |
|
|
701 | goto ERROR2; |
|
|
702 | } |
|
|
703 | |
|
|
704 | if (length) |
|
|
705 | *length = len; |
|
|
706 | |
|
|
707 | psiconv_progress(lev,off+len-1, |
|
|
708 | "End of formula (total length: %08x)", len); |
|
|
709 | return 0; |
|
|
710 | |
|
|
711 | ERROR2: |
|
|
712 | psiconv_free_formula(*result); |
|
|
713 | ERROR1: |
|
|
714 | psiconv_warn(lev+1,off,"Reading of formula failed"); |
|
|
715 | if (length) |
|
|
716 | *length = 0; |
|
|
717 | if (!res) |
|
|
718 | return -PSICONV_E_NOMEM; |
|
|
719 | else |
|
|
720 | return res; |
|
|
721 | } |
|
|
722 | |
|
|
723 | |