DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦820687668⟧ TextFile

    Length: 16332 (0x3fcc)
    Types: TextFile
    Names: »read.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z« 
        └─⟦036c765ac⟧ 
            └─⟦this⟧ »TeX3.0/TeXgraphics/transfig/fig2dev/read.c« 

TextFile

#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "alloc.h"
#include "object.h"

#ifdef hpux
#define bzero(s,n) memset((s),'\0',(n))
#endif

#ifdef gould
extern int            errno;
#endif

extern void		fprintf(), ungetc();
extern F_arrow		*make_arrow();
extern char		*calloc();

static F_ellipse	*read_ellipseobject();
static F_line		*read_lineobject();
static F_text		*read_textobject();
static F_spline		*read_splineobject();
static F_arc		*read_arcobject();
static F_compound	*read_compoundobject();

#define			BUF_SIZE		1024

char			buf[BUF_SIZE];
int			line_no = 0;
int			num_object;
int			tfx_flag;	/* TFX compatible */
int			x_flag;		/* xfig1.4X or 2.0 compatible */
int			v2_flag;	/* xfig2.0  compatible */

read_fail_message(file, err)
char	*file;
int	err;
{
	extern char	*sys_errlist[];

	if (err == 0)		/* Successful read */
	    return;
	else if (err == ENAMETOOLONG)
	    put_msg("File name \"%s\" is too long", file);
	else if (err == ENOENT)
	    put_msg("File \"%s\" does not exist", file);
	else if (err == ENOTDIR)
	    put_msg("A name in the path \"%s\" is not a directory", file);
	else if (err == EACCES)
	    put_msg("Read access to file \"%s\" is blocked", file);
	else if (err == EISDIR)
	    put_msg("File \"%s\" is a directory", file);
	else if (err == -2) {
	    put_msg("File \"%s\" is empty", file);
	    }
	else if (err == -1) {
	    /* Format error; relevant error message is already delivered */
	    }
	else
	    put_msg("File \"%s\" is not accessable; %s", file, sys_errlist[err]);
	}

/**********************************************************
Read_fig returns :

     0 : successful read.
    -1 : File is in incorrect format
    -2 : File is empty
err_no : if file can not be read for various reasons

The resolution (ppi) and the cooridnate system (coord_sys) are
stored in obj->nwcorner.x and obj->nwcorner.x respectively.
**********************************************************/

read_fig(file_name, obj)
char		*file_name;
F_compound	*obj;
{
	FILE		*fp;

	if ((fp = fopen(file_name, "r")) == NULL)
	    return(errno);
	else
	    return(readfp_fig(fp, obj));
	}

readfp_fig(fp, obj)
FILE	*fp;
F_compound	*obj;
{
	char		c;
	int		status;

	num_object = 0;
	c = fgetc(fp);
	if (feof(fp)) return(-2);
	ungetc(c, fp);
	bzero((char*)obj, COMOBJ_SIZE);
	if (c == '#')
	    status = read_objects(fp, obj);
	else
	    status = read_1_3_objects(fp, obj);
	(void)fclose(fp);
	return(status);
	}
	
