… | |
… | |
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; |
… | |
… | |
46 | {psiconv_formula_op_mul,2,"*"}, |
51 | {psiconv_formula_op_mul,2,"*"}, |
47 | {psiconv_formula_op_div,2,"/"}, |
52 | {psiconv_formula_op_div,2,"/"}, |
48 | {psiconv_formula_op_pow,2,"^"}, |
53 | {psiconv_formula_op_pow,2,"^"}, |
49 | {psiconv_formula_op_pos,1,"+"}, |
54 | {psiconv_formula_op_pos,1,"+"}, |
50 | {psiconv_formula_op_neg,1,"-"}, |
55 | {psiconv_formula_op_neg,1,"-"}, |
51 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
56 | {psiconv_formula_op_not,1,"NOT"}, |
52 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
57 | {psiconv_formula_op_and,2,"AND"}, |
53 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, /* 10 */ |
58 | {psiconv_formula_op_or,2,"OR"}, /* 10 */ |
54 | {psiconv_formula_op_con,2,"&"}, |
59 | {psiconv_formula_op_con,2,"&"}, |
55 | {psiconv_formula_op_bra,1,"{}"}, |
60 | {psiconv_formula_op_bra,1,"()"}, |
56 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
61 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
57 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
62 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
58 | {psiconv_formula_mark_eof,0,"End of formula"}, |
63 | {psiconv_formula_mark_eof,0,"End of formula"}, |
59 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
64 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
60 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
65 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
… | |
… | |
284 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
289 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
285 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
290 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
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*"}, |
|
|
290 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
|
|
291 | {psiconv_formula_unknown,0,"*UNKNOWN*"}, |
|
|
292 | {psiconv_formula_unknown,0,"*UNKNOWN*"}}; |
294 | {psiconv_formula_unknown,0,"*UNKNOWN*"}}; |
293 | |
|
|
294 | |
295 | |
295 | 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, |
296 | psiconv_u32 off, int *length, |
297 | psiconv_u32 off, int *length, |
297 | psiconv_sheet_ref_t *result) |
298 | psiconv_sheet_ref_t *result) |
298 | { |
299 | { |
… | |
… | |
383 | if (length) |
384 | if (length) |
384 | *length = 0; |
385 | *length = 0; |
385 | return res; |
386 | return res; |
386 | } |
387 | } |
387 | |
388 | |
388 | int psiconv_parse_formula(const psiconv_buffer buf, int lev, |
389 | static int psiconv_parse_formula_element_list(const psiconv_buffer buf, int lev, |
389 | psiconv_u32 off, int *length, |
390 | psiconv_u32 off, int *length, |
390 | psiconv_formula *result) |
391 | psiconv_formula *result, |
|
|
392 | psiconv_u32 maxlen) |
391 | { |
393 | { |
392 | int res=0; |
394 | int res=0; |
393 | int len=0; |
395 | int len=0; |
394 | int leng; |
396 | int leng; |
395 | int eof = 0; |
397 | int eof = 0; |
396 | psiconv_u8 marker; |
398 | psiconv_u8 marker,submarker,submarker2; |
397 | psiconv_u32 bytelen; |
|
|
398 | psiconv_formula_list formula_stack; |
399 | psiconv_formula_list formula_stack; |
399 | psiconv_formula formula,subformula1,subformula2,subformula3,subformula4; |
400 | psiconv_formula formula,subformula,subformula1,subformula2, |
|
|
401 | subformula3,subformula4; |
|
|
402 | psiconv_u16 temp,nr_of_subs; |
400 | |
403 | |
401 | psiconv_progress(lev+1,off,"Going to read a formula"); |
404 | psiconv_progress(lev+1,off,"Going to read a formula element list"); |
402 | if (!(*result = malloc(sizeof(**result)))) |
405 | if (!(*result = malloc(sizeof(**result)))) |
403 | goto ERROR1; |
406 | goto ERROR1; |
404 | if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) |
407 | if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) |
405 | goto ERROR2; |
408 | goto ERROR2; |
406 | if (!(formula = malloc(sizeof(*formula)))) |
409 | if (!(formula = malloc(sizeof(*formula)))) |
… | |
… | |
418 | subformula3->type = psiconv_formula_unknown; |
421 | subformula3->type = psiconv_formula_unknown; |
419 | if (!(subformula4 = malloc(sizeof(*subformula4)))) |
422 | if (!(subformula4 = malloc(sizeof(*subformula4)))) |
420 | goto ERROR7; |
423 | goto ERROR7; |
421 | subformula4->type = psiconv_formula_unknown; |
424 | subformula4->type = psiconv_formula_unknown; |
422 | |
425 | |
423 | psiconv_progress(lev+2,off+len, |
|
|
424 | "Going to read the formula byte length"); |
|
|
425 | bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); |
|
|
426 | if (res) |
|
|
427 | goto ERROR8; |
|
|
428 | psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); |
|
|
429 | len += leng; |
|
|
430 | bytelen += len; |
|
|
431 | |
|
|
432 | psiconv_progress(lev+2,off+len,"Going to read the formula items"); |
|
|
433 | while (!eof && len < bytelen) { |
426 | while (!eof && len+off < maxlen) { |
434 | psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); |
427 | psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); |
435 | marker = psiconv_read_u8(buf,lev+2,off+len,&res); |
428 | marker = psiconv_read_u8(buf,lev+2,off+len,&res); |
436 | if (res) |
429 | if (res) |
437 | goto ERROR8; |
430 | goto ERROR8; |
438 | psiconv_debug(lev+3,off+len,"Marker: %02x (%s)",marker, |
431 | psiconv_debug(lev+3,off+len,"Marker: %02x (%s)",marker, |
… | |
… | |
440 | len ++; |
433 | len ++; |
441 | |
434 | |
442 | if (formula_elements[marker].formula_type == psiconv_formula_unknown) { |
435 | if (formula_elements[marker].formula_type == psiconv_formula_unknown) { |
443 | psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); |
436 | psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); |
444 | goto ERROR8; |
437 | goto ERROR8; |
445 | } else if (formula_elements[marker].formula_type == |
438 | } else if ((formula_elements[marker].formula_type == |
446 | psiconv_formula_mark_eof) { |
439 | psiconv_formula_mark_eof) || |
|
|
440 | (formula_elements[marker].formula_type == |
|
|
441 | psiconv_formula_mark_opend) || |
|
|
442 | (formula_elements[marker].formula_type == |
|
|
443 | psiconv_formula_mark_opsep)) { |
|
|
444 | len--; |
447 | psiconv_progress(lev+3,off+len,"End of formula"); |
445 | psiconv_progress(lev+3,off+len,"End of this formula list"); |
448 | eof = 1; |
446 | eof = 1; |
449 | } else if (formula_elements[marker].formula_type == |
447 | } else if (formula_elements[marker].formula_type == |
450 | psiconv_formula_dat_int) { |
448 | psiconv_formula_dat_int) { |
451 | psiconv_progress(lev+3,off+len,"Next item: an integer"); |
449 | psiconv_progress(lev+3,off+len,"Next item: an integer"); |
452 | formula->data.dat_int = psiconv_read_u32(buf,lev+2,off+len,&res); |
450 | formula->data.dat_int = psiconv_read_u32(buf,lev+2,off+len,&res); |
… | |
… | |
480 | formula->type = formula_elements[marker].formula_type; |
478 | formula->type = formula_elements[marker].formula_type; |
481 | len += leng; |
479 | len += leng; |
482 | if ((res = psiconv_list_add(formula_stack,formula))) |
480 | if ((res = psiconv_list_add(formula_stack,formula))) |
483 | goto ERROR8; |
481 | goto ERROR8; |
484 | formula->type = psiconv_formula_unknown; |
482 | formula->type = psiconv_formula_unknown; |
485 | } else if (formula_elements[marker].formula_type == |
483 | } else if ((formula_elements[marker].formula_type == |
|
|
484 | psiconv_formula_dat_cellblock) || |
|
|
485 | (formula_elements[marker].formula_type == |
486 | psiconv_formula_dat_cellblock) { |
486 | psiconv_formula_dat_vcellblock)) { |
487 | psiconv_progress(lev+3,off+len,"Next item: a cell block"); |
487 | psiconv_progress(lev+3,off+len,"Next item: a cell block"); |
488 | if ((res = psiconv_parse_sheet_cell_block(buf,lev+2,off+len,&leng, |
488 | if ((res = psiconv_parse_sheet_cell_block(buf,lev+2,off+len,&leng, |
489 | &formula->data.dat_cellblock))) |
489 | &formula->data.dat_cellblock))) |
490 | goto ERROR8; |
490 | goto ERROR8; |
491 | formula->type = formula_elements[marker].formula_type; |
491 | formula->type = formula_elements[marker].formula_type; |
492 | len += leng; |
492 | len += leng; |
493 | if ((res = psiconv_list_add(formula_stack,formula))) |
493 | if ((res = psiconv_list_add(formula_stack,formula))) |
494 | goto ERROR8; |
494 | goto ERROR8; |
495 | formula->type = psiconv_formula_unknown; |
495 | formula->type = psiconv_formula_unknown; |
|
|
496 | } else if (formula_elements[marker].formula_type == |
|
|
497 | psiconv_formula_dat_string) { |
|
|
498 | psiconv_progress(lev+3,off+len,"Next item: a string"); |
|
|
499 | formula->data.dat_string = |
|
|
500 | psiconv_read_short_string(buf,lev+2,off+len,&leng,&res); |
|
|
501 | if (res) |
|
|
502 | goto ERROR8; |
|
|
503 | formula->type = formula_elements[marker].formula_type; |
|
|
504 | len += leng; |
|
|
505 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
506 | goto ERROR8; |
|
|
507 | formula->type = psiconv_formula_unknown; |
496 | } else if ((formula_elements[marker].formula_type == |
508 | } else if ((formula_elements[marker].formula_type == |
497 | psiconv_formula_dat_var) || |
509 | psiconv_formula_dat_var)) { |
498 | (formula_elements[marker].formula_type == |
510 | psiconv_progress(lev+3,off+len,"Next item: a variable reference"); |
499 | psiconv_formula_dat_string) || |
511 | formula->data.dat_variable = psiconv_read_u32(buf,lev+2,off+len,&res); |
500 | (formula_elements[marker].formula_type == |
512 | if (res) |
501 | psiconv_formula_dat_vcellblock) || |
|
|
502 | (formula_elements[marker].formula_type == |
|
|
503 | psiconv_formula_mark_opsep) || |
|
|
504 | (formula_elements[marker].formula_type == |
|
|
505 | psiconv_formula_mark_opend)) { |
|
|
506 | psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); |
|
|
507 | 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; |
508 | } else if (formula_elements[marker].number_of_args == -1) { |
519 | } else if (formula_elements[marker].number_of_args == -1) { |
509 | psiconv_warn(lev+3,off+len,"Vararg functions not yet supported!"); |
520 | psiconv_progress(lev+3,off+len,"Going to parse a vararg function"); |
|
|
521 | if (!(formula->data.fun_operands = |
|
|
522 | psiconv_list_new(sizeof(*formula)))) |
|
|
523 | goto ERROR8; |
|
|
524 | formula->type = formula_elements[marker].formula_type; |
|
|
525 | nr_of_subs = 0; |
|
|
526 | do { |
|
|
527 | nr_of_subs ++; |
|
|
528 | psiconv_progress(lev+4,off+len,"Going to read vararg argument %d", |
|
|
529 | nr_of_subs); |
|
|
530 | if ((res = psiconv_parse_formula_element_list(buf,lev+4,off+len,&leng, |
|
|
531 | &subformula,maxlen))) |
|
|
532 | goto ERROR8; |
|
|
533 | len += leng; |
|
|
534 | if ((res = psiconv_list_add(formula->data.fun_operands,subformula))) { |
|
|
535 | psiconv_free_formula(subformula); |
|
|
536 | goto ERROR8; |
|
|
537 | } |
|
|
538 | free(subformula); |
|
|
539 | psiconv_progress(lev+4,off+len,"Going to read the next marker"); |
|
|
540 | submarker = psiconv_read_u8(buf,lev+4,off+len,&res); |
|
|
541 | len ++; |
|
|
542 | if (res) |
|
|
543 | goto ERROR8; |
|
|
544 | submarker2 = psiconv_read_u8(buf,lev+4,off+len,&res); |
|
|
545 | if (res) |
|
|
546 | goto ERROR8; |
|
|
547 | } while ((formula_elements[submarker].formula_type |
|
|
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 | } |
|
|
558 | if (formula_elements[submarker].formula_type |
|
|
559 | != psiconv_formula_mark_opend) { |
|
|
560 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
561 | psiconv_debug(lev+3,off+len,"Found unexpected marker %02x",submarker); |
510 | goto ERROR8; |
562 | goto ERROR8; |
|
|
563 | } |
|
|
564 | psiconv_progress(lev+3,off+len,"Going to read the repeated marker %02x", |
|
|
565 | marker); |
|
|
566 | submarker = psiconv_read_u8(buf,lev+3,off+len,&res); |
|
|
567 | if (res) |
|
|
568 | goto ERROR8; |
|
|
569 | if (submarker != marker) { |
|
|
570 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
571 | psiconv_debug(lev+3,off+len,"Expected marker %02x, found %02x", |
|
|
572 | marker,submarker); |
|
|
573 | goto ERROR8; |
|
|
574 | } |
|
|
575 | len++; |
|
|
576 | psiconv_progress(lev+3,off+len, |
|
|
577 | "Going to read the number of arguments (%d expected)", |
|
|
578 | nr_of_subs); |
|
|
579 | temp = psiconv_read_u16(buf,lev+3,off+len,&res); |
|
|
580 | if (res) |
|
|
581 | goto ERROR8; |
|
|
582 | if (temp != nr_of_subs) { |
|
|
583 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
584 | psiconv_debug(lev+3,off+len, |
|
|
585 | "Read %d arguments, but formula says there are %d", |
|
|
586 | nr_of_subs,temp); |
|
|
587 | goto ERROR8; |
|
|
588 | } |
|
|
589 | len += 2; |
|
|
590 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
591 | goto ERROR8; |
|
|
592 | formula->type = psiconv_formula_unknown; |
511 | } else { |
593 | } else { |
512 | if (formula_elements[marker].number_of_args > 0) |
594 | if (formula_elements[marker].number_of_args > 0) |
513 | if ((res = psiconv_list_pop(formula_stack,subformula1))) |
595 | if ((res = psiconv_list_pop(formula_stack,subformula1))) |
514 | goto ERROR8; |
596 | goto ERROR8; |
515 | if (formula_elements[marker].number_of_args > 1) |
597 | if (formula_elements[marker].number_of_args > 1) |
… | |
… | |
541 | goto ERROR8; |
623 | goto ERROR8; |
542 | subformula4->type = subformula3->type = subformula2->type = |
624 | subformula4->type = subformula3->type = subformula2->type = |
543 | subformula1->type = formula->type = psiconv_formula_unknown; |
625 | subformula1->type = formula->type = psiconv_formula_unknown; |
544 | } |
626 | } |
545 | } |
627 | } |
546 | if ((len != bytelen) || !eof) { |
628 | if ((len+off > maxlen) || !eof) { |
547 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
629 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
548 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
630 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
549 | bytelen,len); |
631 | maxlen,len+off); |
550 | goto ERROR8; |
632 | goto ERROR8; |
551 | } |
633 | } |
552 | if ((psiconv_list_length(formula_stack)) != 1) { |
634 | if ((psiconv_list_length(formula_stack)) != 1) { |
553 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
635 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
554 | psiconv_debug(lev+2,off+len,"More than one item left on the stack (%d)", |
636 | psiconv_debug(lev+2,off+len,"More than one item left on the stack (%d)", |
… | |
… | |
562 | |
644 | |
563 | if (length) |
645 | if (length) |
564 | *length = len; |
646 | *length = len; |
565 | |
647 | |
566 | psiconv_progress(lev,off+len-1, |
648 | psiconv_progress(lev,off+len-1, |
567 | "End of formula (total length: %08x)", len); |
649 | "End of formula element list (total length: %08x)", len); |
568 | return 0; |
650 | return 0; |
569 | |
651 | |
570 | ERROR8: |
652 | ERROR8: |
571 | psiconv_free_formula(subformula4); |
653 | psiconv_free_formula(subformula4); |
572 | ERROR7: |
654 | ERROR7: |
… | |
… | |
580 | ERROR3: |
662 | ERROR3: |
581 | psiconv_free_formula_list(formula_stack); |
663 | psiconv_free_formula_list(formula_stack); |
582 | ERROR2: |
664 | ERROR2: |
583 | free (*result); |
665 | free (*result); |
584 | ERROR1: |
666 | ERROR1: |
585 | psiconv_warn(lev+1,off,"Reading of formula failed"); |
667 | psiconv_warn(lev+1,off,"Reading of formula element list failed"); |
586 | if (length) |
668 | if (length) |
587 | *length = 0; |
669 | *length = 0; |
588 | if (!res) |
670 | if (!res) |
589 | return -PSICONV_E_NOMEM; |
671 | return -PSICONV_E_NOMEM; |
590 | else |
672 | else |
591 | return res; |
673 | return res; |
592 | } |
674 | } |
593 | |
675 | |
|
|
676 | |
|
|
677 | |
|
|
678 | |
|
|
679 | int psiconv_parse_formula(const psiconv_buffer buf, int lev, |
|
|
680 | psiconv_u32 off, int *length, |
|
|
681 | psiconv_formula *result) |
|
|
682 | { |
|
|
683 | int res=0; |
|
|
684 | int len=0; |
|
|
685 | int leng; |
|
|
686 | psiconv_u32 bytelen,formula_end; |
|
|
687 | psiconv_u8 temp; |
|
|
688 | |
|
|
689 | psiconv_progress(lev+1,off,"Going to read a formula"); |
|
|
690 | |
|
|
691 | psiconv_progress(lev+2,off+len, |
|
|
692 | "Going to read the formula byte length"); |
|
|
693 | bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); |
|
|
694 | if (res) |
|
|
695 | goto ERROR1; |
|
|
696 | psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); |
|
|
697 | len += leng; |
|
|
698 | bytelen += len; |
|
|
699 | formula_end = off + bytelen; |
|
|
700 | |
|
|
701 | psiconv_progress(lev+2,off+len,"Going to read the formula elements list"); |
|
|
702 | if ((res = psiconv_parse_formula_element_list(buf,lev+2,off+len,&leng, |
|
|
703 | result,formula_end))) |
|
|
704 | goto ERROR1; |
|
|
705 | len += leng; |
|
|
706 | |
|
|
707 | psiconv_progress(lev+2,off+len,"Going to read the eof marker"); |
|
|
708 | temp = psiconv_read_u8(buf,lev+2,off+len,&res); |
|
|
709 | if (res) |
|
|
710 | goto ERROR2; |
|
|
711 | if (formula_elements[temp].formula_type != psiconv_formula_mark_eof) { |
|
|
712 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
|
|
713 | psiconv_debug(lev+2,off+len,"Expected marker: %02x, found byte: %02x", |
|
|
714 | 0x15,temp); |
|
|
715 | goto ERROR2; |
|
|
716 | } |
|
|
717 | len ++; |
|
|
718 | |
|
|
719 | if (off+len != formula_end) { |
|
|
720 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
|
|
721 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
|
|
722 | formula_end,len+off); |
|
|
723 | goto ERROR2; |
|
|
724 | } |
|
|
725 | |
|
|
726 | if (length) |
|
|
727 | *length = len; |
|
|
728 | |
|
|
729 | psiconv_progress(lev,off+len-1, |
|
|
730 | "End of formula (total length: %08x)", len); |
|
|
731 | return 0; |
|
|
732 | |
|
|
733 | ERROR2: |
|
|
734 | psiconv_free_formula(*result); |
|
|
735 | ERROR1: |
|
|
736 | psiconv_warn(lev+1,off,"Reading of formula failed"); |
|
|
737 | if (length) |
|
|
738 | *length = 0; |
|
|
739 | if (!res) |
|
|
740 | return -PSICONV_E_NOMEM; |
|
|
741 | else |
|
|
742 | return res; |
|
|
743 | } |
|
|
744 | |
|
|
745 | |