This file is indexed.

/usr/share/nip2/start/_Object.def is in nip2 7.26.3-1build1.

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
/* Lots of little arg checks. Global for convenience.
 */

check_any = [(const true), _ "any"];
check_bool = [is_bool, _ "boolean"];
check_real = [is_real, _ "real"];
check_ureal = [is_ureal, _ "unsigned real"];
check_preal = [is_preal, _ "positive real"];
check_list = [is_list, _ "list"];
check_real_list = [is_real_list, _ "list of real"];
check_string = [is_string, _ "string"];
check_string_list = [is_string_list, _ "list of string"];
check_int = [is_int, _ "integer"];
check_uint = [is_uint, _ "unsigned integer"];
check_pint = [is_pint, _ "positive integer"];
check_matrix = [is_matrix, _ "rectangular array of real"];
check_matrix_display = [Matrix_display.is_display, _ "0|1|2|3"];
check_image = [is_image, _ "image"];
check_xy_list = [is_xy_list, _ "list of form [[1, 2], [3, 4], [5, 6], ...]"];
check_instance name = [is_instanceof name, name];
check_Image = check_instance "Image";
check_Matrix = [is_Matrix, _ "Matrix"];
check_colour_space = [is_colour_space, 
	join_sep "|" Image_type.colour_spaces.names];
check_rectangular = [is_rectangular, _ "rectangular [[*]]"];
check_Guide = [is_Guide, _ "HGuide|VGuide"];
check_Colour = check_instance (_ "Colour");
check_Mark = check_instance (_ "Mark");

/* Check a set of args to a class. Two members to look at: _check_args and
 * _check_all.
 *
 * - each line in _check_args is [arg, "arg name", [test_fn, "arg type"]]
 *   same number of lines as there are args
 *
 *   stuff like "arg 2 must be real"
 *
 * - each line in _check_all is [test, "description"]
 *   any number of lines 
 *
 *   stuff like "to must be greater than from"
 *
 * generate an error dialog with a helpful message on failure.
 *
 * Have as a separate function to try to keep the size of _Object down.
 */
check_args x
	= error message, badargs != [] || badalls != []
	= x
{
	argcheck = x._check_args;
	allcheck = x._check_all;

	// indent string
	indent = "    ";

	// test for a condition in a check line fails
	test_fail x = ! x?0;

	// set of failed argcheck indexes
	badargs = map (extract 1) 
		(filter test_fail (zip2 (map testarg argcheck) [0..]))
	{
		testarg x = x?2?0 x?0;
	}

	// set of failed allcheck indexes
	badalls = map (extract 1) 
		(filter test_fail (zip2 (map hd allcheck) [0..]));

	// the error message
	message = _ "bad properties for " ++ "\"" ++ x.name ++ "\"\n" ++
		argmsg ++ allmsg ++ "\n" ++
		_ "where" ++ "\n" ++ arg_types ++ extra;

	// make the failed argcheck messages ... eg.  ""value" should be 
	// real, you passed <function>" etc.
	argmsg = concat (map fmt badargs)
	{
		fmt n = indent ++ "\"" ++ argcheck?n?1 ++ "\"" ++
			_ " should be of type " ++ argcheck?n?2?1 ++ ", " ++
			_ "you passed" ++ ":\n" ++ 
			indent ++ indent ++ print argcheck?n?0 ++ "\n";
	}

	// make the failed allcheck messages ... eg "condition failed:
	// x < y" ... don't make a message if any typechecks have 
	// failed, as we'll probably error horribly
	allmsg 
		= [], badargs != []
		= concat (map fmt badalls) ++ 
			_ "you passed" ++ "\n" ++
			concat (map fmt_arg argcheck)
	{
		fmt n = _ "condition failed" ++ ": " ++ allcheck?n?1 ++ "\n";
		fmt_arg l = indent ++ l?1 ++ " = " ++ print l?0 ++ "\n";
	}

	// make arg type notes
	arg_types = join_sep "\n" (map fmt argcheck)
	{
		fmt l = indent ++ l?1 ++ " is of type " ++ l?2?1;
	}

	// extra bit at the bottom, if we have any conditions
	extra 
		= [], allcheck == []
		= "\n" ++ _ "and" ++ "\n" ++ all_desc;

	// make a list of all the allcheck descriptions, with a few 
	// spaces in front
	all_desc_list = map (join indent @ extract 1) allcheck;

	// join em up to make a set of condition notes
	all_desc = join_sep "\n" all_desc_list;
}

/* Operator overloading stuff.
 */

