--- psiconv/trunk/lib/psiconv/parse_formula.c 2001/02/02 21:07:11 105 +++ psiconv/trunk/lib/psiconv/parse_formula.c 2002/01/29 18:38:38 142 @@ -25,6 +25,11 @@ #include "parse_routines.h" #include "error.h" +#ifdef DMALLOC +#include +#endif + + struct formula_element { psiconv_formula_type_t formula_type; @@ -48,11 +53,11 @@ {psiconv_formula_op_pow,2,"^"}, {psiconv_formula_op_pos,1,"+"}, {psiconv_formula_op_neg,1,"-"}, - {psiconv_formula_unknown,0,"*UNKNOWN*"}, - {psiconv_formula_unknown,0,"*UNKNOWN*"}, - {psiconv_formula_unknown,0,"*UNKNOWN*"}, /* 10 */ + {psiconv_formula_op_not,1,"NOT"}, + {psiconv_formula_op_and,2,"AND"}, + {psiconv_formula_op_or,2,"OR"}, /* 10 */ {psiconv_formula_op_con,2,"&"}, - {psiconv_formula_op_bra,1,"{}"}, + {psiconv_formula_op_bra,1,"()"}, {psiconv_formula_unknown,0,"*UNKNOWN*"}, {psiconv_formula_unknown,0,"*UNKNOWN*"}, {psiconv_formula_mark_eof,0,"End of formula"}, @@ -286,67 +291,8 @@ {psiconv_formula_unknown,0,"*UNKNOWN*"}, {psiconv_formula_unknown,0,"*UNKNOWN*"}, {psiconv_formula_unknown,0,"*UNKNOWN*"}, - {psiconv_formula_unknown,0,"*UNKNOWN*"}, - {psiconv_formula_unknown,0,"*UNKNOWN*"}, - {psiconv_formula_unknown,0,"*UNKNOWN*"}, {psiconv_formula_unknown,0,"*UNKNOWN*"}}; -static psiconv_string_t psiconv_read_sheet_string(const psiconv_buffer buf, - int lev, - psiconv_u32 off,int *length, int *status) -{ - int stringlen,i,len,localstatus; - psiconv_string_t result; - char *res_copy; - - psiconv_progress(lev+1,off,"Going to read a sheet string"); - - stringlen = psiconv_read_u8(buf,lev+2,off,&localstatus); - if (localstatus) - goto ERROR1; - psiconv_debug(lev+2,off,"Length: %i",stringlen); - len = 1; - - result = malloc(stringlen + 1); - if (!result) - goto ERROR1; - for (i = 0; (i < stringlen) && !localstatus; i++) - result[i] = psiconv_read_u8(buf,lev,off+i+len,&localstatus); - if (localstatus) - goto ERROR2; - result[stringlen] = 0; - len += stringlen; - - res_copy = psiconv_make_printable(result); - if (!res_copy) - goto ERROR2; - psiconv_debug(lev+2,off,"Contents: `%s'",res_copy); - free(res_copy); - - if (length) - *length = len; - - if (status) - *status = 0; - - psiconv_progress(lev+1,off+len-1,"End of sheet string (total length: %08x)", - len); - - return result; - - -ERROR2: - free(result); -ERROR1: - psiconv_warn(lev+1,off,"Reading of sheet string failed"); - if (status) - *status = localstatus; - if (length) - *length = 0; - return NULL; -} - - static int psiconv_parse_sheet_ref(const psiconv_buffer buf,int lev, psiconv_u32 off, int *length, psiconv_sheet_ref_t *result) @@ -449,9 +395,11 @@ int len=0; int leng; int eof = 0; - psiconv_u8 marker; + psiconv_u8 marker,submarker,submarker2; psiconv_formula_list formula_stack; - psiconv_formula formula,subformula1,subformula2,subformula3,subformula4; + psiconv_formula formula,subformula,subformula1,subformula2, + subformula3,subformula4; + psiconv_u16 temp,nr_of_subs; psiconv_progress(lev+1,off,"Going to read a formula element list"); if (!(*result = malloc(sizeof(**result)))) @@ -532,8 +480,10 @@ if ((res = psiconv_list_add(formula_stack,formula))) goto ERROR8; formula->type = psiconv_formula_unknown; - } else if (formula_elements[marker].formula_type == - psiconv_formula_dat_cellblock) { + } else if ((formula_elements[marker].formula_type == + psiconv_formula_dat_cellblock) || + (formula_elements[marker].formula_type == + psiconv_formula_dat_vcellblock)) { psiconv_progress(lev+3,off+len,"Next item: a cell block"); if ((res = psiconv_parse_sheet_cell_block(buf,lev+2,off+len,&leng, &formula->data.dat_cellblock))) @@ -547,7 +497,7 @@ psiconv_formula_dat_string) { psiconv_progress(lev+3,off+len,"Next item: a string"); formula->data.dat_string = - psiconv_read_sheet_string(buf,lev+2,off+len,&leng,&res); + psiconv_read_short_string(buf,lev+2,off+len,&leng,&res); if (res) goto ERROR8; formula->type = formula_elements[marker].formula_type; @@ -556,14 +506,90 @@ goto ERROR8; formula->type = psiconv_formula_unknown; } else if ((formula_elements[marker].formula_type == - psiconv_formula_dat_var) || - (formula_elements[marker].formula_type == - psiconv_formula_dat_vcellblock)) { - psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); - goto ERROR8; + psiconv_formula_dat_var)) { + psiconv_progress(lev+3,off+len,"Next item: a variable reference"); + formula->data.dat_variable = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR8; + formula->type = formula_elements[marker].formula_type; + len += 4; + if ((res = psiconv_list_add(formula_stack,formula))) + goto ERROR8; + formula->type = psiconv_formula_unknown; } else if (formula_elements[marker].number_of_args == -1) { - psiconv_warn(lev+3,off+len,"Vararg functions not yet supported!"); - goto ERROR8; + psiconv_progress(lev+3,off+len,"Going to parse a vararg function"); + if (!(formula->data.fun_operands = + psiconv_list_new(sizeof(*formula)))) + goto ERROR8; + formula->type = formula_elements[marker].formula_type; + nr_of_subs = 0; + do { + nr_of_subs ++; + psiconv_progress(lev+4,off+len,"Going to read vararg argument %d", + nr_of_subs); + if ((res = psiconv_parse_formula_element_list(buf,lev+4,off+len,&leng, + &subformula,maxlen))) + goto ERROR8; + len += leng; + if ((res = psiconv_list_add(formula->data.fun_operands,subformula))) { + psiconv_free_formula(subformula); + goto ERROR8; + } + free(subformula); + psiconv_progress(lev+4,off+len,"Going to read the next marker"); + submarker = psiconv_read_u8(buf,lev+4,off+len,&res); + len ++; + if (res) + goto ERROR8; + submarker2 = psiconv_read_u8(buf,lev+4,off+len,&res); + if (res) + goto ERROR8; + } while ((formula_elements[submarker].formula_type + == psiconv_formula_mark_opsep) && + (formula_elements[submarker2].formula_type + != psiconv_formula_mark_opend)); + if ((formula_elements[submarker].formula_type == + psiconv_formula_mark_opsep) && + (formula_elements[submarker2].formula_type == + psiconv_formula_mark_opend)) { + submarker=submarker2; + len++; + } + if (formula_elements[submarker].formula_type + != psiconv_formula_mark_opend) { + psiconv_warn(lev+3,off+len,"Formula corrupted!"); + psiconv_debug(lev+3,off+len,"Found unexpected marker %02x",submarker); + goto ERROR8; + } + psiconv_progress(lev+3,off+len,"Going to read the repeated marker %02x", + marker); + submarker = psiconv_read_u8(buf,lev+3,off+len,&res); + if (res) + goto ERROR8; + if (submarker != marker) { + psiconv_warn(lev+3,off+len,"Formula corrupted!"); + psiconv_debug(lev+3,off+len,"Expected marker %02x, found %02x", + marker,submarker); + goto ERROR8; + } + len++; + psiconv_progress(lev+3,off+len, + "Going to read the number of arguments (%d expected)", + nr_of_subs); + temp = psiconv_read_u16(buf,lev+3,off+len,&res); + if (res) + goto ERROR8; + if (temp != nr_of_subs) { + psiconv_warn(lev+3,off+len,"Formula corrupted!"); + psiconv_debug(lev+3,off+len, + "Read %d arguments, but formula says there are %d", + nr_of_subs,temp); + goto ERROR8; + } + len += 2; + if ((res = psiconv_list_add(formula_stack,formula))) + goto ERROR8; + formula->type = psiconv_formula_unknown; } else { if (formula_elements[marker].number_of_args > 0) if ((res = psiconv_list_pop(formula_stack,subformula1)))