~ubuntu-branches/ubuntu/quantal/less/quantal

« back to all changes in this revision

Viewing changes to ifile.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Schoepf
  • Date: 2002-04-04 16:43:52 UTC
  • Revision ID: james.westby@ubuntu.com-20020404164352-qldq048yoc7x5sd5
Tags: upstream-374
ImportĀ upstreamĀ versionĀ 374

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1984-2000  Mark Nudelman
 
3
 *
 
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.
 
6
 *
 
7
 * For more information about less, or for information on how to 
 
8
 * contact the author, see the README file.
 
9
 */
 
10
 
 
11
 
 
12
/*
 
13
 * An IFILE represents an input file.
 
14
 *
 
15
 * It is actually a pointer to an ifile structure,
 
16
 * but is opaque outside this module.
 
17
 * Ifile structures are kept in a linked list in the order they 
 
18
 * appear on the command line.
 
19
 * Any new file which does not already appear in the list is
 
20
 * inserted after the current file.
 
21
 */
 
22
 
 
23
#include "less.h"
 
24
 
 
25
extern IFILE    curr_ifile;
 
26
 
 
27
struct ifile {
 
28
        struct ifile *h_next;           /* Links for command line list */
 
29
        struct ifile *h_prev;
 
30
        char *h_filename;               /* Name of the file */
 
31
        void *h_filestate;              /* File state (used in ch.c) */
 
32
        int h_index;                    /* Index within command line list */
 
33
        int h_hold;                     /* Hold count */
 
34
        char h_opened;                  /* Has this ifile been opened? */
 
35
        struct scrpos h_scrpos;         /* Saved position within the file */
 
36
};
 
37
 
 
38
/*
 
39
 * Convert an IFILE (external representation)
 
40
 * to a struct file (internal representation), and vice versa.
 
41
 */
 
42
#define int_ifile(h)    ((struct ifile *)(h))
 
43
#define ext_ifile(h)    ((IFILE)(h))
 
44
 
 
45
/*
 
46
 * Anchor for linked list.
 
47
 */
 
48
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, 0, 0, '\0',
 
49
                                { NULL_POSITION, 0 } };
 
50
static int ifiles = 0;
 
51
 
 
52
        static void
 
53
incr_index(p, incr)
 
54
        register struct ifile *p;
 
55
        int incr;
 
56
{
 
57
        for (;  p != &anchor;  p = p->h_next)
 
58
                p->h_index += incr;
 
59
}
 
60
 
 
61
/*
 
62
 * Link an ifile into the ifile list.
 
63
 */
 
64
        static void
 
65
link_ifile(p, prev)
 
66
        struct ifile *p;
 
67
        struct ifile *prev;
 
68
{
 
69
        /*
 
70
         * Link into list.
 
71
         */
 
72
        if (prev == NULL)
 
73
                prev = &anchor;
 
74
        p->h_next = prev->h_next;
 
75
        p->h_prev = prev;
 
76
        prev->h_next->h_prev = p;
 
77
        prev->h_next = p;
 
78
        /*
 
79
         * Calculate index for the new one,
 
80
         * and adjust the indexes for subsequent ifiles in the list.
 
81
         */
 
82
        p->h_index = prev->h_index + 1;
 
83
        incr_index(p->h_next, 1);
 
84
        ifiles++;
 
85
}
 
86
        
 
87
/*
 
88
 * Unlink an ifile from the ifile list.
 
89
 */
 
90
        static void
 
91
unlink_ifile(p)
 
92
        struct ifile *p;
 
93
{
 
94
        p->h_next->h_prev = p->h_prev;
 
95
        p->h_prev->h_next = p->h_next;
 
96
        incr_index(p->h_next, -1);
 
97
        ifiles--;
 
98
}
 
99
 
 
100
/*
 
101
 * Allocate a new ifile structure and stick a filename in it.
 
102
 * It should go after "prev" in the list
 
103
 * (or at the beginning of the list if "prev" is NULL).
 
104
 * Return a pointer to the new ifile structure.
 
105
 */
 
106
        static struct ifile *
 
107
new_ifile(filename, prev)
 
108
        char *filename;
 
109
        struct ifile *prev;
 
110
{
 
111
        register struct ifile *p;
 
112
 
 
113
        /*
 
114
         * Allocate and initialize structure.
 
115
         */
 
116
        p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
 
117
        p->h_filename = save(filename);
 
118
        p->h_scrpos.pos = NULL_POSITION;
 
119
        p->h_opened = 0;
 
120
        p->h_hold = 0;
 
121
        p->h_filestate = NULL;
 
122
        link_ifile(p, prev);
 
123
        return (p);
 
124
}
 
125
 
 
126
/*
 
127
 * Delete an existing ifile structure.
 
128
 */
 
129
        public void
 
130
del_ifile(h)
 
131
        IFILE h;
 
132
{
 
133
        register struct ifile *p;
 
134
 
 
135
        if (h == NULL_IFILE)
 
136
                return;
 
137
        /*
 
138
         * If the ifile we're deleting is the currently open ifile,
 
139
         * move off it.
 
140
         */
 
141
        unmark(h);
 
142
        if (h == curr_ifile)
 
143
                curr_ifile = getoff_ifile(curr_ifile);
 
144
        p = int_ifile(h);
 
145
        unlink_ifile(p);
 
146
        free(p->h_filename);
 
147
        free(p);
 
148
}
 
149
 
 
150
/*
 
151
 * Get the ifile after a given one in the list.
 
152
 */
 
153
        public IFILE
 
154
next_ifile(h)
 
155
        IFILE h;
 
