
Contents of /Subversion-0.112/config.c:
/* ================================================================
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgment: "This product includes
* software developed by CollabNet (http://www.Collab.Net/)."
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The hosted project names must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact info@collab.net.
*
* 5. Products derived from this software may not use the "Tigris" name
* nor may "Tigris" appear in their names without prior written
* permission of CollabNet.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of CollabNet.
*/
#include "svnmod.h"
#include <svn_path.h>
#include <svn_config.h>
/*! @module Subversion */
/*! @class Config
*!
*! Opaque structure describing a set of configuration options.
*/
/* Internal object structure */
struct config_obj {
svn_config_t *config;
apr_pool_t *pool;
};
#define THIS ((struct config_obj *)(Pike_fp->current_storage))
static struct program *config_program;
static void init_config_obj (struct object *o)
{
struct config_obj *co = THIS;
co->config = NULL;
co->pool = NULL;
}
static void exit_config_obj (struct object *o)
{
struct config_obj *co = THIS;
co->config = NULL;
if (co->pool) {
apr_pool_destroy (co->pool);
co->pool = NULL;
}
}
/*! @decl void create( string file, int|void must_exist )
*!
*! Read configuration data from @[file] (a file or registry path).
*!
*! @param must_exist
*! If non-zero, throw an error if the file does not exist.
*! Otherwise, an empty @[Config] will be created.
*/
static void f_create (INT32 args)
{
struct config_obj *co = THIS;
struct pike_string *file;
svn_boolean_t must_exist;
svn_error_t *err;
get_all_args ("create", args, "%W", &file);
must_exist = svn_pike_check_force_arg ("create", args, 1);
file = svn_pike_to_utf8 (file);
co->pool = svn_pool_create (NULL);
THREADS_ALLOW ();
err = svn_config_read (&co->config,
svn_path_canonicalize (APR_STR0 (file), co->pool),
must_exist, co->pool);
THREADS_DISALLOW ();
if (err)
svn_pike_set_error (err);
do_free_string (file);
if (err)
pike_throw ();
else
pop_n_elems (args);
}
/* Stub for the enumerator callback */
static svn_boolean_t enumerator_callback_stub(const char *name,
const char *value, void *baton)
{
JMP_BUF recovery;
svn_boolean_t ret;
do {
struct thread_state *_tmp=thread_state_for_id (th_self ());
HIDE_GLOBAL_VARIABLES ();
THREADS_DISALLOW ();
if (SETJMP (recovery)) {
call_handle_error ();
ret = FALSE;
} else {
svn_pike_push_utf8 (name);
svn_pike_push_utf8 (value);
apply_svalue ((struct svalue *)baton, 2);
ret = !UNSAFE_IS_ZERO(Pike_sp-1);
pop_stack ();
}
UNSETJMP (recovery);
THREADS_ALLOW ();
} while (0);
return ret;
}
/*! @decl int enumerate( string section, @
*! function(string,string:int(0..1)) callback )
*!
*! Enumerate the options in @[section], passing the current option's
*! name and value to @[callback]. Continue the enumeration if
*! @[callback] returns 1. Return the number of times @[callback]
*! was called.
*/
static void f_enumerate (INT32 args)
{
struct config_obj *co = THIS;
struct pike_string *section;
struct svalue *callback;
int n;
get_all_args ("enumerate", args, "%W%*", §ion, &callback);
section = svn_pike_to_utf8 (section);
THREADS_ALLOW ();
n = svn_config_enumerate (co->config, APR_STR0 (section),
enumerator_callback_stub, callback);
THREADS_DISALLOW ();
do_free_string (section);
pop_n_elems (args);
push_int (n);
}
apr_hash_t *svn_pike_mapping_to_config_hash (struct mapping *m,
apr_pool_t *pool)
{
apr_hash_t *ret = apr_hash_make (pool);
INT32 e;
struct keypair *k;
if (m == NULL || !m_sizeof(m))
return ret;
MAPPING_LOOP (m) {
struct config_obj *co;
struct pike_string *key;
if (k->ind.type != PIKE_T_STRING || k->val.type != PIKE_T_OBJECT)
Pike_error ("Expected mapping from string to object.\n");
if (!(co = (struct config_obj *)get_storage (k->val.u.object,
config_program)))
Pike_error ("Expected object to be a Subversion.Config.\n");
key = svn_pike_to_utf8 (k->ind.u.string);
apr_hash_set (ret, apr_pstrdup (pool, APR_STR0 (key)), APR_HASH_KEY_STRING,
co->config);
do_free_string (key);
}
return ret;
}
/* Initialize Config class */
void svn_pike_init_config (void)
{
start_new_program ();
ADD_STORAGE (struct config_obj);
set_init_callback(init_config_obj);
set_exit_callback(exit_config_obj);
ADD_FUNCTION ("create", f_create, tFunc (tStr tOr (tInt, tVoid), tVoid),
ID_STATIC);
ADD_FUNCTION ("enumerate", f_enumerate,
tFunc (tStr tFunc (tStr tStr, tInt01), tInt), 0);
config_program = end_program ();
add_program_constant ("Config", config_program, 0);
}
/*! @endclass */
/*! @endmodule */