home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xfig2.8 / part13 / read.c < prev   
C/C++ Source or Header  |  1990-07-03  |  17KB  |  741 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : August 1985.
  7.  *    2nd revision : March 1988.
  8.  *
  9.  *    %W%    %G%
  10. */
  11. #include "fig.h"
  12. #include "alloc.h"
  13. #include "object.h"
  14. #include "psfonts.h"
  15.  
  16. extern F_arrow        *make_arrow();
  17. extern char        *calloc();
  18. extern int        errno;
  19.  
  20. static F_ellipse    *read_ellipseobject();
  21. static F_line        *read_lineobject();
  22. static F_text        *read_textobject();
  23. static F_spline        *read_splineobject();
  24. static F_arc        *read_arcobject();
  25. static F_compound    *read_compoundobject();
  26.  
  27. #define            BUF_SIZE        1024
  28.  
  29. char        buf[BUF_SIZE];
  30. int        line_no;
  31. int        num_object;
  32. int        proto;        /* file protocol*10 */
  33.  
  34. read_fail_message(file, err)
  35. char    *file;
  36. int    err;
  37. {
  38.     extern char    *sys_errlist[];
  39.  
  40.     if (err == 0)        /* Successful read */
  41.         return;
  42. #ifdef ENAMETOOLONG
  43.     else if (err == ENAMETOOLONG)
  44.         put_msg("File name \"%s\" is too long", file);
  45. #endif
  46.     else if (err == ENOENT)
  47.         put_msg("File \"%s\" does not exist", file);
  48.     else if (err == ENOTDIR)
  49.         put_msg("A name in the path \"%s\" is not a directory", file);
  50.     else if (err == EACCES)
  51.         put_msg("Read access to file \"%s\" is blocked", file);
  52.     else if (err == EISDIR)
  53.         put_msg("File \"%s\" is a directory", file);
  54.     else if (err == -2) {
  55.         put_msg("File \"%s\" is empty", file);
  56.         }
  57.     else if (err == -1) {
  58.         /* Format error; relevant error message is already delivered */
  59.         }
  60.     else
  61.         put_msg("File \"%s\" is not accessable; %s", file, sys_errlist[err]);
  62.     }
  63.  
  64. /**********************************************************
  65. Read_fig returns :
  66.  
  67.      0 : successful read.
  68.     -1 : File is in incorrect format
  69.     -2 : File is empty
  70. err_no : if file can not be read for various reasons
  71.  
  72. The resolution (ppi) and the coordinate system (coord_sys) are
  73. stored in obj->nwcorner.x and obj->nwcorner.y respectively.
  74. The coordinate system is 1 for lower left at 0,0 and 
  75. 2 for upper left at 0,0
  76. >>> xfig only uses 2 for the coordinate system. <<<
  77. **********************************************************/
  78.  
  79. read_fig(file_name, obj)
  80. char        *file_name;
  81. F_compound    *obj;
  82. {
  83.     FILE    *fp;
  84.  
  85.     line_no = 0;
  86.     if ((fp = fopen(file_name, "r")) == NULL)
  87.         return(errno);
  88.     else
  89.         return(readfp_fig(fp, obj));
  90.     }
  91.  
  92. readfp_fig(fp, obj)
  93. FILE  *fp;
  94. F_compound    *obj;
  95. {
  96.     int    status;
  97.     float    fproto;
  98.   
  99.     num_object = 0;
  100.     bzero((char*)obj, COMOBJ_SIZE);
  101.     if (fgets(buf,BUF_SIZE,fp)==0)    /* version */
  102.         return -2;
  103.     if (strncmp(buf,"#FIG",4)==0)    /* versions 1.4/later have #FIG in first line */
  104.         {
  105.         if ((sscanf(index(buf,' ')+1,"%f",&fproto))==0)    /* assume 1.4 */
  106.             proto=14;
  107.         else
  108.             proto = (fproto+.01)*10;    /* protocol version*10 */
  109.         status = read_objects(fp, obj);
  110.         }
  111.     else
  112.         {
  113.         proto = 13;
  114.         status = read_1_3_objects(fp, obj);
  115.         }
  116.  
  117.     fclose(fp);
  118.     return(status);
  119.         }
  120.     
  121. int
  122. read_objects(fp, obj)
  123. FILE        *fp;
  124. F_compound    *obj;
  125. {
  126.     F_ellipse    *e, *le = NULL;
  127.     F_line        *l, *ll = NULL;
  128.     F_text        *t, *lt = NULL;
  129.     F_spline    *s, *ls = NULL;
  130.     F_arc        *a, *la = NULL;
  131.     F_compound    *c, *lc = NULL;
  132.     int        object, ppi, coord_sys;
  133.  
  134.     line_no++;
  135.     if (get_line(fp) < 0) {
  136.         put_msg("File is truncated");
  137.         return(-1);
  138.         }
  139.     if (2 != sscanf(buf,"%d%d\n", &ppi, &coord_sys)) {
  140.         put_msg("Incomplete data at line %d", line_no);
  141.         return(-1);
  142.         }
  143.  
  144.     obj->nwcorner.x = ppi;
  145.     obj->nwcorner.y = coord_sys;
  146.     while (get_line(fp) > 0) {
  147.         if (1 != sscanf(buf, "%d", &object)) {
  148.         put_msg("Incorrect format at line %d", line_no);
  149.         return(-1);
  150.         }
  151.         switch (object) {
  152.         case O_POLYLINE :
  153.             if ((l = read_lineobject(fp)) == NULL) return(-1);
  154.             if (ll)
  155.             ll = (ll->next = l);
  156.             else 
  157.             ll = obj->lines = l;
  158.             num_object++;
  159.             break;
  160.         case O_SPLINE :
  161.             if ((s = read_splineobject(fp)) == NULL) return(-1);
  162.             if (ls)
  163.             ls = (ls->next = s);
  164.             else 
  165.             ls = obj->splines = s;
  166.             num_object++;
  167.             break;
  168.         case O_ELLIPSE :
  169.             if ((e = read_ellipseobject()) == NULL) return(-1);
  170.             if (le)
  171.             le = (le->next = e);
  172.             else 
  173.             le = obj->ellipses = e;
  174.             num_object++;
  175.             break;
  176.         case O_ARC :
  177.             if ((a = read_arcobject(fp)) == NULL) return(-1);
  178.             if (la)
  179.             la = (la->next = a);
  180.             else 
  181.             la = obj->arcs = a;
  182.             num_object++;
  183.             break;
  184.         case O_TEXT :
  185.             if ((t = read_textobject(fp)) == NULL) return(-1);
  186.             if (lt)
  187.             lt = (lt->next = t);
  188.             else 
  189.             lt = obj->texts = t;
  190.             num_object++;
  191.             break;
  192.         case O_COMPOUND :
  193.             if ((c = read_compoundobject(fp)) == NULL) return(-1);
  194.             if (lc)
  195.             lc = (lc->next = c);
  196.             else 
  197.             lc = obj->compounds = c;
  198.             num_object++;
  199.             break;
  200.         default :
  201.             put_msg("Incorrect object code at line %d", line_no);
  202.             return(-1);
  203.         } /*  switch */
  204.         } /*  while */
  205.     if (feof(fp))
  206.         return(0);
  207.     else
  208.         return(errno);
  209.     } /*  read_objects */
  210.  
  211. static F_arc *
  212. read_arcobject(fp)
  213. FILE    *fp;
  214. {
  215.     F_arc    *a;
  216.     int    n, fa, ba;
  217.     int    type, style;
  218.     float    thickness, wid, ht;
  219.  
  220.     if (NULL == (Arc_malloc(a))) {
  221.         put_msg(Err_mem);
  222.         return(NULL);
  223.         }
  224.     a->next = NULL;
  225.     a->for_arrow = a->back_arrow = NULL;    /* added 8/23/89 B.V.Smith */
  226.     n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%f%f%d%d%d%d%d%d\n",
  227.         &a->type, &a->style, &a->thickness, 
  228.         &a->color, &a->depth, 
  229.         &a->pen, &a->area_fill,
  230.         &a->style_val, &a->direction, &fa, &ba,
  231.         &a->center.x, &a->center.y, 
  232.         &a->point[0].x, &a->point[0].y, 
  233.         &a->point[1].x, &a->point[1].y, 
  234.         &a->point[2].x, &a->point[2].y);
  235.     if (n != 19) {
  236.         put_msg(Err_incomp, "arc", line_no);
  237.         free((char*)a);
  238.         return(NULL);
  239.         }
  240.  
  241.     skip_comment(fp);
  242.     if (fa) {
  243.         line_no++;
  244.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  245.         fprintf(stderr, Err_incomp, "arc", line_no);
  246.         return(NULL);
  247.         }
  248.         skip_line(fp);
  249.         a->for_arrow = make_arrow(type, style, thickness, wid, ht);
  250.         skip_comment(fp);
  251.         }
  252.     skip_comment(fp);
  253.     if (ba) {
  254.         line_no++;
  255.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  256.         fprintf(stderr, Err_incomp, "arc", line_no);
  257.         return(NULL);
  258.         }
  259.         skip_line(fp);
  260.         a->back_arrow = make_arrow(type, style, thickness, wid, ht);
  261.         }
  262.     return(a);
  263.     }
  264.  
  265. static F_compound *
  266. read_compoundobject(fp)
  267. FILE    *fp;
  268. {
  269.     F_arc        *a, *la = NULL;
  270.     F_ellipse    *e, *le = NULL;
  271.     F_line        *l, *ll = NULL;
  272.     F_spline    *s, *ls = NULL;
  273.     F_text        *t, *lt = NULL;
  274.     F_compound    *com, *c, *lc = NULL;
  275.     int        n, object;
  276.  
  277.     if (NULL == (Compound_malloc(com))) {
  278.         put_msg(Err_mem);
  279.         return(NULL);
  280.         }
  281.     com->arcs = NULL;
  282.     com->ellipses = NULL;
  283.     com->lines = NULL;
  284.     com->splines = NULL;
  285.     com->texts = NULL;
  286.     com->compounds = NULL;
  287.     com->next = NULL;
  288.     n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y,
  289.         &com->secorner.x, &com->secorner.y);
  290.     if (4 != n) {
  291.         put_msg(Err_incomp, "compound", line_no);
  292.         free((char*)com);
  293.         return(NULL);
  294.         }
  295.     while (get_line(fp) > 0) {
  296.         if (1 != sscanf(buf, "%d", &object)) {
  297.         put_msg(Err_incomp, "compound", line_no);
  298.         free_compound(&com);
  299.         return(NULL);
  300.         }
  301.         switch (object) {
  302.         case O_POLYLINE :
  303.             if ((l = read_lineobject(fp)) == NULL) { 
  304.             free_line(&l);
  305.             return(NULL);
  306.             }
  307.             if (ll)
  308.             ll = (ll->next = l);
  309.             else 
  310.             ll = com->lines = l;
  311.             break;
  312.         case O_SPLINE :
  313.             if ((s = read_splineobject(fp)) == NULL) { 
  314.             free_spline(&s);
  315.             return(NULL);
  316.             }
  317.             if (ls)
  318.             ls = (ls->next = s);
  319.             else 
  320.             ls = com->splines = s;
  321.             break;
  322.         case O_ELLIPSE :
  323.             if ((e = read_ellipseobject()) == NULL) { 
  324.             free_ellipse(&e);
  325.             return(NULL);
  326.             }
  327.             if (le)
  328.             le = (le->next = e);
  329.             else 
  330.             le = com->ellipses = e;
  331.             break;
  332.         case O_ARC :
  333.             if ((a = read_arcobject(fp)) == NULL) { 
  334.             free_arc(&a);
  335.             return(NULL);
  336.             }
  337.             if (la)
  338.             la = (la->next = a);
  339.             else 
  340.             la = com->arcs = a;
  341.             break;
  342.         case O_TEXT :
  343.             if ((t = read_textobject(fp)) == NULL) { 
  344.             free_text(&t);
  345.             return(NULL);
  346.             }
  347.             if (lt)
  348.             lt = (lt->next = t);
  349.             else 
  350.             lt = com->texts = t;
  351.             break;
  352.         case O_COMPOUND :
  353.             if ((c = read_compoundobject(fp)) == NULL) { 
  354.             free_compound(&c);
  355.             return(NULL);
  356.             }
  357.             if (lc)
  358.             lc = (lc->next = c);
  359.             else 
  360.             lc = com->compounds = c;
  361.             break;
  362.         case O_END_COMPOUND :
  363.             return(com);
  364.         default :
  365.             put_msg("Wrong object code at line %d", line_no);
  366.             return(NULL);
  367.         } /*  switch */
  368.         }
  369.     if (feof(fp))
  370.         return(com);
  371.     else
  372.         return(NULL);
  373.     }
  374.  
  375. static F_ellipse *
  376. read_ellipseobject()
  377. {
  378.     F_ellipse    *e;
  379.     int        n;
  380.  
  381.     if (NULL == (Ellipse_malloc(e))) {
  382.         put_msg(Err_mem);
  383.         return(NULL);
  384.         }
  385.     e->next = NULL;
  386.     n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%f%d%d%d%d%d%d%d%d\n",
  387.         &e->type, &e->style, &e->thickness,
  388.         &e->color, &e->depth, &e->pen, &e->area_fill,
  389.         &e->style_val, &e->direction, &e->angle,
  390.         &e->center.x, &e->center.y, 
  391.         &e->radiuses.x, &e->radiuses.y, 
  392.         &e->start.x, &e->start.y, 
  393.         &e->end.x, &e->end.y);
  394.     if (n != 18) {
  395.         put_msg(Err_incomp, "ellipse", line_no);
  396.         free((char*)e);
  397.         return(NULL);
  398.         }
  399.     return(e);
  400.     }
  401.  
  402. static F_line *
  403. read_lineobject(fp)
  404. FILE    *fp;
  405. {
  406.     F_line    *l;
  407.     F_point    *p, *q;
  408.     int    n, x, y, fa, ba;
  409.     int    type, style;
  410.     float    thickness, wid, ht;
  411.  
  412.     if (NULL == (Line_malloc(l))) {
  413.         put_msg(Err_mem);
  414.         return(NULL);
  415.         }
  416.     l->points = NULL;
  417.     l->for_arrow = l->back_arrow = NULL;
  418.     l->next = NULL;
  419.  
  420.     sscanf(buf,"%*d%d",&l->type);
  421. #ifndef TFX
  422.     /* 2.0 or later; has separate radius parm for arc-box corners */
  423.     if (l->type == T_ARC_BOX && proto >= 20)
  424.         {
  425.         n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d",
  426.             &l->type, &l->style, &l->thickness, &l->color,
  427.             &l->depth, &l->pen, &l->area_fill, &l->style_val, &l->radius,
  428.             &fa, &ba);
  429.         }
  430.     /* old format uses pen for radius of arc-box corners */
  431.     else
  432. #endif TFX
  433.         {
  434.         n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d",
  435.             &l->type, &l->style, &l->thickness, &l->color,
  436.             &l->depth, &l->pen, &l->area_fill, &l->style_val, &fa, &ba);
  437. #ifndef TFX
  438.         if (l->type == T_ARC_BOX)
  439.             {
  440.             l->radius = l->pen;
  441.             l->pen = 0;
  442.             }
  443.         else
  444. #endif TFX
  445.             l->radius = 0;
  446.         }
  447.  
  448. #ifdef TFX
  449.     if (n != 10)
  450. #else
  451.     if ((proto==14 && n != 10) || 
  452.         (proto==20 && (l->type == T_ARC_BOX && n != 11) || 
  453.               (l->type != T_ARC_BOX && n != 10))) {
  454. #endif TFX
  455.         put_msg(Err_incomp, "line", line_no);
  456.         free((char*)l);
  457.         return(NULL);
  458.         }
  459.     skip_comment(fp);
  460.     if (fa) {
  461.         line_no++;
  462.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  463.         fprintf(stderr, Err_incomp, "line", line_no);
  464.         return(NULL);
  465.         }
  466.         skip_line(fp);
  467.         l->for_arrow = make_arrow(type, style, thickness, wid, ht);
  468.         skip_comment(fp);
  469.         }
  470.     if (ba) {
  471.         line_no++;
  472.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  473.         fprintf(stderr, Err_incomp, "line", line_no);
  474.         return(NULL);
  475.         }
  476.         skip_line(fp);
  477.         l->back_arrow = make_arrow(type, style, thickness, wid, ht);
  478.         skip_comment(fp);
  479.         }
  480.  
  481.     if (NULL == (l->points = Point_malloc(p))) {
  482.         put_msg(Err_mem);
  483.         return(NULL);
  484.         }
  485.     p->next = NULL;
  486.  
  487.     /* points start on new line */
  488.     line_no++;
  489.  
  490.     /* read first point */
  491.     if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
  492.         put_msg(Err_incomp, "line", line_no);
  493.         free_linestorage(l);
  494.         return(NULL);
  495.         }
  496.     /* read subsequent points */
  497.     for (;;) {
  498.         if (fscanf(fp, "%d%d", &x, &y) != 2) {
  499.         put_msg(Err_incomp, "line", line_no);
  500.         free_linestorage(l);
  501.         return(NULL);
  502.         }
  503.         if (x == 9999) break;
  504.         if (NULL == (Point_malloc(q))) {
  505.         put_msg(Err_mem);
  506.         free_linestorage(l);
  507.         return(NULL);
  508.         }
  509.         q->x = x;
  510.         q->y = y;
  511.         q->next = NULL;
  512.         p->next = q;
  513.         p = q;
  514.         }
  515.     skip_line(fp);
  516.     return(l);
  517.     }
  518.  
  519. static F_spline *
  520. read_splineobject(fp)
  521. FILE    *fp;
  522. {
  523.     F_spline    *s;
  524.     F_point        *p, *q;
  525.     F_control    *cp, *cq;
  526.     int        c, n, x, y, fa, ba;
  527.     int        type, style;
  528.     float        thickness, wid, ht;
  529.     float        lx, ly, rx, ry;
  530.  
  531.     if (NULL == (Spline_malloc(s))) {
  532.         put_msg(Err_mem);
  533.         return(NULL);
  534.         }
  535.     s->points = NULL;
  536.     s->controls = NULL;
  537.     s->for_arrow = s->back_arrow = NULL;
  538.     s->next = NULL;
  539.  
  540.     n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%d%d%d", 
  541.             &s->type, &s->style, &s->thickness, &s->color,
  542.         &s->depth, &s->pen, &s->area_fill, &s->style_val, &fa, &ba);
  543.     if (n != 10) {
  544.         put_msg(Err_incomp, "spline", line_no);
  545.         free((char*)s);
  546.         return(NULL);
  547.         }
  548.     skip_comment(fp);
  549.     if (fa) {
  550.         line_no++;
  551.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  552.         fprintf(stderr, Err_incomp, "spline", line_no);
  553.         return(NULL);
  554.         }
  555.         skip_line(fp);
  556.         s->for_arrow = make_arrow(type, style, thickness, wid, ht);
  557.         skip_comment(fp);
  558.         }
  559.     if (ba) {
  560.         line_no++;
  561.         if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
  562.         fprintf(stderr, Err_incomp, "spline", line_no);
  563.         return(NULL);
  564.         }
  565.         skip_line(fp);
  566.         s->back_arrow = make_arrow(type, style, thickness, wid, ht);
  567.         skip_comment(fp);
  568.         }
  569.  
  570.     line_no++;
  571.  
  572.     /* Read points */
  573.     if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) {
  574.         put_msg(Err_incomp, "spline", line_no);
  575.         free_splinestorage(s);
  576.         return(NULL);
  577.         };
  578.     if (NULL == (s->points = Point_malloc(p))) {
  579.         put_msg(Err_mem);
  580.         free_splinestorage(s);
  581.         return(NULL);
  582.         }
  583.     p->x = x; p->y = y;
  584.     for (c = 1;;) {
  585.         if (fscanf(fp, "%d%d", &x, &y) != 2) {
  586.         put_msg(Err_incomp, "spline", line_no);
  587.         p->next = NULL;
  588.         free_splinestorage(s);
  589.         return(NULL);
  590.         };
  591.         if (x == 9999) break;
  592.         if (NULL == (Point_malloc(q))) {
  593.         put_msg(Err_mem);
  594.         free_splinestorage(s);
  595.         return(NULL);
  596.         }
  597.         q->x = x;
  598.         q->y = y;
  599.         p->next = q;
  600.         p = q;
  601.         c++;
  602.         }
  603.     p->next = NULL;
  604.     skip_line(fp);
  605.  
  606.     if (normal_spline(s)) return(s);
  607.  
  608.     line_no++;
  609.     skip_comment(fp);
  610.     /* Read controls */
  611.     if ((n = fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry)) != 4) {
  612.         put_msg(Err_incomp, "spline", line_no);
  613.         free_splinestorage(s);
  614.         return(NULL);
  615.         };
  616.     if (NULL == (s->controls = Control_malloc(cp))) {
  617.         put_msg(Err_mem);
  618.         free_splinestorage(s);
  619.         return(NULL);
  620.         }
  621.     cp->lx = lx; cp->ly = ly;
  622.     cp->rx = rx; cp->ry = ry;
  623.     while (--c) {
  624.         if (fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry) != 4) {
  625.         put_msg(Err_incomp, "spline", line_no);
  626.         cp->next = NULL;
  627.         free_splinestorage(s);
  628.         return(NULL);
  629.         };
  630.         if (NULL == (Control_malloc(cq))) {
  631.         put_msg(Err_mem);
  632.         cp->next = NULL;
  633.         free_splinestorage(s);
  634.         return(NULL);
  635.         }
  636.         cq->lx = lx; cq->ly = ly;
  637.         cq->rx = rx; cq->ry = ry;
  638.         cp->next = cq;
  639.         cp = cq;
  640.         }
  641.     cp->next = NULL;
  642.  
  643.     skip_line(fp);
  644.     return(s);
  645.     }
  646.  
  647. static F_text *
  648. read_textobject(fp)
  649. FILE    *fp;
  650. {
  651.     F_text    *t;
  652.     int    n;
  653.     int    ignore = 0;
  654.     char    s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];
  655.  
  656.     if (NULL == (Text_malloc(t))) {
  657.         put_msg(Err_mem);
  658.         return(NULL);
  659.         }
  660.     t->next = NULL;
  661.     /* The text object is terminated by a CONTROL-A, so we read
  662.            everything up to the CONTROL-A and then read that character.
  663.            If we do not find the CONTROL-A on this line then this must
  664.            be a multi-line text object and we will have to read more. */
  665.     n = sscanf(buf,"%*d%d%d%d%d%d%d%f%d%d%d%d%d %[^\1]%[\1]",
  666.         &t->type, &t->font, &t->size, &t->pen,
  667.         &t->color, &t->depth, &t->angle,
  668.         &t->style, &t->height, &t->length, 
  669.         &t->base_x, &t->base_y, s, junk);
  670.     if (n != 13 && n != 14) {
  671.         put_msg(Err_incomp, "text", line_no);
  672.         free((char*)t);
  673.         /* return(NULL); */
  674.         }
  675.     if (n == 13) {
  676.       /* Read in the remainder of the text object. */
  677.       do {
  678.         fgets(buf, BUF_SIZE, fp);
  679.         line_no++;          /* As is done in get_line */
  680.         n = sscanf(buf,"%[^\1]%[\1]", s_temp, junk);
  681.         /* Safety check */
  682.         if (strlen(s)+1 + strlen(s_temp)+1 > BUF_SIZE) {
  683.           /* Too many characters.  Ignore the rest. */
  684.           ignore = 1;
  685.         }
  686.         if (!ignore)
  687.           strcat(s, s_temp);
  688.       } while (n == 1);
  689.     }
  690.     if (t->type > T_RIGHT_JUSTIFIED)
  691.         {
  692.         put_msg("Invalid text justification at line %d.",line_no);
  693.         return(NULL);
  694.         }
  695.     if (t->font >= NUMFONTS)
  696.         {
  697.         put_msg("Invalid text font (%d) at line %d.",t->font,line_no);
  698.         return(NULL);
  699.         }
  700.     if (strlen(s) == 0)
  701.         (void) strcpy(s," ");
  702.     t->cstring = (char*)calloc((unsigned)(strlen(s)+1), sizeof(char));
  703.     if (NULL == t->cstring) {
  704.         put_msg(Err_mem);
  705.         free((char*)t);
  706.         return(NULL);
  707.         }
  708.     (void) strcpy(t->cstring, s);
  709.     return(t);
  710.     }
  711.  
  712. get_line(fp)
  713. FILE    *fp;
  714. {
  715.     while (1) {
  716.         if (NULL == fgets(buf, BUF_SIZE, fp)) {
  717.         return(-1);
  718.         }
  719.         line_no++;
  720.         if (*buf != '\n' && *buf != '#')    /* Skip empty and comment lines */
  721.         return(1);
  722.         }
  723.     }
  724.  
  725. skip_comment(fp)
  726. FILE    *fp;
  727. {
  728.     char c;
  729.  
  730.     while ((c = fgetc(fp)) == '#') skip_line(fp);
  731.     if (c != '#') ungetc(c, fp);
  732.     }
  733.  
  734. skip_line(fp)
  735. FILE    *fp;
  736. {
  737.     while (fgetc(fp) != '\n') {
  738.         if (feof(fp)) return;
  739.         }
  740.     }
  741.