int
read_objects(fp, obj)
FILE		*fp;
F_compound	*obj;
{
	F_ellipse	*e, *le = NULL;
	F_line		*l, *ll = NULL;
	F_text		*t, *lt = NULL;
	F_spline	*s, *ls = NULL;
	F_arc		*a, *la = NULL;
	F_compound	*c, *lc = NULL;
	int		object, ppi, coord_sys;

	bzero((char*)obj, COMOBJ_SIZE);
	(void)fgets(buf, BUF_SIZE, fp);	/* get the version line */
	tfx_flag = (!strncmp(&buf[strlen(buf)-3], "TFX", 3)); /* check for TFX */
	v2_flag = (!strncmp(buf, "#FIG 2", 6));	/* v2.0 and later have extra
						   field for arc_box radius */
	x_flag = v2_flag || (!strncmp(buf, "#FIG 1.4X", 9));	/* non-TFX */

	line_no++;
	if (get_line(fp) < 0) {
	    put_msg("File is truncated");
	    return(-1);
	    }
	if (2 != sscanf(buf,"%d%d\n", &ppi, &coord_sys)) {
	    put_msg("Incomplete data at line %d", line_no);
	    return(-1);
	    }

	obj->nwcorner.x = ppi;
	obj->nwcorner.y = coord_sys;
	while (get_line(fp) > 0) {
	    if (1 != sscanf(buf, "%d", &object)) {
		put_msg("Incorrect format at line %d", line_no);
		return(-1);
		}
	    switch (object) {
		case O_POLYLINE :
		    if ((l = read_lineobject(fp)) == NULL) return(-1);
		    if (ll)
			ll = (ll->next = l);
		    else 
			ll = obj->lines = l;
		    num_object++;
		    break;
		case O_SPLINE :
		    if ((s = read_splineobject(fp)) == NULL) return(-1);
		    if (ls)
			ls = (ls->next = s);
		    else 
			ls = obj->splines = s;
		    num_object++;
		    break;
		case O_ELLIPSE :
		    if ((e = read_ellipseobject()) == NULL) return(-1);
		    if (le)
			le = (le->next = e);
		    else 
			le = obj->ellipses = e;
		    num_object++;
		    break;
		case O_ARC :
		    if ((a = read_arcobject(fp)) == NULL) return(-1);
		    if (la)
			la = (la->next = a);
		    else 
			la = obj->arcs = a;
		    num_object++;
		    break;
		case O_TEXT :
		    if ((t = read_textobject(fp)) == NULL) return(-1);
		    if (lt)
			lt = (lt->next = t);
		    else 
			lt = obj->texts = t;
		    num_object++;
		    break;
		case O_COMPOUND :
		    if ((c = read_compoundobject(fp)) == NULL) return(-1);
		    if (lc)
			lc = (lc->next = c);
		    else 
			lc = obj->compounds = c;
		    num_object++;
		    break;
		default :
		    put_msg("Incorrect object code at line %d", line_no);
		    return(-1);
		} /*  switch */
	    } /*  while */
	if (feof(fp))
	    return(0);
	else
	    return(errno);
	} /*  read_objects */

static F_arc *
read_arcobject(fp)
FILE	*fp;
{
	F_arc	*a;
	int	n, fa, ba;
	int	type, style;
	double	thickness, wid, ht;

	if (NULL == (Arc_malloc(a))) {
	    put_msg(Err_mem);
	    return(NULL);
	    }
	a->pen = NULL;
	a->area_fill = NULL;
	a->for_arrow = NULL;
	a->back_arrow = NULL;
	a->next = NULL;
	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d%d%lf%lf%d%d%d%d%d%d\n",
		&a->type, &a->style, &a->thickness, 
		&a->color, &a->depth, &a->pen, &a->area_fill, 
		&a->style_val, &a->direction, &fa, &ba,
		&a->center.x, &a->center.y, 
		&a->point[0].x, &a->point[0].y, 
		&a->point[1].x, &a->point[1].y, 
		&a->point[2].x, &a->point[2].y);
	if (n != 19) {
	    put_msg(Err_incomp, "arc", line_no);
	    free((char*)a);
	    return(NULL);
	    }

	skip_comment(fp);
	if (fa) {
	    line_no++;
	    if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
		fprintf(stderr, Err_incomp, "arc", line_no);
		return(NULL);
		}
	    skip_line(fp);
	    a->for_arrow = make_arrow(type, style, thickness, wid, ht);
	    skip_comment(fp);
	    }
	skip_comment(fp);
	if (ba) {
	    line_no++;
	    if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
		fprintf(stderr, Err_incomp, "arc", line_no);
		return(NULL);
		}
	    skip_line(fp);
	    a->back_arrow = make_arrow(type, style, thickness, wid, ht);
	    }
	return(a);
	}

