This file is indexed.

/usr/include/pike7.8/pike/array.h is in pike7.8-dev 7.8.700-7.

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
/*
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
|| $Id: d0533bae20ed6798d5747f5e710f214b1b979c00 $
*/

#ifndef ARRAY_H
#define ARRAY_H

#include "svalue.h"
#include "dmalloc.h"

/* This debug tool writes out messages whenever arrays with unfinished
 * type fields are encountered. */
/* #define TRACE_UNFINISHED_TYPE_FIELDS */

/**
 * A Pike array is represented as a 'struct array' with all the
 * needed svalues malloced in the same block.
 * 
 * @see type_field
 */
struct array
{
  PIKE_MEMORY_OBJECT_MEMBERS;

  struct array *next;	/**< we need to keep track of all arrays */
  struct array *prev;	/**< Another pointer, so we don't have to search
			 * when freeing arrays */
  INT32 size;		/**< number of svalues in this array */
  INT32 malloced_size;	/**< number of svalues that can fit in this array */
  TYPE_FIELD type_field;/**< A bitfield with one bit for each type of
			  * data in this array.
   Bits can be set that don't exist in the array. type_field is
   * initialized to BIT_MIXED|BIT_UNFINISHED for newly allocated
   * arrays so that they can be modified without having to update
   * this. It should be set accurately when that's done, though. */
  INT16 flags;          /**< ARRAY_* flags */
  struct svalue *item;  /**< the array of svalues */
  struct svalue real_item[1];
};

#define ARRAY_WEAK_FLAG 1
#define ARRAY_CYCLIC 2
#define ARRAY_LVALUE 4

PMOD_EXPORT extern struct array empty_array, weak_empty_array;
extern struct array *first_array;
extern struct array *gc_internal_array;

#if defined(DEBUG_MALLOC) && defined(PIKE_DEBUG)
#define ITEM(X) (((struct array *)(debug_malloc_pass((X))))->item)
#else
#define ITEM(X) ((X)->item)
#endif

/* These are arguments for the function 'merge' which merges two sorted
 * set stored in arrays in the way you specify
 */
#define PIKE_ARRAY_OP_A 1
#define PIKE_ARRAY_OP_SKIP_A 2
#define PIKE_ARRAY_OP_TAKE_A 3
#define PIKE_ARRAY_OP_B 4
#define PIKE_ARRAY_OP_SKIP_B 8
#define PIKE_ARRAY_OP_TAKE_B 12
#define PIKE_MINTERM(X,Y,Z) (((X)<<8)+((Y)<<4)+(Z))

#define PIKE_ARRAY_OP_AND PIKE_MINTERM(PIKE_ARRAY_OP_SKIP_A,PIKE_ARRAY_OP_SKIP_A | PIKE_ARRAY_OP_TAKE_B,PIKE_ARRAY_OP_SKIP_B)
#define PIKE_ARRAY_OP_AND_LEFT PIKE_MINTERM(PIKE_ARRAY_OP_SKIP_A,PIKE_ARRAY_OP_SKIP_B | PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_B)
#define PIKE_ARRAY_OP_OR  PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_A | PIKE_ARRAY_OP_TAKE_B,PIKE_ARRAY_OP_TAKE_B)
#define PIKE_ARRAY_OP_OR_LEFT  PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_B | PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_TAKE_B)
#define PIKE_ARRAY_OP_XOR PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_A | PIKE_ARRAY_OP_SKIP_B,PIKE_ARRAY_OP_TAKE_B)
#define PIKE_ARRAY_OP_ADD PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_TAKE_A | PIKE_ARRAY_OP_TAKE_B ,PIKE_ARRAY_OP_TAKE_B)
#define PIKE_ARRAY_OP_SUB PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_A ,PIKE_ARRAY_OP_SKIP_B)

/**
 *  This macro frees one reference to the array V. If the reference
 *  is the last reference to the array, it will free the memory used
 *  by the array V.
 *  @param V an array struct to be freed.
 */
#define free_array(V) do{						\
    struct array *v_=(V);						\
    debug_malloc_touch(v_);						\
    DO_IF_DEBUG (							\
      DO_IF_PIKE_CLEANUP (						\
	if (gc_external_refs_zapped)					\
	  gc_check_zapped (v_, PIKE_T_ARRAY, __FILE__, __LINE__)));	\
    if(!sub_ref(v_))							\
      really_free_array(v_);						\
  }while(0)

