X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=extras%2Fanalyser%2Fzsh.cpp;h=6ced8fef8f3c80a89db6ed76846bb6a8152106a8;hb=fe69b6768d6a1ae820a038ea05bff9eb4d35452f;hp=4f432fac5a14b7ec66f4c4e15ac1d39aa3001d2d;hpb=d550023d98891a13a6fd1f19c949a6c78868b7a8;p=vlc diff --git a/extras/analyser/zsh.cpp b/extras/analyser/zsh.cpp index 4f432fac5a..6ced8fef8f 100644 --- a/extras/analyser/zsh.cpp +++ b/extras/analyser/zsh.cpp @@ -1,10 +1,10 @@ /***************************************************************************** * zsh.cpp: create zsh completion rule for vlc ***************************************************************************** - * Copyright © 2005-2008 the VideoLAN team - * $Id$ + * Copyright © 2005-2011 the VideoLAN team * * Authors: Sigmund Augdal Helberg + Rafaël Carré * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,438 +21,256 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include -#include -#include -#include -typedef std::multimap mumap; -typedef std::multimap mcmap; - -typedef std::pair mpair; -typedef std::pair mcpair; - #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include +#include +#include +#include +#include + #include +#include +#include +#include +#include "../src/modules/modules.h" /* evil hack */ -/* evil hack */ -#undef __PLUGIN__ -#undef __BUILTIN__ -#include <../src/modules/modules.h> +typedef std::pair mpair; +typedef std::multimap mumap; +mumap capabilities; -void ParseModules( mumap &mods, mcmap &mods2 ); -void PrintModuleList( mumap &mods, mcmap &mods2 ); -void ParseOption( module_config_t *p_item, mumap &mods, mcmap &mods2 ); -void PrintOption( char *psz_option, char i_short, char *psz_exlusive, - char *psz_text, char *psz_longtext, char *psz_args ); +typedef std::pair mcpair; +typedef std::multimap mcmap; +mcmap categories; -int main( int i_argc, const char **ppsz_argv ) +static void ReplaceChars(char *str) { - mumap mods; - mcmap mods2; - /* Create a libvlc structure */ + if (str) { + char *parser; + while ((parser = strchr(str, ':'))) *parser=';' ; + while ((parser = strchr(str, '"'))) *parser='\'' ; + while ((parser = strchr(str, '`'))) *parser='\'' ; + } +} - libvlc_exception_t ex; - libvlc_exception_init(&ex); +static void PrintOption(const module_config_t *item, const std::string &opt, + const std::string &excl, const std::string &args) +{ + char *longtext = item->psz_longtext; + char *text = item->psz_text; + char i_short = item->i_short; + ReplaceChars(longtext); + ReplaceChars(text); - const char * const argv[] = { "vlc" }; - libvlc_instance_t *p_libvlc_instance = libvlc_new(1, argv, &ex); + if (!longtext || strchr(longtext, '\n') || strchr(longtext, '(')) + longtext = text; - if( !p_libvlc_instance || libvlc_exception_raised(&ex) ) - { - libvlc_exception_clear(&ex); - return 1; - } + printf(" \""); - printf("#compdef vlc\n\n" - - "#This file is autogenerated by zsh.cpp\n" - "typeset -A opt_args\n" - "local context state line ret=1\n" - "local modules\n\n" ); - - PrintModuleList( mods, mods2 ); - - printf( "_arguments -S -s \\\n" ); - ParseModules( mods, mods2 ); - printf( " \"(--module)-p[print help on module]:print help on module:($modules)\"\\\n" ); - printf( " \"(-p)--module[print help on module]:print help on module:($modules)\"\\\n" ); - printf( " \"(--help)-h[print help]\"\\\n" ); - printf( " \"(-h)--help[print help]\"\\\n" ); - printf( " \"(--longhelp)-H[print detailed help]\"\\\n" ); - printf( " \"(-H)--longhelp[print detailed help]\"\\\n" ); - printf( " \"(--list)-l[print a list of available modules]\"\\\n" ); - printf( " \"(-l)--list[print a list of available modules]\"\\\n" ); - printf( " \"--save-config[save the current command line options in the config file]\"\\\n" ); - printf( " \"--reset-config[reset the current config to the default values]\"\\\n" ); - printf( " \"--config[use alternate config file]\"\\\n" ); - printf( " \"--reset-plugins-cache[resets the current plugins cache]\"\\\n" ); - printf( " \"--version[print version information]\"\\\n" ); - printf( " \"*:Playlist item:->mrl\" && ret=0\n\n" ); - - printf( "case $state in\n" ); - printf( " mrl)\n" ); - printf( " _alternative 'files:file:_files' 'urls:URL:_urls' && ret=0\n" ); - printf( " ;;\n" ); - printf( "esac\n\n" ); - - printf( "return ret\n" ); - - libvlc_release( p_libvlc_instance ); + const char *args_c = args.empty() ? "" : "="; + if (i_short) { + printf("(-%c", i_short); - return 0; -} + if (!excl.empty()) + printf("%s", excl.c_str()); -void ParseModules( mumap &mods, mcmap &mods2 ) -{ - module_t **p_list; - module_t *p_module; - module_config_t *p_item; - int i_index; - int i_items; - size_t i_modules; - - /* List the plugins */ - p_list = module_list_get(&i_modules); - if( !p_list ) return; - for( i_index = 0; i_index < i_modules; i_index++ ) - { - p_module = p_list[i_index]; + printf(")--%s%s[%s]", opt.c_str(), args_c, text); - /* Exclude empty plugins (submodules don't have config options, they - * are stored in the parent module) */ - if( p_module->b_submodule ) - continue; -// p_item = ((module_t *)p_module->p_parent)->p_config; - else - p_item = p_module->p_config; - -// printf( " #%s\n", p_module->psz_longname ); - if( !p_item ) continue; - i_items = 0; - do - { - if( p_item->i_type == CONFIG_CATEGORY ) - { -// printf( " #Category %d\n", p_item->i_value ); - } - else if( p_item->i_type == CONFIG_SUBCATEGORY ) - { -// printf( " #Subcategory %d\n", p_item->i_value ); - } - if( p_item->i_type & CONFIG_ITEM ) - ParseOption( p_item, mods, mods2 ); - } - while( i_items++ < p_module->i_config_items && p_item++ ); + if (!args.empty()) + printf(":%s:%s", longtext, args.c_str()); + printf("\"\\\n \"(--%s%s)-%c", opt.c_str(), excl.c_str(), i_short); + } else { + if (!excl.empty()) + printf("(%s)", excl.c_str()); + printf("--%s", opt.c_str()); + if (!excl.empty()) + printf("%s", args_c); } -} - -void PrintModuleList( mumap &mods, mcmap &mods2 ) -{ - module_t **p_list = NULL; - module_t *p_module; - int i_index; - int i_items; - size_t i_modules; - - /* List the plugins */ - p_list = module_list_get(&i_modules); - if( !p_list ) return; - - printf( "modules=\"" ); - for( i_index = 0; i_index < i_modules; i_index++ ) - { - p_module = p_list[i_index]; - - /* Exclude empty plugins (submodules don't have config options, they - * are stored in the parent module) */ - - if( strcmp( p_module->psz_object_name, "main" ) ) - { - mods.insert( mpair( p_module->psz_capability, - p_module->psz_object_name ) ); - module_config_t *p_config = p_module->p_config; - i_items = 0; - if( p_config ) do - { - /* Hack: required subcategory is stored in i_min */ - if( p_config->i_type == CONFIG_SUBCATEGORY ) - { - mods2.insert( mcpair( p_config->value.i, - p_module->psz_object_name ) ); - } - } while( i_items++ < p_module->i_config_items && p_config++ ); - if( p_module->b_submodule ) - continue; - printf( "%s ", p_module->psz_object_name ); - } - } - printf( "\"\n\n" ); - return; + printf("[%s]", text); + if (!args.empty()) + printf( ":%s:%s", longtext, args.c_str()); + puts( "\"\\"); } -void ParseOption( module_config_t *p_item, mumap &mods, mcmap &mods2 ) +static void ParseOption(const module_config_t *item) { - char *psz_arguments = NULL; - char *psz_exclusive; - char *psz_option; - char *psz_name; - char *psz_text; - char *psz_longtext; - -#define DUP( x ) strdup( x ? x : "" ) + std::string excl, args; + std::string list; + std::pair range; + std::pair range_mod; - //Skip deprecated options - if( p_item->b_removed ) + if (item->b_removed) return; - switch( p_item->i_type ) + switch(item->i_type) { case CONFIG_ITEM_MODULE: - { - std::pair range = mods.equal_range( p_item->psz_type ); - std::string list = (*range.first).second; - ++range.first; - while( range.first != range.second ) - { - list = list.append( " " ); - list = list.append( range.first->second ); - ++range.first; - } - asprintf( &psz_arguments, "(%s)", list.c_str() ); - } + range_mod = capabilities.equal_range(item->psz_type); + args = "(" + (*range_mod.first).second; + while (range_mod.first++ != range_mod.second) + args += " " + range_mod.first->second; + args += ")"; break; + case CONFIG_ITEM_MODULE_CAT: - { - std::pair range = - mods2.equal_range( p_item->min.i ); - std::string list = (*range.first).second; - ++range.first; - while( range.first != range.second ) - { - list = list.append( " " ); - list = list.append( range.first->second ); - ++range.first; - } - asprintf( &psz_arguments, "(%s)", list.c_str() ); - } + range = categories.equal_range(item->min.i); + args = "(" + (*range.first).second; + while (range.first++ != range.second) + args += " " + range.first->second; + args += ")"; break; + case CONFIG_ITEM_MODULE_LIST_CAT: - { - std::pair range = - mods2.equal_range( p_item->min.i ); - std::string list = "_values -s , "; - list = list.append( p_item->psz_name ); - while( range.first != range.second ) - { - list = list.append( " '*" ); - list = list.append( range.first->second ); - list = list.append( "'" ); - ++range.first; - } - asprintf( &psz_arguments, "%s", list.c_str() ); - } + range = categories.equal_range(item->min.i); + args = std::string("_values -s , ") + item->psz_name; + while (range.first != range.second) + args += " '*" + range.first++->second + "'"; break; - case CONFIG_ITEM_STRING: - if( p_item->i_list ) - { - int i = p_item->i_list -1; - char *psz_list; - if( p_item->ppsz_list_text ) - asprintf( &psz_list, "%s\\:%s", p_item->ppsz_list[i], - p_item->ppsz_list_text[i] ); - else - psz_list = strdup(p_item->ppsz_list[i]); - char *psz_list2; - while( i>1 ) - { - if( p_item->ppsz_list_text ) - asprintf( &psz_list2, "%s\\:%s %s", p_item->ppsz_list[i-1], - p_item->ppsz_list_text[i-1], psz_list ); - else - asprintf( &psz_list2, "%s %s", p_item->ppsz_list[i-1], - psz_list ); - - free( psz_list ); - psz_list = psz_list2; - i--; - } - if( p_item->ppsz_list_text ) - asprintf( &psz_arguments, "((%s))", psz_list ); - else - asprintf( &psz_arguments, "(%s)", psz_list ); - - free( psz_list ); - } - break; - - case CONFIG_ITEM_FILE: - psz_arguments = strdup( "_files" ); + case CONFIG_ITEM_LOADFILE: + case CONFIG_ITEM_SAVEFILE: + args = "_files"; break; case CONFIG_ITEM_DIRECTORY: - psz_arguments = strdup( "_files -/" ); + args = "_files -/"; break; + case CONFIG_ITEM_STRING: case CONFIG_ITEM_INTEGER: - if( p_item->i_list ) - { - int i = p_item->i_list -1; - char *psz_list; - if( p_item->ppsz_list_text ) - asprintf( &psz_list, "%d\\:%s", p_item->pi_list[i], - p_item->ppsz_list_text[i] ); - else - psz_list = strdup(p_item->ppsz_list[i]); - char *psz_list2; - while( i>1 ) - { - if( p_item->ppsz_list_text ) - asprintf( &psz_list2, "%d\\:%s %s", p_item->pi_list[i-1], - p_item->ppsz_list_text[i-1], psz_list ); - else - asprintf( &psz_list2, "%s %s", p_item->ppsz_list[i-1], - psz_list ); - - free( psz_list ); - psz_list = psz_list2; - i--; - } - if( p_item->ppsz_list_text ) - asprintf( &psz_arguments, "((%s))", psz_list ); - else - asprintf( &psz_arguments, "(%s)", psz_list ); - - free( psz_list ); - } - else if( p_item->min.i != 0 || p_item->max.i != 0 ) - { -// p_control = new RangedIntConfigControl( p_this, p_item, parent ); - } - else - { -// p_control = new IntegerConfigControl( p_this, p_item, parent ); + if (item->list_count == 0) + break; + + for (int i = 0; i < item->list_count; i++) { + std::string val; + if (item->list_text) { + const char *text = item->list_text[i]; + if (item->i_type == CONFIG_ITEM_INTEGER) { + std::stringstream s; + s << item->list.i[i]; + val = s.str() + "\\:\\\"" + text; + } else { + if (!item->list.psz[i] || !text) + continue; + val = item->list.psz[i] + std::string("\\:\\\"") + text; + } + } else + val = std::string("\\\"") + item->list.psz[i]; + + list = val + "\\\" " + list; } - break; - case CONFIG_ITEM_KEY: -// p_control = new KeyConfigControl( p_this, p_item, parent ); - break; + if (item->list_text) + args = std::string("((") + list + "))"; + else + args = std::string("(") + list + ")"; - case CONFIG_ITEM_FLOAT: -// p_control = new FloatConfigControl( p_this, p_item, parent ); break; case CONFIG_ITEM_BOOL: -// p_control = new BoolConfigControl( p_this, p_item, parent ); - asprintf( &psz_exclusive, "--no%s --no-%s", p_item->psz_name, - p_item->psz_name ); - psz_name = DUP( p_item->psz_name ); - psz_text = DUP( p_item->psz_text ); - psz_longtext = DUP( p_item->psz_longtext ); - PrintOption( psz_name, p_item->i_short, psz_exclusive, - psz_text, psz_longtext, psz_arguments ); - free( psz_name ); - free( psz_text ); - free( psz_longtext ); - free( psz_exclusive ); - asprintf( &psz_exclusive, "--no%s --%s", p_item->psz_name, - p_item->psz_name ); - asprintf( &psz_option, "no-%s", p_item->psz_name ); - psz_text = DUP( p_item->psz_text ); - psz_longtext = DUP( p_item->psz_longtext ); - PrintOption( psz_option, p_item->i_short, psz_exclusive, - psz_text, psz_longtext, psz_arguments ); - free( psz_text ); - free( psz_longtext ); - free( psz_exclusive ); - free( psz_option ); - asprintf( &psz_exclusive, "--no-%s --%s", p_item->psz_name, - p_item->psz_name ); - asprintf( &psz_option, "no%s", p_item->psz_name ); - psz_text = DUP( p_item->psz_text ); - psz_longtext = DUP( p_item->psz_longtext ); - PrintOption( psz_option, p_item->i_short, psz_exclusive, - psz_text, psz_longtext, psz_arguments ); - free( psz_text ); - free( psz_longtext ); - free( psz_exclusive ); - free( psz_option ); + excl = std::string("--no") + item->psz_name + " --no-" + item->psz_name; + PrintOption(item, item->psz_name, excl, args); + + excl = std::string("--no") + item->psz_name + " --" + item->psz_name; + PrintOption(item, std::string("no-") + item->psz_name, excl, args); + + excl = std::string("--no-")+ item->psz_name + " --" + item->psz_name; + PrintOption(item, std::string("no") + item->psz_name, excl, args); return; + case CONFIG_ITEM_KEY: case CONFIG_SECTION: -// p_control = new SectionConfigControl( p_this, p_item, parent ); - break; - + case CONFIG_ITEM_FLOAT: default: break; } - psz_name = DUP( p_item->psz_name ); - psz_text = DUP( p_item->psz_text ); - psz_longtext = DUP( p_item->psz_longtext ); - PrintOption( psz_name, p_item->i_short, NULL, - psz_text, psz_longtext, psz_arguments ); - free( psz_name ); - free( psz_text ); - free( psz_longtext ); - free( psz_arguments ); + + PrintOption(item, item->psz_name, "", args); } -void PrintOption( char *psz_option, char i_short, char *psz_exclusive, - char *psz_text, char *psz_longtext, char *psz_args ) +static void PrintModule(const module_t *mod) { - char *foo; - if( psz_text ) - { - while( (foo = strchr( psz_text, ':' ))) *foo=';'; - while( (foo = strchr( psz_text, '"' ))) *foo='\''; - } - if( psz_longtext ) - { - while( (foo = strchr( psz_longtext, ':' ))) *foo=';'; - while( (foo = strchr( psz_longtext, '"' ))) *foo='\''; - } - if( !psz_longtext || - strchr( psz_longtext, '\n' ) || - strchr( psz_longtext, '(' ) ) psz_longtext = psz_text; - if( i_short ) - { - if( !psz_exclusive ) psz_exclusive = strdup( "" ); - else asprintf( &psz_exclusive, " %s", psz_exclusive ); - printf( " \"(-%c%s)--%s%s[%s]", i_short, psz_exclusive, - psz_option, psz_args?"=":"", psz_text ); - if( psz_args ) - printf( ":%s:%s\"\\\n", psz_longtext, psz_args ); - else - printf( "\"\\\n" ); - printf( " \"(--%s%s)-%c[%s]", psz_option, psz_exclusive, - i_short, psz_text ); - if( psz_args ) - printf( ":%s:%s\"\\\n", psz_longtext, psz_args ); - else - printf( "\"\\\n" ); + const char *name = mod->pp_shortcuts[0]; + if (!strcmp(name, "main")) + return; - } - else - { - if( psz_exclusive ) - printf( " \"(%s)--%s%s[%s]", psz_exclusive, psz_option, - psz_args?"=":"", psz_text ); - else - printf( " \"--%s[%s]", psz_option, psz_text ); + if (mod->psz_capability) + capabilities.insert(mpair(mod->psz_capability, name)); - if( psz_args ) - printf( ":%s:%s\"\\\n", psz_longtext, psz_args ); - else - printf( "\"\\\n" ); + module_config_t *max = &mod->p_config[mod->i_config_items]; + for (module_config_t *cfg = mod->p_config; cfg && cfg < max; cfg++) + if (cfg->i_type == CONFIG_SUBCATEGORY) + categories.insert(mcpair(cfg->value.i, name)); - } + if (!mod->parent) + printf("%s ", name); +} + +static void ParseModule(const module_t *mod) +{ + if (mod->parent) + return; + + module_config_t *max = mod->p_config + mod->confsize; + for (module_config_t *cfg = mod->p_config; cfg && cfg < max; cfg++) + if (CONFIG_ITEM(cfg->i_type)) + ParseOption(cfg); } +int main(int argc, const char **argv) +{ + libvlc_instance_t *libvlc = libvlc_new(argc, argv); + if (!libvlc) + return 1; + + size_t modules = 0; + module_t **mod_list; + + mod_list = module_list_get(&modules); + if (!mod_list || modules == 0) + return 2; + + module_t **max = &mod_list[modules]; + + puts("#compdef vlc cvlc rvlc svlc mvlc qvlc nvlc\n" + "#This file is autogenerated by zsh.cpp" + "typeset -A opt_args" + "local context state line ret=1" + "local modules\n"); + + printf("vlc_modules=\""); + for (module_t **mod = mod_list; mod < max; mod++) + PrintModule(*mod); + puts("\"\n"); + + puts("_arguments -S -s \\"); + for (module_t **mod = mod_list; mod < max; mod++) + ParseModule(*mod); + puts(" \"(--module)-p[print help on module]:print help on module:($vlc_modules)\"\\"); + puts(" \"(-p)--module[print help on module]:print help on module:($vlc_modules)\"\\"); + puts(" \"(--help)-h[print help]\"\\"); + puts(" \"(-h)--help[print help]\"\\"); + puts(" \"(--longhelp)-H[print detailed help]\"\\"); + puts(" \"(-H)--longhelp[print detailed help]\"\\"); + puts(" \"(--list)-l[print a list of available modules]\"\\"); + puts(" \"(-l)--list[print a list of available modules]\"\\"); + puts(" \"--reset-config[reset the current config to the default values]\"\\"); + puts(" \"--config[use alternate config file]\"\\"); + puts(" \"--reset-plugins-cache[resets the current plugins cache]\"\\"); + puts(" \"--version[print version information]\"\\"); + puts(" \"*:Playlist item:->mrl\" && ret=0\n"); + + puts("case $state in"); + puts(" mrl)"); + puts(" _alternative 'files:file:_files' 'urls:URL:_urls' && ret=0"); + puts(" ;;"); + puts("esac\n"); + + puts("return ret"); + + module_list_free(mod_list); + libvlc_release(libvlc); + return 0; +}