Operator_type = class {
	ARITHMETIC = 1;			// eg. add
	RELATIONAL = 2;			// eg. less
	COMPOUND = 3;			// eg. max/mean/etc.
	COMPOUND_REWRAP = 4;	// eg. transpose
}

Operator op_name fn type symmetric = class {
}

/* Form the converse of an Operator.
 */
oo_converse op 
	= Operator (converse_name op.op_name) 
		(converse op.fn) op.type op.symmetric
{
	converse_name x
		= init x, last x == last "'"
		= x ++ "'";
}

/* Given an operator name, look up the definition.
 */
oo_binary_lookup op_name
	= matches?0, matches != []
	= error (_ "unknown binary operator" ++ ": " ++ print op_name)
{
	operator_table = [
		Operator "add" add 
			Operator_type.ARITHMETIC true,
		Operator "subtract" subtract 
			Operator_type.ARITHMETIC false,
		Operator "remainder" remainder 
			Operator_type.ARITHMETIC false,
		Operator "power" power 
			Operator_type.ARITHMETIC false,
		Operator "subscript" subscript 
			Operator_type.ARITHMETIC false,
		Operator "left_shift" left_shift 
			Operator_type.ARITHMETIC false,
		Operator "right_shift" right_shift 
			Operator_type.ARITHMETIC false,
		Operator "divide" divide 
			Operator_type.ARITHMETIC false,
		Operator "join" join 
			Operator_type.ARITHMETIC false,
		Operator "multiply" multiply 
			Operator_type.ARITHMETIC true,
		Operator "logical_and" logical_and 
			Operator_type.ARITHMETIC true,
		Operator "logical_or" logical_or 
			Operator_type.ARITHMETIC true,
		Operator "bitwise_and" bitwise_and 
			Operator_type.ARITHMETIC true,
		Operator "bitwise_or" bitwise_or 
			Operator_type.ARITHMETIC true,
		Operator "eor" eor 
			Operator_type.ARITHMETIC true,
		Operator "comma" comma 
			Operator_type.ARITHMETIC false,
		Operator "if_then_else" if_then_else 
			Operator_type.ARITHMETIC false,
		Operator "equal" equal 
			Operator_type.RELATIONAL true,
		Operator "not_equal" not_equal 
			Operator_type.RELATIONAL true,
		Operator "less" less 
			Operator_type.RELATIONAL false,
		Operator "less_equal" less_equal 
			Operator_type.RELATIONAL false
	];

	matches = filter test_name operator_table;
	test_name x = x.op_name == op_name;
}

/* Given an operator name, look up a function that implements that
 * operator.
 */
oo_unary_lookup op_name
	= matches?0, matches != []
	= error (_ "unknown unary operator" ++ ": " ++ print op_name)
{
	operator_table = [
		/* Operators.
		 */
		Operator "cast_signed_char" cast_signed_char 
		Operator_type.ARITHMETIC false,
		Operator "cast_unsigned_char" cast_unsigned_char 
		Operator_type.ARITHMETIC false,
		Operator "cast_signed_short" cast_signed_short 
		Operator_type.ARITHMETIC false,
		Operator "cast_unsigned_short" cast_unsigned_short 
		Operator_type.ARITHMETIC false,
		Operator "cast_signed_int" cast_signed_int 
		Operator_type.ARITHMETIC false,
		Operator "cast_unsigned_int" cast_unsigned_int 
		Operator_type.ARITHMETIC false,
		Operator "cast_float" cast_float 
		Operator_type.ARITHMETIC false,
		Operator "cast_double" cast_double 
		Operator_type.ARITHMETIC false,
		Operator "cast_complex" cast_complex 
		Operator_type.ARITHMETIC false,
		Operator "cast_double_complex" cast_double_complex 
		Operator_type.ARITHMETIC false,
		Operator "unary_minus" unary_minus 
		Operator_type.ARITHMETIC false,
		Operator "negate" negate 
		Operator_type.RELATIONAL false,
		Operator "complement" complement 
		Operator_type.ARITHMETIC false,
		Operator "unary_plus" unary_plus 
		Operator_type.ARITHMETIC false,

		/* Built in projections.
 		 */
		Operator "re" re Operator_type.ARITHMETIC false,
		Operator "im" im Operator_type.ARITHMETIC false,
		Operator "hd" hd Operator_type.ARITHMETIC false,
		Operator "tl" tl Operator_type.ARITHMETIC false,

		/* Maths builtins.
		 */
		Operator "sin" sin Operator_type.ARITHMETIC false,
		Operator "cos" cos Operator_type.ARITHMETIC false,
		Operator "tan" tan Operator_type.ARITHMETIC false,
		Operator "asin" asin Operator_type.ARITHMETIC false,
		Operator "acos" acos Operator_type.ARITHMETIC false,
		Operator "atan" atan Operator_type.ARITHMETIC false,
		Operator "log" log Operator_type.ARITHMETIC false,
		Operator "log10" log10 Operator_type.ARITHMETIC false,
		Operator "exp" exp Operator_type.ARITHMETIC false,
		Operator "exp10" exp10 Operator_type.ARITHMETIC false,
		Operator "ceil" ceil Operator_type.ARITHMETIC false,
		Operator "floor" floor Operator_type.ARITHMETIC false
	];

	matches = filter test_name operator_table;
	test_name x = x.op_name == op_name;
}