#define allocate_array(X) low_allocate_array((X),0)
#define allocate_array_no_init(X,Y) low_allocate_array((X),(Y))

typedef int (*cmpfun)(const struct svalue *, const struct svalue *);
typedef int (*short_cmpfun)(union anything *, union anything *);
typedef short_cmpfun (*cmpfun_getter)(TYPE_T);


#define low_allocate_array(size, extra_space)				\
  dmalloc_touch (struct array *,					\
		 real_allocate_array ((size), (extra_space)))

/* Prototypes begin here */
PMOD_EXPORT struct array *real_allocate_array(ptrdiff_t size, ptrdiff_t extra_space);
PMOD_EXPORT void really_free_array(struct array *v);
PMOD_EXPORT void do_free_array(struct array *a);
PMOD_EXPORT struct array *array_set_flags(struct array *a, int flags);
PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 ind);
PMOD_EXPORT struct array *array_column (struct array *data, struct svalue *index,
					int destructive);
PMOD_EXPORT void simple_array_index_no_free(struct svalue *s,
				struct array *a,struct svalue *ind);
PMOD_EXPORT void array_free_index(struct array *v,INT32 ind);
PMOD_EXPORT void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s);
PMOD_EXPORT struct array *array_insert(struct array *v,struct svalue *s,INT32 ind);
void o_append_array(INT32 args);
PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size);
PMOD_EXPORT struct array *array_shrink(struct array *v, ptrdiff_t size);
PMOD_EXPORT struct array *array_remove(struct array *v,INT32 ind);
PMOD_EXPORT ptrdiff_t array_search(struct array *v, struct svalue *s,
				   ptrdiff_t start);
PMOD_EXPORT struct array *slice_array(struct array *v, ptrdiff_t start,
				      ptrdiff_t end);
PMOD_EXPORT struct array *friendly_slice_array(struct array *v,
					       ptrdiff_t start,
					       ptrdiff_t end);
PMOD_EXPORT struct array *copy_array(struct array *v);
PMOD_EXPORT void check_array_for_destruct(struct array *v);
PMOD_EXPORT INT32 array_find_destructed_object(struct array *v);
INT32 *get_order(struct array *v, cmpfun fun);
int set_svalue_cmpfun(const struct svalue *a, const struct svalue *b);
int alpha_svalue_cmpfun(const struct svalue *a, const struct svalue *b);
PMOD_EXPORT void sort_array_destructively(struct array *v);
PMOD_EXPORT INT32 *stable_sort_array_destructively(struct array *v);
PMOD_EXPORT INT32 *get_set_order(struct array *a);
PMOD_EXPORT INT32 *get_switch_order(struct array *a);
PMOD_EXPORT INT32 *get_alpha_order(struct array *a);
INT32 set_lookup(struct array *a, struct svalue *s);
INT32 switch_lookup(struct array *a, struct svalue *s);
PMOD_EXPORT struct array *order_array(struct array *v, INT32 *order);
PMOD_EXPORT struct array *reorder_and_copy_array(struct array *v, INT32 *order);
PMOD_EXPORT TYPE_FIELD array_fix_type_field(struct array *v);
#ifdef PIKE_DEBUG
PMOD_EXPORT void array_check_type_field(struct array *v);
#endif
PMOD_EXPORT union anything *low_array_get_item_ptr(struct array *a,
				       INT32 ind,
				       TYPE_T t);
PMOD_EXPORT union anything *array_get_item_ptr(struct array *a,
				   struct svalue *ind,
				   TYPE_T t);
INT32 * merge(struct array *a,struct array *b,INT32 opcode);
PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper);
PMOD_EXPORT struct array *add_arrays(struct svalue *argp, INT32 args);
PMOD_EXPORT int array_equal_p(struct array *a, struct array *b, struct processing *p);
PMOD_EXPORT struct array *merge_array_with_order(struct array *a,
						 struct array *b, INT32 op);
PMOD_EXPORT struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op);
PMOD_EXPORT struct array *merge_array_without_order(struct array *a,
					struct array *b,
					INT32 op);
PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b);
PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b);
int array_is_constant(struct array *a,
		      struct processing *p);
