1%{ 2/* 3 * Copyright 2004, 2008 by the Massachusetts Institute of Technology. 4 * All Rights Reserved. 5 * 6 * Export of this software from the United States of America may 7 * require a specific license from the United States Government. 8 * It is the responsibility of any person or organization contemplating 9 * export to obtain such a license before exporting. 10 * 11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 12 * distribute this software and its documentation for any purpose and 13 * without fee is hereby granted, provided that the above copyright 14 * notice appear in all copies and that both that copyright notice and 15 * this permission notice appear in supporting documentation, and that 16 * the name of M.I.T. not be used in advertising or publicity pertaining 17 * to distribution of the software without specific, written prior 18 * permission. Furthermore if you modify this software you must label 19 * your software as modified software and not distribute it in such a 20 * fashion that it might be confused with the original M.I.T. software. 21 * M.I.T. makes no representations about the suitability of 22 * this software for any purpose. It is provided "as is" without express 23 * or implied warranty. 24 * 25 * 26 * Input for wrapper generator program SWIG for profile routines. 27 */ 28#include <errno.h> 29#include "com_err.h" 30#include "profile.h" 31 32#ifdef SWIGTCL 33/* Reduce warnings about cast discarding const to just this one, from 34 every SWIG-generated call to Tcl_SetResult. */ 35static void my_tcl_setresult(Tcl_Interp *i, const char *str, Tcl_FreeProc *f) 36{ 37 Tcl_SetResult(i, (char *) str, f); 38} 39#undef Tcl_SetResult 40#define Tcl_SetResult my_tcl_setresult 41#endif 42%} 43 44%include "typemaps.i" 45 46/* These should perhaps be part of the general SWIG package, maybe? */ 47%typemap(in,numinputs=0) SWIGTYPE *OUTPUT ($1_basetype tmp) { 48 /*generic swigtype hack*/ $1 = &tmp; 49} 50%typemap(tcl8,argout) SWIGTYPE *OUTPUT 51 "/*generic swigtype hack*/ Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void *) *$1, $*1_descriptor,0));"; 52%typemap(python,argout) SWIGTYPE *OUTPUT 53 "/*generic swigtype hack*/ resultobj = SWIG_NewPointerObj((void *) *$1, $*1_descriptor,0);"; 54 55%module profile 56 57typedef long errcode_t; 58%inline %{ 59typedef void **iter_t; /* ick */ 60%} 61 62/* As a hack, if we have too much trouble trying to manage output 63 arguments for functions returning error codes, this output argument 64 type will let us twist it around into a function returning the 65 interesting type, and incidentally possibly raising an error. */ 66%typemap(in,numinputs=0) errcode_t * (errcode_t tmp) { 67 /* in errcode_t * */ 68 tmp = 0; 69 $1 = &tmp; 70} 71%typemap(tcl8,argout) errcode_t* { 72 /* argout errcode_t * */ 73 if (*$1) { 74 /* There could be a memory leak here in the SWIG-Tcl layer, 75 I'm not sure. Not going to worry about it though. */ 76 Tcl_SetResult(interp, (char *) error_message(*$1), TCL_STATIC); 77 SWIG_fail; 78 } 79} 80/* returning errcode_t */ 81%typemap(tcl8,out) errcode_t { 82 /* out errcode_t $1 */ 83 if ($1) { 84 /* There could be a memory leak here in the SWIG-Tcl layer, 85 I'm not sure. Not going to worry about it though. */ 86 Tcl_SetResult(interp, (char *) error_message($1), TCL_STATIC); 87 SWIG_fail; 88 } 89} 90%typemap(python,argout) errcode_t* { 91 /* do something with *($1) */ abort(); 92} 93%typemap(python,out) errcode_t { 94 /* do something with $1 */ abort(); 95} 96 97/* "char **OUTPUT" : Supply a place for the function to stuff one 98 string pointer. */ 99%typemap(in,numinputs=0) char **OUTPUT (char * tmp) { 100 /* in char **OUTPUT */ 101 tmp = NULL; 102 $1 = &tmp; 103} 104%typemap(tcl8,argout) char **OUTPUT { 105 /* argout char **OUTPUT */ 106/* Tcl_SetResult(interp, *$1, TCL_DYNAMIC); */ 107 char *s = ($1 && *$1) ? *$1 : ""; 108 Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), 109 Tcl_NewStringObj(s, strlen(s))); 110} 111%typemap(freearg) char **OUTPUT { 112 /* There may be a memory leak here. Investigate later, if anyone 113 cares. */ 114/* profile_release_string(*$1); */ 115} 116 117/* "char **nullterm" : Null-terminated list of strings, from a single 118 input value which is a list. */ 119%typemap(tcl8,in) char **nullterm { 120 /* in char **nullterm */ 121 int n; 122 if (Tcl_SplitList(interp, Tcl_GetStringFromObj($input,NULL), &n, &$1) == TCL_ERROR) SWIG_fail; 123} 124%typemap(tcl8,freearg) char **nullterm { 125 /* freearg char **nullterm */ 126 if ($1) { Tcl_Free((char *)$1); $1 = (char **) NULL; } 127} 128 129/* "char ***OUTPUT" : Supply a place for the function to stuff a 130 pointer to a list of strings, which will be combined into a list to 131 return, and the data from the function itself freed before 132 returning. */ 133%typemap(in,numinputs=0) char ***OUTPUT (char ** tmp) { 134 /* in char ***OUTPUT */ 135 tmp = NULL; 136 $1 = &tmp; 137} 138%typemap(tcl8,argout) char ***OUTPUT { 139 /* argout char ***OUTPUT */ 140 int i; 141 for (i = 0; (*$1)[i]; i++) 142 Tcl_AppendElement(interp, (*$1)[i]); 143} 144%typemap(tcl8,freearg) char ***OUTPUT { 145 /* freearg char ***OUTPUT */ 146 profile_free_list(*$1); 147} 148 149typedef struct _profile_t *profile_t; 150 151errcode_t profile_init_path(const char *path = NULL, profile_t *OUTPUT); 152errcode_t profile_init(const char **nullterm = NULL, profile_t *OUTPUT); 153errcode_t profile_flush(profile_t); 154errcode_t profile_flush_to_file(profile_t, const char *path); 155/* Nota bene: There is nothing at all in this code to prevent a script 156 from accessing a profile object after calling one of these routines 157 to destroy it! */ 158void profile_abandon(profile_t); 159void profile_release(profile_t); 160 161errcode_t profile_get_values(profile_t p, const char **nullterm, 162 char ***OUTPUT); 163 164/* XXX Because of the way this is specified, the default can only be 165 given if you're actually using all three names (e.g., for realm 166 data). SWIG currently doesn't support a non-optional argument (at 167 the scripting-language level -- the output-only argument doesn't 168 count) after an optional one. */ 169extern errcode_t profile_get_string(profile_t p, 170 const char *name, 171 const char *subname, 172 const char *subsubname = NULL, 173 const char *defval = NULL, 174 char **OUTPUT); 175 176errcode_t profile_get_integer(profile_t p, 177 const char *name, 178 const char *subname, 179 const char *subsubname = NULL, 180 int defval = 0, 181 int *OUTPUT); 182errcode_t profile_get_boolean(profile_t p, 183 const char *name, 184 const char *subname, 185 const char *subsubname = NULL, 186 int defval = 0, 187 int *OUTPUT); 188errcode_t profile_get_relation_names(profile_t p, 189 const char **nullterm, 190 char ***OUTPUT); 191errcode_t profile_get_subsection_names(profile_t p, 192 const char **nullterm, 193 char ***OUTPUT); 194 195%rename("profile_iterator_create") iter_create; 196%rename("profile_iterator_free") iter_free; 197%inline %{ 198static errcode_t iter_create(profile_t p, const char **nullterm, 199 int flags, iter_t *OUTPUT) 200{ 201 iter_t it; 202 errcode_t err; 203 char **args; 204 205 it = malloc(sizeof(*it)); 206 if (it == NULL) 207 return ENOMEM; 208 { 209 /* Memory leak! 210 211 The profile code seems to assume that I'll keep the string 212 array around for as long as the iterator is valid; I can't 213 create the iterator and then throw them away. 214 215 But right now, I can't be bothered to track the necessary 216 information to do the cleanup later. */ 217 int count, j; 218 for (count = 0; nullterm[count]; count++) ; 219 args = calloc(count+1, sizeof(char *)); 220 if (args == NULL) 221 return ENOMEM; 222 for (j = 0; j < count; j++) { 223 args[j] = strdup(nullterm[j]); 224 if (args[j] == NULL) 225 return ENOMEM; 226 } 227 args[j] = NULL; 228 } 229 err = profile_iterator_create(p, args, flags, it); 230 if (err) 231 free(it); 232 else 233 *OUTPUT = it; 234 return err; 235} 236static errcode_t iter_free(iter_t i) 237{ 238 profile_iterator_free(i); 239 free(i); 240} 241%} 242errcode_t profile_iterator(iter_t, char **OUTPUT, char **OUTPUT); 243 244 245errcode_t profile_update_relation(profile_t p, const char **nullterm, 246 const char *oldval, 247 const char *newval = NULL); 248errcode_t profile_clear_relation(profile_t p, const char **nullterm); 249errcode_t profile_rename_section(profile_t p, const char **nullterm, 250 const char *new_name = NULL); 251errcode_t profile_add_relation(profile_t p, const char **nullterm, 252 const char *new_val = NULL); 253/* XXX Should be using profile_free_buffer blah. */ 254errcode_t profile_flush_to_buffer(profile_t p, char **OUTPUT); 255 256#ifdef SWIGTCL 257%include "tclsh.i" 258#endif 259