/* Find the matching methods in a method table.
 */
oo_method_lookup table = map (extract 0) (filter (extract 1) table);

/* A binary op: a is a class, b may be a class ... eg. "add" a b

   two obvious ways to find a method:

   - a.oo_binary_search "add" (+) b
   - b.oo_binary_search "add'" (converse (+)) a, is_class b

   if these fail but op is a symmetric operator (eg. a + b == b + a), we can
   also try reversing the args

   - a.oo_binary_search "add'" (converse (+)) b
   - b.oo_binary_search "add" (+) a, is_class b

   if those fail as well, but this is ==, do pointer equals as a fallback

 */
oo_binary_function op a b
	= matches1?0, 
		matches1 != []
	= matches2?0, 
		is_class b && matches2 != []
	= matches3?0, 
		op.symmetric && matches3 != []
	= matches4?0, 
		op.symmetric && is_class b && matches4 != []
	= pointer_equal a b,
		op.op_name == "equal" || op.op_name == "equal'"
	= not_pointer_equal a b,
		op.op_name == "not_equal" || op.op_name == "not_equal'"
	= error (_ "No method found for binary operator." ++ "\n" ++
		_ "left" ++ " = " ++ print a ++ "\n" ++
		_ "operator" ++ " = " ++ op.op_name ++ "\n" ++
		_ "right" ++ " = " ++ print b)
{
	matches1 = oo_method_lookup (a.oo_binary_table op b);
	matches2 = oo_method_lookup (b.oo_binary_table (oo_converse op) a);
	matches3 = oo_method_lookup (a.oo_binary_table (oo_converse op) b);
	matches4 = oo_method_lookup (b.oo_binary_table op a);
}

/* A binary op: a is not a class, b is a class ... eg. "subtract" a b

   only one way to find a method:

   - b.oo_binary_search "subtract'" (converse (-)) a

   if this fails but op is a symmetric operator (eg. a + b == b + a), we can
   try reversing the args

   - b.oo_binary_search "add" (+) a, is_class b

   if that fails as well, but this is ==, do pointer equals as a fallback

 */
oo_binary'_function op a b
	= matches1?0, matches1 != []
	= matches2?0, op.symmetric && matches2 != []
	= pointer_equal a b,
		op.op_name == "equal" || op.op_name == "equal'"
	= not_pointer_equal a b,
		op.op_name == "not_equal" || op.op_name == "not_equal'"
	= error (_ "No method found for binary operator." ++ "\n" ++
		_ "left" ++ " = " ++ print a ++ "\n" ++
		_ "operator" ++ " = " ++ op.op_name ++ "\n" ++
		_ "right" ++ " = " ++ print b)
{
	matches1 = oo_method_lookup (b.oo_binary_table (oo_converse op) a);
	matches2 = oo_method_lookup (b.oo_binary_table op a);
}

oo_unary_function op x
	= matches?0, matches != []
	= error (_ "No method found for unary operator." ++ "\n" ++ 
		_ "operator" ++ " = " ++ op.op_name ++ "\n" ++
		_ "argument" ++ " = " ++ print x)
{
	matches = oo_method_lookup (x.oo_unary_table op);
}

/* Base class for nip's built-in classes ... base check function, base
 * operator overload functions.
 */
_Object = class {
	check = check_args this;

	// these should always be defined
	_check_args = [];
	_check_all = [];

	/* Operator overloading stuff.
	 */
	oo_binary op x = oo_binary_function (oo_binary_lookup op) this x;
	oo_binary' op x = oo_binary'_function (oo_binary_lookup op) x this;
	oo_unary op = oo_unary_function (oo_unary_lookup op) this;

	oo_binary_table op x = [];
	oo_unary_table op = [];
}