summaryrefslogtreecommitdiffstats
path: root/src/util/profile/profile.swg
blob: 2e75bb4c6dc5519a9fe9a93157d5d9539831507d (plain)
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
%{
/*
 * Copyright 2004 by the Massachusetts Institute of Technology.
 * All Rights Reserved.
 *
 * Export of this software from the United States of America may
 *   require a specific license from the United States Government.
 *   It is the responsibility of any person or organization contemplating
 *   export to obtain such a license before exporting.
 * 
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
 * distribute this software and its documentation for any purpose and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of M.I.T. not be used in advertising or publicity pertaining
 * to distribution of the software without specific, written prior
 * permission.  Furthermore if you modify this software you must label
 * your software as modified software and not distribute it in such a
 * fashion that it might be confused with the original M.I.T. software.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without express
 * or implied warranty.
 *
 *
 * Input for wrapper generator program SWIG for profile routines.
 */
#include <errno.h>
#include "com_err.h"
#include "profile.h"

#ifdef SWIGTCL
/* Reduce warnings about cast discarding const to just this one, from
   every SWIG-generated call to Tcl_SetResult.  */
static void my_tcl_setresult(Tcl_Interp *i, const char *str, Tcl_FreeProc *f)
{
    Tcl_SetResult(i, (char *) str, f);
}
#undef Tcl_SetResult
#define Tcl_SetResult my_tcl_setresult
#endif
%}

%include "typemaps.i"

/* These should perhaps be part of the general SWIG package, maybe?  */
%typemap(in,numinputs=0) SWIGTYPE *OUTPUT ($1_basetype tmp) {
    /*generic swigtype hack*/ $1 = &tmp;
}
%typemap(tcl8,argout) SWIGTYPE *OUTPUT
  "/*generic swigtype hack*/ Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void *) *$1, $*1_descriptor,0));";
%typemap(python,argout) SWIGTYPE *OUTPUT
  "/*generic swigtype hack*/ resultobj = SWIG_NewPointerObj((void *) *$1, $*1_descriptor,0);";

%module profile

typedef long errcode_t;
%inline %{
typedef void **iter_t; /* ick */
%}

/* As a hack, if we have too much trouble trying to manage output
   arguments for functions returning error codes, this output argument
   type will let us twist it around into a function returning the
   interesting type, and incidentally possibly raising an error.  */
%typemap(in,numinputs=0) errcode_t * (errcode_t tmp) {
    /* in errcode_t * */
    tmp = 0;
    $1 = &tmp;
}
%typemap(tcl8,argout) errcode_t* {
    /* argout errcode_t * */
    if (*$1) {
	/* There could be a memory leak here in the SWIG-Tcl layer,
	   I'm not sure.  Not going to worry about it though.  */
	Tcl_SetResult(interp, (char *) error_message(*$1), TCL_STATIC);
	SWIG_fail;
    }
}
/* returning errcode_t */
%typemap(tcl8,out) errcode_t {
    /* out errcode_t $1 */
    if ($1) {
	/* There could be a memory leak here in the SWIG-Tcl layer,
	   I'm not sure.  Not going to worry about it though.  */
	Tcl_SetResult(interp, (char *) error_message($1), TCL_STATIC);
	SWIG_fail;
    }
}
%typemap(python,argout) errcode_t* {
    /* do something with *($1) */ abort();
}
%typemap(python,out) errcode_t {
    /* do something with $1 */ abort();
}

/* "char **OUTPUT" : Supply a place for the function to stuff one
   string pointer.  */
%typemap(in,numinputs=0) char **OUTPUT (char * tmp) {
    /* in char **OUTPUT */
    tmp = NULL;
    $1 = &tmp;
}
%typemap(tcl8,argout) char **OUTPUT {
    /* argout char **OUTPUT */
/*    Tcl_SetResult(interp, *$1, TCL_DYNAMIC); */
    char *s = ($1 && *$1) ? *$1 : "";
    Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
			     Tcl_NewStringObj(s, strlen(s)));
}
%typemap(freearg) char **OUTPUT {
    /* There may be a memory leak here.  Investigate later, if anyone
       cares.  */
/*    profile_release_string(*$1); */
}

/* "char **nullterm" : Null-terminated list of strings, from a single
   input value which is a list.  */
%typemap(tcl8,in) char **nullterm {
    /* in char **nullterm */
    int n;
    if (Tcl_SplitList(interp, Tcl_GetStringFromObj($input,NULL), &n, &$1) == TCL_ERROR) SWIG_fail;
}
%typemap(tcl8,freearg) char **nullterm {
    /* freearg char **nullterm */
    if ($1) { Tcl_Free((char *)$1); $1 = (char **) NULL; }
}

