This file is indexed.

/usr/include/wvstreams/wvlinklist.h is in libwvstreams-dev 4.6.1-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
/* -*- Mode: C++ -*-
 * Worldvisions Weaver Software:
 *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
 *
 * A linked list container.
 */
#ifndef __WVLINKLIST_H
#define __WVLINKLIST_H

#include "wvtypetraits.h"
#include "wvsorter.h"

/**
 * @internal
 * The untyped base class of WvList<T>.
 * 
 * Putting common code in here allows us to prevent it from being
 * replicated by each template instantiation of WvList<T>.
 * 
 */
class WvListBase
{
    WvListBase(const WvListBase &l); // copy constructor - not actually defined anywhere!
private:
    //This is private to force people to pass by reference, not by value
    WvListBase& operator= (const WvListBase &l);
    
public:
    WvLink head, *tail;

    /** Creates an empty linked list. */
    WvListBase() : head(NULL, false)
        { tail = &head; }

    /**
     * Returns the number of elements in the list.
     * 
     * This function causes a full traversal of the list which may be
     * overly inefficient depending on how and when it is used.
     * 
     * Returns: the number of elements
     */
    size_t count() const;

    /**
     * Reverses the order of elements in the list.
     *
     * This function traverses the list and rearranges the pointers
     * and updates the pointers to head & tail appropriately.
     *
     * It does nothing for lists of count<2
     */
    void reverse();

    /**
     * Quickly determines if the list is empty.
     * 
     * This is much faster than checking count() == 0.
     * 
     * Returns: true if empty
     */
    bool isempty() const
        { return head.next == NULL; }

    /**
     * @internal
     * The untyped base class of WvList<T>::Iter.
     * 
     * Putting common code in here allows us to prevent it from being
     * replicated by each template instantiation of WvList<T>.
     * 
     */
    class IterBase
    {
    public:
	const WvListBase *list;
	WvLink *link, *prev;

        /**
         * Binds the iterator to the specified list.
         * "l" is the list
         */
	IterBase(const WvListBase &l)
            { list = &l; link = NULL; }

        /**
         * Rewinds the iterator to make it point to an imaginary element
         * preceeding the first element of the list.
         */
	void rewind() // dropping a const pointer here!  Danger!
            { prev = NULL; link = &((WvListBase *)list)->head; }

	
        /**
         * Moves the iterator along the list to point to the next element.
         * 
         * If the iterator had just been rewound, it now points to the
         * first element of the list.
         * 
         * Returns: the current WvLink pointer, or null if there were no
         *         more elements remaining in the traversal sequence
         */
	WvLink *next()
            { prev = link; return link = link->next; }

        /**
         * Returns a pointer to the WvLink at the iterator's current location.
         * Returns: the current WvLink pointer, or null if there were no
         *         more elements remaining in the traversal sequence
         */
	WvLink *cur() const
            { return link; }
	
	/**
	 * Returns a void pointer to the object at the iterator's current
	 * location.  You should almost never need this.  Use ptr() instead.
	 */
	void *vptr() const
	    { return link->data; }

        /**
         * Rewinds the iterator and repositions it over the element that
         * matches the specified value.
         *
         * Uses pointer equality (object identity) as the criteria for
         * finding the matching element.
         *
         * In order to locate multiple matching elements, first call find()
         * and then use find_next().
         *
         * Returns: the current WvLink pointer, or null if no such element
         *          was found
         */
	WvLink *find(const void *data);

        /**
         * Repositions the iterator over the element that matches the
         * specified value.
         *
         * Uses pointer equality (object identity) as the criteria for
         * finding the matching element.
         *
         * Returns: the current WvLink pointer, or null if no such element
         *          was found
         */
	WvLink *find_next(const void*data);
    };
};


/**
 * A linked list container class.
 * 
 * Some rather horrible macros are used to declare actual concrete
 * list types.
 * 
 * Example:
 * 
 *   DeclareWvList(WvString);
 *
 *   int main()
 *   {
 *       WvStringList l;
 *       WvStringList::Iter i(l);
 *
 *       ... fill the list ...
 *
 *       i.rewind();
 *       while (i.next())
 *           printf("%s\\n", i.str);
 *   }
 * 
 * 
 * Deallocating list will free all of the WvLinks in the list, but
 * will only free the user objects that were added with autofree
 * set to true.
 * 
 * We need to malloc memory for each WvLink as well as the data it
 * stores; this is unnecessarily slow.  I would rather have made a
 * base "Link" class for object types that could be stored as links
 * in a list, and then used object->next instead of all the
 * List Iterator stuff, but the end result was pure ugliness, so I
 * gave up.  At least this way, the same object can be in multiple
 * lists.
 * 
 * List type construction is facilitated by the following macros:
 * 
 *  - DeclareWvList(Type): creates a subclass named TypeList
 *     that contains pointers to Type.
 *  - DeclareWvList2(name, Type): as the above, but calls the
 *     resulting class by the specified name. 
 * 
 * 
 * "T" is the object type
 */
template<class T>
class WvList : public WvListBase
{
    // copy constructor: not defined anywhere!
    WvList(const WvList &list);

public:
    /** Creates an empty linked list. */
    WvList()
	{ }
    
    /**
     * Destroys the linked list.
     * 
     * Destroys any elements that were added with autofree == true.
     * 
     */
    ~WvList()
	{ zap(); }
	
    /** Invoked by subclasses after the linked list is first created. */
    void setup() {}
    