node *make_node_from_array(struct array *a);
PMOD_EXPORT void push_array_items(struct array *a);
void describe_array_low(struct array *a, struct processing *p, int indent);
#ifdef PIKE_DEBUG
void simple_describe_array(struct array *a);
void describe_index(struct array *a,
		    int e,
		    struct processing *p,
		    int indent);
#endif
void describe_array(struct array *a,struct processing *p,int indent);
PMOD_EXPORT struct array *aggregate_array(INT32 args);
PMOD_EXPORT struct array *append_array(struct array *a, struct svalue *s);
PMOD_EXPORT struct array *explode(struct pike_string *str,
		       struct pike_string *del);
PMOD_EXPORT struct pike_string *implode(struct array *a,struct pike_string *del);
PMOD_EXPORT struct array *copy_array_recursively(struct array *a,
						 struct mapping *p);
PMOD_EXPORT void apply_array(struct array *a, INT32 args, int flags);
PMOD_EXPORT struct array *reverse_array(struct array *a, int start, int end);
void array_replace(struct array *a,
		   struct svalue *from,
		   struct svalue *to);
#ifdef PIKE_DEBUG
PMOD_EXPORT void check_array(struct array *a);
void check_all_arrays(void);
#endif
PMOD_EXPORT void visit_array (struct array *a, int action);
void gc_mark_array_as_referenced(struct array *a);
void real_gc_cycle_check_array(struct array *a, int weak);
unsigned gc_touch_all_arrays(void);
void gc_check_all_arrays(void);
void gc_mark_all_arrays(void);
void gc_cycle_check_all_arrays(void);
void gc_zap_ext_weak_refs_in_arrays(void);
size_t gc_free_all_unreferenced_arrays(void);
#ifdef PIKE_DEBUG
void debug_dump_type_field(TYPE_FIELD t);
void debug_dump_array(struct array *a);
#endif
void count_memory_in_arrays(size_t *num_, size_t *size_);
PMOD_EXPORT struct array *explode_array(struct array *a, struct array *b);
PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b);
/* Prototypes end here */

#define array_get_flags(a) ((a)->flags)

#define visit_array_ref(A, REF_TYPE)					\
  visit_ref (pass_array (A), (REF_TYPE),				\
	     (visit_thing_fn *) &visit_array, NULL)
#define gc_cycle_check_array(X, WEAK) \
  gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_array, (X), (WEAK))


/** Macros for aggregating results built on the stack into an array,
 * while maintaining a bound on stack consumption. Use like this:
 *
 * check_stack(120);
 * BEGIN_AGGREGATE_ARRAY(estimated_size_of_final_array) {
 *   for (...) {
 *     ... stuff that produces a value on the stack ...
 *     DO_AGGREGATE_ARRAY(120);
 *     ...
 *   }
 * } END_AGGREGATE_ARRAY;
 *
 * The array is left on top of the stack.
 */

#define AGGR_ARR_PROLOGUE(base_sval, estimated_size) do {		\
    push_array(allocate_array_no_init(0, (estimated_size)));		\
    base_sval = Pike_sp;						\
    if (base_sval[-1].u.array->malloced_size)				\
      base_sval[-1].u.array->type_field = (BIT_MIXED | BIT_UNFINISHED);	\
  } while (0)

#define AGGR_ARR_CHECK(base_sval, max_keep_on_stack)			\
  do {									\
    ptrdiff_t diff__ = Pike_sp - base_sval;				\
    if (diff__ > (max_keep_on_stack)) {					\
      INT32 oldsize__ = base_sval[-1].u.array->size;			\
      ACCEPT_UNFINISHED_TYPE_FIELDS {					\
	base_sval[-1].u.array =						\
	  resize_array(base_sval[-1].u.array, oldsize__ + diff__);	\
      } END_ACCEPT_UNFINISHED_TYPE_FIELDS;				\
      /* Unless the user does something, the type field will contain */	\
      /* BIT_MIXED|BIT_UNFINISHED from the allocation above. */		\
      MEMCPY((char *) (ITEM(base_sval[-1].u.array) + oldsize__),	\
	     (char *) base_sval, diff__ * sizeof(struct svalue));	\
      Pike_sp = base_sval;						\
    }									\
  } while (0)