static F_compound *
read_compoundobject(fp)
FILE	*fp;
{
	F_arc		*a, *la = NULL;
	F_ellipse	*e, *le = NULL;
	F_line		*l, *ll = NULL;
	F_spline	*s, *ls = NULL;
	F_text		*t, *lt = NULL;
	F_compound	*com, *c, *lc = NULL;
	int		n, object;

	Compound_malloc(com);
	com->arcs = NULL;
	com->ellipses = NULL;
	com->lines = NULL;
	com->splines = NULL;
	com->texts = NULL;
	com->compounds = NULL;
	com->next = NULL;
	n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y,
		&com->secorner.x, &com->secorner.y);
	if (4 != n) {
	    put_msg(Err_incomp, "compound", line_no);
	    free((char*)com);
	    return(NULL);
	    }
	while (get_line(fp) > 0) {
	    if (1 != sscanf(buf, "%d", &object)) {
		put_msg(Err_incomp, "compound", line_no);
		free_compound(&com);
		return(NULL);
		}
	    switch (object) {
		case O_POLYLINE :
		    if ((l = read_lineobject(fp)) == NULL) { 
			free_line(&l);
			return(NULL);
			}
		    if (ll)
			ll = (ll->next = l);
		    else 
			ll = com->lines = l;
		    break;
		case O_SPLINE :
		    if ((s = read_splineobject(fp)) == NULL) { 
			free_spline(&s);
			return(NULL);
			}
		    if (ls)
			ls = (ls->next = s);
		    else 
			ls = com->splines = s;
		    break;
		case O_ELLIPSE :
		    if ((e = read_ellipseobject()) == NULL) { 
			free_ellipse(&e);
			return(NULL);
			}
		    if (le)
			le = (le->next = e);
		    else 
			le = com->ellipses = e;
		    break;
		case O_ARC :
		    if ((a = read_arcobject(fp)) == NULL) { 
			free_arc(&a);
			return(NULL);
			}
		    if (la)
			la = (la->next = a);
		    else 
			la = com->arcs = a;
		    break;
		case O_TEXT :
		    if ((t = read_textobject(fp)) == NULL) { 
			free_text(&t);
			return(NULL);
			}
		    if (lt)
			lt = (lt->next = t);
		    else 
			lt = com->texts = t;
		    break;
		case O_COMPOUND :
		    if ((c = read_compoundobject(fp)) == NULL) { 
			free_compound(&c);
			return(NULL);
			}
		    if (lc)
			lc = (lc->next = c);
		    else 
			lc = com->compounds = c;
		    break;
		case O_END_COMPOUND :
		    return(com);
		default :
		    put_msg("Wrong object code at line %d", line_no);
		    return(NULL);
		} /*  switch */
	    }
	if (feof(fp))
	    return(com);
	else
	    return(NULL);
	}

static F_ellipse *
read_ellipseobject()
{
	F_ellipse	*e;
	int		n;

	Ellipse_malloc(e);
	e->area_fill = NULL;
	e->pen = NULL;
	e->next = NULL;
	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%lf%d%d%d%d%d%d%d%d\n",
		&e->type, &e->style, &e->thickness,
		&e->color, &e->depth, &e->pen, &e->area_fill,
		&e->style_val, &e->direction, &e->angle,
		&e->center.x, &e->center.y, 
		&e->radiuses.x, &e->radiuses.y, 
		&e->start.x, &e->start.y, 
		&e->end.x, &e->end.y);
	if (n != 18) {
	    put_msg(Err_incomp, "ellipse", line_no);
	    free((char*)e);
	    return(NULL);
	    }
	return(e);
	}

