* profile.swg: New file.
authorKen Raeburn <raeburn@mit.edu>
Fri, 27 Aug 2004 20:22:37 +0000 (20:22 +0000)
committerKen Raeburn <raeburn@mit.edu>
Fri, 27 Aug 2004 20:22:37 +0000 (20:22 +0000)
* configure.in: Look for Tcl.
* Makefile.in (profile_tcl, profile_tcl.c, profile_tcl.o): New targets, not
built by default.
(PROG_LIBPATH, PROG_RPATH, LOCALINCLUDES): Add Tcl options.
(DEFINES): Define.
(clean-unix): Delete profile_tcl.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16691 dc483132-0cff-0310-8789-dd5450dbe970

src/util/profile/ChangeLog
src/util/profile/Makefile.in
src/util/profile/configure.in
src/util/profile/profile.swg [new file with mode: 0644]

index 6a8bfa4247958a95d6fbfd1cc904bf9cddd6db1a..ed8095b1b5aba3c17ffcf0053f95c263248e8be8 100644 (file)
@@ -1,5 +1,13 @@
 2004-08-27  Ken Raeburn  <raeburn@mit.edu>
 
+       * profile.swg: New file.
+       * configure.in: Look for Tcl.
+       * Makefile.in (profile_tcl, profile_tcl.c, profile_tcl.o): New
+       targets, not built by default.
+       (PROG_LIBPATH, PROG_RPATH, LOCALINCLUDES): Add Tcl options.
+       (DEFINES): Define.
+       (clean-unix): Delete profile_tcl.
+
        * prof_int.h (struct _prf_data_t): Add a mutex.
        * prof_file.c (profile_open_file): Initialize data mutex.
        (profile_update_file_data, profile_flush_file_data): Lock it while
index 6f82a7f0b0a62777d3b00e657bd47b9b706b2677..6735909b719af2ed98d54cce0f669d529e188d09 100644 (file)
@@ -2,13 +2,15 @@ thisconfigdir=.
 myfulldir=util/profile
 mydir=.
 BUILDTOP=$(REL)..$(S)..
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
+PROG_LIBPATH=-L$(TOPLIBD) $(TCL_LIBPATH)
+PROG_RPATH=$(KRB5_LIBDIR)$(TCL_RPATH)
 ##DOS##BUILDTOP = ..\..
 ##DOS##OBJFILE=$(OUTPRE)profile.lst
 ##DOS##LIBNAME=$(OUTPRE)profile.lib
 
-LOCALINCLUDES=-I.
+LOCALINCLUDES=-I. $(TCL_INCLUDES)
+# for tcl.h
+DEFINES=-DHAS_STDARG
 
 STLIBOBJS = \
        prof_tree.o \
@@ -109,9 +111,18 @@ prof_err.c: $(srcdir)/prof_err.et
 
 prof_err.o: prof_err.c
 
+# not built by default, but may be useful for testing
+profile_tcl.c: profile.swg
+       (cd $(srcdir) && swig -tcl8 -o profile_tcl.c profile.swg)
+profile_tcl.o: $(srcdir)/profile_tcl.c
+profile_tcl: profile_tcl.o libprofile.a
+       $(CC_LINK) -o profile_tcl profile_tcl.o \
+               $(TCL_MAYBE_RPATH) \
+               -L../et -L../.. libprofile.a $(DEPLIBS) $(TCL_LIBS)
+
 clean-unix:: clean-libs clean-libobjs
        $(RM) $(PROGS) *.o *~ test_parse core prof_err.h \
-               prof_err.c test_profile profile.h
+               prof_err.c test_profile profile.h profile_tcl
 
 clean-windows::
        $(RM) $(PROFILE_HDR)
index f8576ea55efb5044126a13b5cd61c463951689f5..da9d921e867107d99ceba37034e1be72472561cc 100644 (file)
@@ -7,6 +7,7 @@ AC_CHECK_SIZEOF(long)
 AC_CHECK_HEADERS(unistd.h stdlib.h pwd.h)
 AC_CHECK_FUNCS(stat access strdup getpwuid_r)
 AC_PROG_AWK
+AC_KRB5_TCL
 KRB5_BUILD_LIBOBJS
 KRB5_BUILD_PROGRAM
 KRB5_BUILD_LIBRARY_WITH_DEPS
diff --git a/src/util/profile/profile.swg b/src/util/profile/profile.swg
new file mode 100644 (file)
index 0000000..5de7093
--- /dev/null
@@ -0,0 +1,242 @@
+%{
+/*
+ * 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"
+
+/* 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
+%}
+
+%include "typemaps.i"
+
+%typemap(tcl8,in,numinputs=0) SWIGTYPE *OUTPUT ($1_basetype tmp) {
+    $1 = &tmp;
+}
+%typemap(tcl8,argout) SWIGTYPE *OUTPUT
+  "/*foo*/Tcl_SetObjResult(interp,SWIG_NewInstanceObj((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, 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, error_message($1), TCL_STATIC);
+       SWIG_fail;
+    }
+}
+
+/* "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);
+/* 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);
+
+%include "tclsh.i"