%% options copyright owner = Dirk Krause copyright year = 2012-2014 license = bsd %% header #ifdef __cplusplus extern "C" { #endif /** Apply one line from a Fig file to a drawing. @param drw Drawing to modify. @param lp Line to apply. Line is modified during analysis. @return 1 on success, 0 on error with ec set. */ int dk3fig_read_apply_line(dk3_fig_drawing_t *drw, char *lp); /** Read a Fig drawing from a file specified by name. @param drw Drawing to modify. @param fn File name to read. @return 1 on success, 0 on error with ec set. */ int dk3fig_read_file_name(dk3_fig_drawing_t *drw, dkChar const *fn); /** Read a Fig drawing from an open file (must be opened for reading in text mode). @param drw Drawing to modify @param fipo Input file to process. @return 1 on success, 0 on error. */ int dk3fig_read_file(dk3_fig_drawing_t *drw, FILE *fipo); #ifdef __cplusplus } #endif %% module #include "dk3all.h" #include "dk3fig.h" #include "dk3figrd.h" #include "fig2lat.h" $!trace-include /** Keywords used by the module, not localized. */ static dkChar const * const dk3figrd_kw[] = { $!string-table macro=dkT # # 0: File open mode. # r $!end }; /** Keywords used by the module. */ static char const * const dk3figrd_c8_kw[] = { $!string-table # # 0: Locale for input reading. # C # # 1/2/3: Created by WinFIG # Created by WinFIG $!end }; /** File type tag at start of file. */ static char const dk3figrd_file_start_tag[] = { "#FIG 3.2" }; /** Error reporting function. @param drw Drawing structure. @param res Operation result (1=success, 0=error). @param ec Error code (1=syntax, 2=memory, 3=redefinition). */ static void dk3figrd_report_error_code(dk3_fig_drawing_t *drw, int res, int ec) { if(!(res)) { switch(ec) { case 1: { /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } break; case 2: { /* ERROR: Memory */ dk3app_log_i1(drw->app, DK3_LL_ERROR, 9); } break; case 3: { /* ERROR: Color redefinition */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 2); } break; } } } /** Expect file identifier. @param drw Drawing to modify. @param lp Text line to process. @return 1 on success (identifier found or comment line). */ static int dk3figrd_expect_start(dk3_fig_drawing_t *drw, char *lp) { int back = 0; $? "+ dk3figrd_expect_start \"%s\"", lp if('#' == *lp) { back = 1; if(7 < dk3str_c8_len(lp)) { if(0 == dk3str_c8_ncmp(lp, dk3figrd_file_start_tag, 8)) { drw->state = DK3_FIG_RD_STATE_EXPECT_ORIENTATION; } else { $? "! no Fig signature" } } else { $? "! line too short" } } else { $? "! not a comment line" } if(!(back)) { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } $? "- dk3figrd_expect_start %d", back return back; } /** Retrieve transparent color number. @param drw Drawing to modify. @param lp Text line to process. @return 1 on success, 0 on error. */ static int dk3figrd_expect_transparent(dk3_fig_drawing_t *drw, char *lp) { int back = 0; int i; if(1 == sscanf(lp, "%d", &i)) { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_RESOLUTION; drw->transcol = i; $? ". transparent color = %d", drw->transcol } else { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Not a number! */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } return back; } /** Retrieve resolution. @param drw Drawing to modify. @param lp Text line to process. @return 1 on success, 0 on error. */ static int dk3figrd_expect_resolution(dk3_fig_drawing_t *drw, char *lp) { long lres; int back = 0; if(1 == sscanf(lp, "%ld", &lres)) { if(0L < lres) { drw->lres = lres; #if VERSION_BEFORE_20140716 drw->res = dk3ma_l_to_d(lres); #else drw->res = (double)lres; #endif back = 1; drw->state = DK3_FIG_RD_STATE_READY; } } if(!(back)) { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } dk3figrd_report_error_code(drw, back, 1); return back; } /** Get a hexadecimal digit. @param c Character to process. @param x Pointer to result variable. @return 1 on success, 0 on error. */ static int dk3figrd_hex_digit(char c, int *x) { int back = 0; switch(c) { case '0': { *x = 0; back = 1; } break; case '1': { *x = 1; back = 1; } break; case '2': { *x = 2; back = 1; } break; case '3': { *x = 3; back = 1; } break; case '4': { *x = 4; back = 1; } break; case '5': { *x = 5; back = 1; } break; case '6': { *x = 6; back = 1; } break; case '7': { *x = 7; back = 1; } break; case '8': { *x = 8; back = 1; } break; case '9': { *x = 9; back = 1; } break; case 'a': { *x = 10; back = 1; } break; case 'A': { *x = 10; back = 1; } break; case 'b': { *x = 11; back = 1; } break; case 'B': { *x = 11; back = 1; } break; case 'c': { *x = 12; back = 1; } break; case 'C': { *x = 12; back = 1; } break; case 'd': { *x = 13; back = 1; } break; case 'D': { *x = 13; back = 1; } break; case 'e': { *x = 14; back = 1; } break; case 'E': { *x = 14; back = 1; } break; case 'f': { *x = 15; back = 1; } break; case 'F': { *x = 15; back = 1; } break; } return back; } /** Read color object. @param drw Drawing to modify. @param args Arguments in color line. @return 1 on success, 0 on error. */ static int dk3figrd_color_object(dk3_fig_drawing_t *drw, char *args) { dk3_fig_color_t col; /* Temporary buffer. */ dk3_fig_color_t *pcol; /* Object found in storage. */ char *pn; /* Next word to process. */ int x; /* Temporary variable. */ int back = 0; int ec = 1; /* 1=syntax, 2=memory, 3=redef */ $? "+ dk3figrd_color_object \"%s\"", TR_STR(args) if(args) { pn = dk3str_c8_next(args, NULL); if(pn) { if(1 == sscanf(args, "%d", &(col.i))) { if(31 < col.i) { if('#' == *(pn++)) { col.r = col.g = col.b = x = 0; if(dk3figrd_hex_digit(*(pn++), &x)) { col.r = x; if(dk3figrd_hex_digit(*(pn++), &x)) { col.r = 16 * col.r + x; if(dk3figrd_hex_digit(*(pn++), &x)) { col.g = x; if(dk3figrd_hex_digit(*(pn++), &x)) { col.g = 16 * col.g + x; if(dk3figrd_hex_digit(*(pn++), &x)) { col.b = x; if(dk3figrd_hex_digit(*(pn++), &x)) { col.b = 16 * col.b + x; if(dk3sto_it_find_like(drw->icol, (void *)(&col), 0)) { ec = 3; } else { pcol = dk3_new_app(dk3_fig_color_t,1,drw->app); if(pcol) { /* 2013-01-15: Copy color data to new buffer! */ dk3mem_cpy( (void *)pcol, (void *)(&col), sizeof(dk3_fig_color_t) ); if(dk3sto_add(drw->scol, (void *)pcol)) { back = 1; } else { dk3_delete(pcol); ec = 2; } } else { ec = 2; } } } } } } } } } } } } } if(!(back)) { switch(ec) { case 1: case 3: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_color_object %d", back return back; } /** Complete arc. @param drw Drawing to modify. @param tobj Object to complete. @param args Object arguments in start line. @return 1 on success, 0 on error. */ static int dk3figrd_arc_complete(dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args) { dk3_fig_obj_t *pobj; /* New object. */ char *pc; /* Current text word to process. */ char *pn; /* Next text word to process. */ int i; /* Index of current text word. */ int af = 0; /* Flag: Arrowhead forward. */ int ab = 0; /* Flag: Arrowhead backward. */ int ec = 1; /* Error code. */ int back = 1; $? "+ dk3figrd_arc_complete \"%s\"", args pc = args; for(i = 0; ((back) && (pc) && (i < 12)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* int cap style */ if(1 != sscanf(pc, "%d", &(tobj->cs))) { $? "! cap style" back = 0; } } break; case 1: { /* int direction 0=clockwise, ignored */ } break; case 2: { /* int arrow forward */ if(1 != sscanf(pc, "%d", &af)) { $? "! arrow forward" back = 0; } } break; case 3: { /* int arrow backward */ if(1 != sscanf(pc, "%d", &ab)) { $? "! arrow backward" back = 0; } } break; case 4: { /* double cx */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.xc))) { $? "! cx" back = 0; } } break; case 5: { /* double cy */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.yc))) { $? "! cy" back = 0; } } break; case 6: { /* double x1 */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x1))) { $? "! x1" back = 0; } } break; case 7: { /* double y1 */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y1))) { $? "! y1" back = 0; } } break; case 8: { /* double x2 */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x2))) { $? "! x2" back = 0; } } break; case 9: { /* double y2 */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y2))) { $? "! y2" back = 0; } } break; case 10: { /* double x3 */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x3))) { $? "! x3" back = 0; } } break; case 11: { /* double y3 */ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y3))) { $? "! y3" back = 0; } } break; } if(!(pc)) { if(i < 11) { $? "! no more text" back = 0; } } pc = pn; } if(back) { $? ". no errors yet" pobj = dk3fig_obj_new( drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc, tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, af, ab, 0, NULL, drw->app ); if(pobj) { $? ". arrowhead:arc af = %d pobj->af = %s", af, TR_PTR(pobj->af) $? ". arrowhead:arc ab = %d pobj->ab = %s", ab, TR_PTR(pobj->ab) if(dk3sto_add(drw->sobj, (void *)pobj)) { dk3mem_cpy( (void *)(&((pobj->dt).arc)), (void *)(&((tobj->dt).arc)), sizeof(dk3_fig_det_arc_t) ); if(pobj->ab) { drw->state = DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD; } if(pobj->af) { drw->state = DK3_FIG_RD_STATE_ARC_ARROW_FORWARD; } drw->cobj = pobj; } else { back = 0; ec = 2; $? "! memory" dk3fig_obj_delete(pobj); } } else { back = 0; ec = 2; $? "! memory" } } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_arc_complete %d", back return back; } /** Complete ellipse. @param drw Drawing to modify. @param tobj Object to complete. @param args Object arguments in start line. @return 1 on success, 0 on error. */ static int dk3figrd_ellipse_complete( dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args ) { dk3_fig_obj_t *pobj; /* New object. */ char *pc; /* Current text word to process. */ char *pn; /* Next text to process. */ int i; /* Index of current text word. */ int ec = 1; /* Error code. */ int back = 1; $? "+ dk3figrd_ellipse_complete \"%s\"", args pc = args; for(i = 0; ((back) && (pc) && (i < 10)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* direction, ignored */ } break; case 1: { /* angle */ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.an))) { $? "! angle" back = 0; } $? ". angle=%lg", (tobj->dt).ell.an } break; case 2: { /* cx */ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.cx))) { $? "! cx" back = 0; } } break; case 3: { /* cy */ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.cy))) { $? "! cy" back = 0; } } break; case 4: { /* rx */ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.rx))) { $? "! rx" back = 0; } } break; case 5: { /* ry */ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.ry))) { $? "! ry" back = 0; } } break; case 6: { /* start x */ } break; case 7: { /* start y */ } break; case 8: { /* end x */ } break; case 9: { /* end y */ } break; } pc = pn; if(!(pc)) { if(i < 9) { $? "! end of line" back = 0; } } } if(back) { pobj = dk3fig_obj_new( drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc, tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, 0, 0, 0, NULL, drw->app ); if(pobj) { if(dk3sto_add(drw->sobj, (void *)pobj)) { dk3mem_cpy( (void *)(&((pobj->dt).ell)), (void *)(&((tobj->dt).ell)), sizeof(dk3_fig_det_ell_t) ); } else { back = 0; ec = 2; dk3fig_obj_delete(pobj); } } else { back = 0; ec = 2; } } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_ellipse_complete %d", back return back; } /** Complete polyline. @param drw Drawing to modify. @param tobj Object to complete. @param args Object arguments in start line. @return 1 on success, 0 on error. */ static int dk3figrd_polyline_complete( dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args ) { dk3_fig_obj_t *pobj; /* New object. */ char *pc; /* Current text word to process. */ char *pn; /* Next text to process. */ #if VERSION_BEFORE_20140809 unsigned u; /* Number of points. */ #endif int i; /* Index of current text word. */ int af = 0; /* Flag: Arrowhead forward. */ int ab = 0; /* Flag: Arrowhead backward. */ int ec = 1; /* Error code. */ int back = 1; $? "+ dk3figrd_polyline_complete \"%s\"", args pc = args; for(i = 0; ((back) && (pc) && (i < 6)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* js, join style */ if(1 != sscanf(pc, "%d", &(tobj->js))) { $? "! join style" back = 0; } } break; case 1: { /* cs, cap style */ if(1 != sscanf(pc, "%d", &(tobj->cs))) { $? "! cap style" back = 0; } } break; case 2: { /* radius */ if(1 != sscanf(pc, "%lg", &((tobj->dt).pol.ra))) { $? "! radius" back = 0; } } break; case 3: { /* af, array forward */ if(1 != sscanf(pc, "%d", &af)) { $? "! arrow forward" back = 0; } } break; case 4: { /* ab, array backward */ if(1 != sscanf(pc, "%d", &ab)) { $? "! arrow backward" back = 0; } } break; case 5: { /* Number of points */ #if VERSION_BEFORE_20140809 if(1 == sscanf(pc, "%u", &u)) { (tobj->dt).pol.np = (size_t)u; if(u != (unsigned)((tobj->dt).pol.np)) { $? "! overflow" back = 0; } } else { $? "! number of points" back = 0; } #else dk3_um_t um = DK3_UM_0; int mec = 0; if (dk3ma_um_from_c8_string(&um, pc, NULL)) { (tobj->dt).pol.np = dk3ma_um_to_sz(um, &mec); if (0 != mec) { /* Overflow */ back = 0; } } else { /* Not a number */ back = 0; } #endif } break; } pc = pn; if(!(pc)) { if(i < 5) { $? "! line end" back = 0; } } } if(back) { pobj = dk3fig_obj_new( drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc, tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, af, ab, (tobj->dt).pol.np, NULL, drw->app ); if(pobj) { (pobj->dt).pol.ra = (tobj->dt).pol.ra; $? ". arrowhead:poly af = %d pobj->af = %s", af, TR_PTR(pobj->af) $? ". arrowhead:poly ab = %d pobj->ab = %s", ab, TR_PTR(pobj->ab) if(dk3sto_add(drw->sobj, (void *)pobj)) { drw->cobj = pobj; drw->cind = 0; drw->cxy = 0; drw->state = DK3_FIG_RD_STATE_PL_POINTS; if(5 == pobj->st) { drw->state = DK3_FIG_RD_STATE_PL_IMAGE; } if(pobj->ab) { drw->state = DK3_FIG_RD_STATE_PL_ARROW_BACKWARD; } if(pobj->af) { drw->state = DK3_FIG_RD_STATE_PL_ARROW_FORWARD; } } else { back = 0; ec = 2; $? "! memory" dk3fig_obj_delete(pobj); } } else { back = 0; ec = 2; $? "! memory" } } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_polyline_complete %d", back return back; } /** Complete spline. @param drw Drawing to modify. @param tobj Object to complete. @param args Object arguments in start line. @return 1 on success, 0 on error. */ static int dk3figrd_spline_complete(dk3_fig_drawing_t *drw,dk3_fig_obj_t *tobj,char *args) { dk3_fig_obj_t *pobj; /* New object. */ char *pc; /* Current text word to process. */ char *pn; /* Next text to process. */ #if VERSION_BEFORE_20140809 unsigned u; /* Number of points. */ #endif int i; /* Index of current text word. */ int af = 0; /* Flag: Arrowhead forward. */ int ab = 0; /* Flag: Arrowhead backward. */ int ec = 1; /* Error code. */ int back = 1; $? "+ dk3figrd_spline_complete %d %d \"%s\"", tobj->ot, tobj->st, args pc = args; for(i = 0; ((back) && (pc) && (i < 4)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* cs, cap style */ if(1 != sscanf(pc, "%d", &(tobj->cs))) { $? "! cap style" back = 0; } } break; case 1: { /* af, arrowhead forward */ if(1 != sscanf(pc, "%d", &af)) { $? "! arrow forward" back = 0; } } break; case 2: { /* ab, arrowhead backward */ if(1 != sscanf(pc, "%d", &ab)) { $? "! arrow backward" back = 0; } } break; case 3: { /* np, number of points */ #if VERSION_BEFORE_20140809 if(1 == sscanf(pc, "%u", &u)) { (tobj->dt).pol.np = (size_t)u; if(u != (unsigned)((tobj->dt).pol.np)) { $? "! range overflow" back = 0; } } else { back = 0; } #else dk3_um_t um = DK3_UM_0; int mec = 0; if (dk3ma_um_from_c8_string(&um, pc, NULL)) { (tobj->dt).pol.np = dk3ma_um_to_sz(um, &mec); if (0 != mec) { /* Range overflow */ back = 0; } } else { /* Not a number */ back = 0; } #endif } break; } pc = pn; if(!(pc)) { if(i < 3) { back = 0; } } } if(back) { pobj = dk3fig_obj_new( drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc, tobj->fi, tobj->cs, 0, tobj->ls, tobj->sv, af, ab, (tobj->dt).pol.np, NULL, drw->app ); if(pobj) { $? ". arrowhead:spline af = %d pobj->af = %s", af, TR_PTR(pobj->af) $? ". arrowhead:spline ab = %d pobj->ab = %s", ab, TR_PTR(pobj->ab) if(dk3sto_add(drw->sobj, (void *)pobj)) { drw->cobj = pobj; drw->cind = 0; drw->cxy = 0; drw->state = DK3_FIG_RD_STATE_SP_POINTS; if(pobj->ab) { drw->state = DK3_FIG_RD_STATE_SP_ARROW_BACKWARD; } if(pobj->af) { drw->state = DK3_FIG_RD_STATE_SP_ARROW_FORWARD; } } else { $? "! memory" back = 0; ec = 2; dk3fig_obj_delete(pobj); } } else { $? "! memory" back = 0; ec = 2; } } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_spline_complete %d", back return back; } /** Read graphics element. @param drw Drawing to modify. @param ot Object type. @param args Object arguments in start line. @return 1 on success, 0 on error. */ static int dk3figrd_path_object(dk3_fig_drawing_t *drw, int ot, char *args) { dk3_fig_obj_t tobj; /* Buffer object. */ char *pc; /* Current text word to process. */ char *pn; /* Next text to process. */ int i; /* Index of current text word. */ int back = 0; $? "+ dk3figrd_path_object %d \"%s\"", ot, TR_STR(args) if(args) { dk3fig_obj_init(&tobj); tobj.ot = ot; back = 1; pc = args; for(i = 0; ((back) && (pc) && (i < 9)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* st: sub type */ if(1 != sscanf(pc, "%d", &(tobj.st))) { $? "! sub type" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } $? ". st = %d", tobj.st } break; case 1: { /* ls: line style: int */ if(1 != sscanf(pc, "%d", &(tobj.ls))) { $? "! line style" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; case 2: { /* lw: line thickness: int */ if(1 != sscanf(pc, "%d", &(tobj.lw))) { $? "! line thickness" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; case 3: { /* pc: pen color: int */ if(1 != sscanf(pc, "%d", &(tobj.pc))) { $? "! pen clor" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; case 4: { /* fc: fill color: int */ if(1 != sscanf(pc, "%d", &(tobj.fc))) { $? "! fill color" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; case 5: { /* la: depth: int */ if(1 != sscanf(pc, "%d", &(tobj.la))) { $? "! depth" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; case 6: { /* pen style: int, unused */ } break; case 7: { /* fi: area fill: int */ if(1 != sscanf(pc, "%d", &(tobj.fi))) { $? "! area fill" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; case 8: { /* sv: style value: double */ if(1 != sscanf(pc, "%lg", &(tobj.sv))) { $? "! style value" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } break; } pc = pn; if(!(pc)) { $? "! end of line" back = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); /* ERROR: Syntax */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } if((back) && (pc)) { $? ". first part la=%d lw=%d pc=%d fc=%d ls=%d", tobj.la, tobj.lw, tobj.pc, tobj.fc, tobj.ls switch(ot) { case DK3_FIG_OBJ_ARC: { back = dk3figrd_arc_complete(drw, &tobj, pc); } break; case DK3_FIG_OBJ_ELLIPSE: { back = dk3figrd_ellipse_complete(drw, &tobj, pc); } break; case DK3_FIG_OBJ_POLYLINE: { back = dk3figrd_polyline_complete(drw, &tobj, pc); } break; case DK3_FIG_OBJ_SPLINE: { back = dk3figrd_spline_complete(drw, &tobj, pc); } break; } } else { /* ERROR: Syntax */ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } } else { /* ERROR: Missing arguments! */ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } $? "- dk3figrd_path_object %d", back return back; } /** Copy string from right to left while resolving escape sequences. Destination and source source address point to the same buffer but src must point somewhere right from dst. @param dst Destination pointer. @param src Source pointer. */ static void dk3figrd_string_copy_to_left(char *dst, char *src) { char *pd; /* Current destination pointer. */ char *ps; /* Current source pointer. */ pd = dst; ps = src; while(*ps) { *(pd++) = *(ps++); } *pd = '\0'; } /** Squeeze Fig string (resolve octal codes and backslash escapes). @param str String to modify. @return 1 on success, 0 on error. */ static int dk3figrd_squeeze_string(char *str) { char *ptr; /* Current character to process. */ int i1 = 0; /* First octal value. */ int i2 = 0; /* Second octal value. */ int i3 = 0; /* Third octal value. */ int back = 1; $? "+ dk3figrd_squeeze_string \"%s\"", TR_STR(str) ptr = str; while((back) && (*ptr)) { $? ". position \"%s\"", ptr if('\\' == *ptr) { $? ". backslash" if((ptr[1] >= '0') && (ptr[1] <= '3')) { if((ptr[2] >= '0') && (ptr[2] <= '7')) { if((ptr[3] >= '0') && (ptr[3] <= '7')) { $? ". octal" i1 = i2 = i3 = 0; (void)dk3figrd_hex_digit(ptr[1], &i1); $? ". i1 = %d", i1 (void)dk3figrd_hex_digit(ptr[2], &i2); $? ". i2 = %d", i2 (void)dk3figrd_hex_digit(ptr[3], &i3); $? ". i3 = %d", i3 $? ". %d", 64 * i1 + 8 * i2 + i3 *ptr = (char)(64 * i1 + 8 * i2 + i3); dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[4])); if(0x01 == *ptr) { *ptr = '\0'; } else { ptr++; } } else { $? "! octal 3" back = 0; } } else { back = 0; $? "! octal 2" } } else { switch(ptr[1]) { case '\0': { *ptr = '\0'; } break; case 'r': { *ptr = '\r'; dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2])); ptr++; } break; case 'n': { *ptr = '\n'; dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2])); ptr++; } break; case 'a': { *ptr = '\a'; dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2])); ptr++; } break; default: { dk3figrd_string_copy_to_left(ptr, &(ptr[1])); ptr++; } break; } } } else { $? ". normal char" ptr++; } } if(!(back)) { } $? "- dk3figrd_squeeze_string %d \"%s\"", back, TR_STR(str) return back; } /** Read text element. @param drw Drawing to modify. @param args Object arguments in start line. @return 1 on success, 0 on error. */ static int dk3figrd_text_object(dk3_fig_drawing_t *drw, char *args) { dk3_fig_obj_t tobj; /* Buffer object. */ dk3_fig_obj_t *pobj = NULL; /* New object. */ char *pc; /* Current text word to process. */ char *pn; /* Next text to process. */ int back = 0; int ec = 1; /* 1=syntax, 2=memory */ int i; /* Index of current text word. */ $? "+ dk3figrd_text_object \"%s\"", TR_STR(args) if(args) { dk3fig_obj_init(&tobj); tobj.ot = DK3_FIG_OBJ_TEXT; back = 1; pc = args; pn = NULL; for(i = 0; ((back) && (pc) && (i < 12)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* sub type */ if(1 != sscanf(pc, "%d", &(tobj.st))) { $? "! sub type" back = 0; } } break; case 1: { /* color */ if(1 != sscanf(pc, "%d", &(tobj.pc))) { $? "! pen color" back = 0; } } break; case 2: { /* depth (layer) */ if(1 != sscanf(pc, "%d", &(tobj.la))) { $? "! depth" back = 0; } } break; case 3: { /* pen style, unused */ } break; case 4: { /* font */ if(1 != sscanf(pc, "%d", &(tobj.dt.txt.fo))) { $? "! font" back = 0; } } break; case 5: { /* font size */ if(1 == sscanf(pc, "%lg", &(tobj.dt.txt.fs))) { $? ". size" if(tobj.dt.txt.fs < 0.0) { $? "! neg size" back = 0; } } else { $? "! size" back = 0; } } break; case 6: { /* angle */ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.an))) { $? "! angle" back = 0; } } break; case 7: { /* font flags */ if(1 != sscanf(pc, "%d", &(tobj.dt.txt.ff))) { $? "! flags" back = 0; } } break; case 8: { /* height */ } break; case 9: { /* length */ } break; case 10: { /* x */ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.x))) { $? "! x" back = 0; } } break; case 11: { /* y */ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.y))) { $? "! y" back = 0; } } break; } pc = pn; if(!(pc)) { $? "! text" back = 0; } } if((pc) && (back)) { if(dk3figrd_squeeze_string(pc)) { pobj = dk3fig_obj_new( drw->lineno, tobj.la, tobj.ot, tobj.st, 0, tobj.pc, 0, 0, 0, 0, 0, 0.0, 0, 0, 0, pc, drw->app ); if(pobj) { if(dk3sto_add(drw->sobj, (void *)pobj)) { (pobj->dt).txt.x = tobj.dt.txt.x; (pobj->dt).txt.y = tobj.dt.txt.y; (pobj->dt).txt.an = tobj.dt.txt.an; (pobj->dt).txt.fs = tobj.dt.txt.fs; (pobj->dt).txt.he = tobj.dt.txt.he; (pobj->dt).txt.wi = tobj.dt.txt.wi; (pobj->dt).txt.fo = tobj.dt.txt.fo; (pobj->dt).txt.ff = tobj.dt.txt.ff; } else { back = 0; ec = 2; $? "! memory" dk3fig_obj_delete(pobj); } } else { back = 0; ec = 2; $? "! memory" } } else { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); back = 0; $? "! no text or previous error" } } } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_text_object %d", back return back; } /** Read start line of an object. @param drw Drawing to modify. @param lp Text line to process. @return 1 on success, 0 on error. */ static int dk3figrd_start_object(dk3_fig_drawing_t *drw, char *lp) { char *pn; /* Pointer to text after object type. */ int ot = 0; /* Object type. */ int back = 0; $? "+ dk3figrd_start_object \"%s\"", lp pn = dk3str_c8_next(lp, NULL); if(1 == sscanf(lp, "%d", &ot)) { switch(ot) { case DK3_FIG_OBJ_COLOR: { back = dk3figrd_color_object(drw, pn); } break; case DK3_FIG_OBJ_ARC: case DK3_FIG_OBJ_ELLIPSE: case DK3_FIG_OBJ_POLYLINE: case DK3_FIG_OBJ_SPLINE: { back = dk3figrd_path_object(drw, ot, pn); } break; case DK3_FIG_OBJ_TEXT: { back = dk3figrd_text_object(drw, pn); } break; case DK3_FIG_OBJ_COMPOUND: { back = 1; } break; case DK3_FIG_OBJ_ENDCOMPOUND: { back = 1; } break; } } else { /* Syntax error, no numeric object type! */ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1); } $? "- dk3figrd_start_object %d", back return back; } /** Read arrowhead line. @param drw Drawing. @param obj Current object. @param ah Arrowhead structure to fill. @param lp Text containing arrowhead information. @return 1 on success, 0 on error. */ static int dk3figrd_arrowhead( dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, dk3_fig_ah_t *ah, char *lp ) { char *pc; /* Current text word to process. */ char *pn; /* Next text to process. */ int i; /* Index of current text word. */ int back = 1; $? "+ dk3figrd_arrowhead \"%s\"", TR_STR(lp) pc = dk3str_c8_start(lp, NULL); for(i = 0; ((back) && (pc) && (i < 5)); i++) { pn = dk3str_c8_next(pc, NULL); switch(i) { case 0: { /* arrow type */ if(1 != sscanf(pc, "%d", &(ah->as))) { $? "! arrow type" back = 0; } } break; case 1: { /* arrow style */ if(1 != sscanf(pc, "%d", &(ah->af))) { $? "! arrow fill style" back = 0; } } break; case 2: { /* thickness (ignored, linewidth used) */ } break; case 3: { /* width */ if(1 != sscanf(pc, "%lg", &(ah->wi))) { $? "! arrow width" back = 0; } } break; case 4: { /* height */ if(1 != sscanf(pc, "%lg", &(ah->he))) { $? "! Arrow height" back = 0; } } break; } pc = pn; if(!(pc)) { if(i < 4) { $? "! unexpected end of line" back = 0; } } } $? "- dk3figrd_arrowhead %d", back return back; } /** Attach arrowhead information to arc. @param drw Drawing to modify. @param lp Text line containing arrowhead information. @return 1 on success, 0 on error. */ static int dk3figrd_arc_arrow(dk3_fig_drawing_t *drw, char *lp) { int ec = 1; /* Error code. */ int ostate; /* Old object reader state. */ int back = 0; $? "+ dk3figrd_arc_arrow \"%s\"", TR_STR(lp) ostate = drw->state; if(drw->cobj) { switch(ostate) { case DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD: { if((drw->cobj)->ab) { back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp); } else { $? "! bug ab" } } break; default: { if((drw->cobj)->af) { back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp); } else { $? "! bug af" } } break; } drw->state = DK3_FIG_RD_STATE_READY; switch(ostate) { case DK3_FIG_RD_STATE_ARC_ARROW_FORWARD: { if((drw->cobj)->ab) { drw->state = DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD; } } break; } } else { $? "! bug cobj" } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_arc_arrow %d", back return back; } /** Attach arrowhead information to polyline. @param drw Drawing to modify. @param lp Text line containing arrowhead information. @return 1 on success, 0 on error. */ static int dk3figrd_polyline_arrow(dk3_fig_drawing_t *drw, char *lp) { int ostate; /* Old object reader state. */ int ec = 1; /* Error code. */ int back = 0; $? "+ dk3figrd_polyline_arrow \"%s\"", TR_STR(lp) ostate = drw->state; if(drw->cobj) { switch(ostate) { case DK3_FIG_RD_STATE_PL_ARROW_BACKWARD: { if((drw->cobj)->ab) { back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp); } else { $? "! bug ab" } } break; default: { if((drw->cobj)->af) { back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp); } else { $? "! bug af" } } break; } drw->state = DK3_FIG_RD_STATE_PL_POINTS; if(5 == (drw->cobj)->st) { drw->state = DK3_FIG_RD_STATE_PL_IMAGE; } switch(ostate) { case DK3_FIG_RD_STATE_PL_ARROW_FORWARD: { if((drw->cobj)->ab) { drw->state = DK3_FIG_RD_STATE_PL_ARROW_BACKWARD; } } break; } } else { $? "! bug cobj" } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_polyline_arrow %d", back return back; } /** Attach arrowhead information to spline. @param drw Drawing to modify. @param lp Text line containing arrowhead information. @return 1 on success, 0 on error. */ static int dk3figrd_spline_arrow(dk3_fig_drawing_t *drw, char *lp) { int ostate; /* Old object reader state. */ int ec = 1; /* Error code. */ int back = 0; $? "+ dk3figrd_spline_arrow \"%s\"", TR_STR(lp) ostate = drw->state; if(drw->cobj) { switch(ostate) { case DK3_FIG_RD_STATE_SP_ARROW_BACKWARD: { if((drw->cobj)->ab) { back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp); } else { $? "! bug ab" } } break; default: { if((drw->cobj)->af) { back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp); } else { $? "! bug af" } } break; } drw->state = DK3_FIG_RD_STATE_SP_POINTS; switch(ostate) { case DK3_FIG_RD_STATE_SP_ARROW_FORWARD: { if((drw->cobj)->ab) { drw->state = DK3_FIG_RD_STATE_SP_ARROW_BACKWARD; } } break; } } else { $? "! bug cobj" } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_spline_arrow %d", back return back; } /** Read image line for a polyline object. @param drw Drawing to modify. @param lp Text line containing image information. @return 1 on success, 0 on error. */ static int dk3figrd_polyline_image(dk3_fig_drawing_t *drw, char *lp) { char *p1; /* Text for flipped-flag. */ char *p2; /* File name. */ int i; /* Flag: Flipped. */ int ec = 1; /* Error code. */ int back = 0; $? "+ dk3figrd_polyline_image \"%s\"", TR_STR(lp) if(drw->cobj) { p1 = dk3str_c8_start(lp, NULL); if(p1) { p2 = dk3str_c8_next(p1, NULL); if(p2) { if(1 == sscanf(p1, "%d", &i)) { ((drw->cobj)->dt).pol.flf = ((i) ? 1 : 0); if(!(((drw->cobj)->dt).pol.fn)) { ((drw->cobj)->dt).pol.fn = dk3str_c8_dup_app(p2, drw->app); if(((drw->cobj)->dt).pol.fn) { back = 1; drw->state = DK3_FIG_RD_STATE_PL_POINTS; } else { ec = 2; } } } } } } else { $? "! bug cobj" } if(!(back)) { switch(ec) { case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break; case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break; } } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_polyline_image %d", back return back; } /** Read point data or control data. @param drw @param lp @return 1 on success, 0 on error. */ static int dk3figrd_point_data(dk3_fig_drawing_t *drw, char *lp) { dk3_fig_poly_point_t *pp = NULL; /* Point to read. */ dk3_fig_spline_point_t *sp = NULL; /* Point to read. */ char *pc; /* Current text word. */ char *pn; /* Next text. */ double d; /* Result sscanf(). */ int cc = 1; /* Flag: Can continue. */ int ec = 1; /* Error code. */ int back = 1; $? "+ dk3figrd_point_data \"%s\"", TR_STR(lp) if(drw->cobj) { switch((drw->cobj)->ot) { case DK3_FIG_OBJ_POLYLINE: { pp = ((drw->cobj)->dt).pol.po; if(!(pp)) { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); } } break; case DK3_FIG_OBJ_SPLINE: { sp = ((drw->cobj)->dt).spl.po; if(!(sp)) { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); } } break; default: { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); $? "! wrong object type bug" } break; } if(back) { pc = dk3str_c8_start(lp, NULL); while((cc) && (back) && (pc)) { pn = dk3str_c8_next(pc, NULL); $? ". pc = \"%s\"", pc if(1 == sscanf(pc, "%lg", &d)) { switch((drw->cobj)->ot) { case DK3_FIG_OBJ_POLYLINE: { if(drw->cind < ((drw->cobj)->dt).pol.np) { if(drw->cxy) { $? ". polyline y %lu",(unsigned long)(drw->cind) pp[drw->cind].y = d; drw->cxy = 0; drw->cind += 1; } else { $? ". polyline x %lu",(unsigned long)(drw->cind) pp[drw->cind].x = d; drw->cxy = 1; } } if(drw->cind >= ((drw->cobj)->dt).pol.np) { drw->state = DK3_FIG_RD_STATE_READY; cc = 0; } } break; case DK3_FIG_OBJ_SPLINE: { if(DK3_FIG_RD_STATE_SP_CONTROL == drw->state) { if(drw->cind < ((drw->cobj)->dt).spl.np) { sp[drw->cind].s = d; $? ". spl s %lu", (unsigned long)(drw->cind) drw->cind += 1; } if(drw->cind >= ((drw->cobj)->dt).spl.np) { drw->state = DK3_FIG_RD_STATE_READY; cc = 0; } } else { if(drw->cind < ((drw->cobj)->dt).spl.np) { if(drw->cxy) { $? ". spl y %lu", (unsigned long)(drw->cind) sp[drw->cind].y = d; drw->cxy = 0; drw->cind += 1; } else { $? ". spl x %lu", (unsigned long)(drw->cind) sp[drw->cind].x = d; drw->cxy = 1; } } if(drw->cind >= ((drw->cobj)->dt).spl.np) { drw->state = DK3_FIG_RD_STATE_SP_CONTROL; drw->cind = 0; drw->cxy = 0; $? ". switching to spline control" } } } break; } } else { cc = 0; dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } pc = pn; } } } else { $? "! cobj bug" } dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_point_data %d", back return back; } /** Process comment line. @param drw Drawing to modify. @param lp Text line to process. */ static void dk3figrd_process_comment(dk3_fig_drawing_t *drw, char *lp) { char *cp[16]; char *lp1; size_t ncp; $? "+ dk3figrd_process_comment \"%s\"", TR_STR(lp) switch(drw->state) { case DK3_FIG_RD_STATE_EXPECT_ORIENTATION: { if(DK3_FIG_SRCTYPE_UNKNOWN == drw->srctype) { lp1 = lp; lp1++; lp1 = dk3str_c8_start(lp1, NULL); if(lp1) { ncp = dk3str_c8_explode(cp, 15, lp1, NULL); if(ncp >= 3) { if(dk3str_c8_casecmp(cp[0], dk3figrd_c8_kw[1]) == 0) { if(dk3str_c8_casecmp(cp[1], dk3figrd_c8_kw[2]) == 0) { if(dk3str_c8_casecmp(cp[2], dk3figrd_c8_kw[3]) == 0) { drw->srctype = DK3_FIG_SRCTYPE_WINFIG; $? ". WinFIG" } } } } } } } break; } $? "- dk3figrd_process_comment" } /** Apply one input line to drawing, LC_NUMERIC is set correctly. @param drw Drawing to modify. @param lp Text to process. @return 1 on success, 0 on error. */ static int dk3fig_read_my_apply_line(dk3_fig_drawing_t *drw, char *lp) { char *p1; /* Start of line. */ int back = 0; $? "+ dk3fig_read_my_apply_line %lu \"%s\"", (1UL + drw->lineno), TR_STR(lp) if((drw) && (lp)) { drw->lineno += 1UL; if(drw->app) { dk3app_set_source_line(drw->app, drw->lineno); } p1 = dk3str_c8_start(lp, NULL); if(p1) { dk3str_c8_delnl(p1); if(DK3_FIG_RD_STATE_START == drw->state) { back = dk3figrd_expect_start(drw, p1); } else { if('#' != *p1) { switch(drw->state) { case DK3_FIG_RD_STATE_EXPECT_ORIENTATION: { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION; } break; case DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION: { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_UNITS; } break; case DK3_FIG_RD_STATE_EXPECT_UNITS: { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_PAPERSIZE; } break; case DK3_FIG_RD_STATE_EXPECT_PAPERSIZE: { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION; } break; case DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION: { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_MULTIPAGE; } break; case DK3_FIG_RD_STATE_EXPECT_MULTIPAGE: { back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_TRANSPARENT; } break; case DK3_FIG_RD_STATE_EXPECT_TRANSPARENT: { back = dk3figrd_expect_transparent(drw, p1); } break; case DK3_FIG_RD_STATE_EXPECT_RESOLUTION: { back = dk3figrd_expect_resolution(drw, p1); } break; case DK3_FIG_RD_STATE_READY: { back = dk3figrd_start_object(drw, p1); } break; case DK3_FIG_RD_STATE_ARC_ARROW_FORWARD: { back = dk3figrd_arc_arrow(drw, p1); } break; case DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD: { back = dk3figrd_arc_arrow(drw, p1); } break; case DK3_FIG_RD_STATE_PL_ARROW_FORWARD: { back = dk3figrd_polyline_arrow(drw, p1); } break; case DK3_FIG_RD_STATE_PL_ARROW_BACKWARD: { back = dk3figrd_polyline_arrow(drw, p1); } break; case DK3_FIG_RD_STATE_PL_IMAGE: { back = dk3figrd_polyline_image(drw, p1); } break; case DK3_FIG_RD_STATE_PL_POINTS: { back = dk3figrd_point_data(drw, p1); } break; case DK3_FIG_RD_STATE_SP_ARROW_FORWARD: { back = dk3figrd_spline_arrow(drw, p1); } break; case DK3_FIG_RD_STATE_SP_ARROW_BACKWARD: { back = dk3figrd_spline_arrow(drw, p1); } break; case DK3_FIG_RD_STATE_SP_POINTS: { back = dk3figrd_point_data(drw, p1); } break; case DK3_FIG_RD_STATE_SP_CONTROL: { back = dk3figrd_point_data(drw, p1); } break; } } else { back = 1; $? ". comment line" dk3figrd_process_comment(drw, p1); } } } else { back = 1; $? ". empty line" } if(!(back)) { drw->state = DK3_FIG_RD_STATE_ERROR; } if(DK3_FIG_RD_STATE_ERROR == drw->state) { /* ERROR: Error while reading input file! */ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 6); } if(DK3_FIG_RD_STATE_READY == drw->state) { drw->cobj = NULL; drw->cind = 0; drw->cxy = 0; } } else { $? "! args" } $? "- dk3fig_read_my_apply_line %d", back return back; } int dk3fig_read_apply_line(dk3_fig_drawing_t *drw, char *lp) { int back; #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H char *oldlocale; #endif #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H $? ". set locale to C" oldlocale = setlocale(LC_NUMERIC, "C"); #endif back = dk3fig_read_my_apply_line(drw, lp); #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H if(oldlocale) { $? ". restore old locale" setlocale(LC_NUMERIC, oldlocale); } #endif return back; } int dk3fig_read_file(dk3_fig_drawing_t *drw, FILE *fipo) { char il[DK3_FIG_LINE_SIZE]; /* Input line buffer. */ #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H char *oldlocale; #endif int cc; /* Flag: Can continue. */ int back = 0; $? "+ dk3fig_read_file" if((drw) && (fipo)) { #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H $? ". change locale to C" oldlocale = setlocale(LC_NUMERIC, "C"); #endif back = 1; cc = 1; while((back) && (cc)) { if(fgets(il, sizeof(il), fipo)) { if(!dk3fig_read_my_apply_line(drw, il)) { $? "! error in line" back = 0; } } else { $? ". end of file" cc = 0; } } #if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H if(oldlocale) { $? ". restore old locale" setlocale(LC_NUMERIC, oldlocale); } #endif } else { $? "! args" } $? "- dk3fig_read_file %d", back return back; } int dk3fig_read_file_name(dk3_fig_drawing_t *drw, dkChar const *fn) { dkChar const *oldsrcname = NULL; /* Saved source file name. */ FILE *fipo; /* Input file. */ unsigned long oldsrcline = 0UL; /* Saved source line number. */ int back = 0; $? "+ dk3fig_read_file_name \"%s\"", TR_STR(fn) if((drw) && (fn)) { if(drw->app) { oldsrcname = dk3app_get_source_file(drw->app); oldsrcline = dk3app_get_source_line(drw->app); dk3app_set_source_file(drw->app, fn); dk3app_set_source_line(drw->app, 0UL); } fipo = dk3sf_fopen_app(fn, dk3figrd_kw[0], drw->app); if(fipo) { back = dk3fig_read_file(drw, fipo); fclose(fipo); } else { $? "! fopen" dk3fig_set_ec(drw, DK3_ERROR_SYSTEM); } if(drw->app) { dk3app_set_source_file(drw->app, oldsrcname); dk3app_set_source_line(drw->app, oldsrcline); } } else { $? "! args" if(drw) { dk3fig_set_ec(drw, DK3_ERROR_INVALID_ARGS); } } $? "- dk3fig_read_file_name %d", back return back; }