    /** Invoked by subclasses before the linked list is destroyed. */
    void shutdown() {}

    /**
     * Clears the linked list.
     * 
     * If destroy is true, destroys any elements that were added with autofree == true.
     * 
     */
    void zap(bool destroy = true)
    {
        while (head.next)
            unlink_after(& head, destroy);
    }

    /**
     * Returns a pointer to the first element in the linked list.
     * 
     * The list must be non-empty.
     * 
     * Returns: the element pointer, possibly null
     */
    T *first() const
        { return (T*)head.next->data; }

    /**
     * Returns a pointer to the last element in the linked list.
     * 
     * The list must be non-empty.
     * 
     * Returns: the element pointer, possibly null
     */
    T *last() const
        { return (T*)tail->data; }

    /**
     * Adds the element after the specified link in the list.
     *
     * "link" is the link preceeding the desired location of the element
     *             to be inserted, non-null
     * "data" is the element pointer, may be null
     * "autofree" is if true, takes ownership of the element
     * "id" is an optional string to associate with the element, or null
     */
    void add_after(WvLink *after, T *data, bool autofree,
			const char *id = NULL )
    {
	(void)new WvLink((void *)data, after, tail, autofree, id);
    }

    /**
     * Appends the element to the end of the list.
     *
     * "data" is the element pointer, may be null
     * "autofree" is if true, takes ownership of the element
     * "id" is an optional string to associate with the element, or null
     */
    void append(T *data, bool autofree, const char *id = NULL)
	{ add_after(tail, data, autofree, id); }

    /**
     * Synonym for append(T*, bool, char*).
     * @see append(T*, bool, char*)
     */
    void add(T *data, bool autofree, const char *id = NULL)
        { append(data, autofree, id); }

    /**
     * Prepends the element to the beginning of the list.
     *
     * "data" is the element pointer, may be null
     * "autofree" is if true, takes ownership of the element
     * "id" is an optional string to associate with the element, or null
     */
    void prepend(T *data, bool autofree, const char *id = NULL)
	{ add_after(&head, data, autofree, id); }

    /**
     * Unlinks the specified element from the list.
     * 
     * Destroys the element if it was added with autofree == true.
     * 
     * "data" is the element pointer, may be null
     */
    void unlink(T *data)
        { Iter i(*this); while (i.find(data)) i.unlink(); }

    /**
     * Unlinks the first element from the list.
     * 
     * Destroys the element if it was added with autofree == true.
     * 
     */ 
    void unlink_first()
    { 
        if(head.next != NULL)   
        { Iter i(*this); i.rewind(); i.next(); i.unlink(); }
    }
    /**
     * Unlinks the element that follows the specified link in the list.
     * 
     * Destroys the element if it was added with autofree == true and
     * destroy == true.
     * 
     * "after" is the link preceeding the element to be removed, non-null
     */ 
    void unlink_after(WvLink *after, bool destroy = true)
    {
        WvLink *next = after->next;
        if(next != NULL)
        {
            T *obj = (destroy && next->get_autofree()) ?
            static_cast<T*>(next->data) : NULL;
            if (next == tail) tail = after;
            next->unlink(after);
	    if (obj)
	        WvTraits<T>::release(obj);
        }
    }

    /**
     * The iterator type for linked lists.
     * 
     * An iterator instance does not initially point to any valid
     * elements in a list.  Before using, it must be reset using rewind()
     * which causes it to point to an imaginary element located before
     * the first elements in the list.  Then next() must be invoked
     * to incrementally move the iterator along the list to first element,
     * and then later to the second, third, and subsequent elements.
     * 
     */
    class Iter : public WvListBase::IterBase
    {
    public:
        /**
         * Binds the iterator to the specified list.
         * "l" is the list
         */
        Iter(const WvList &l) : IterBase(l)
            { }

        /**
         * Returns a pointer to the current element.
         * Returns: the element pointer, possibly null
         */
        T *ptr() const
            { return (T *)link->data; }

	WvIterStuff(T);

	/**
	 * Returns the state of autofree for the current element.
	 */
	bool get_autofree() const
	{
	    return link->get_autofree();
	}

	/**
	 * Sets the state of autofree for the current element.
	 */
	void set_autofree(bool autofree)
	{
	    link->set_autofree(autofree);
	}

        /**
         * Unlinks the current element from the list and automatically
         * increments the iterator to point to the next element as if
         * next() had been called.
         */
        void unlink(bool destroy = true)
        {
	    if (prev) ((WvList *)list)->unlink_after(prev, destroy);
	    link = prev->next;
        }
	
        /**
         * Unlinks the current element from the list but unlike unlink()
         * automatically returns the iterator to the previous link in
         * the list such that next() must be called to obtain the
         * next element.
         * 
         * This version allows for writing neater loop structures since
         * an element can be unlinked in mid-traversal while still allowing
         * the iterator to be incremented at the top of the loop as usual.
         * 
         * Calling xunlink() twice in a row is currently unsupported.
         * 
         */
	void xunlink(bool destroy = true)
	{
	    if (prev) ((WvList *)list)->unlink_after(prev, destroy);
	    link = prev;
	}
    };
    
    /** The sorted iterator type for linked lists. */
    typedef class WvSorter<T, WvListBase, WvListBase::IterBase> Sorter;
};

#define DeclareWvList2(_classname_, _type_)  \
    typedef class WvList<_type_> _classname_ 

#define DeclareWvList(_type_) DeclareWvList2(_type_##List, _type_)


#endif // __WVLINKLIST_H