|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: R T
Length: 10445 (0x28cd)
Types: TextFile
Names: »ReadObj.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/offconv/ReadObj.c«
/*
*
* 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 char *strptr;
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;
/* 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;
firsttime = 0;
str = getenv("OBJ_PATH");
for (i = 0; i < strlen(str); 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;
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);
if (strcmp(PropName, "comment") == 0)
{
String[strlen(String) - 1] = '\0';
newprop->PropData = (char *) malloc(strlen(String));
strcpy(newprop->PropData, String);
newprop->PropType = OFF_COMMENT_DATA;
return(0);
}
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_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_POLY_DATA:
strcpy(filename, Directory);
strcat(filename, newprop->PropFileName);
if (OFFReadIndexedPoly(newprop, filename) != 0)
return(-1);
break;
default:
return(-1);
break;
} /* switch */
}
return(0);
}