static F_line *
read_lineobject(fp)
FILE	*fp;
{
	F_line	*l;
	F_point	*p, *q;
	int	n, x, y, fa, ba;
	int	type, style;
	double	thickness, wid, ht;

	Line_malloc(l);
	l->points = NULL;
	l->pen = NULL;
	l->area_fill = NULL;
	l->for_arrow = NULL;
	l->back_arrow = NULL;
	l->next = NULL;

	sscanf(buf,"%*d%d",&l->type);	/* get the line type */
	/* 2.0 or later has separate radius parm for arc-box corners */
	if (l->type == T_ARC_BOX && v2_flag)
	    {
	    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d%d",
	    &l->type, &l->style, &l->thickness, &l->color,
	    &l->depth, &l->pen, &l->area_fill, &l->style_val, &l->radius, &fa, &ba);
	    }
	/* old format uses pen for radius of arc-box corners */
	else
	    {
	    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d",
		&l->type, &l->style, &l->thickness, &l->color,
		&l->depth, &l->pen, &l->area_fill, &l->style_val, &fa, &ba);
	    if (l->type == T_ARC_BOX)
		{
		l->radius = (int) l->pen;
		l->pen = 0;
		}
	    else
		l->radius = 0;
	    }
	if ((!v2_flag && n!=10) || 
	     (v2_flag && (l->type == T_ARC_BOX && n!=11) ||
			 (l->type != T_ARC_BOX && n!=10))) {
	    put_msg(Err_incomp, "line", line_no);
	    free((char*)l);
	    return(NULL);
	    }
	skip_comment(fp);
	if (fa) {
	    line_no++;
	    if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
		fprintf(stderr, Err_incomp, "line", line_no);
		return(NULL);
		}
	    skip_line(fp);
	    l->for_arrow = make_arrow(type, style, thickness, wid, ht);
	    skip_comment(fp);
	    }
	if (ba) {
	    line_no++;
	    if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
		fprintf(stderr, Err_incomp, "line", line_no);
		return(NULL);
		}
	    skip_line(fp);
	    l->back_arrow = make_arrow(type, style, thickness, wid, ht);
	    skip_comment(fp);
	    }

	if (NULL == (l->points = Point_malloc(p))) {
	    put_msg(Err_mem);
	    return(NULL);
	    }
	p->next = NULL;
	if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
	    put_msg(Err_incomp, "line", line_no);
	    free_linestorage(l);
	    return(NULL);
	    }
	for (;;) {
	    if (fscanf(fp, "%d%d", &x, &y) != 2) {
		put_msg(Err_incomp, "line", line_no);
		free_linestorage(l);
		return(NULL);
		}
	    if (x == 9999) break;
	    if (NULL == (Point_malloc(q))) {
		put_msg(Err_mem);
		free_linestorage(l);
		return(NULL);
		}
	    q->x = x;
	    q->y = y;
	    q->next = NULL;
	    p->next = q;
	    p = q;
	    }
	skip_line(fp);
	return(l);
	}

static F_spline *
read_splineobject(fp)
FILE	*fp;
{
	F_spline	*s;
	F_point		*p, *q;
	F_control	*cp, *cq;
	int		c, n, x, y, fa, ba;
	int		type, style;
	double		thickness, wid, ht;
	double		lx, ly, rx, ry;

	Spline_malloc(s);
	s->points = NULL;
	s->controls = NULL;
	s->pen = NULL;
	s->area_fill = NULL;
	s->for_arrow = NULL;
	s->back_arrow = NULL;
	s->next = NULL;

	n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d",
	    	&s->type, &s->style, &s->thickness, &s->color,
		&s->depth, &s->pen, &s->area_fill, &s->style_val, &fa, &ba);
	if (n != 10) {
	    put_msg(Err_incomp, "spline", line_no);
	    free((char*)s);
	    return(NULL);
	    }
	skip_comment(fp);
	if (fa) {
	    line_no++;
	    if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
		fprintf(stderr, Err_incomp, "spline", line_no);
		return(NULL);
		}
	    skip_line(fp);
	    s->for_arrow = make_arrow(type, style, thickness, wid, ht);
	    skip_comment(fp);
	    }
	if (ba) {
	    line_no++;
	    if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
		fprintf(stderr, Err_incomp, "spline", line_no);
		return(NULL);
		}
	    skip_line(fp);
	    s->back_arrow = make_arrow(type, style, thickness, wid, ht);
	    skip_comment(fp);
	    }

	/* Read points */
	if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) {
	    put_msg(Err_incomp, "spline", line_no);
	    free_splinestorage(s);
	    return(NULL);
	    };
	if (NULL == (s->points = Point_malloc(p))) {
	    put_msg(Err_mem);
	    free_splinestorage(s);
	    return(NULL);
	    }
	p->x = x; p->y = y;
	for (c = 1;;) {
	    if (fscanf(fp, "%d%d", &x, &y) != 2) {
		put_msg(Err_incomp, "spline", line_no);
		p->next = NULL;
		free_splinestorage(s);
		return(NULL);
		};
	    if (x == 9999) break;
	    if (NULL == (Point_malloc(q))) {
		put_msg(Err_mem);
		free_splinestorage(s);
		return(NULL);
		}
	    q->x = x;
	    q->y = y;
	    p->next = q;
	    p = q;
	    c++;
	    }
	p->next = NULL;
	skip_line(fp);

	if (normal_spline(s)) return(s);

	skip_comment(fp);
	/* Read controls */
	if ((n = fscanf(fp, "%lf%lf%lf%lf", &lx, &ly, &rx, &ry)) != 4) {
	    put_msg(Err_incomp, "spline", line_no);
	    free_splinestorage(s);
	    return(NULL);
	    };
	if (NULL == (s->controls = Control_malloc(cp))) {
	    put_msg(Err_mem);
	    free_splinestorage(s);
	    return(NULL);
	    }
	cp->lx = lx; cp->ly = ly;
	cp->rx = rx; cp->ry = ry;
	while (--c) {
	    if (fscanf(fp, "%lf%lf%lf%lf", &lx, &ly, &rx, &ry) != 4) {
		put_msg(Err_incomp, "spline", line_no);
		cp->next = NULL;
		free_splinestorage(s);
		return(NULL);
		};
	    if (NULL == (Control_malloc(cq))) {
		put_msg(Err_mem);
		cp->next = NULL;
		free_splinestorage(s);
		return(NULL);
		}
	    cq->lx = lx; cq->ly = ly;
	    cq->rx = rx; cq->ry = ry;
	    cp->next = cq;
	    cp = cq;
	    }
	cp->next = NULL;

	skip_line(fp);
	return(s);
	}

