This file is indexed.

/usr/share/doc/libelektra-dev/examples/functional.c is in libelektra-dev 0.8.7-4.

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
#include <kdb.h>

// for keySetComment
#include <kdbextension.h>

#include <stdlib.h>

/**A functional access to keys.
 *
 * Instead of writing your own loop you can write
 * a function working with a key and pass it to
 * this method.
 *
 * The function will be executed for all keys in
 * the keyset.
 *
 * @param ks the keyset to work with
 * @param func the function to execute on every key of the keyset
 * @return the sum of all return values
 * @return -1 if any function returned -1, the execution will stop there, but
 * 	ksCurrent() will tell you where it stopped.
 * @see ksFilter()
 */
int ksForEach (KeySet *ks, int (*func) (Key *k))
{
	int rc = 0;
	int ret = 0;
	Key *current;

	cursor_t cursor = ksGetCursor (ks);
	ksRewind (ks);
	while ((current = ksNext (ks)) != 0)
	{
		rc = func (current);
		if (rc == -1) return -1;
		ret += rc;
	}
	ksSetCursor(ks, cursor);
	return ret;
}


/**Filter a keyset.
 *
 * filter is executed for every key in the keyset result. When it returns 0,
 * the key will be dropped, when it returns 1 it will be ksAppendKey()ed to result,
 * when it returns -1 the processing will be stopped. You can use ksCurrent()
 * on input to see where the problem was. Because of this input is not const,
 * apart from ksCurrent() the input will not be changed. The keys that have
 * been in result before will stay untouched.
 *
 * @param result is the keyset where keys are added.
 * @param input is the keyset the filter works on.
 * @param filter is the function to execute on every key of the keyset to decide if
 * 	it should be ksAppendKey()ed to the result.
 * @return the number of keys added on success
 * @return 0 when nothing was done
 * @return -1 when filter returned an error (-1), ksCurrent() of input will
 * 	be the problematic key.
 * @see ksForEach()
 **/
int ksFilter (KeySet *result, KeySet *input, int (*filter) (Key *k))
{
	int rc = 0;
	int ret = 0;
	Key *current;

	cursor_t cursor = ksGetCursor (input);
	ksRewind (input);
	while ((current = ksNext (input)) != 0)
	{
		rc = filter (current);
		if (rc == -1) return -1;
		else if (rc != 0)
		{
			++ ret;
			ksAppendKey(result, keyDup (current));
		}
	}
	ksSetCursor(input, cursor);
	return ret;
}


Key *global_a;

int add_string (Key *check) { return keySetString (check, "string"); }
int add_comment (Key *check) { return keySetComment (check, "comment"); }
int has_a (Key *check) { return keyName(check)[5]=='a'; }
int below_a (Key *check) { return keyIsBelow(global_a, check); }
int direct_below_a (Key *check) { return keyIsDirectBelow(global_a, check); }

int sum_helper (Key *check) { return atoi(keyValue(check)); }
int below_30 (Key *check) { return atoi(keyValue(check))<30; }
int find_80 (Key *check) { int n=atoi(keyValue(check)); return n>70?-1:1; }

int main()
{
	KeySet *out;
	KeySet *ks = ksNew (64,
		keyNew ("user/a/1", KEY_END),
		keyNew ("user/a/2", KEY_END),
		keyNew ("user/a/b/1", KEY_END),
		keyNew ("user/a/b/2", KEY_END),
		keyNew ("user/ab/2", KEY_END),
		keyNew ("user/b/1", KEY_END),
		keyNew ("user/b/2", KEY_END),
		KS_END);
	KeySet *values = 0;
	KeySet *values_below_30 = 0;

	global_a = keyNew ("user/a", KEY_END);

	ksForEach (ks, add_string);
	ksForEach (ks, add_comment);

	out = ksNew (0);
	ksFilter (out, ks, has_a);
	ksDel (out);

	out = ksNew (0);
	ksFilter (out, ks, below_a);
	ksDel (out);

	out = ksNew (0);
	ksFilter (out, ks, direct_below_a);
	ksDel (out);

	ksDel (ks);
	keyDel (global_a); global_a = 0;

	values = ksNew (64,
		keyNew ("user/a", KEY_VALUE, "40", KEY_END),
		keyNew ("user/b", KEY_VALUE, "20", KEY_END),
		keyNew ("user/c", KEY_VALUE, "80", KEY_END),
		keyNew ("user/d", KEY_VALUE, "24", KEY_END),
		keyNew ("user/e", KEY_VALUE, "32", KEY_END),
		keyNew ("user/f", KEY_VALUE, "12", KEY_END),
		keyNew ("user/g", KEY_VALUE, "43", KEY_END),
		KS_END);

	/* add together */
	ksForEach (values, sum_helper);

	values_below_30 = ksNew (0);
	ksFilter (values_below_30, values, below_30);
	ksForEach (values_below_30, sum_helper);

	ksForEach (values, find_80);
	ksCurrent (values); /* here is user/c */
	ksLookupByName (values, "user/c", 0); /* should find the same */
	ksDel (values);
	ksDel (values_below_30);
}