2 * Copyright (C) 1984-2015 Mark Nudelman
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Less License, as specified in the README file.
7 * For more information, see the README file.
12 * An IFILE represents an input file.
14 * It is actually a pointer to an ifile structure,
15 * but is opaque outside this module.
16 * Ifile structures are kept in a linked list in the order they
17 * appear on the command line.
18 * Any new file which does not already appear in the list is
19 * inserted after the current file.
24 extern IFILE curr_ifile
;
27 struct ifile
*h_next
; /* Links for command line list */
29 char *h_filename
; /* Name of the file */
30 void *h_filestate
; /* File state (used in ch.c) */
31 int h_index
; /* Index within command line list */
32 int h_hold
; /* Hold count */
33 char h_opened
; /* Has this ifile been opened? */
34 struct scrpos h_scrpos
; /* Saved position within the file */
38 * Convert an IFILE (external representation)
39 * to a struct file (internal representation), and vice versa.
41 #define int_ifile(h) ((struct ifile *)(h))
42 #define ext_ifile(h) ((IFILE)(h))
45 * Anchor for linked list.
47 static struct ifile anchor
= { &anchor
, &anchor
, NULL
, NULL
, 0, 0, '\0',
48 { NULL_POSITION
, 0 } };
49 static int ifiles
= 0;
53 register struct ifile
*p
;
56 for (; p
!= &anchor
; p
= p
->h_next
)
61 * Link an ifile into the ifile list.
73 p
->h_next
= prev
->h_next
;
75 prev
->h_next
->h_prev
= p
;
78 * Calculate index for the new one,
79 * and adjust the indexes for subsequent ifiles in the list.
81 p
->h_index
= prev
->h_index
+ 1;
82 incr_index(p
->h_next
, 1);
87 * Unlink an ifile from the ifile list.
93 p
->h_next
->h_prev
= p
->h_prev
;
94 p
->h_prev
->h_next
= p
->h_next
;
95 incr_index(p
->h_next
, -1);
100 * Allocate a new ifile structure and stick a filename in it.
101 * It should go after "prev" in the list
102 * (or at the beginning of the list if "prev" is NULL).
103 * Return a pointer to the new ifile structure.
105 static struct ifile
*
106 new_ifile(filename
, prev
)
110 register struct ifile
*p
;
113 * Allocate and initialize structure.
115 p
= (struct ifile
*) ecalloc(1, sizeof(struct ifile
));
116 p
->h_filename
= save(filename
);
117 p
->h_scrpos
.pos
= NULL_POSITION
;
120 p
->h_filestate
= NULL
;
126 * Delete an existing ifile structure.
132 register struct ifile
*p
;
137 * If the ifile we're deleting is the currently open ifile,
142 curr_ifile
= getoff_ifile(curr_ifile
);
150 * Get the ifile after a given one in the list.
156 register struct ifile
*p
;
158 p
= (h
== NULL_IFILE
) ? &anchor
: int_ifile(h
);
159 if (p
->h_next
== &anchor
)
161 return (ext_ifile(p
->h_next
));
165 * Get the ifile before a given one in the list.
171 register struct ifile
*p
;
173 p
= (h
== NULL_IFILE
) ? &anchor
: int_ifile(h
);
174 if (p
->h_prev
== &anchor
)
176 return (ext_ifile(p
->h_prev
));
180 * Return a different ifile from the given one.
188 if ((newifile
= prev_ifile(ifile
)) != NULL_IFILE
)
190 if ((newifile
= next_ifile(ifile
)) != NULL_IFILE
)
196 * Return the number of ifiles.
205 * Find an ifile structure, given a filename.
207 static struct ifile
*
211 register struct ifile
*p
;
213 for (p
= anchor
.h_next
; p
!= &anchor
; p
= p
->h_next
)
214 if (strcmp(filename
, p
->h_filename
) == 0)
220 * Get the ifile associated with a filename.
221 * If the filename has not been seen before,
222 * insert the new ifile after "prev" in the list.
225 get_ifile(filename
, prev
)
229 register struct ifile
*p
;
231 if ((p
= find_ifile(filename
)) == NULL
)
232 p
= new_ifile(filename
, int_ifile(prev
));
233 return (ext_ifile(p
));
237 * Get the filename associated with a ifile.
245 return (int_ifile(ifile
)->h_filename
);
249 * Get the index of the file associated with a ifile.
255 return (int_ifile(ifile
)->h_index
);
259 * Save the file position to be associated with a given file.
262 store_pos(ifile
, scrpos
)
264 struct scrpos
*scrpos
;
266 int_ifile(ifile
)->h_scrpos
= *scrpos
;
270 * Recall the file position associated with a file.
271 * If no position has been associated with the file, return NULL_POSITION.
274 get_pos(ifile
, scrpos
)
276 struct scrpos
*scrpos
;
278 *scrpos
= int_ifile(ifile
)->h_scrpos
;
282 * Mark the ifile as "opened".
288 int_ifile(ifile
)->h_opened
= 1;
292 * Return whether the ifile has been opened previously.
298 return (int_ifile(ifile
)->h_opened
);
302 hold_ifile(ifile
, incr
)
306 int_ifile(ifile
)->h_hold
+= incr
;
313 return (int_ifile(ifile
)->h_hold
);
320 return (int_ifile(ifile
)->h_filestate
);
324 set_filestate(ifile
, filestate
)
328 int_ifile(ifile
)->h_filestate
= filestate
;
335 register struct ifile
*p
;
337 for (p
= anchor
.h_next
; p
!= &anchor
; p
= p
->h_next
)
339 printf("%x: %d. <%s> pos %d,%x\n",
340 p
, p
->h_index
, p
->h_filename
,
341 p
->h_scrpos
.ln
, p
->h_scrpos
.pos
);
342 ch_dump(p
->h_filestate
);