Mercurial > hg > Applications > mh
comparison miscellany/less-177/ifile.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
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 } |