home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume8
/
xfig2.8
/
part13
/
read.c
< prev
Wrap
C/C++ Source or Header
|
1990-07-03
|
17KB
|
741 lines
/*
* FIG : Facility for Interactive Generation of figures
*
* Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
* January 1985.
* 1st revision : August 1985.
* 2nd revision : March 1988.
*
* %W% %G%
*/
#include "fig.h"
#include "alloc.h"
#include "object.h"
#include "psfonts.h"
extern F_arrow *make_arrow();
extern char *calloc();
extern int errno;
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;
int num_object;
int proto; /* file protocol*10 */
read_fail_message(file, err)
char *file;
int err;
{
extern char *sys_errlist[];
if (err == 0) /* Successful read */
return;
#ifdef ENAMETOOLONG
else if (err == ENAMETOOLONG)
put_msg("File name \"%s\" is too long", file);
#endif
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 coordinate system (coord_sys) are
stored in obj->nwcorner.x and obj->nwcorner.y respectively.
The coordinate system is 1 for lower left at 0,0 and
2 for upper left at 0,0
>>> xfig only uses 2 for the coordinate system. <<<
**********************************************************/
read_fig(file_name, obj)
char *file_name;
F_compound *obj;
{
FILE *fp;
line_no = 0;
if ((fp = fopen(file_name, "r")) == NULL)
return(errno);
else
return(readfp_fig(fp, obj));
}
readfp_fig(fp, obj)
FILE *fp;
F_compound *obj;
{
int status;
float fproto;
num_object = 0;
bzero((char*)obj, COMOBJ_SIZE);
if (fgets(buf,BUF_SIZE,fp)==0) /* version */
return -2;
if (strncmp(buf,"#FIG",4)==0) /* versions 1.4/later have #FIG in first line */
{
if ((sscanf(index(buf,' ')+1,"%f",&fproto))==0) /* assume 1.4 */
proto=14;
else
proto = (fproto+.01)*10; /* protocol version*10 */
status = read_objects(fp, obj);
}
else
{
proto = 13;
status = read_1_3_objects(fp, obj);
}
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;
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;
float thickness, wid, ht;
if (NULL == (Arc_malloc(a))) {
put_msg(Err_mem);
return(NULL);
}
a->next = NULL;
a->for_arrow = a->back_arrow = NULL; /* added 8/23/89 B.V.Smith */
n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%f%f%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%f%f%f", &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%f%f%f", &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;
if (NULL == (Compound_malloc(com))) {
put_msg(Err_mem);
return(NULL);
}
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;
if (NULL == (Ellipse_malloc(e))) {
put_msg(Err_mem);
return(NULL);
}
e->next = NULL;
n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%f%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;
float thickness, wid, ht;
if (NULL == (Line_malloc(l))) {
put_msg(Err_mem);
return(NULL);
}
l->points = NULL;
l->for_arrow = l->back_arrow = NULL;
l->next = NULL;
sscanf(buf,"%*d%d",&l->type);
#ifndef TFX
/* 2.0 or later; has separate radius parm for arc-box corners */
if (l->type == T_ARC_BOX && proto >= 20)
{
n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%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
#endif TFX
{
n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d",
&l->type, &l->style, &l->thickness, &l->color,
&l->depth, &l->pen, &l->area_fill, &l->style_val, &fa, &ba);
#ifndef TFX
if (l->type == T_ARC_BOX)
{
l->radius = l->pen;
l->pen = 0;
}
else
#endif TFX
l->radius = 0;
}
#ifdef TFX
if (n != 10)
#else
if ((proto==14 && n != 10) ||
(proto==20 && (l->type == T_ARC_BOX && n != 11) ||
(l->type != T_ARC_BOX && n != 10))) {
#endif TFX
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%f%f%f", &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%f%f%f", &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;
/* points start on new line */
line_no++;
/* read first point */
if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
put_msg(Err_incomp, "line", line_no);
free_linestorage(l);
return(NULL);
}
/* read subsequent points */
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;
float thickness, wid, ht;
float lx, ly, rx, ry;
if (NULL == (Spline_malloc(s))) {
put_msg(Err_mem);
return(NULL);
}
s->points = NULL;
s->controls = NULL;
s->for_arrow = s->back_arrow = NULL;
s->next = NULL;
n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%d%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%f%f%f", &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%f%f%f", &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);
}
line_no++;
/* 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);
line_no++;
skip_comment(fp);
/* Read controls */
if ((n = fscanf(fp, "%f%f%f%f", &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, "%f%f%f%f", &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;
int ignore = 0;
char s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];
if (NULL == (Text_malloc(t))) {
put_msg(Err_mem);
return(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%f%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 != 13 && n != 14) {
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 (t->type > T_RIGHT_JUSTIFIED)
{
put_msg("Invalid text justification at line %d.",line_no);
return(NULL);
}
if (t->font >= NUMFONTS)
{
put_msg("Invalid text font (%d) at line %d.",t->font,line_no);
return(NULL);
}
if (strlen(s) == 0)
(void) strcpy(s," ");
t->cstring = (char*)calloc((unsigned)(strlen(s)+1), sizeof(char));
if (NULL == t->cstring) {
put_msg(Err_mem);
free((char*)t);
return(NULL);
}
(void) strcpy(t->cstring, s);
return(t);
}
get_line(fp)
FILE *fp;
{
while (1) {
if (NULL == fgets(buf, BUF_SIZE, fp)) {
return(-1);
}
line_no++;
if (*buf != '\n' && *buf != '#') /* Skip empty and comment lines */
return(1);
}
}
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;
}
}