… | |
… | |
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 | |
290 | |
|
|
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 | |
294 | int psiconv_parse_formula(const psiconv_buffer buf, int lev, |
347 | static int psiconv_parse_sheet_ref(const psiconv_buffer buf,int lev, |
295 | psiconv_u32 off, int *length, |
348 | psiconv_u32 off, int *length, |
|
|
349 | psiconv_sheet_ref_t *result) |
|
|
350 | { |
|
|
351 | int res; |
|
|
352 | psiconv_u16 temp; |
|
|
353 | |
|
|
354 | psiconv_progress(lev+1,off,"Going to read a sheet ref"); |
|
|
355 | psiconv_progress(lev+2,off,"Going to read the offset encoding"); |
|
|
356 | temp = psiconv_read_u16(buf,lev+2,off,&res); |
|
|
357 | if (res) { |
|
|
358 | if (length) |
|
|
359 | *length = 0; |
|
|
360 | return res; |
|
|
361 | } |
|
|
362 | psiconv_debug(lev+2,off,"Encoded word: %04x",temp); |
|
|
363 | result->absolute = (temp & 0x4000)?psiconv_bool_true:psiconv_bool_false; |
|
|
364 | result->offset = (temp & 0x3fff) * ((temp & 0x8000)?-1:1); |
|
|
365 | psiconv_debug(lev+2,off,"Reference: %s offset %d", |
|
|
366 | result->absolute?"absolute":"relative",result->offset); |
|
|
367 | if (length) |
|
|
368 | *length = 2; |
|
|
369 | return 0; |
|
|
370 | } |
|
|
371 | |
|
|
372 | static int psiconv_parse_sheet_cell_reference(const psiconv_buffer buf,int lev, |
|
|
373 | psiconv_u32 off, int *length, |
|
|
374 | psiconv_sheet_cell_reference_t *result) |
|
|
375 | { |
|
|
376 | int len = 0; |
|
|
377 | int leng,res; |
|
|
378 | psiconv_u8 temp; |
|
|
379 | |
|
|
380 | psiconv_progress(lev+1,off+len,"Going to read a sheet cell reference"); |
|
|
381 | psiconv_progress(lev+2,off+len,"Going to read the row reference"); |
|
|
382 | if ((res = psiconv_parse_sheet_ref(buf,lev+2,off+len,&leng,&result->row))) |
|
|
383 | goto ERROR; |
|
|
384 | len += leng; |
|
|
385 | psiconv_progress(lev+2,off+len,"Going to read the column reference"); |
|
|
386 | if ((res = psiconv_parse_sheet_ref(buf,lev+2,off+len,&leng,&result->column))) |
|
|
387 | goto ERROR; |
|
|
388 | len += leng; |
|
|
389 | |
|
|
390 | psiconv_progress(lev+2,off+len, |
|
|
391 | "Going to read the trailing byte (%02x expected)",0); |
|
|
392 | temp = psiconv_read_u8(buf,lev+2,off+len,&res); |
|
|
393 | if (res) |
|
|
394 | goto ERROR; |
|
|
395 | if (temp != 0) { |
|
|
396 | psiconv_warn(lev+2,off+len,"Unknown byte in cell reference (ignored"); |
|
|
397 | psiconv_debug(lev+2,off+len,"Trailing byte: %02x",temp); |
|
|
398 | } |
|
|
399 | len ++; |
|
|
400 | psiconv_progress(lev,off+len-1, |
|
|
401 | "End of cell reference (total length: %08x)", len); |
|
|
402 | if (length) |
|
|
403 | *length = len; |
|
|
404 | return 0; |
|
|
405 | ERROR: |
|
|
406 | if (length) |
|
|
407 | *length = 0; |
|
|
408 | return res; |
|
|
409 | } |
|
|
410 | |
|
|
411 | static int psiconv_parse_sheet_cell_block(const psiconv_buffer buf,int lev, |
|
|
412 | psiconv_u32 off, int *length, |
|
|
413 | psiconv_sheet_cell_block_t *result) |
|
|
414 | { |
|
|
415 | int len = 0; |
|
|
416 | int leng,res; |
|
|
417 | |
|
|
418 | psiconv_progress(lev+1,off+len,"Going to read a sheet cell block"); |
|
|
419 | psiconv_progress(lev+2,off+len,"Going to read the first cell"); |
|
|
420 | if ((res = psiconv_parse_sheet_cell_reference(buf,lev+2,off+len,&leng, |
|
|
421 | &result->first))) |
|
|
422 | goto ERROR; |
|
|
423 | len += leng; |
|
|
424 | psiconv_progress(lev+2,off+len,"Going to read the last cell"); |
|
|
425 | if ((res = psiconv_parse_sheet_cell_reference(buf,lev+2,off+len,&leng, |
|
|
426 | &result->last))) |
|
|
427 | goto ERROR; |
|
|
428 | len += leng; |
|
|
429 | psiconv_progress(lev,off+len-1, |
|
|
430 | "End of cell block (total length: %08x)", len); |
|
|
431 | if (length) |
|
|
432 | *length = len; |
|
|
433 | return 0; |
|
|
434 | ERROR: |
|
|
435 | if (length) |
|
|
436 | *length = 0; |
|
|
437 | return res; |
|
|
438 | } |
|
|
439 | |
|
|
440 | static int psiconv_parse_formula_element_list(const psiconv_buffer buf, int lev, |
|
|
441 | psiconv_u32 off, int *length, |
296 | psiconv_formula *result) |
442 | psiconv_formula *result, |
|
|
443 | psiconv_u32 maxlen) |
297 | { |
444 | { |
298 | int res=0; |
445 | int res=0; |
299 | int len=0; |
446 | int len=0; |
300 | int leng; |
447 | int leng; |
301 | int eof = 0; |
448 | int eof = 0; |
302 | psiconv_u8 marker; |
449 | psiconv_u8 marker,submarker; |
303 | psiconv_u32 bytelen; |
|
|
304 | psiconv_formula_list formula_stack; |
450 | psiconv_formula_list formula_stack; |
305 | psiconv_formula formula,subformula1,subformula2,subformula3,subformula4; |
451 | psiconv_formula formula,subformula,subformula1,subformula2, |
|
|
452 | subformula3,subformula4; |
|
|
453 | psiconv_u16 temp,nr_of_subs; |
306 | |
454 | |
307 | psiconv_progress(lev+1,off,"Going to read a formula"); |
455 | psiconv_progress(lev+1,off,"Going to read a formula element list"); |
308 | if (!(*result = malloc(sizeof(**result)))) |
456 | if (!(*result = malloc(sizeof(**result)))) |
309 | goto ERROR1; |
457 | goto ERROR1; |
310 | if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) |
458 | if (!(formula_stack = psiconv_list_new(sizeof(struct psiconv_formula_s)))) |
311 | goto ERROR2; |
459 | goto ERROR2; |
312 | if (!(formula = malloc(sizeof(*formula)))) |
460 | if (!(formula = malloc(sizeof(*formula)))) |
… | |
… | |
324 | subformula3->type = psiconv_formula_unknown; |
472 | subformula3->type = psiconv_formula_unknown; |
325 | if (!(subformula4 = malloc(sizeof(*subformula4)))) |
473 | if (!(subformula4 = malloc(sizeof(*subformula4)))) |
326 | goto ERROR7; |
474 | goto ERROR7; |
327 | subformula4->type = psiconv_formula_unknown; |
475 | subformula4->type = psiconv_formula_unknown; |
328 | |
476 | |
329 | psiconv_progress(lev+2,off+len, |
|
|
330 | "Going to read the formula byte length"); |
|
|
331 | bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); |
|
|
332 | if (res) |
|
|
333 | goto ERROR8; |
|
|
334 | psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); |
|
|
335 | len += leng; |
|
|
336 | bytelen += len; |
|
|
337 | |
|
|
338 | psiconv_progress(lev+2,off+len,"Going to read the formula items"); |
|
|
339 | while (!eof && len < bytelen) { |
477 | while (!eof && len+off < maxlen) { |
340 | psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); |
478 | psiconv_progress(lev+3,off+len,"Going to read a formula item marker"); |
341 | marker = psiconv_read_u8(buf,lev+2,off+len,&res); |
479 | marker = psiconv_read_u8(buf,lev+2,off+len,&res); |
342 | if (res) |
480 | if (res) |
343 | goto ERROR8; |
481 | goto ERROR8; |
344 | psiconv_debug(lev+3,off+len,"Marker: %02x (%s)",marker, |
482 | psiconv_debug(lev+3,off+len,"Marker: %02x (%s)",marker, |
… | |
… | |
346 | len ++; |
484 | len ++; |
347 | |
485 | |
348 | if (formula_elements[marker].formula_type == psiconv_formula_unknown) { |
486 | if (formula_elements[marker].formula_type == psiconv_formula_unknown) { |
349 | psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); |
487 | psiconv_warn(lev+3,off+len,"Unknown formula marker found!"); |
350 | goto ERROR8; |
488 | goto ERROR8; |
351 | } else if (formula_elements[marker].formula_type == |
489 | } else if ((formula_elements[marker].formula_type == |
352 | psiconv_formula_mark_eof) { |
490 | psiconv_formula_mark_eof) || |
|
|
491 | (formula_elements[marker].formula_type == |
|
|
492 | psiconv_formula_mark_opend) || |
|
|
493 | (formula_elements[marker].formula_type == |
|
|
494 | psiconv_formula_mark_opsep)) { |
|
|
495 | len--; |
353 | psiconv_progress(lev+3,off+len,"End of formula"); |
496 | psiconv_progress(lev+3,off+len,"End of this formula list"); |
354 | eof = 1; |
497 | eof = 1; |
355 | } else if (formula_elements[marker].formula_type == |
498 | } else if (formula_elements[marker].formula_type == |
356 | psiconv_formula_dat_int) { |
499 | psiconv_formula_dat_int) { |
357 | psiconv_progress(lev+3,off+len,"Next item: an integer"); |
500 | psiconv_progress(lev+3,off+len,"Next item: an integer"); |
358 | formula->data.dat_int = psiconv_read_u32(buf,lev+2,off+len,&res); |
501 | formula->data.dat_int = psiconv_read_u32(buf,lev+2,off+len,&res); |
… | |
… | |
362 | psiconv_debug(lev+3,off+len,"Value: %08x",formula->data.dat_int); |
505 | psiconv_debug(lev+3,off+len,"Value: %08x",formula->data.dat_int); |
363 | len += 4; |
506 | len += 4; |
364 | if ((res = psiconv_list_add(formula_stack,formula))) |
507 | if ((res = psiconv_list_add(formula_stack,formula))) |
365 | goto ERROR8; |
508 | goto ERROR8; |
366 | formula->type = psiconv_formula_unknown; |
509 | formula->type = psiconv_formula_unknown; |
|
|
510 | } else if (formula_elements[marker].formula_type == |
|
|
511 | psiconv_formula_dat_float) { |
|
|
512 | psiconv_progress(lev+3,off+len,"Next item: a float"); |
|
|
513 | formula->data.dat_float = psiconv_read_float(buf,lev+2,off+len,&leng, |
|
|
514 | &res); |
|
|
515 | if (res) |
|
|
516 | goto ERROR8; |
|
|
517 | formula->type = formula_elements[marker].formula_type; |
|
|
518 | psiconv_debug(lev+3,off+len,"Value: %f",formula->data.dat_float); |
|
|
519 | len += leng; |
|
|
520 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
521 | goto ERROR8; |
|
|
522 | formula->type = psiconv_formula_unknown; |
|
|
523 | } else if (formula_elements[marker].formula_type == |
|
|
524 | psiconv_formula_dat_cellref) { |
|
|
525 | psiconv_progress(lev+3,off+len,"Next item: a cell reference"); |
|
|
526 | if ((res = psiconv_parse_sheet_cell_reference(buf,lev+2,off+len,&leng, |
|
|
527 | &formula->data.dat_cellref))) |
|
|
528 | goto ERROR8; |
|
|
529 | formula->type = formula_elements[marker].formula_type; |
|
|
530 | len += leng; |
|
|
531 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
532 | goto ERROR8; |
|
|
533 | formula->type = psiconv_formula_unknown; |
367 | } else if ((formula_elements[marker].formula_type == |
534 | } else if ((formula_elements[marker].formula_type == |
|
|
535 | psiconv_formula_dat_cellblock) || |
|
|
536 | (formula_elements[marker].formula_type == |
|
|
537 | psiconv_formula_dat_vcellblock)) { |
|
|
538 | psiconv_progress(lev+3,off+len,"Next item: a cell block"); |
|
|
539 | if ((res = psiconv_parse_sheet_cell_block(buf,lev+2,off+len,&leng, |
|
|
540 | &formula->data.dat_cellblock))) |
|
|
541 | goto ERROR8; |
|
|
542 | formula->type = formula_elements[marker].formula_type; |
|
|
543 | len += leng; |
|
|
544 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
545 | goto ERROR8; |
|
|
546 | formula->type = psiconv_formula_unknown; |
|
|
547 | } else if (formula_elements[marker].formula_type == |
|
|
548 | psiconv_formula_dat_string) { |
|
|
549 | psiconv_progress(lev+3,off+len,"Next item: a string"); |
|
|
550 | formula->data.dat_string = |
|
|
551 | psiconv_read_sheet_string(buf,lev+2,off+len,&leng,&res); |
|
|
552 | if (res) |
|
|
553 | goto ERROR8; |
|
|
554 | formula->type = formula_elements[marker].formula_type; |
|
|
555 | len += leng; |
|
|
556 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
557 | goto ERROR8; |
|
|
558 | formula->type = psiconv_formula_unknown; |
|
|
559 | } else if ((formula_elements[marker].formula_type == |
368 | psiconv_formula_dat_float) || |
560 | psiconv_formula_dat_var) || |
369 | (formula_elements[marker].formula_type == |
561 | (formula_elements[marker].formula_type == |
370 | psiconv_formula_dat_var) || |
|
|
371 | (formula_elements[marker].formula_type == |
|
|
372 | psiconv_formula_dat_string) || |
|
|
373 | (formula_elements[marker].formula_type == |
|
|
374 | psiconv_formula_dat_cellref) || |
|
|
375 | (formula_elements[marker].formula_type == |
|
|
376 | psiconv_formula_dat_cellblock) || |
|
|
377 | (formula_elements[marker].formula_type == |
|
|
378 | psiconv_formula_dat_vcellblock) || |
562 | psiconv_formula_dat_vcellblock)) { |
379 | (formula_elements[marker].formula_type == |
|
|
380 | psiconv_formula_mark_opsep) || |
|
|
381 | (formula_elements[marker].formula_type == |
|
|
382 | psiconv_formula_mark_opend)) { |
|
|
383 | psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); |
563 | psiconv_warn(lev+3,off+len,"Not yet supported formula mark!"); |
384 | goto ERROR8; |
564 | goto ERROR8; |
385 | } else if (formula_elements[marker].number_of_args == -1) { |
565 | } else if (formula_elements[marker].number_of_args == -1) { |
386 | psiconv_warn(lev+3,off+len,"Vararg functions not yet supported!"); |
566 | psiconv_progress(lev+3,off+len,"Going to parse a vararg function"); |
|
|
567 | if (!(formula->data.fun_operands = |
|
|
568 | psiconv_list_new(sizeof(*formula)))) |
|
|
569 | goto ERROR8; |
|
|
570 | formula->type = formula_elements[marker].formula_type; |
|
|
571 | nr_of_subs = 0; |
|
|
572 | do { |
|
|
573 | nr_of_subs ++; |
|
|
574 | psiconv_progress(lev+4,off+len,"Going to read vararg argument %d", |
|
|
575 | nr_of_subs); |
|
|
576 | if ((res = psiconv_parse_formula_element_list(buf,lev+4,off+len,&leng, |
|
|
577 | &subformula,maxlen))) |
|
|
578 | goto ERROR8; |
|
|
579 | len += leng; |
|
|
580 | if ((res = psiconv_list_add(formula->data.fun_operands,subformula))) { |
|
|
581 | psiconv_free_formula(subformula); |
|
|
582 | goto ERROR8; |
|
|
583 | } |
|
|
584 | free(subformula); |
|
|
585 | psiconv_progress(lev+4,off+len,"Going to read the next marker"); |
|
|
586 | submarker = psiconv_read_u8(buf,lev+4,off+len,&res); |
|
|
587 | len ++; |
|
|
588 | if (res) |
|
|
589 | goto ERROR8; |
|
|
590 | } while (formula_elements[submarker].formula_type |
|
|
591 | == psiconv_formula_mark_opsep); |
|
|
592 | if (formula_elements[submarker].formula_type |
|
|
593 | != psiconv_formula_mark_opend) { |
|
|
594 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
595 | psiconv_debug(lev+3,off+len,"Found unexpected marker %02x",submarker); |
387 | goto ERROR8; |
596 | goto ERROR8; |
|
|
597 | } |
|
|
598 | psiconv_progress(lev+3,off+len,"Going to read the repeated marker %02x", |
|
|
599 | marker); |
|
|
600 | submarker = psiconv_read_u8(buf,lev+3,off+len,&res); |
|
|
601 | if (res) |
|
|
602 | goto ERROR8; |
|
|
603 | if (submarker != marker) { |
|
|
604 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
605 | psiconv_debug(lev+3,off+len,"Expected marker %02x, found %02x", |
|
|
606 | marker,submarker); |
|
|
607 | goto ERROR8; |
|
|
608 | } |
|
|
609 | len++; |
|
|
610 | psiconv_progress(lev+3,off+len, |
|
|
611 | "Going to read the number of arguments (%d expected)", |
|
|
612 | nr_of_subs); |
|
|
613 | temp = psiconv_read_u16(buf,lev+3,off+len,&res); |
|
|
614 | if (res) |
|
|
615 | goto ERROR8; |
|
|
616 | if (temp != nr_of_subs) { |
|
|
617 | psiconv_warn(lev+3,off+len,"Formula corrupted!"); |
|
|
618 | psiconv_debug(lev+3,off+len, |
|
|
619 | "Read %d arguments, but formula says there are %d", |
|
|
620 | nr_of_subs,temp); |
|
|
621 | goto ERROR8; |
|
|
622 | } |
|
|
623 | len += 2; |
|
|
624 | if ((res = psiconv_list_add(formula_stack,formula))) |
|
|
625 | goto ERROR8; |
|
|
626 | formula->type = psiconv_formula_unknown; |
388 | } else { |
627 | } else { |
389 | if (formula_elements[marker].number_of_args > 0) |
628 | if (formula_elements[marker].number_of_args > 0) |
390 | if ((res = psiconv_list_pop(formula_stack,subformula1))) |
629 | if ((res = psiconv_list_pop(formula_stack,subformula1))) |
391 | goto ERROR8; |
630 | goto ERROR8; |
392 | if (formula_elements[marker].number_of_args > 1) |
631 | if (formula_elements[marker].number_of_args > 1) |
… | |
… | |
418 | goto ERROR8; |
657 | goto ERROR8; |
419 | subformula4->type = subformula3->type = subformula2->type = |
658 | subformula4->type = subformula3->type = subformula2->type = |
420 | subformula1->type = formula->type = psiconv_formula_unknown; |
659 | subformula1->type = formula->type = psiconv_formula_unknown; |
421 | } |
660 | } |
422 | } |
661 | } |
423 | if ((len != bytelen) || !eof) { |
662 | if ((len+off > maxlen) || !eof) { |
424 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
663 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
425 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
664 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
426 | bytelen,len); |
665 | maxlen,len+off); |
427 | goto ERROR8; |
666 | goto ERROR8; |
428 | } |
667 | } |
429 | if ((psiconv_list_length(formula_stack)) != 1) { |
668 | if ((psiconv_list_length(formula_stack)) != 1) { |
430 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
669 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
431 | psiconv_debug(lev+2,off+len,"More than one item left on the stack (%d)", |
670 | psiconv_debug(lev+2,off+len,"More than one item left on the stack (%d)", |
… | |
… | |
439 | |
678 | |
440 | if (length) |
679 | if (length) |
441 | *length = len; |
680 | *length = len; |
442 | |
681 | |
443 | psiconv_progress(lev,off+len-1, |
682 | psiconv_progress(lev,off+len-1, |
444 | "End of formula (total length: %08x)", len); |
683 | "End of formula element list (total length: %08x)", len); |
445 | return 0; |
684 | return 0; |
446 | |
685 | |
447 | ERROR8: |
686 | ERROR8: |
448 | psiconv_free_formula(subformula4); |
687 | psiconv_free_formula(subformula4); |
449 | ERROR7: |
688 | ERROR7: |
… | |
… | |
457 | ERROR3: |
696 | ERROR3: |
458 | psiconv_free_formula_list(formula_stack); |
697 | psiconv_free_formula_list(formula_stack); |
459 | ERROR2: |
698 | ERROR2: |
460 | free (*result); |
699 | free (*result); |
461 | ERROR1: |
700 | ERROR1: |
462 | psiconv_warn(lev+1,off,"Reading of formula failed"); |
701 | psiconv_warn(lev+1,off,"Reading of formula element list failed"); |
463 | if (length) |
702 | if (length) |
464 | *length = 0; |
703 | *length = 0; |
465 | if (!res) |
704 | if (!res) |
466 | return -PSICONV_E_NOMEM; |
705 | return -PSICONV_E_NOMEM; |
467 | else |
706 | else |
468 | return res; |
707 | return res; |
469 | } |
708 | } |
470 | |
709 | |
|
|
710 | |
|
|
711 | |
|
|
712 | |
|
|
713 | int psiconv_parse_formula(const psiconv_buffer buf, int lev, |
|
|
714 | psiconv_u32 off, int *length, |
|
|
715 | psiconv_formula *result) |
|
|
716 | { |
|
|
717 | int res=0; |
|
|
718 | int len=0; |
|
|
719 | int leng; |
|
|
720 | psiconv_u32 bytelen,formula_end; |
|
|
721 | psiconv_u8 temp; |
|
|
722 | |
|
|
723 | psiconv_progress(lev+1,off,"Going to read a formula"); |
|
|
724 | |
|
|
725 | psiconv_progress(lev+2,off+len, |
|
|
726 | "Going to read the formula byte length"); |
|
|
727 | bytelen = psiconv_read_S(buf,lev+2,off+len,&leng,&res); |
|
|
728 | if (res) |
|
|
729 | goto ERROR1; |
|
|
730 | psiconv_debug(lev+2,off+len,"Formula byte length: %d",bytelen); |
|
|
731 | len += leng; |
|
|
732 | bytelen += len; |
|
|
733 | formula_end = off + bytelen; |
|
|
734 | |
|
|
735 | psiconv_progress(lev+2,off+len,"Going to read the formula elements list"); |
|
|
736 | if ((res = psiconv_parse_formula_element_list(buf,lev+2,off+len,&leng, |
|
|
737 | result,formula_end))) |
|
|
738 | goto ERROR1; |
|
|
739 | len += leng; |
|
|
740 | |
|
|
741 | psiconv_progress(lev+2,off+len,"Going to read the eof marker"); |
|
|
742 | temp = psiconv_read_u8(buf,lev+2,off+len,&res); |
|
|
743 | if (res) |
|
|
744 | goto ERROR2; |
|
|
745 | if (formula_elements[temp].formula_type != psiconv_formula_mark_eof) { |
|
|
746 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
|
|
747 | psiconv_debug(lev+2,off+len,"Expected marker: %02x, found byte: %02x", |
|
|
748 | 0x15,temp); |
|
|
749 | goto ERROR2; |
|
|
750 | } |
|
|
751 | len ++; |
|
|
752 | |
|
|
753 | if (off+len != formula_end) { |
|
|
754 | psiconv_warn(lev+2,off+len,"Formula corrupted!"); |
|
|
755 | psiconv_debug(lev+2,off+len,"Expected end: %04x, found end: %04x", |
|
|
756 | formula_end,len+off); |
|
|
757 | goto ERROR2; |
|
|
758 | } |
|
|
759 | |
|
|
760 | if (length) |
|
|
761 | *length = len; |
|
|
762 | |
|
|
763 | psiconv_progress(lev,off+len-1, |
|
|
764 | "End of formula (total length: %08x)", len); |
|
|
765 | return 0; |
|
|
766 | |
|
|
767 | ERROR2: |
|
|
768 | psiconv_free_formula(*result); |
|
|
769 | ERROR1: |
|
|
770 | psiconv_warn(lev+1,off,"Reading of formula failed"); |
|
|
771 | if (length) |
|
|
772 | *length = 0; |
|
|
773 | if (!res) |
|
|
774 | return -PSICONV_E_NOMEM; |
|
|
775 | else |
|
|
776 | return res; |
|
|
777 | } |
|
|
778 | |
|
|
779 | |