/* ----------------------------------------------------------------------------- * chicken.swg * * CHICKEN configuration module. * ----------------------------------------------------------------------------- */ /* chicken.h has to appear first. */ %insert(runtime) %{ #include "chicken.h" %} %insert(runtime) "precommon.swg" %insert(runtime) "common.swg"; // Common type-checking code %insert(runtime) "chickenrun.swg"; // CHICKEN run-time code /* ----------------------------------------------------------------------------- * standard typemaps * ----------------------------------------------------------------------------- */ /* CHICKEN: C ---------- fixnum: int, short, unsigned int, unsigned short, unsigned char, signed char char: char bool: bool flonum: float, double, long, long long, unsigned long, unsigned long long */ /* --- Primitive types --- */ %include "fragments.i" %define SIMPLE_TYPEMAP(type_, from_scheme, to_scheme, checker, convtype, storage_) %typemap(in) type_ %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'"); } $1 = ($1_ltype) from_scheme ($input); %} /* Const primitive references. Passed by value */ %typemap(in) const type_ & ($*1_ltype temp) %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'"); } temp = ($*1_ltype) from_scheme ($input); $1 = &temp; %} /* --- Variable input --- */ %typemap(varin) type_ %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use '$1_ltype' for variable '$name' of type 'type_'"); } $1 = ($1_ltype) from_scheme ($input); %} #if "storage_" == "0" %typemap(out, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (convtype ($1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype ($1))); /*endif*/ %} /* References to primitive types. Return by value */ %typemap(out, fragment="list_output_helper",chicken_words="storage_") const type_ & %{/*if ONE*/ $result = to_scheme (convtype (*$1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype (*$1))); /*endif*/ %} /* --- Variable output --- */ %typemap(varout, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (convtype ($varname)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype ($varname))); /*endif*/ %} #else %typemap(out, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (&known_space, convtype ($1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (&known_space, convtype ($1))); /*endif*/ %} /* References to primitive types. Return by value */ %typemap(out, fragment="list_output_helper",chicken_words="storage_") const type_ & %{/*if ONE*/ $result = to_scheme (convtype (*$1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype (*$1))); /*endif*/ %} /* --- Variable output --- */ %typemap(varout, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (&known_space, convtype ($varname)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (&known_space, convtype ($varname))); /*endif*/ %} #endif /* --- Constants --- */ #if ("type_" == "char") || ("type_" == "unsigned char") || ("type_" == "signed char") %typemap(constcode) type_ "static const $1_type $result = '$value';" #else %typemap(constcode) type_ "static const $1_type $result = $value;" #endif %enddef SIMPLE_TYPEMAP(int, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(enum SWIGTYPE, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(short, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(long long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(unsigned int, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(unsigned short, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(unsigned long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(unsigned long long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(unsigned char, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(signed char, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0); SIMPLE_TYPEMAP(bool, C_truep, C_mk_bool, C_swig_is_bool, (bool), 0); SIMPLE_TYPEMAP(float, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(double, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); /* --- Input arguments --- */ /* Strings */ %typemap(in) char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else { if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'char *'"); } $1 = ($ltype) swig_make_string ($input); } } %typemap(freearg) char * "if ($1 != NULL) { free ($1); }" /* Pointers, references, and arrays */ %typemap(in) SWIGTYPE *, SWIGTYPE [] "swig_convert_ptr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION);" /* Additional check for null references */ %typemap(in) SWIGTYPE & "swig_convert_ptr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION); if ($1 == NULL) swig_barf (SWIG_BARF1_ARGUMENT_NULL, \"null reference\");" /* Void pointer. Accepts any kind of pointer */ %typemap(in) void * "swig_convert_ptr($input,(void **) &$1, 0, SWIG_POINTER_EXCEPTION);" /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_ltype argp) "swig_convert_ptr($input,(void **) &argp, $&1_descriptor,SWIG_POINTER_EXCEPTION); $1 = *argp; "; /* Pointer to a class member */ %typemap(in) SWIGTYPE (CLASS::*) "swig_convert_packed($input, (void *) &$1, sizeof($1_type), $1_descriptor,SWIG_POINTER_EXCEPTION);"; /* --- Output values --- */ /* Strings */ %typemap(out,fragment="list_output_helper",chicken_words="0") char * { char *s = (char*) $1; if ($1 == NULL) { $result = C_SCHEME_FALSE; } else { int string_len = strlen ($1); C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len)); /*if ONE*/ $result = C_string (&string_space, string_len, s); /*else*/ $result = list_output_helper (&known_space, $result, C_string (&string_space, string_len, s)); /*endif*/ } } %typemap(varout,fragment="list_output_helper",chicken_words="0") char * { char *s = (char*) $varname; if ($varname == NULL) { $result = C_SCHEME_FALSE; } else { int string_len = strlen ($varname); C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len)); /*if ONE*/ $result = C_string (&string_space, string_len, s); /*else*/ $result = list_output_helper (&known_space, $result, C_string (&string_space, string_len, s)); /*endif*/ } } /* Pointers, references, and arrays */ %typemap(out,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = swig_new_pointer_obj((void *) $1, &known_space, $1_descriptor);"; /* Dynamic casts */ %typemap(out,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); $result = swig_new_pointer_obj((void *) $1, &known_space, ty); } /* Member pointer */ %typemap(out,chicken_words="SWIG_ALLOCSZ_PACKED_OBJ(sizeof($1_type),$typename)") SWIGTYPE (CLASS::*) "$result = swig_new_packed_obj((void *) &$1, &known_space, sizeof($1_type), $1_descriptor);"; /* Void */ %typemap(out,chicken_words="void") void %{ /*if ONE*/ $result = C_SCHEME_UNDEFINED; /*else*/ /* void return value, no need to be in $result */ /*endif*/ %} /* Special typemap for character array return values */ %typemap(out,fragment="list_output_helper",chicken_words="0") char [ANY], const char [ANY] %{ if ($1 == NULL) { $result = C_SCHEME_FALSE; } else { const int string_len = strlen ($1); C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len)); /*if ONE*/ $result = C_string (&string_space, string_len, $1); /*else*/ $result = list_output_helper (&known_space, $result, C_string (&string_space, string_len, $1)); /*endif*/ } %} /* Primitive types--return by value */ %typemap(out,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = swig_new_pointer_obj((void *) resultptr, &known_space, $&1_descriptor); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = swig_new_pointer_obj((void *) resultptr, &known_space, $&1_descriptor); } #endif /* --- Variable input --- */ /* A string */ #ifdef __cplusplus %typemap(varin) char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); if ($1) delete [] $1; $1 = ($type) new char[len+1]; strncpy((char*)$1, temp, len); ((char*)$1) [len] = 0; } } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); $1 = ($type) new char[len+1]; strncpy((char*)$1,temp,len); ((char*)$1) [len] = 0; } } #else %typemap(varin) char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); if ($1) free((char*) $1); $1 = ($type) malloc(len+1); strncpy((char*)$1,temp,len); ((char*)$1) [len] = 0; } } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); $1 = ($type) malloc(len+1); strncpy((char*)$1,temp,len); ((char*)$1) [len] = 0; } } #endif /* Special case for string array variables */ %typemap(varin) char [ANY] { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); strncpy($1,temp,$1_dim0); } } %typemap(varin) SWIGTYPE * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else { void *temp; swig_convert_ptr($input,(void **) &temp, $1_descriptor, SWIG_POINTER_EXCEPTION); $1 = ($1_ltype) temp; } } %typemap(varin) SWIGTYPE & { void *temp; swig_convert_ptr($input,(void **) &temp, $1_descriptor, SWIG_POINTER_EXCEPTION); if (temp == NULL) { swig_barf (SWIG_BARF1_ARGUMENT_NULL, "$name is a null reference"); return 1; } $1 = ($1_ltype) temp; } %typemap(varin) void * { void * temp; swig_convert_ptr($input,(void **) &temp, 0, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN); $1 = ($1_ltype) temp; } %typemap(varin) SWIGTYPE (CLASS::*) { char temp[sizeof($1_type)]; swig_convert_packed($input,(void *) temp, sizeof($1_type), $1_descriptor, SWIG_POINTER_EXCEPTION); memmove((void *) &$1,temp,sizeof($1_type)); } %typemap(varin) SWIGTYPE { $&1_ltype temp; swig_convert_ptr($input, (void **) &temp, $&1_descriptor, SWIG_POINTER_EXCEPTION); $1 = *(($&1_type) temp); } /* --- Variable output --- */ /* Pointers, references, and arrays */ %typemap(varout,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = swig_new_pointer_obj((void *) $varname, &known_space, $1_descriptor);"; /* Member pointer */ %typemap(varout,chicken_words="SWIG_ALLOCSZ_PACKED_OBJ(sizeof($1_type),$typename)") SWIGTYPE (CLASS::*) "$result = swig_new_packed_obj((void *) &$varname, sizeof($1_type), &known_space, $1_descriptor);"; /* Void */ %typemap(varout) void "$result = C_SCHEME_UNDEFINED;"; /* Special typemap for character array return values */ %typemap(varout) char [ANY], const char [ANY] %{ if ($varname == C_SCHEME_FALSE) { $result = NULL; } else if (C_swig_is_string ($varname)) { $result = swig_make_string ($varname); } else { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'string'"); } %} %typemap(varout,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE "$result = swig_new_pointer_obj((void *) &$varname, &known_space, $&1_descriptor);"; /* --- Constants --- */ %typemap(constcode) char * "static const char *$result = \"$value\";" %typemap(constcode) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "static const void *$result = (void*) $value;" %typemap(constcode) SWIGTYPE (CLASS::*) "static const void *$result = (void*) &$value;" /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in) (char *STRING, int LENGTH) { if ($input == C_SCHEME_FALSE) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use a null/#f string for a char*, int arguments"); } else if (C_swig_is_string ($input)) { $1 = ($1_ltype) C_c_string ($input); $2 = ($2_ltype) C_header_size ($input); } else { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'string'"); } } /* ------------------------------------------------------------ * ANSI C typemaps * ------------------------------------------------------------ */ %typemap(in) size_t %{ if (!C_swig_is_flonum ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'flonum'"); } $1 = (size_t) C_flonum_magnitude ($input); %} %typemap(out) size_t = long; %typemap(varin) size_t = long; %typemap(varout) size_t = long; %typemap(constcode) size_t = long; /* ------------------------------------------------------------ * CHICKEN types * ------------------------------------------------------------ */ %typemap(in) C_word "$1 = $input;"; %typemap(out) C_word "$result = $1;"; /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) bool, const bool & { $1 = C_swig_is_bool ($input); } %typecheck(SWIG_TYPECHECK_INTEGER) int, short, unsigned int, unsigned short, signed char, unsigned char, const int &, const short &, const unsigned int &, const unsigned short &, enum SWIGTYPE { $1 = C_swig_is_fixnum ($input); } %typecheck(SWIG_TYPECHECK_INTEGER) long, unsigned long, long long, unsigned long long, const long &, const unsigned long &, const long long &, const unsigned long long & { $1 = (C_swig_is_bool ($input) || C_swig_is_fixnum ($input) || C_swig_is_flonum ($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = C_swig_is_flonum ($input); } %typecheck(SWIG_TYPECHECK_CHAR) char { $1 = C_swig_is_string ($input); } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = C_swig_is_string ($input); } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; if (swig_convert_ptr($input, (void **) &ptr, $1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; if (swig_convert_ptr($input, (void **) &ptr, $&1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; if (swig_convert_ptr($input, (void **) &ptr, 0, 0) == -1) { $1 = 0; } else { $1 = 1; } } /* ------------------------------------------------------------ * Exception handling * ------------------------------------------------------------ */ /* TODO */ /* ------------------------------------------------------------ * Overloaded operator support * ------------------------------------------------------------ */ #ifdef __cplusplus %rename(__add__) *::operator+; %rename(__pos__) *::operator+(); %rename(__pos__) *::operator+() const; %rename(__sub__) *::operator-; %rename(__neg__) *::operator-(); %rename(__neg__) *::operator-() const; %rename(__mul__) *::operator*; %rename(__div__) *::operator/; %rename(__mod__) *::operator%; %rename(__lshift__) *::operator<<; %rename(__rshift__) *::operator>>; %rename(__and__) *::operator&; %rename(__or__) *::operator|; %rename(__xor__) *::operator^; %rename(__invert__) *::operator~; %rename(__iadd__) *::operator+=; %rename(__isub__) *::operator-=; %rename(__imul__) *::operator*=; %rename(__idiv__) *::operator/=; %rename(__imod__) *::operator%=; %rename(__ilshift__) *::operator<<=; %rename(__irshift__) *::operator>>=; %rename(__iand__) *::operator&=; %rename(__ior__) *::operator|=; %rename(__ixor__) *::operator^=; %rename(__lt__) *::operator<; %rename(__le__) *::operator<=; %rename(__gt__) *::operator>; %rename(__ge__) *::operator>=; %rename(__eq__) *::operator==; %rename(__ne__) *::operator!=; /* Special cases */ %rename(__call__) *::operator(); /* Ignored operators */ %ignorewarn("362:operator= ignored") operator=; %ignorewarn("383:operator++ ignored") operator++; %ignorewarn("384:operator-- ignored") operator--; %ignorewarn("381:operator&& ignored") operator&&; %ignorewarn("382:operator|| ignored") operator||; %ignorewarn("386:operator->* ignored") operator->*; %ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; #endif /* Warnings for certain CHICKEN keywords */ %include "chickenkw.swg" /* TinyCLOS <--> Low-level CHICKEN */ %typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))" %typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)" /* VERBATIM CODE INSERTIONS */ %insert(header) %{ #ifdef __cplusplus extern "C" { #endif /* Chicken initialization function */ SWIGEXPORT(void) $realmodule_swig_init(int, C_word, C_word) C_noret; /* Tag functions */ SWIGEXPORT(int) $realmodule_swig_num_types (void); SWIGEXPORT(const char*) $realmodule_swig_type_name (int); SWIGEXPORT(void*) $realmodule_swig_type_ptr (int); SWIGEXPORT(const char*) $realmodule_swig_type_str (int); SWIGEXPORT(void) $realmodule_swig_type_tag (int, C_word); #ifdef __cplusplus } #endif %} %insert(init) %{ /* CHICKEN initialization function */ SWIGEXPORT(void) $realmodule_swig_init(int argc, C_word closure, C_word continuation) { static int typeinit = 0; int i; if (!typeinit) { for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } typeinit = 1; swig_init_helper (continuation); } else { C_kontinue (continuation, C_SCHEME_FALSE); } } /* Tag functions */ SWIGEXPORT(int) $realmodule_swig_num_types (void) { int i; for (i=0; swig_types_initial[i]; i++); return i; } SWIGEXPORT(const char*) $realmodule_swig_type_name (int index) { return swig_types[index]->name; } SWIGEXPORT(void*) $realmodule_swig_type_ptr (int index) { return (void*) (swig_types[index]); } SWIGEXPORT(const char*) $realmodule_swig_type_str (int index) { return swig_types[index]->str; } SWIGEXPORT(void) $realmodule_swig_type_tag (int index, C_word tag) { swig_chicken_clientdata *data = (swig_chicken_clientdata*) malloc (sizeof (swig_chicken_clientdata)); C_mutate (&(data->tag), tag); data->literal_frame = C_register_lf (&(data->tag), 1); SWIG_TypeClientData (swig_types[index], (void*) data); } %} %insert(chicken) %{ (declare (foreign-declare "C_extern int $realmodule_swig_num_types (void);") (foreign-declare "C_extern char* $realmodule_swig_type_name (int);") (foreign-declare "C_extern void* $realmodule_swig_type_ptr (int);") (foreign-declare "C_extern char* $realmodule_swig_type_str (int);") (foreign-declare "C_extern void $realmodule_swig_type_tag (int, C_word);")) (define-record swig-$module-tag class name ptr str) (define-record-printer (swig-$module-tag tag out) (fprintf out "#(~A)" (swig-$module-tag-str tag) (swig-$module-tag-ptr tag))) (define swig-$module-tag-num ((foreign-lambda int "$realmodule_swig_num_types"))) (define swig-$module-tags (make-vector swig-$module-tag-num #f)) (letrec ((gen (lambda (l i) (if (= i 0) (cons 0 l) (gen (cons i l) (- i 1)))))) (let ((indices (if (<= swig-$module-tag-num 0) (quote ()) (gen (quote ()) (- swig-$module-tag-num 1))))) (for-each (lambda (index) (let ((tag (make-swig-$module-tag 1000 ((foreign-lambda c-string "$realmodule_swig_type_name" int) index) ((foreign-lambda c-pointer "$realmodule_swig_type_ptr" int) index) ((foreign-lambda c-string "$realmodule_swig_type_str" int) index)))) (vector-set! swig-$module-tags index tag) ((foreign-lambda void "$realmodule_swig_type_tag" int scheme-object) index tag))) indices))) %}