/* "char ***OUTPUT" : Supply a place for the function to stuff a
   pointer to a list of strings, which will be combined into a list to
   return, and the data from the function itself freed before
   returning.  */
%typemap(in,numinputs=0) char ***OUTPUT (char ** tmp) {
    /* in char ***OUTPUT */
    tmp = NULL;
    $1 = &tmp;
}
%typemap(tcl8,argout) char ***OUTPUT {
    /* argout char ***OUTPUT */
    int i;
    for (i = 0; (*$1)[i]; i++)
	Tcl_AppendElement(interp, (*$1)[i]);
}
%typemap(tcl8,freearg) char ***OUTPUT {
    /* freearg char ***OUTPUT */
    profile_free_list(*$1);
}

typedef struct _profile_t *profile_t;

errcode_t profile_init_path(const char *path = NULL, profile_t *OUTPUT);
errcode_t profile_init(const char **nullterm = NULL, profile_t *OUTPUT);
errcode_t profile_flush(profile_t);
errcode_t profile_flush_to_file(profile_t, const char *path);
/* Nota bene: There is nothing at all in this code to prevent a script
   from accessing a profile object after calling one of these routines
   to destroy it!  */
void profile_abandon(profile_t);
void profile_release(profile_t);

errcode_t profile_get_values(profile_t p, const char **nullterm,
			     char ***OUTPUT);

/* XXX Because of the way this is specified, the default can only be
   given if you're actually using all three names (e.g., for realm
   data).  SWIG currently doesn't support a non-optional argument (at
   the scripting-language level -- the output-only argument doesn't
   count) after an optional one.  */
extern errcode_t profile_get_string(profile_t p,
				    const char *name,
				    const char *subname,
				    const char *subsubname = NULL,
				    const char *defval = NULL,
				    char **OUTPUT);

errcode_t profile_get_integer(profile_t p,
			      const char *name,
			      const char *subname,
			      const char *subsubname = NULL,
			      int defval = 0,
			      int *OUTPUT);
errcode_t profile_get_boolean(profile_t p,
			      const char *name,
			      const char *subname,
			      const char *subsubname = NULL,
			      int defval = 0,
			      int *OUTPUT);
errcode_t profile_get_relation_names(profile_t p,
				     const char **nullterm,
				     char ***OUTPUT);
errcode_t profile_get_subsection_names(profile_t p,
				       const char **nullterm,
				       char ***OUTPUT);

%rename("profile_iterator_create") iter_create;
%rename("profile_iterator_free") iter_free;
%inline %{
static errcode_t iter_create(profile_t p, const char **nullterm,
			     int flags, iter_t *OUTPUT)
{
    iter_t it;
    errcode_t err;
    char **args;

    it = malloc(sizeof(*it));
    if (it == NULL)
	return errno;
    {
	/* Memory leak!

	   The profile code seems to assume that I'll keep the string
	   array around for as long as the iterator is valid; I can't
	   create the iterator and then throw them away.

	   But right now, I can't be bothered to track the necessary
	   information to do the cleanup later.  */
	int count, j;
	for (count = 0; nullterm[count]; count++) ;
	args = calloc(count+1, sizeof(char *));
	if (args == NULL)
	    return errno;
	for (j = 0; j < count; j++) {
	    args[j] = strdup(nullterm[j]);
	    if (args[j] == NULL)
		return errno;
	}
	args[j] = NULL;
    }
    err = profile_iterator_create(p, args, flags, it);
    if (err)
	free(it);
    else
	*OUTPUT = it;
    return err;
}
static errcode_t iter_free(iter_t i)
{
    profile_iterator_free(i);
    free(i);
}
%}
errcode_t profile_iterator(iter_t, char **OUTPUT, char **OUTPUT);


errcode_t profile_update_relation(profile_t p, const char **nullterm,
				  const char *oldval,
				  const char *newval = NULL);
errcode_t profile_clear_relation(profile_t p, const char **nullterm);
errcode_t profile_rename_section(profile_t p, const char **nullterm,
				 const char *new_name = NULL);
errcode_t profile_add_relation(profile_t p, const char **nullterm,
			       const char *new_val = NULL);
/* XXX Should be using profile_free_buffer blah.  */
errcode_t profile_flush_to_buffer(profile_t p, char **OUTPUT);

#ifdef SWIGTCL
%include "tclsh.i"
#endif