Commit | Line | Data |
---|---|---|
3b5b17f7 C |
1 | /* |
2 | * An IFILE represents an input file. | |
3 | * | |
4 | * It is actually a pointer to an ifile structure, | |
5 | * but is opaque outside this module. | |
6 | * Ifile structures are kept in a linked list in the order they | |
7 | * appear on the command line. | |
8 | * Any new file which does not already appear in the list is | |
9 | * inserted after the current file. | |
10 | */ | |
11 | ||
12 | #include "less.h" | |
13 | ||
14 | struct ifile { | |
15 | struct ifile *h_next; /* Links for command line list */ | |
16 | struct ifile *h_prev; | |
17 | int h_index; /* Index within command line list */ | |
18 | char *h_filename; /* Name of the file */ | |
19 | struct scrpos h_scrpos; /* Saved position within the file */ | |
20 | }; | |
21 | ||
22 | /* | |
23 | * Convert an IFILE (external representation) | |
24 | * to a struct file (internal representation), and vice versa. | |
25 | */ | |
26 | #define int_ifile(h) ((struct ifile *)(h)) | |
27 | #define ext_ifile(h) ((IFILE)(h)) | |
28 | ||
29 | /* | |
30 | * Anchor for linked list. | |
31 | */ | |
32 | static struct ifile anchor = { &anchor, &anchor, 0 }; | |
33 | static int ifiles = 0; | |
34 | ||
35 | /* | |
36 | * Allocate a new ifile structure and stick a filename in it. | |
37 | * It should go after "prev" in the list | |
38 | * (or at the beginning of the list if "prev" is NULL). | |
39 | * Return a pointer to the new ifile structure. | |
40 | */ | |
41 | static struct ifile * | |
42 | new_ifile(filename, prev) | |
43 | char *filename; | |
44 | struct ifile *prev; | |
45 | { | |
46 | register struct ifile *p; | |
47 | register struct ifile *np; | |
48 | ||
49 | /* | |
50 | * Allocate and initialize structure. | |
51 | */ | |
52 | p = (struct ifile *) ecalloc(1, sizeof(struct ifile)); | |
53 | p->h_filename = filename; | |
54 | p->h_scrpos.pos = NULL_POSITION; | |
55 | ||
56 | /* | |
57 | * Link into list. | |
58 | */ | |
59 | if (prev == NULL) | |
60 | prev = &anchor; | |
61 | p->h_next = prev->h_next; | |
62 | p->h_prev = prev; | |
63 | prev->h_next->h_prev = p; | |
64 | prev->h_next = p; | |
65 | ||
66 | /* | |
67 | * Calculate index for the new one, | |
68 | * and adjust the indexes for subsequent ifiles in the list. | |
69 | */ | |
70 | p->h_index = prev->h_index + 1; | |
71 | for (np = p->h_next; np != &anchor; np = np->h_next) | |
72 | np->h_index++; | |
73 | ||
74 | ifiles++; | |
75 | return (p); | |
76 | } | |
77 | ||
78 | /* | |
79 | * Get the ifile after a given one in the list. | |
80 | */ | |
81 | public IFILE | |
82 | next_ifile(h) | |
83 | IFILE h; | |
84 | { | |
85 | register struct ifile *p; | |
86 | ||
87 | p = (h == NULL_IFILE) ? &anchor : int_ifile(h); | |
88 | if (p->h_next == &anchor) | |
89 | return (NULL_IFILE); | |
90 | return (ext_ifile(p->h_next)); | |
91 | } | |
92 | ||
93 | /* | |
94 | * Get the ifile before a given one in the list. | |
95 | */ | |
96 | public IFILE | |
97 | prev_ifile(h) | |
98 | IFILE h; | |
99 | { | |
100 | register struct ifile *p; | |
101 | ||
102 | p = (h == NULL_IFILE) ? &anchor : int_ifile(h); | |
103 | if (p->h_prev == &anchor) | |
104 | return (NULL_IFILE); | |
105 | return (ext_ifile(p->h_prev)); | |
106 | } | |
107 | ||
108 | /* | |
109 | * Return the number of ifiles. | |
110 | */ | |
111 | public int | |
112 | nifile() | |
113 | { | |
114 | return (ifiles); | |
115 | } | |
116 | ||
117 | /* | |
118 | * Find an ifile structure, given a filename. | |
119 | */ | |
120 | static struct ifile * | |
121 | find_ifile(filename) | |
122 | char *filename; | |
123 | { | |
124 | register struct ifile *p; | |
125 | ||
126 | for (p = anchor.h_next; p != &anchor; p = p->h_next) | |
127 | if (strcmp(filename, p->h_filename) == 0) | |
128 | return (p); | |
129 | return (NULL); | |
130 | } | |
131 | ||
132 | /* | |
133 | * Get the ifile associated with a filename. | |
134 | * If the filename has not been seen before, | |
135 | * insert the new ifile after "prev" in the list. | |
136 | */ | |
137 | public IFILE | |
138 | get_ifile(filename, prev) | |
139 | char *filename; | |
140 | IFILE prev; | |
141 | { | |
142 | register struct ifile *p; | |
143 | ||
144 | if ((p = find_ifile(filename)) == NULL) | |
145 | p = new_ifile(save(filename), int_ifile(prev)); | |
146 | return (ext_ifile(p)); | |
147 | } | |
148 | ||
149 | /* | |
150 | * Get the filename associated with a ifile. | |
151 | */ | |
152 | public char * | |
153 | get_filename(ifile) | |
154 | IFILE ifile; | |
155 | { | |
156 | if (ifile == NULL) | |
157 | return (NULL); | |
158 | return (int_ifile(ifile)->h_filename); | |
159 | } | |
160 | ||
161 | /* | |
162 | * Get the index of the file associated with a ifile. | |
163 | */ | |
164 | public int | |
165 | get_index(ifile) | |
166 | IFILE ifile; | |
167 | { | |
168 | return (int_ifile(ifile)->h_index); | |
169 | } | |
170 | ||
171 | /* | |
172 | * Save the file position to be associated with a given file. | |
173 | */ | |
174 | public void | |
175 | store_pos(ifile, scrpos) | |
176 | IFILE ifile; | |
177 | struct scrpos *scrpos; | |
178 | { | |
179 | int_ifile(ifile)->h_scrpos = *scrpos; | |
180 | } | |
181 | ||
182 | /* | |
183 | * Recall the file position associated with a file. | |
184 | * If no position has been associated with the file, return NULL_POSITION. | |
185 | */ | |
186 | public void | |
187 | get_pos(ifile, scrpos) | |
188 | IFILE ifile; | |
189 | struct scrpos *scrpos; | |
190 | { | |
191 | *scrpos = int_ifile(ifile)->h_scrpos; | |
192 | } |