#define AGGR_ARR_EPILOGUE(base_sval) do {				\
    ptrdiff_t diff__ = Pike_sp - base_sval;				\
    if (!diff__) {							\
      if (!base_sval[-1].u.array->size) {				\
	free_array (base_sval[-1].u.array);				\
	add_ref (base_sval[-1].u.array = &empty_array);			\
      }									\
    }									\
    else								\
      AGGR_ARR_CHECK (base_sval, 0);					\
    if (base_sval[-1].u.array->type_field & BIT_UNFINISHED)		\
      array_fix_type_field(Pike_sp[-1].u.array);			\
    DO_IF_DEBUG(if (Pike_sp[-1].type != T_ARRAY) {			\
	Pike_fatal("Lost track of aggregated array.\n");		\
      });								\
  } while (0)

#define BEGIN_AGGREGATE_ARRAY(estimated_size) do {			\
    struct svalue *base__;						\
    AGGR_ARR_PROLOGUE (base__, estimated_size);

#define DO_AGGREGATE_ARRAY(max_keep_on_stack)				\
    AGGR_ARR_CHECK (base__, max_keep_on_stack)

#define END_AGGREGATE_ARRAY						\
    AGGR_ARR_EPILOGUE (base__);						\
  } while (0)


/**
 * Extract an svalue from an array
 */
#define array_index_no_free(S,A,I) do {				\
  INT32 ind_=(I);						\
  struct array *v_=(A);						\
  DO_IF_DEBUG(							\
    if(ind_<0 || ind_>=v_->size)				\
    Pike_fatal("Illegal index in low level index routine.\n");	\
    )								\
								\
  assign_svalue_no_free((S), ITEM(v_) + ind_);			\
}while(0)


/**
 * Sets an index in an array. 
 * 
 * @param V the array to modify
 * @param I the index of the array to set
 * @param S the svalue to set
 */
#define array_set_index_no_free(V,I,S) do {				\
  struct array *v_=(V);							 \
  INT32 index_=(I);							 \
  struct svalue *s_=(S);						 \
									 \
  DO_IF_DEBUG(								 \
  if(index_<0 || index_>v_->size)					 \
    Pike_fatal("Illegal index in low level array set routine.\n");	 \
    )									 \
									 \
  check_destructed(s_);							 \
									 \
  v_->type_field |= 1 << s_->type;					 \
  assign_svalue_no_free( ITEM(v_) + index_, s_);			 \
}while(0)
#define array_set_index(V,I,S) do {					\
  struct array *v_=(V);							 \
  INT32 index_=(I);							 \
  struct svalue *s_=(S);						 \
									 \
  DO_IF_DEBUG(								 \
  if(index_<0 || index_>v_->size)					 \
    Pike_fatal("Illegal index in low level array set routine.\n");	 \
    )									 \
									 \
  check_destructed(s_);							 \
									 \
  v_->type_field |= 1 << s_->type;					 \
  assign_svalue( ITEM(v_) + index_, s_);				\
}while(0)

#define array_fix_unfinished_type_field(A) do {				\
    struct array *a_ = (A);						\
    if (a_->type_field & BIT_UNFINISHED) {				\
      DO_IF_DEBUG (array_check_type_field (a_));			\
      array_fix_type_field (a_);					\
    }									\
  } while (0)

#ifdef TRACE_UNFINISHED_TYPE_FIELDS
/* Note: These macros don't support thread switches. */

extern PMOD_EXPORT int accept_unfinished_type_fields;
PMOD_EXPORT void dont_accept_unfinished_type_fields (void *orig);

#define ACCEPT_UNFINISHED_TYPE_FIELDS do {				\
    ONERROR autf_uwp_;							\
    int orig_autf_ = accept_unfinished_type_fields;			\
    accept_unfinished_type_fields++;					\
    SET_ONERROR (autf_uwp_, dont_accept_unfinished_type_fields,		\
		 (void *) orig_autf_);					\
    do

#define END_ACCEPT_UNFINISHED_TYPE_FIELDS				\
    while (0);								\
    accept_unfinished_type_fields = orig_autf_;				\
    UNSET_ONERROR (autf_uwp_);						\
  } while (0)

#else

#define ACCEPT_UNFINISHED_TYPE_FIELDS do
#define END_ACCEPT_UNFINISHED_TYPE_FIELDS while (0)

#endif

#endif /* ARRAY_H */