static F_text *
read_textobject(fp)
FILE	*fp;
{
	F_text	*t;
	int	n, ignore = 0;
	char	s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];

	Text_malloc(t);
	t->font = NULL;
	t->size = NULL;
	t->next = NULL;
	/* The text object is terminated by a CONTROL-A, so we read
	   everything up to the CONTROL-A and then read that character.
	   If we do not find the CONTROL-A on this line then this must
	   be a multi-line text object and we will have to read more. */
	n = sscanf(buf,"%*d%d%d%d%d%d%d%lf%d%d%d%d%d%[^\1]%[\1]",
		&t->type, &t->font, &t->size, &t->pen,
		&t->color, &t->depth, &t->angle,
		&t->style, &t->height, &t->length, 
		&t->base_x, &t->base_y, s, junk);
	if ((n != 14) && (n != 13)) {
	  put_msg(Err_incomp, "text", line_no);
	  free((char*)t);
/* 	  return(NULL); */
	}
	if (n == 13) {
	  /* Read in the remainder of the text object. */
	  do {
	    fgets(buf, BUF_SIZE, fp);
	    line_no++;  /* As is done in get_line */
	    n = sscanf(buf,"%[^\1]%[\1]", s_temp, junk);
	    /* Safety check */
	    if (strlen(s)+1 + strlen(s_temp)+1 > BUF_SIZE) {
	      /* Too many characters.  Ignore the rest. */
	      ignore = 1;
	    }
	    if (!ignore)
	      strcat(s, s_temp);
	  } while (n == 1);
	}
	if (strlen(s) == 0) (void)strcpy(s, " ");
	t->cstring = (char*)calloc((unsigned)(strlen(s)), sizeof(char));
	if (NULL == t->cstring) {
	    put_msg(Err_mem);
	    free((char*)t);
	    return(NULL);
	    }
	(void)strcpy(t->cstring, s+1);
 	if (!tfx_flag && !x_flag) 
 		t->size = 0;	/* 1.4(not X) and earlier had garbage in size*/
	if (t->style > 1) {
		put_msg(
		    "Text styles not supported; default font substituted\n");
		t->style = t->font = DEFAULT;
	}
	return(t);
	}

get_line(fp)
FILE	*fp;
{
	while (1) {
	    if (NULL == fgets(buf, BUF_SIZE, fp)) {
		return(-1);
		}
	    line_no++;
	    if (*buf != '\n' && *buf != '#') return(1);
			/* Skip empty and comment lines */
	    }
	}

skip_comment(fp)
FILE	*fp;
{
	char c;

	while ((c = fgetc(fp)) == '#') skip_line(fp);
	if (c != '#') ungetc(c, fp);
	}

skip_line(fp)
FILE	*fp;
{
	while (fgetc(fp) != '\n') {
	    if (feof(fp)) return;
	    }
	}