home *** CD-ROM | disk | FTP | other *** search
-
- /*
- *
- * 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);
- }
-