156
{
 
157
        register struct ifile *p;
 
158
 
 
159
        p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
 
160
        if (p->h_next == &anchor)
 
161
                return (NULL_IFILE);
 
162
        return (ext_ifile(p->h_next));
 
163
}
 
164
 
 
165
/*
 
166
 * Get the ifile before a given one in the list.
 
167
 */
 
168
        public IFILE
 
169
prev_ifile(h)
 
170
        IFILE h;
 
171
{
 
172
        register struct ifile *p;
 
173
 
 
174
        p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
 
175
        if (p->h_prev == &anchor)
 
176
                return (NULL_IFILE);
 
177
        return (ext_ifile(p->h_prev));
 
178
}
 
179
 
 
180
/*
 
181
 * Return a different ifile from the given one.
 
182
 */
 
183
        public IFILE
 
184
getoff_ifile(ifile)
 
185
        IFILE ifile;
 
186
{
 
187
        IFILE newifile;
 
188
        
 
189
        if ((newifile = prev_ifile(ifile)) != NULL_IFILE)
 
190
                return (newifile);
 
191
        if ((newifile = next_ifile(ifile)) != NULL_IFILE)
 
192
                return (newifile);
 
193
        return (NULL_IFILE);
 
194
}
 
195
 
 
196
/*
 
197
 * Return the number of ifiles.
 
198
 */
 
199
        public int
 
200
nifile()
 
201
{
 
202
        return (ifiles);
 
203
}
 
204
 
 
205
/*
 
206
 * Find an ifile structure, given a filename.
 
207
 */
 
208
        static struct ifile *
 
209
find_ifile(filename)
 
210
        char *filename;
 
211
{
 
212
        register struct ifile *p;
 
213
 
 
214
        for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
 
215
                if (strcmp(filename, p->h_filename) == 0)
 
216
                        return (p);
 
217
        return (NULL);
 
218
}
 
219
 
 
220
/*
 
221
 * Get the ifile associated with a filename.
 
222
 * If the filename has not been seen before,
 
223
 * insert the new ifile after "prev" in the list.
 
224
 */
 
225
        public IFILE
 
226
get_ifile(filename, prev)
 
227
        char *filename;
 
228
        IFILE prev;
 
229
{
 
230
        register struct ifile *p;
 
231
 
 
232
        if ((p = find_ifile(filename)) == NULL)
 
233
                p = new_ifile(filename, int_ifile(prev));
 
234
        return (ext_ifile(p));
 
235
}
 
236
 
 
237
/*
 
238
 * Get the filename associated with a ifile.
 
239
 */
 
240
        public char *
 
241
get_filename(ifile)
 
242
        IFILE ifile;
 
243
{
 
244
        if (ifile == NULL)
 
245
                return (NULL);
 
246
        return (int_ifile(ifile)->h_filename);
 
247
}
 
248
 
 
249
/*
 
250
 * Get the index of the file associated with a ifile.
 
251
 */
 
252
        public int
 
253
get_index(ifile)
 
254
        IFILE ifile;
 
255
{
 
256
        return (int_ifile(ifile)->h_index); 
 
257
}
 
258
 
 
259
/*
 
260
 * Save the file position to be associated with a given file.
 
261
 */
 
262
        public void
 
263
store_pos(ifile, scrpos)
 
264
        IFILE ifile;
 
265
        struct scrpos *scrpos;
 
266
{
 
267
        int_ifile(ifile)->h_scrpos = *scrpos;
 
268
}
 
269
 
 
270
/*
 
271
 * Recall the file position associated with a file.
 
272
 * If no position has been associated with the file, return NULL_POSITION.
 
273
 */
 
274
        public void
 
275
get_pos(ifile, scrpos)
 
276
        IFILE ifile;
 
277
        struct scrpos *scrpos;
 
278
{
 
279
        *scrpos = int_ifile(ifile)->h_scrpos;
 
280
}
 
281
 
 
282
/*
 
283
 * Mark the ifile as "opened".
 
284
 */
 
285
        public void
 
286
set_open(ifile)
 
287
        IFILE ifile;
 
288
{
 
289
        int_ifile(ifile)->h_opened = 1;
 
290
}
 
291
 
 
292
/*
 
293
 * Return whether the ifile has been opened previously.
 
294
 */
 
295
        public int
 
296
opened(ifile)
 
297
        IFILE ifile;
 
298
{
 
299
        return (int_ifile(ifile)->h_opened);
 
300
}
 
301
 
 
302
        public void
 
303
hold_ifile(ifile, incr)
 
304
        IFILE ifile;
 
305
        int incr;
 
306
{
 
307
        int_ifile(ifile)->h_hold += incr;
 
308
}
 
309
 
 
310
        public int
 
311
held_ifile(ifile)
 
312
        IFILE ifile;
 
313
{
 
314
        return (int_ifile(ifile)->h_hold);
 
315
}
 
316
 
 
317
        public void *
 
318
get_filestate(ifile)
 
319
        IFILE ifile;
 
320
{
 
321
        return (int_ifile(ifile)->h_filestate);
 
322
}
 
323
 
 
324
        public void
 
325
set_filestate(ifile, filestate)
 
326
        IFILE ifile;
 
327
        void *filestate;
 
328
{
 
329
        int_ifile(ifile)->h_filestate = filestate;
 
330
}
 
331
 
 
332
#if 0
 
333
        public void
 
334
if_dump()
 
335
{
 
336
        register struct ifile *p;
 
337
 
 
338
        for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
 
339
        {
 
340
                printf("%x: %d. <%s> pos %d,%x\n", 
 
341
                        p, p->h_index, p->h_filename, 
 
342
                        p->h_scrpos.ln, p->h_scrpos.pos);
 
343
                ch_dump(p->h_filestate);
 
344
        }
 
345
}
 
346
#endif