nsdefaults.c: a module to operate with the NeXTSTEP Defaults System

Lele Gaifax (lele@nautilus.eclipse.it)
Fri, 21 Apr 95 15:39:54 +0200

Here is a simple module that lets NeXTSTEP users operate on their
defaults within Python.
I did test it a little, and it works for me, but I'm just learning
Python so...

Enjoy,
lele.

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1995-04-21 15:28 MET by <lele@nautilus>.
# Source directory was `/LocalDeveloper/WiP/Python-1.2-NeXT'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 4705 -rw-r--r-- Doc/libnsdefaults.tex
# 9911 -rw-r--r-- Modules/nsdefaults.c
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
echo 'WARNING: not restoring timestamps. Consider getting and'
echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
# ============= Doc/libnsdefaults.tex ==============
if test ! -d 'Doc'; then
echo 'x - creating directory Doc'
mkdir 'Doc'
fi
if test -f 'Doc/libnsdefaults.tex' && test X"$1" != X"-c"; then
echo 'x - skipping Doc/libnsdefaults.tex (file already exists)'
else
echo 'x - extracting Doc/libnsdefaults.tex (text)'
sed 's/^X//' << 'SHAR_EOF' > 'Doc/libnsdefaults.tex' &&
\chapter{NeXTSTEP Specific Services}
X
The modules described in this chapter provide interfaces to features
that are unique to the NeXTSTEP operating system.
X
\section{Built-in Module \sectcode{nsdefaults}}
\bimodindex{nsdefaults}
X
The \code{nsdefaults} module is a wrapper around the {\em NeXTSTEP
Defaults
System}: it defines a set of functions that let you enquire or modify
the NeXTSTEP Defaults Database.
X
\strong{Note:} Until me or someone else won't write a portable
reimplementation of
the core NeXTSTEP functions, this module will be available only on
NeXTSTEP environments.
X
The \code{nsdefaults} module defines the following functions:
X
\renewcommand{\indexsubitem}{(in module nsdefaults)}
X
\begin{funcdesc}{registerDefaults}{owner\, parametersdict}
Store in the Defaults System cache a set of parameters with their
default values, with \var{owner} as the name of the
owner. \var{parametersdict} is a dictionary containing the parameters as
keys, and the corresponding default value as the value.
X
This function does not change the Defaults Database, just the cache is
updated.
\end{funcdesc}
X
\begin{funcdesc}{getDefaultValue}{owner\, parameter}
Get the default value for the parameter \var{parameter}, owned by
\var{owner}. If it is found, either in the cache or in the Defaults
Database, then return it as a string object, otherwise return
\var{None}.
\end{funcdesc}
X
\begin{funcdesc}{readDefault}{owner\, parameter}
This is similar to \code{getDefaultValue}, but it looks only in the
Defaults Database and not in the cache.
\end{funcdesc}
X
\begin{funcdesc}{removeDefault}{owner\, parameter}
Remove the parameter \var{parameter}, owned by \var{owner}. Returns
the boolean value \var{True} on successfull deletion, \var{False}
otherwise.
\end{funcdesc}
X
\begin{funcdesc}{setDefault}{owner\, parameter\, defaultvalue}
Change the cached value for \var{parameter}, owned by \var{owner}, to
\var{defaultvalue}. This doesn't change the Defaults Database.
\end{funcdesc}
X
\begin{funcdesc}{updateDefault}{owner\, parameter}
Update the cached value for \var{parameter}, owned by \var{owner}, by
rereading it from the Defaults Database. This is useful to refresh a
parameter that may be modified by other users since we loaded it in
the cache.
The function returns the previous value of the parameter.
\end{funcdesc}
X
\begin{funcdesc}{updateDefaults}{}
Update all cached parameter values. This is similar, but faster, to
executing \code{updateDefault} for each parameter of each owner in the
cache.
\end{funcdesc}
X
\begin{funcdesc}{writeDefault}{owner\, parameter\, defaultvalue}
Write in the user's Default Database the \var{defaultvalue} for
\var{parameter} owned by \var{owner}. The cache is updated as well.
\end{funcdesc}
X
\begin{funcdesc}{writeDefaults}{owner\, parametersdict}
This is like \code{writeDefault}, but is faster when more than one
parameter need to be written in the database, since this is opened
just once. \var{owner} is the name of the owner of the parameters, and
\var{parametersdict} is a dictionary containing the parameters and
their default values.
The function returns the number of successfully written items.
\end{funcdesc}
X
\begin{funcdesc}{setDefaultsUser}{username}
By default (!) these functions operate on the database belonging to
the user who started the script. Sometime it is useful to work on
someone's else database. \code{setDefaultsUser} accepts the name of a
user whose database you wish to use; it returns the name of the user
whose defaults database was previously set for access by these
functions. All entries in the internal cache are purged; use
\code{getDefaultValue} or \code{registerDefaults} to get the new user's
defaults. When \code{setDefaultsUser} is called,
the user who started the application must have appropriate access
(read, write, or both) to the defaults database of the new user.
\end{funcdesc}
X
Example:
X
\begin{verbatim}
>>> import nsdefaults
>>>
nsdefaults.registerDefaults('PythonTest',{'param_a':1,'param_b':'two'})
1
>>> nsdefaults.getDefaultValue('PythonTest','param_a')
'1'
>>> nsdefaults.setDefaultsUser('root')
>>> nsdefaults.readDefault('Edit', 'Programmer')
>>> nsdefaults.setDefaultsUser('lele')
'root'
>>> nsdefaults.readDefault('Edit', 'Programmer')
'YES'
>>> nsdefaults.setDefault('PythonTest', 'param_b', 'three')
1
>>> nsdefaults.getDefaultValue('PythonTest','param_b')
'three'
>>> print nsdefaults.getDefaultValue.__doc__
Look in the cache for a parameter and return its value if found.
X
Arguments:
X OWNER the name of the owner of the parameter
X PARAM the name of the paramenter
X
Returns:
X A string representing the value of the parameter if it is found, None
X otherwise.
X
\end{verbatim}
X
SHAR_EOF
$shar_touch -am 0421152795 'Doc/libnsdefaults.tex' &&
chmod 0644 'Doc/libnsdefaults.tex' ||
echo 'restore of Doc/libnsdefaults.tex failed'
shar_count="`wc -c < 'Doc/libnsdefaults.tex'`"
test 4705 -eq "$shar_count" ||
echo "Doc/libnsdefaults.tex: original size 4705, current size
$shar_count"
fi
# ============= Modules/nsdefaults.c ==============
if test ! -d 'Modules'; then
echo 'x - creating directory Modules'
mkdir 'Modules'
fi
if test -f 'Modules/nsdefaults.c' && test X"$1" != X"-c"; then
echo 'x - skipping Modules/nsdefaults.c (file already exists)'
else
echo 'x - extracting Modules/nsdefaults.c (text)'
sed 's/^X//' << 'SHAR_EOF' > 'Modules/nsdefaults.c' &&
/* Copyright (c) 1995 by Lele Gaifax. All Rights Reserved
X *
X * $Source$
X * $Revision$
X * $Author$
X * $Date$
X *
X */
X
X
#include "allobjects.h"
#include "modsupport.h" /* For getargs() etc. */
#include <defaults/defaults.h>
X
static PyObject * NsdefaultsError;
X
/* Given a Python dictionary, allocate a NXDefaultVector with the same
X number of elements plus one for the ending null ''sentinel'' and
X initialize it with the content of the dictionary. No check is done
X on VALUES type, so this is a responsibility of the caller.
X Returns the new NXDefaultVector. */
X
static struct _NXDefault *
build_vector_from_dict (PyObject * values)
{
X struct _NXDefault * vector;
X int pos;
X int idx;
X PyObject * key;
X PyObject * value;
X
X vector = PyMem_NEW(struct _NXDefault, PyDict_Size (values) + 1);
X idx = pos = 0;
X while (PyDict_Next (values, &pos, &key, &value))
X {
X PyObject * keyString = PyObject_Str (key);
X PyObject * valueString = PyObject_Str (value);
X char * n = PyString_AsString (keyString);
X char * v = PyString_AsString (valueString);
X
X vector[idx].name = n;
X vector[idx].value = v;
X
X Py_DECREF (keyString);
X Py_DECREF (valueString);
X
X idx++;
X }
X vector[idx].name = vector[idx].value = 0;
X return vector;
}
X
static char register_defaults_doc[] =
"Register default parameters in the cache.
X
Arguments:
X OWNER the name of the owner of these parameters
X PARAMS a dictionary containing the parameters with their
X default values
X
Returns:
X A boolean value, TRUE on succeding operation, FALSE if something goes
X wrong.";
X
static PyObject *
register_defaults (PyObject * self, PyObject * args)
{
X const char * owner;
X PyObject * values;
X
X if (PyArg_ParseTuple (args, "sO;a string and a dictionary",
&owner, &values)
X && is_mappingobject (values))
X {
X struct _NXDefault * vector = build_vector_from_dict (values);
X int status;
X
X if (! (status = NXRegisterDefaults (owner, vector)))
X PyErr_SetString (NsdefaultsError, "could't open the default
database");
X
X DEL(vector);
X
X if (! status)
X {
X Py_INCREF (Py_False);
X return Py_False;
X }
X else
X {
X Py_INCREF (Py_True);
X return Py_True;
X }
X }
X else
X return NULL;
}
X
static char get_default_value_doc[] =
"Look in the cache for a parameter and return its value if found.
X
Arguments:
X OWNER the name of the owner of the parameter
X PARAM the name of the paramenter
X
Returns:
X A string representing the value of the parameter if it is found, None
X otherwise.";
X
static PyObject *
get_default_value (PyObject * self, PyObject * args)
{
X char * owner;
X char * name;
X
X if (PyArg_ParseTuple (args, "ss;two strings", &owner, &name))
X {
X const char * value = NXGetDefaultValue (owner, name);
X
X if (value)
X {
X return Py_BuildValue ("s", value);
X }
X else
X {
X Py_INCREF(None);
X return None;
X }
X }
X else
X return NULL;
}
X
static char read_default_doc[] =
"Look in the Default Database for a parameter and return its value
if found.
X
Arguments:
X OWNER the name of the owner of the parameter
X PARAM the name of the paramenter
X
Returns:
X A string representing the value of the parameter if it is found, None
X otherwise.";
X
static PyObject *
read_default (PyObject * self, PyObject * args)
{
X char * owner;
X char * name;
X
X if (PyArg_ParseTuple (args, "ss;two strings", &owner, &name))
X {
X const char * value = NXReadDefault (owner, name);
X
X if (value)
X {
X return Py_BuildValue ("s", value);
X }
X else
X {
X Py_INCREF(None);
X return None;
X }
X }
X else
X return NULL;
}
X
static char remove_default_doc[] =
"Remove from the Default Database a parameter.
X
Arguments:
X OWNER the name of the owner of the parameter
X PARAM the name of the parameter
X
Returns:
X A boolean value, TRUE on succeding operation, FALSE if something goes
X wrong.";
X
static PyObject *
remove_default (PyObject * self, PyObject * args)
{
X char * owner;
X char * name;
X
X if (PyArg_ParseTuple (args, "ss;two strings", &owner, &name))
X {
X int status = NXRemoveDefault (owner, name);
X
X if (status == 0)
X {
X PyErr_SetString (NsdefaultsError, "couldn't remove the value");
X Py_INCREF (Py_False);
X return Py_False;
X }
X else
X {
X Py_INCREF (Py_True);
X return Py_True;
X }
X }
X else
X return NULL;
}
X
static char set_default_doc[] =
"Store a default parameters with its value in the cache.
X
Arguments:
X OWNER the name of the owner of this parameter
X PARAM the name of the parameter
X VALUE its value
X
Returns:
X A boolean value, TRUE on succeding operation, FALSE if something goes
X wrong.";
X
static PyObject *
set_default (PyObject * self, PyObject * args)
{
X char * owner;
X char * name;
X char * value;
X
X if (PyArg_ParseTuple (args, "sss;three strings", &owner, &name,
&value))
X {
X int status = NXSetDefault (owner, name, value);
X
X if (status == 0)
X {
X PyErr_SetString (NsdefaultsError, "couldn't set the value");
X Py_INCREF (Py_False);
X return Py_False;
X }
X else
X {
X Py_INCREF (Py_True);
X return Py_True;
X }
X }
X else
X return NULL;
}
X
static char update_default_doc[] =
"Update a default parameter in the cache from the Default Database.
X
Arguments:
X OWNER the name of the owner of this parameter
X PARAM the name of the parameter
X
Returns:
X A string representing the previous value of the parameter if found,
X None otherwise.";
X
static PyObject *
update_default (PyObject * self, PyObject * args)
{
X char * owner;
X char * name;
X
X if (PyArg_ParseTuple (args, "ss;two strings", &owner, &name))
X {
X const char * value = NXUpdateDefault (owner, name);
X
X if (value)
X {
X return Py_BuildValue ("s", value);
X }
X else
X {
X Py_INCREF(None);
X return None;
X }
X }
X else
X return NULL;
}
X
static char update_defaults_doc[] =
"Update a the cache re-reading the entire Default Database.
X
Arguments:
X None
X
Returns:
X None";
X
static PyObject *
update_defaults (PyObject * self, PyObject * args)
{
X NXUpdateDefaults ();
X
X Py_INCREF(None);
X return None;
}
X
static char write_default_doc[] =
"Store a default parameters with its value in the Default Database.
X
Arguments:
X OWNER the name of the owner of this parameter
X PARAM the name of the parameter
X VALUE its value
X
Returns:
X A boolean value, TRUE on succeding operation, FALSE if something goes
X wrong.";
X
static PyObject *
write_default (PyObject * self, PyObject * args)
{
X char * owner;
X char * name;
X char * value;
X
X if (PyArg_ParseTuple (args, "sss;three strings", &owner, &name,
&value))
X {
X int status = NXWriteDefault (owner, name, value);
X
X if (status == 0)
X {
X PyErr_SetString (NsdefaultsError, "couldn't write the value");
X Py_INCREF (Py_False);
X return Py_False;
X }
X else
X {
X Py_INCREF (Py_True);
X return Py_True;
X }
X }
X else
X return NULL;
}
X
static char write_defaults_doc[] =
"Write a set of parameters and their values into the Default Database.
X
Arguments:
X OWNER the name of the owner of these parameters
X PARAMS a dictionary containing the parameters with their
X default values
X
Returns:
X An integer value representing the number of succesfully written
parameters";
X
static PyObject *
write_defaults (PyObject * self, PyObject * args)
{
X const char * owner;
X PyObject * values;
X
X if (PyArg_ParseTuple (args, "sO;a string and a dictionary",
&owner, &values) && is_mappingobject (values))
X {
X struct _NXDefault * vector = build_vector_from_dict (values);
X int written = NXWriteDefaults (owner, vector);
X
X DEL(vector);
X
X return Py_BuildValue ("i", written);
X }
X else
X return NULL;
}
X
static char set_defaults_user_doc[] =
"Set the name of the user whose database you want to use by
subsequent calls to these functions.
X
Arguments:
X USER the name of the user
X
Returns:
X A string containing the name of the previous user.";
X
static PyObject *
set_defaults_user (PyObject * self, PyObject * args)
{
X char * user;
X
X if (PyArg_ParseTuple (args, "s;a string", &user))
X {
X const char * value = NXSetDefaultsUser (user);
X
X if (value)
X {
X return Py_BuildValue ("s", value);
X }
X else
X {
X Py_INCREF(None);
X return None;
X }
X }
X else
X return NULL;
}
X
#if 0
X
/* How can this be written? How can I inspect the entire Default
Database?
X There is no public function to do it. */
X
static PyObject *
list_defaults (PyObject * self, PyObject * args)
{
X char * owner;
X
X if (PyArg_ParseTuple (args, "s;a string", &owner))
X {
X }
X Py_INCREF(None);
X return None;
}
X
#endif /* 0 */
X
/* List of functions defined in the module */
X
static PyMethodDef nsdefaults_methods[] = {
X {"registerDefaults", (method) register_defaults, 1,
register_defaults_doc},
X {"getDefaultValue", (method) get_default_value, 1,
get_default_value_doc},
X {"readDefault", (method) read_default, 1,
read_default_doc},
X {"removeDefault", (method) remove_default, 1,
remove_default_doc},
X {"setDefault", (method) set_default, 1,
set_default_doc},
X {"updateDefault", (method) update_default, 1,
update_default_doc},
X {"updateDefaults", (method) update_defaults, 1,
update_defaults_doc},
X {"writeDefault", (method) write_default, 1,
write_default_doc},
X {"writeDefaults", (method) write_defaults, 1,
write_defaults_doc},
X {"setDefaultsUser", (method) set_defaults_user, 1,
set_defaults_user_doc},
X {NULL, NULL} /* sentinel */
};
X
X
X
/* Initialization function for the module (*must* be called
initnsdefaults) */
X
void
initnsdefaults()
{
X PyObject *m, *d;
X
X /* Create the module and add the functions */
X m = Py_InitModule("nsdefaults", nsdefaults_methods);
X
X /* Add some symbolic constants to the module */
X d = PyModule_GetDict(m);
X NsdefaultsError = PyString_FromString ("nsdefaults.error");
X PyDict_SetItemString (d, "error", NsdefaultsError);
X
X /* Check for errors */
X if (PyErr_Occurred())
X Py_FatalError ("can't initialize module nsdefaults");
}
SHAR_EOF
$shar_touch -am 0419123295 'Modules/nsdefaults.c' &&
chmod 0644 'Modules/nsdefaults.c' ||
echo 'restore of Modules/nsdefaults.c failed'
shar_count="`wc -c < 'Modules/nsdefaults.c'`"
test 9911 -eq "$shar_count" ||
echo "Modules/nsdefaults.c: original size 9911, current size
$shar_count"
fi
exit 0