/* Q_file Use: #include RSX IO error codes #include FILE_QUEUE * enQ_file (queue, file, filename) FILE_QUEUE *queue; The relevant file queue (null if new queue) FILE *file; Current file pointer char *filename; Name of new file to become the current file FILE_QUEUE * deQ_file (queue, file) Description: A file is enqueued/dequeued to/from the specified file queue. The FILE_QUEUE is defined in the filequeue.h header file. These routines manage a queue, or stack, of files typically used in indirect command file processing. They allow for an indefinate number of files to be processed in a nested fashion where a currently open file from which commands are being read may encounter a command to open another file from which to continue reading commands, recursively. Upon completion (for any reason) of processing a nested file, the file previously being read (if any) when the currenty active file reference was encountered, can be restored to its previous condition as the current file. enQ_file - The enQ_file function will place the name of the currently open file, and the location in the file, on a singly linked (reverse) queue, or push down stack; close it; and open the new file using the same file pointer. Memory is allocated for the FILE_QUEUE data structure. The new FILE_QUEUE pointer is returned; check IO_ERROR to see if an error occured. On error it is set appropriately. IE_NBF - no buffer space available - is set if memory cannot be allocated for the FILE_QUEUE data structure. deQ_file - The deQ_file function will close the current file; open the previously enqueued file using the same file pointer; and position the file to the same location it was in when it was enqueued. The next previous FILE_QUEUE pointer is returned. This will be null if the queue is now empty. Check if IO_ERROR is set to see if an error occured. >>> CAUTION <<< The use user MUST refer to the returned FILE_QUEUE pointer when dequeueing the file, otherwise the files stacked subsequent to the establishment of the queue pointer value will be lost (the file pointed to in the file queue by the current value of queue will be accessed by a deQ_file operation). Typical usage is: file = fopen (old_file, "r"); { ... old_file is processed; probably until new_file is encountered. } queue = enQ_file (queue, file, new_file); { ... new_file is processed; probably to EOF. } queue = deQ_file (queue, file); { ... processing of old_file continues; positioned where it was when it was queued (ready to read the next line from the file). } ******************************************************************************/ #include #include #include #include #define MAX_FILENAME 32 FILE_QUEUE * enQ_file (queue, file, filename) FILE_QUEUE *queue; FILE *file; char *filename; { FILE_QUEUE *entry; char name[MAX_FILENAME]; FILE *temp; extern long ftell (); IO_ERROR = NULL; /* Build a new file queue entry. */ fgetname (file, name); if (entry = malloc (sizeof (FILE_QUEUE) + strlen (name) + 1)) { entry->position = ftell (file); if (temp = fopen (filename, "r")) { fclose (temp); file = freopen (filename, "r", file); entry->previous = queue; queue = entry; entry->filename = (STRING)entry + sizeof (FILE_QUEUE); strcpy (entry->filename, name); } else free (entry); } else IO_ERROR = IE_NBF; return (queue); } FILE_QUEUE * deQ_file (queue, file) FILE_QUEUE *queue; FILE *file; { FILE_QUEUE *entry; FILE *temp; IO_ERROR = NULL; if (queue) { if (temp = fopen (queue->filename, "r")) { fclose (temp); file = freopen (queue->filename, "r", file); fseek (file, queue->position, 0); if (! IO_ERROR) { entry = queue; queue = queue->previous; free (entry); } } } return (queue); }