static int l_proplist (lua_State *L) { const char *path = (lua_gettop (L) < 1 || lua_isnil (L, 1)) ? "" : luaL_checkstring (L, 1); svn_opt_revision_t peg_revision; svn_opt_revision_t revision; if (lua_gettop (L) < 2 || lua_isnil (L, 2)) { revision.kind = svn_opt_revision_unspecified; } else { revision.kind = svn_opt_revision_number; revision.value.number = lua_tointeger (L, 2); } peg_revision.kind = svn_opt_revision_unspecified; apr_pool_t *pool; svn_error_t *err; svn_client_ctx_t *ctx; init_function (&ctx, &pool, L); path = svn_path_canonicalize (path, pool); apr_array_header_t *props; int is_url = svn_path_is_url (path); err = svn_client_proplist2 (&props, path, &peg_revision, &revision, TRUE, ctx, pool); IF_ERROR_RETURN (err, pool, L); lua_newtable (L); int i; for (i = 0; i < props->nelts; ++i) { const void *key; void *val; svn_client_proplist_item_t *item = ((svn_client_proplist_item_t **)props->elts)[i]; const char *name_local; if (is_url) { name_local = svn_path_local_style (item->node_name->data, pool); } else { name_local = item->node_name->data; } lua_pushstring (L, name_local); lua_newtable (L); apr_hash_index_t *hi; for (hi = apr_hash_first (pool, item->prop_hash); hi; hi = apr_hash_next (hi)) { const char *pname; svn_string_t *pval; apr_hash_this (hi, &key, NULL, &val); pname = key; pval = (svn_string_t *) val; err = svn_cmdline_cstring_from_utf8 (&pname, pname, pool); IF_ERROR_RETURN (err, pool, L); lua_pushstring (L, pval->data); lua_setfield (L, -2, pname); } lua_settable (L, -3); } svn_pool_destroy (pool); return 1; }
Py::Object pysvn_client::cmd_proplist( const Py::Tuple &a_args, const Py::Dict &a_kws ) { static argument_description args_desc[] = { { true, name_url_or_path }, { false, name_revision }, { false, name_recurse }, #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) { false, name_peg_revision }, #endif #if defined( PYSVN_HAS_CLIENT_PROPLIST3 ) { false, name_depth }, { false, name_changelists }, #endif { false, NULL } }; FunctionArguments args( "proplist", args_desc, a_args, a_kws ); args.check(); Py::List path_list( toListOfStrings( args.getArg( name_url_or_path ) ) ); SvnPool pool( m_context ); #if defined( PYSVN_HAS_CLIENT_PROPLIST3 ) apr_array_header_t *changelists = NULL; if( args.hasArg( name_changelists ) ) { changelists = arrayOfStringsFromListOfStrings( args.getArg( name_changelists ), pool ); } svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_files, svn_depth_empty ); #else bool recurse = args.getBoolean( name_recurse, false ); #endif bool is_revision_setup = false; bool is_url = false; svn_opt_revision_t revision_url; svn_opt_revision_t revision_file; if( args.hasArg( name_revision ) ) { revision_url = args.getRevision( name_revision ); revision_file = revision_url; } else { revision_url.kind = svn_opt_revision_head; revision_file.kind = svn_opt_revision_working; } #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) svn_opt_revision_t peg_revision_url; svn_opt_revision_t peg_revision_file; if( args.hasArg( name_peg_revision ) ) { peg_revision_url = args.getRevision( name_peg_revision ); peg_revision_file = peg_revision_url; } else { peg_revision_url = revision_url; peg_revision_file = revision_file; } #endif Py::List list_of_proplists; for( Py::List::size_type i=0; i<path_list.length(); i++ ) { Py::String path_str( asUtf8String( path_list[i] ) ); std::string path( path_str.as_std_string() ); std::string norm_path( svnNormalisedIfPath( path, pool ) ); svn_opt_revision_t revision; svn_opt_revision_t peg_revision; if( !is_revision_setup ) if( is_svn_url( path ) ) { revision = revision_url; #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) peg_revision = peg_revision_url; #endif is_url = true; } else { revision = revision_file; #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) peg_revision = peg_revision_file; #endif } else if( is_svn_url( path ) && !is_url ) { throw Py::AttributeError( "cannot mix URL and PATH in name_path" ); } try { const char *norm_path_c_str= norm_path.c_str(); checkThreadPermission(); PythonAllowThreads permission( m_context ); #if defined( PYSVN_HAS_CLIENT_PROPLIST3 ) ProplistReceiveBaton proplist_baton( &permission, pool, list_of_proplists ); svn_error_t *error = svn_client_proplist3 ( norm_path_c_str, &peg_revision, &revision, depth, changelists, proplist_receiver_c, reinterpret_cast<void *>( &proplist_baton ), m_context, pool ); #elif defined( PYSVN_HAS_CLIENT_PROPLIST2 ) apr_array_header_t *props = NULL; svn_error_t *error = svn_client_proplist2 ( &props, norm_path_c_str, &peg_revision, &revision, recurse, m_context, pool ); #else apr_array_header_t *props = NULL; svn_error_t *error = svn_client_proplist ( &props, norm_path_c_str, &revision, recurse, m_context, pool ); #endif permission.allowThisThread(); if( error != NULL ) throw SvnException( error ); #if !defined( PYSVN_HAS_CLIENT_PROPLIST3 ) proplistToObject( list_of_proplists, props, pool ); #endif } catch( SvnException &e ) { // use callback error over ClientException m_context.checkForError( m_module.client_error ); throw_client_error( e ); } } return list_of_proplists; }