home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Encyclopedia of Graphics File Formats Companion
/
GFF_CD.ISO
/
formats
/
off
/
code
/
readobj.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-20
|
12KB
|
459 lines
/*
*
* Description
* Read an OFF object data file.
*
* Output
*
* Input
* Obj Pointer to object structure in which to store data.
* FileName Name of file to be read.
*
* Diagnostics
* Returns 0 if successful, -1 if unsuccessful for any reason.
*
* Author
* Randi J. Rost
* Digital Equipment Corp.
* Workstation Systems Engineering
* Palo Alto, CA
*
* History
* 17-Nov-86 Created
*
*/
#include <stdio.h>
#include "off.h"
#define MAX_OBJ_DIRS 10
#define DEFAULT_DATA_BLK 100
static char ObjDir[MAX_OBJ_DIRS][OFF_BIGSTR];
static int NumObjDirs = 0;
static int firsttime = 1;
static OFFProperty **pProp;
OFFReadObj(Obj, FileName)
OFFObjDesc *Obj; /* Object data structure to fill out */
char *FileName; /* File to be opened and read */
{
FILE *ObjFile;
char Line[OFF_BIGSTR];
char Key[OFF_BIGSTR];
char Remainder[OFF_BIGSTR];
char Directory[OFF_BIGSTR];
char Path[OFF_BIGSTR];
char TmpString[OFF_BIGSTR];
char *index(), *getenv();
int i;
int status = 0;
char *comment = "comment";
char *nl = "nl";
/* If this is the first time, parse the object search path */
if (firsttime)
status = ParseObjPath();
/* Punt if too many directories in OBJ_PATH */
if (status < 0)
{
fprintf(stderr,"OFFReadObj: too many (> %d) directories in OBJ_PATH\n",
MAX_OBJ_DIRS);
return(-1);
}
/* See if filename has a leading pathname component */
Directory[0] = '\0';
for (i = strlen(FileName) - 1; i >= 0; i--)
if (FileName[i] == '/') break;
if (i >= 0)
{
strncpy(Directory, FileName, i + 1);
Directory[i+1] = '\0';
}
/* First try opening the file as passed to us */
ObjFile = fopen(FileName,"r");
/* If that doesn't work, try each directory in search path */
if (ObjFile == NULL)
{
for (i = 0; i < NumObjDirs; i++)
{
strcpy(Path, ObjDir[i]);
strcat(Path, FileName);
ObjFile = fopen(Path, "r");
if (ObjFile != NULL)
{
strcpy(TmpString, ObjDir[i]);
strcat(TmpString, Directory);
strcpy(Directory, TmpString);
break;
}
}
}
/* If the file isn't found in any of the search directories, punt */
if (ObjFile == NULL)
{
fprintf(stderr, "OFFReadObj: %s not found\n", FileName);
return(-1);
}
/* Initialize fields in object structure */
pProp = &(Obj->FirstProp);
Obj->FirstProp = NULL;
/* Read lines from the header file */
while((fgets(Line, OFF_BIGSTR - 1, ObjFile)) != NULL)
{
/* Get the first token */
if (Line[0] == '\n')
status = AddProperty(nl, NULL, NULL);
else if (Line[0] == '#')
status = AddProperty(comment, Line, NULL);
else
{
SplitLine(Line, Key, Remainder);
status = AddProperty(Key, Remainder, Directory);
}
if (status != 0)
{
fprintf(stderr, "OFFReadObj: problem parsing line\n");
fprintf(stderr, "\t>>>%s\n", Line);
return(-1);
}
}
fclose(ObjFile);
return(0);
}
static SplitLine(str, part1, remainder)
char *str, *part1, *remainder;
{
int i, p1, p2;
/* If first character is '#' for a comment, we're done */
if (str[0] == '#')
{
strcpy(part1, "#");
strcpy(remainder, &(str[1]));
return;
}
/* Position p1 to first non-separator character */
/* Blanks, tabs, commas are separators */
p1 = 0;
while ((str[p1] == ' ' ) || (str[p1] == '\t') || (str[p1] == ',')) p1++;
/* Position p2 to first separator character after p1 */
p2 = p1;
while ((str[p2] != ' ') && (str[p2] != '\t') && (str[p2] != '\0') &&
(str[p2] != ',') && (str[p2] != '\n')) p2++;
/* Copy what's between p1 and p2 to part1 */
for (i = p1; i < p2; i++)
part1[i - p1] = str[i];
part1[i - p1] = '\0';
/* Position p2 to next non-separator character */
while ((str[p2] == ' ' ) || (str[p2] == '\t') || (str[p2] == ',')) p2++;
i = 0;
while ((str[p2] != '\0') && (str[p2] != '\n') && (str[p2] != '\0'))
remainder[i++] = str[p2++];
remainder[i] = '\0';
}
#ifdef caca
OFFPrintObjPath()
{
int i;
/* If this is the first time, parse the object search path */
if (firsttime)
i = ParseObjPath();
/* Punt if too many directories in OBJ_PATH */
if (i < 0)
{
fprintf(stderr,
"PrintObjPath: too many (> %d) directories in OBJ_PATH\n",
MAX_OBJ_DIRS);
return(-1);
}
/* Print out all directories in the object search path */
for (i = 0; i < NumObjDirs; i++)
printf("%s ", ObjDir[i]);
printf("\n");
return(0);
}
#endif
static ParseObjPath()
{
char *str;
int i, j, len;
firsttime = 0;
str = getenv("OBJ_PATH");
len = (str == NULL) ? 0 : strlen(str);
for (i = 0; i < len; i++)
{
while ((str[i] == ' ') || (str[i] == '\t')) i++;
j = i;
while ((str[j] != ' ') && (str[j] != '\t') && (j < strlen(str)))
j++;
strncpy(ObjDir[NumObjDirs], &(str[i]), j - i);
ObjDir[NumObjDirs][j - i] = '/';
ObjDir[NumObjDirs][j - i + 1] = '\0';
if (strcmp(ObjDir[NumObjDirs], "./") != 0)
glob(ObjDir[NumObjDirs++]); /* ignore directory "." in path */
i = j;
if (NumObjDirs > MAX_OBJ_DIRS)
return(-1);
}
return(0);
}
#include <pwd.h>
#include <ctype.h>
static glob(string)
char *string;
{
struct passwd *p, *getpwname();
char str1[160], str2[160];
char *pstr;
char *getenv();
/* If first character is '~', expand it */
if (string[0] == '~')
{
strcpy(str1, string);
/* ~/... means use home directory */
if (string[1] == '/')
{
strcpy(string, getenv("HOME"));
strcat(string, &(str1[1]));
}
/* ~whatever/... means use whatever's home directory */
else
{
pstr = index(str1, '/');
strncpy(str2, &(string[1]), pstr - str1 - 1);
str2[pstr - str1 - 1] = 0;
p = getpwnam(str2);
strcpy(string, p->pw_dir);
strcat(string, pstr);
}
}
}
static int AddProperty(PropName, String, Directory)
char *PropName;
char *String;
char *Directory;
{
OFFProperty *newprop;
char str[OFF_BIGSTR], junk[OFF_BIGSTR], remainder[OFF_BIGSTR];
char datatype[OFF_BIGSTR];
char filename[OFF_BIGSTR];
long *iptr;
short *hptr;
float *fptr;
double *dptr;
char *ptr;
int i, j, k;
char *comment = "comment";
newprop = (OFFProperty *) malloc(sizeof(OFFProperty));
*pProp = newprop;
pProp = &(newprop->NextProp);
newprop->NextProp = NULL;
newprop->PropData = NULL;
newprop->PropFileName[0] = '\0';
newprop->DataFormat[0] = '\0';
newprop->PropCount = 0;
PropName[OFF_SMSTR] = '\0';
strcpy(newprop->PropName, PropName);
/* The following strcmp apparently caused some problems with the MIPS
compiler...don't know what the problem was, but have altered the code
some and it seems to work now. Somehow the value for PropName was
getting trashed. Don't ask me. */
/* fprintf(stderr, "PropName = >%s<\n", PropName); */
if (strncmp(PropName, comment, strlen(comment) - 1) == 0)
{
/* fprintf(stderr, "Got a comment!!!\n"); */
String[strlen(String) - 1] = '\0';
newprop->PropData = (char *) malloc(strlen(String));
strcpy(newprop->PropData, String);
newprop->PropType = OFF_COMMENT_DATA;
return(0);
}
/* fprintf(stderr, "PropName = >%s<\n", PropName); */
if (strcmp(PropName, "nl") == 0)
{
newprop->PropData = (char *) malloc(OFF_BIGSTR);
newprop->PropType = OFF_COMMENT_DATA;
return(0);
}
if (strcmp(PropName, "name") == 0 || strcmp(PropName, "author") == 0 ||
strcmp(PropName, "type") == 0 || strcmp(PropName, "description") == 0
|| strcmp(PropName, "copyright") == 0)
{
newprop->PropData = (char *) malloc(OFF_BIGSTR);
strcpy(newprop->PropData, String);
newprop->PropType = OFF_STANDARD_DATA;
return(0);
}
else
{
SplitLine(String, datatype, remainder);
if (strcmp(datatype, "default") == 0)
newprop->PropType = OFF_DEFAULT_DATA;
else if (strcmp(datatype, "generic") == 0)
newprop->PropType = OFF_GENERIC_DATA;
else if (strcmp(datatype, "indexed") == 0)
newprop->PropType = OFF_INDEXED_DATA;
else if (strcmp(datatype, "indexed_poly") == 0)
newprop->PropType = OFF_INDEXED_POLY_DATA;
else
newprop->PropType = OFF_UNKNOWN_TYPE_DATA;
strcpy(str, remainder);
SplitLine(str, newprop->DataFormat, remainder);
remainder[OFF_SMSTR] = '\0';
if (newprop->PropType != OFF_DEFAULT_DATA)
strcpy(newprop->PropFileName, remainder);
switch(newprop->PropType)
{
case OFF_DEFAULT_DATA:
newprop->PropCount = 1;
newprop->PropData = (char *) malloc(DEFAULT_DATA_BLK);
ptr = newprop->PropData;
for (i = 0; i < strlen(newprop->DataFormat); i++)
{
switch (newprop->DataFormat[i])
{
case 'i':
/* Make sure we're aligned on word boundary */
ptr += (((int) ptr % 4) == 0) ?
0 : 4 - (int) ptr % 4;
iptr = (long *) ptr;
sscanf(remainder, "%d", iptr);
ptr += sizeof(long);
strcpy(str, remainder);
SplitLine(str, junk, remainder);
break;
case 'b':
sscanf(remainder, "%d", &j);
*ptr++ = (unsigned char) j;
strcpy(str, remainder);
SplitLine(str, junk, remainder);
break;
case 'd':
/* Make sure we're aligned on word boundary */
ptr += (((int) ptr % 4) == 0) ?
0 : 4 - (int) ptr % 4;
dptr = (double *) ptr;
sscanf(remainder, "%F", dptr);
ptr += sizeof(double);
strcpy(str, remainder);
SplitLine(str, junk, remainder);
break;
case 'h':
/* Make sure we're aligned on halfword boundary */
ptr += (((int) ptr % 2) == 0) ? 0 : 1;
hptr = (short *) ptr;
sscanf(remainder, "%hd", hptr);
ptr += sizeof(short);
strcpy(str, remainder);
SplitLine(str, junk, remainder);
break;
case 'f':
/* Make sure we're aligned on word boundary */
ptr += (((int) ptr % 4) == 0) ?
0 : 4 - (int) ptr % 4;
fptr = (float *) ptr;
sscanf(remainder, "%f", fptr);
ptr += sizeof(float);
strcpy(str, remainder);
SplitLine(str, junk, remainder);
break;
case 's':
j = 0; k = 0;
while (remainder[j] != ' ' && remainder[j] != '\t'
&& j < strlen(remainder))
junk[k++] = remainder[j++];
junk[k] = '\0';
*((char **) ptr) = (char *) malloc(k + 1);
strcpy(*((char **) ptr), junk);
ptr += sizeof(char *);
strcpy(junk, &(remainder[j]));
strcpy(remainder, junk);
break;
default:
return(-1);
} /* switch */
} /* for */
break;
case OFF_GENERIC_DATA:
strcpy(filename, Directory);
strcat(filename, newprop->PropFileName);
if ((i = OFFReadGeneric(newprop, filename)) != 0)
return(-1);
break;
case OFF_INDEXED_DATA:
strcpy(filename, Directory);
strcat(filename, newprop->PropFileName);
if ((i = OFFReadIndexed(newprop, filename)) != 0)
return(-1);
break;
case OFF_INDEXED_POLY_DATA:
strcpy(filename, Directory);
strcat(filename, newprop->PropFileName);
if (OFFReadIndexedPoly(newprop, filename) != 0)
return(-1);
break;
default:
return(-1);
break;
} /* switch */
}
return(0);
}