slv2-0.6.6+dfsg1/0000755000175000017500000000000011703116025013265 5ustar alessioalessioslv2-0.6.6+dfsg1/autowaf.py0000644000175000017500000003143311231361306015311 0ustar alessioalessio#!/usr/bin/env python # Waf utilities for easily building standard unixey packages/libraries # Licensed under the GNU GPL v2 or later, see COPYING file for details. # Copyright (C) 2008 Dave Robillard # Copyright (C) 2008 Nedko Arnaudov import os import misc import Configure import Options import Utils import sys from TaskGen import feature, before, after global g_is_child g_is_child = False # Only run autowaf hooks once (even if sub projects call several times) global g_step g_step = 0 # Compute dependencies globally #import preproc #preproc.go_absolute = True @feature('cc', 'cxx') @after('apply_lib_vars') @before('apply_obj_vars_cc', 'apply_obj_vars_cxx') def include_config_h(self): self.env.append_value('INC_PATHS', self.bld.srcnode) def set_options(opt): "Add standard autowaf options if they havn't been added yet" global g_step if g_step > 0: return opt.tool_options('compiler_cc') opt.tool_options('compiler_cxx') opt.add_option('--debug', action='store_true', default=False, dest='debug', help="Build debuggable binaries [Default: False]") opt.add_option('--strict', action='store_true', default=False, dest='strict', help="Use strict compiler flags and show all warnings [Default: False]") opt.add_option('--build-docs', action='store_true', default=False, dest='build_docs', help="Build documentation - requires doxygen [Default: False]") opt.add_option('--bundle', action='store_true', default=False, help="Build a self-contained bundle [Default: False]") opt.add_option('--bindir', type='string', help="Executable programs [Default: PREFIX/bin]") opt.add_option('--libdir', type='string', help="Libraries [Default: PREFIX/lib]") opt.add_option('--includedir', type='string', help="Header files [Default: PREFIX/include]") opt.add_option('--datadir', type='string', help="Shared data [Default: PREFIX/share]") opt.add_option('--configdir', type='string', help="Configuration data [Default: PREFIX/etc]") opt.add_option('--mandir', type='string', help="Manual pages [Default: DATADIR/man]") opt.add_option('--htmldir', type='string', help="HTML documentation [Default: DATADIR/doc/PACKAGE]") opt.add_option('--lv2-user', action='store_true', default=False, dest='lv2_user', help="Install LV2 bundles to user-local location [Default: False]") if sys.platform == "darwin": opt.add_option('--lv2dir', type='string', help="LV2 bundles [Default: /Library/Audio/Plug-Ins/LV2]") else: opt.add_option('--lv2dir', type='string', help="LV2 bundles [Default: LIBDIR/lv2]") g_step = 1 def check_header(conf, name, define='', mandatory=False): "Check for a header iff it hasn't been checked for yet" if type(conf.env['AUTOWAF_HEADERS']) != dict: conf.env['AUTOWAF_HEADERS'] = {} checked = conf.env['AUTOWAF_HEADERS'] if not name in checked: checked[name] = True if define != '': conf.check(header_name=name, define_name=define, mandatory=mandatory) else: conf.check(header_name=name, mandatory=mandatory) def check_tool(conf, name): "Check for a tool iff it hasn't been checked for yet" if type(conf.env['AUTOWAF_TOOLS']) != dict: conf.env['AUTOWAF_TOOLS'] = {} checked = conf.env['AUTOWAF_TOOLS'] if not name in checked: conf.check_tool(name) checked[name] = True def nameify(name): return name.replace('/', '_').replace('++', 'PP').replace('-', '_') def check_pkg(conf, name, **args): if not 'mandatory' in args: args['mandatory'] = True "Check for a package iff it hasn't been checked for yet" var_name = 'HAVE_' + nameify(args['uselib_store']) check = not var_name in conf.env if not check and 'atleast_version' in args: # Re-check if version is newer than previous check checked_version = conf.env['VERSION_' + name] if checked_version and checked_version < args['atleast_version']: check = True; if check: conf.check_cfg(package=name, args="--cflags --libs", **args) found = bool(conf.env[var_name]) if found: conf.define(var_name, int(found)) if 'atleast_version' in args: conf.env['VERSION_' + name] = args['atleast_version'] else: conf.undefine(var_name) if args['mandatory'] == True: conf.fatal("Required package " + name + " not found") def chop_prefix(conf, var): name = conf.env[var][len(conf.env['PREFIX']):] if len(name) > 0 and name[0] == '/': name = name[1:] if name == "": name = "/" return name; def configure(conf): global g_step if g_step > 1: return def append_cxx_flags(vals): conf.env.append_value('CCFLAGS', vals.split()) conf.env.append_value('CXXFLAGS', vals.split()) conf.line_just = 43 check_tool(conf, 'misc') check_tool(conf, 'compiler_cc') check_tool(conf, 'compiler_cxx') conf.env['BUILD_DOCS'] = Options.options.build_docs conf.env['DEBUG'] = Options.options.debug conf.env['STRICT'] = Options.options.strict conf.env['PREFIX'] = os.path.abspath(os.path.expanduser(os.path.normpath(conf.env['PREFIX']))) if Options.options.bundle: conf.env['BUNDLE'] = True conf.define('BUNDLE', 1) conf.env['BINDIR'] = conf.env['PREFIX'] conf.env['INCLUDEDIR'] = os.path.join(conf.env['PREFIX'], 'Headers') conf.env['LIBDIR'] = os.path.join(conf.env['PREFIX'], 'Libraries') conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'Resources') conf.env['HTMLDIR'] = os.path.join(conf.env['PREFIX'], 'Resources/Documentation') conf.env['MANDIR'] = os.path.join(conf.env['PREFIX'], 'Resources/Man') conf.env['LV2DIR'] = os.path.join(conf.env['PREFIX'], 'PlugIns') else: conf.env['BUNDLE'] = False if Options.options.bindir: conf.env['BINDIR'] = Options.options.bindir else: conf.env['BINDIR'] = os.path.join(conf.env['PREFIX'], 'bin') if Options.options.includedir: conf.env['INCLUDEDIR'] = Options.options.includedir else: conf.env['INCLUDEDIR'] = os.path.join(conf.env['PREFIX'], 'include') if Options.options.libdir: conf.env['LIBDIR'] = Options.options.libdir else: conf.env['LIBDIR'] = os.path.join(conf.env['PREFIX'], 'lib') if Options.options.datadir: conf.env['DATADIR'] = Options.options.datadir else: conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'share') if Options.options.configdir: conf.env['CONFIGDIR'] = Options.options.configdir else: conf.env['CONFIGDIR'] = os.path.join(conf.env['PREFIX'], 'etc') if Options.options.htmldir: conf.env['HTMLDIR'] = Options.options.htmldir else: conf.env['HTMLDIR'] = os.path.join(conf.env['DATADIR'], 'doc', Utils.g_module.APPNAME) if Options.options.mandir: conf.env['MANDIR'] = Options.options.mandir else: conf.env['MANDIR'] = os.path.join(conf.env['DATADIR'], 'man') if Options.options.lv2dir: conf.env['LV2DIR'] = Options.options.lv2dir else: if Options.options.lv2_user: if sys.platform == "darwin": conf.env['LV2DIR'] = os.path.join(os.getenv('HOME'), 'Library/Audio/Plug-Ins/LV2') else: conf.env['LV2DIR'] = os.path.join(os.getenv('HOME'), '.lv2') else: if sys.platform == "darwin": conf.env['LV2DIR'] = '/Library/Audio/Plug-Ins/LV2' else: conf.env['LV2DIR'] = os.path.join(conf.env['LIBDIR'], 'lv2') conf.env['BINDIRNAME'] = chop_prefix(conf, 'BINDIR') conf.env['LIBDIRNAME'] = chop_prefix(conf, 'LIBDIR') conf.env['DATADIRNAME'] = chop_prefix(conf, 'DATADIR') conf.env['CONFIGDIRNAME'] = chop_prefix(conf, 'CONFIGDIR') conf.env['LV2DIRNAME'] = chop_prefix(conf, 'LV2DIR') if Options.options.debug: conf.env['CCFLAGS'] = [ '-O0', '-g' ] conf.env['CXXFLAGS'] = [ '-O0', '-g' ] else: append_cxx_flags('-DNDEBUG') if Options.options.strict: conf.env.append_value('CCFLAGS', [ '-std=c99', '-pedantic' ]) conf.env.append_value('CXXFLAGS', [ '-ansi', '-Woverloaded-virtual']) append_cxx_flags('-Wall -Wextra -Wno-unused-parameter') append_cxx_flags('-fPIC -DPIC -fshow-column') g_step = 2 def set_local_lib(conf, name, has_objects): conf.define('HAVE_' + nameify(name.upper()), 1) if has_objects: if type(conf.env['AUTOWAF_LOCAL_LIBS']) != dict: conf.env['AUTOWAF_LOCAL_LIBS'] = {} conf.env['AUTOWAF_LOCAL_LIBS'][name.lower()] = True else: if type(conf.env['AUTOWAF_LOCAL_HEADERS']) != dict: conf.env['AUTOWAF_LOCAL_HEADERS'] = {} conf.env['AUTOWAF_LOCAL_HEADERS'][name.lower()] = True def use_lib(bld, obj, libs): libs_list = libs.split() for l in libs_list: in_headers = l.lower() in bld.env['AUTOWAF_LOCAL_HEADERS'] in_libs = l.lower() in bld.env['AUTOWAF_LOCAL_LIBS'] if in_libs: if hasattr(obj, 'uselib_local'): obj.uselib_local += ' lib' + l.lower() + ' ' else: obj.uselib_local = 'lib' + l.lower() + ' ' if in_headers or in_libs: inc_flag = '-iquote../' + l.lower() for f in ['CCFLAGS', 'CXXFLAGS']: if not inc_flag in bld.env[f]: bld.env.append_value(f, inc_flag) else: if hasattr(obj, 'uselib'): obj.uselib += ' ' + l else: obj.uselib = l def display_header(title): Utils.pprint('BOLD', title) def display_msg(conf, msg, status = None, color = None): color = 'CYAN' if type(status) == bool and status or status == "True": color = 'GREEN' elif type(status) == bool and not status or status == "False": color = 'YELLOW' Utils.pprint('NORMAL', "%s :" % msg.ljust(conf.line_just), sep='') Utils.pprint(color, status) def print_summary(conf): global g_step if g_step > 2: print return e = conf.env print display_header('Global configuration') display_msg(conf, "Install prefix", conf.env['PREFIX']) display_msg(conf, "Debuggable build", str(conf.env['DEBUG'])) display_msg(conf, "Strict compiler flags", str(conf.env['STRICT'])) display_msg(conf, "Build documentation", str(conf.env['BUILD_DOCS'])) print g_step = 3 def link_flags(env, lib): return ' '.join(map(lambda x: env['LIB_ST'] % x, env['LIB_' + lib])) def compile_flags(env, lib): return ' '.join(map(lambda x: env['CPPPATH_ST'] % x, env['CPPPATH_' + lib])) def set_recursive(): global g_is_child g_is_child = True def is_child(): global g_is_child return g_is_child # Pkg-config file def build_pc(bld, name, version, libs): '''Build a pkg-config file for a library. name -- uppercase variable name (e.g. 'SOMENAME') version -- version string (e.g. '1.2.3') libs -- string/list of dependencies (e.g. 'LIBFOO GLIB') ''' obj = bld.new_task_gen('subst') obj.source = name.lower() + '.pc.in' obj.target = name.lower() + '.pc' obj.install_path = '${PREFIX}/${LIBDIRNAME}/pkgconfig' pkg_prefix = bld.env['PREFIX'] if pkg_prefix[-1] == '/': pkg_prefix = pkg_prefix[:-1] obj.dict = { 'prefix' : pkg_prefix, 'exec_prefix' : '${prefix}', 'libdir' : '${exec_prefix}/lib', 'includedir' : '${prefix}/include', name + '_VERSION' : version, } if type(libs) != list: libs = libs.split() for i in libs: obj.dict[i + '_LIBS'] = link_flags(bld.env, i) obj.dict[i + '_CFLAGS'] = compile_flags(bld.env, i) # Doxygen API documentation def build_dox(bld, name, version, srcdir, blddir): if not bld.env['BUILD_DOCS']: return obj = bld.new_task_gen('subst') obj.source = 'doc/reference.doxygen.in' obj.target = 'doc/reference.doxygen' if is_child(): src_dir = os.path.join(srcdir, name.lower()) doc_dir = os.path.join(blddir, 'default', name.lower(), 'doc') else: src_dir = srcdir doc_dir = os.path.join(blddir, 'default', 'doc') obj.dict = { name + '_VERSION' : version, name + '_SRCDIR' : os.path.abspath(src_dir), name + '_DOC_DIR' : os.path.abspath(doc_dir) } obj.install_path = '' out1 = bld.new_task_gen('command-output') out1.dependencies = [obj] out1.stdout = '/doc/doxygen.out' out1.stdin = '/doc/reference.doxygen' # whatever.. out1.command = 'doxygen' out1.argv = [os.path.abspath(doc_dir) + '/reference.doxygen'] out1.command_is_external = True # Version code file generation def build_version_files(header_path, source_path, domain, major, minor, micro): header_path = os.path.abspath(header_path) source_path = os.path.abspath(source_path) text = "int " + domain + "_major_version = " + str(major) + ";\n" text += "int " + domain + "_minor_version = " + str(minor) + ";\n" text += "int " + domain + "_micro_version = " + str(micro) + ";\n" try: o = file(source_path, 'w') o.write(text) o.close() except IOError: print "Could not open", source_path, " for writing\n" sys.exit(-1) text = "#ifndef __" + domain + "_version_h__\n" text += "#define __" + domain + "_version_h__\n" text += "extern const char* " + domain + "_revision;\n" text += "extern int " + domain + "_major_version;\n" text += "extern int " + domain + "_minor_version;\n" text += "extern int " + domain + "_micro_version;\n" text += "#endif /* __" + domain + "_version_h__ */\n" try: o = file(header_path, 'w') o.write(text) o.close() except IOError: print "Could not open", header_path, " for writing\n" sys.exit(-1) return None def shutdown(): # This isn't really correct (for packaging), but people asking is annoying if Options.commands['install']: try: os.popen("/sbin/ldconfig") except: pass slv2-0.6.6+dfsg1/AUTHORS0000644000175000017500000000015711231361306014340 0ustar alessioalessioAuthor: Dave Robillard GTK2 GUI and I18N support: Lars Luthman slv2-0.6.6+dfsg1/wscript0000644000175000017500000001005311231361306014702 0ustar alessioalessio#!/usr/bin/env python import autowaf import Options # Version of this package (even if built as a child) SLV2_VERSION = '0.6.6' # Library version (UNIX style major, minor, micro) # major increment <=> incompatible changes # minor increment <=> compatible changes (additions) # micro increment <=> no interface changes # Version history: # 0.0.1 = 0,0,0 # 0.1.0 = 2,0,0 # 0.2.0 = 3,0,0 # 0.3.0 = 4,0,0 # 0.3.1 = 4,0,0 # 0.3.2 = 5,0,1 # 0.4.0 = 6,0,0 # 0.4.1 = 6,0,0 (oops, should have been 6,1,0) # 0.4.2 = 6,0,0 (oops, should have been 6,2,0) # 0.4.3 = 6,0,0 (oops, should have been 6,3,0) # 0.4.4 = 7,0,1 # 0.4.5 = 7,0,1 # 0.5.0 = 8,0,0 # 0.6.0 = 9,0,0 (SVN r1282) # 0.6.1 = 9,1,0 # 0.6.2 = 9,1,1 # 0.6.4 = 9,2,0 # 0.6.6 = 9,2,0 SLV2_LIB_VERSION = '9.2.0' # Variables for 'waf dist' APPNAME = 'slv2' VERSION = SLV2_VERSION # Mandatory variables srcdir = '.' blddir = 'build' def set_options(opt): autowaf.set_options(opt) opt.add_option('--no-jack', action='store_true', default=False, dest='no_jack', help="Do not build JACK clients") opt.add_option('--test', action='store_true', default=False, dest='build_tests', help="Build unit tests") def configure(conf): autowaf.configure(conf) autowaf.check_tool(conf, 'compiler_cc') autowaf.check_pkg(conf, 'lv2core', uselib_store='LV2CORE', atleast_version='1.0', mandatory=True) autowaf.check_pkg(conf, 'redland', uselib_store='REDLAND', atleast_version='1.0.6', mandatory=True) autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.107.0', mandatory=False) conf.env.append_value('CCFLAGS', '-std=c99') conf.define('SLV2_VERSION', SLV2_VERSION) conf.write_config_header('slv2-config.h') conf.env['USE_JACK'] = conf.env['HAVE_JACK'] and not Options.options.no_jack conf.env['BUILD_TESTS'] = Options.options.build_tests autowaf.print_summary(conf) autowaf.display_header('SLV2 Configuration') autowaf.display_msg(conf, "Jack clients", str(conf.env['USE_JACK'])) autowaf.display_msg(conf, "Unit tests", str(conf.env['BUILD_TESTS'])) print def build(bld): # C Headers bld.install_files('${INCLUDEDIR}/slv2', 'slv2/*.h') # Pkgconfig file autowaf.build_pc(bld, 'SLV2', SLV2_VERSION, ['REDLAND']) lib_source = ''' src/collections.c src/plugin.c src/pluginclass.c src/plugininstance.c src/plugins.c src/pluginui.c src/pluginuiinstance.c src/port.c src/query.c src/scalepoint.c src/util.c src/value.c src/world.c ''' # Library obj = bld.new_task_gen('cc', 'shlib') obj.export_incdirs = ['.'] obj.source = lib_source obj.includes = ['.', './src'] obj.name = 'libslv2' obj.target = 'slv2' obj.vnum = SLV2_LIB_VERSION obj.install_path = '${LIBDIR}' autowaf.use_lib(bld, obj, 'REDLAND LV2CORE') # Static library (for unit test code coverage) if bld.env['BUILD_TESTS']: obj = bld.new_task_gen('cc', 'staticlib') obj.source = lib_source obj.includes = ['.', './src'] obj.name = 'libslv2_static' obj.target = 'slv2_static' obj.install_path = '' obj.ccflags = [ '-fprofile-arcs', '-ftest-coverage' ] # Utilities utils = ''' utils/lv2_inspect utils/lv2_list ''' for i in utils.split(): obj = bld.new_task_gen('cc', 'program') obj.source = i + '.c' obj.includes = ['.', './src'] obj.uselib_local = 'libslv2' obj.target = i obj.install_path = '${BINDIR}' # JACK Hosts hosts = ''' hosts/lv2_jack_host hosts/lv2_simple_jack_host ''' if bld.env['USE_JACK']: for i in hosts.split(): obj = bld.new_task_gen('cc', 'program') obj.source = i + '.c' obj.includes = ['.', './src'] obj.uselib = 'JACK' obj.uselib_local = 'libslv2' obj.target = i obj.install_path = '${BINDIR}' # Unit tests bld.add_subdirs('test') # Documentation autowaf.build_dox(bld, 'SLV2', SLV2_VERSION, srcdir, blddir) bld.install_files('${HTMLDIR}', blddir + '/default/doc/html/*') bld.install_files('${MANDIR}/man3', blddir + '/default/doc/man/man3/*') bld.install_files('${MANDIR}/man1', 'doc/*.1') def shutdown(): autowaf.shutdown() slv2-0.6.6+dfsg1/doc/0000755000175000017500000000000011231361306014032 5ustar alessioalessioslv2-0.6.6+dfsg1/doc/lv2_jack_host.10000644000175000017500000000203411231361306016643 0ustar alessioalessio.\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH LV2_JACK_HOST 1 "4 May 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME .B lv2_jack_host \- Run an LV2 plugin as a JACK application (with MIDI support). .SH SYNOPSIS .B lv2_jack_host PLUGIN_URI .SH SEE ALSO .BR slv2(3), .BR lv2_list(1), .BR lv2_jack_host(1), .BR lv2_simple_jack_host(1), .BR jackd(1) .SH AUTHOR lv2_inspect was written by Dave Robillard .PP This manual page was written by Jaromír Mikes and Dave Robillard slv2-0.6.6+dfsg1/doc/lv2_inspect.10000644000175000017500000000201011231361306016335 0ustar alessioalessio.\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH LV2_INSPECT 1 "4 May 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME .B lv2_inspect \- print information about an LV2 plugin in human-readable form. .SH SYNOPSIS .B lv2_inspect PLUGIN_URI .SH SEE ALSO .BR slv2(3), .BR lv2_list(1), .BR lv2_jack_host(1), .BR lv2_simple_jack_host(1) .SH AUTHOR lv2_inspect was written by Dave Robillard .PP This manual page was written by Jaromír Mikes and Dave Robillard slv2-0.6.6+dfsg1/doc/reference.doxygen.in0000644000175000017500000017540011231361306020003 0ustar alessioalessio# Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = SLV2 # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @SLV2_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @SLV2_DOC_DIR@ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = NO # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = NO # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = YES # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = NO # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = YES # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = NO # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = NO # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = NO # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = NO # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @SLV2_SRCDIR@/doc/mainpage.dox \ @SLV2_SRCDIR@/slv2/collections.h \ @SLV2_SRCDIR@/slv2/plugin.h \ @SLV2_SRCDIR@/slv2/pluginclass.h \ @SLV2_SRCDIR@/slv2/plugininstance.h \ @SLV2_SRCDIR@/slv2/pluginui.h \ @SLV2_SRCDIR@/slv2/pluginuiinstance.h \ @SLV2_SRCDIR@/slv2/port.h \ @SLV2_SRCDIR@/slv2/query.h \ @SLV2_SRCDIR@/slv2/scalepoint.h \ @SLV2_SRCDIR@/slv2/slv2.h \ @SLV2_SRCDIR@/slv2/types.h \ @SLV2_SRCDIR@/slv2/util.h \ @SLV2_SRCDIR@/slv2/value.h \ @SLV2_SRCDIR@/slv2/world.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = *.c # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = NO # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = NO # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = NO # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO slv2-0.6.6+dfsg1/doc/lv2_simple_jack_host.10000644000175000017500000000205211231361306020214 0ustar alessioalessio.\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH LV2_SIMPLE_JACK_HOST 1 "4 May 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME .B lv2_simple_jack_host \- Run an LV2 plugin as a JACK application (audio only). .SH SYNOPSIS .B lv2_simple_jack_host PLUGIN_URI .SH SEE ALSO .BR slv2(3), .BR lv2_list(1), .BR lv2_jack_host(1), .BR lv2_simple_jack_host(1), .BR jackd(1) .SH AUTHOR lv2_inspect was written by Dave Robillard .PP This manual page was written by Jaromír Mikes and Dave Robillard slv2-0.6.6+dfsg1/doc/mainpage.dox0000644000175000017500000000466611231361306016343 0ustar alessioalessio/* This duplication sucks :( */ /* HTML */ /** @mainpage * @section Overview * * SLV2 is a host library to simplify the discovery, loading, and use of LV2 * plugins (http://lv2plug.in). * * SLV2 is written in standard C99, and depends only on the Redland RDF library * (http://librdf.org). It should be portable to any system with Redland, and * is tested on various GNU/Linux distributions (often), and MacOS X (occasionally). * * The data (RDF) and code (shared library) functionality in SLV2 is strictly * separated so it is simple to control where each is used (e.g. it is * possible to discover/investigate plugins and related data without loading * any shared libraries, avoiding the associated risks). * * The SLV2 documentation is broken into several pages: * * \li \link slv2_world slv2_world \endlink - Global library initialisation, state, plugin discovery, etc. * * \li \link slv2_util slv2_util \endlink - Generally useful utility functions * * \li \link slv2_collections slv2_collections \endlink - Collections of values (literals and URIs) and objects * * \li \link slv2_data slv2_data \endlink - Access to plugin RDF data * * \li \link slv2_library slv2_library \endlink - Access to plugin shared libraries */ /* man page */ /** @defgroup slv2 SLV2 * SLV2 is a host library to simplify the discovery, loading, and use of LV2 * plugins (http://lv2plug.in). * * SLV2 is written in standard C99, and depends only on the Redland RDF library * (http://librdf.org). It should be portable to any system with Redland, and * is tested on various GNU/Linux distributions (often), and MacOS X (occasionally). * * The data (RDF) and code (shared library) functionality in SLV2 is strictly * separated so it is simple to control where each is used (e.g. it is * possible to discover/investigate plugins and related data without loading * any shared libraries, avoiding the associated risks). * * The SLV2 documentation is broken into several pages: * * \li \link slv2_world slv2_world \endlink - Global library initialisation, state, plugin discovery, etc. * * \li \link slv2_util slv2_util \endlink - Generally useful utility functions * * \li \link slv2_collections slv2_collections \endlink - Collections of values (literals and URIs) and objects * * \li \link slv2_data slv2_data \endlink - Access to plugin RDF data * * \li \link slv2_library slv2_library \endlink - Access to plugin shared libraries */ slv2-0.6.6+dfsg1/doc/lv2_list.10000644000175000017500000000172711231361306015661 0ustar alessioalessio.\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH LV2_LIST 1 "4 May 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME .B lv2_list \- List all installed LV2 plugins. .SH SYNOPSIS .B lv2_list .SH SEE ALSO .BR slv2(3), .BR lv2_list(1), .BR lv2_jack_host(1), .BR lv2_simple_jack_host(1) .SH AUTHOR lv2_inspect was written by Dave Robillard .PP This manual page was written by Jaromír Mikes and Dave Robillard slv2-0.6.6+dfsg1/INSTALL0000644000175000017500000000135111231361306014316 0ustar alessioalessioThis software requires only Python to build. Like an auto* project, building has three phases: * Configure: ./waf configure [OPTIONS] Example: ./waf configure --prefix=/some/where --debug --strict If --debug is not given, the flags from the environment variables CFLAGS and CXXFLAGS will be used. The default prefix is /usr/local * Build: ./waf [OPTIONS] Example: ./waf -j4 * Install: ./waf install [OPTIONS] The environment variable DESTDIR can be used to add any prefix to the install paths (useful for packaging). Example: DESTDIR=/home/drobilla/packages ./waf install *** IMPORTANT: You must use absolute paths everywhere Run './waf --help' for detailed option information. slv2-0.6.6+dfsg1/slv2.ttl0000644000175000017500000000214311231361306014700 0ustar alessioalessio@prefix rdf: . @prefix rdfs: . @prefix : . @prefix foaf: . a :Project ; :bug-database ; :developer [ a foaf:Person ; rdfs:seeAlso ; foaf:homepage ; foaf:mbox_sha1sum "253b3c58086250260bac1232d744d150274ad308" ; foaf:name "Dave Robillard" ] ; :download-page ; :homepage ; :license ; :name "SLV2" ; :programming-language "C", "Turtle" ; :repository [ :browse ; :location ; a :SVNRepository ] ; :shortdesc "Library for simple use of LV2 plugins" ; :shortname "SLV2" . slv2-0.6.6+dfsg1/utils/0000755000175000017500000000000011231361306014425 5ustar alessioalessioslv2-0.6.6+dfsg1/utils/lv2_inspect.c0000644000175000017500000002133311231361306017023 0ustar alessioalessio/* lv2_inspect - Display information about an LV2 plugin. * Copyright (C) 2007-2009 Dave Robillard * * 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 the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "slv2-config.h" #include #include #include #include #include #include "slv2/slv2.h" SLV2Value event_class = NULL; SLV2Value control_class = NULL; void print_port(SLV2Plugin p, uint32_t index, float* mins, float* maxes, float* defaults) { SLV2Port port = slv2_plugin_get_port_by_index(p, index); printf("\n\tPort %d:\n", index); SLV2Values classes = slv2_port_get_classes(p, port); printf("\t\tClasses:\n"); for (unsigned i=0; i < slv2_values_size(classes); ++i) { printf("\t\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(classes, i))); } if (slv2_port_is_a(p, port, event_class)) { SLV2Values supported = slv2_port_get_value_by_qname(p, port, "lv2ev:supportsEvent"); if (slv2_values_size(supported) > 0) { printf("\n\t\tSupported events:\n"); for (unsigned i=0; i < slv2_values_size(supported); ++i) { printf("\t\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(supported, i))); } } slv2_values_free(supported); } SLV2ScalePoints points = slv2_port_get_scale_points(p, port); if (points) printf("\t\tScale Points:\n"); for (unsigned i=0; i < slv2_scale_points_size(points); ++i) { SLV2ScalePoint p = slv2_scale_points_get_at(points, i); printf("\t\t\t%s = \"%s\"\n", slv2_value_as_string(slv2_scale_point_get_value(p)), slv2_value_as_string(slv2_scale_point_get_label(p))); } slv2_scale_points_free(points); SLV2Value val = slv2_port_get_symbol(p, port); printf("\n\t\tSymbol: %s\n", slv2_value_as_string(val)); val = slv2_port_get_name(p, port); printf("\t\tName: %s\n", slv2_value_as_string(val)); slv2_value_free(val); if (slv2_port_is_a(p, port, control_class)) { if (!isnan(mins[index])) printf("\t\tMinimum: %f\n", mins[index]); if (!isnan(mins[index])) printf("\t\tMaximum: %f\n", maxes[index]); if (!isnan(mins[index])) printf("\t\tDefault: %f\n", defaults[index]); } SLV2Values properties = slv2_port_get_properties(p, port); if (slv2_values_size(properties) > 0) printf("\t\tProperties: "); for (unsigned i=0; i < slv2_values_size(properties); ++i) { if (i > 0) { printf("\t\t "); } printf("%s\n", slv2_value_as_uri(slv2_values_get_at(properties, i))); } if (slv2_values_size(properties) > 0) printf("\n"); slv2_values_free(properties); } void print_plugin(SLV2Plugin p) { SLV2Value val = NULL; printf("%s\n\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); val = slv2_plugin_get_name(p); printf("\tName: %s\n", slv2_value_as_string(val)); slv2_value_free(val); SLV2Value class_label = slv2_plugin_class_get_label(slv2_plugin_get_class(p)); printf("\tClass: %s\n", slv2_value_as_string(class_label)); val = slv2_plugin_get_author_name(p); if (val) { printf("\tAuthor: %s\n", slv2_value_as_string(val)); slv2_value_free(val); } val = slv2_plugin_get_author_email(p); if (val) { printf("\tAuthor Email: %s\n", slv2_value_as_uri(val)); slv2_value_free(val); } val = slv2_plugin_get_author_homepage(p); if (val) { printf("\tAuthor Homepage: %s\n", slv2_value_as_uri(val)); slv2_value_free(val); } if (slv2_plugin_has_latency(p)) { uint32_t latency_port = slv2_plugin_get_latency_port_index(p); printf("\tHas latency: yes, reported by port %d\n", latency_port); } else { printf("\tHas latency: no\n"); } printf("\tBundle: %s\n", slv2_value_as_uri(slv2_plugin_get_bundle_uri(p))); printf("\tBinary: %s\n", slv2_value_as_uri(slv2_plugin_get_library_uri(p))); SLV2UIs uis = slv2_plugin_get_uis(p); if (slv2_values_size(uis) > 0) { printf("\tGUI: "); for (unsigned i=0; i < slv2_uis_size(uis); ++i) { SLV2UI ui = slv2_uis_get_at(uis, i); printf("%s\n", slv2_value_as_uri(slv2_ui_get_uri(ui))); const char* binary = slv2_value_as_uri(slv2_ui_get_binary_uri(ui)); SLV2Values types = slv2_ui_get_classes(ui); for (unsigned i=0; i < slv2_values_size(types); ++i) { printf("\t Class: %s\n", slv2_value_as_uri(slv2_values_get_at(types, i))); } if (binary) printf("\t Binary: %s\n", binary); printf("\t Bundle: %s\n", slv2_value_as_uri(slv2_ui_get_bundle_uri(ui))); } } slv2_uis_free(uis); //SLV2Values ui = slv2_plugin_get_value_for_subject(p, // ""); printf("\tData URIs: "); SLV2Values data_uris = slv2_plugin_get_data_uris(p); for (unsigned i=0; i < slv2_values_size(data_uris); ++i) { if (i > 0) { printf("\n\t "); } printf("%s", slv2_value_as_uri(slv2_values_get_at(data_uris, i))); } printf("\n"); /* Required Features */ SLV2Values features = slv2_plugin_get_required_features(p); if (features) printf("\tRequired Features: "); for (unsigned i=0; i < slv2_values_size(features); ++i) { if (i > 0) { printf("\n\t "); } printf("%s", slv2_value_as_uri(slv2_values_get_at(features, i))); } if (features) printf("\n"); slv2_values_free(features); /* Optional Features */ features = slv2_plugin_get_optional_features(p); if (features) printf("\tOptional Features: "); for (unsigned i=0; i < slv2_values_size(features); ++i) { if (i > 0) { printf("\n\t "); } printf("%s", slv2_value_as_uri(slv2_values_get_at(features, i))); } if (features) printf("\n"); slv2_values_free(features); /* Presets */ SLV2Results presets = slv2_plugin_query_sparql(p, "\ PREFIX lv2p: \ PREFIX dc: \ SELECT ?name WHERE { <> lv2p:hasPreset ?preset . ?preset dc:title ?name }"); if (!slv2_results_finished(presets)) printf("\tPresets: \n"); for (; !slv2_results_finished(presets); slv2_results_next(presets)) { SLV2Value name = slv2_results_get_binding_value(presets, 0); printf("\t %s\n", slv2_value_as_string(name)); } slv2_results_free(presets); /* Ports */ const uint32_t num_ports = slv2_plugin_get_num_ports(p); float* mins = calloc(num_ports, sizeof(float)); float* maxes = calloc(num_ports, sizeof(float)); float* defaults = calloc(num_ports, sizeof(float)); slv2_plugin_get_port_ranges_float(p, mins, maxes, defaults); //printf("\n\t# Ports: %d\n", num_ports); for (uint32_t i=0; i < num_ports; ++i) print_port(p, i, mins, maxes, defaults); free(mins); free(maxes); free(defaults); } void print_version() { printf("lv2_inspect (slv2) " SLV2_VERSION "\n"); printf("Copyright (C) 2007-2009 Dave Robillard \n"); printf("License: GNU GPL version 2 or later \n"); printf("This is free software: you are free to change and redistribute it.\n"); printf("There is NO WARRANTY, to the extent permitted by law.\n"); } void print_usage() { printf("Usage: lv2_inspect PLUGIN_URI\n"); printf("Show information about an installed LV2 plugin.\n"); } int main(int argc, char** argv) { int ret = 0; setlocale (LC_ALL, ""); SLV2World world = slv2_world_new(); slv2_world_load_all(world); event_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_EVENT); control_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_CONTROL); if (argc != 2) { print_usage(); ret = 1; goto done; } if (!strcmp(argv[1], "--version")) { print_version(); ret = 0; goto done; } else if (!strcmp(argv[1], "--help")) { print_usage(); ret = 0; goto done; } else if (argv[1][0] == '-') { print_usage(); ret = 2; goto done; } SLV2Plugins plugins = slv2_world_get_all_plugins(world); SLV2Value uri = slv2_value_new_uri(world, argv[1]); SLV2Plugin p = slv2_plugins_get_by_uri(plugins, uri); if (p) { print_plugin(p); } else { fprintf(stderr, "Plugin not found.\n"); } ret = (p != NULL ? 0 : -1); slv2_value_free(uri); slv2_plugins_free(world, plugins); done: slv2_value_free(event_class); slv2_value_free(control_class); slv2_world_free(world); return ret; } slv2-0.6.6+dfsg1/utils/ladspa.h0000644000175000017500000006564311231361306016060 0ustar alessioalessio/* ladspa.h Linux Audio Developer's Simple Plugin API Version 1.1[LGPL]. Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, Stefan Westerfeld. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifndef LADSPA_INCLUDED #define LADSPA_INCLUDED #define LADSPA_VERSION "1.1" #define LADSPA_VERSION_MAJOR 1 #define LADSPA_VERSION_MINOR 1 #ifdef __cplusplus extern "C" { #endif /*****************************************************************************/ /* Overview: There is a large number of synthesis packages in use or development on the Linux platform at this time. This API (`The Linux Audio Developer's Simple Plugin API') attempts to give programmers the ability to write simple `plugin' audio processors in C/C++ and link them dynamically (`plug') into a range of these packages (`hosts'). It should be possible for any host and any plugin to communicate completely through this interface. This API is deliberately short and simple. To achieve compatibility with a range of promising Linux sound synthesis packages it attempts to find the `greatest common divisor' in their logical behaviour. Having said this, certain limiting decisions are implicit, notably the use of a fixed type (LADSPA_Data) for all data transfer and absence of a parameterised `initialisation' phase. See below for the LADSPA_Data typedef. Plugins are expected to distinguish between control and audio data. Plugins have `ports' that are inputs or outputs for audio or control data and each plugin is `run' for a `block' corresponding to a short time interval measured in samples. Audio data is communicated using arrays of LADSPA_Data, allowing a block of audio to be processed by the plugin in a single pass. Control data is communicated using single LADSPA_Data values. Control data has a single value at the start of a call to the `run()' or `run_adding()' function, and may be considered to remain this value for its duration. The plugin may assume that all its input and output ports have been connected to the relevant data location (see the `connect_port()' function below) before it is asked to run. Plugins will reside in shared object files suitable for dynamic linking by dlopen() and family. The file will provide a number of `plugin types' that can be used to instantiate actual plugins (sometimes known as `plugin instances') that can be connected together to perform tasks. This API contains very limited error-handling. */ /*****************************************************************************/ /* Fundamental data type passed in and out of plugin. This data type is used to communicate audio samples and control values. It is assumed that the plugin will work sensibly given any numeric input value although it may have a preferred range (see hints below). For audio it is generally assumed that 1.0f is the `0dB' reference amplitude and is a `normal' signal level. */ typedef float LADSPA_Data; /*****************************************************************************/ /* Special Plugin Properties: Optional features of the plugin type are encapsulated in the LADSPA_Properties type. This is assembled by ORing individual properties together. */ typedef int LADSPA_Properties; /* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a real-time dependency (e.g. listens to a MIDI device) and so its output must not be cached or subject to significant latency. */ #define LADSPA_PROPERTY_REALTIME 0x1 /* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin may cease to work correctly if the host elects to use the same data location for both input and output (see connect_port()). This should be avoided as enabling this flag makes it impossible for hosts to use the plugin to process audio `in-place.' */ #define LADSPA_PROPERTY_INPLACE_BROKEN 0x2 /* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin is capable of running not only in a conventional host but also in a `hard real-time' environment. To qualify for this the plugin must satisfy all of the following: (1) The plugin must not use malloc(), free() or other heap memory management within its run() or run_adding() functions. All new memory used in run() must be managed via the stack. These restrictions only apply to the run() function. (2) The plugin will not attempt to make use of any library functions with the exceptions of functions in the ANSI standard C and C maths libraries, which the host is expected to provide. (3) The plugin will not access files, devices, pipes, sockets, IPC or any other mechanism that might result in process or thread blocking. (4) The plugin will take an amount of time to execute a run() or run_adding() call approximately of form (A+B*SampleCount) where A and B depend on the machine and host in use. This amount of time may not depend on input signals or plugin state. The host is left the responsibility to perform timings to estimate upper bounds for A and B. */ #define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4 #define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME) #define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN) #define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE) /*****************************************************************************/ /* Plugin Ports: Plugins have `ports' that are inputs or outputs for audio or data. Ports can communicate arrays of LADSPA_Data (for audio inputs/outputs) or single LADSPA_Data values (for control input/outputs). This information is encapsulated in the LADSPA_PortDescriptor type which is assembled by ORing individual properties together. Note that a port must be an input or an output port but not both and that a port must be a control or audio port but not both. */ typedef int LADSPA_PortDescriptor; /* Property LADSPA_PORT_INPUT indicates that the port is an input. */ #define LADSPA_PORT_INPUT 0x1 /* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */ #define LADSPA_PORT_OUTPUT 0x2 /* Property LADSPA_PORT_CONTROL indicates that the port is a control port. */ #define LADSPA_PORT_CONTROL 0x4 /* Property LADSPA_PORT_AUDIO indicates that the port is a audio port. */ #define LADSPA_PORT_AUDIO 0x8 #define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT) #define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT) #define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL) #define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO) /*****************************************************************************/ /* Plugin Port Range Hints: The host may wish to provide a representation of data entering or leaving a plugin (e.g. to generate a GUI automatically). To make this more meaningful, the plugin should provide `hints' to the host describing the usual values taken by the data. Note that these are only hints. The host may ignore them and the plugin must not assume that data supplied to it is meaningful. If the plugin receives invalid input data it is expected to continue to run without failure and, where possible, produce a sensible output (e.g. a high-pass filter given a negative cutoff frequency might switch to an all-pass mode). Hints are meaningful for all input and output ports but hints for input control ports are expected to be particularly useful. More hint information is encapsulated in the LADSPA_PortRangeHintDescriptor type which is assembled by ORing individual hint types together. Hints may require further LowerBound and UpperBound information. All the hint information for a particular port is aggregated in the LADSPA_PortRangeHint structure. */ typedef int LADSPA_PortRangeHintDescriptor; /* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field of the LADSPA_PortRangeHint should be considered meaningful. The value in this field should be considered the (inclusive) lower bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also specified then the value of LowerBound should be multiplied by the sample rate. */ #define LADSPA_HINT_BOUNDED_BELOW 0x1 /* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field of the LADSPA_PortRangeHint should be considered meaningful. The value in this field should be considered the (inclusive) upper bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also specified then the value of UpperBound should be multiplied by the sample rate. */ #define LADSPA_HINT_BOUNDED_ABOVE 0x2 /* Hint LADSPA_HINT_TOGGLED indicates that the data item should be considered a Boolean toggle. Data less than or equal to zero should be considered `off' or `false,' and data above zero should be considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or LADSPA_HINT_DEFAULT_1. */ #define LADSPA_HINT_TOGGLED 0x4 /* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified should be interpreted as multiples of the sample rate. For instance, a frequency range from 0Hz to the Nyquist frequency (half the sample rate) could be requested by this hint in conjunction with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds at all must support this hint to retain meaning. */ #define LADSPA_HINT_SAMPLE_RATE 0x8 /* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the user will find it more intuitive to view values using a logarithmic scale. This is particularly useful for frequencies and gains. */ #define LADSPA_HINT_LOGARITHMIC 0x10 /* Hint LADSPA_HINT_INTEGER indicates that a user interface would probably wish to provide a stepped control taking only integer values. Any bounds set should be slightly wider than the actual integer range required to avoid floating point rounding errors. For instance, the integer set {0,1,2,3} might be described as [-0.1, 3.1]. */ #define LADSPA_HINT_INTEGER 0x20 /* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal' value for the port that is sensible as a default. For instance, this value is suitable for use as an initial value in a user interface or as a value the host might assign to a control port when the user has not provided one. Defaults are encoded using a mask so only one default may be specified for a port. Some of the hints make use of lower and upper bounds, in which case the relevant bound or bounds must be available and LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting default must be rounded if LADSPA_HINT_INTEGER is present. Default values were introduced in LADSPA v1.1. */ #define LADSPA_HINT_DEFAULT_MASK 0x3C0 /* This default values indicates that no default is provided. */ #define LADSPA_HINT_DEFAULT_NONE 0x0 /* This default hint indicates that the suggested lower bound for the port should be used. */ #define LADSPA_HINT_DEFAULT_MINIMUM 0x40 /* This default hint indicates that a low value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 + log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper * 0.25). */ #define LADSPA_HINT_DEFAULT_LOW 0x80 /* This default hint indicates that a middle value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 + log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper * 0.5). */ #define LADSPA_HINT_DEFAULT_MIDDLE 0xC0 /* This default hint indicates that a high value between the suggested lower and upper bounds should be chosen. For ports with LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 + log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper * 0.75). */ #define LADSPA_HINT_DEFAULT_HIGH 0x100 /* This default hint indicates that the suggested upper bound for the port should be used. */ #define LADSPA_HINT_DEFAULT_MAXIMUM 0x140 /* This default hint indicates that the number 0 should be used. Note that this default may be used in conjunction with LADSPA_HINT_TOGGLED. */ #define LADSPA_HINT_DEFAULT_0 0x200 /* This default hint indicates that the number 1 should be used. Note that this default may be used in conjunction with LADSPA_HINT_TOGGLED. */ #define LADSPA_HINT_DEFAULT_1 0x240 /* This default hint indicates that the number 100 should be used. */ #define LADSPA_HINT_DEFAULT_100 0x280 /* This default hint indicates that the Hz frequency of `concert A' should be used. This will be 440 unless the host uses an unusual tuning convention, in which case it may be within a few Hz. */ #define LADSPA_HINT_DEFAULT_440 0x2C0 #define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW) #define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE) #define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED) #define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE) #define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC) #define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER) #define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK) #define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MINIMUM) #define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_LOW) #define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MIDDLE) #define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_HIGH) #define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_MAXIMUM) #define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_0) #define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_1) #define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_100) #define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ == LADSPA_HINT_DEFAULT_440) typedef struct _LADSPA_PortRangeHint { /* Hints about the port. */ LADSPA_PortRangeHintDescriptor HintDescriptor; /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When LADSPA_HINT_SAMPLE_RATE is also active then this value should be multiplied by the relevant sample rate. */ LADSPA_Data LowerBound; /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When LADSPA_HINT_SAMPLE_RATE is also active then this value should be multiplied by the relevant sample rate. */ LADSPA_Data UpperBound; } LADSPA_PortRangeHint; /*****************************************************************************/ /* Plugin Handles: This plugin handle indicates a particular instance of the plugin concerned. It is valid to compare this to NULL (0 for C++) but otherwise the host should not attempt to interpret it. The plugin may use it to reference internal instance data. */ typedef void * LADSPA_Handle; /*****************************************************************************/ /* Descriptor for a Type of Plugin: This structure is used to describe a plugin type. It provides a number of functions to examine the type, instantiate it, link it to buffers and workspaces and to run it. */ typedef struct _LADSPA_Descriptor { /* This numeric identifier indicates the plugin type uniquely. Plugin programmers may reserve ranges of IDs from a central body to avoid clashes. Hosts may assume that IDs are below 0x1000000. */ unsigned long UniqueID; /* This identifier can be used as a unique, case-sensitive identifier for the plugin type within the plugin file. Plugin types should be identified by file and label rather than by index or plugin name, which may be changed in new plugin versions. Labels must not contain white-space characters. */ const char * Label; /* This indicates a number of properties of the plugin. */ LADSPA_Properties Properties; /* This member points to the null-terminated name of the plugin (e.g. "Sine Oscillator"). */ const char * Name; /* This member points to the null-terminated string indicating the maker of the plugin. This can be an empty string but not NULL. */ const char * Maker; /* This member points to the null-terminated string indicating any copyright applying to the plugin. If no Copyright applies the string "None" should be used. */ const char * Copyright; /* This indicates the number of ports (input AND output) present on the plugin. */ unsigned long PortCount; /* This member indicates an array of port descriptors. Valid indices vary from 0 to PortCount-1. */ const LADSPA_PortDescriptor * PortDescriptors; /* This member indicates an array of null-terminated strings describing ports (e.g. "Frequency (Hz)"). Valid indices vary from 0 to PortCount-1. */ const char * const * PortNames; /* This member indicates an array of range hints for each port (see above). Valid indices vary from 0 to PortCount-1. */ const LADSPA_PortRangeHint * PortRangeHints; /* This may be used by the plugin developer to pass any custom implementation data into an instantiate call. It must not be used or interpreted by the host. It is expected that most plugin writers will not use this facility as LADSPA_Handle should be used to hold instance data. */ void * ImplementationData; /* This member is a function pointer that instantiates a plugin. A handle is returned indicating the new plugin instance. The instantiation function accepts a sample rate as a parameter. The plugin descriptor from which this instantiate function was found must also be passed. This function must return NULL if instantiation fails. Note that instance initialisation should generally occur in activate() rather than here. */ LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long SampleRate); /* This member is a function pointer that connects a port on an instantiated plugin to a memory location at which a block of data for the port will be read/written. The data location is expected to be an array of LADSPA_Data for audio ports or a single LADSPA_Data value for control ports. Memory issues will be managed by the host. The plugin must read/write the data at these locations every time run() or run_adding() is called and the data present at the time of this connection call should not be considered meaningful. connect_port() may be called more than once for a plugin instance to allow the host to change the buffers that the plugin is reading or writing. These calls may be made before or after activate() or deactivate() calls. connect_port() must be called at least once for each port before run() or run_adding() is called. When working with blocks of LADSPA_Data the plugin should pay careful attention to the block size passed to the run function as the block allocated may only just be large enough to contain the block of samples. Plugin writers should be aware that the host may elect to use the same buffer for more than one port and even use the same buffer for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN). However, overlapped buffers or use of a single buffer for both audio and control data may result in unexpected behaviour. */ void (*connect_port)(LADSPA_Handle Instance, unsigned long Port, LADSPA_Data * DataLocation); /* This member is a function pointer that initialises a plugin instance and activates it for use. This is separated from instantiate() to aid real-time support and so that hosts can reinitialise a plugin instance by calling deactivate() and then activate(). In this case the plugin instance must reset all state information dependent on the history of the plugin instance except for any data locations provided by connect_port() and any gain set by set_run_adding_gain(). If there is nothing for activate() to do then the plugin writer may provide a NULL rather than an empty function. When present, hosts must call this function once before run() (or run_adding()) is called for the first time. This call should be made as close to the run() call as possible and indicates to real-time plugins that they are now live. Plugins should not rely on a prompt call to run() after activate(). activate() may not be called again unless deactivate() is called first. Note that connect_port() may be called before or after a call to activate(). */ void (*activate)(LADSPA_Handle Instance); /* This method is a function pointer that runs an instance of a plugin for a block. Two parameters are required: the first is a handle to the particular instance to be run and the second indicates the block size (in samples) for which the plugin instance may run. Note that if an activate() function exists then it must be called before run() or run_adding(). If deactivate() is called for a plugin instance then the plugin instance may not be reused until activate() has been called again. If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE then there are various things that the plugin should not do within the run() or run_adding() functions (see above). */ void (*run)(LADSPA_Handle Instance, unsigned long SampleCount); /* This method is a function pointer that runs an instance of a plugin for a block. This has identical behaviour to run() except in the way data is output from the plugin. When run() is used, values are written directly to the memory areas associated with the output ports. However when run_adding() is called, values must be added to the values already present in the memory areas. Furthermore, output values written must be scaled by the current gain set by set_run_adding_gain() (see below) before addition. run_adding() is optional. When it is not provided by a plugin, this function pointer must be set to NULL. When it is provided, the function set_run_adding_gain() must be provided also. */ void (*run_adding)(LADSPA_Handle Instance, unsigned long SampleCount); /* This method is a function pointer that sets the output gain for use when run_adding() is called (see above). If this function is never called the gain is assumed to default to 1. Gain information should be retained when activate() or deactivate() are called. This function should be provided by the plugin if and only if the run_adding() function is provided. When it is absent this function pointer must be set to NULL. */ void (*set_run_adding_gain)(LADSPA_Handle Instance, LADSPA_Data Gain); /* This is the counterpart to activate() (see above). If there is nothing for deactivate() to do then the plugin writer may provide a NULL rather than an empty function. Hosts must deactivate all activated units after they have been run() (or run_adding()) for the last time. This call should be made as close to the last run() call as possible and indicates to real-time plugins that they are no longer live. Plugins should not rely on prompt deactivation. Note that connect_port() may be called before or after a call to deactivate(). Deactivation is not similar to pausing as the plugin instance will be reinitialised when activate() is called to reuse it. */ void (*deactivate)(LADSPA_Handle Instance); /* Once an instance of a plugin has been finished with it can be deleted using the following function. The instance handle passed ceases to be valid after this call. If activate() was called for a plugin instance then a corresponding call to deactivate() must be made before cleanup() is called. */ void (*cleanup)(LADSPA_Handle Instance); } LADSPA_Descriptor; /**********************************************************************/ /* Accessing a Plugin: */ /* The exact mechanism by which plugins are loaded is host-dependent, however all most hosts will need to know is the name of shared object file containing the plugin types. To allow multiple hosts to share plugin types, hosts may wish to check for environment variable LADSPA_PATH. If present, this should contain a colon-separated path indicating directories that should be searched (in order) when loading plugin types. A plugin programmer must include a function called "ladspa_descriptor" with the following function prototype within the shared object file. This function will have C-style linkage (if you are using C++ this is taken care of by the `extern "C"' clause at the top of the file). A host will find the plugin shared object file by one means or another, find the ladspa_descriptor() function, call it, and proceed from there. Plugin types are accessed by index (not ID) using values from 0 upwards. Out of range indexes must result in this function returning NULL, so the plugin count can be determined by checking for the least index that results in NULL being returned. */ const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); /* Datatype corresponding to the ladspa_descriptor() function. */ typedef const LADSPA_Descriptor * (*LADSPA_Descriptor_Function)(unsigned long Index); /**********************************************************************/ #ifdef __cplusplus } #endif #endif /* LADSPA_INCLUDED */ /* EOF */ slv2-0.6.6+dfsg1/utils/ladspa2lv2.c0000644000175000017500000002561111231361306016550 0ustar alessioalessio/* ladspa2lv2 * Copyright (C) 2007-2009 Dave Robillard * * 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 the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include #include "ladspa.h" #define U(x) ((const unsigned char*)(x)) #define NS_RDF(x) "http://www.w3.org/1999/02/22-rdf-syntax-ns#" x #define NS_LV2(x) "http://lv2plug.in/ns/lv2core#" x #define NS_DOAP(x) "http://usefulinc.com/ns/doap#" x librdf_world* world = NULL; void add_resource(librdf_model* model, librdf_node* subject, const char* predicate_uri, const char* object_uri) { librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); librdf_node* object = librdf_new_node_from_uri_string(world, U(object_uri)); librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); librdf_model_add_statement(model, triple); //librdf_free_statement(triple); } void add_node(librdf_model* model, librdf_node* subject, const char* predicate_uri, librdf_node* object) { librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); librdf_model_add_statement(model, triple); //librdf_free_statement(triple); } void add_string(librdf_model* model, librdf_node* subject, const char* predicate_uri, const char* object_string) { librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); librdf_node* object = librdf_new_node_from_literal(world, U(object_string), NULL, 0); librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); librdf_model_add_statement(model, triple); //librdf_free_statement(triple); } void add_int(librdf_model* model, librdf_node* subject, const char* predicate_uri, int object_int) { static const size_t MAX_LEN = 21; // strlen(2^64) + 1 char object_str[MAX_LEN]; snprintf(object_str, MAX_LEN, "%d", object_int); librdf_uri* type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#integer")); librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); librdf_node* object = librdf_new_node_from_typed_literal(world, U(object_str), NULL, type); librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); librdf_model_add_statement(model, triple); //librdf_free_statement(triple); librdf_free_uri(type); } void add_float(librdf_model* model, librdf_node* subject, const char* predicate_uri, float object_float) { static const size_t MAX_LEN = 64; // ? char object_str[MAX_LEN]; snprintf(object_str, MAX_LEN, "%f", object_float); librdf_uri* type = librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema#decimal")); librdf_node* predicate = librdf_new_node_from_uri_string(world, U(predicate_uri)); librdf_node* object = librdf_new_node_from_typed_literal(world, U(object_str), NULL, type); librdf_statement* triple = librdf_new_statement_from_nodes(world, subject, predicate, object); librdf_model_add_statement(model, triple); //librdf_free_statement(triple); librdf_free_uri(type); } LADSPA_Descriptor* load_ladspa_plugin(const char* lib_path, unsigned long index) { void* const handle = dlopen(lib_path, RTLD_LAZY); if (handle == NULL) return NULL; LADSPA_Descriptor_Function df = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor"); if (df == NULL) { dlclose(handle); return NULL; } LADSPA_Descriptor* const descriptor = (LADSPA_Descriptor*)df(index); return descriptor; } void add_port_range(LADSPA_Descriptor* plugin, unsigned long port_index, librdf_model* model, librdf_node* port) { LADSPA_PortRangeHintDescriptor hint_descriptor = plugin->PortRangeHints[port_index].HintDescriptor; bool range_valid = false; float upper=1.0f, lower=0.0f, normal=0.0f; /* Convert hints */ if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { add_resource(model, port, NS_LV2("portHint"), NS_LV2("sampleRate")); upper = plugin->PortRangeHints[port_index].UpperBound; lower = plugin->PortRangeHints[port_index].LowerBound; range_valid = true; } if (LADSPA_IS_HINT_INTEGER(hint_descriptor)) { add_resource(model, port, NS_LV2("portHint"), NS_LV2("integer")); upper = plugin->PortRangeHints[port_index].UpperBound; lower = plugin->PortRangeHints[port_index].LowerBound; range_valid = true; } if (LADSPA_IS_HINT_TOGGLED(hint_descriptor)) { add_resource(model, port, NS_LV2("portHint"), NS_LV2("toggled")); upper = 1.0; lower = 0.0; range_valid = true; } if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { /* FLT_EPSILON is defined as the different between 1.0 and the minimum * float greater than 1.0. So, if lower is < FLT_EPSILON, it will be 1.0 * and the logarithmic control will have a base of 1 and thus not change */ if (range_valid && lower < FLT_EPSILON) lower = FLT_EPSILON; } if (LADSPA_IS_HINT_HAS_DEFAULT(hint_descriptor)) { bool valid = true; if (range_valid && LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { normal = lower; } else if (range_valid && LADSPA_IS_HINT_DEFAULT_LOW(hint_descriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { normal = exp(log(lower) * 0.75 + log(upper) * 0.25); } else { normal = lower * 0.75 + upper * 0.25; } } else if (range_valid && LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { normal = exp(log(lower) * 0.5 + log(upper) * 0.5); } else { normal = lower * 0.5 + upper * 0.5; } } else if (range_valid && LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { normal = exp(log(lower) * 0.25 + log(upper) * 0.75); } else { normal = lower * 0.25 + upper * 0.75; } } else if (range_valid && LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { normal = upper; } else if (LADSPA_IS_HINT_DEFAULT_0(hint_descriptor)) { normal = 0.0; } else if (LADSPA_IS_HINT_DEFAULT_1(hint_descriptor)) { normal = 1.0; } else if (LADSPA_IS_HINT_DEFAULT_100(hint_descriptor)) { normal = 100.0; } else if (LADSPA_IS_HINT_DEFAULT_440(hint_descriptor)) { normal = 440.0; } else { valid = false; } if (valid) add_float(model, port, NS_LV2("default"), normal); } else { // No default hint if (range_valid && LADSPA_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { normal = lower; add_float(model, port, NS_LV2("default"), normal); } else if (range_valid && LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { normal = upper; add_float(model, port, NS_LV2("default"), normal); } } } void write_lv2_turtle(LADSPA_Descriptor* descriptor, const char* plugin_uri, const char* filename) { //librdf_storage* storage = librdf_new_storage(world, // "hashes", NULL, "hash-type='memory'"); librdf_storage* storage = librdf_new_storage(world, "memory", NULL, NULL); librdf_model* model = librdf_new_model(world, storage, NULL); librdf_serializer* serializer = librdf_new_serializer(world, "turtle", NULL, NULL); librdf_node* plugin = librdf_new_node_from_uri_string(world, U(plugin_uri)); // Set up namespaces librdf_serializer_set_namespace(serializer, librdf_new_uri(world, U("http://www.w3.org/1999/02/22-rdf-syntax-ns#")), "rdf"); librdf_serializer_set_namespace(serializer, librdf_new_uri(world, U("http://www.w3.org/2000/01/rdf-schema#")), "rdfs"); librdf_serializer_set_namespace(serializer, librdf_new_uri(world, U("http://www.w3.org/2001/XMLSchema")), "xsd"); librdf_serializer_set_namespace(serializer, librdf_new_uri(world, U("http://usefulinc.com/ns/doap#")), "doap"); librdf_serializer_set_namespace(serializer, librdf_new_uri(world, U("http://xmlns.com/foaf/0.1/")), "foaf"); librdf_serializer_set_namespace(serializer, librdf_new_uri(world, U("http://lv2plug.in/ns/lv2core#")), "lv2"); add_resource(model, plugin, NS_RDF("type"), NS_LV2("Plugin")); add_string(model, plugin, NS_DOAP("name"), descriptor->Name); if (LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties)) add_resource(model, plugin, NS_LV2("optionalFeature"), NS_LV2("hardRTCapable")); for (uint32_t i=0; i < descriptor->PortCount; ++i) { char index_str[32]; snprintf(index_str, (size_t)32, "%u", i); const LADSPA_PortDescriptor port_descriptor = descriptor->PortDescriptors[i]; librdf_node* port_node = librdf_new_node(world); add_node(model, plugin, NS_LV2("port"), port_node); add_int(model, port_node, NS_LV2("index"), (int)i); if (LADSPA_IS_PORT_INPUT(port_descriptor)) add_resource(model, port_node, NS_RDF("type"), NS_LV2("InputPort")); else add_resource(model, port_node, NS_RDF("type"), NS_LV2("OutputPort")); if (LADSPA_IS_PORT_AUDIO(port_descriptor)) add_resource(model, port_node, NS_RDF("type"), NS_LV2("AudioPort")); else add_resource(model, port_node, NS_RDF("type"), NS_LV2("ControlPort")); add_string(model, port_node, NS_LV2("name"), descriptor->PortNames[i]); add_port_range(descriptor, i, model, port_node); } librdf_serializer_serialize_model_to_file(serializer, filename, NULL, model); } void print_usage() { printf("Usage: ladspa2lv2 /path/to/ladspalib.so ladspa_index lv2_uri output_data_file\n"); printf("Partially convert a LADSPA plugin to an LV2 plugin.\n"); printf("This utility is for developers, it will not generate a usable\n"); printf("LV2 plugin directly.\n\n"); } int main(int argc, char** argv) { if (argc != 5) { print_usage(); return 1; } const char* const lib_path = argv[1]; const unsigned long index = atol(argv[2]); const char* const uri = argv[3]; world = librdf_new_world(); librdf_world_open(world); LADSPA_Descriptor* descriptor = load_ladspa_plugin(lib_path, index); if (descriptor) { printf("Loaded %s : %lu\n", lib_path, index); write_lv2_turtle(descriptor, uri, argv[4]); } else { printf("Failed to load %s : %lu\n", lib_path, index); } librdf_free_world(world); return 0; } slv2-0.6.6+dfsg1/utils/lv2_list.c0000644000175000017500000000433411231361306016333 0ustar alessioalessio/* lv2_list - List system installed LV2 plugins. * Copyright (C) 2007-2009 Dave Robillard * * 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 the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "slv2-config.h" #include #include #include "slv2/slv2.h" void list_plugins(SLV2Plugins list) { for (unsigned i=0; i < slv2_plugins_size(list); ++i) { SLV2Plugin p = slv2_plugins_get_at(list, i); printf("%s\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); } } void print_version() { printf("lv2_list (slv2) " SLV2_VERSION "\n"); printf("Copyright (C) 2007-2009 Dave Robillard \n"); printf("License: GNU GPL version 2 or later \n"); printf("This is free software: you are free to change and redistribute it.\n"); printf("There is NO WARRANTY, to the extent permitted by law.\n"); } void print_usage() { printf("Usage: lv2_list\n"); printf("List all installed LV2 plugins.\n"); printf("The environment variable LV2_PATH can be used to control where\n"); printf("this (and all other slv2 based LV2 hosts) will search for plugins.\n"); } int main(int argc, char** argv) { if (argc > 1) { if (argc == 2 && !strcmp(argv[1], "--version")) { print_version(); return 0; } else if (argc == 2 && !strcmp(argv[1], "--help")) { print_usage(); return 0; } else { print_usage(); return -1; } } SLV2World world = slv2_world_new(); slv2_world_load_all(world); SLV2Plugins plugins = slv2_world_get_all_plugins(world); list_plugins(plugins); slv2_plugins_free(world, plugins); slv2_world_free(world); return 0; } slv2-0.6.6+dfsg1/wafadmin/0000755000175000017500000000000011703115001015044 5ustar alessioalessioslv2-0.6.6+dfsg1/wafadmin/Node.py0000644000175000017500000002543211176703512016327 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,fnmatch,re import Utils UNDEFINED=0 DIR=1 FILE=2 BUILD=3 type_to_string={UNDEFINED:"unk",DIR:"dir",FILE:"src",BUILD:"bld"} exclude_regs=''' **/*~ **/#*# **/.#* **/%*% **/._* **/CVS **/CVS/** **/.cvsignore **/SCCS **/SCCS/** **/vssver.scc **/.svn **/.svn/** **/.DS_Store'''.split() exc_fun=None def default_excludes(): global exc_fun if exc_fun: return exc_fun regs=[Utils.jar_regexp(x)for x in exclude_regs] def mat(path): for x in regs: if x.match(path): return True return False exc_fun=mat return exc_fun class Node(object): __slots__=("name","parent","id","childs") def __init__(self,name,parent,node_type=UNDEFINED): self.name=name self.parent=parent self.__class__.bld.id_nodes+=4 self.id=self.__class__.bld.id_nodes+node_type if node_type==DIR:self.childs={} if parent and name in parent.childs: raise Utils.WafError('node %s exists in the parent files %r already'%(name,parent)) if parent:parent.childs[name]=self def __setstate__(self,data): if len(data)==4: (self.parent,self.name,self.id,self.childs)=data else: (self.parent,self.name,self.id)=data def __getstate__(self): if getattr(self,'childs',None)is None: return(self.parent,self.name,self.id) else: return(self.parent,self.name,self.id,self.childs) def __str__(self): if not self.parent:return'' return"%s://%s"%(type_to_string[self.id&3],self.abspath()) def __repr__(self): return self.__str__() def __hash__(self): raise Utils.WafError('nodes, you are doing it wrong') def __copy__(self): raise Utils.WafError('nodes are not supposed to be cloned') def get_type(self): return self.id&3 def set_type(self,t): self.id=self.id+t-self.id&3 def dirs(self): return[x for x in self.childs.values()if x.id&3==DIR] def files(self): return[x for x in self.childs.values()if x.id&3==FILE] def get_dir(self,name,default=None): node=self.childs.get(name,None) if not node or node.id&3!=DIR:return default return node def get_file(self,name,default=None): node=self.childs.get(name,None) if not node or node.id&3!=FILE:return default return node def get_build(self,name,default=None): node=self.childs.get(name,None) if not node or node.id&3!=BUILD:return default return node def find_resource(self,lst): if isinstance(lst,str): lst=Utils.split_path(lst) if len(lst)==1: parent=self else: parent=self.find_dir(lst[:-1]) if not parent:return None self.__class__.bld.rescan(parent) name=lst[-1] node=parent.childs.get(name,None) if node: tp=node.id&3 if tp==FILE or tp==BUILD: return node else: return None tree=self.__class__.bld if not name in tree.cache_dir_contents[parent.id]: return None path=parent.abspath()+os.sep+name try: st=Utils.h_file(path) except IOError: return None child=self.__class__(name,parent,FILE) tree.node_sigs[0][child.id]=st return child def find_or_declare(self,lst): if isinstance(lst,str): lst=Utils.split_path(lst) if len(lst)==1: parent=self else: parent=self.find_dir(lst[:-1]) if not parent:return None self.__class__.bld.rescan(parent) name=lst[-1] node=parent.childs.get(name,None) if node: tp=node.id&3 if tp!=BUILD: raise Utils.WafError("find_or_declare returns a build node, not a source nor a directory %r"%lst) return node node=self.__class__(name,parent,BUILD) return node def find_dir(self,lst): if isinstance(lst,str): lst=Utils.split_path(lst) current=self for name in lst: self.__class__.bld.rescan(current) prev=current if not current.parent and name==current.name: continue elif not name: continue elif name=='.': continue elif name=='..': current=current.parent or current else: current=prev.childs.get(name,None) if current is None: dir_cont=self.__class__.bld.cache_dir_contents if prev.id in dir_cont and name in dir_cont[prev.id]: if not prev.name: if os.sep=='/': dirname=os.sep+name else: dirname=name else: dirname=prev.abspath()+os.sep+name if not os.path.isdir(dirname): return None current=self.__class__(name,prev,DIR) elif(not prev.name and len(name)==2 and name[1]==':')or name.startswith('\\\\'): current=self.__class__(name,prev,DIR) else: return None else: if current.id&3!=DIR: return None return current def ensure_dir_node_from_path(self,lst): if isinstance(lst,str): lst=Utils.split_path(lst) current=self for name in lst: if not name: continue elif name=='.': continue elif name=='..': current=current.parent or current else: prev=current current=prev.childs.get(name,None) if current is None: current=self.__class__(name,prev,DIR) return current def exclusive_build_node(self,path): lst=Utils.split_path(path) name=lst[-1] if len(lst)>1: parent=None try: parent=self.find_dir(lst[:-1]) except OSError: pass if not parent: parent=self.ensure_dir_node_from_path(lst[:-1]) self.__class__.bld.cache_scanned_folders[parent.id]=1 else: try: self.__class__.bld.rescan(parent) except OSError: pass else: parent=self node=parent.childs.get(name,None) if not node: node=self.__class__(name,parent,BUILD) return node def path_to_parent(self,parent): lst=[] p=self h1=parent.height() h2=p.height() while h2>h1: h2-=1 lst.append(p.name) p=p.parent if lst: lst.reverse() ret=os.path.join(*lst) else: ret='' return ret def find_ancestor(self,node): dist=self.height()-node.height() if dist<0:return node.find_ancestor(self) cand=self while dist>0: cand=cand.parent dist-=1 if cand==node:return cand cursor=node while cand.parent: cand=cand.parent cursor=cursor.parent if cand==cursor:return cand def relpath_gen(self,going_to): if self==going_to:return'.' if going_to.parent==self:return'..' ancestor=self.find_ancestor(going_to) lst=[] cand=self while not cand.id==ancestor.id: lst.append(cand.name) cand=cand.parent cand=going_to while not cand.id==ancestor.id: lst.append('..') cand=cand.parent lst.reverse() return os.sep.join(lst) def nice_path(self,env=None): tree=self.__class__.bld ln=tree.launch_node() if self.id&3==FILE:return self.relpath_gen(ln) else:return os.path.join(tree.bldnode.relpath_gen(ln),env.variant(),self.relpath_gen(tree.srcnode)) def is_child_of(self,node): p=self diff=self.height()-node.height() while diff>0: diff-=1 p=p.parent return p.id==node.id def variant(self,env): if not env:return 0 elif self.id&3==FILE:return 0 else:return env.variant() def height(self): d=self val=-1 while d: d=d.parent val+=1 return val def abspath(self,env=None): variant=(env and(self.id&3!=FILE)and env.variant())or 0 ret=self.__class__.bld.cache_node_abspath[variant].get(self.id,None) if ret:return ret if not variant: if not self.parent: val=os.sep=='/'and os.sep or'' elif not self.parent.name: val=(os.sep=='/'and os.sep or'')+self.name else: val=self.parent.abspath()+os.sep+self.name else: val=os.sep.join((self.__class__.bld.bldnode.abspath(),env.variant(),self.path_to_parent(self.__class__.bld.srcnode))) self.__class__.bld.cache_node_abspath[variant][self.id]=val return val def change_ext(self,ext): name=self.name k=name.rfind('.') if k>=0: name=name[:k]+ext else: name=name+ext return self.parent.find_or_declare([name]) def src_dir(self,env): return self.parent.srcpath(env) def bld_dir(self,env): return self.parent.bldpath(env) def bld_base(self,env): s=os.path.splitext(self.name)[0] return os.path.join(self.bld_dir(env),s) def bldpath(self,env=None): if self.id&3==FILE: return self.relpath_gen(self.__class__.bld.bldnode) if self.path_to_parent(self.__class__.bld.srcnode)is not'': return os.path.join(env.variant(),self.path_to_parent(self.__class__.bld.srcnode)) return env.variant() def srcpath(self,env=None): if self.id&3==BUILD: return self.bldpath(env) return self.relpath_gen(self.__class__.bld.bldnode) def read(self,env): return Utils.readf(self.abspath(env)) def dir(self,env): return self.parent.abspath(env) def file(self): return self.name def file_base(self): return os.path.splitext(self.name)[0] def suffix(self): k=max(0,self.name.rfind('.')) return self.name[k:] def find_iter_impl(self,src=True,bld=True,dir=True,accept_name=None,is_prune=None,maxdepth=25): self.__class__.bld.rescan(self) for name in self.__class__.bld.cache_dir_contents[self.id]: if accept_name(self,name): node=self.find_resource(name) if node: if src and node.id&3==FILE: yield node else: node=self.find_dir(name) if node and node.id!=self.__class__.bld.bldnode.id: if dir: yield node if not is_prune(self,name): if maxdepth: for k in node.find_iter_impl(src,bld,dir,accept_name,is_prune,maxdepth=maxdepth-1): yield k else: if not is_prune(self,name): node=self.find_resource(name) if not node: node=self.find_dir(name) if node and node.id!=self.__class__.bld.bldnode.id: if dir: yield node if maxdepth: for k in node.find_iter_impl(src,bld,dir,accept_name,is_prune,maxdepth=maxdepth-1): yield k if bld: for node in self.childs.values(): if node.id==self.__class__.bld.bldnode.id: continue if node.id&3==BUILD: if accept_name(self,node.name): yield node raise StopIteration def find_iter(self,in_pat=['*'],ex_pat=[],prune_pat=['.svn'],src=True,bld=True,dir=False,maxdepth=25,flat=False): if not(src or bld or dir): raise StopIteration if self.id&3!=DIR: raise StopIteration in_pat=Utils.to_list(in_pat) ex_pat=Utils.to_list(ex_pat) prune_pat=Utils.to_list(prune_pat) def accept_name(node,name): for pat in ex_pat: if fnmatch.fnmatchcase(name,pat): return False for pat in in_pat: if fnmatch.fnmatchcase(name,pat): return True return False def is_prune(node,name): for pat in prune_pat: if fnmatch.fnmatchcase(name,pat): return True return False ret=self.find_iter_impl(src,bld,dir,accept_name,is_prune,maxdepth=maxdepth) if flat: return" ".join([x.relpath_gen(self)for x in ret]) return ret def ant_glob(self,*k,**kw): regex=Utils.jar_regexp(k[0]) def accept(node,name): ts=node.relpath_gen(self)+'/'+name return regex.match(ts) def reject(node,name): ts=node.relpath_gen(self)+'/'+name return default_excludes()(ts) ret=[x for x in self.find_iter_impl(accept_name=accept,is_prune=reject,src=kw.get('src',1),bld=kw.get('bld',1),dir=kw.get('dir',0),maxdepth=kw.get('maxdepth',25))] if kw.get('flat',True): return" ".join([x.relpath_gen(self)for x in ret]) return ret class Nodu(Node): pass slv2-0.6.6+dfsg1/wafadmin/Tools/0000755000175000017500000000000011703115001016144 5ustar alessioalessioslv2-0.6.6+dfsg1/wafadmin/Tools/gcc.py0000644000175000017500000000467611176703511017304 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys import Configure,Options,Utils,TaskGen import ccroot,ar from Configure import conftest def find_gcc(conf): v=conf.env cc=None if v['CC']: cc=v['CC'] elif'CC'in conf.environ: cc=conf.environ['CC'] if not cc:cc=conf.find_program('gcc',var='CC') if not cc:cc=conf.find_program('cc',var='CC') if not cc:conf.fatal('gcc was not found') cc=conf.cmd_to_list(cc) ccroot.get_cc_version(conf,cc,gcc=True) v['CC_NAME']='gcc' v['CC']=cc def gcc_common_flags(conf): v=conf.env v['CC_SRC_F']='' v['CC_TGT_F']=['-c','-o',''] v['CPPPATH_ST']='-I%s' if not v['LINK_CC']:v['LINK_CC']=v['CC'] v['CCLNK_SRC_F']='' v['CCLNK_TGT_F']=['-o',''] v['LIB_ST']='-l%s' v['LIBPATH_ST']='-L%s' v['STATICLIB_ST']='-l%s' v['STATICLIBPATH_ST']='-L%s' v['RPATH_ST']='-Wl,-rpath,%s' v['CCDEFINES_ST']='-D%s' v['SONAME_ST']='-Wl,-h,%s' v['SHLIB_MARKER']='-Wl,-Bdynamic' v['STATICLIB_MARKER']='-Wl,-Bstatic' v['FULLSTATIC_MARKER']='-static' v['program_PATTERN']='%s' v['shlib_CCFLAGS']=['-fPIC','-DPIC'] v['shlib_LINKFLAGS']=['-shared'] v['shlib_PATTERN']='lib%s.so' v['staticlib_LINKFLAGS']=['-Wl,-Bstatic'] v['staticlib_PATTERN']='lib%s.a' v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup'] v['CCFLAGS_MACBUNDLE']=['-fPIC'] v['macbundle_PATTERN']='%s.bundle' def gcc_modifier_win32(conf): v=conf.env v['program_PATTERN']='%s.exe' v['shlib_PATTERN']='%s.dll' v['staticlib_PATTERN']='%s.lib' v['shlib_CCFLAGS']=[] v['staticlib_LINKFLAGS']=[] def gcc_modifier_cygwin(conf): return conf.gcc_modifier_win32() def gcc_modifier_darwin(conf): v=conf.env v['shlib_CCFLAGS']=['-fPIC','-compatibility_version','1','-current_version','1'] v['shlib_LINKFLAGS']=['-dynamiclib'] v['shlib_PATTERN']='lib%s.dylib' v['staticlib_LINKFLAGS']=[] v['SHLIB_MARKER']='' v['STATICLIB_MARKER']='' def gcc_modifier_aix5(conf): v=conf.env v['program_LINKFLAGS']=['-Wl,-brtl'] v['shlib_LINKFLAGS']=['-shared','-Wl,-brtl,-bexpfull'] v['SHLIB_MARKER']='' def detect(conf): conf.find_gcc() conf.find_cpp() conf.find_ar() conf.gcc_common_flags() target_platform=conf.env['TARGET_PLATFORM']or sys.platform gcc_modifier_func=globals().get('gcc_modifier_'+target_platform) if gcc_modifier_func: gcc_modifier_func(conf) conf.cc_load_tools() conf.cc_add_flags() conftest(find_gcc) conftest(gcc_common_flags) conftest(gcc_modifier_win32) conftest(gcc_modifier_cygwin) conftest(gcc_modifier_darwin) conftest(gcc_modifier_aix5) slv2-0.6.6+dfsg1/wafadmin/Tools/suncc.py0000644000175000017500000000241611176703511017651 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,optparse import Utils,Options,Configure import ccroot,ar from Configure import conftest def find_scc(conf): v=conf.env cc=None if v['CC']:cc=v['CC'] elif'CC'in conf.environ:cc=conf.environ['CC'] if not cc:cc=conf.find_program('cc',var='CC') if not cc:conf.fatal('suncc was not found') try: if not Utils.cmd_output('%s -flags'%cc): conf.fatal('suncc %r was not found'%cc) except ValueError: conf.fatal('suncc -flags could not be executed') v['CC']=cc v['CC_NAME']='sun' def scc_common_flags(conf): v=conf.env v['CC_SRC_F']='' v['CC_TGT_F']=['-c','-o',''] v['CPPPATH_ST']='-I%s' if not v['LINK_CC']:v['LINK_CC']=v['CC'] v['CCLNK_SRC_F']='' v['CCLNK_TGT_F']=['-o',''] v['LIB_ST']='-l%s' v['LIBPATH_ST']='-L%s' v['STATICLIB_ST']='-l%s' v['STATICLIBPATH_ST']='-L%s' v['CCDEFINES_ST']='-D%s' v['SONAME_ST']='-Wl,-h -Wl,%s' v['SHLIB_MARKER']='-Bdynamic' v['STATICLIB_MARKER']='-Bstatic' v['program_PATTERN']='%s' v['shlib_CCFLAGS']=['-Kpic','-DPIC'] v['shlib_LINKFLAGS']=['-G'] v['shlib_PATTERN']='lib%s.so' v['staticlib_LINKFLAGS']=['-Bstatic'] v['staticlib_PATTERN']='lib%s.a' detect=''' find_scc find_cpp find_ar scc_common_flags cc_load_tools cc_add_flags ''' conftest(find_scc) conftest(scc_common_flags) slv2-0.6.6+dfsg1/wafadmin/Tools/gas.py0000644000175000017500000000230011176703511017300 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys import Task from TaskGen import extension,taskgen,after,before EXT_ASM=['.s','.S','.asm','.ASM','.spp','.SPP'] as_str='${AS} ${ASFLAGS} ${_ASINCFLAGS} ${SRC} -o ${TGT}' Task.simple_task_type('asm',as_str,'PINK',ext_out='.o',shell=False) def asm_hook(self,node): task=self.create_task('asm') try:obj_ext=self.obj_ext except AttributeError:obj_ext='_%d.o'%self.idx task.inputs=[node] task.outputs=[node.change_ext(obj_ext)] self.compiled_tasks.append(task) self.meths.append('asm_incflags') def asm_incflags(self): if self.env['ASINCFLAGS']:self.env['_ASINCFLAGS']=self.env['ASINCFLAGS'] if'cxx'in self.features:self.env['_ASINCFLAGS']=self.env['_CXXINCFLAGS'] else:self.env['_ASINCFLAGS']=self.env['_CCINCFLAGS'] def detect(conf): comp=conf.environ.get('AS','') if not comp:comp=conf.env['AS'] if not comp:comp=conf.find_program('as',var='AS') if not comp:comp=conf.find_program('gas',var='AS') if not comp:comp=conf.env['CC'] if not comp:return v=conf.env v['ASFLAGS']='' extension(EXT_ASM)(asm_hook) taskgen(asm_incflags) after('apply_obj_vars_cc')(asm_incflags) after('apply_obj_vars_cxx')(asm_incflags) before('apply_link')(asm_incflags) slv2-0.6.6+dfsg1/wafadmin/Tools/compiler_cc.py0000644000175000017500000000300011176703511021003 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,imp,types,ccroot import optparse import Utils,Configure,Options c_compiler={'win32':['msvc','gcc'],'cygwin':['gcc'],'darwin':['gcc'],'aix5':['gcc'],'linux':['gcc','icc','suncc'],'sunos':['gcc','suncc'],'irix':['gcc'],'hpux':['gcc'],'default':['gcc']} def __list_possible_compiler(platform): try: return c_compiler[platform] except KeyError: return c_compiler["default"] def detect(conf): try:test_for_compiler=Options.options.check_c_compiler except AttributeError:conf.fatal("Add set_options(opt): opt.tool_options('compiler_cc')") for c_compiler in test_for_compiler.split(): try: conf.check_tool(c_compiler) except Configure.ConfigurationError: pass else: if conf.env['CC']: conf.check_message("%s"%c_compiler,'',True) conf.env["COMPILER_CC"]="%s"%c_compiler return conf.check_message("%s"%c_compiler,'',False) break conf.env["COMPILER_CC"]=None def set_options(opt): detected_platform=Options.platform possible_compiler_list=__list_possible_compiler(detected_platform) test_for_compiler=str(" ").join(possible_compiler_list) cc_compiler_opts=opt.add_option_group("C Compiler Options") cc_compiler_opts.add_option('--check-c-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C-Compiler will be checked by default: "%s"'%(detected_platform,test_for_compiler),dest="check_c_compiler") for c_compiler in test_for_compiler.split(): opt.tool_options('%s'%c_compiler,option_group=cc_compiler_opts) slv2-0.6.6+dfsg1/wafadmin/Tools/ocaml.py0000644000175000017500000002054111176703511017630 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,re import TaskGen,Utils,Task,Build from Logs import error from TaskGen import taskgen,feature,before,after,extension EXT_MLL=['.mll'] EXT_MLY=['.mly'] EXT_MLI=['.mli'] EXT_MLC=['.c'] EXT_ML=['.ml'] open_re=re.compile('^\s*open\s+([a-zA-Z]+)(;;){0,1}$',re.M) foo=re.compile(r"""(\(\*)|(\*\))|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^()*"'\\]*)""",re.M) def filter_comments(txt): meh=[0] def repl(m): if m.group(1):meh[0]+=1 elif m.group(2):meh[0]-=1 elif not meh[0]:return m.group(0) return'' return foo.sub(repl,txt) def scan(self): node=self.inputs[0] code=filter_comments(node.read(self.env)) global open_re names=[] import_iterator=open_re.finditer(code) if import_iterator: for import_match in import_iterator: names.append(import_match.group(1)) found_lst=[] raw_lst=[] for name in names: nd=None for x in self.incpaths: nd=x.find_resource(name.lower()+'.ml') if not nd:nd=x.find_resource(name+'.ml') if nd: found_lst.append(nd) break else: raw_lst.append(name) return(found_lst,raw_lst) native_lst=['native','all','c_object'] bytecode_lst=['bytecode','all'] class ocaml_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def init_ml(self): Utils.def_attrs(self,type='all',incpaths_lst=[],bld_incpaths_lst=[],mlltasks=[],mlytasks=[],mlitasks=[],native_tasks=[],bytecode_tasks=[],linktasks=[],bytecode_env=None,native_env=None,compiled_tasks=[],includes='',uselib='',are_deps_set=0) def init_envs_ml(self): self.islibrary=getattr(self,'islibrary',False) global native_lst,bytecode_lst self.native_env=None if self.type in native_lst: self.native_env=self.env.copy() if self.islibrary:self.native_env['OCALINKFLAGS']='-a' self.bytecode_env=None if self.type in bytecode_lst: self.bytecode_env=self.env.copy() if self.islibrary:self.bytecode_env['OCALINKFLAGS']='-a' if self.type=='c_object': self.native_env.append_unique('OCALINKFLAGS_OPT','-output-obj') def apply_incpaths_ml(self): inc_lst=self.includes.split() lst=self.incpaths_lst for dir in inc_lst: node=self.path.find_dir(dir) if not node: error("node not found: "+str(dir)) continue self.bld.rescan(node) if not node in lst:lst.append(node) self.bld_incpaths_lst.append(node) def apply_vars_ml(self): for i in self.incpaths_lst: if self.bytecode_env: app=self.bytecode_env.append_value app('OCAMLPATH','-I') app('OCAMLPATH',i.srcpath(self.env)) app('OCAMLPATH','-I') app('OCAMLPATH',i.bldpath(self.env)) if self.native_env: app=self.native_env.append_value app('OCAMLPATH','-I') app('OCAMLPATH',i.bldpath(self.env)) app('OCAMLPATH','-I') app('OCAMLPATH',i.srcpath(self.env)) varnames=['INCLUDES','OCAMLFLAGS','OCALINKFLAGS','OCALINKFLAGS_OPT'] for name in self.uselib.split(): for vname in varnames: cnt=self.env[vname+'_'+name] if cnt: if self.bytecode_env:self.bytecode_env.append_value(vname,cnt) if self.native_env:self.native_env.append_value(vname,cnt) def apply_link_ml(self): if self.bytecode_env: ext=self.islibrary and'.cma'or'.run' linktask=self.create_task('ocalink') linktask.bytecode=1 linktask.set_outputs(self.path.find_or_declare(self.target+ext)) linktask.obj=self linktask.env=self.bytecode_env self.linktasks.append(linktask) if self.native_env: if self.type=='c_object':ext='.o' elif self.islibrary:ext='.cmxa' else:ext='' linktask=self.create_task('ocalinkx') linktask.set_outputs(self.path.find_or_declare(self.target+ext)) linktask.obj=self linktask.env=self.native_env self.linktasks.append(linktask) self.compiled_tasks.append(linktask) def mll_hook(self,node): mll_task=self.create_task('ocamllex',self.native_env) mll_task.set_inputs(node) mll_task.set_outputs(node.change_ext('.ml')) self.mlltasks.append(mll_task) self.allnodes.append(mll_task.outputs[0]) def mly_hook(self,node): mly_task=self.create_task('ocamlyacc',self.native_env) mly_task.set_inputs(node) mly_task.set_outputs([node.change_ext('.ml'),node.change_ext('.mli')]) self.mlytasks.append(mly_task) self.allnodes.append(mly_task.outputs[0]) task=self.create_task('ocamlcmi',self.native_env) task.set_inputs(mly_task.outputs[1]) task.set_outputs(mly_task.outputs[1].change_ext('.cmi')) def mli_hook(self,node): task=self.create_task('ocamlcmi',self.native_env) task.set_inputs(node) task.set_outputs(node.change_ext('.cmi')) self.mlitasks.append(task) def mlc_hook(self,node): task=self.create_task('ocamlcc',self.native_env) task.set_inputs(node) task.set_outputs(node.change_ext('.o')) self.compiled_tasks.append(task) def ml_hook(self,node): if self.native_env: task=self.create_task('ocamlx',self.native_env) task.set_inputs(node) task.set_outputs(node.change_ext('.cmx')) task.obj=self task.incpaths=self.bld_incpaths_lst self.native_tasks.append(task) if self.bytecode_env: task=self.create_task('ocaml',self.bytecode_env) task.set_inputs(node) task.obj=self task.bytecode=1 task.incpaths=self.bld_incpaths_lst task.set_outputs(node.change_ext('.cmo')) self.bytecode_tasks.append(task) def compile_may_start(self): if not getattr(self,'flag_deps',''): self.flag_deps=1 if getattr(self,'bytecode',''):alltasks=self.obj.bytecode_tasks else:alltasks=self.obj.native_tasks self.signature() tree=self.generator.bld env=self.env for node in self.inputs: lst=tree.node_deps[self.unique_id()] for depnode in lst: for t in alltasks: if t==self:continue if depnode in t.inputs: self.set_run_after(t) delattr(self,'cache_sig') self.signature() return Task.Task.runnable_status(self) b=Task.simple_task_type cls=b('ocamlx','${OCAMLOPT} ${OCAMLPATH} ${OCAMLFLAGS} ${INCLUDES} -c -o ${TGT} ${SRC}',color='GREEN',shell=False) cls.runnable_status=compile_may_start cls.scan=scan b=Task.simple_task_type cls=b('ocaml','${OCAMLC} ${OCAMLPATH} ${OCAMLFLAGS} ${INCLUDES} -c -o ${TGT} ${SRC}',color='GREEN',shell=False) cls.runnable_status=compile_may_start cls.scan=scan b('ocamlcmi','${OCAMLC} ${OCAMLPATH} ${INCLUDES} -o ${TGT} -c ${SRC}',color='BLUE',before="ocaml ocamlcc ocamlx") b('ocamlcc','cd ${TGT[0].bld_dir(env)} && ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLPATH} ${INCLUDES} -c ${SRC[0].abspath(env)}',color='GREEN') b('ocamllex','${OCAMLLEX} ${SRC} -o ${TGT}',color='BLUE',before="ocamlcmi ocaml ocamlcc") b('ocamlyacc','${OCAMLYACC} -b ${TGT[0].bld_base(env)} ${SRC}',color='BLUE',before="ocamlcmi ocaml ocamlcc") def link_may_start(self): if not getattr(self,'order',''): if getattr(self,'bytecode',0):alltasks=self.obj.bytecode_tasks else:alltasks=self.obj.native_tasks seen=[] pendant=[]+alltasks while pendant: task=pendant.pop(0) if task in seen:continue for x in task.run_after: if not x in seen: pendant.append(task) break else: seen.append(task) self.inputs=[x.outputs[0]for x in seen] self.order=1 return Task.Task.runnable_status(self) act=b('ocalink','${OCAMLC} -o ${TGT} ${INCLUDES} ${OCALINKFLAGS} ${SRC}',color='YELLOW',after="ocaml ocamlcc") act.runnable_status=link_may_start act=b('ocalinkx','${OCAMLOPT} -o ${TGT} ${INCLUDES} ${OCALINKFLAGS_OPT} ${SRC}',color='YELLOW',after="ocamlx ocamlcc") act.runnable_status=link_may_start def detect(conf): opt=conf.find_program('ocamlopt',var='OCAMLOPT') occ=conf.find_program('ocamlc',var='OCAMLC') if(not opt)or(not occ): conf.fatal('The objective caml compiler was not found:\ninstall it or make it available in your PATH') conf.env['OCAMLC']=occ conf.env['OCAMLOPT']=opt conf.env['OCAMLLEX']=conf.find_program('ocamllex',var='OCAMLLEX') conf.env['OCAMLYACC']=conf.find_program('ocamlyacc',var='OCAMLYACC') conf.env['OCAMLFLAGS']='' conf.env['OCAMLLIB']=Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep conf.env['LIBPATH_OCAML']=Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep conf.env['CPPPATH_OCAML']=Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep conf.env['LIB_OCAML']='camlrun' feature('ocaml')(init_ml) feature('ocaml')(init_envs_ml) after('init_ml')(init_envs_ml) feature('ocaml')(apply_incpaths_ml) before('apply_vars_ml')(apply_incpaths_ml) after('init_envs_ml')(apply_incpaths_ml) feature('ocaml')(apply_vars_ml) before('apply_core')(apply_vars_ml) feature('ocaml')(apply_link_ml) after('apply_core')(apply_link_ml) extension(EXT_MLL)(mll_hook) extension(EXT_MLY)(mly_hook) extension(EXT_MLI)(mli_hook) extension(EXT_MLC)(mlc_hook) extension(EXT_ML)(ml_hook) slv2-0.6.6+dfsg1/wafadmin/Tools/flex.py0000644000175000017500000000057011176703511017473 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import TaskGen def decide_ext(self,node): if'cxx'in self.features:return'.lex.cc' else:return'.lex.c' TaskGen.declare_chain(name='flex',rule='${FLEX} -o${TGT} ${FLEXFLAGS} ${SRC}',ext_in='.l',decider=decide_ext,before='cc cxx',) def detect(conf): conf.find_program('flex',var='FLEX',mandatory=True) v=conf.env v['FLEXFLAGS']='' slv2-0.6.6+dfsg1/wafadmin/Tools/suncxx.py0000644000175000017500000000225711176703511020071 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,optparse import Utils,Options,Configure import ccroot,ar from Configure import conftest def find_sxx(conf): v=conf.env cc=None if v['CXX']:cc=v['CXX'] elif'CXX'in conf.environ:cc=conf.environ['CXX'] if not cc:cc=conf.find_program('c++',var='CXX') if not cc:cc=conf.find_program('CC',var='CXX') if not cc:conf.fatal('sunc++ was not found') v['CXX']=cc v['CXX_NAME']='sun' def sxx_common_flags(conf): v=conf.env v['CXX_SRC_F']='' v['CXX_TGT_F']=['-c','-o',''] v['CPPPATH_ST']='-I%s' if not v['LINK_CXX']:v['LINK_CXX']=v['CXX'] v['CXXLNK_SRC_F']='' v['CXXLNK_TGT_F']=['-o',''] v['LIB_ST']='-l%s' v['LIBPATH_ST']='-L%s' v['STATICLIB_ST']='-l%s' v['STATICLIBPATH_ST']='-L%s' v['CXXDEFINES_ST']='-D%s' v['SONAME_ST']='-Wl,-h -Wl,%s' v['SHLIB_MARKER']='-Bdynamic' v['STATICLIB_MARKER']='-Bstatic' v['program_PATTERN']='%s' v['shlib_CXXFLAGS']=['-Kpic','-DPIC'] v['shlib_LINKFLAGS']=['-G'] v['shlib_PATTERN']='lib%s.so' v['staticlib_LINKFLAGS']=['-Bstatic'] v['staticlib_PATTERN']='lib%s.a' detect=''' find_sxx find_cpp find_ar sxx_common_flags cxx_load_tools cxx_add_flags ''' conftest(find_sxx) conftest(sxx_common_flags) slv2-0.6.6+dfsg1/wafadmin/Tools/compiler_cxx.py0000644000175000017500000000310211176703511021223 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,imp,types,ccroot import optparse import Utils,Configure,Options cxx_compiler={'win32':['msvc','g++'],'cygwin':['g++'],'darwin':['g++'],'aix5':['g++'],'linux':['g++','icpc','sunc++'],'sunos':['g++','sunc++'],'irix':['g++'],'hpux':['g++'],'default':['g++']} def __list_possible_compiler(platform): try: return(cxx_compiler[platform]) except KeyError: return(cxx_compiler["default"]) def detect(conf): try:test_for_compiler=Options.options.check_cxx_compiler except AttributeError:raise Configure.ConfigurationError("Add set_options(opt): opt.tool_options('compiler_cxx')") for cxx_compiler in test_for_compiler.split(): try: conf.check_tool(cxx_compiler) except Configure.ConfigurationError: pass else: if conf.env['CXX']: conf.check_message("%s"%cxx_compiler,'',True) conf.env["COMPILER_CXX"]="%s"%cxx_compiler return conf.check_message("%s"%cxx_compiler,'',False) break conf.env["COMPILER_CXX"]=None def set_options(opt): detected_platform=Options.platform possible_compiler_list=__list_possible_compiler(detected_platform) test_for_compiler=str(" ").join(possible_compiler_list) cxx_compiler_opts=opt.add_option_group("C++ Compiler Options") cxx_compiler_opts.add_option('--check-cxx-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"'%(detected_platform,test_for_compiler),dest="check_cxx_compiler") for cxx_compiler in test_for_compiler.split(): opt.tool_options('%s'%cxx_compiler,option_group=cxx_compiler_opts) slv2-0.6.6+dfsg1/wafadmin/Tools/osx.py0000644000175000017500000001061411176703511017346 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,shutil,sys,platform import TaskGen,Task,Build,Options from TaskGen import taskgen,feature,after,before from Logs import error,debug def set_macosx_deployment_target(self): if self.env['MACOSX_DEPLOYMENT_TARGET']: os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env['MACOSX_DEPLOYMENT_TARGET'] elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ: if sys.platform=='darwin': os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2]) def apply_framework(self): for x in self.to_list(self.env['FRAMEWORKPATH']): frameworkpath_st='-F%s' self.env.append_unique('CXXFLAGS',frameworkpath_st%x) self.env.append_unique('CCFLAGS',frameworkpath_st%x) self.env.append_unique('LINKFLAGS',frameworkpath_st%x) for x in self.to_list(self.env['FRAMEWORK']): self.env.append_value('LINKFLAGS',['-framework',x]) def create_task_macapp(self): if'cprogram'in self.features and self.link_task: apptask=self.create_task('macapp',self.env) apptask.set_inputs(self.link_task.outputs) apptask.set_outputs(self.link_task.outputs[0].change_ext('.app')) self.apptask=apptask def apply_link_osx(self): if self.env['MACAPP']or getattr(self,'mac_app',False): self.create_task_macapp() name=self.link_task.outputs[0].name if getattr(self,'vnum',None): name=name.replace('.dylib','.%s.dylib'%self.vnum) path=os.path.join(self.env['PREFIX'],'lib',name) self.env.append_value('LINKFLAGS','-install_name') self.env.append_value('LINKFLAGS',path) def apply_bundle(self): if not('cshlib'in self.features or'shlib'in self.features):return if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False): self.env['shlib_PATTERN']=self.env['macbundle_PATTERN'] uselib=self.uselib=self.to_list(self.uselib) if not'MACBUNDLE'in uselib:uselib.append('MACBUNDLE') def apply_bundle_remove_dynamiclib(self): if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False): if not getattr(self,'vnum',None): try: self.env['LINKFLAGS'].remove('-dynamiclib') except ValueError: pass app_dirs=['Contents',os.path.join('Contents','MacOS'),os.path.join('Contents','Resources')] app_info=''' CFBundlePackageType APPL CFBundleGetInfoString Created by Waf CFBundleSignature ???? NOTE THIS IS A GENERATED FILE, DO NOT MODIFY CFBundleExecutable %s ''' def app_build(task): global app_dirs env=task.env i=0 for p in task.outputs: srcfile=p.srcpath(env) debug('osx: creating directories') try: os.mkdir(srcfile) [os.makedirs(os.path.join(srcfile,d))for d in app_dirs] except(OSError,IOError): pass srcprg=task.inputs[i].srcpath(env) dst=os.path.join(srcfile,'Contents','MacOS') debug('osx: copy %s to %s'%(srcprg,dst)) shutil.copy(srcprg,dst) debug('osx: generate Info.plist') f=open(os.path.join(srcfile,"Contents","Info.plist"),"w") f.write(app_info%os.path.basename(srcprg)) f.close() i+=1 return 0 def install_shlib(task): nums=task.vnum.split('.') path=self.install_path libname=task.outputs[0].name name3=libname.replace('.dylib','.%s.dylib'%task.vnum) name2=libname.replace('.dylib','.%s.dylib'%nums[0]) name1=libname filename=task.outputs[0].abspath(task.env) bld=task.outputs[0].__class__.bld bld.install_as(path+name3,filename,env=task.env) bld.symlink_as(path+name2,name3) bld.symlink_as(path+name1,name3) def install_target_osx_cshlib(self): if not self.bld.is_install:return if getattr(self,'vnum','')and sys.platform!='win32': self.link_task.install=install_shlib Task.task_type_from_func('macapp',vars=[],func=app_build,after="cxx_link cc_link ar_link_static") feature('cc','cxx')(set_macosx_deployment_target) before('apply_lib_vars')(set_macosx_deployment_target) feature('cc','cxx')(apply_framework) after('apply_lib_vars')(apply_framework) taskgen(create_task_macapp) after('apply_link')(apply_link_osx) feature('cc','cxx')(apply_link_osx) before('apply_link','apply_lib_vars')(apply_bundle) feature('cc','cxx')(apply_bundle) after('apply_link')(apply_bundle_remove_dynamiclib) feature('cshlib')(apply_bundle_remove_dynamiclib) feature('osx')(install_target_osx_cshlib) after('install_target_cshlib')(install_target_osx_cshlib) slv2-0.6.6+dfsg1/wafadmin/Tools/cxx.py0000644000175000017500000000524411176703511017342 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import TaskGen,Task,Utils from Logs import debug import ccroot from TaskGen import feature,before,extension,after g_cxx_flag_vars=['CXXDEPS','FRAMEWORK','FRAMEWORKPATH','STATICLIB','LIB','LIBPATH','LINKFLAGS','RPATH','CXXFLAGS','CCFLAGS','CPPPATH','CPPFLAGS','CXXDEFINES'] EXT_CXX=['.cpp','.cc','.cxx','.C','.c++'] g_cxx_type_vars=['CXXFLAGS','LINKFLAGS'] class cxx_taskgen(ccroot.ccroot_abstract): pass def init_cxx(self): if not'cc'in self.features: self.mappings['.c']=TaskGen.task_gen.mappings['.cxx'] self.p_flag_vars=set(self.p_flag_vars).union(g_cxx_flag_vars) self.p_type_vars=set(self.p_type_vars).union(g_cxx_type_vars) if not self.env['CXX_NAME']: raise Utils.WafError("At least one compiler (g++, ..) must be selected") def apply_obj_vars_cxx(self): env=self.env app=env.append_unique cxxpath_st=env['CPPPATH_ST'] for i in env['INC_PATHS']: app('_CXXINCFLAGS',cxxpath_st%i.bldpath(env)) app('_CXXINCFLAGS',cxxpath_st%i.srcpath(env)) for i in env['CPPPATH']: app('_CXXINCFLAGS',cxxpath_st%i) def apply_defines_cxx(self): self.defines=getattr(self,'defines',[]) lst=self.to_list(self.defines)+self.to_list(self.env['CXXDEFINES']) milst=[] for defi in lst: if not defi in milst: milst.append(defi) libs=self.to_list(self.uselib) for l in libs: val=self.env['CXXDEFINES_'+l] if val:milst+=self.to_list(val) self.env['DEFLINES']=["%s %s"%(x[0],Utils.trimquotes('='.join(x[1:])))for x in[y.split('=')for y in milst]] y=self.env['CXXDEFINES_ST'] self.env['_CXXDEFFLAGS']=[y%x for x in milst] def cxx_hook(self,node): task=self.create_task('cxx') if getattr(self,'obj_ext',None): obj_ext=self.obj_ext else: obj_ext='_%d.o'%self.idx task.inputs=[node] task.outputs=[node.change_ext(obj_ext)] self.compiled_tasks.append(task) return task cxx_str='${CXX} ${CXXFLAGS} ${CPPFLAGS} ${_CXXINCFLAGS} ${_CXXDEFFLAGS} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}' cls=Task.simple_task_type('cxx',cxx_str,color='GREEN',ext_out='.o',ext_in='.cxx',shell=False) cls.scan=ccroot.scan cls.vars.append('CXXDEPS') link_str='${LINK_CXX} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT} ${LINKFLAGS}' cls=Task.simple_task_type('cxx_link',link_str,color='YELLOW',ext_in='.o',shell=False) cls.maxjobs=1 cls2=Task.task_type_from_func('vnum_cxx_link',ccroot.link_vnum,cls.vars,color='CYAN',ext_in='.o') cls2.maxjobs=1 feature('cxx')(init_cxx) before('apply_type_vars')(init_cxx) after('default_cc')(init_cxx) feature('cxx')(apply_obj_vars_cxx) after('apply_incpaths')(apply_obj_vars_cxx) feature('cxx')(apply_defines_cxx) after('apply_lib_vars')(apply_defines_cxx) extension(EXT_CXX)(cxx_hook) slv2-0.6.6+dfsg1/wafadmin/Tools/libtool.py0000644000175000017500000001744011176703511020205 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys,re,os,optparse import TaskGen,Task,Utils,preproc from Logs import error,debug,warn from TaskGen import taskgen,after,before,feature REVISION="0.1.3" fakelibtool_vardeps=['CXX','PREFIX'] def fakelibtool_build(task): env=task.env dest=open(task.outputs[0].abspath(env),'w') sname=task.inputs[0].name fu=dest.write fu("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by BKsys II code name WAF)\n") if env['vnum']: nums=env['vnum'].split('.') libname=task.inputs[0].name name3=libname+'.'+env['vnum'] name2=libname+'.'+nums[0] name1=libname fu("dlname='%s'\n"%name2) strn=" ".join([name3,name2,name1]) fu("library_names='%s'\n"%(strn)) else: fu("dlname='%s'\n"%sname) fu("library_names='%s %s %s'\n"%(sname,sname,sname)) fu("old_library=''\n") vars=' '.join(env['libtoolvars']+env['LINKFLAGS']) fu("dependency_libs='%s'\n"%vars) fu("current=0\n") fu("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n") fu("dlopen=''\ndlpreopen=''\n") fu("libdir='%s/lib'\n"%env['PREFIX']) dest.close() return 0 def read_la_file(path): sp=re.compile(r'^([^=]+)=\'(.*)\'$') dc={} file=open(path,"r") for line in file.readlines(): try: _,left,right,_=sp.split(line.strip()) dc[left]=right except ValueError: pass file.close() return dc def apply_link_libtool(self): if self.type!='program': linktask=self.link_task latask=self.create_task('fakelibtool') latask.set_inputs(linktask.outputs) latask.set_outputs(linktask.outputs[0].change_ext('.la')) self.latask=latask if self.bld.is_install: self.bld.install_files('${PREFIX}/lib',linktask.outputs[0].abspath(self.env),self.env) def apply_libtool(self): self.env['vnum']=self.vnum paths=[] libs=[] libtool_files=[] libtool_vars=[] for l in self.env['LINKFLAGS']: if l[:2]=='-L': paths.append(l[2:]) elif l[:2]=='-l': libs.append(l[2:]) for l in libs: for p in paths: dict=read_la_file(p+'/lib'+l+'.la') linkflags2=dict.get('dependency_libs','') for v in linkflags2.split(): if v.endswith('.la'): libtool_files.append(v) libtool_vars.append(v) continue self.env.append_unique('LINKFLAGS',v) break self.env['libtoolvars']=libtool_vars while libtool_files: file=libtool_files.pop() dict=read_la_file(file) for v in dict['dependency_libs'].split(): if v[-3:]=='.la': libtool_files.append(v) continue self.env.append_unique('LINKFLAGS',v) Task.task_type_from_func('fakelibtool',vars=fakelibtool_vardeps,func=fakelibtool_build,color='BLUE',after="cc_link cxx_link ar_link_static") class libtool_la_file: def __init__(self,la_filename): self.__la_filename=la_filename self.linkname=str(os.path.split(la_filename)[-1])[:-3] if self.linkname.startswith("lib"): self.linkname=self.linkname[3:] self.dlname=None self.library_names=None self.old_library=None self.dependency_libs=None self.current=None self.age=None self.revision=None self.installed=None self.shouldnotlink=None self.dlopen=None self.dlpreopen=None self.libdir='/usr/lib' if not self.__parse(): raise"file %s not found!!"%(la_filename) def __parse(self): if not os.path.isfile(self.__la_filename):return 0 la_file=open(self.__la_filename,'r') for line in la_file: ln=line.strip() if not ln:continue if ln[0]=='#':continue (key,value)=str(ln).split('=',1) key=key.strip() value=value.strip() if value=="no":value=False elif value=="yes":value=True else: try:value=int(value) except ValueError:value=value.strip("'") setattr(self,key,value) la_file.close() return 1 def get_libs(self): libs=[] if self.dependency_libs: libs=str(self.dependency_libs).strip().split() if libs==None: libs=[] libs.insert(0,"-l%s"%self.linkname.strip()) libs.insert(0,"-L%s"%self.libdir.strip()) return libs def __str__(self): return'''\ dlname = "%(dlname)s" library_names = "%(library_names)s" old_library = "%(old_library)s" dependency_libs = "%(dependency_libs)s" version = %(current)s.%(age)s.%(revision)s installed = "%(installed)s" shouldnotlink = "%(shouldnotlink)s" dlopen = "%(dlopen)s" dlpreopen = "%(dlpreopen)s" libdir = "%(libdir)s"'''%self.__dict__ class libtool_config: def __init__(self,la_filename): self.__libtool_la_file=libtool_la_file(la_filename) tmp=self.__libtool_la_file self.__version=[int(tmp.current),int(tmp.age),int(tmp.revision)] self.__sub_la_files=[] self.__sub_la_files.append(la_filename) self.__libs=None def __cmp__(self,other): if not other: return 1 othervers=[int(s)for s in str(other).split(".")] selfvers=self.__version return cmp(selfvers,othervers) def __str__(self): return"\n".join([str(self.__libtool_la_file),' '.join(self.__libtool_la_file.get_libs()),'* New getlibs:',' '.join(self.get_libs())]) def __get_la_libs(self,la_filename): return libtool_la_file(la_filename).get_libs() def get_libs(self): libs_list=list(self.__libtool_la_file.get_libs()) libs_map={} while len(libs_list)>0: entry=libs_list.pop(0) if entry: if str(entry).endswith(".la"): if entry not in self.__sub_la_files: self.__sub_la_files.append(entry) libs_list.extend(self.__get_la_libs(entry)) else: libs_map[entry]=1 self.__libs=libs_map.keys() return self.__libs def get_libs_only_L(self): if not self.__libs:self.get_libs() libs=self.__libs libs=[s for s in libs if str(s).startswith('-L')] return libs def get_libs_only_l(self): if not self.__libs:self.get_libs() libs=self.__libs libs=[s for s in libs if str(s).startswith('-l')] return libs def get_libs_only_other(self): if not self.__libs:self.get_libs() libs=self.__libs libs=[s for s in libs if not(str(s).startswith('-L')or str(s).startswith('-l'))] return libs def useCmdLine(): usage='''Usage: %prog [options] PathToFile.la example: %prog --atleast-version=2.0.0 /usr/lib/libIlmImf.la nor: %prog --libs /usr/lib/libamarok.la''' parser=optparse.OptionParser(usage) a=parser.add_option a("--version",dest="versionNumber",action="store_true",default=False,help="output version of libtool-config") a("--debug",dest="debug",action="store_true",default=False,help="enable debug") a("--libs",dest="libs",action="store_true",default=False,help="output all linker flags") a("--libs-only-l",dest="libs_only_l",action="store_true",default=False,help="output -l flags") a("--libs-only-L",dest="libs_only_L",action="store_true",default=False,help="output -L flags") a("--libs-only-other",dest="libs_only_other",action="store_true",default=False,help="output other libs (e.g. -pthread)") a("--atleast-version",dest="atleast_version",default=None,help="return 0 if the module is at least version ATLEAST_VERSION") a("--exact-version",dest="exact_version",default=None,help="return 0 if the module is exactly version EXACT_VERSION") a("--max-version",dest="max_version",default=None,help="return 0 if the module is at no newer than version MAX_VERSION") (options,args)=parser.parse_args() if len(args)!=1 and not options.versionNumber: parser.error("incorrect number of arguments") if options.versionNumber: print("libtool-config version %s"%REVISION) return 0 ltf=libtool_config(args[0]) if options.debug: print(ltf) if options.atleast_version: if ltf>=options.atleast_version:return 0 sys.exit(1) if options.exact_version: if ltf==options.exact_version:return 0 sys.exit(1) if options.max_version: if ltf<=options.max_version:return 0 sys.exit(1) def p(x): print(" ".join(x)) if options.libs:p(ltf.get_libs()) elif options.libs_only_l:p(ltf.get_libs_only_l()) elif options.libs_only_L:p(ltf.get_libs_only_L()) elif options.libs_only_other:p(ltf.get_libs_only_other()) return 0 if __name__=='__main__': useCmdLine() feature("libtool")(apply_link_libtool) after('apply_link')(apply_link_libtool) feature("libtool")(apply_libtool) before('apply_core')(apply_libtool) slv2-0.6.6+dfsg1/wafadmin/Tools/kde4.py0000644000175000017500000000414411176703511017365 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,re import Options,TaskGen,Task,Utils from TaskGen import taskgen,feature,after class msgfmt_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def init_msgfmt(self): self.default_install_path='${KDE4_LOCALE_INSTALL_DIR}' def apply_msgfmt(self): for lang in self.to_list(self.langs): node=self.path.find_resource(lang+'.po') task=self.create_task('msgfmt') task.set_inputs(node) task.set_outputs(node.change_ext('.mo')) if not self.bld.is_install:continue langname=lang.split('/') langname=langname[-1] task.install_path=self.install_path+os.sep+langname+os.sep+'LC_MESSAGES' task.filename=getattr(self,'appname','set_your_appname')+'.mo' task.chmod=self.chmod def detect(conf): kdeconfig=conf.find_program('kde4-config') if not kdeconfig: conf.fatal('we need kde4-config') prefix=Utils.cmd_output('%s --prefix'%kdeconfig,silent=True).strip() file='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix try:os.stat(file) except OSError: file='%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake'%prefix try:os.stat(file) except OSError:conf.fatal('could not open %s'%file) try: txt=Utils.readf(file) except(OSError,IOError): conf.fatal('could not read %s'%file) txt=txt.replace('\\\n','\n') fu=re.compile('#(.*)\n') txt=fu.sub('',txt) setregexp=re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)') found=setregexp.findall(txt) for(_,key,val)in found: conf.env[key]=val conf.env['LIB_KDECORE']='kdecore' conf.env['LIB_KDEUI']='kdeui' conf.env['LIB_KIO']='kio' conf.env['LIB_KHTML']='khtml' conf.env['LIB_KPARTS']='kparts' conf.env['LIBPATH_KDECORE']=conf.env['KDE4_LIB_INSTALL_DIR'] conf.env['CPPPATH_KDECORE']=conf.env['KDE4_INCLUDE_INSTALL_DIR'] conf.env.append_value('CPPPATH_KDECORE',conf.env['KDE4_INCLUDE_INSTALL_DIR']+"/KDE") conf.env['MSGFMT']=conf.find_program('msgfmt') Task.simple_task_type('msgfmt','${MSGFMT} ${SRC} -o ${TGT}',color='BLUE',shell=False) feature('msgfmt')(init_msgfmt) feature('msgfmt')(apply_msgfmt) after('init_msgfmt')(apply_msgfmt) slv2-0.6.6+dfsg1/wafadmin/Tools/winres.py0000644000175000017500000000207711176703511020050 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,re import TaskGen,Task from Utils import quote_whitespace from TaskGen import extension EXT_WINRC=['.rc'] winrc_str='${WINRC} ${_CPPDEFFLAGS} ${_CCDEFFLAGS} ${WINRCFLAGS} ${_CPPINCFLAGS} ${_CCINCFLAGS} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' def rc_file(self,node): obj_ext='.rc.o' if self.env['WINRC_TGT_F']=='/fo':obj_ext='.res' rctask=self.create_task('winrc') rctask.set_inputs(node) rctask.set_outputs(node.change_ext(obj_ext)) self.compiled_tasks.append(rctask) Task.simple_task_type('winrc',winrc_str,color='BLUE',before='cc cxx',shell=False) def detect(conf): v=conf.env winrc=v['WINRC'] v['WINRC_TGT_F']='-o' v['WINRC_SRC_F']='-i' if not winrc: if v['CC_NAME']in['gcc','cc','g++','c++']: winrc=conf.find_program('windres',var='WINRC',path_list=v['PATH']) elif v['CC_NAME']=='msvc': winrc=conf.find_program('RC',var='WINRC',path_list=v['PATH']) v['WINRC_TGT_F']='/fo' v['WINRC_SRC_F']='' if not winrc: conf.fatal('winrc was not found!') v['WINRCFLAGS']='' extension(EXT_WINRC)(rc_file) slv2-0.6.6+dfsg1/wafadmin/Tools/qt4.py0000644000175000017500000002752111176703511017252 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 try: from xml.sax import make_parser from xml.sax.handler import ContentHandler except ImportError: has_xml=False ContentHandler=object else: has_xml=True import os,sys import ccroot,cxx import TaskGen,Task,Utils,Runner,Options,Node from TaskGen import taskgen,feature,after,extension from Logs import error from Constants import* MOC_H=['.h','.hpp','.hxx','.hh'] EXT_RCC=['.qrc'] EXT_UI=['.ui'] EXT_QT4=['.cpp','.cc','.cxx','.C'] class qxx_task(Task.Task): before=['cxx_link','ar_link_static'] def __init__(self,*k,**kw): Task.Task.__init__(self,*k,**kw) self.moc_done=0 def scan(self): (nodes,names)=ccroot.scan(self) for x in nodes: if x.name.endswith('.moc'): nodes.remove(x) names.append(x.relpath_gen(self.inputs[0].parent)) return(nodes,names) def runnable_status(self): if self.moc_done: for t in self.run_after: if not t.hasrun: return ASK_LATER self.signature() return Task.Task.runnable_status(self) else: for t in self.run_after: if not t.hasrun: return ASK_LATER self.add_moc_tasks() return ASK_LATER def add_moc_tasks(self): node=self.inputs[0] tree=node.__class__.bld try: self.signature() except KeyError: pass else: delattr(self,'cache_sig') moctasks=[] mocfiles=[] variant=node.variant(self.env) try: tmp_lst=tree.raw_deps[self.unique_id()] tree.raw_deps[self.unique_id()]=[] except KeyError: tmp_lst=[] for d in tmp_lst: if not d.endswith('.moc'):continue if d in mocfiles: error("paranoia owns") continue mocfiles.append(d) ext='' try:ext=Options.options.qt_header_ext except AttributeError:pass if not ext: base2=d[:-4] paths=[node.parent.srcpath(self.env),node.parent.bldpath(self.env)] poss=[(x,y)for x in MOC_H for y in paths] for(i,path)in poss: try: os.stat(os.path.join(path,base2+i)) except OSError: pass else: ext=i break if not ext:raise Utils.WafError("no header found for %s which is a moc file"%str(d)) h_node=node.parent.find_resource(base2+i) m_node=h_node.change_ext('.moc') tree.node_deps[(self.inputs[0].parent.id,self.env.variant(),m_node.name)]=h_node task=Task.TaskBase.classes['moc'](self.env,normal=0) task.set_inputs(h_node) task.set_outputs(m_node) generator=tree.generator generator.outstanding.insert(0,task) generator.total+=1 moctasks.append(task) tmp_lst=tree.raw_deps[self.unique_id()]=mocfiles lst=tree.node_deps.get(self.unique_id(),()) for d in lst: name=d.name if name.endswith('.moc'): task=Task.TaskBase.classes['moc'](self.env,normal=0) task.set_inputs(tree.node_deps[(self.inputs[0].parent.id,self.env.variant(),name)]) task.set_outputs(d) generator=tree.generator generator.outstanding.insert(0,task) generator.total+=1 moctasks.append(task) self.run_after=moctasks self.moc_done=1 run=Task.TaskBase.classes['cxx'].__dict__['run'] def translation_update(task): outs=[a.abspath(task.env)for a in task.outputs] outs=" ".join(outs) lupdate=task.env['QT_LUPDATE'] for x in task.inputs: file=x.abspath(task.env) cmd="%s %s -ts %s"%(lupdate,file,outs) Utils.pprint('BLUE',cmd) task.generator.bld.exec_command(cmd) class XMLHandler(ContentHandler): def __init__(self): self.buf=[] self.files=[] def startElement(self,name,attrs): if name=='file': self.buf=[] def endElement(self,name): if name=='file': self.files.append(''.join(self.buf)) def characters(self,cars): self.buf.append(cars) def scan(self): node=self.inputs[0] parser=make_parser() curHandler=XMLHandler() parser.setContentHandler(curHandler) fi=open(self.inputs[0].abspath(self.env)) parser.parse(fi) fi.close() nodes=[] names=[] root=self.inputs[0].parent for x in curHandler.files: x=x.encode('utf8') nd=root.find_resource(x) if nd:nodes.append(nd) else:names.append(x) return(nodes,names) def create_rcc_task(self,node): rcnode=node.change_ext('_rc.cpp') rcctask=self.create_task('rcc') rcctask.inputs=[node] rcctask.outputs=[rcnode] cpptask=self.create_task('cxx') cpptask.inputs=[rcnode] cpptask.outputs=[rcnode.change_ext('.o')] self.compiled_tasks.append(cpptask) return cpptask def create_uic_task(self,node): uictask=self.create_task('ui4') uictask.inputs=[node] uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])] class qt4_taskgen(cxx.cxx_taskgen): def __init__(self,*k,**kw): cxx.cxx_taskgen.__init__(self,*k,**kw) self.features.append('qt4') def add_lang(self,node): self.lang=self.to_list(getattr(self,'lang',[]))+[node] def apply_qt4(self): if getattr(self,'lang',None): update=getattr(self,'update',None) lst=[] trans=[] for l in self.to_list(self.lang): if not isinstance(l,Node.Node): l=self.path.find_resource(l+'.ts') t=self.create_task('ts2qm') t.set_inputs(l) t.set_outputs(l.change_ext('.qm')) lst.append(t.outputs[0]) if update: trans.append(t.inputs[0]) if update and Options.options.trans_qt4: u=Task.TaskCmd(translation_update,self.env,2) u.inputs=[a.inputs[0]for a in self.compiled_tasks] u.outputs=trans if getattr(self,'langname',None): t=Task.TaskBase.classes['qm2rcc'](self.env) t.set_inputs(lst) t.set_outputs(self.path.find_or_declare(self.langname+'.qrc')) t.path=self.path k=create_rcc_task(self,t.outputs[0]) self.link_task.inputs.append(k.outputs[0]) lst=[] for flag in self.to_list(self.env['CXXFLAGS']): if len(flag)<2:continue if flag[0:2]=='-D'or flag[0:2]=='-I': lst.append(flag) self.env['MOC_FLAGS']=lst def cxx_hook(self,node): task=self.create_task('qxx') self.compiled_tasks.append(task) try:obj_ext=self.obj_ext except AttributeError:obj_ext='_%d.o'%self.idx task.inputs=[node] task.outputs=[node.change_ext(obj_ext)] def process_qm2rcc(task): outfile=task.outputs[0].abspath(task.env) f=open(outfile,'w') f.write('\n\n') for k in task.inputs: f.write(' ') f.write(k.path_to_parent(task.path)) f.write('\n') f.write('\n') f.close() b=Task.simple_task_type b('moc','${QT_MOC} ${MOC_FLAGS} ${SRC} ${MOC_ST} ${TGT}',color='BLUE',vars=['QT_MOC','MOC_FLAGS'],shell=False) cls=b('rcc','${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath(env)} ${RCC_ST} -o ${TGT}',color='BLUE',before='cxx moc qxx_task',after="qm2rcc",shell=False) cls.scan=scan b('ui4','${QT_UIC} ${SRC} -o ${TGT}',color='BLUE',before='cxx moc qxx_task',shell=False) b('ts2qm','${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}',color='BLUE',before='qm2rcc',shell=False) Task.task_type_from_func('qm2rcc',vars=[],func=process_qm2rcc,color='BLUE',before='rcc',after='ts2qm') def detect_qt4(conf): env=conf.env opt=Options.options qtlibs=getattr(opt,'qtlibs','') qtincludes=getattr(opt,'qtincludes','') qtbin=getattr(opt,'qtbin','') useframework=getattr(opt,'use_qt4_osxframework',True) qtdir=getattr(opt,'qtdir','') if not qtdir:qtdir=conf.environ.get('QT4_ROOT','') if not qtdir: try: lst=os.listdir('/usr/local/Trolltech/') lst.sort() lst.reverse() qtdir='/usr/local/Trolltech/%s/'%lst[0] except OSError: pass if not qtdir: try: path=conf.environ['PATH'].split(':') for qmk in['qmake-qt4','qmake4','qmake']: qmake=conf.find_program(qmk,path) if qmake: version=Utils.cmd_output([qmake,'-query','QT_VERSION']).strip().split('.') if version[0]=="4": qtincludes=Utils.cmd_output([qmake,'-query','QT_INSTALL_HEADERS']).strip() qtdir=Utils.cmd_output([qmake,'-query','QT_INSTALL_PREFIX']).strip()+"/" qtbin=Utils.cmd_output([qmake,'-query','QT_INSTALL_BINS']).strip()+"/" break except(OSError,ValueError): pass if not qtlibs:qtlibs=os.path.join(qtdir,'lib') vars="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtWebKit Qt3Support".split() framework_ok=False if sys.platform=="darwin"and useframework: for i in vars: e=conf.create_framework_configurator() e.path=[qtlibs,'/Library/Frameworks'] e.name=i e.remove_dot_h=True e.run() if not i=='QtCore': for r in env['CCFLAGS_'+i.upper()]: if r.startswith('-F'): env['CCFLAGS_'+i.upper()].remove(r) break if conf.is_defined('HAVE_QTOPENGL'): env.append_unique('FRAMEWORK_QTOPENGL','OpenGL') if conf.is_defined('HAVE_QTGUI'): env.append_unique('FRAMEWORK_QTGUI',['AppKit','ApplicationServices']) framework_ok=True if not conf.is_defined("HAVE_QTGUI"): if not qtincludes:qtincludes=os.path.join(qtdir,'include') env['QTINCLUDEPATH']=qtincludes lst=[qtincludes,'/usr/share/qt4/include/','/opt/qt4/include'] conf.check(header_name='QtGui/QFont',define_name='HAVE_QTGUI',mandatory=1,includes=lst) if not qtbin:qtbin=os.path.join(qtdir,'bin') binpath=[qtbin,'/usr/share/qt4/bin/']+conf.environ['PATH'].split(':') def find_bin(lst,var): for f in lst: ret=conf.find_program(f,path_list=binpath) if ret: env[var]=ret break find_bin(['uic-qt3','uic3'],'QT_UIC3') find_bin(['uic-qt4','uic'],'QT_UIC') if not env['QT_UIC']: conf.fatal('connot find uic compiler') try: version=Utils.cmd_output(env['QT_UIC']+" -version 2>&1").strip() except ValueError: conf.fatal('your uic compiler is for qt3, add uic for qt4 to your path') version=version.replace('Qt User Interface Compiler ','') version=version.replace('User Interface Compiler for Qt','') if version.find(" 3.")!=-1: conf.check_message('uic version','(too old)',0,option='(%s)'%version) sys.exit(1) conf.check_message('uic version','',1,option='(%s)'%version) find_bin(['moc-qt4','moc'],'QT_MOC') find_bin(['rcc'],'QT_RCC') find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE') find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE') env['UIC3_ST']='%s -o %s' env['UIC_ST']='%s -o %s' env['MOC_ST']='-o' env['ui_PATTERN']='ui_%s.h' env['QT_LRELEASE_FLAGS']=['-silent'] if not framework_ok: vars_debug=[a+'_debug'for a in vars] pkgconfig=env['pkg-config']or'PKG_CONFIG_PATH=%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib pkg-config --silence-errors'%(qtlibs,qtlibs) for i in vars_debug+vars: try: conf.check_cfg(package=i,args='--cflags --libs',path=pkgconfig) except ValueError: pass def process_lib(vars_,coreval): for d in vars_: var=d.upper() if var=='QTCORE':continue value=env['LIBPATH_'+var] if value: core=env[coreval] accu=[] for lib in value: if lib in core:continue accu.append(lib) env['LIBPATH_'+var]=accu process_lib(vars,'LIBPATH_QTCORE') process_lib(vars_debug,'LIBPATH_QTCORE_DEBUG') if Options.options.want_rpath: def process_rpath(vars_,coreval): for d in vars_: var=d.upper() value=env['LIBPATH_'+var] if value: core=env[coreval] accu=[] for lib in value: if var!='QTCORE': if lib in core: continue accu.append('-Wl,--rpath='+lib) env['RPATH_'+var]=accu process_rpath(vars,'LIBPATH_QTCORE') process_rpath(vars_debug,'LIBPATH_QTCORE_DEBUG') env['QTLOCALE']=str(env['PREFIX'])+'/share/locale' def detect(conf): detect_qt4(conf) def set_options(opt): opt.add_option('--want-rpath',type='int',default=1,dest='want_rpath',help='set rpath to 1 or 0 [Default 1]') opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext') for i in"qtdir qtincludes qtlibs qtbin".split(): opt.add_option('--'+i,type='string',default='',dest=i) if sys.platform=="darwin": opt.add_option('--no-qt4-framework',action="store_false",help='do not use the framework version of Qt4 in OS X',dest='use_qt4_osxframework',default=True) opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt4",default=False) extension(EXT_RCC)(create_rcc_task) extension(EXT_UI)(create_uic_task) extension('.ts')(add_lang) feature('qt4')(apply_qt4) after('apply_link')(apply_qt4) extension(EXT_QT4)(cxx_hook) slv2-0.6.6+dfsg1/wafadmin/Tools/msvc.py0000644000175000017500000004360611176703511017514 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,re,string,optparse import Utils,TaskGen,Runner,Configure,Task,Options from Logs import debug,error,warn from TaskGen import after,before,feature from Configure import conftest,conf import ccroot,cc,cxx,ar,winres from libtool import read_la_file import _winreg all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64')] all_icl_platforms=[('Itanium','ia64'),('intel64','amd64'),('em64t','amd64'),('ia32','x86')] def setup_msvc(conf,versions): platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms] desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1] versiondict=dict(versions) for version in desired_versions: try: targets=dict(versiondict[version]) for target in platforms: try: arch,(p1,p2,p3)=targets[target] compiler,version=version.split() return compiler,p1,p2,p3 except KeyError:continue except KeyError:continue conf.fatal('msvc: Impossible to find a valid architecture for building') def get_msvc_version(conf,version,target,vcvars): batfile=os.path.join(conf.blddir,"waf-print-msvc.bat") f=open(batfile,'w') f.write("""@echo off set INCLUDE= set LIB= call %1 %2 echo PATH=%PATH% echo INCLUDE=%INCLUDE% echo LIB=%LIB% """) f.close() sout=Utils.cmd_output(['cmd','/E:on','/V:on','/C',batfile,vcvars,target]) lines=sout.splitlines() if lines[0].find("Setting environment")==-1 and lines[0].find("Setting SDK environment")==-1 and lines[1].find('Intel(R) C++ Compiler')==-1: conf.fatal('msvc: Impossible to find a valid architecture for building') for line in lines[1:]: if line.startswith('PATH='): MSVC_PATH=line[5:].split(';') elif line.startswith('INCLUDE='): MSVC_INCDIR=[i for i in line[8:].split(';')if i] elif line.startswith('LIB='): MSVC_LIBDIR=[i for i in line[4:].split(';')if i] return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR) def gather_wsdk_versions(conf,versions): version_pattern=re.compile('^v..?.?\...?.?') try: all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') except WindowsError: try: all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') except WindowsError: return index=0 while 1: try: version=_winreg.EnumKey(all_versions,index) except WindowsError: break index=index+1 if not version_pattern.match(version): continue try: msvc_version=_winreg.OpenKey(all_versions,version) path,type=_winreg.QueryValueEx(msvc_version,'InstallationFolder') except WindowsError: continue if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')): targets=[] for target,arch in all_msvc_platforms: try: targets.append((target,(arch,conf.get_msvc_version(version,'/'+target,os.path.join(path,'bin','SetEnv.cmd'))))) except Configure.ConfigurationError: pass versions.append(('wsdk '+version[1:],targets)) def gather_msvc_versions(conf,versions): version_pattern=re.compile('^..?\...?') for vcver,vcvar in[('VCExpress','exp'),('VisualStudio','')]: try: all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\'+vcver) except WindowsError: try: all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\'+vcver) except WindowsError: continue index=0 while 1: try: version=_winreg.EnumKey(all_versions,index) except WindowsError: break index=index+1 if not version_pattern.match(version): continue try: msvc_version=_winreg.OpenKey(all_versions,version+"\\Setup\\VS") path,type=_winreg.QueryValueEx(msvc_version,'ProductDir') targets=[] if os.path.isfile(os.path.join(path,'VC','vcvarsall.bat')): for target,realtarget in all_msvc_platforms[::-1]: try: targets.append((target,(realtarget,conf.get_msvc_version(version,target,os.path.join(path,'VC','vcvarsall.bat'))))) except: pass elif os.path.isfile(os.path.join(path,'Common7','Tools','vsvars32.bat')): try: targets.append(('x86',('x86',conf.get_msvc_version(version,'x86',os.path.join(path,'Common7','Tools','vsvars32.bat'))))) except Configure.ConfigurationError: pass versions.append(('msvc '+version,targets)) except WindowsError: continue def gather_icl_versions(conf,versions): version_pattern=re.compile('^...?.?\....?.?') try: all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') except WindowsError: try: all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++') except WindowsError: return index=0 while 1: try: version=_winreg.EnumKey(all_versions,index) except WindowsError: break index=index+1 if not version_pattern.match(version): continue targets=[] for target,arch in all_icl_platforms: try: icl_version=_winreg.OpenKey(all_versions,version+'\\'+target) path,type=_winreg.QueryValueEx(icl_version,'ProductDir') if os.path.isfile(os.path.join(path,'bin','iclvars.bat')): try: targets.append((target,(arch,conf.get_msvc_version(version,target,os.path.join(path,'bin','iclvars.bat'))))) except Configure.ConfigurationError: pass except WindowsError: continue major=version[0:2] versions.append(('intel '+major,targets)) def get_msvc_versions(conf): if not conf.env['MSVC_INSTALLED_VERSIONS']: conf.env['MSVC_INSTALLED_VERSIONS']=[] conf.gather_msvc_versions(conf.env['MSVC_INSTALLED_VERSIONS']) conf.gather_wsdk_versions(conf.env['MSVC_INSTALLED_VERSIONS']) conf.gather_icl_versions(conf.env['MSVC_INSTALLED_VERSIONS']) return conf.env['MSVC_INSTALLED_VERSIONS'] def detect_msvc(conf): versions=get_msvc_versions(conf) return setup_msvc(conf,versions) def msvc_linker(task): static=task.__class__.name.find('static')>0 e=env=task.env subsystem=getattr(task.generator,'subsystem','') if subsystem: subsystem='/subsystem:%s'%subsystem outfile=task.outputs[0].bldpath(e) manifest=outfile+'.manifest' def to_list(xx): if isinstance(xx,str):return[xx] return xx lst=[] if static: lst.extend(to_list(env['STLIBLINK'])) else: lst.extend(to_list(env['LINK'])) lst.extend(to_list(subsystem)) if static: lst.extend(to_list(env['STLINKFLAGS'])) else: lst.extend(to_list(env['LINKFLAGS'])) lst.extend([a.srcpath(env)for a in task.inputs]) lst.extend(to_list('/OUT:%s'%outfile)) lst=[x for x in lst if x] lst=[lst] ret=task.exec_command(*lst) if ret:return ret pdbnode=task.outputs[0].change_ext('.pdb') pdbfile=pdbnode.bldpath(e) if os.path.exists(pdbfile): task.outputs.append(pdbnode) if not static and os.path.exists(manifest): debug('msvc: manifesttool') mtool=e['MT'] if not mtool: return 0 mode='' if'cprogram'in task.generator.features: mode='1' elif'cshlib'in task.generator.features: mode='2' debug('msvc: embedding manifest') lst=[] lst.extend(to_list(e['MT'])) lst.extend(to_list(e['MTFLAGS'])) lst.extend(to_list("-manifest")) lst.extend(to_list(manifest)) lst.extend(to_list("-outputresource:%s;%s"%(outfile,mode))) lst=[lst] ret=task.exec_command(*lst) return ret g_msvc_systemlibs=""" aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp """.split() def find_lt_names_msvc(self,libname,is_static=False): lt_names=['lib%s.la'%libname,'%s.la'%libname,] for path in self.env['LIBPATH']: for la in lt_names: laf=os.path.join(path,la) dll=None if os.path.exists(laf): ltdict=read_la_file(laf) lt_libdir=None if ltdict.get('libdir',''): lt_libdir=ltdict['libdir'] if not is_static and ltdict.get('library_names',''): dllnames=ltdict['library_names'].split() dll=dllnames[0].lower() dll=re.sub('\.dll$','',dll) return(lt_libdir,dll,False) elif ltdict.get('old_library',''): olib=ltdict['old_library'] if os.path.exists(os.path.join(path,olib)): return(path,olib,True) elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)): return(lt_libdir,olib,True) else: return(None,olib,True) else: raise Utils.WafError('invalid libtool object file: %s'%laf) return(None,None,None) def libname_msvc(self,libname,is_static=False,mandatory=False): lib=libname.lower() lib=re.sub('\.lib$','',lib) if lib in g_msvc_systemlibs: return lib lib=re.sub('^lib','',lib) if lib=='m': return None (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static) if lt_path!=None and lt_libname!=None: if lt_static==True: return os.path.join(lt_path,lt_libname) if lt_path!=None: _libpaths=[lt_path]+self.env['LIBPATH'] else: _libpaths=self.env['LIBPATH'] static_libs=['%ss.lib'%lib,'lib%ss.lib'%lib,'%s.lib'%lib,'lib%s.lib'%lib,] dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,] libnames=static_libs if not is_static: libnames=dynamic_libs+static_libs for path in _libpaths: for libn in libnames: if os.path.exists(os.path.join(path,libn)): debug('msvc: lib found: %s'%os.path.join(path,libn)) return re.sub('\.lib$','',libn) if mandatory: self.fatal("The library %r could not be found"%libname) return re.sub('\.lib$','',libname) def check_lib_msvc(self,libname,is_static=False,uselib_store=None,mandatory=False): libn=self.libname_msvc(libname,is_static,mandatory) if not uselib_store: uselib_store=libname.upper() if is_static: self.env['LIB_'+uselib_store]=[libn] else: self.env['STATICLIB_'+uselib_store]=[libn] def check_libs_msvc(self,libnames,is_static=False,mandatory=False): for libname in Utils.to_list(libnames): self.check_lib_msvc(libname,is_static,mandatory=mandatory) def apply_obj_vars_msvc(self): if self.env['CC_NAME']!='msvc': return try: self.meths.remove('apply_obj_vars') except ValueError: pass env=self.env app=env.append_unique cpppath_st=env['CPPPATH_ST'] lib_st=env['LIB_ST'] staticlib_st=env['STATICLIB_ST'] libpath_st=env['LIBPATH_ST'] staticlibpath_st=env['STATICLIBPATH_ST'] for i in env['LIBPATH']: app('LINKFLAGS',libpath_st%i) if not self.libpaths.count(i): self.libpaths.append(i) for i in env['LIBPATH']: app('LINKFLAGS',staticlibpath_st%i) if not self.libpaths.count(i): self.libpaths.append(i) if not env['FULLSTATIC']: if env['STATICLIB']or env['LIB']: app('LINKFLAGS',env['SHLIB_MARKER']) for i in env['STATICLIB']: app('LINKFLAGS',lib_st%i) for i in env['LIB']: app('LINKFLAGS',lib_st%i) def apply_link_msvc(self): if self.env['CC_NAME']!='msvc': return link=getattr(self,'link',None) if not link: if'cstaticlib'in self.features:link='msvc_link_static' elif'cxx'in self.features:link='msvc_cxx_link' else:link='msvc_cc_link' self.vnum='' self.link=link def init_msvc(self): try:getattr(self,'libpaths') except AttributeError:self.libpaths=[] Task.task_type_from_func('msvc_link_static',vars=['STLIBLINK','STLINKFLAGS'],color='YELLOW',func=msvc_linker,ext_in='.o') Task.task_type_from_func('msvc_cc_link',vars=['LINK','LINK_SRC_F','LINKFLAGS','MT','MTFLAGS'],color='YELLOW',func=msvc_linker,ext_in='.o') Task.task_type_from_func('msvc_cxx_link',vars=['LINK','LINK_SRC_F','LINKFLAGS','MT','MTFLAGS'],color='YELLOW',func=msvc_linker,ext_in='.o') rc_str='${RC} ${RCFLAGS} /fo ${TGT} ${SRC}' Task.simple_task_type('rc',rc_str,color='GREEN',before='cc cxx',shell=False) def no_autodetect(conf): conf.eval_rules(detect.replace('autodetect','')) detect=''' autodetect find_msvc msvc_common_flags cc_load_tools cxx_load_tools cc_add_flags cxx_add_flags ''' def autodetect(conf): v=conf.env compiler,path,includes,libdirs=detect_msvc(conf) v['PATH']=path v['CPPPATH']=includes v['LIBPATH']=libdirs v['MSVC_COMPILER']=compiler def find_msvc(conf): if sys.platform!='win32': conf.fatal('MSVC module only works under native Win32 Python! cygwin is not supported yet') v=conf.env compiler,path,includes,libdirs=detect_msvc(conf) v['PATH']=path v['CPPPATH']=includes v['LIBPATH']=libdirs if compiler=='msvc'or compiler=='wsdk': compiler_name='CL' linker_name='LINK' lib_name='LIB' elif compiler=='intel': compiler_name='ICL' linker_name='XILINK' lib_name='XILIB' else: conf.fatal('Unknown compiler type : %s'%compiler) cxx=None if v['CXX']:cxx=v['CXX'] elif'CXX'in conf.environ:cxx=conf.environ['CXX'] if not cxx:cxx=conf.find_program(compiler_name,var='CXX',path_list=path) if not cxx:conf.fatal('%s was not found (compiler)'%compiler_name) cxx=conf.cmd_to_list(cxx) env=dict(conf.environ) env.update(PATH=';'.join(path)) if not Utils.cmd_output([cxx,'/nologo','/?'],silent=True,env=env): conf.fatal('the msvc compiler could not be identified') v['CC']=v['CXX']=cxx v['CC_NAME']=v['CXX_NAME']='msvc' try:v.prepend_value('CPPPATH',conf.environ['INCLUDE']) except KeyError:pass try:v.prepend_value('LIBPATH',conf.environ['LIB']) except KeyError:pass if not v['LINK_CXX']: link=conf.find_program(linker_name,path_list=path) if link:v['LINK_CXX']=link else:conf.fatal('%s was not found (linker)'%linker_name) v['LINK']=link if not v['LINK_CC']:v['LINK_CC']=v['LINK_CXX'] if not v['STLIBLINK']: stliblink=conf.find_program(lib_name,path_list=path) if not stliblink:return v['STLIBLINK']=stliblink v['STLINKFLAGS']=['/NOLOGO'] manifesttool=conf.find_program('MT',path_list=path) if manifesttool: v['MT']=manifesttool v['MTFLAGS']=['/NOLOGO'] conf.check_tool('winres') if not conf.env['WINRC']: warn('Resource compiler not found. Compiling resource file is disabled') def exec_command_msvc(self,*k,**kw): if self.env['CC_NAME']=='msvc': if isinstance(k[0],list): lst=[] carry='' for a in k[0]: if(len(a)==3 and(a.startswith('/F')or a.startswith('/Y')))or(a=='/doc'): carry=a else: lst.append(carry+a) carry='' k=[lst] env=dict(os.environ) env.update(PATH=';'.join(self.env['PATH'])) kw['env']=env return self.generator.bld.exec_command(*k,**kw) for k in'cc cxx msvc_cc_link msvc_cxx_link msvc_link_static winrc'.split(): cls=Task.TaskBase.classes.get(k,None) if cls: cls.exec_command=exec_command_msvc def msvc_common_flags(conf): v=conf.env v['CPPFLAGS']=['/W3','/nologo','/EHsc'] v['CCDEFINES']=['WIN32'] v['CXXDEFINES']=['WIN32'] v['_CCINCFLAGS']=[] v['_CCDEFFLAGS']=[] v['_CXXINCFLAGS']=[] v['_CXXDEFFLAGS']=[] v['CC_SRC_F']='' v['CC_TGT_F']=['/c','/Fo'] v['CXX_SRC_F']='' v['CXX_TGT_F']=['/c','/Fo'] v['CPPPATH_ST']='/I%s' v['CPPFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE'] v['CPPFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE'] v['CPPFLAGS_POSIX']=['/SUBSYSTEM:POSIX'] v['CPPFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS'] v['CPPFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE'] v['CPPFLAGS_CRT_MULTITHREADED']=['/MT'] v['CPPFLAGS_CRT_MULTITHREADED_DLL']=['/MD'] v['CPPDEFINES_CRT_MULTITHREADED']=['_MT'] v['CPPDEFINES_CRT_MULTITHREADED_DLL']=['_MT','_DLL'] v['CPPFLAGS_CRT_MULTITHREADED_DBG']=['/MTd'] v['CPPFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd'] v['CPPDEFINES_CRT_MULTITHREADED_DBG']=['_DEBUG','_MT'] v['CPPDEFINES_CRT_MULTITHREADED_DLL_DBG']=['_DEBUG','_MT','_DLL'] v['CCFLAGS']=['/TC'] v['CCFLAGS_OPTIMIZED']=['/O2','/DNDEBUG'] v['CCFLAGS_RELEASE']=['/O2','/DNDEBUG'] v['CCFLAGS_DEBUG']=['/Od','/RTC1','/D_DEBUG','/ZI'] v['CCFLAGS_ULTRADEBUG']=['/Od','/RTC1','/D_DEBUG','/ZI'] v['CXXFLAGS']=['/TP'] v['CXXFLAGS_OPTIMIZED']=['/O2','/DNDEBUG'] v['CXXFLAGS_RELEASE']=['/O2','/DNDEBUG'] v['CXXFLAGS_DEBUG']=['/Od','/RTC1','/D_DEBUG','/ZI'] v['CXXFLAGS_ULTRADEBUG']=['/Od','/RTC1','/D_DEBUG','/ZI'] v['LIB']=[] v['LINK_TGT_F']='/OUT:' v['LINK_SRC_F']='' v['LIB_ST']='%s.lib' v['LIBPATH_ST']='/LIBPATH:%s' v['STATICLIB_ST']='%s.lib' v['STATICLIBPATH_ST']='/LIBPATH:%s' v['CCDEFINES_ST']='/D%s' v['CXXDEFINES_ST']='/D%s' v['LINKFLAGS']=['/NOLOGO','/MANIFEST'] v['shlib_CCFLAGS']=[''] v['shlib_CXXFLAGS']=[''] v['shlib_LINKFLAGS']=['/DLL'] v['shlib_PATTERN']='%s.dll' v['staticlib_LINKFLAGS']=[''] v['staticlib_PATTERN']='%s.lib' v['program_PATTERN']='%s.exe' conf(get_msvc_version) conf(gather_wsdk_versions) conf(gather_msvc_versions) conf(gather_icl_versions) conf(get_msvc_versions) conf(find_lt_names_msvc) conf(libname_msvc) conf(check_lib_msvc) conf(check_libs_msvc) feature('cprogram','cshlib','cstaticlib')(apply_obj_vars_msvc) after('apply_lib_vars')(apply_obj_vars_msvc) before('apply_obj_vars')(apply_obj_vars_msvc) feature('cprogram','cshlib','cstaticlib')(apply_link_msvc) before('apply_link')(apply_link_msvc) feature('cc','cxx')(init_msvc) after('init_cc','init_cxx')(init_msvc) before('apply_type_vars','apply_core')(init_msvc) conftest(no_autodetect) conftest(autodetect) conftest(find_msvc) conftest(msvc_common_flags) slv2-0.6.6+dfsg1/wafadmin/Tools/boost.py0000644000175000017500000001700111176703511017660 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os.path,glob,types,re,sys import Configure,config_c,Options,Utils,Logs from Logs import warn from Configure import conf boost_code=''' #include #include int main() { std::cout << BOOST_VERSION << std::endl; } ''' boost_libpath=['/usr/lib','/usr/local/lib','/opt/local/lib','/sw/lib','/lib'] boost_cpppath=['/usr/include','/usr/local/include','/opt/local/include','/sw/include'] STATIC_NOSTATIC='nostatic' STATIC_BOTH='both' STATIC_ONLYSTATIC='onlystatic' is_versiontag=re.compile('^\d+_\d+_?\d*$') is_threadingtag=re.compile('^mt$') is_abitag=re.compile('^[sgydpn]+$') is_toolsettag=re.compile('^(acc|borland|como|cw|dmc|darwin|gcc|hp_cxx|intel|kylix|msvc|qcc|sun|vacpp)\d*$') def set_options(opt): opt.add_option('--boost-includes',type='string',default='',dest='boostincludes',help='path to the boost directory where the includes are e.g. /usr/local/include/boost-1_35') opt.add_option('--boost-libs',type='string',default='',dest='boostlibs',help='path to the directory where the boost libs are e.g. /usr/local/lib') def string_to_version(s): version=s.split('.') if len(version)<3:return 0 return int(version[0])*100000+int(version[1])*100+int(version[2]) def version_string(version): major=version/100000 minor=version/100%1000 minor_minor=version%100 if minor_minor==0: return"%d_%d"%(major,minor) else: return"%d_%d_%d"%(major,minor,minor_minor) def libfiles(lib,pattern,lib_paths): result=[] for lib_path in lib_paths: libname=pattern%('boost_'+lib+'*') result+=glob.glob(lib_path+'/'+libname) return result def get_boost_version_number(self,dir): try: return self.run_c_code(compiler='cxx',code=boost_code,includes=dir,execute=1,env=self.env.copy(),type='cprogram',compile_mode='cxx',compile_filename='test.cpp') except Configure.ConfigurationError,e: return-1 def set_default(kw,var,val): if not var in kw: kw[var]=val def tags_score(tags,kw): score=0 needed_tags={'threading':kw['tag_threading'],'abi':kw['tag_abi'],'toolset':kw['tag_toolset'],'version':kw['tag_version']} if kw['tag_toolset']is None: v=kw['env'] toolset=v['CXX_NAME'] if v['CXX_VERSION']: version_no=v['CXX_VERSION'].split('.') toolset+=version_no[0] if len(version_no)>1: toolset+=version_no[1] needed_tags['toolset']=toolset found_tags={} for tag in tags: if is_versiontag.match(tag):found_tags['version']=tag if is_threadingtag.match(tag):found_tags['threading']=tag if is_abitag.match(tag):found_tags['abi']=tag if is_toolsettag.match(tag):found_tags['toolset']=tag for tagname in needed_tags.iterkeys(): if needed_tags[tagname]is not None and tagname in found_tags: if re.compile(needed_tags[tagname]).match(found_tags[tagname]): score+=kw['score_'+tagname][0] else: score+=kw['score_'+tagname][1] return score def validate_boost(self,kw): ver=kw.get('version','') for x in'min_version max_version version'.split(): set_default(kw,x,ver) set_default(kw,'lib','') kw['lib']=Utils.to_list(kw['lib']) set_default(kw,'env',self.env) set_default(kw,'libpath',boost_libpath) set_default(kw,'cpppath',boost_cpppath) for x in'tag_threading tag_version tag_toolset'.split(): set_default(kw,x,None) set_default(kw,'tag_abi','^[^d]*$') set_default(kw,'score_threading',(10,-10)) set_default(kw,'score_abi',(10,-10)) set_default(kw,'score_toolset',(1,-1)) set_default(kw,'score_version',(100,-100)) set_default(kw,'score_min',0) set_default(kw,'static',STATIC_NOSTATIC) set_default(kw,'found_includes',False) set_default(kw,'min_score',0) set_default(kw,'errmsg','not found') set_default(kw,'okmsg','ok') def find_boost_includes(self,kw): boostPath=getattr(Options.options,'boostincludes','') if boostPath: boostPath=[os.path.normpath(os.path.expandvars(os.path.expanduser(boostPath)))] else: boostPath=Utils.to_list(kw['cpppath']) min_version=string_to_version(kw.get('min_version','')) max_version=string_to_version(kw.get('max_version',''))or(sys.maxint-1) version=0 for include_path in boostPath: boost_paths=glob.glob(os.path.join(include_path,'boost*')) for path in boost_paths: pathname=os.path.split(path)[-1] ret=-1 if pathname=='boost': path=include_path ret=self.get_boost_version_number(path) elif pathname.startswith('boost-'): ret=self.get_boost_version_number(path) ret=int(ret) if ret!=-1 and ret>=min_version and ret<=max_version and ret>version: boost_path=path version=ret if not version: self.fatal('boost headers not found! (required version min: %s max: %s)'%(kw['min_version'],kw['max_version'])) return False found_version=version_string(version) versiontag='^'+found_version+'$' if kw['tag_version']is None: kw['tag_version']=versiontag elif kw['tag_version']!=versiontag: warn('boost header version %r and tag_version %r do not match!'%(versiontag,kw['tag_version'])) env=self.env env['CPPPATH_BOOST']=boost_path env['BOOST_VERSION']=found_version self.found_includes=1 ret='Version %s (%s)'%(found_version,boost_path) return ret def find_boost_library(self,lib,kw): def find_library_from_list(lib,files): lib_pattern=re.compile('.*boost_(.*?)\..*') result=(None,None) resultscore=kw['min_score']-1 for file in files: m=lib_pattern.search(file,1) if m: libname=m.group(1) libtags=libname.split('-')[1:] currentscore=tags_score(libtags,kw) if currentscore>resultscore: result=(libname,file) resultscore=currentscore return result lib_paths=getattr(Options.options,'boostlibs','') if lib_paths: lib_paths=[os.path.normpath(os.path.expandvars(os.path.expanduser(lib_paths)))] else: lib_paths=Utils.to_list(kw['libpath']) v=kw.get('env',self.env) (libname,file)=(None,None) if kw['static']in[STATIC_NOSTATIC,STATIC_BOTH]: st_env_prefix='LIB' files=libfiles(lib,v['shlib_PATTERN'],lib_paths) (libname,file)=find_library_from_list(lib,files) if libname is None and kw['static']in[STATIC_ONLYSTATIC,STATIC_BOTH]: st_env_prefix='STATICLIB' staticLibPattern=v['staticlib_PATTERN'] if self.env['CC_NAME']=='msvc': staticLibPattern='lib'+staticLibPattern files=libfiles(lib,staticLibPattern,lib_paths) (libname,file)=find_library_from_list(lib,files) if libname is not None: v['LIBPATH_BOOST_'+lib.upper()]=os.path.split(file)[0] if self.env['CC_NAME']=='msvc'and os.path.splitext(file)[1]=='.lib': v[st_env_prefix+'_BOOST_'+lib.upper()]='libboost_'+libname else: v[st_env_prefix+'_BOOST_'+lib.upper()]='boost_'+libname return self.fatal('lib boost_'+lib+' not found!') def check_boost(self,*k,**kw): self.validate_boost(kw) ret=None try: if not kw.get('found_includes',None): self.check_message_1(kw.get('msg_includes','boost headers')) ret=self.find_boost_includes(kw) except Configure.ConfigurationError,e: if'errmsg'in kw: self.check_message_2(kw['errmsg'],'YELLOW') if'mandatory'in kw: if Logs.verbose>1: raise else: self.fatal('the configuration failed (see %r)'%self.log.name) else: if'okmsg'in kw: self.check_message_2(kw.get('okmsg_includes',ret)) for lib in kw['lib']: self.check_message_1('library boost_'+lib) try: self.find_boost_library(lib,kw) except Configure.ConfigurationError,e: if'errmsg'in kw: self.check_message_2(kw['errmsg'],'YELLOW') if'mandatory'in kw: if Logs.verbose>1: raise else: self.fatal('the configuration failed (see %r)'%self.log.name) else: if'okmsg'in kw: self.check_message_2(kw['okmsg']) return ret conf(get_boost_version_number) conf(validate_boost) conf(find_boost_includes) conf(find_boost_library) conf(check_boost) slv2-0.6.6+dfsg1/wafadmin/Tools/gnu_dirs.py0000644000175000017500000000506011176703511020346 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import Utils,Options _options=[x.split(', ')for x in''' bindir, user executables, ${EXEC_PREFIX}/bin sbindir, system admin executables, ${EXEC_PREFIX}/sbin libexecdir, program executables, ${EXEC_PREFIX}/libexec sysconfdir, read-only single-machine data, ${PREFIX}/etc sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com localstatedir, modifiable single-machine data, ${PREFIX}/var libdir, object code libraries, ${EXEC_PREFIX}/lib includedir, C header files, ${PREFIX}/include oldincludedir, C header files for non-gcc, /usr/include datarootdir, read-only arch.-independent data root, ${PREFIX}/share datadir, read-only architecture-independent data, ${DATAROOTDIR} infodir, info documentation, ${DATAROOTDIR}/info localedir, locale-dependent data, ${DATAROOTDIR}/locale mandir, man documentation, ${DATAROOTDIR}/man docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE} htmldir, html documentation, ${DOCDIR} dvidir, dvi documentation, ${DOCDIR} pdfdir, pdf documentation, ${DOCDIR} psdir, ps documentation, ${DOCDIR} '''.split('\n')if x] def detect(conf): def get_param(varname,default): return getattr(Options.options,varname,'')or default env=conf.env env['EXEC_PREFIX']=get_param('EXEC_PREFIX',env['PREFIX']) env['PACKAGE']=Utils.g_module.APPNAME or env['PACKAGE'] complete=False iter=0 while not complete and iter=0: conf.fatal('The intel compiler pretends to be gcc') if out.find('__GNUC__')<0: conf.fatal('Could not determine the compiler type') if icc and out.find('__INTEL_COMPILER')<0: conf.fatal('Not icc/icpc') k={} if icc or gcc: out=out.split('\n') import shlex for line in out: lst=shlex.split(line) if len(lst)>2: key=lst[1] val=lst[2] k[key]=val conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__']) return k class DEBUG_LEVELS: ULTRADEBUG="ultradebug" DEBUG="debug" RELEASE="release" OPTIMIZED="optimized" CUSTOM="custom" ALL=[ULTRADEBUG,DEBUG,RELEASE,OPTIMIZED,CUSTOM] def scan(self): debug('ccroot: _scan_preprocessor(self, node, env, path_lst)') if len(self.inputs)==1: node=self.inputs[0] (nodes,names)=preproc.get_deps(node,self.env,nodepaths=self.env['INC_PATHS']) if Logs.verbose: debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names)) return(nodes,names) all_nodes=[] all_names=[] seen=[] for node in self.inputs: (nodes,names)=preproc.get_deps(node,self.env,nodepaths=self.env['INC_PATHS']) if Logs.verbose: debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names)) for x in nodes: if id(x)in seen:continue seen.append(id(x)) all_nodes.append(x) for x in names: if not x in all_names: all_names.append(x) return(all_nodes,all_names) class ccroot_abstract(TaskGen.task_gen): def __init__(self,*k,**kw): if len(k)>1: k=list(k) if k[1][0]!='c': k[1]='c'+k[1] TaskGen.task_gen.__init__(self,*k,**kw) def get_target_name(self): tp='program' for x in self.features: if x in['cshlib','cstaticlib']: tp=x.lstrip('c') pattern=self.env[tp+'_PATTERN'] if not pattern:pattern='%s' dir,name=os.path.split(self.target) return os.path.join(dir,pattern%name) def install_shlib(self): nums=self.vnum.split('.') path=self.install_path if not path:return libname=self.outputs[0].name name3=libname+'.'+self.vnum name2=libname+'.'+nums[0] name1=libname filename=self.outputs[0].abspath(self.env) bld=self.outputs[0].__class__.bld bld.install_as(os.path.join(path,name3),filename,env=self.env) bld.symlink_as(os.path.join(path,name2),name3) bld.symlink_as(os.path.join(path,name1),name3) def default_cc(self): Utils.def_attrs(self,includes='',defines='',rpaths='',uselib='',uselib_local='',add_objects='',p_flag_vars=[],p_type_vars=[],compiled_tasks=[],link_task=None) def apply_verif(self): if not(self.source or getattr(self,'add_objects',None)): raise Utils.WafError('no source files specified for %s'%self) if not self.target: raise Utils.WafError('no target for %s'%self) def vars_target_cprogram(self): self.default_install_path=self.env['BINDIR']or'${PREFIX}/bin' self.default_chmod=O755 def vars_target_cstaticlib(self): self.default_install_path=self.env['LIBDIR']or'${PREFIX}/lib${LIB_EXT}' if sys.platform in['win32','cygwin']: self.default_chmod=O755 def install_target_cstaticlib(self): if not self.bld.is_install:return self.link_task.install_path=self.install_path def install_target_cshlib(self): if getattr(self,'vnum','')and sys.platform!='win32': tsk=self.link_task tsk.vnum=self.vnum tsk.install=install_shlib def apply_incpaths(self): lst=[] for lib in self.to_list(self.uselib): for path in self.env['CPPPATH_'+lib]: if not path in lst: lst.append(path) if preproc.go_absolute: for path in preproc.standard_includes: if not path in lst: lst.append(path) for path in self.to_list(self.includes): if not path in lst: if preproc.go_absolute or not os.path.isabs(path): lst.append(path) else: self.env.prepend_value('CPPPATH',path) for path in lst: node=None if os.path.isabs(path): if preproc.go_absolute: node=self.bld.root.find_dir(path) elif path[0]=='#': node=self.bld.srcnode if len(path)>1: node=node.find_dir(path[1:]) else: node=self.path.find_dir(path) if node: self.env.append_value('INC_PATHS',node) if USE_TOP_LEVEL: self.env.append_value('INC_PATHS',self.bld.srcnode) def apply_type_vars(self): for x in self.features: if not x in['cprogram','cstaticlib','cshlib']: continue x=x.lstrip('c') st=self.env[x+'_USELIB'] if st:self.uselib=self.uselib+' '+st for var in self.p_type_vars: compvar='%s_%s'%(x,var) value=self.env[compvar] if value:self.env.append_value(var,value) def apply_link(self): link=getattr(self,'link',None) if not link: if'cstaticlib'in self.features:link='ar_link_static' elif'cxx'in self.features:link='cxx_link' else:link='cc_link' if'cshlib'in self.features and getattr(self,'vnum',None): if sys.platform=='darwin'or sys.platform=='win32': self.vnum='' else: link='vnum_'+link tsk=self.create_task(link) outputs=[t.outputs[0]for t in self.compiled_tasks] tsk.set_inputs(outputs) tsk.set_outputs(self.path.find_or_declare(get_target_name(self))) tsk.chmod=self.chmod self.link_task=tsk def apply_lib_vars(self): env=self.env uselib=self.to_list(self.uselib) seen=[] names=self.to_list(self.uselib_local)[:] while names: x=names.pop(0) if x in seen: continue y=self.name_to_obj(x) if not y: raise Utils.WafError("object '%s' was not found in uselib_local (required by '%s')"%(x,self.name)) if getattr(y,'uselib_local',None): lst=y.to_list(y.uselib_local) for u in lst: if not u in seen: names.append(u) y.post() seen.append(x) libname=y.target[y.target.rfind(os.sep)+1:] if'cshlib'in y.features or'cprogram'in y.features: env.append_value('LIB',libname) elif'cstaticlib'in y.features: env.append_value('STATICLIB',libname) if y.link_task is not None: self.link_task.set_run_after(y.link_task) dep_nodes=getattr(self.link_task,'dep_nodes',[]) self.link_task.dep_nodes=dep_nodes+y.link_task.outputs tmp_path=y.link_task.outputs[0].parent.bldpath(self.env) if not tmp_path in env['LIBPATH']:env.prepend_value('LIBPATH',tmp_path) morelibs=y.to_list(y.uselib) for v in morelibs: if v in uselib:continue uselib=[v]+uselib if getattr(y,'export_incdirs',None): cpppath_st=self.env['CPPPATH_ST'] for x in self.to_list(y.export_incdirs): node=y.path.find_dir(x) if not node: raise Utils.WafError('object %s: invalid folder %s in export_incdirs'%(y.target,x)) self.env.append_unique('INC_PATHS',node) for x in uselib: for v in self.p_flag_vars: val=self.env[v+'_'+x] if val:self.env.append_value(v,val) def apply_objdeps(self): if not getattr(self,'add_objects',None):return seen=[] names=self.to_list(self.add_objects) while names: x=names[0] if x in seen: names=names[1:] continue y=self.name_to_obj(x) if not y: raise Utils.WafError("object '%s' was not found in uselib_local (required by add_objects '%s')"%(x,self.name)) if getattr(y,'add_objects',None): added=0 lst=y.to_list(y.add_objects) lst.reverse() for u in lst: if u in seen:continue added=1 names=[u]+names if added:continue y.post() seen.append(x) for t in y.compiled_tasks: self.link_task.inputs.extend(t.outputs) def apply_obj_vars(self): v=self.env lib_st=v['LIB_ST'] staticlib_st=v['STATICLIB_ST'] libpath_st=v['LIBPATH_ST'] staticlibpath_st=v['STATICLIBPATH_ST'] rpath_st=v['RPATH_ST'] app=v.append_unique if v['FULLSTATIC']: v.append_value('LINKFLAGS',v['FULLSTATIC_MARKER']) for i in v['RPATH']: if i and rpath_st: app('LINKFLAGS',rpath_st%i) for i in v['LIBPATH']: app('LINKFLAGS',libpath_st%i) app('LINKFLAGS',staticlibpath_st%i) if v['STATICLIB']: v.append_value('LINKFLAGS',v['STATICLIB_MARKER']) k=[(staticlib_st%i)for i in v['STATICLIB']] app('LINKFLAGS',k) if not v['FULLSTATIC']: if v['STATICLIB']or v['LIB']: v.append_value('LINKFLAGS',v['SHLIB_MARKER']) app('LINKFLAGS',[lib_st%i for i in v['LIB']]) def apply_vnum(self): if sys.platform!='darwin'and sys.platform!='win32': try: nums=self.vnum.split('.') except AttributeError: pass else: try:name3=self.soname except AttributeError:name3=self.link_task.outputs[0].name+'.'+nums[0] self.link_task.outputs.append(self.link_task.outputs[0].parent.find_or_declare(name3)) self.env.append_value('LINKFLAGS',(self.env['SONAME_ST']%name3).split()) def process_obj_files(self): if not hasattr(self,'obj_files'):return for x in self.obj_files: node=self.path.find_resource(x) self.link_task.inputs.append(node) def add_obj_file(self,file): if not hasattr(self,'obj_files'):self.obj_files=[] if not'process_obj_files'in self.meths:self.meths.append('process_obj_files') self.obj_files.append(file) c_attrs={'cxxflag':'CXXFLAGS','cflag':'CCFLAGS','ccflag':'CCFLAGS','linkflag':'LINKFLAGS','ldflag':'LINKFLAGS','lib':'LIB','libpath':'LIBPATH','staticlib':'STATICLIB','staticlibpath':'STATICLIBPATH','rpath':'RPATH','framework':'FRAMEWORK','frameworkpath':'FRAMEWORKPATH'} def add_extra_flags(self): for x in self.__dict__.keys(): y=x.lower() if y[-1]=='s': y=y[:-1] if c_attrs.get(y,None): self.env.append_unique(c_attrs[y],getattr(self,x)) def link_vnum(self): clsname=self.__class__.__name__.replace('vnum_','') out=self.outputs self.outputs=out[1:] ret=Task.TaskBase.classes[clsname].__dict__['run'](self) self.outputs=out if ret: return ret try: os.remove(self.outputs[0].abspath(self.env)) except OSError: pass try: os.symlink(self.outputs[1].name,self.outputs[0].bldpath(self.env)) except: return 1 feature('cc','cxx')(default_cc) before('apply_core')(default_cc) feature('cprogram','dprogram','cstaticlib','dstaticlib','cshlib','dshlib')(apply_verif) feature('cprogram','dprogram')(vars_target_cprogram) before('apply_core')(vars_target_cprogram) feature('cstaticlib','dstaticlib','cshlib','dshlib')(vars_target_cstaticlib) before('apply_core')(vars_target_cstaticlib) feature('cprogram','dprogram','cstaticlib','dstaticlib','cshlib','dshlib')(install_target_cstaticlib) after('apply_objdeps','apply_link')(install_target_cstaticlib) feature('cshlib','dshlib')(install_target_cshlib) after('apply_link')(install_target_cshlib) feature('cc','cxx')(apply_incpaths) after('apply_type_vars','apply_lib_vars','apply_core')(apply_incpaths) feature('cc','cxx')(apply_type_vars) after('init_cc','init_cxx')(apply_type_vars) before('apply_lib_vars')(apply_type_vars) feature('cprogram','cshlib','cstaticlib')(apply_link) after('apply_core')(apply_link) feature('cc','cxx')(apply_lib_vars) after('apply_link','init_cc','init_cxx')(apply_lib_vars) feature('cprogram','cstaticlib','cshlib')(apply_objdeps) after('apply_obj_vars','apply_vnum','apply_link')(apply_objdeps) feature('cprogram','cshlib','cstaticlib')(apply_obj_vars) after('apply_lib_vars')(apply_obj_vars) feature('cshlib')(apply_vnum) after('apply_link')(apply_vnum) before('apply_lib_vars')(apply_vnum) after('apply_link')(process_obj_files) taskgen(add_obj_file) feature('cc','cxx')(add_extra_flags) before('init_cxx','init_cc')(add_extra_flags) before('apply_lib_vars','apply_obj_vars','apply_incpaths','init_cc')(add_extra_flags) slv2-0.6.6+dfsg1/wafadmin/Tools/lua.py0000644000175000017500000000060411176703511017314 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import TaskGen from TaskGen import taskgen,feature from Constants import* TaskGen.declare_chain(name='luac',rule='${LUAC} -s -o ${TGT} ${SRC}',ext_in='.lua',ext_out='.luac',reentrant=0,install='LUADIR',) def init_lua(self): self.default_chmod=O755 def detect(conf): conf.find_program('luac',var='LUAC',mandatory=True) feature('lua')(init_lua) slv2-0.6.6+dfsg1/wafadmin/Tools/cc.py0000644000175000017500000000476011176703511017127 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os import TaskGen,Build,Utils,Task from Logs import debug import ccroot from TaskGen import feature,before,extension,after g_cc_flag_vars=['CCDEPS','FRAMEWORK','FRAMEWORKPATH','STATICLIB','LIB','LIBPATH','LINKFLAGS','RPATH','CCFLAGS','CPPPATH','CPPFLAGS','CCDEFINES'] EXT_CC=['.c'] g_cc_type_vars=['CCFLAGS','LINKFLAGS'] class cc_taskgen(ccroot.ccroot_abstract): pass def init_cc(self): self.p_flag_vars=set(self.p_flag_vars).union(g_cc_flag_vars) self.p_type_vars=set(self.p_type_vars).union(g_cc_type_vars) if not self.env['CC_NAME']: raise Utils.WafError("At least one compiler (gcc, ..) must be selected") def apply_obj_vars_cc(self): env=self.env app=env.append_unique cpppath_st=env['CPPPATH_ST'] for i in env['INC_PATHS']: app('_CCINCFLAGS',cpppath_st%i.bldpath(env)) app('_CCINCFLAGS',cpppath_st%i.srcpath(env)) for i in env['CPPPATH']: app('_CCINCFLAGS',cpppath_st%i) def apply_defines_cc(self): self.defines=getattr(self,'defines',[]) lst=self.to_list(self.defines)+self.to_list(self.env['CCDEFINES']) milst=[] for defi in lst: if not defi in milst: milst.append(defi) libs=self.to_list(self.uselib) for l in libs: val=self.env['CCDEFINES_'+l] if val:milst+=val self.env['DEFLINES']=["%s %s"%(x[0],Utils.trimquotes('='.join(x[1:])))for x in[y.split('=')for y in milst]] y=self.env['CCDEFINES_ST'] self.env['_CCDEFFLAGS']=[y%x for x in milst] def c_hook(self,node): task=self.create_task('cc') if getattr(self,'obj_ext',None): obj_ext=self.obj_ext else: obj_ext='_%d.o'%self.idx task.inputs=[node] task.outputs=[node.change_ext(obj_ext)] self.compiled_tasks.append(task) return task cc_str='${CC} ${CCFLAGS} ${CPPFLAGS} ${_CCINCFLAGS} ${_CCDEFFLAGS} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}' cls=Task.simple_task_type('cc',cc_str,'GREEN',ext_out='.o',ext_in='.c',shell=False) cls.scan=ccroot.scan cls.vars.append('CCDEPS') link_str='${LINK_CC} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT} ${LINKFLAGS}' cls=Task.simple_task_type('cc_link',link_str,color='YELLOW',ext_in='.o',shell=False) cls.maxjobs=1 cls2=Task.task_type_from_func('vnum_cc_link',ccroot.link_vnum,cls.vars,color='CYAN',ext_in='.o') cls2.maxjobs=1 feature('cc')(init_cc) before('apply_type_vars')(init_cc) after('default_cc')(init_cc) feature('cc')(apply_obj_vars_cc) after('apply_incpaths')(apply_obj_vars_cc) feature('cc')(apply_defines_cc) after('apply_lib_vars')(apply_defines_cc) extension(EXT_CC)(c_hook) slv2-0.6.6+dfsg1/wafadmin/Tools/glib2.py0000644000175000017500000000774311176703511017545 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import Task,Utils from TaskGen import taskgen,before,after,feature def add_marshal_file(self,filename,prefix): if not hasattr(self,'marshal_list'): self.marshal_list=[] self.meths.append('process_marshal') self.marshal_list.append((filename,prefix)) def process_marshal(self): for f,prefix in getattr(self,'marshal_list',[]): node=self.path.find_resource(f) if not node: raise Utils.WafError('file not found %r'%f) h_node=node.change_ext('.h') c_node=node.change_ext('.c') task=self.create_task('glib_genmarshal') task.set_inputs(node) task.set_outputs([h_node,c_node]) task.env['GLIB_GENMARSHAL_PREFIX']=prefix self.allnodes.append(c_node) def genmarshal_func(self): bld=self.inputs[0].__class__.bld get=self.env.get_flat cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(self.env),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath(self.env)) ret=bld.exec_command(cmd1) if ret:return ret f=open(self.outputs[1].abspath(self.env),'wb') f.write('''#include "%s"\n'''%self.outputs[0].name) f.close() cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(self.env),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath(self.env)) ret=Utils.exec_command(cmd2) if ret:return ret def add_enums_from_template(self,source='',target='',template='',comments=''): if not hasattr(self,'enums_list'): self.enums_list=[] self.meths.append('process_enums') self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments}) def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''): if not hasattr(self,'enums_list'): self.enums_list=[] self.meths.append('process_enums') self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments}) def process_enums(self): for enum in getattr(self,'enums_list',[]): env=self.env.copy() task=self.create_task('glib_mkenums',env) inputs=[] source_list=self.to_list(enum['source']) if not source_list: raise Utils.WafError('missing source '+str(enum)) source_list=[self.path.find_resource(k)for k in source_list] inputs+=source_list env['GLIB_MKENUMS_SOURCE']=[k.srcpath(env)for k in source_list] if not enum['target']: raise Utils.WafError('missing target '+str(enum)) tgt_node=self.path.find_or_declare(enum['target']) if tgt_node.name.endswith('.c'): self.allnodes.append(tgt_node) env['GLIB_MKENUMS_TARGET']=tgt_node.abspath(env) options=[] if enum['template']: template_node=self.path.find_resource(enum['template']) options.append('--template %s'%(template_node.abspath(env))) inputs.append(template_node) params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'} for param,option in params.iteritems(): if enum[param]: options.append('%s %r'%(option,enum[param])) env['GLIB_MKENUMS_OPTIONS']=' '.join(options) task.set_inputs(inputs) task.set_outputs(tgt_node) Task.task_type_from_func('glib_genmarshal',func=genmarshal_func,vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL'],color='BLUE',before='cc') Task.simple_task_type('glib_mkenums','${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}',color='PINK',before='cc') def detect(conf): glib_genmarshal=conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL') mk_enums_tool=conf.find_program('glib-mkenums',var='GLIB_MKENUMS') taskgen(add_marshal_file) before('apply_core')(process_marshal) taskgen(add_enums_from_template) taskgen(add_enums) before('apply_core')(process_enums) slv2-0.6.6+dfsg1/wafadmin/Tools/dbus.py0000644000175000017500000000201511176703511017466 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import Task,Utils from TaskGen import taskgen,before,after,feature def add_dbus_file(self,filename,prefix,mode): if not hasattr(self,'dbus_lst'): self.dbus_lst=[] self.meths.append('process_dbus') self.dbus_lst.append([filename,prefix,mode]) def process_dbus(self): for filename,prefix,mode in getattr(self,'dbus_lst',[]): env=self.env.copy() node=self.path.find_resource(filename) if not node: raise Utils.WafError('file not found '+filename) env['DBUS_BINDING_TOOL_PREFIX']=prefix env['DBUS_BINDING_TOOL_MODE']=mode task=self.create_task('dbus_binding_tool',env) task.set_inputs(node) task.set_outputs(node.change_ext('.h')) Task.simple_task_type('dbus_binding_tool','${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}',color='BLUE',before='cc') def detect(conf): dbus_binding_tool=conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL') taskgen(add_dbus_file) before('apply_core')(process_dbus) slv2-0.6.6+dfsg1/wafadmin/Tools/java.py0000644000175000017500000001064311176703511017460 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os,re from Configure import conf import TaskGen,Task,Utils from TaskGen import feature,before,taskgen class_check_source=''' public class Test { public static void main(String[] argv) { Class lib; if (argv.length < 1) { System.err.println("Missing argument"); System.exit(77); } try { lib = Class.forName(argv[0]); } catch (ClassNotFoundException e) { System.err.println("ClassNotFoundException"); System.exit(1); } lib = null; System.exit(0); } } ''' def jar_files(self): basedir=getattr(self,'basedir','.') destfile=getattr(self,'destfile','test.jar') jaropts=getattr(self,'jaropts',[]) dir=self.path.find_dir(basedir) if not dir:raise jaropts.append('-C') jaropts.append(dir.abspath(self.env)) jaropts.append('.') out=self.path.find_or_declare(destfile) tsk=self.create_task('jar_create') tsk.set_outputs(out) tsk.inputs=[x for x in dir.find_iter(src=0,bld=1)if x.id!=out.id] tsk.env['JAROPTS']=jaropts tsk.env['JARCREATE']='cf' def apply_java(self): Utils.def_attrs(self,jarname='',jaropts='',classpath='',source_root='.',source_re='[A-Za-z0-9]+\.java$',jar_mf_attributes={},jar_mf_classpath=[]) nodes_lst=[] if not self.classpath: if not self.env['CLASSPATH']: self.env['CLASSPATH']='..'+os.pathsep+'.' else: self.env['CLASSPATH']=self.classpath source_root_node=self.path.find_dir(self.source_root) re_foo=re.compile(self.source_re) def acc(node,name): return re_foo.search(name)>-1 def prune(node,name): if name=='.svn':return True return False src_nodes=[x for x in source_root_node.find_iter_impl(dir=False,accept_name=acc,is_prune=prune)] bld_nodes=[x.change_ext('.class')for x in src_nodes] self.env['OUTDIR']=[source_root_node.abspath(self.env)] tsk=self.create_task('javac') tsk.set_inputs(src_nodes) tsk.set_outputs(bld_nodes) if self.jarname: tsk=self.create_task('jar_create') tsk.set_inputs(bld_nodes) tsk.set_outputs(self.path.find_or_declare(self.jarname)) if not self.env['JAROPTS']: if self.jaropts: self.env['JAROPTS']=self.jaropts else: dirs='.' self.env['JAROPTS']=['-C',''.join(self.env['OUTDIR']),dirs] Task.simple_task_type('jar_create','${JAR} ${JARCREATE} ${TGT} ${JAROPTS}',color='GREEN') cls=Task.simple_task_type('javac','${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}') cls.color='BLUE' def post_run_javac(self): par={} for x in self.inputs: par[x.parent.id]=x.parent inner={} for k in par.values(): path=k.abspath(self.env) lst=os.listdir(path) for u in lst: if u.find('$')>=0: inner_class_node=k.find_or_declare(u) inner[inner_class_node.id]=inner_class_node to_add=set(inner.keys())-set([x.id for x in self.outputs]) for x in to_add: self.outputs.append(inner[x]) return Task.Task.post_run(self) cls.post_run=post_run_javac def detect(conf): java_path=conf.environ['PATH'].split(os.pathsep) v=conf.env if'JAVA_HOME'in conf.environ: java_path=[os.path.join(conf.environ['JAVA_HOME'],'bin')]+java_path conf.env['JAVA_HOME']=[conf.environ['JAVA_HOME']] for x in'javac java jar'.split(): conf.find_program(x,var=x.upper(),path_list=java_path) conf.env[x.upper()]=conf.cmd_to_list(conf.env[x.upper()]) v['JAVA_EXT']=['.java'] if'CLASSPATH'in conf.environ: v['CLASSPATH']=conf.environ['CLASSPATH'] if not v['JAR']:conf.fatal('jar is required for making java packages') if not v['JAVAC']:conf.fatal('javac is required for compiling java classes') v['JARCREATE']='cf' def check_java_class(self,classname,with_classpath=None): import shutil javatestdir='.waf-javatest' classpath=javatestdir if self.env['CLASSPATH']: classpath+=os.pathsep+self.env['CLASSPATH'] if isinstance(with_classpath,str): classpath+=os.pathsep+with_classpath shutil.rmtree(javatestdir,True) os.mkdir(javatestdir) java_file=open(os.path.join(javatestdir,'Test.java'),'w') java_file.write(class_check_source) java_file.close() Utils.exec_command(self.env['JAVAC']+[os.path.join(javatestdir,'Test.java')],shell=False) cmd=self.env['JAVA']+['-cp',classpath,'Test',classname] self.log.write("%s\n"%str(cmd)) found=Utils.exec_command(cmd,shell=False,log=self.log) self.check_message('Java class %s'%classname,"",not found) shutil.rmtree(javatestdir,True) return found feature('jar')(jar_files) before('apply_core')(jar_files) feature('javac')(apply_java) before('apply_core')(apply_java) conf(check_java_class) slv2-0.6.6+dfsg1/wafadmin/Tools/icc.py0000644000175000017500000000130511176703511017270 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys import Configure,Options,Utils import ccroot,ar,gcc from Configure import conftest def find_icc(conf): if sys.platform=='cygwin': conf.fatal('The Intel compiler does not work on Cygwin') v=conf.env cc=None if v['CC']:cc=v['CC'] elif'CC'in conf.environ:cc=conf.environ['CC'] if not cc:cc=conf.find_program('icc',var='CC') if not cc:cc=conf.find_program('ICL',var='CC') if not cc:conf.fatal('Intel C Compiler (icc) was not found') cc=conf.cmd_to_list(cc) ccroot.get_cc_version(conf,cc,icc=True) v['CC']=cc v['CC_NAME']='icc' detect=''' find_icc find_ar gcc_common_flags gcc_modifier_darwin cc_load_tools cc_add_flags ''' conftest(find_icc) slv2-0.6.6+dfsg1/wafadmin/Tools/dmd.py0000644000175000017500000000217511176703511017304 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys import ar def find_dmd(conf): v=conf.env d_compiler=None if v['D_COMPILER']: d_compiler=v['D_COMPILER'] if not d_compiler:d_compiler=conf.find_program('dmd',var='D_COMPILER') if not d_compiler:return 0 v['D_COMPILER']=d_compiler def common_flags(conf): v=conf.env v['DFLAGS']=['-version=Posix'] v['D_SRC_F']='' v['D_TGT_F']=['-c','-of'] v['DPATH_ST']='-I%s' v['D_LINKER']=v['D_COMPILER'] v['DLNK_SRC_F']='' v['DLNK_TGT_F']='-of' v['DLIB_ST']='-L-l%s' v['DLIBPATH_ST']='-L-L%s' v['DFLAGS_OPTIMIZED']=['-O'] v['DFLAGS_DEBUG']=['-g','-debug'] v['DFLAGS_ULTRADEBUG']=['-g','-debug'] v['DLINKFLAGS']=['-quiet'] v['D_shlib_DFLAGS']=['-fPIC'] v['D_shlib_LINKFLAGS']=['-L-shared'] v['DHEADER_ext']='.di' v['D_HDR_F']=['-H','-Hf'] if sys.platform=="win32": v['D_program_PATTERN']='%s.exe' v['D_shlib_PATTERN']='lib%s.dll' v['D_staticlib_PATTERN']='lib%s.a' else: v['D_program_PATTERN']='%s' v['D_shlib_PATTERN']='lib%s.so' v['D_staticlib_PATTERN']='lib%s.a' def detect(conf): v=conf.env find_dmd(conf) ar.find_ar(conf) conf.check_tool('d') common_flags(conf) slv2-0.6.6+dfsg1/wafadmin/Tools/ar.py0000644000175000017500000000165411176703511017143 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys import Task from Configure import conftest ar_str='${AR} ${ARFLAGS} ${TGT} ${SRC}' cls=Task.simple_task_type('ar_link_static',ar_str,color='YELLOW',ext_in='.o',shell=False) cls.maxjobs=1 old=cls.run def wrap(self): try:os.remove(self.outputs[0].abspath(self.env)) except OSError:pass return old(self) setattr(cls,'run',wrap) def detect(conf): comp=conf.environ.get('AR','') if not comp:comp=conf.env['AR'] if not comp:comp=conf.find_program('ar',var='AR') if not comp:return ranlib=conf.environ.get('RANLIB','') if not ranlib:ranlib=conf.env['RANLIB'] if not ranlib:ranlib=conf.find_program('ranlib',var='RANLIB') if not ranlib:return v=conf.env v['AR']=comp v['ARFLAGS']='rcs' v['RANLIB']=ranlib v['RANLIBFLAGS']='' def find_ar(conf): v=conf.env conf.check_tool('ar') if not v['AR']:conf.fatal('ar is required for static libraries - not found') conftest(find_ar) slv2-0.6.6+dfsg1/wafadmin/Tools/tex.py0000644000175000017500000001306511176703511017340 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,re import Utils,TaskGen,Task,Runner,Build from TaskGen import feature,before from Logs import error,warn,debug re_tex=re.compile(r'\\(?Pinclude|input|import|bringin){(?P[^{}]*)}',re.M) def scan(self): node=self.inputs[0] env=self.env nodes=[] names=[] if not node:return(nodes,names) code=Utils.readf(node.abspath(env)) curdirnode=self.curdirnode abs=curdirnode.abspath() for match in re_tex.finditer(code): path=match.group('file') if path: for k in['','.tex','.ltx']: debug('tex: trying %s%s'%(path,k)) try: os.stat(abs+os.sep+path+k) except OSError: continue found=path+k node=curdirnode.find_resource(found) if node: nodes.append(node) else: debug('tex: could not find %s'%path) names.append(path) debug("tex: found the following : %s and names %s"%(nodes,names)) return(nodes,names) g_bibtex_re=re.compile('bibdata',re.M) def tex_build(task,command='LATEX'): env=task.env bld=task.generator.bld com='%s %s'%(env[command],env.get_flat(command+'FLAGS')) if not env['PROMPT_LATEX']:com="%s %s"%(com,'-interaction=batchmode') node=task.inputs[0] reldir=node.bld_dir(env) srcfile=node.srcpath(env) lst=[] for c in Utils.split_path(reldir): if c:lst.append('..') sr=os.path.join(*(lst+[srcfile])) sr2=os.path.join(*(lst+[node.parent.srcpath(env)])) aux_node=node.change_ext('.aux') idx_node=node.change_ext('.idx') hash='' old_hash='' nm=aux_node.name docuname=nm[:len(nm)-4] latex_compile_cmd='cd %s && TEXINPUTS=%s:$TEXINPUTS %s %s'%(reldir,sr2,com,sr) warn('first pass on %s'%command) ret=bld.exec_command(latex_compile_cmd) if ret:return ret try: ct=Utils.readf(aux_node.abspath(env)) except(OSError,IOError): error('error bibtex scan') else: fo=g_bibtex_re.findall(ct) if fo: bibtex_compile_cmd='cd %s && BIBINPUTS=%s:$BIBINPUTS %s %s'%(reldir,sr2,env['BIBTEX'],docuname) warn('calling bibtex') ret=bld.exec_command(bibtex_compile_cmd) if ret: error('error when calling bibtex %s'%bibtex_compile_cmd) return ret try: idx_path=idx_node.abspath(env) os.stat(idx_path) except OSError: error('error file.idx scan') else: makeindex_compile_cmd='cd %s && %s %s'%(reldir,env['MAKEINDEX'],idx_path) warn('calling makeindex') ret=bld.exec_command(makeindex_compile_cmd) if ret: error('error when calling makeindex %s'%makeindex_compile_cmd) return ret i=0 while i<10: i+=1 old_hash=hash try: hash=Utils.h_file(aux_node.abspath(env)) except KeyError: error('could not read aux.h -> %s'%aux_node.abspath(env)) pass if hash and hash==old_hash:break warn('calling %s'%command) ret=bld.exec_command(latex_compile_cmd) if ret: error('error when calling %s %s'%(command,latex_compile_cmd)) return ret return 0 latex_vardeps=['LATEX','LATEXFLAGS'] def latex_build(task): return tex_build(task,'LATEX') pdflatex_vardeps=['PDFLATEX','PDFLATEXFLAGS'] def pdflatex_build(task): return tex_build(task,'PDFLATEX') class tex_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def apply_tex(self): if not getattr(self,'type',None)in['latex','pdflatex']: self.type='pdflatex' tree=self.bld outs=Utils.to_list(getattr(self,'outs',[])) self.env['PROMPT_LATEX']=getattr(self,'prompt',1) deps_lst=[] if getattr(self,'deps',None): deps=self.to_list(self.deps) for filename in deps: n=self.path.find_resource(filename) if not n in deps_lst:deps_lst.append(n) self.source=self.to_list(self.source) for filename in self.source: base,ext=os.path.splitext(filename) node=self.path.find_resource(filename) if not node:raise Utils.WafError('cannot find %s'%filename) if self.type=='latex': task=self.create_task('latex') task.set_inputs(node) task.set_outputs(node.change_ext('.dvi')) elif self.type=='pdflatex': task=self.create_task('pdflatex') task.set_inputs(node) task.set_outputs(node.change_ext('.pdf')) task.env=self.env task.curdirnode=self.path if deps_lst: variant=node.variant(self.env) try: lst=tree.node_deps[task.unique_id()] for n in deps_lst: if not n in lst: lst.append(n) except KeyError: tree.node_deps[task.unique_id()]=deps_lst if self.type=='latex': if'ps'in outs: pstask=self.create_task('dvips') pstask.set_inputs(task.outputs) pstask.set_outputs(node.change_ext('.ps')) if'pdf'in outs: pdftask=self.create_task('dvipdf') pdftask.set_inputs(task.outputs) pdftask.set_outputs(node.change_ext('.pdf')) elif self.type=='pdflatex': if'ps'in outs: pstask=self.create_task('pdf2ps') pstask.set_inputs(task.outputs) pstask.set_outputs(node.change_ext('.ps')) self.source=[] def detect(conf): v=conf.env for p in'tex latex pdflatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split(): conf.find_program(p,var=p.upper()) v[p.upper()+'FLAGS']='' v['DVIPSFLAGS']='-Ppdf' b=Task.simple_task_type b('tex','${TEX} ${TEXFLAGS} ${SRC}',color='BLUE',shell=False) b('bibtex','${BIBTEX} ${BIBTEXFLAGS} ${SRC}',color='BLUE',shell=False) b('dvips','${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}',color='BLUE',after="latex pdflatex tex bibtex",shell=False) b('dvipdf','${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}',color='BLUE',after="latex pdflatex tex bibtex",shell=False) b('pdf2ps','${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}',color='BLUE',after="dvipdf pdflatex",shell=False) b=Task.task_type_from_func cls=b('latex',latex_build,vars=latex_vardeps) cls.scan=scan cls=b('pdflatex',pdflatex_build,vars=pdflatex_vardeps) cls.scan=scan feature('tex')(apply_tex) before('apply_core')(apply_tex) slv2-0.6.6+dfsg1/wafadmin/Tools/compiler_d.py0000644000175000017500000000151711176703511020654 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,imp,types import Utils,Configure,Options def detect(conf): if getattr(Options.options,'check_dmd_first',None): test_for_compiler=['dmd','gdc'] else: test_for_compiler=['gdc','dmd'] for d_compiler in test_for_compiler: conf.check_tool(d_compiler) if conf.env['D_COMPILER']: conf.check_message("%s"%d_compiler,'',True) conf.env["COMPILER_D"]=d_compiler return conf.check_message("%s"%d_compiler,'',False) def set_options(opt): d_compiler_opts=opt.add_option_group("D Compiler Options") d_compiler_opts.add_option('--check-dmd-first',action="store_true",help='checks for the gdc compiler before dmd (default is the other way round)',dest='check_dmd_first',default=False) for d_compiler in['gdc','dmd']: opt.tool_options('%s'%d_compiler,option_group=d_compiler_opts) slv2-0.6.6+dfsg1/wafadmin/Tools/python.py0000644000175000017500000002576111176703511020067 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys import TaskGen,Utils,Utils,Runner,Options,Build from Logs import debug,warn,info from TaskGen import extension,taskgen,before,after,feature from Configure import conf EXT_PY=['.py'] FRAG_2=''' #ifdef __cplusplus extern "C" { #endif void Py_Initialize(void); void Py_Finalize(void); #ifdef __cplusplus } #endif int main(int argc, char *argv[]) { argc++; /* avoid unused variable warning */ argv++; /* avoid unused variable warning */ Py_Initialize(); Py_Finalize(); return 0; } ''' def init_pyext(self): self.default_install_path='${PYTHONDIR}' self.uselib=self.to_list(getattr(self,'uselib','')) if not'PYEXT'in self.uselib: self.uselib.append('PYEXT') self.env['MACBUNDLE']=True def pyext_shlib_ext(self): self.env['shlib_PATTERN']=self.env['pyext_PATTERN'] def init_pyembed(self): self.uselib=self.to_list(getattr(self,'uselib','')) if not'PYEMBED'in self.uselib: self.uselib.append('PYEMBED') def process_py(self,node): if self.bld.is_install and self.install_path: if not hasattr(self,'_py_installed_files'): self._py_installed_files=[] installed_files=self.bld.install_files(self.install_path,node.abspath(self.env),self.env,self.chmod) self._py_installed_files.extend(installed_files) def byte_compile_py(self): if self.bld.is_install and self.install_path: installed_files=self._py_installed_files if not installed_files: return if self.bld.is_install<0: info("* removing byte compiled python files") for fname in installed_files: try: os.remove(fname+'c') except OSError: pass try: os.remove(fname+'o') except OSError: pass if self.bld.is_install>0: if self.env['PYC']or self.env['PYO']: info("* byte compiling python files") if self.env['PYC']: program=(""" import sys, py_compile for pyfile in sys.argv[1:]: py_compile.compile(pyfile, pyfile + 'c') """) argv=[self.env['PYTHON'],"-c",program] argv.extend(installed_files) retval=Utils.pproc.Popen(argv).wait() if retval: raise Utils.WafError("bytecode compilation failed") if self.env['PYO']: program=(""" import sys, py_compile for pyfile in sys.argv[1:]: py_compile.compile(pyfile, pyfile + 'o') """) argv=[self.env['PYTHON'],self.env['PYFLAGS_OPT'],"-c",program] argv.extend(installed_files) retval=Utils.pproc.Popen(argv).wait() if retval: raise Utils.WafError("bytecode compilation failed") class py_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def init_py(self): self.default_install_path='${PYTHONDIR}' def _get_python_variables(python_exe,variables,imports=['import sys']): program=list(imports) program.append('') for v in variables: program.append("print(repr(%s))"%v) os_env=dict(os.environ) try: del os_env['MACOSX_DEPLOYMENT_TARGET'] except KeyError: pass proc=Utils.pproc.Popen([python_exe,"-c",'\n'.join(program)],stdout=Utils.pproc.PIPE,env=os_env) output=proc.communicate()[0].split("\n") if proc.returncode: if Options.options.verbose: warn("Python program to extract python configuration variables failed:\n%s"%'\n'.join(["line %03i: %s"%(lineno+1,line)for lineno,line in enumerate(program)])) raise RuntimeError return_values=[] for s in output: s=s.strip() if not s: continue if s=='None': return_values.append(None) elif s[0]=="'"and s[-1]=="'": return_values.append(s[1:-1]) elif s[0].isdigit(): return_values.append(int(s)) else:break return return_values def check_python_headers(conf): if not conf.env['CC_NAME']and not conf.env['CXX_NAME']: conf.fatal('load a compiler first (gcc, g++, ..)') env=conf.env python=env['PYTHON'] assert python,("python is %r !"%(python,)) if Options.platform=='darwin': conf.check_tool('osx') try: v='prefix SO SYSLIBS LDFLAGS SHLIBS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET'.split() (python_prefix,python_SO,python_SYSLIBS,python_LDFLAGS,python_SHLIBS,python_LIBDIR,python_LIBPL,INCLUDEPY,Py_ENABLE_SHARED,python_MACOSX_DEPLOYMENT_TARGET)=_get_python_variables(python,["get_config_var('%s')"%x for x in v],['from distutils.sysconfig import get_config_var']) except RuntimeError: conf.fatal("Python development headers not found (-v for details).") conf.log.write("""Configuration returned from %r: python_prefix = %r python_SO = %r python_SYSLIBS = %r python_LDFLAGS = %r python_SHLIBS = %r python_LIBDIR = %r python_LIBPL = %r INCLUDEPY = %r Py_ENABLE_SHARED = %r MACOSX_DEPLOYMENT_TARGET = %r """%(python,python_prefix,python_SO,python_SYSLIBS,python_LDFLAGS,python_SHLIBS,python_LIBDIR,python_LIBPL,INCLUDEPY,Py_ENABLE_SHARED,python_MACOSX_DEPLOYMENT_TARGET)) if python_MACOSX_DEPLOYMENT_TARGET: conf.env['MACOSX_DEPLOYMENT_TARGET']=python_MACOSX_DEPLOYMENT_TARGET conf.environ['MACOSX_DEPLOYMENT_TARGET']=python_MACOSX_DEPLOYMENT_TARGET env['pyext_PATTERN']='%s'+python_SO if python_SYSLIBS is not None: for lib in python_SYSLIBS.split(): if lib.startswith('-l'): lib=lib[2:] env.append_value('LIB_PYEMBED',lib) if python_SHLIBS is not None: for lib in python_SHLIBS.split(): if lib.startswith('-l'): lib=lib[2:] env.append_value('LIB_PYEMBED',lib) if Options.platform!='darwin'and python_LDFLAGS: env.append_value('LINKFLAGS_PYEMBED',python_LDFLAGS.split()) result=False name='python'+env['PYTHON_VERSION'] if python_LIBDIR is not None: path=[python_LIBDIR] conf.log.write("\n\n# Trying LIBDIR: %r\n"%path) result=conf.check(lib=name,uselib='PYEMBED',libpath=path) if not result and python_LIBPL is not None: conf.log.write("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n") path=[python_LIBPL] result=conf.check(lib=name,uselib='PYEMBED',libpath=path) if not result: conf.log.write("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n") path=[os.path.join(python_prefix,"libs")] name='python'+env['PYTHON_VERSION'].replace('.','') result=conf.check(lib=name,uselib='PYEMBED',libpath=path) if result: env['LIBPATH_PYEMBED']=path env.append_value('LIB_PYEMBED',name) else: conf.log.write("\n\n### LIB NOT FOUND\n") if(sys.platform=='win32'or sys.platform.startswith('os2')or sys.platform=='darwin'or Py_ENABLE_SHARED): env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED'] env['LIB_PYEXT']=env['LIB_PYEMBED'] python_config=conf.find_program('python%s-config'%('.'.join(env['PYTHON_VERSION'].split('.')[:2])),var='PYTHON_CONFIG') if not python_config: python_config=conf.find_program('python-config-%s'%('.'.join(env['PYTHON_VERSION'].split('.')[:2])),var='PYTHON_CONFIG') includes=[] if python_config: for incstr in Utils.cmd_output("%s %s --includes"%(python,python_config)).strip().split(): if(incstr.startswith('-I')or incstr.startswith('/I')): incstr=incstr[2:] if incstr not in includes: includes.append(incstr) conf.log.write("Include path for Python extensions ""(found via python-config --includes): %r\n"%(includes,)) env['CPPPATH_PYEXT']=includes env['CPPPATH_PYEMBED']=includes else: conf.log.write("Include path for Python extensions ""(found via distutils module): %r\n"%(INCLUDEPY,)) env['CPPPATH_PYEXT']=[INCLUDEPY] env['CPPPATH_PYEMBED']=[INCLUDEPY] if env['CC_NAME']=='gcc': env.append_value('CCFLAGS_PYEMBED','-fno-strict-aliasing') env.append_value('CCFLAGS_PYEXT','-fno-strict-aliasing') if env['CXX_NAME']=='gcc': env.append_value('CXXFLAGS_PYEMBED','-fno-strict-aliasing') env.append_value('CXXFLAGS_PYEXT','-fno-strict-aliasing') test_env=env.copy() a=test_env.append_value a('CPPPATH',env['CPPPATH_PYEMBED']) a('LIBPATH',env['LIBPATH_PYEMBED']) a('LIB',env['LIB_PYEMBED']) a('LINKFLAGS',env['LINKFLAGS_PYEMBED']) a('CXXFLAGS',env['CXXFLAGS_PYEMBED']) a('CCFLAGS',env['CCFLAGS_PYEMBED']) conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',env=test_env,fragment=FRAG_2,errmsg='Could not find the python development headers',mandatory=1) def check_python_version(conf,minver=None): assert minver is None or isinstance(minver,tuple) python=conf.env['PYTHON'] assert python,("python is %r !"%(python,)) cmd=[python,"-c","import sys\nfor x in sys.version_info: print(str(x))"] debug('python: Running python command %r'%cmd) proc=Utils.pproc.Popen(cmd,stdout=Utils.pproc.PIPE) lines=proc.communicate()[0].split() assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines) pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4])) result=(minver is None)or(pyver_tuple>=minver) if result: pyver='.'.join([str(x)for x in pyver_tuple[:2]]) conf.env['PYTHON_VERSION']=pyver if'PYTHONDIR'in conf.environ: pydir=conf.environ['PYTHONDIR'] else: if sys.platform=='win32': (python_LIBDEST,)=_get_python_variables(python,["get_config_var('LIBDEST')"],['from distutils.sysconfig import get_config_var']) else: python_LIBDEST=None if python_LIBDEST is None: if conf.env['LIBDIR']: python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver) else: python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver) pydir=os.path.join(python_LIBDEST,"site-packages") if hasattr(conf,'define'): conf.define('PYTHONDIR',pydir) conf.env['PYTHONDIR']=pydir pyver_full='.'.join(map(str,pyver_tuple[:3])) if minver is None: conf.check_message_custom('Python version','',pyver_full) else: minver_str='.'.join(map(str,minver)) conf.check_message('Python version',">= %s"%(minver_str,),result,option=pyver_full) if not result: conf.fatal("Python too old.") def check_python_module(conf,module_name): result=not Utils.pproc.Popen([conf.env['PYTHON'],"-c","import %s"%module_name],stderr=Utils.pproc.PIPE,stdout=Utils.pproc.PIPE).wait() conf.check_message('Python module',module_name,result) if not result: conf.fatal("Python module not found.") def detect(conf): python=conf.find_program('python',var='PYTHON') if not python:return v=conf.env v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"' v['PYFLAGS']='' v['PYFLAGS_OPT']='-O' v['PYC']=getattr(Options.options,'pyc',1) v['PYO']=getattr(Options.options,'pyo',1) def set_options(opt): opt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc') opt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo') before('apply_incpaths','apply_lib_vars','apply_type_vars')(init_pyext) feature('pyext')(init_pyext) before('apply_bundle')(init_pyext) before('apply_link','apply_lib_vars','apply_type_vars')(pyext_shlib_ext) after('apply_bundle')(pyext_shlib_ext) feature('pyext')(pyext_shlib_ext) before('apply_incpaths','apply_lib_vars','apply_type_vars')(init_pyembed) feature('pyembed')(init_pyembed) extension(EXT_PY)(process_py) feature('py')(byte_compile_py) before('apply_core')(init_py) after('vars_target_cprogram','vars_target_cstaticlib')(init_py) feature('py')(init_py) conf(check_python_headers) conf(check_python_version) conf(check_python_module) slv2-0.6.6+dfsg1/wafadmin/Tools/preproc.py0000644000175000017500000003752011176703511020214 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import re,sys,os,string import Logs,Build,Utils from Logs import debug,error import traceback class PreprocError(Utils.WafError): pass POPFILE='-' go_absolute=0 standard_includes=['/usr/include'] if sys.platform=="win32": standard_includes=[] use_trigraphs=0 'apply the trigraph rules first' strict_quotes=0 g_optrans={'not':'!','and':'&&','bitand':'&','and_eq':'&=','or':'||','bitor':'|','or_eq':'|=','xor':'^','xor_eq':'^=','compl':'~',} re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE) re_mac=re.compile("^[a-zA-Z_]\w*") re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE) re_nl=re.compile('\\\\\r*\n',re.MULTILINE) re_cpp=re.compile(r"""(/\*[^*]*\*+([^/*][^*]*\*+)*/)|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)""",re.MULTILINE) trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')] chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39} NUM='i' OP='O' IDENT='T' STR='s' CHAR='c' tok_types=[NUM,STR,IDENT,OP] exp_types=[r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',] re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M) accepted='a' ignored='i' undefined='u' skipped='s' def repl(m): s=m.group(1) if s is not None:return' ' s=m.group(3) if s is None:return'' return s def filter_comments(filename): code=Utils.readf(filename) if use_trigraphs: for(a,b)in trig_def:code=code.split(a).join(b) code=re_nl.sub('',code) code=re_cpp.sub(repl,code) return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)] prec={} ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',','] for x in range(len(ops)): syms=ops[x] for u in syms.split(): prec[u]=x def reduce_nums(val_1,val_2,val_op): try:a=0+val_1 except TypeError:a=int(val_1) try:b=0+val_2 except TypeError:b=int(val_2) d=val_op if d=='%':c=a%b elif d=='+':c=a+b elif d=='-':c=a-b elif d=='*':c=a*b elif d=='/':c=a/b elif d=='^':c=a^b elif d=='|':c=a|b elif d=='||':c=int(a or b) elif d=='&':c=a&b elif d=='&&':c=int(a and b) elif d=='==':c=int(a==b) elif d=='!=':c=int(a!=b) elif d=='<=':c=int(a<=b) elif d=='<':c=int(a':c=int(a>b) elif d=='>=':c=int(a>=b) elif d=='^':c=int(a^b) elif d=='<<':c=a<>':c=a>>b else:c=0 return c def get_num(lst): if not lst:raise PreprocError("empty list for get_num") (p,v)=lst[0] if p==OP: if v=='(': count_par=1 i=1 while i=prec[v]: num2=reduce_nums(num,num2,v) return get_term([(NUM,num2)]+lst) else: num3,lst=get_num(lst[1:]) num3=reduce_nums(num2,num3,v2) return get_term([(NUM,num),(p,v),(NUM,num3)]+lst) raise PreprocError("cannot reduce %r"%lst) def reduce_eval(lst): num,lst=get_term(lst) return(NUM,num) def stringize(lst): lst=[str(v2)for(p2,v2)in lst] return"".join(lst) def paste_tokens(t1,t2): p1=None if t1[0]==OP and t2[0]==OP: p1=OP elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM): p1=IDENT elif t1[0]==NUM and t2[0]==NUM: p1=NUM if not p1: raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2)) return(p1,t1[1]+t2[1]) def reduce_tokens(lst,defs,ban=[]): i=0 while i=len(lst): raise PreprocError("expected '(' after %r (got nothing)"%v) (p2,v2)=lst[i] if p2!=OP or v2!='(': raise PreprocError("expected '(' after %r"%v) del lst[i] one_param=[] count_paren=0 while i1: (p3,v3)=accu[-1] (p4,v4)=accu[-2] if v3=='##': accu.pop() if v4==','and pt.*)>|"(?P.*)")') def extract_include(txt,defs): m=re_include.search(txt) if m: if m.group('a'):return'<',m.group('a') if m.group('b'):return'"',m.group('b') toks=tokenize(txt) reduce_tokens(toks,defs,['waf_include']) if not toks: raise PreprocError("could not parse include %s"%txt) if len(toks)==1: if toks[0][0]==STR: return'"',toks[0][1] else: if toks[0][1]=='<'and toks[-1][1]=='>': return stringize(toks).lstrip('<').rstrip('>') raise PreprocError("could not parse include %s."%txt) def parse_char(txt): if not txt:raise PreprocError("attempted to parse a null char") if txt[0]!='\\': return ord(txt) c=txt[1] if c=='x': if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16) return int(txt[2:],16) elif c.isdigit(): if c=='0'and len(txt)==2:return 0 for i in 3,2,1: if len(txt)>i and txt[1:1+i].isdigit(): return(1+i,int(txt[1:1+i],8)) else: try:return chr_esc[c] except KeyError:raise PreprocError("could not parse char literal '%s'"%txt) def tokenize(s): ret=[] for match in re_clexer.finditer(s): m=match.group for name in tok_types: v=m(name) if v: if name==IDENT: try:v=g_optrans[v];name=OP except KeyError: if v.lower()=="true": v=1 name=NUM elif v.lower()=="false": v=0 name=NUM elif name==NUM: if m('oct'):v=int(v,8) elif m('hex'):v=int(m('hex'),16) elif m('n0'):v=m('n0') else: v=m('char') if v:v=parse_char(v) else:v=m('n2')or m('n4') elif name==OP: if v=='%:':v='#' elif v=='%:%:':v='##' elif name==STR: v=v[1:-1] ret.append((name,v)) break return ret class c_parser(object): def __init__(self,nodepaths=None,defines=None): self.lines=[] if defines is None: self.defs={} else: self.defs=dict(defines) self.state=[] self.env=None self.count_files=0 self.currentnode_stack=[] self.nodepaths=nodepaths or[] self.nodes=[] self.names=[] self.curfile='' self.ban_includes=[] def tryfind(self,filename): self.curfile=filename found=self.currentnode_stack[-1].find_resource(filename) for n in self.nodepaths: if found: break found=n.find_resource(filename) if not found: if not filename in self.names: self.names.append(filename) else: self.nodes.append(found) if filename[-4:]!='.moc': self.addlines(found) return found def addlines(self,node): self.currentnode_stack.append(node.parent) filepath=node.abspath(self.env) self.count_files+=1 if self.count_files>30000:raise PreprocError("recursion limit exceeded") pc=self.parse_cache debug('preproc: reading file %r'%filepath) try: lns=pc[filepath] except KeyError: pass else: self.lines=lns+self.lines return try: lines=filter_comments(filepath) lines.append((POPFILE,'')) pc[filepath]=lines self.lines=lines+self.lines except IOError: raise PreprocError("could not read the file %s"%filepath) except Exception: if Logs.verbose>0: error("parsing %s failed"%filepath) traceback.print_exc() def start(self,node,env): debug('preproc: scanning %s (in %s)'%(node.name,node.parent.name)) self.env=env variant=node.variant(env) bld=node.__class__.bld try: self.parse_cache=bld.parse_cache except AttributeError: bld.parse_cache={} self.parse_cache=bld.parse_cache self.addlines(node) if env['DEFLINES']: self.lines=[('define',x)for x in env['DEFLINES']]+self.lines while self.lines: (kind,line)=self.lines.pop(0) if kind==POPFILE: self.currentnode_stack.pop() continue try: self.process_line(kind,line) except Exception,e: if Logs.verbose: debug('preproc: line parsing failed (%s): %s %s'%(e,line,Utils.ex_stack())) def process_line(self,token,line): ve=Logs.verbose if ve:debug('preproc: line is %s - %s state is %s'%(token,line,self.state)) state=self.state if token in['ifdef','ifndef','if']: state.append(undefined) elif token=='endif': state.pop() if not token in['else','elif','endif']: if skipped in self.state or ignored in self.state: return if token=='if': ret=eval_macro(tokenize(line),self.defs) if ret:state[-1]=accepted else:state[-1]=ignored elif token=='ifdef': m=re_mac.search(line) if m and m.group(0)in self.defs:state[-1]=accepted else:state[-1]=ignored elif token=='ifndef': m=re_mac.search(line) if m and m.group(0)in self.defs:state[-1]=ignored else:state[-1]=accepted elif token=='include'or token=='import': (kind,inc)=extract_include(line,self.defs) if inc in self.ban_includes:return if token=='import':self.ban_includes.append(inc) if ve:debug('preproc: include found %s (%s) '%(inc,kind)) if kind=='"'or not strict_quotes: self.tryfind(inc) elif token=='elif': if state[-1]==accepted: state[-1]=skipped elif state[-1]==ignored: if eval_macro(tokenize(line),self.defs): state[-1]=accepted elif token=='else': if state[-1]==accepted:state[-1]=skipped elif state[-1]==ignored:state[-1]=accepted elif token=='define': m=re_mac.search(line) if m: name=m.group(0) if ve:debug('preproc: define %s %s'%(name,line)) self.defs[name]=line else: raise PreprocError("invalid define line %s"%line) elif token=='undef': m=re_mac.search(line) if m and m.group(0)in self.defs: self.defs.__delitem__(m.group(0)) elif token=='pragma': if re_pragma_once.search(line.lower()): self.ban_includes.append(self.curfile) def get_deps(node,env,nodepaths=[]): gruik=c_parser(nodepaths) gruik.start(node,env) return(gruik.nodes,gruik.names) re_inc=re.compile('^[ \t]*(#|%:)[ \t]*(include)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE) def lines_includes(filename): code=Utils.readf(filename) if use_trigraphs: for(a,b)in trig_def:code=code.split(a).join(b) code=re_nl.sub('',code) code=re_cpp.sub(repl,code) return[(m.group(2),m.group(3))for m in re.finditer(re_inc,code)] def get_deps_simple(node,env,nodepaths=[],defines={}): nodes=[] names=[] def find_deps(node): lst=lines_includes(node.abspath(env)) for(_,line)in lst: (t,filename)=extract_include(line,defines) if filename in names: continue if filename.endswith('.moc'): names.append(filename) found=None for n in nodepaths: if found: break found=n.find_resource(filename) if not found: if not filename in names: names.append(filename) elif not found in nodes: nodes.append(found) find_deps(node) find_deps(node) return(nodes,names) slv2-0.6.6+dfsg1/wafadmin/Tools/perl.py0000644000175000017500000000574111176703511017504 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os import Task,Options,Utils from Configure import conf from TaskGen import extension,taskgen,feature,before xsubpp_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}' EXT_XS=['.xs'] def init_perlext(self): self.uselib=self.to_list(getattr(self,'uselib','')) if not'PERL'in self.uselib:self.uselib.append('PERL') if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT') self.env['shlib_PATTERN']=self.env['perlext_PATTERN'] def xsubpp_file(self,node): gentask=self.create_task('xsubpp') gentask.set_inputs(node) outnode=node.change_ext('.c') gentask.set_outputs(outnode) self.allnodes.append(outnode) Task.simple_task_type('xsubpp',xsubpp_str,color='BLUE',before="cc cxx",shell=False) def check_perl_version(conf,minver=None): res=True if not getattr(Options.options,'perlbinary',None): perl=conf.find_program("perl",var="PERL") if not perl: return False else: perl=Options.options.perlbinary conf.env['PERL']=perl version=Utils.cmd_output(perl+" -e'printf \"%vd\", $^V'") if not version: res=False version="Unknown" elif not minver is None: ver=tuple(map(int,version.split("."))) if ver1:target=node.name newnode=self.path.find_or_declare(target) tsk=self.create_task('copy') tsk.set_inputs(node) tsk.set_outputs(newnode) tsk.fun=self.fun tsk.chmod=self.chmod if not tsk.env: tsk.debug() raise Utils.WafError('task without an environment') def subst_func(tsk): m4_re=re.compile('@(\w+)@',re.M) env=tsk.env infile=tsk.inputs[0].abspath(env) outfile=tsk.outputs[0].abspath(env) code=Utils.readf(infile) code=code.replace('%','%%') s=m4_re.sub(r'%(\1)s',code) di=tsk.dict or{} if not di: names=m4_re.findall(code) for i in names: di[i]=env.get_flat(i)or env.get_flat(i.upper()) file=open(outfile,'w') file.write(s%di) file.close() if tsk.chmod:os.chmod(outfile,tsk.chmod) class subst_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def apply_subst(self): Utils.def_attrs(self,fun=subst_func) self.default_install_path=0 lst=self.to_list(self.source) self.meths.remove('apply_core') self.dict=getattr(self,'dict',{}) for filename in lst: node=self.path.find_resource(filename) if not node:raise Utils.WafError('cannot find input file %s for processing'%filename) if self.target: newnode=self.path.find_or_declare(self.target) else: newnode=node.change_ext('') try: self.dict=self.dict.get_merged_dict() except AttributeError: pass if self.dict and not self.env['DICT_HASH']: self.env=self.env.copy() keys=self.dict.keys() keys.sort() lst=[self.dict[x]for x in keys] self.env['DICT_HASH']=str(Utils.h_list(lst)) tsk=self.create_task('copy') tsk.set_inputs(node) tsk.set_outputs(newnode) tsk.fun=self.fun tsk.dict=self.dict tsk.dep_vars=['DICT_HASH'] tsk.install_path=self.install_path tsk.chmod=self.chmod if not tsk.env: tsk.debug() raise Utils.WafError('task without an environment') class cmd_arg(object): def __init__(self,name,template='%s'): self.name=name self.template=template self.node=None class input_file(cmd_arg): def find_node(self,base_path): assert isinstance(base_path,Node.Node) self.node=base_path.find_resource(self.name) if self.node is None: raise Utils.WafError("Input file %s not found in "%(self.name,base_path)) def get_path(self,env,absolute): if absolute: return self.template%self.node.abspath(env) else: return self.template%self.node.srcpath(env) class output_file(cmd_arg): def find_node(self,base_path): assert isinstance(base_path,Node.Node) self.node=base_path.find_or_declare(self.name) if self.node is None: raise Utils.WafError("Output file %s not found in "%(self.name,base_path)) def get_path(self,env,absolute): if absolute: return self.template%self.node.abspath(env) else: return self.template%self.node.bldpath(env) class cmd_dir_arg(cmd_arg): def __init__(self,name,template=None): cmd_arg.__init__(self) self.name=name self.node=None if template is None: self.template='%s' else: self.template=template def find_node(self,base_path): assert isinstance(base_path,Node.Node) self.node=base_path.find_dir(self.name) if self.node is None: raise Utils.WafError("Directory %s not found in "%(self.name,base_path)) class input_dir(cmd_dir_arg): def get_path(self,dummy_env,dummy_absolute): return self.template%self.node.abspath() class output_dir(cmd_dir_arg): def get_path(self,env,dummy_absolute): return self.template%self.node.abspath(env) class command_output(Task.Task): color="BLUE" def __init__(self,env,command,command_node,command_args,stdin,stdout,cwd,os_env,stderr): Task.Task.__init__(self,env,normal=1) assert isinstance(command,(str,Node.Node)) self.command=command self.command_args=command_args self.stdin=stdin self.stdout=stdout self.cwd=cwd self.os_env=os_env self.stderr=stderr if command_node is not None:self.dep_nodes=[command_node] self.dep_vars=[] def run(self): task=self def input_path(node,template): if task.cwd is None: return template%node.bldpath(task.env) else: return template%node.abspath() def output_path(node,template): fun=node.abspath if task.cwd is None:fun=node.bldpath return template%fun(task.env) if isinstance(task.command,Node.Node): argv=[input_path(task.command,'%s')] else: argv=[task.command] for arg in task.command_args: if isinstance(arg,str): argv.append(arg) else: assert isinstance(arg,cmd_arg) argv.append(arg.get_path(task.env,(task.cwd is not None))) if task.stdin: stdin=open(input_path(task.stdin,'%s')) else: stdin=None if task.stdout: stdout=open(output_path(task.stdout,'%s'),"w") else: stdout=None if task.stderr: stderr=open(output_path(task.stderr,'%s'),"w") else: stderr=None if task.cwd is None: cwd=('None (actually %r)'%os.getcwd()) else: cwd=repr(task.cwd) debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r"%(cwd,stdin,stdout,argv)) if task.os_env is None: os_env=os.environ else: os_env=task.os_env command=Utils.pproc.Popen(argv,stdin=stdin,stdout=stdout,stderr=stderr,cwd=task.cwd,env=os_env) return command.wait() class cmd_output_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def init_cmd_output(self): Utils.def_attrs(self,stdin=None,stdout=None,stderr=None,command=None,command_is_external=False,argv=[],dependencies=[],dep_vars=[],hidden_inputs=[],hidden_outputs=[],cwd=None,os_env=None) def apply_cmd_output(self): if self.command is None: raise Utils.WafError("command-output missing command") if self.command_is_external: cmd=self.command cmd_node=None else: cmd_node=self.path.find_resource(self.command) assert cmd_node is not None,('''Could not find command '%s' in source tree. Hint: if this is an external command, use command_is_external=True''')%(self.command,) cmd=cmd_node if self.cwd is None: cwd=None else: assert isinstance(cwd,CmdDirArg) self.cwd.find_node(self.path) args=[] inputs=[] outputs=[] for arg in self.argv: if isinstance(arg,cmd_arg): arg.find_node(self.path) if isinstance(arg,input_file): inputs.append(arg.node) if isinstance(arg,output_file): outputs.append(arg.node) if self.stdout is None: stdout=None else: assert isinstance(self.stdout,basestring) stdout=self.path.find_or_declare(self.stdout) if stdout is None: raise Utils.WafError("File %s not found"%(self.stdout,)) outputs.append(stdout) if self.stderr is None: stderr=None else: assert isinstance(self.stderr,basestring) stderr=self.path.find_or_declare(self.stderr) if stderr is None: raise Utils.WafError("File %s not found"%(self.stderr,)) outputs.append(stderr) if self.stdin is None: stdin=None else: assert isinstance(self.stdin,basestring) stdin=self.path.find_resource(self.stdin) if stdin is None: raise Utils.WafError("File %s not found"%(self.stdin,)) inputs.append(stdin) for hidden_input in self.to_list(self.hidden_inputs): node=self.path.find_resource(hidden_input) if node is None: raise Utils.WafError("File %s not found in dir %s"%(hidden_input,self.path)) inputs.append(node) for hidden_output in self.to_list(self.hidden_outputs): node=self.path.find_or_declare(hidden_output) if node is None: raise Utils.WafError("File %s not found in dir %s"%(hidden_output,self.path)) outputs.append(node) if not(inputs or getattr(self,'no_inputs',None)): raise Utils.WafError('command-output objects must have at least one input file or give self.no_inputs') if not(outputs or getattr(self,'no_outputs',None)): raise Utils.WafError('command-output objects must have at least one output file or give self.no_outputs') task=command_output(self.env,cmd,cmd_node,self.argv,stdin,stdout,cwd,self.os_env,stderr) Utils.copy_attrs(self,task,'before after ext_in ext_out',only_if_set=True) self.tasks.append(task) task.inputs=inputs task.outputs=outputs task.dep_vars=self.to_list(self.dep_vars) for dep in self.dependencies: assert dep is not self dep.post() for dep_task in dep.tasks: task.set_run_after(dep_task) if not task.inputs: task.runnable_status=type(Task.TaskBase.run)(runnable_status,task,task.__class__) task.post_run=type(Task.TaskBase.run)(post_run,task,task.__class__) def post_run(self): for x in self.outputs: h=Utils.h_file(x.abspath(self.env)) self.generator.bld.node_sigs[self.env.variant()][x.id]=h def runnable_status(self): return Constants.RUN_ME Task.task_type_from_func('copy',vars=[],func=action_process_file_func) TaskGen.task_gen.classes['command-output']=cmd_output_taskgen feature('cmd')(apply_cmd) feature('copy')(apply_copy) before('apply_core')(apply_copy) feature('subst')(apply_subst) before('apply_core')(apply_subst) feature('command-output')(init_cmd_output) feature('command-output')(apply_cmd_output) after('init_cmd_output')(apply_cmd_output) slv2-0.6.6+dfsg1/wafadmin/Tools/gnome.py0000644000175000017500000001460111176703511017642 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,re import TaskGen,Utils,Runner,Task,Build,Options,Logs import cc from Logs import error from TaskGen import taskgen,before,after,feature n1_regexp=re.compile('(.*)',re.M) n2_regexp=re.compile('(.*)',re.M) def postinstall_schemas(prog_name): if Build.bld.is_install: dir=Build.bld.get_install_path('${PREFIX}/etc/gconf/schemas/%s.schemas'%prog_name) if not Options.options.destdir: Utils.pprint('YELLOW','Installing GConf schema') command='gconftool-2 --install-schema-file=%s 1> /dev/null'%dir ret=Utils.exec_command(command) else: Utils.pprint('YELLOW','GConf schema not installed. After install, run this:') Utils.pprint('YELLOW','gconftool-2 --install-schema-file=%s'%dir) def postinstall_icons(): dir=Build.bld.get_install_path('${DATADIR}/icons/hicolor') if Build.bld.is_install: if not Options.options.destdir: Utils.pprint('YELLOW',"Updating Gtk icon cache.") command='gtk-update-icon-cache -q -f -t %s'%dir ret=Utils.exec_command(command) else: Utils.pprint('YELLOW','Icon cache not updated. After install, run this:') Utils.pprint('YELLOW','gtk-update-icon-cache -q -f -t %s'%dir) def postinstall_scrollkeeper(prog_name): if Build.bld.is_install: if os.access('/var/log/scrollkeeper.log',os.W_OK): dir1=Build.bld.get_install_path('${PREFIX}/var/scrollkeeper') dir2=Build.bld.get_install_path('${DATADIR}/omf/%s'%prog_name) command='scrollkeeper-update -q -p %s -o %s'%(dir1,dir2) ret=Utils.exec_command(command) def postinstall(prog_name='myapp',schemas=1,icons=1,scrollkeeper=1): if schemas:postinstall_schemas(prog_name) if icons:postinstall_icons() if scrollkeeper:postinstall_scrollkeeper(prog_name) class gnome_doc_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def init_gnome_doc(self): self.default_install_path='${PREFIX}/share' def apply_gnome_doc(self): self.env['APPNAME']=self.doc_module lst=self.to_list(self.doc_linguas) bld=self.bld for x in lst: tsk=self.create_task('xml2po') node=self.path.find_resource(x+'/'+x+'.po') src=self.path.find_resource('C/%s.xml'%self.doc_module) out=self.path.find_or_declare('%s/%s.xml'%(x,self.doc_module)) tsk.set_inputs([node,src]) tsk.set_outputs(out) tsk2=self.create_task('xsltproc2po') out2=self.path.find_or_declare('%s/%s-%s.omf'%(x,self.doc_module,x)) tsk2.set_outputs(out2) node=self.path.find_resource(self.doc_module+".omf.in") tsk2.inputs=[node,out] tsk2.run_after.append(tsk) if bld.is_install: path=self.install_path+'gnome/help/%s/%s'%(self.doc_module,x) bld.install_files(self.install_path+'omf',out2.abspath(self.env)) for y in self.to_list(self.doc_figures): try: os.stat(self.path.abspath()+'/'+x+'/'+y) bld.install_as(path+'/'+y,self.path.abspath()+'/'+x+'/'+y) except: bld.install_as(path+'/'+y,self.path.abspath()+'/C/'+y) bld.install_as(path+'/%s.xml'%self.doc_module,out.abspath(self.env)) class xml_to_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def init_xml_to(self): Utils.def_attrs(self,source='xmlfile',xslt='xlsltfile',target='hey',default_install_path='${PREFIX}',task_created=None) def apply_xml_to(self): xmlfile=self.path.find_resource(self.source) xsltfile=self.path.find_resource(self.xslt) tsk=self.create_task('xmlto') tsk.set_inputs([xmlfile,xsltfile]) tsk.set_outputs(xmlfile.change_ext('html')) tsk.install_path=self.install_path def sgml_scan(self): node=self.inputs[0] env=self.env variant=node.variant(env) fi=open(node.abspath(env),'r') content=fi.read() fi.close() name=n1_regexp.findall(content)[0] num=n2_regexp.findall(content)[0] doc_name=name+'.'+num if not self.outputs: self.outputs=[self.generator.path.find_or_declare(doc_name)] return([],[doc_name]) class gnome_sgml2man_taskgen(TaskGen.task_gen): def __init__(self,*k,**kw): TaskGen.task_gen.__init__(self,*k,**kw) def apply_gnome_sgml2man(self): assert(getattr(self,'appname',None)) def install_result(task): out=task.outputs[0] name=out.name ext=name[-1] env=task.env self.bld.install_files('${DATADIR}/man/man%s/'%ext,out.abspath(env),env) self.bld.rescan(self.path) for name in self.bld.cache_dir_contents[self.path.id]: base,ext=os.path.splitext(name) if ext!='.sgml':continue task=self.create_task('sgml2man') task.set_inputs(self.path.find_resource(name)) task.task_generator=self if self.bld.is_install:task.install=install_result task.scan() cls=Task.simple_task_type('sgml2man','${SGML2MAN} -o ${TGT[0].bld_dir(env)} ${SRC} > /dev/null',color='BLUE') cls.scan=sgml_scan cls.quiet=1 Task.simple_task_type('xmlto','${XMLTO} html -m ${SRC[1].abspath(env)} ${SRC[0].abspath(env)}') Task.simple_task_type('xml2po','${XML2PO} ${XML2POFLAGS} ${SRC} > ${TGT}',color='BLUE') xslt_magic="""${XSLTPROC2PO} -o ${TGT[0].abspath(env)} \ --stringparam db2omf.basename ${APPNAME} \ --stringparam db2omf.format docbook \ --stringparam db2omf.lang C \ --stringparam db2omf.dtd '-//OASIS//DTD DocBook XML V4.3//EN' \ --stringparam db2omf.omf_dir ${PREFIX}/share/omf \ --stringparam db2omf.help_dir ${PREFIX}/share/gnome/help \ --stringparam db2omf.omf_in ${SRC[0].abspath(env)} \ --stringparam db2omf.scrollkeeper_cl ${SCROLLKEEPER_DATADIR}/Templates/C/scrollkeeper_cl.xml \ ${DB2OMF} ${SRC[1].abspath(env)}""" Task.simple_task_type('xsltproc2po',xslt_magic,color='BLUE') def detect(conf): conf.check_tool('gnu_dirs glib2 dbus') sgml2man=conf.find_program('docbook2man',var='SGML2MAN') def getstr(varname): return getattr(Options.options,varname,'') conf.define('GNOMELOCALEDIR',os.path.join(conf.env['DATADIR'],'locale')) xml2po=conf.find_program('xml2po',var='XML2PO') xsltproc2po=conf.find_program('xsltproc',var='XSLTPROC2PO') conf.env['XML2POFLAGS']='-e -p' conf.env['SCROLLKEEPER_DATADIR']=Utils.cmd_output("scrollkeeper-config --pkgdatadir",silent=1).strip() conf.env['DB2OMF']=Utils.cmd_output("/usr/bin/pkg-config --variable db2omf gnome-doc-utils",silent=1).strip() def set_options(opt): opt.add_option('--want-rpath',type='int',default=1,dest='want_rpath',help='set rpath to 1 or 0 [Default 1]') feature('gnome_doc')(init_gnome_doc) feature('gnome_doc')(apply_gnome_doc) after('init_gnome_doc')(apply_gnome_doc) feature('xml_to')(init_xml_to) feature('xml_to')(apply_xml_to) after('init_xml_to')(apply_xml_to) feature('gnome_sgml2man')(apply_gnome_sgml2man) slv2-0.6.6+dfsg1/wafadmin/Tools/vala.py0000644000175000017500000001625011176703511017462 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os.path,shutil import Task,Runner,Utils,Logs,Build,Node from TaskGen import extension,after,before EXT_VALA=['.vala','.gs'] class valac_task(Task.Task): vars=("VALAC","VALAC_VERSION","VALAFLAGS") before=("cc","cxx") def run(self): env=self.env inputs=[a.srcpath(env)for a in self.inputs] valac=env['VALAC'] vala_flags=env.get_flat('VALAFLAGS') top_src=self.generator.bld.srcnode.abspath() top_bld=self.generator.bld.srcnode.abspath(env) if env['VALAC_VERSION']>(0,1,6): cmd=[valac,'-C','--quiet',vala_flags] else: cmd=[valac,'-C',vala_flags] if self.threading: cmd.append('--thread') if self.target_glib: cmd.append('--target-glib=%s'%self.target_glib) features=self.generator.features if'cshlib'in features or'cstaticlib'in features: output_dir=self.outputs[0].bld_dir(env) cmd.append('--library '+self.target) if env['VALAC_VERSION']>=(0,7,0): cmd.append('--header '+os.path.join(output_dir,self.target+'.h')) self.outputs.append(self.generator.path.find_or_declare(self.target+'.h')) cmd.append('--basedir '+top_src) cmd.append('-d '+top_bld) else: output_dir=self.outputs[0].bld_dir(env) cmd.append('-d %s'%output_dir) for vapi_dir in self.vapi_dirs: cmd.append('--vapidir=%s'%vapi_dir) for package in self.packages: cmd.append('--pkg %s'%package) for package in self.packages_private: cmd.append('--pkg %s'%package) cmd.append(" ".join(inputs)) result=self.generator.bld.exec_command(" ".join(cmd)) if not'cprogram'in features: if self.packages: filename=os.path.join(self.generator.path.abspath(env),"%s.deps"%self.target) deps=open(filename,'w') for package in self.packages: deps.write(package+'\n') deps.close() self._fix_output("../%s.vapi"%self.target) self._fix_output("%s.vapi"%self.target) self._fix_output("%s.gidl"%self.target) self._fix_output("%s.gir"%self.target) return result def install(self): bld=self.generator.bld features=self.generator.features if self.attr("install_path")and("cshlib"in features or"cstaticlib"in features): headers_list=[o for o in self.outputs if o.suffix()==".h"] vapi_list=[o for o in self.outputs if(o.suffix()in(".vapi",".deps"))] for header in headers_list: top_src=self.generator.bld.srcnode package=self.env['PACKAGE'] try: api_version=Utils.g_module.API_VERSION except AttributeError: version=Utils.g_module.VERSION.split(".") if version[0]=="0": api_version="0."+version[1] else: api_version=version[0]+".0" install_path="${INCLUDEDIR}/%s-%s/%s"%(package,api_version,header.relpath_gen(top_src)) bld.install_as(install_path,header.abspath(self.env),self.env) for vapi in vapi_list: bld.install_files("${DATAROOTDIR}/vala/vapi",vapi.abspath(self.env),self.env) def _fix_output(self,output): top_bld=self.generator.bld.srcnode.abspath(self.env) try: src=os.path.join(top_bld,output) dst=self.generator.path.abspath(self.env) shutil.move(src,dst) except: pass def vala_file(self,node): valatask=getattr(self,"valatask",None) if not valatask: valatask=self.create_task('valac') self.valatask=valatask self.includes=Utils.to_list(getattr(self,'includes',[])) valatask.packages=[] valatask.packages_private=Utils.to_list(getattr(self,'packages_private',[])) valatask.vapi_dirs=[] valatask.target=self.target valatask.threading=False valatask.install_path=self.install_path valatask.target_glib=None packages=Utils.to_list(getattr(self,'packages',[])) vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[])) includes=[] if hasattr(self,'uselib_local'): local_packages=Utils.to_list(self.uselib_local) seen=[] while len(local_packages)>0: package=local_packages.pop() if package in seen: continue seen.append(package) package_obj=self.name_to_obj(package) if not package_obj: raise Utils.WafError("object '%s' was not found in uselib_local (required by '%s')"%(package,self.name)) package_name=package_obj.target package_node=package_obj.path package_dir=package_node.relpath_gen(self.path) for task in package_obj.tasks: for output in task.outputs: if output.name==package_name+".vapi": valatask.set_run_after(task) if package_name not in packages: packages.append(package_name) if package_dir not in vapi_dirs: vapi_dirs.append(package_dir) if package_dir not in includes: includes.append(package_dir) if hasattr(package_obj,'uselib_local'): lst=self.to_list(package_obj.uselib_local) lst.reverse() local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages valatask.packages=packages for vapi_dir in vapi_dirs: try: valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath()) valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath(self.env)) except AttributeError: Logs.warn("Unable to locate Vala API directory: '%s'"%vapi_dir) self.includes.append(node.bld.srcnode.abspath()) self.includes.append(node.bld.srcnode.abspath(self.env)) for include in includes: try: self.includes.append(self.path.find_dir(include).abspath()) self.includes.append(self.path.find_dir(include).abspath(self.env)) except AttributeError: Logs.warn("Unable to locate include directory: '%s'"%include) if hasattr(self,'threading'): valatask.threading=self.threading self.uselib=self.to_list(self.uselib) if not'GTHREAD'in self.uselib: self.uselib.append('GTHREAD') if hasattr(self,'target_glib'): valatask.target_glib=self.target_glib env=valatask.env output_nodes=[] c_node=node.change_ext('.c') output_nodes.append(c_node) self.allnodes.append(c_node) if env['VALAC_VERSION']<(0,7,0): output_nodes.append(node.change_ext('.h')) else: if not'cprogram'in self.features: output_nodes.append(self.path.find_or_declare('%s.h'%self.target)) if not'cprogram'in self.features: output_nodes.append(self.path.find_or_declare('%s.vapi'%self.target)) if env['VALAC_VERSION']>(0,3,5): output_nodes.append(self.path.find_or_declare('%s.gir'%self.target)) elif env['VALAC_VERSION']>(0,1,7): output_nodes.append(self.path.find_or_declare('%s.gidl'%self.target)) if valatask.packages: output_nodes.append(self.path.find_or_declare('%s.deps'%self.target)) valatask.inputs.append(node) valatask.outputs.extend(output_nodes) def detect(conf): min_version=(0,1,6) min_version_str="%d.%d.%d"%min_version valac=conf.find_program('valac',var='VALAC',mandatory=True) if not conf.env["HAVE_GTHREAD"]: conf.check_cfg(package='gthread-2.0',uselib_store='GTHREAD',args='--cflags --libs') try: output=Utils.cmd_output(valac+" --version",silent=True) version=output.split(' ',1)[-1].strip().split(".") version=[int(x)for x in version] valac_version=tuple(version) except Exception: valac_version=(0,0,0) conf.check_message('program version','valac >= '+min_version_str,valac_version>=min_version,"%d.%d.%d"%valac_version) conf.check_tool('gnu_dirs') if valac_version=','exact-version':'==','max-version':'<=',} SNIP1=''' int main() { void *p; p=(void*)(%s); return 0; } ''' SNIP2=''' int main() { if ((%(type_name)s *) 0) return 0; if (sizeof (%(type_name)s)) return 0; } ''' SNIP3=''' int main() { return 0; } ''' def parse_flags(line,uselib,env): lst=shlex.split(line) while lst: x=lst.pop(0) st=x[:2] ot=x[2:] if st=='-I'or st=='/I': if not ot:ot=lst.pop(0) env.append_unique('CPPPATH_'+uselib,ot) elif st=='-D': if not ot:ot=lst.pop(0) env.append_unique('CXXDEFINES_'+uselib,ot) env.append_unique('CCDEFINES_'+uselib,ot) elif st=='-l': if not ot:ot=lst.pop(0) env.append_unique('LIB_'+uselib,ot) elif st=='-L': if not ot:ot=lst.pop(0) env.append_unique('LIBPATH_'+uselib,ot) elif x=='-pthread'or x.startswith('+'): env.append_unique('CCFLAGS_'+uselib,x) env.append_unique('CXXFLAGS_'+uselib,x) env.append_unique('LINKFLAGS_'+uselib,x) elif x.startswith('-std'): env.append_unique('CCFLAGS_'+uselib,x) env.append_unique('LINKFLAGS_'+uselib,x) elif x.startswith('-Wl'): env.append_unique('LINKFLAGS_'+uselib,x) elif x.startswith('-m'): env.append_unique('CCFLAGS_'+uselib,x) env.append_unique('CXXFLAGS_'+uselib,x) def ret_msg(self,f,kw): if isinstance(f,str): return f return f(kw) def validate_cfg(self,kw): if not'path'in kw: kw['path']='pkg-config --errors-to-stdout --print-errors' if'atleast_pkgconfig_version'in kw: if not'msg'in kw: kw['msg']='Checking for pkg-config version >= %s'%kw['atleast_pkgconfig_version'] return if'modversion'in kw: return for x in cfg_ver.keys(): y=x.replace('-','_') if y in kw: if not'package'in kw: raise ValueError('%s requires a package'%x) if not'msg'in kw: kw['msg']='Checking for %s %s %s'%(kw['package'],cfg_ver[x],kw[y]) return if not'msg'in kw: kw['msg']='Checking for %s'%kw['package'] if not'okmsg'in kw: kw['okmsg']='ok' if not'errmsg'in kw: kw['errmsg']='not found' def cmd_and_log(self,cmd,kw): Logs.debug('runner: %s\n'%cmd) if self.log:self.log.write('%s\n'%cmd) try: p=Utils.pproc.Popen(cmd,stdout=Utils.pproc.PIPE,shell=True) output=p.communicate()[0] except WindowsError: self.fatal('fail') if p.returncode: if not kw.get('errmsg',''): if kw.get('mandatory',False): kw['errmsg']=output.strip() else: kw['errmsg']='fail' self.fatal('fail') return output def exec_cfg(self,kw): if'atleast_pkgconfig_version'in kw: cmd='%s --atleast-pkgconfig-version=%s'%(kw['path'],kw['atleast_pkgconfig_version']) self.cmd_and_log(cmd,kw) if not'okmsg'in kw: kw['okmsg']='ok' return for x in cfg_ver: y=x.replace('-','_') if y in kw: self.cmd_and_log('%s --%s=%s %s'%(kw['path'],x,kw[y],kw['package']),kw) if not'okmsg'in kw: kw['okmsg']='ok' self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0) break if'modversion'in kw: version=self.cmd_and_log('%s --modversion %s'%(kw['path'],kw['modversion']),kw).strip() self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version) return version lst=[kw['path']] for key,val in kw.get('define_variable',{}).iteritems(): lst.append('--define-variable=%s=%s'%(key,val)) lst.append(kw.get('args','')) lst.append(kw['package']) cmd=' '.join(lst) ret=self.cmd_and_log(cmd,kw) if not'okmsg'in kw: kw['okmsg']='ok' self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0) parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env)) return ret def check_cfg(self,*k,**kw): self.validate_cfg(kw) if'msg'in kw: self.check_message_1(kw['msg']) ret=None try: ret=self.exec_cfg(kw) except Configure.ConfigurationError,e: if'errmsg'in kw: self.check_message_2(kw['errmsg'],'YELLOW') if'mandatory'in kw and kw['mandatory']: if Logs.verbose>1: raise else: self.fatal('the configuration failed (see %r)'%self.log.name) else: kw['success']=ret if'okmsg'in kw: self.check_message_2(self.ret_msg(kw['okmsg'],kw)) return ret def validate_c(self,kw): if not'env'in kw: kw['env']=self.env.copy() env=kw['env'] if not'compiler'in kw: kw['compiler']='cc' if env['CXX_NAME']and Task.TaskBase.classes.get('cxx',None): kw['compiler']='cxx' if not'type'in kw: kw['type']='cprogram' assert not(kw['type']!='cprogram'and kw.get('execute',0)),'can only execute programs' def to_header(dct): if'header_name'in dct: dct=Utils.to_list(dct['header_name']) return''.join(['#include <%s>\n'%x for x in dct]) return'' if not'compile_mode'in kw: kw['compile_mode']=(kw['compiler']=='cxx')and'cxx'or'cc' if not'compile_filename'in kw: kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'') if'framework_name'in kw: try:TaskGen.task_gen.create_task_macapp except AttributeError:self.fatal('frameworks require the osx tool') fwkname=kw['framework_name'] if not'uselib_store'in kw: kw['uselib_store']=fwkname.upper() if not kw.get('no_header',False): if not'header_name'in kw: kw['header_name']=[] fwk='%s/%s.h'%(fwkname,fwkname) if kw.get('remove_dot_h',None): fwk=fwk[:-2] kw['header_name']=Utils.to_list(kw['header_name'])+[fwk] kw['msg']='Checking for framework %s'%fwkname kw['framework']=fwkname if'function_name'in kw: fu=kw['function_name'] if not'msg'in kw: kw['msg']='Checking for function %s'%fu kw['code']=to_header(kw)+SNIP1%fu if not'uselib_store'in kw: kw['uselib_store']=fu.upper() if not'define_name'in kw: kw['define_name']=self.have_define(fu) elif'type_name'in kw: tu=kw['type_name'] if not'msg'in kw: kw['msg']='Checking for type %s'%tu if not'header_name'in kw: kw['header_name']='stdint.h' kw['code']=to_header(kw)+SNIP2%{'type_name':tu} if not'define_name'in kw: kw['define_name']=self.have_define(tu.upper()) elif'header_name'in kw: if not'msg'in kw: kw['msg']='Checking for header %s'%kw['header_name'] l=Utils.to_list(kw['header_name']) assert len(l)>0,'list of headers in header_name is empty' kw['code']=to_header(kw)+SNIP3 if not'uselib_store'in kw: kw['uselib_store']=l[0].upper() if not'define_name'in kw: kw['define_name']=self.have_define(l[0]) if'lib'in kw: if not'msg'in kw: kw['msg']='Checking for library %s'%kw['lib'] if not'uselib_store'in kw: kw['uselib_store']=kw['lib'].upper() if'staticlib'in kw: if not'msg'in kw: kw['msg']='Checking for static library %s'%kw['staticlib'] if not'uselib_store'in kw: kw['uselib_store']=kw['staticlib'].upper() if'fragment'in kw: kw['code']=kw['fragment'] if not'msg'in kw: kw['msg']='Checking for custom code' if not'errmsg'in kw: kw['errmsg']='fail' for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]: if flagsname in kw: if not'msg'in kw: kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname]) if not'errmsg'in kw: kw['errmsg']='fail' if not'execute'in kw: kw['execute']=False if not'errmsg'in kw: kw['errmsg']='not found' if not'okmsg'in kw: kw['okmsg']='ok' if not'code'in kw: kw['code']=SNIP3 if not kw.get('success'):kw['success']=None assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c' def post_check(self,*k,**kw): is_success=0 if kw['execute']: if kw['success']: is_success=kw['success'] else: is_success=(kw['success']==0) def define_or_stuff(): nm=kw['define_name'] if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str): self.define(kw['define_name'],is_success) else: self.define_cond(kw['define_name'],is_success) if'define_name'in kw: if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw: define_or_stuff() if is_success and'uselib_store'in kw: import cc,cxx for k in set(cc.g_cc_flag_vars).union(cxx.g_cxx_flag_vars): lk=k.lower() if k=='CPPPATH':lk='includes' if k=='CXXDEFINES':lk='defines' if k=='CCDEFINES':lk='defines' if lk in kw: val=kw[lk] if isinstance(val,str): val=val.rstrip(os.path.sep) self.env.append_unique(k+'_'+kw['uselib_store'],val) def check(self,*k,**kw): self.validate_c(kw) self.check_message_1(kw['msg']) ret=None try: ret=self.run_c_code(*k,**kw) except Configure.ConfigurationError,e: self.check_message_2(kw['errmsg'],'YELLOW') if'mandatory'in kw and kw['mandatory']: if Logs.verbose>1: raise else: self.fatal('the configuration failed (see %r)'%self.log.name) else: kw['success']=ret self.check_message_2(self.ret_msg(kw['okmsg'],kw)) self.post_check(*k,**kw) if not kw.get('execute',False): return ret==0 return ret def run_c_code(self,*k,**kw): test_f_name=kw['compile_filename'] dir=os.path.join(self.blddir,'.wscript-trybuild') try: shutil.rmtree(dir) except OSError: pass os.makedirs(dir) bdir=os.path.join(dir,'testbuild') if not os.path.exists(bdir): os.makedirs(bdir) env=kw['env'] dest=open(os.path.join(dir,test_f_name),'w') dest.write(kw['code']) dest.close() back=os.path.abspath('.') bld=Build.BuildContext() bld.log=self.log bld.all_envs.update(self.all_envs) bld.all_envs['default']=env bld.lst_variants=bld.all_envs.keys() bld.load_dirs(dir,bdir) os.chdir(dir) bld.rescan(bld.srcnode) o=bld.new_task_gen(features=[kw['compile_mode'],kw['type']],source=test_f_name,target='testprog') for k,v in kw.iteritems(): setattr(o,k,v) self.log.write("==>\n%s\n<==\n"%kw['code']) try: bld.compile() except Utils.WafError: ret=Utils.ex_stack() else: ret=0 os.chdir(back) if ret: self.log.write('command returned %r'%ret) self.fatal(str(ret)) if kw['execute']: lastprog=o.link_task.outputs[0].abspath(env) if kw['execute']: args=Utils.to_list(kw.get('exec_args',[])) try: data=Utils.cmd_output([lastprog]+args).strip() except ValueError,e: self.fatal(Utils.ex_stack()) ret=data return ret def check_cxx(self,*k,**kw): kw['compiler']='cxx' return self.check(*k,**kw) def check_cc(self,*k,**kw): kw['compiler']='cc' return self.check(*k,**kw) def define(self,define,value,quote=1): assert define and isinstance(define,str) tbl=self.env[DEFINES]or Utils.ordered_dict() if isinstance(value,str): if quote==1: tbl[define]='"%s"'%str(value) else: tbl[define]=value elif isinstance(value,int): tbl[define]=value else: raise TypeError('define %r -> %r must be a string or an int'%(define,value)) self.env[DEFINES]=tbl self.env[define]=value def undefine(self,define): assert define and isinstance(define,str) tbl=self.env[DEFINES]or Utils.ordered_dict() value=UNDEFINED tbl[define]=value self.env[DEFINES]=tbl self.env[define]=value def define_cond(self,name,value): if value: self.define(name,1) else: self.undefine(name) def is_defined(self,key): defines=self.env[DEFINES] if not defines: return False try: value=defines[key] except KeyError: return False else: return value!=UNDEFINED def get_define(self,define): try:return self.env[DEFINES][define] except KeyError:return None def have_define(self,name): return self.__dict__.get('HAVE_PAT','HAVE_%s')%Utils.quote_define_name(name) def write_config_header(self,configfile='',env='',guard='',top=False): if not configfile:configfile=WAF_CONFIG_H waf_guard=guard or'_%s_WAF'%Utils.quote_define_name(configfile) if not env:env=self.env if top: diff='' else: diff=Utils.diff_path(self.srcdir,self.curdir) full=os.sep.join([self.blddir,env.variant(),diff,configfile]) full=os.path.normpath(full) (dir,base)=os.path.split(full) try:os.makedirs(dir) except:pass dest=open(full,'w') dest.write('/* Configuration header created by Waf - do not edit */\n') dest.write('#ifndef %s\n#define %s\n\n'%(waf_guard,waf_guard)) dest.write(self.get_config_header()) env.append_value(CFG_FILES,os.path.join(diff,configfile)) dest.write('\n#endif /* %s */\n'%waf_guard) dest.close() def get_config_header(self): config_header=[] tbl=self.env[DEFINES]or Utils.ordered_dict() for key in tbl.allkeys: value=tbl[key] if value is None: config_header.append('#define %s'%key) elif value is UNDEFINED: config_header.append('/* #undef %s */'%key) else: config_header.append('#define %s %s'%(key,value)) return"\n".join(config_header) def find_cpp(conf): v=conf.env cpp=None if v['CPP']:cpp=v['CPP'] elif'CPP'in conf.environ:cpp=conf.environ['CPP'] if not cpp:cpp=conf.find_program('cpp',var='CPP') if not cpp:cpp=v['CC'] if not cpp:cpp=v['CXX'] v['CPP']=cpp def cc_add_flags(conf): conf.add_os_flags('CFLAGS','CCFLAGS') conf.add_os_flags('CPPFLAGS') conf.add_os_flags('LINKFLAGS') def cxx_add_flags(conf): conf.add_os_flags('CXXFLAGS') conf.add_os_flags('CPPFLAGS') conf.add_os_flags('LINKFLAGS') def cc_load_tools(conf): conf.check_tool('cc') def cxx_load_tools(conf): conf.check_tool('cxx') conf(ret_msg) conf(validate_cfg) conf(cmd_and_log) conf(exec_cfg) conf(check_cfg) conf(validate_c) conf(post_check) conf(check) conf(run_c_code) conf(check_cxx) conf(check_cc) conf(define) conf(undefine) conf(define_cond) conf(is_defined) conf(get_define) conf(have_define) conf(write_config_header) conf(get_config_header) conftest(find_cpp) conftest(cc_add_flags) conftest(cxx_add_flags) conftest(cc_load_tools) conftest(cxx_load_tools) slv2-0.6.6+dfsg1/wafadmin/Tools/d.py0000644000175000017500000002261511176703511016764 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,re,optparse import ccroot import TaskGen,Utils,Task,Configure,Logs,Build from Logs import debug,error from TaskGen import taskgen,feature,after,before,extension EXT_D=['.d','.di','.D'] D_METHS=['apply_core','apply_vnum','apply_objdeps'] def filter_comments(filename): txt=Utils.readf(filename) buf=[] i=0 max=len(txt) while i1: self.features.append('d'+k[1]) TaskGen.bind_feature('d',D_METHS) def init_d(self): Utils.def_attrs(self,dflags='',importpaths='',libs='',libpaths='',uselib='',uselib_local='',generate_headers=False,compiled_tasks=[],add_objects=[],link_task=None) def apply_d_libs(self): uselib=self.to_list(self.uselib) seen=[] local_libs=self.to_list(self.uselib_local) libs=[] libpaths=[] env=self.env while local_libs: x=local_libs.pop() if x in seen: continue else: seen.append(x) y=self.name_to_obj(x) if not y: raise Utils.WafError('object not found in uselib_local: obj %s uselib %s'%(self.name,x)) if y.uselib_local: added=0 lst=y.to_list(y.uselib_local) lst.reverse() for u in lst: if u in seen:continue added=1 local_libs=[u]+local_libs if added:continue y.post() seen.append(x) libname=y.target[y.target.rfind(os.sep)+1:] if'dshlib'in y.features or'dstaticlib'in y.features: env.append_unique('DLINKFLAGS',env['DLIBPATH_ST']%y.link_task.outputs[0].parent.bldpath(env)) env.append_unique('DLINKFLAGS',env['DLIB_ST']%libname) tmp_path=y.path.bldpath(env) if not tmp_path in libpaths:libpaths=[tmp_path]+libpaths if y.link_task is not None: self.link_task.set_run_after(y.link_task) dep_nodes=getattr(self.link_task,'dep_nodes',[]) self.link_task.dep_nodes=dep_nodes+y.link_task.outputs morelibs=y.to_list(y.uselib) for v in morelibs: if v in uselib:continue uselib=[v]+uselib self.uselib=uselib def apply_d_link(self): link=getattr(self,'link',None) if not link: if'dstaticlib'in self.features:link='ar_link_static' else:link='d_link' linktask=self.create_task(link) outputs=[t.outputs[0]for t in self.compiled_tasks] linktask.set_inputs(outputs) linktask.set_outputs(self.path.find_or_declare(get_target_name(self))) self.link_task=linktask def apply_d_vars(self): env=self.env dpath_st=env['DPATH_ST'] lib_st=env['DLIB_ST'] libpath_st=env['DLIBPATH_ST'] importpaths=self.to_list(self.importpaths) libpaths=[] libs=[] uselib=self.to_list(self.uselib) for i in uselib: if env['DFLAGS_'+i]: env.append_unique('DFLAGS',env['DFLAGS_'+i]) for x in self.features: if not x in['dprogram','dstaticlib','dshlib']: continue x.lstrip('d') d_shlib_dflags=env['D_'+x+'_DFLAGS'] if d_shlib_dflags: env.append_unique('DFLAGS',d_shlib_dflags) for i in uselib: if env['DPATH_'+i]: for entry in self.to_list(env['DPATH_'+i]): if not entry in importpaths: importpaths.append(entry) for path in importpaths: if os.path.isabs(path): env.append_unique('_DIMPORTFLAGS',dpath_st%path) else: node=self.path.find_dir(path) self.env.append_unique('INC_PATHS',node) env.append_unique('_DIMPORTFLAGS',dpath_st%node.srcpath(env)) env.append_unique('_DIMPORTFLAGS',dpath_st%node.bldpath(env)) for i in uselib: if env['LIBPATH_'+i]: for entry in self.to_list(env['LIBPATH_'+i]): if not entry in libpaths: libpaths+=[entry] libpaths=self.to_list(self.libpaths)+libpaths for path in libpaths: env.append_unique('DLINKFLAGS',libpath_st%path) for i in uselib: if env['LIB_'+i]: for entry in self.to_list(env['LIB_'+i]): if not entry in libs: libs+=[entry] libs=libs+self.to_list(self.libs) for lib in libs: env.append_unique('DLINKFLAGS',lib_st%lib) for i in uselib: dlinkflags=env['DLINKFLAGS_'+i] if dlinkflags: for linkflag in dlinkflags: env.append_unique('DLINKFLAGS',linkflag) def add_shlib_d_flags(self): for linkflag in self.env['D_shlib_LINKFLAGS']: self.env.append_unique('DLINKFLAGS',linkflag) def d_hook(self,node): task=self.create_task(self.generate_headers and'd_with_header'or'd') try:obj_ext=self.obj_ext except AttributeError:obj_ext='_%d.o'%self.idx task.inputs=[node] task.outputs=[node.change_ext(obj_ext)] self.compiled_tasks.append(task) if self.generate_headers: header_node=node.change_ext(self.env['DHEADER_ext']) task.outputs+=[header_node] d_str='${D_COMPILER} ${DFLAGS} ${_DIMPORTFLAGS} ${D_SRC_F}${SRC} ${D_TGT_F}${TGT}' d_with_header_str='${D_COMPILER} ${DFLAGS} ${_DIMPORTFLAGS} \ ${D_HDR_F}${TGT[1].bldpath(env)} \ ${D_SRC_F}${SRC} \ ${D_TGT_F}${TGT[0].bldpath(env)}' link_str='${D_LINKER} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F}${TGT} ${DLINKFLAGS}' cls=Task.simple_task_type('d',d_str,'GREEN',before='ar_link_static d_link',shell=False) cls.scan=scan Task.simple_task_type('d_with_header',d_with_header_str,'GREEN',before='ar_link_static d_link',shell=False) Task.simple_task_type('d_link',link_str,color='YELLOW',shell=False) def generate_header(self,filename,install_path): if not hasattr(self,'header_lst'):self.header_lst=[] self.meths.append('process_header') self.header_lst.append([filename,install_path]) def process_header(self): env=self.env for i in getattr(self,'header_lst',[]): node=self.path.find_resource(i[0]) if not node: raise Utils.WafError('file not found on d obj '+i[0]) task=self.create_task('d_header') task.set_inputs(node) task.set_outputs(node.change_ext('.di')) d_header_str='${D_COMPILER} ${D_HEADER} ${SRC}' Task.simple_task_type('d_header',d_header_str,color='BLUE',shell=False) feature('d')(init_d) before('apply_type_vars')(init_d) feature('d')(init_d) before('apply_d_libs')(init_d) feature('d')(apply_d_libs) after('apply_d_link')(apply_d_libs) before('apply_vnum')(apply_d_libs) feature('dprogram','dshlib','dstaticlib')(apply_d_link) after('apply_core')(apply_d_link) feature('d')(apply_d_vars) after('apply_core')(apply_d_vars) feature('dshlib')(add_shlib_d_flags) after('apply_d_vars')(add_shlib_d_flags) extension(EXT_D)(d_hook) taskgen(generate_header) before('apply_core')(process_header) slv2-0.6.6+dfsg1/wafadmin/Scripting.py0000644000175000017500000002550611176703512017406 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,shutil,traceback,datetime,inspect import Utils,Configure,Build,Logs,Options,Environment,Task from Logs import error,warn,info from Constants import* g_gz='bz2' commands=[] def prepare_impl(t,cwd,ver,wafdir): Options.tooldir=[t] Options.launch_dir=cwd if'--version'in sys.argv: opt_obj=Options.Handler() opt_obj.curdir=cwd opt_obj.parse_args() sys.exit(0) msg1='Waf: Please run waf from a directory containing a file named "%s" or run distclean'%WSCRIPT_FILE build_dir_override=None candidate=None lst=os.listdir(cwd) search_for_candidate=True if WSCRIPT_FILE in lst: candidate=cwd elif'configure'in sys.argv and not WSCRIPT_BUILD_FILE in lst: calldir=os.path.abspath(os.path.dirname(sys.argv[0])) if WSCRIPT_FILE in os.listdir(calldir): candidate=calldir search_for_candidate=False else: error('arg[0] directory does not contain a wscript file') sys.exit(1) build_dir_override=cwd while search_for_candidate: if len(cwd)<=3: break dirlst=os.listdir(cwd) if WSCRIPT_FILE in dirlst: candidate=cwd if'configure'in sys.argv and candidate: break if Options.lockfile in dirlst: env=Environment.Environment() env.load(os.path.join(cwd,Options.lockfile)) candidate=env['cwd']or cwd break cwd=os.path.dirname(cwd) if not candidate: if'-h'in sys.argv or'--help'in sys.argv: warn('No wscript file found: the help message may be incomplete') opt_obj=Options.Handler() opt_obj.curdir=cwd opt_obj.parse_args() else: error(msg1) sys.exit(0) try: os.chdir(candidate) except OSError: raise Utils.WafError("the folder %r is unreadable"%candidate) Utils.set_main_module(os.path.join(candidate,WSCRIPT_FILE)) if build_dir_override: d=getattr(Utils.g_module,BLDDIR,None) if d: msg=' Overriding build directory %s with %s'%(d,build_dir_override) warn(msg) Utils.g_module.blddir=build_dir_override def set_def(obj,name=''): n=name or obj.__name__ if not n in Utils.g_module.__dict__: setattr(Utils.g_module,n,obj) for k in[dist,distclean,distcheck,build,clean,install,uninstall]: set_def(k) set_def(Configure.ConfigurationContext,'configure_context') for k in['build','clean','install','uninstall']: set_def(Build.BuildContext,k+'_context') opt_obj=Options.Handler(Utils.g_module) opt_obj.curdir=candidate try: f=Utils.g_module.set_options except AttributeError: pass else: opt_obj.sub_options(['']) opt_obj.parse_args() if not'init'in Utils.g_module.__dict__: Utils.g_module.init=Utils.nada if not'shutdown'in Utils.g_module.__dict__: Utils.g_module.shutdown=Utils.nada main() def prepare(t,cwd,ver,wafdir): if WAFVERSION!=ver: msg='Version mismatch: waf %s <> wafadmin %s (wafdir %s)'%(ver,WAFVERSION,wafdir) print('\033[91mError: %s\033[0m'%msg) sys.exit(1) try: prepare_impl(t,cwd,ver,wafdir) except Utils.WafError,e: error(e) sys.exit(1) except KeyboardInterrupt: Utils.pprint('RED','Interrupted') sys.exit(68) def main(): global commands commands=Options.arg_line[:] while commands: x=commands.pop(0) ini=datetime.datetime.now() if x=='configure': fun=configure elif x=='build': fun=build else: fun=getattr(Utils.g_module,x,None) if not fun: raise Utils.WscriptError('No such command %r'%x) ctx=getattr(Utils.g_module,x+'_context',Utils.Context)() if x in['init','shutdown','dist','distclean','distcheck']: try: fun(ctx) except TypeError: fun() else: fun(ctx) ela='' if not Options.options.progress_bar: ela=' (%s)'%Utils.get_elapsed_time(ini) if x!='init'and x!='shutdown': info('%r finished successfully%s'%(x,ela)) if not commands and x!='shutdown': commands.append('shutdown') def configure(conf): src=getattr(Options.options,SRCDIR,None) if not src:src=getattr(Utils.g_module,SRCDIR,None) if not src: src='.' incomplete_src=1 src=os.path.abspath(src) bld=getattr(Options.options,BLDDIR,None) if not bld: bld=getattr(Utils.g_module,BLDDIR,None) if bld=='.': raise Utils.WafError('Setting blddir="." may cause distclean problems') if not bld: bld='build' incomplete_bld=1 bld=os.path.abspath(bld) try:os.makedirs(bld) except OSError:pass targets=Options.options.compile_targets Options.options.compile_targets=None Options.is_install=False conf.srcdir=src conf.blddir=bld conf.post_init() if'incomplete_src'in vars(): conf.check_message_1('Setting srcdir to') conf.check_message_2(src) if'incomplete_bld'in vars(): conf.check_message_1('Setting blddir to') conf.check_message_2(bld) conf.sub_config(['']) conf.store() env=Environment.Environment() env[BLDDIR]=bld env[SRCDIR]=src env['argv']=sys.argv env['commands']=Options.commands env['options']=Options.options.__dict__ env['hash']=conf.hash env['files']=conf.files env['environ']=dict(conf.environ) env['cwd']=os.path.split(Utils.g_module.root_path)[0] if Utils.g_module.root_path!=src: env.store(os.path.join(src,Options.lockfile)) env.store(Options.lockfile) Options.options.compile_targets=targets def clean(bld): '''removes the build files''' try: proj=Environment.Environment(Options.lockfile) except IOError: raise Utils.WafError('Nothing to clean (project not configured)') bld.load_dirs(proj[SRCDIR],proj[BLDDIR]) bld.load_envs() bld.is_install=0 bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]]) try: bld.clean() finally: bld.save() def check_configured(bld): if not Configure.autoconfig: return bld conf_cls=getattr(Utils.g_module,'configure_context',Utils.Context) bld_cls=getattr(Utils.g_module,'build_context',Utils.Context) def reconf(proj): back=(Options.commands,Options.options.__dict__,Logs.zones,Logs.verbose) Options.commands=proj['commands'] Options.options.__dict__=proj['options'] conf=conf_cls() conf.environ=proj['environ'] configure(conf) (Options.commands,Options.options.__dict__,Logs.zones,Logs.verbose)=back try: proj=Environment.Environment(Options.lockfile) except IOError: conf=conf_cls() configure(conf) else: try: bld=bld_cls() bld.load_dirs(proj[SRCDIR],proj[BLDDIR]) bld.load_envs() except Utils.WafError: reconf(proj) return bld_cls() try: proj=Environment.Environment(Options.lockfile) except IOError: raise Utils.WafError('Auto-config: project does not configure (bug)') h=0 try: for file in proj['files']: if file.endswith('configure'): h=hash((h,Utils.readf(file))) else: mod=Utils.load_module(file) h=hash((h,mod.waf_hash_val)) except(OSError,IOError): warn('Reconfiguring the project: a file is unavailable') reconf(proj) else: if(h!=proj['hash']): warn('Reconfiguring the project: the configuration has changed') reconf(proj) return bld_cls() def install(bld): '''installs the build files''' bld=check_configured(bld) Options.commands['install']=True Options.commands['uninstall']=False Options.is_install=True bld.is_install=INSTALL build_impl(bld) bld.install() def uninstall(bld): '''removes the installed files''' Options.commands['install']=False Options.commands['uninstall']=True Options.is_install=True bld.is_install=UNINSTALL try: def runnable_status(self): return SKIP_ME setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status) setattr(Task.Task,'runnable_status',runnable_status) build_impl(bld) bld.install() finally: setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back) def build(bld): bld=check_configured(bld) Options.commands['install']=False Options.commands['uninstall']=False Options.is_install=False bld.is_install=0 return build_impl(bld) def build_impl(bld): try: proj=Environment.Environment(Options.lockfile) except IOError: raise Utils.WafError("Project not configured (run 'waf configure' first)") bld.load_dirs(proj[SRCDIR],proj[BLDDIR]) bld.load_envs() info("Waf: Entering directory `%s'"%bld.bldnode.abspath()) bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]]) bld.pre_build() try: bld.compile() finally: if Options.options.progress_bar:print('') info("Waf: Leaving directory `%s'"%bld.bldnode.abspath()) bld.post_build() bld.install() excludes='.bzr .bzrignore .git .gitignore .svn CVS .cvsignore .arch-ids {arch} SCCS BitKeeper .hg Makefile Makefile.in config.log'.split() dist_exts='~ .rej .orig .pyc .pyo .bak .tar.bz2 tar.gz .zip .swp'.split() def dont_dist(name,src,build_dir): global excludes,dist_exts if(name.startswith(',,')or name.startswith('++')or name.startswith('.waf-1.')or(src=='.'and name==Options.lockfile)or name in excludes or name==build_dir): return True for ext in dist_exts: if name.endswith(ext): return True return False def copytree(src,dst,build_dir): names=os.listdir(src) os.makedirs(dst) for name in names: srcname=os.path.join(src,name) dstname=os.path.join(dst,name) if dont_dist(name,src,build_dir): continue if os.path.isdir(srcname): copytree(srcname,dstname,build_dir) else: shutil.copy2(srcname,dstname) def distclean(ctx=None): '''removes the build directory''' lst=os.listdir('.') for f in lst: if f==Options.lockfile: try: proj=Environment.Environment(f) shutil.rmtree(proj[BLDDIR]) except(OSError,IOError): pass try: os.remove(f) except(OSError,IOError): pass if f.startswith('.waf-'): shutil.rmtree(f,ignore_errors=True) def dist(appname='',version=''): '''makes a tarball for redistributing the sources''' import tarfile if not appname:appname=getattr(Utils.g_module,APPNAME,'noname') if not version:version=getattr(Utils.g_module,VERSION,'1.0') tmp_folder=appname+'-'+version arch_name=tmp_folder+'.tar.'+g_gz try: shutil.rmtree(tmp_folder) except(OSError,IOError): pass try: os.remove(arch_name) except(OSError,IOError): pass copytree('.',tmp_folder,getattr(Utils.g_module,BLDDIR,None)) dist_hook=getattr(Utils.g_module,'dist_hook',None) if dist_hook: back=os.getcwd() os.chdir(tmp_folder) try: dist_hook() finally: os.chdir(back) tar=tarfile.open(arch_name,'w:'+g_gz) tar.add(tmp_folder) tar.close() info('The archive is ready: %s'%arch_name) if os.path.exists(tmp_folder):shutil.rmtree(tmp_folder) return arch_name def distcheck(appname='',version=''): '''checks if the sources compile (tarball from 'dist')''' import tempfile,tarfile if not appname:appname=getattr(Utils.g_module,APPNAME,'noname') if not version:version=getattr(Utils.g_module,VERSION,'1.0') waf=os.path.abspath(sys.argv[0]) tarball=dist(appname,version) t=tarfile.open(tarball) for x in t:t.extract(x) t.close() path=appname+'-'+version instdir=tempfile.mkdtemp('.inst','%s-%s'%(appname,version)) ret=Utils.pproc.Popen([waf,'configure','install','uninstall','--destdir='+instdir],cwd=path).wait() if ret: raise Utils.WafError('distcheck failed with code %i'%ret) if os.path.exists(instdir): raise Utils.WafError('distcheck succeeded, but files were left in %s'%instdir) shutil.rmtree(path) def add_subdir(dir,bld): bld.recurse(dir,'build') slv2-0.6.6+dfsg1/wafadmin/Configure.py0000644000175000017500000001417711176703512017367 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,shlex,sys,time try:import cPickle except ImportError:import pickle as cPickle import Environment,Utils,Options from Logs import warn from Constants import* conf_template='''# project %(app)s configured on %(now)s by # waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) # using %(args)s # ''' class ConfigurationError(Utils.WscriptError): pass autoconfig=False def find_file(filename,path_list): for directory in Utils.to_list(path_list): if os.path.exists(os.path.join(directory,filename)): return directory return'' def find_program_impl(env,filename,path_list=[],var=None,environ=None): if not environ: environ=os.environ try:path_list=path_list.split() except AttributeError:pass if var: if var in environ:env[var]=environ[var] if env[var]:return env[var] if not path_list:path_list=environ['PATH'].split(os.pathsep) ext=(Options.platform=='win32')and'.exe,.com,.bat,.cmd'or'' for y in[filename+x for x in ext.split(',')]: for directory in path_list: x=os.path.join(directory,y) if os.path.isfile(x): if var:env[var]=x return x return'' class ConfigurationContext(Utils.Context): tests={} error_handlers=[] def __init__(self,env=None,blddir='',srcdir=''): self.env=None self.envname='' self.environ=dict(os.environ) self.line_just=40 self.blddir=blddir self.srcdir=srcdir self.all_envs={} self.cwd=self.curdir=os.getcwd() self.tools=[] self.setenv(DEFAULT) self.lastprog='' self.hash=0 self.files=[] self.tool_cache=[] if self.blddir: self.post_init() def post_init(self): self.cachedir=os.path.join(self.blddir,CACHE_DIR) path=os.path.join(self.blddir,WAF_CONFIG_LOG) try:os.unlink(path) except(OSError,IOError):pass self.log=open(path,'w') app=getattr(Utils.g_module,'APPNAME','') if app: ver=getattr(Utils.g_module,'VERSION','') if ver: app="%s (%s)"%(app,ver) now=time.ctime() pyver=sys.hexversion systype=sys.platform args=" ".join(sys.argv) wafver=WAFVERSION abi=ABI self.log.write(conf_template%vars()) def __del__(self): if hasattr(self,'log')and self.log: self.log.close() def fatal(self,msg): raise ConfigurationError(msg) def check_tool(self,input,tooldir=None,funs=None): tools=Utils.to_list(input) if tooldir:tooldir=Utils.to_list(tooldir) for tool in tools: tool=tool.replace('++','xx') mag=(tool,id(self.env),funs) if mag in self.tool_cache: continue self.tool_cache.append(mag) module=Utils.load_tool(tool,tooldir) func=getattr(module,'detect',None) if func: if type(func)is type(find_file):func(self) else:self.eval_rules(funs or func) self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs}) def sub_config(self,k): self.recurse(k,name='configure') def pre_recurse(self,name_or_mod,path,nexdir): return{'conf':self,'ctx':self} def post_recurse(self,name_or_mod,path,nexdir): if not autoconfig: return self.hash=hash((self.hash,getattr(name_or_mod,'waf_hash_val',name_or_mod))) self.files.append(path) def store(self,file=''): if not os.path.isdir(self.cachedir): os.makedirs(self.cachedir) if not file: file=open(os.path.join(self.cachedir,'build.config.py'),'w') file.write('version = 0x%x\n'%HEXVERSION) file.write('tools = %r\n'%self.tools) file.close() if not self.all_envs: self.fatal('nothing to store in the configuration context!') for key in self.all_envs: tmpenv=self.all_envs[key] tmpenv.store(os.path.join(self.cachedir,key+CACHE_SUFFIX)) def set_env_name(self,name,env): self.all_envs[name]=env return env def retrieve(self,name,fromenv=None): try: env=self.all_envs[name] except KeyError: env=Environment.Environment() env['PREFIX']=os.path.abspath(os.path.expanduser(Options.options.prefix)) self.all_envs[name]=env else: if fromenv:warn("The environment %s may have been configured already"%name) return env def setenv(self,name): self.env=self.retrieve(name) self.envname=name def add_os_flags(self,var,dest=None): try:self.env.append_value(dest or var,Utils.to_list(self.environ[var])) except KeyError:pass def check_message_1(self,sr): self.line_just=max(self.line_just,len(sr)) self.log.write(sr+'\n\n') Utils.pprint('NORMAL',"%s :"%sr.ljust(self.line_just),sep='') def check_message_2(self,sr,color='GREEN'): Utils.pprint(color,sr) def check_message(self,th,msg,state,option=''): sr='Checking for %s %s'%(th,msg) self.check_message_1(sr) p=self.check_message_2 if state:p('ok '+option) else:p('not found','YELLOW') def check_message_custom(self,th,msg,custom,option='',color='PINK'): sr='Checking for %s %s'%(th,msg) self.check_message_1(sr) self.check_message_2(custom,color) def find_program(self,filename,path_list=[],var=None,mandatory=False): ret=find_program_impl(self.env,filename,path_list,var,environ=self.environ) self.check_message('program',filename,ret,ret) self.log.write('find program=%r paths=%r var=%r -> %r\n\n'%(filename,path_list,var,ret)) if not ret and mandatory: self.fatal('The program %s could not be found'%filename) return ret def cmd_to_list(self,cmd): if isinstance(cmd,str)and cmd.find(' '): try: os.stat(cmd) except OSError: return shlex.split(cmd) else: return[cmd] return cmd def __getattr__(self,name): r=self.__class__.__dict__.get(name,None) if r:return r if name and name.startswith('require_'): for k in['check_','find_']: n=name.replace('require_',k) ret=self.__class__.__dict__.get(n,None) if ret: def run(*k,**kw): r=ret(self,*k,**kw) if not r: self.fatal('requirement failure') return r return run self.fatal('No such method %r'%name) def eval_rules(self,rules): self.rules=Utils.to_list(rules) for x in self.rules: f=getattr(self,x) if not f:self.fatal("No such method '%s'."%x) try: f() except Exception,e: ret=self.err_handler(x,e) if ret==BREAK: break elif ret==CONTINUE: continue else: self.fatal(e) def err_handler(self,fun,error): pass def conf(f): setattr(ConfigurationContext,f.__name__,f) return f def conftest(f): ConfigurationContext.tests[f.__name__]=f return conf(f) slv2-0.6.6+dfsg1/wafadmin/Utils.py0000644000175000017500000002637711176715151016555 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os,sys,imp,string,errno,traceback,inspect,re,shutil,datetime try:from UserDict import UserDict except ImportError:from collections import UserDict if sys.hexversion>=0x2060000: import subprocess as pproc else: import pproc import Logs from Constants import* is_win32=sys.platform=='win32' try: from collections import defaultdict as DefaultDict except ImportError: class DefaultDict(dict): def __init__(self,default_factory): super(DefaultDict,self).__init__() self.default_factory=default_factory def __getitem__(self,key): try: return super(DefaultDict,self).__getitem__(key) except KeyError: value=self.default_factory() self[key]=value return value class WafError(Exception): def __init__(self,*args): self.args=args self.stack=traceback.extract_stack() Exception.__init__(self,*args) def __str__(self): return str(len(self.args)==1 and self.args[0]or self.args) class WscriptError(WafError): def __init__(self,message,wscript_file=None): if wscript_file: self.wscript_file=wscript_file self.wscript_line=None else: (self.wscript_file,self.wscript_line)=self.locate_error() msg_file_line='' if self.wscript_file: msg_file_line="%s:"%self.wscript_file if self.wscript_line: msg_file_line+="%s:"%self.wscript_line err_message="%s error: %s"%(msg_file_line,message) WafError.__init__(self,err_message) def locate_error(self): stack=traceback.extract_stack() stack.reverse() for frame in stack: file_name=os.path.basename(frame[0]) is_wscript=(file_name==WSCRIPT_FILE or file_name==WSCRIPT_BUILD_FILE) if is_wscript: return(frame[0],frame[1]) return(None,None) indicator=is_win32 and'\x1b[A\x1b[K%s%s%s\r'or'\x1b[K%s%s%s\r' try: from fnv import new as md5 import Constants Constants.SIG_NIL='signofnv' def h_file(filename): m=md5() try: m.hfile(filename) x=m.digest() if x is None:raise OSError("not a file") return x except SystemError: raise OSError("not a file"+filename) except ImportError: try: from hashlib import md5 except ImportError: from md5 import md5 def h_file(filename): f=open(filename,'rb') m=md5() readBytes=100000 while(filename): filename=f.read(100000) m.update(filename) f.close() return m.digest() class ordered_dict(UserDict): def __init__(self,dict=None): self.allkeys=[] UserDict.__init__(self,dict) def __delitem__(self,key): self.allkeys.remove(key) UserDict.__delitem__(self,key) def __setitem__(self,key,item): if key not in self.allkeys:self.allkeys.append(key) UserDict.__setitem__(self,key,item) def exec_command(s,**kw): if'log'in kw: kw['stdout']=kw['stderr']=kw['log'] del(kw['log']) kw['shell']=isinstance(s,str) try: proc=pproc.Popen(s,**kw) return proc.wait() except WindowsError: return-1 if is_win32: old_log=exec_command def exec_command(s,**kw): if len(s)<2000:return old_log(s,**kw) if'log'in kw: kw['stdout']=kw['stderr']=kw['log'] del(kw['log']) kw['shell']=isinstance(s,str) startupinfo=pproc.STARTUPINFO() startupinfo.dwFlags|=pproc.STARTF_USESHOWWINDOW kw['startupinfo']=startupinfo proc=pproc.Popen(s,**kw) return proc.wait() listdir=os.listdir if is_win32: def listdir_win32(s): if re.match('^[A-Za-z]:$',s): s+=os.sep if not os.path.isdir(s): e=OSError() e.errno=errno.ENOENT raise e return os.listdir(s) listdir=listdir_win32 def waf_version(mini=0x010000,maxi=0x100000): ver=HEXVERSION try:min_val=mini+0 except TypeError:min_val=int(mini.replace('.','0'),16) if min_val>ver: Logs.error("waf version should be at least %s (%s found)"%(mini,ver)) sys.exit(0) try:max_val=maxi+0 except TypeError:max_val=int(maxi.replace('.','0'),16) if max_val= 2.3 but the raw source requires Python 2.4") def ex_stack(): exc_type,exc_value,tb=sys.exc_info() exc_lines=traceback.format_exception(exc_type,exc_value,tb) return''.join(exc_lines) def to_list(sth): if isinstance(sth,str): return sth.split() else: return sth g_loaded_modules={} g_module=None def load_module(file_path,name=WSCRIPT_FILE): try: return g_loaded_modules[file_path] except KeyError: pass module=imp.new_module(name) try: code=readf(file_path,m='rU') except(IOError,OSError): raise WscriptError('The file %s could not be opened!'%file_path) module.waf_hash_val=code module_dir=os.path.dirname(file_path) sys.path.insert(0,module_dir) exec(code,module.__dict__) sys.path.remove(module_dir) g_loaded_modules[file_path]=module return module def set_main_module(file_path): global g_module g_module=load_module(file_path,'wscript_main') g_module.root_path=file_path def to_hashtable(s): tbl={} lst=s.split('\n') for line in lst: if not line:continue mems=line.split('=') tbl[mems[0]]=mems[1] return tbl def get_term_cols(): return 80 try: import struct,fcntl,termios except ImportError: pass else: if Logs.got_tty: def myfun(): dummy_lines,cols=struct.unpack("HHHH",fcntl.ioctl(sys.stderr.fileno(),termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[:2] return cols try: myfun() except IOError: pass else: get_term_cols=myfun rot_idx=0 rot_chr=['\\','|','/','-'] def split_path(path): return path.split('/') def split_path_cygwin(path): if path.startswith('//'): ret=path.split('/')[2:] ret[0]='/'+ret[0] return ret return path.split('/') re_sp=re.compile('[/\\\\]') def split_path_win32(path): if path.startswith('\\\\'): ret=re.split(re_sp,path)[2:] ret[0]='\\'+ret[0] return ret return re.split(re_sp,path) if sys.platform=='cygwin': split_path=split_path_cygwin elif is_win32: split_path=split_path_win32 def copy_attrs(orig,dest,names,only_if_set=False): for a in to_list(names): u=getattr(orig,a,()) if u or not only_if_set: setattr(dest,a,u) def def_attrs(cls,**kw): ''' set attributes for class. @param cls [any class]: the class to update the given attributes in. @param kw [dictionary]: dictionary of attributes names and values. if the given class hasn't one (or more) of these attributes, add the attribute with its value to the class. ''' for k,v in kw.iteritems(): if not hasattr(cls,k): setattr(cls,k,v) quote_define_name_table=None def quote_define_name(path): global quote_define_name_table if not quote_define_name_table: invalid_chars=set([chr(x)for x in xrange(256)])-set(string.digits+string.uppercase) quote_define_name_table=string.maketrans(''.join(invalid_chars),'_'*len(invalid_chars)) return string.translate(string.upper(path),quote_define_name_table) def quote_whitespace(path): return(path.strip().find(' ')>0 and'"%s"'%path or path).replace('""','"') def trimquotes(s): if not s:return'' s=s.rstrip() if s[0]=="'"and s[-1]=="'":return s[1:-1] return s def h_list(lst): m=md5() m.update(str(lst)) return m.digest() def h_fun(fun): try: return fun.code except AttributeError: try: h=inspect.getsource(fun) except IOError: h="nocode" try: fun.code=h except AttributeError: pass return h def pprint(col,str,label='',sep=os.linesep): sys.stderr.write("%s%s%s %s%s"%(Logs.colors(col),str,Logs.colors.NORMAL,label,sep)) def check_dir(dir): try: os.stat(dir) except OSError: try: os.makedirs(dir) except OSError,e: raise WafError("Cannot create folder '%s' (original error: %s)"%(dir,e)) def cmd_output(cmd,**kw): silent=kw.get('silent',False) if silent: del(kw['silent']) if'e'in kw: tmp=kw['e'] del(kw['e']) kw['env']=tmp kw['shell']=isinstance(cmd,str) kw['stdout']=pproc.PIPE if silent: kw['stderr']=pproc.PIPE try: p=pproc.Popen(cmd,**kw) output=p.communicate()[0] except WindowsError,e: raise ValueError(str(e)) if p.returncode: if not silent: msg="command execution failed: %s -> %r"%(cmd,str(output)) raise ValueError(msg) output='' return output reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") def subst_vars(expr,params): def repl_var(m): if m.group(1): return'\\' if m.group(2): return'$' try: return params.get_flat(m.group(3)) except AttributeError: return params[m.group(3)] return reg_subst.sub(repl_var,expr) def detect_platform(): s=sys.platform for x in'cygwin linux irix sunos hpux aix darwin'.split(): if s.find(x)>=0: return x if os.name in'posix java os2'.split(): return os.name return s def load_tool(tool,tooldir=None): if tooldir: assert isinstance(tooldir,list) sys.path=tooldir+sys.path try: try: return __import__(tool) except ImportError,e: raise WscriptError(e) finally: if tooldir: for d in tooldir: sys.path.remove(d) def readf(fname,m='r'): f=None try: f=open(fname,m) txt=f.read() finally: if f:f.close() return txt def nada(*k,**kw): pass def diff_path(top,subdir): top=os.path.normpath(top).replace('\\','/').split('/') subdir=os.path.normpath(subdir).replace('\\','/').split('/') if len(top)==len(subdir):return'' diff=subdir[len(top)-len(subdir):] return os.path.join(*diff) class Context(object): def set_curdir(self,dir): self.curdir_=dir def get_curdir(self): try: return self.curdir_ except AttributeError: self.curdir_=os.getcwd() return self.get_curdir() curdir=property(get_curdir,set_curdir) def recurse(self,dirs,name=''): if not name: name=inspect.stack()[1][3] if isinstance(dirs,str): dirs=to_list(dirs) for x in dirs: if os.path.isabs(x): nexdir=x else: nexdir=os.path.join(self.curdir,x) base=os.path.join(nexdir,WSCRIPT_FILE) try: txt=readf(base+'_'+name,m='rU') except(OSError,IOError): try: module=load_module(base) except OSError: raise WscriptError('No such script %s'%base) try: f=module.__dict__[name] except KeyError: raise WscriptError('No function %s defined in %s'%(name,base)) if getattr(self.__class__,'pre_recurse',None): self.pre_recurse(f,base,nexdir) old=self.curdir self.curdir=nexdir try: f(self) finally: self.curdir=old if getattr(self.__class__,'post_recurse',None): self.post_recurse(module,base,nexdir) else: dc={'ctx':self} if getattr(self.__class__,'pre_recurse',None): dc=self.pre_recurse(txt,base+'_'+name,nexdir) old=self.curdir self.curdir=nexdir try: exec(txt,dc) finally: self.curdir=old if getattr(self.__class__,'post_recurse',None): self.post_recurse(txt,base+'_'+name,nexdir) def jar_regexp(regex): if regex.endswith('/'): regex+='**' regex=(re.escape(regex).replace(r"\*\*\/",".*").replace(r"\*\*",".*").replace(r"\*","[^/]*").replace(r"\?","[^/]")) if regex.endswith(r'\/.*'): regex=regex[:-4]+'([/].*)*' regex+='$' return re.compile(regex) if is_win32: old=shutil.copy2 def copy2(src,dst): old(src,dst) shutil.copystat(src,src) setattr(shutil,'copy2',copy2) def get_elapsed_time(start): delta=datetime.datetime.now()-start days=int(delta.days) hours=int(delta.seconds/3600) minutes=int((delta.seconds-hours*3600)/60) seconds=delta.seconds-hours*3600-minutes*60+float(delta.microseconds)/1000/1000 result='' if days: result+='%dd'%days if days or hours: result+='%dh'%hours if days or hours or minutes: result+='%dm'%minutes return'%s%.3fs'%(result,seconds) slv2-0.6.6+dfsg1/wafadmin/Options.py0000644000175000017500000001276611176703512017103 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,sys,imp,types,tempfile,optparse import Logs,Utils,Configure from Constants import* cmds='distclean configure build install clean uninstall check dist distcheck'.split() commands={} is_install=False options={} arg_line=[] launch_dir='' tooldir='' lockfile=os.environ.get('WAFLOCK','.lock-wscript') try:cache_global=os.path.abspath(os.environ['WAFCACHE']) except KeyError:cache_global='' platform=Utils.detect_platform() conf_file='conf-runs-%s-%d.pickle'%(platform,ABI) default_prefix=os.environ.get('PREFIX') if not default_prefix: if platform=='win32':default_prefix=tempfile.gettempdir() else:default_prefix='/usr/local/' default_jobs=os.environ.get('JOBS',-1) if default_jobs<1: try: if os.sysconf_names.has_key('SC_NPROCESSORS_ONLN'): default_jobs=os.sysconf('SC_NPROCESSORS_ONLN') else: default_jobs=int(Utils.cmd_output(['sysctl','-n','hw.ncpu'])) except: default_jobs=int(os.environ.get('NUMBER_OF_PROCESSORS',1)) default_destdir=os.environ.get('DESTDIR','') def get_usage(self): cmds_str=[] module=Utils.g_module if module: tbl=module.__dict__ keys=tbl.keys() keys.sort() if'build'in tbl: if not module.build.__doc__: module.build.__doc__='builds the project' if'configure'in tbl: if not module.configure.__doc__: module.configure.__doc__='configures the project' ban=['set_options','init','shutdown'] optlst=[x for x in keys if not x in ban and type(tbl[x])is type(parse_args_impl)and tbl[x].__doc__ and not x.startswith('_')] just=max([len(x)for x in optlst]) for x in optlst: cmds_str.append(' %s: %s'%(x.ljust(just),tbl[x].__doc__)) ret='\n'.join(cmds_str) else: ret=' '.join(cmds) return'''waf [command] [options] Main commands (example: ./waf build -j4) %s '''%ret setattr(optparse.OptionParser,'get_usage',get_usage) def create_parser(module=None): Logs.debug('options: create_parser is called') parser=optparse.OptionParser(conflict_handler="resolve",version='waf %s (%s)'%(WAFVERSION,WAFREVISION)) parser.formatter.width=Utils.get_term_cols() p=parser.add_option p('-j','--jobs',type='int',default=default_jobs,help='amount of parallel jobs (%r)'%default_jobs,dest='jobs') p('-k','--keep',action='store_true',default=False,help='keep running happily on independent task groups',dest='keep') p('-v','--verbose',action='count',default=0,help='verbosity level -v -vv or -vvv [default: 0]',dest='verbose') p('--nocache',action='store_true',default=False,help='ignore the WAFCACHE (if set)',dest='nocache') p('--zones',action='store',default='',help='debugging zones (task_gen, deps, tasks, etc)',dest='zones') p('-p','--progress',action='count',default=0,help='-p: progress bar; -pp: ide output',dest='progress_bar') p('--targets',action='store',default='',help='build given task generators, e.g. "target1,target2"',dest='compile_targets') gr=optparse.OptionGroup(parser,'configuration options') parser.add_option_group(gr) gr.add_option('-b','--blddir',action='store',default='',help='build dir for the project (configuration)',dest='blddir') gr.add_option('-s','--srcdir',action='store',default='',help='src dir for the project (configuration)',dest='srcdir') gr.add_option('--prefix',help='installation prefix (configuration) [default: %r]'%default_prefix,default=default_prefix,dest='prefix') gr=optparse.OptionGroup(parser,'installation options') parser.add_option_group(gr) gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir') gr.add_option('-f','--force',action='store_true',default=False,help='force file installation',dest='force') return parser def parse_args_impl(parser,_args=None): global options,commands,arg_line (options,args)=parser.parse_args(args=_args) arg_line=args commands={} for var in cmds:commands[var]=0 if not args: commands['build']=1 args.append('build') for arg in args: commands[arg]=True if'check'in args: idx=args.index('check') try: bidx=args.index('build') if bidx>idx: raise ValueError,'build before check' except ValueError,e: args.insert(idx,'build') if args[0]!='init': args.insert(0,'init') if options.keep:options.jobs=1 if options.jobs<1:options.jobs=1 if'install'in sys.argv or'uninstall'in sys.argv: options.destdir=options.destdir and os.path.abspath(os.path.expanduser(options.destdir)) Logs.verbose=options.verbose Logs.init_log() if options.zones: Logs.zones=options.zones.split(',') if not Logs.verbose:Logs.verbose=1 elif Logs.verbose>0: Logs.zones=['runner'] if Logs.verbose>2: Logs.zones=['*'] class Handler(Utils.Context): parser=None def __init__(self,module=None): self.parser=create_parser(module) self.cwd=os.getcwd() Handler.parser=self def add_option(self,*k,**kw): self.parser.add_option(*k,**kw) def add_option_group(self,*k,**kw): return self.parser.add_option_group(*k,**kw) def get_option_group(self,opt_str): return self.parser.get_option_group(opt_str) def sub_options(self,*k,**kw): if not k:raise Utils.WscriptError('folder expected') self.recurse(k[0],name='set_options') def tool_options(self,*k,**kw): if not k[0]: raise Utils.WscriptError('invalid tool_options call %r %r'%(k,kw)) tools=Utils.to_list(k[0]) path=Utils.to_list(kw.get('tdir',kw.get('tooldir',tooldir))) for tool in tools: tool=tool.replace('++','xx') module=Utils.load_tool(tool,path) try: fun=module.set_options except AttributeError: pass else: fun(kw.get('option_group',self)) def parse_args(self,args=None): parse_args_impl(self.parser,args) slv2-0.6.6+dfsg1/wafadmin/Build.py0000644000175000017500000004405011176703512016476 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os,sys,errno,re,glob,gc,datetime,shutil try:import cPickle except:import pickle as cPickle import Runner,TaskGen,Node,Scripting,Utils,Environment,Task,Logs,Options from Logs import debug,error,info from Constants import* SAVED_ATTRS='root srcnode bldnode node_sigs node_deps raw_deps task_sigs id_nodes'.split() bld=None class BuildError(Utils.WafError): def __init__(self,b=None,t=[]): self.bld=b self.tasks=t self.ret=1 Utils.WafError.__init__(self,self.format_error()) def format_error(self): lst=['Build failed'] for tsk in self.tasks: txt=tsk.format_error() if txt:lst.append(txt) return'\n'.join(lst) class BuildContext(Utils.Context): def __init__(self): global bld bld=self self.task_manager=Task.TaskManager() self.id_nodes=0 self.idx={} self.all_envs={} self.bdir='' self.path=None self.deps_man=Utils.DefaultDict(list) self.cache_node_abspath={} self.cache_scanned_folders={} self.uninstall=[] for v in'cache_node_abspath task_sigs node_deps raw_deps node_sigs'.split(): var={} setattr(self,v,var) self.cache_dir_contents={} self.all_task_gen=[] self.task_gen_cache_names={} self.cache_sig_vars={} self.log=None self.root=None self.srcnode=None self.bldnode=None class node_class(Node.Node): pass self.node_class=node_class self.node_class.__module__="Node" self.node_class.__name__="Nodu" self.node_class.bld=self self.is_install=None def __copy__(self): raise Utils.WafError('build contexts are not supposed to be cloned') def load(self): try: env=Environment.Environment(os.path.join(self.cachedir,'build.config.py')) except(IOError,OSError): pass else: if env['version']1:raise if data: for x in SAVED_ATTRS:setattr(self,x,data[x]) else: debug('build: Build cache loading failed') finally: if f:f.close() gc.enable() def save(self): gc.disable() self.root.__class__.bld=None Node.Nodu=self.node_class db=os.path.join(self.bdir,DBFILE) file=open(db+'.tmp','wb') data={} for x in SAVED_ATTRS:data[x]=getattr(self,x) cPickle.dump(data,file,-1) file.close() try:os.unlink(db) except OSError:pass os.rename(db+'.tmp',db) self.root.__class__.bld=self gc.enable() def clean(self): debug('build: clean called') precious=set([]) for env in self.all_envs.values(): for x in env[CFG_FILES]: node=self.srcnode.find_resource(x) if node: precious.add(node.id) def clean_rec(node): for x in node.childs.keys(): nd=node.childs[x] tp=nd.id&3 if tp==Node.DIR: clean_rec(nd) elif tp==Node.BUILD: if nd.id in precious:continue for env in self.all_envs.values(): try:os.remove(nd.abspath(env)) except OSError:pass node.childs.__delitem__(x) clean_rec(self.srcnode) for v in'node_sigs node_deps task_sigs raw_deps cache_node_abspath'.split(): setattr(self,v,{}) def compile(self): debug('build: compile called') self.flush() self.generator=Runner.Parallel(self,Options.options.jobs) def dw(on=True): if Options.options.progress_bar: if on:sys.stderr.write(Logs.colors.cursor_on) else:sys.stderr.write(Logs.colors.cursor_off) debug('build: executor starting') back=os.getcwd() os.chdir(self.bldnode.abspath()) try: try: dw(on=False) self.generator.start() except KeyboardInterrupt: dw() if self.generator.consumers: self.save() raise except Exception: dw() raise else: dw() if self.generator.consumers: self.save() if self.generator.error: raise BuildError(self,self.task_manager.tasks_done) finally: os.chdir(back) def install(self): debug('build: install called') self.flush() if self.is_install<0: lst=[] for x in self.uninstall: dir=os.path.dirname(x) if not dir in lst:lst.append(dir) lst.sort() lst.reverse() nlst=[] for y in lst: x=y while len(x)>4: if not x in nlst:nlst.append(x) x=os.path.dirname(x) nlst.sort() nlst.reverse() for x in nlst: try:os.rmdir(x) except OSError:pass def new_task_gen(self,*k,**kw): kw['bld']=self if len(k)==0: ret=TaskGen.task_gen(*k,**kw) else: cls_name=k[0] try:cls=TaskGen.task_gen.classes[cls_name] except KeyError:raise Utils.WscriptError('%s is not a valid task generator -> %s'%(cls_name,[x for x in TaskGen.task_gen.classes])) ret=cls(*k,**kw) return ret def load_envs(self): try: lst=Utils.listdir(self.cachedir) except OSError,e: if e.errno==errno.ENOENT: raise Utils.WafError('The project was not configured: run "waf configure" first!') else: raise if not lst: raise Utils.WafError('The cache directory is empty: reconfigure the project') for file in lst: if file.endswith(CACHE_SUFFIX): env=Environment.Environment(os.path.join(self.cachedir,file)) name=file[:-len(CACHE_SUFFIX)] self.all_envs[name]=env self.init_variants() for env in self.all_envs.values(): for f in env[CFG_FILES]: newnode=self.path.find_or_declare(f) try: hash=Utils.h_file(newnode.abspath(env)) except(IOError,AttributeError): error("cannot find "+f) hash=SIG_NIL self.node_sigs[env.variant()][newnode.id]=hash self.bldnode=self.root.find_dir(self.bldnode.abspath()) self.path=self.srcnode=self.root.find_dir(self.srcnode.abspath()) self.cwd=self.bldnode.abspath() def setup(self,tool,tooldir=None,funs=None): if isinstance(tool,list): for i in tool:self.setup(i,tooldir) return if not tooldir:tooldir=Options.tooldir file=None module=Utils.load_tool(tool,tooldir) if hasattr(module,"setup"):module.setup(self) if file:file.close() def init_variants(self): debug('build: init variants') lstvariants=[] for env in self.all_envs.values(): if not env.variant()in lstvariants: lstvariants.append(env.variant()) self.lst_variants=lstvariants debug('build: list of variants is %r'%lstvariants) for name in lstvariants+[0]: for v in'node_sigs cache_node_abspath'.split(): var=getattr(self,v) if not name in var: var[name]={} def load_dirs(self,srcdir,blddir,load_cache=1): assert(os.path.isabs(srcdir)) assert(os.path.isabs(blddir)) self.cachedir=os.path.join(blddir,CACHE_DIR) if srcdir==blddir: raise Utils.WafError("build dir must be different from srcdir: %s <-> %s "%(srcdir,blddir)) self.bdir=blddir self.load() if not self.root: Node.Nodu=self.node_class self.root=Node.Nodu('',None,Node.DIR) if not self.srcnode: self.srcnode=self.root.ensure_dir_node_from_path(srcdir) debug('build: srcnode is %s and srcdir %s'%(self.srcnode.name,srcdir)) self.path=self.srcnode try:os.makedirs(blddir) except OSError:pass if not self.bldnode: self.bldnode=self.root.ensure_dir_node_from_path(blddir) self.init_variants() def rescan(self,src_dir_node): if self.cache_scanned_folders.get(src_dir_node.id,None):return self.cache_scanned_folders[src_dir_node.id]=1 if hasattr(self,'repository'):self.repository(src_dir_node) if sys.platform=="win32"and not src_dir_node.name: return self.listdir_src(src_dir_node) h1=self.srcnode.height() h2=src_dir_node.height() lst=[] child=src_dir_node while h2>h1: lst.append(child.name) child=child.parent h2-=1 lst.reverse() for variant in self.lst_variants: sub_path=os.path.join(self.bldnode.abspath(),variant,*lst) try: self.listdir_bld(src_dir_node,sub_path,variant) except OSError: dict=self.node_sigs[variant] for node in src_dir_node.childs.values(): if node.id in dict: dict.__delitem__(node.id) if node.id!=self.bldnode.id: src_dir_node.childs.__delitem__(node.name) os.makedirs(sub_path) def listdir_src(self,parent_node): parent_path=parent_node.abspath() try: lst=set(Utils.listdir(parent_path)) except OSError: if not parent_node.childs: raise for x in parent_node.childs.values(): if x.id&3==Node.FILE: raise lst=set([]) self.cache_dir_contents[parent_node.id]=lst debug('build: folder contents %r'%lst) node_names=set([x.name for x in parent_node.childs.values()if x.id&3 in(Node.FILE,Node.DIR)]) cache=self.node_sigs[0] to_keep=lst&node_names for x in to_keep: node=parent_node.childs[x] if node.id&3==Node.DIR:continue try: cache[node.id]=Utils.h_file(parent_path+os.sep+node.name) except IOError: raise Utils.WafError("The file %s is not readable or has become a dir"%node.abspath()) to_remove=node_names-lst if to_remove: for name in to_remove: nd=parent_node.childs[name] if nd.id&3==Node.DIR: for x in nd.childs.values(): if x.id&3==Node.FILE: break else: continue self.remove_node(nd) def remove_node(self,node): if node.id&3==Node.DIR: for x in node.childs.values(): self.remove_node(x) if node.id!=self.bldnode.id: node.parent.childs.__delitem__(node.name) elif node.id&3==Node.FILE: if node.id in self.node_sigs[0]: self.node_sigs[0].__delitem__(node.id) node.parent.childs.__delitem__(node.name) else: for variant in self.lst_variants: if node.id in self.node_sigs[variant]: self.node_sigs[variant].__delitem__(node.id) node.parent.childs.__delitem__(node.name) def listdir_bld(self,parent_node,path,variant): i_existing_nodes=[x for x in parent_node.childs.values()if x.id&3==Node.BUILD] lst=set(Utils.listdir(path)) node_names=set([x.name for x in i_existing_nodes]) remove_names=node_names-lst ids_to_remove=[x.id for x in i_existing_nodes if x.name in remove_names] cache=self.node_sigs[variant] for nid in ids_to_remove: if nid in cache: cache.__delitem__(nid) def get_env(self): return self.env_of_name('default') def set_env(self,name,val): self.all_envs[name]=val env=property(get_env,set_env) def add_manual_dependency(self,path,value): if isinstance(path,Node.Node): node=path elif os.path.isabs(path): node=self.root.find_resource(path) else: node=self.path.find_resource(path) self.deps_man[node.id].append(value) def launch_node(self): try: return self.p_ln except AttributeError: self.p_ln=self.root.find_dir(Options.launch_dir) return self.p_ln def glob(self,pattern,relative=True): path=self.path.abspath() files=[self.root.find_resource(x)for x in glob.glob(path+os.sep+pattern)] if relative: files=[x.path_to_parent(self.path)for x in files if x] else: files=[x.abspath()for x in files if x] return files def add_group(self,*k): self.task_manager.add_group(*k) def set_group(self,*k,**kw): self.task_manager.set_group(*k,**kw) def hash_env_vars(self,env,vars_lst): idx=str(id(env))+str(vars_lst) try:return self.cache_sig_vars[idx] except KeyError:pass lst=[str(env[a])for a in vars_lst] ret=Utils.h_list(lst) debug("envhash: %r %r"%(ret,lst)) self.cache_sig_vars[idx]=ret return ret def name_to_obj(self,name,env): cache=self.task_gen_cache_names if not cache: for x in self.all_task_gen: vt=x.env.variant()+'_' if x.name: cache[vt+x.name]=x else: if isinstance(x.target,str): target=x.target else: target=' '.join(x.target) v=vt+target if not cache.get(v,None): cache[v]=x return cache.get(env.variant()+'_'+name,None) def flush(self,all=1): self.ini=datetime.datetime.now() self.task_gen_cache_names={} self.name_to_obj('',self.env) debug('build: delayed operation TaskGen.flush() called') if Options.options.compile_targets: debug('task_gen: posting objects listed in compile_targets') target_objects=Utils.DefaultDict(list) for target_name in Options.options.compile_targets.split(','): target_name=target_name.strip() for env in self.all_envs.values(): obj=self.name_to_obj(target_name,env) if obj: target_objects[target_name].append(obj) if not target_name in target_objects and all: raise Utils.WafError("target '%s' does not exist"%target_name) to_compile=[] for x in target_objects.values(): for y in x: to_compile.append(id(y)) for i in xrange(len(self.task_manager.groups)): g=self.task_manager.groups[i] self.task_manager.current_group=i for tg in g.tasks_gen: if id(tg)in to_compile: tg.post() else: debug('task_gen: posting objects (normal)') ln=self.launch_node() if ln.is_child_of(self.bldnode)or not ln.is_child_of(self.srcnode): ln=self.srcnode proj_node=self.root.find_dir(os.path.split(Utils.g_module.root_path)[0]) if proj_node.id!=self.srcnode.id: ln=self.srcnode for i in xrange(len(self.task_manager.groups)): g=self.task_manager.groups[i] self.task_manager.current_group=i for tg in g.tasks_gen: if not tg.path.is_child_of(ln): continue tg.post() def env_of_name(self,name): try: return self.all_envs[name] except KeyError: error('no such environment: '+name) return None def progress_line(self,state,total,col1,col2): n=len(str(total)) Utils.rot_idx+=1 ind=Utils.rot_chr[Utils.rot_idx%4] ini=self.ini pc=(100.*state)/total eta=Utils.get_elapsed_time(ini) fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind) left=fs%(state,total,col1,pc,col2) right='][%s%s%s]'%(col1,eta,col2) cols=Utils.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2) if cols<7:cols=7 ratio=int((cols*state)/total)-1 bar=('='*ratio+'>').ljust(cols) msg=Utils.indicator%(left,bar,right) return msg def do_install(self,src,tgt,chmod=O644): if self.is_install>0: if not Options.options.force: try: st1=os.stat(tgt) st2=os.stat(src) except OSError: pass else: if st1.st_mtime>=st2.st_mtime and st1.st_size==st2.st_size: return False srclbl=src.replace(self.srcnode.abspath(None)+os.sep,'') info("* installing %s as %s"%(srclbl,tgt)) try:os.remove(tgt) except OSError:pass try: shutil.copy2(src,tgt) os.chmod(tgt,chmod) except IOError: try: os.stat(src) except(OSError,IOError): error('File %r does not exist'%src) raise Utils.WafError('Could not install the file %r'%tgt) return True elif self.is_install<0: info("* uninstalling %s"%tgt) self.uninstall.append(tgt) try:os.remove(tgt) except OSError:pass return True def get_install_path(self,path,env=None): if not env:env=self.env destdir=env.get_destdir() path=path.replace('/',os.sep) destpath=Utils.subst_vars(path,env) if destdir: destpath=os.path.join(destdir,destpath.lstrip(os.sep)) return destpath def install_files(self,path,files,env=None,chmod=O644,relative_trick=False): if env: assert isinstance(env,Environment.Environment),"invalid parameter" if not self.is_install:return[] if not path:return[] node=self.path if isinstance(files,str)and'*'in files: gl=node.abspath()+os.sep+files lst=glob.glob(gl) else: lst=Utils.to_list(files) env=env or self.env destpath=self.get_install_path(path,env) Utils.check_dir(destpath) installed_files=[] for filename in lst: if not os.path.isabs(filename): nd=node.find_resource(filename) if not nd: raise Utils.WafError("Unable to install the file `%s': not found in %s"%(filename,node)) if relative_trick: destfile=os.path.join(destpath,filename) Utils.check_dir(os.path.dirname(destfile)) else: destfile=os.path.join(destpath,nd.name) filename=nd.abspath(env) else: alst=Utils.split_path(filename) destfile=os.path.join(destpath,alst[-1]) if self.do_install(filename,destfile,chmod): installed_files.append(destfile) return installed_files def install_as(self,path,srcfile,env=None,chmod=O644): if env: assert isinstance(env,Environment.Environment),"invalid parameter" if not self.is_install:return False if not path:return False if not env:env=self.env node=self.path destpath=self.get_install_path(path,env) dir,name=os.path.split(destpath) Utils.check_dir(dir) if not os.path.isabs(srcfile): filenode=node.find_resource(srcfile) src=filenode.abspath(env) else: src=srcfile return self.do_install(src,destpath,chmod) def symlink_as(self,path,src,env=None): if not self.is_install:return if not path:return tgt=self.get_install_path(path,env) dir,name=os.path.split(tgt) Utils.check_dir(dir) if self.is_install>0: link=False if not os.path.islink(tgt): link=True elif os.readlink(tgt)!=src: link=True try:os.remove(tgt) except OSError:pass if link: info('* symlink %s (-> %s)'%(tgt,src)) os.symlink(src,tgt) return 0 else: try: info("* removing %s"%(tgt)) os.remove(tgt) return 0 except OSError: return 1 def exec_command(self,cmd,**kw): debug('runner: system command -> %s'%cmd) if self.log: self.log.write('%s\n'%cmd) kw['log']=self.log try: if not kw.get('cwd',None): kw['cwd']=self.cwd except AttributeError: self.cwd=kw['cwd']=self.bldnode.abspath() return Utils.exec_command(cmd,**kw) def printout(self,s): f=self.log or sys.stderr f.write(s) f.flush() def add_subdirs(self,dirs): self.recurse(dirs,'build') def pre_recurse(self,name_or_mod,path,nexdir): if not hasattr(self,'oldpath'): self.oldpath=[] self.oldpath.append(self.path) self.path=self.root.find_dir(nexdir) return{'bld':self,'ctx':self} def post_recurse(self,name_or_mod,path,nexdir): self.path=self.oldpath.pop() def pre_build(self): if hasattr(self,'pre_funs'): for m in self.pre_funs: m(self) def post_build(self): if hasattr(self,'post_funs'): for m in self.post_funs: m(self) def add_pre_fun(self,meth): try:self.pre_funs.append(meth) except AttributeError:self.pre_funs=[meth] def add_post_fun(self,meth): try:self.post_funs.append(meth) except AttributeError:self.post_funs=[meth] def use_the_magic(self): Task.algotype=Task.MAXPARALLEL Task.file_deps=Task.extract_deps slv2-0.6.6+dfsg1/wafadmin/Runner.py0000644000175000017500000000701111176703512016704 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import sys,random,time,threading,traceback try:from Queue import Queue except ImportError:from queue import Queue import Build,Utils,Logs,Options from Logs import debug,error from Constants import* GAP=15 run_old=threading.Thread.run def run(*args,**kwargs): try: run_old(*args,**kwargs) except(KeyboardInterrupt,SystemExit): raise except: sys.excepthook(*sys.exc_info()) threading.Thread.run=run class TaskConsumer(threading.Thread): def __init__(self,m): threading.Thread.__init__(self) self.setDaemon(1) self.master=m self.start() def run(self): try: self.loop() except: pass def loop(self): m=self.master while 1: tsk=m.ready.get() if m.stop: m.out.put(tsk) continue try: tsk.generator.bld.printout(tsk.display()) if tsk.__class__.stat:ret=tsk.__class__.stat(tsk) else:ret=tsk.call_run() except Exception,e: tsk.err_msg=Utils.ex_stack() tsk.hasrun=EXCEPTION m.error_handler(tsk) m.out.put(tsk) continue if ret: tsk.err_code=ret tsk.hasrun=CRASHED else: try: tsk.post_run() except Utils.WafError: pass except Exception: tsk.err_msg=Utils.ex_stack() tsk.hasrun=EXCEPTION else: tsk.hasrun=SUCCESS if tsk.hasrun!=SUCCESS: m.error_handler(tsk) m.out.put(tsk) class Parallel(object): def __init__(self,bld,j=2): self.numjobs=j self.manager=bld.task_manager self.manager.current_group=0 self.total=self.manager.total() self.outstanding=[] self.maxjobs=MAXJOBS self.frozen=[] self.ready=Queue(0) self.out=Queue(0) self.count=0 self.processed=1 self.consumers=None self.stop=False self.error=False def get_next(self): if not self.outstanding: return None return self.outstanding.pop(0) def postpone(self,tsk): if random.randint(0,1): self.frozen.insert(0,tsk) else: self.frozen.append(tsk) def refill_task_list(self): while self.count>self.numjobs+GAP or self.count>=self.maxjobs: self.get_out() while not self.outstanding: if self.count: self.get_out() if self.frozen: self.outstanding+=self.frozen self.frozen=[] elif not self.count: (self.maxjobs,tmp)=self.manager.get_next_set() if tmp:self.outstanding+=tmp break def get_out(self): ret=self.out.get() self.manager.add_finished(ret) if not self.stop and getattr(ret,'more_tasks',None): self.outstanding+=ret.more_tasks self.total+=len(ret.more_tasks) self.count-=1 def error_handler(self,tsk): if not Options.options.keep: self.stop=True self.error=True def start(self): while not self.stop: self.refill_task_list() tsk=self.get_next() if not tsk: if self.count: continue else: break if tsk.hasrun: self.processed+=1 self.manager.add_finished(tsk) continue try: st=tsk.runnable_status() except Exception,e: tsk.err_msg=Utils.ex_stack() tsk.hasrun=EXCEPTION self.processed+=1 self.error_handler(tsk) self.manager.add_finished(tsk) continue if st==ASK_LATER: self.postpone(tsk) elif st==SKIP_ME: self.processed+=1 tsk.hasrun=SKIPPED self.manager.add_finished(tsk) else: tsk.position=(self.processed,self.total) self.count+=1 self.ready.put(tsk) self.processed+=1 if not self.consumers: self.consumers=[TaskConsumer(self)for i in xrange(self.numjobs)] while self.error and self.count: self.get_out() assert(self.count==0 or self.stop) slv2-0.6.6+dfsg1/wafadmin/Task.py0000644000175000017500000004612711176703512016350 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os,shutil,sys,re,random,datetime from Utils import md5 import Build,Runner,Utils,Node,Logs,Options from Logs import debug,warn,error from Constants import* algotype=NORMAL COMPILE_TEMPLATE_SHELL=''' def f(task): env = task.env wd = getattr(task, 'cwd', None) p = env.get_flat cmd = \'\'\' %s \'\'\' % s return task.exec_command(cmd, cwd=wd) ''' COMPILE_TEMPLATE_NOSHELL=''' def f(task): env = task.env wd = getattr(task, 'cwd', None) def to_list(xx): if isinstance(xx, str): return [xx] return xx lst = [] %s lst = [x for x in lst if x] return task.exec_command(lst, cwd=wd) ''' file_deps=Utils.nada class TaskManager(object): def __init__(self): self.groups=[] self.tasks_done=[] self.current_group=0 self.groups_names={} def get_next_set(self): ret=None while not ret and self.current_group0: self.set_order(keys[i],keys[j]) elif val<0: self.set_order(keys[j],keys[i]) def tasks_in_parallel(self): if not self.ready:self.prepare() keys=self.cstr_groups.keys() unconnected=[] remainder=[] for u in keys: for k in self.cstr_order.values(): if u in k: remainder.append(u) break else: unconnected.append(u) toreturn=[] for y in unconnected: toreturn.extend(self.cstr_groups[y]) for y in unconnected: try:self.cstr_order.__delitem__(y) except KeyError:pass self.cstr_groups.__delitem__(y) if not toreturn and remainder: raise Utils.WafError("circular order constraint detected %r"%remainder) return toreturn def tasks_by_max_jobs(self): if not self.ready:self.prepare() if not self.temp_tasks:self.temp_tasks=self.tasks_in_parallel() if not self.temp_tasks:return(None,None) maxjobs=MAXJOBS ret=[] remaining=[] for t in self.temp_tasks: m=getattr(t,"maxjobs",getattr(self.__class__,"maxjobs",MAXJOBS)) if m>maxjobs: remaining.append(t) elif m task failed (err #%d): %r"%(self.err_code,self) except AttributeError: return" -> task failed: %r"%self elif self.hasrun==MISSING: return" -> missing files: %r"%self else: return'' def install(self): bld=self.generator.bld d=self.attr('install') if self.attr('install_path'): lst=[a.relpath_gen(bld.srcnode)for a in self.outputs] perm=self.attr('chmod',O644) if self.attr('src'): lst+=[a.relpath_gen(bld.srcnode)for a in self.inputs] if self.attr('filename'): dir=self.install_path.rstrip(os.sep)+os.sep+self.attr('filename') bld.install_as(dir,lst[0],self.env,perm) else: bld.install_files(self.install_path,lst,self.env,perm) class Task(TaskBase): vars=[] def __init__(self,env,**kw): TaskBase.__init__(self,**kw) self.env=env self.inputs=[] self.outputs=[] self.deps_nodes=[] self.run_after=[] def __str__(self): env=self.env src_str=' '.join([a.nice_path(env)for a in self.inputs]) tgt_str=' '.join([a.nice_path(env)for a in self.outputs]) if self.outputs:sep=' -> ' else:sep='' return'%s: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str) def __repr__(self): return"".join(['\n\t{task: ',self.__class__.__name__," ",",".join([x.name for x in self.inputs])," -> ",",".join([x.name for x in self.outputs]),'}']) def unique_id(self): try: return self.uid except AttributeError: m=md5() up=m.update up(self.__class__.__name__) up(self.env.variant()) p=None for x in self.inputs+self.outputs: if p!=x.parent.id: p=x.parent.id up(x.parent.abspath()) up(x.name) self.uid=m.digest() return self.uid def set_inputs(self,inp): if isinstance(inp,list):self.inputs+=inp else:self.inputs.append(inp) def set_outputs(self,out): if isinstance(out,list):self.outputs+=out else:self.outputs.append(out) def set_run_after(self,task): assert isinstance(task,TaskBase) self.run_after.append(task) def add_file_dependency(self,filename): node=self.generator.bld.current.find_resource(filename) self.deps_nodes.append(node) def signature(self): try:return self.cache_sig[0] except AttributeError:pass m=md5() exp_sig=self.sig_explicit_deps() m.update(exp_sig) imp_sig=self.scan and self.sig_implicit_deps()or SIG_NIL m.update(imp_sig) var_sig=self.sig_vars() m.update(var_sig) ret=m.digest() self.cache_sig=(ret,exp_sig,imp_sig,var_sig) return ret def runnable_status(self): if self.inputs and(not self.outputs): if not getattr(self.__class__,'quiet',None): warn("invalid task (no inputs OR outputs): override in a Task subclass or set the attribute 'quiet' %r"%self) for t in self.run_after: if not t.hasrun: return ASK_LATER env=self.env bld=self.generator.bld try: new_sig=self.signature() except KeyError: debug("task: something is wrong, computing the task %r signature failed"%self) return RUN_ME key=self.unique_id() try: prev_sig=bld.task_sigs[key][0] except KeyError: debug("task: task %r must run as it was never run before or the task code changed"%self) return RUN_ME try: for node in self.outputs: variant=node.variant(env) if bld.node_sigs[variant][node.id]!=new_sig: return RUN_ME except KeyError: debug("task: task %r must run as the output nodes do not exist"%self) return RUN_ME if Logs.verbose:self.debug_why(bld.task_sigs[key]) if new_sig!=prev_sig: return RUN_ME return SKIP_ME def post_run(self): bld=self.generator.bld env=self.env sig=self.signature() cnt=0 variant=env.variant() for node in self.outputs: try: os.stat(node.abspath(env)) except OSError: self.has_run=MISSING self.err_msg='-> missing file: %r'%node.abspath(env) raise Utils.WafError bld.node_sigs[variant][node.id]=sig if Options.cache_global: ssig=sig.encode('hex') dest=os.path.join(Options.cache_global,'%s_%d_%s'%(ssig,cnt,node.name)) try:shutil.copy2(node.abspath(env),dest) except IOError:warn('Could not write the file to the cache') cnt+=1 bld.task_sigs[self.unique_id()]=self.cache_sig def can_retrieve_cache(self): if not Options.cache_global:return None if Options.options.nocache:return None if not self.outputs:return None env=self.env sig=self.signature() cnt=0 for node in self.outputs: variant=node.variant(env) ssig=sig.encode('hex') orig=os.path.join(Options.cache_global,'%s_%d_%s'%(ssig,cnt,node.name)) try: shutil.copy2(orig,node.abspath(env)) os.utime(orig,None) except(OSError,IOError): debug('task: failed retrieving file') return None else: cnt+=1 for node in self.outputs: self.generator.bld.node_sigs[variant][node.id]=sig self.generator.bld.printout('restoring from cache %r\n'%node.bldpath(env)) return 1 def debug_why(self,old_sigs): new_sigs=self.cache_sig def v(x): return x.encode('hex') debug("Task %r"%self) msgs=['Task must run','* Source file or manual dependency','* Implicit dependency','* Environment variable'] tmp='task: -> %s: %s %s' for x in xrange(len(msgs)): if(new_sigs[x]!=old_sigs[x]): debug(tmp%(msgs[x],v(old_sigs[x]),v(new_sigs[x]))) def sig_explicit_deps(self): bld=self.generator.bld m=md5() for x in self.inputs+getattr(self,'dep_nodes',[]): if not x.parent.id in bld.cache_scanned_folders: bld.rescan(x.parent) variant=x.variant(self.env) m.update(bld.node_sigs[variant][x.id]) if bld.deps_man: additional_deps=bld.deps_man for x in self.inputs+self.outputs: try: d=additional_deps[x.id] except KeyError: continue for v in d: if isinstance(v,Node.Node): bld.rescan(v.parent) variant=v.variant(self.env) try: v=bld.node_sigs[variant][v.id] except KeyError: v='' elif hasattr(v,'__call__'): v=v() m.update(v) return m.digest() def sig_vars(self): m=md5() bld=self.generator.bld env=self.env act_sig=bld.hash_env_vars(env,self.__class__.vars) m.update(act_sig) dep_vars=getattr(self,'dep_vars',None) if dep_vars: m.update(bld.hash_env_vars(env,dep_vars)) return m.digest() scan=None def sig_implicit_deps(self): bld=self.generator.bld key=self.unique_id() prev_sigs=bld.task_sigs.get(key,()) if prev_sigs: try: if prev_sigs[2]==self.compute_sig_implicit_deps(): return prev_sigs[2] except(KeyError,OSError): pass (nodes,names)=self.scan() if Logs.verbose: debug('deps: scanner for %s returned %s %s'%(str(self),str(nodes),str(names))) bld.node_deps[key]=nodes bld.raw_deps[key]=names sig=self.compute_sig_implicit_deps() return sig def compute_sig_implicit_deps(self): m=md5() upd=m.update bld=self.generator.bld tstamp=bld.node_sigs env=self.env for k in bld.node_deps.get(self.unique_id(),[]): if not k.parent.id in bld.cache_scanned_folders: bld.rescan(k.parent) if k.id&3==2: upd(tstamp[0][k.id]) else: upd(tstamp[env.variant()][k.id]) return m.digest() def funex(c): dc={} exec(c,dc) return dc['f'] reg_act=re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})",re.M) def compile_fun_shell(name,line): extr=[] def repl(match): g=match.group if g('dollar'):return"$" elif g('backslash'):return'\\\\' elif g('subst'):extr.append((g('var'),g('code')));return"%s" return None line=reg_act.sub(repl,line) parm=[] dvars=[] app=parm.append for(var,meth)in extr: if var=='SRC': if meth:app('task.inputs%s'%meth) else:app('" ".join([a.srcpath(env) for a in task.inputs])') elif var=='TGT': if meth:app('task.outputs%s'%meth) else:app('" ".join([a.bldpath(env) for a in task.outputs])') else: if not var in dvars:dvars.append(var) app("p('%s')"%var) if parm:parm="%% (%s) "%(',\n\t\t'.join(parm)) else:parm='' c=COMPILE_TEMPLATE_SHELL%(line,parm) debug('action: %s'%c) return(funex(c),dvars) def compile_fun_noshell(name,line): extr=[] def repl(match): g=match.group if g('dollar'):return"$" elif g('subst'):extr.append((g('var'),g('code')));return"<<|@|>>" return None line2=reg_act.sub(repl,line) params=line2.split('<<|@|>>') buf=[] dvars=[] app=buf.append for x in xrange(len(extr)): params[x]=params[x].strip() if params[x]: app("lst.extend(%r)"%params[x].split()) (var,meth)=extr[x] if var=='SRC': if meth:app('lst.append(task.inputs%s)'%meth) else:app("lst.extend([a.srcpath(env) for a in task.inputs])") elif var=='TGT': if meth:app('lst.append(task.outputs%s)'%meth) else:app("lst.extend([a.bldpath(env) for a in task.outputs])") else: app('lst.extend(to_list(env[%r]))'%var) if not var in dvars:dvars.append(var) if extr: if params[-1]: app("lst.extend(%r)"%params[-1].split()) fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf) debug('action: %s'%fun) return(funex(fun),dvars) def compile_fun(name,line,shell=None): if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0: shell=True if shell is None: if sys.platform=='win32': shell=False else: shell=True if shell: return compile_fun_shell(name,line) else: return compile_fun_noshell(name,line) def simple_task_type(name,line,color='GREEN',vars=[],ext_in=[],ext_out=[],before=[],after=[],shell=None): (fun,dvars)=compile_fun(name,line,shell) fun.code=line return task_type_from_func(name,fun,vars or dvars,color,ext_in,ext_out,before,after) def task_type_from_func(name,func,vars=[],color='GREEN',ext_in=[],ext_out=[],before=[],after=[]): params={'run':func,'vars':vars,'color':color,'name':name,'ext_in':Utils.to_list(ext_in),'ext_out':Utils.to_list(ext_out),'before':Utils.to_list(before),'after':Utils.to_list(after),} cls=type(Task)(name,(Task,),params) TaskBase.classes[name]=cls return cls def always_run(cls): old=cls.runnable_status def always(self): old(self) return RUN_ME cls.runnable_status=always def update_outputs(cls): old_post_run=cls.post_run def post_run(self): old_post_run(self) bld=self.outputs[0].__class__.bld bld.node_sigs[self.env.variant()][self.outputs[0].id]=Utils.h_file(self.outputs[0].abspath(self.env)) cls.post_run=post_run def extract_outputs(tasks): v={} for x in tasks: try: (ins,outs)=v[x.env.variant()] except KeyError: ins={} outs={} v[x.env.variant()]=(ins,outs) for a in getattr(x,'inputs',[]): try:ins[a.id].append(x) except KeyError:ins[a.id]=[x] for a in getattr(x,'outputs',[]): try:outs[a.id].append(x) except KeyError:outs[a.id]=[x] for(ins,outs)in v.values(): links=set(ins.iterkeys()).intersection(outs.iterkeys()) for k in links: for a in ins[k]: for b in outs[k]: a.set_run_after(b) def extract_deps(tasks): extract_outputs(tasks) out_to_task={} for x in tasks: v=x.env.variant() try: lst=x.outputs except AttributeError: pass else: for node in lst: out_to_task[(v,node.id)]=x dep_to_task={} for x in tasks: try: x.signature() except: pass variant=x.env.variant() key=x.unique_id() for k in x.generator.bld.node_deps.get(x.unique_id(),[]): try:dep_to_task[(v,k.id)].append(x) except KeyError:dep_to_task[(v,k.id)]=[x] deps=set(dep_to_task.keys()).intersection(set(out_to_task.keys())) for idx in deps: for k in dep_to_task[idx]: k.set_run_after(out_to_task[idx]) for x in tasks: try: delattr(x,'cache_sig') except AttributeError: pass slv2-0.6.6+dfsg1/wafadmin/Constants.py0000644000175000017500000000147311176703512017415 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 HEXVERSION=0x10506 WAFVERSION="1.5.6" WAFREVISION="6178M" ABI=7 O644=420 O755=493 MAXJOBS=99999999 CACHE_DIR='c4che' CACHE_SUFFIX='.cache.py' DBFILE='.wafpickle-%d'%ABI WSCRIPT_FILE='wscript' WSCRIPT_BUILD_FILE='wscript_build' WAF_CONFIG_LOG='config.log' WAF_CONFIG_H='config.h' SIG_NIL='iluvcuteoverload' VARIANT='_VARIANT_' DEFAULT='default' SRCDIR='srcdir' BLDDIR='blddir' APPNAME='APPNAME' VERSION='VERSION' DEFINES='defines' UNDEFINED=() BREAK="break" CONTINUE="continue" JOBCONTROL="JOBCONTROL" MAXPARALLEL="MAXPARALLEL" NORMAL="NORMAL" NOT_RUN=0 MISSING=1 CRASHED=2 EXCEPTION=3 SKIPPED=8 SUCCESS=9 ASK_LATER=-1 SKIP_ME=-2 RUN_ME=-3 LOG_FORMAT="%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s" HOUR_FORMAT="%H:%M:%S" TEST_OK=True CFG_FILES='cfg_files' INSTALL=1337 UNINSTALL=-1337 slv2-0.6.6+dfsg1/wafadmin/pproc.py0000644000175000017500000003471211176703512016566 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys mswindows=(sys.platform=="win32") import os import types import traceback import gc class CalledProcessError(Exception): def __init__(self,returncode,cmd): self.returncode=returncode self.cmd=cmd def __str__(self): return"Command '%s' returned non-zero exit status %d"%(self.cmd,self.returncode) if mswindows: import threading import msvcrt if 0: import pywintypes from win32api import GetStdHandle,STD_INPUT_HANDLE,STD_OUTPUT_HANDLE,STD_ERROR_HANDLE from win32api import GetCurrentProcess,DuplicateHandle,GetModuleFileName,GetVersion from win32con import DUPLICATE_SAME_ACCESS,SW_HIDE from win32pipe import CreatePipe from win32process import CreateProcess,STARTUPINFO,GetExitCodeProcess,STARTF_USESTDHANDLES,STARTF_USESHOWWINDOW,CREATE_NEW_CONSOLE from win32event import WaitForSingleObject,INFINITE,WAIT_OBJECT_0 else: from _subprocess import* class STARTUPINFO: dwFlags=0 hStdInput=None hStdOutput=None hStdError=None wShowWindow=0 class pywintypes: error=IOError else: import select import errno import fcntl import pickle __all__=["Popen","PIPE","STDOUT","call","check_call","CalledProcessError"] try: MAXFD=os.sysconf("SC_OPEN_MAX") except: MAXFD=256 try: False except NameError: False=0 True=1 _active=[] def _cleanup(): for inst in _active[:]: if inst.poll(_deadstate=sys.maxint)>=0: try: _active.remove(inst) except ValueError: pass PIPE=-1 STDOUT=-2 def call(*popenargs,**kwargs): return Popen(*popenargs,**kwargs).wait() def check_call(*popenargs,**kwargs): retcode=call(*popenargs,**kwargs) cmd=kwargs.get("args") if cmd is None: cmd=popenargs[0] if retcode: raise CalledProcessError(retcode,cmd) return retcode def list2cmdline(seq): result=[] needquote=False for arg in seq: bs_buf=[] if result: result.append(' ') needquote=(" "in arg)or("\t"in arg)or arg=="" if needquote: result.append('"') for c in arg: if c=='\\': bs_buf.append(c) elif c=='"': result.append('\\'*len(bs_buf)*2) bs_buf=[] result.append('\\"') else: if bs_buf: result.extend(bs_buf) bs_buf=[] result.append(c) if bs_buf: result.extend(bs_buf) if needquote: result.extend(bs_buf) result.append('"') return''.join(result) class Popen(object): def __init__(self,args,bufsize=0,executable=None,stdin=None,stdout=None,stderr=None,preexec_fn=None,close_fds=False,shell=False,cwd=None,env=None,universal_newlines=False,startupinfo=None,creationflags=0): _cleanup() self._child_created=False if not isinstance(bufsize,(int,long)): raise TypeError("bufsize must be an integer") if mswindows: if preexec_fn is not None: raise ValueError("preexec_fn is not supported on Windows platforms") if close_fds: raise ValueError("close_fds is not supported on Windows platforms") else: if startupinfo is not None: raise ValueError("startupinfo is only supported on Windows platforms") if creationflags!=0: raise ValueError("creationflags is only supported on Windows platforms") self.stdin=None self.stdout=None self.stderr=None self.pid=None self.returncode=None self.universal_newlines=universal_newlines (p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite)=self._get_handles(stdin,stdout,stderr) self._execute_child(args,executable,preexec_fn,close_fds,cwd,env,universal_newlines,startupinfo,creationflags,shell,p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite) if mswindows: if stdin is None and p2cwrite is not None: os.close(p2cwrite) p2cwrite=None if stdout is None and c2pread is not None: os.close(c2pread) c2pread=None if stderr is None and errread is not None: os.close(errread) errread=None if p2cwrite: self.stdin=os.fdopen(p2cwrite,'wb',bufsize) if c2pread: if universal_newlines: self.stdout=os.fdopen(c2pread,'rU',bufsize) else: self.stdout=os.fdopen(c2pread,'rb',bufsize) if errread: if universal_newlines: self.stderr=os.fdopen(errread,'rU',bufsize) else: self.stderr=os.fdopen(errread,'rb',bufsize) def _translate_newlines(self,data): data=data.replace("\r\n","\n") data=data.replace("\r","\n") return data def __del__(self,sys=sys): if not self._child_created: return self.poll(_deadstate=sys.maxint) if self.returncode is None and _active is not None: _active.append(self) def communicate(self,input=None): if[self.stdin,self.stdout,self.stderr].count(None)>=2: stdout=None stderr=None if self.stdin: if input: self.stdin.write(input) self.stdin.close() elif self.stdout: stdout=self.stdout.read() elif self.stderr: stderr=self.stderr.read() self.wait() return(stdout,stderr) return self._communicate(input) if mswindows: def _get_handles(self,stdin,stdout,stderr): if stdin is None and stdout is None and stderr is None: return(None,None,None,None,None,None) p2cread,p2cwrite=None,None c2pread,c2pwrite=None,None errread,errwrite=None,None if stdin is None: p2cread=GetStdHandle(STD_INPUT_HANDLE) if p2cread is not None: pass elif stdin is None or stdin==PIPE: p2cread,p2cwrite=CreatePipe(None,0) p2cwrite=p2cwrite.Detach() p2cwrite=msvcrt.open_osfhandle(p2cwrite,0) elif isinstance(stdin,int): p2cread=msvcrt.get_osfhandle(stdin) else: p2cread=msvcrt.get_osfhandle(stdin.fileno()) p2cread=self._make_inheritable(p2cread) if stdout is None: c2pwrite=GetStdHandle(STD_OUTPUT_HANDLE) if c2pwrite is not None: pass elif stdout is None or stdout==PIPE: c2pread,c2pwrite=CreatePipe(None,0) c2pread=c2pread.Detach() c2pread=msvcrt.open_osfhandle(c2pread,0) elif isinstance(stdout,int): c2pwrite=msvcrt.get_osfhandle(stdout) else: c2pwrite=msvcrt.get_osfhandle(stdout.fileno()) c2pwrite=self._make_inheritable(c2pwrite) if stderr is None: errwrite=GetStdHandle(STD_ERROR_HANDLE) if errwrite is not None: pass elif stderr is None or stderr==PIPE: errread,errwrite=CreatePipe(None,0) errread=errread.Detach() errread=msvcrt.open_osfhandle(errread,0) elif stderr==STDOUT: errwrite=c2pwrite elif isinstance(stderr,int): errwrite=msvcrt.get_osfhandle(stderr) else: errwrite=msvcrt.get_osfhandle(stderr.fileno()) errwrite=self._make_inheritable(errwrite) return(p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite) def _make_inheritable(self,handle): return DuplicateHandle(GetCurrentProcess(),handle,GetCurrentProcess(),0,1,DUPLICATE_SAME_ACCESS) def _find_w9xpopen(self): w9xpopen=os.path.join(os.path.dirname(GetModuleFileName(0)),"w9xpopen.exe") if not os.path.exists(w9xpopen): w9xpopen=os.path.join(os.path.dirname(sys.exec_prefix),"w9xpopen.exe") if not os.path.exists(w9xpopen): raise RuntimeError("Cannot locate w9xpopen.exe, which is needed for Popen to work with your shell or platform.") return w9xpopen def _execute_child(self,args,executable,preexec_fn,close_fds,cwd,env,universal_newlines,startupinfo,creationflags,shell,p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite): if not isinstance(args,types.StringTypes): args=list2cmdline(args) if startupinfo is None: startupinfo=STARTUPINFO() if None not in(p2cread,c2pwrite,errwrite): startupinfo.dwFlags|=STARTF_USESTDHANDLES startupinfo.hStdInput=p2cread startupinfo.hStdOutput=c2pwrite startupinfo.hStdError=errwrite if shell: startupinfo.dwFlags|=STARTF_USESHOWWINDOW startupinfo.wShowWindow=SW_HIDE comspec=os.environ.get("COMSPEC","cmd.exe") args=comspec+" /c "+args if(GetVersion()>=0x80000000L or os.path.basename(comspec).lower()=="command.com"): w9xpopen=self._find_w9xpopen() args='"%s" %s'%(w9xpopen,args) creationflags|=CREATE_NEW_CONSOLE try: hp,ht,pid,tid=CreateProcess(executable,args,None,None,1,creationflags,env,cwd,startupinfo) except pywintypes.error,e: raise WindowsError(*e.args) self._child_created=True self._handle=hp self.pid=pid ht.Close() if p2cread is not None: p2cread.Close() if c2pwrite is not None: c2pwrite.Close() if errwrite is not None: errwrite.Close() def poll(self,_deadstate=None): if self.returncode is None: if WaitForSingleObject(self._handle,0)==WAIT_OBJECT_0: self.returncode=GetExitCodeProcess(self._handle) return self.returncode def wait(self): if self.returncode is None: obj=WaitForSingleObject(self._handle,INFINITE) self.returncode=GetExitCodeProcess(self._handle) return self.returncode def _readerthread(self,fh,buffer): buffer.append(fh.read()) def _communicate(self,input): stdout=None stderr=None if self.stdout: stdout=[] stdout_thread=threading.Thread(target=self._readerthread,args=(self.stdout,stdout)) stdout_thread.setDaemon(True) stdout_thread.start() if self.stderr: stderr=[] stderr_thread=threading.Thread(target=self._readerthread,args=(self.stderr,stderr)) stderr_thread.setDaemon(True) stderr_thread.start() if self.stdin: if input is not None: self.stdin.write(input) self.stdin.close() if self.stdout: stdout_thread.join() if self.stderr: stderr_thread.join() if stdout is not None: stdout=stdout[0] if stderr is not None: stderr=stderr[0] if self.universal_newlines and hasattr(file,'newlines'): if stdout: stdout=self._translate_newlines(stdout) if stderr: stderr=self._translate_newlines(stderr) self.wait() return(stdout,stderr) else: def _get_handles(self,stdin,stdout,stderr): p2cread,p2cwrite=None,None c2pread,c2pwrite=None,None errread,errwrite=None,None if stdin is None: pass elif stdin==PIPE: p2cread,p2cwrite=os.pipe() elif isinstance(stdin,int): p2cread=stdin else: p2cread=stdin.fileno() if stdout is None: pass elif stdout==PIPE: c2pread,c2pwrite=os.pipe() elif isinstance(stdout,int): c2pwrite=stdout else: c2pwrite=stdout.fileno() if stderr is None: pass elif stderr==PIPE: errread,errwrite=os.pipe() elif stderr==STDOUT: errwrite=c2pwrite elif isinstance(stderr,int): errwrite=stderr else: errwrite=stderr.fileno() return(p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite) def _set_cloexec_flag(self,fd): try: cloexec_flag=fcntl.FD_CLOEXEC except AttributeError: cloexec_flag=1 old=fcntl.fcntl(fd,fcntl.F_GETFD) fcntl.fcntl(fd,fcntl.F_SETFD,old|cloexec_flag) def _close_fds(self,but): for i in xrange(3,MAXFD): if i==but: continue try: os.close(i) except: pass def _execute_child(self,args,executable,preexec_fn,close_fds,cwd,env,universal_newlines,startupinfo,creationflags,shell,p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite): if isinstance(args,types.StringTypes): args=[args] else: args=list(args) if shell: args=["/bin/sh","-c"]+args if executable is None: executable=args[0] errpipe_read,errpipe_write=os.pipe() self._set_cloexec_flag(errpipe_write) gc_was_enabled=gc.isenabled() gc.disable() try: self.pid=os.fork() except: if gc_was_enabled: gc.enable() raise self._child_created=True if self.pid==0: try: if p2cwrite: os.close(p2cwrite) if c2pread: os.close(c2pread) if errread: os.close(errread) os.close(errpipe_read) if p2cread: os.dup2(p2cread,0) if c2pwrite: os.dup2(c2pwrite,1) if errwrite: os.dup2(errwrite,2) if p2cread and p2cread not in(0,): os.close(p2cread) if c2pwrite and c2pwrite not in(p2cread,1): os.close(c2pwrite) if errwrite and errwrite not in(p2cread,c2pwrite,2): os.close(errwrite) if close_fds: self._close_fds(but=errpipe_write) if cwd is not None: os.chdir(cwd) if preexec_fn: apply(preexec_fn) if env is None: os.execvp(executable,args) else: os.execvpe(executable,args,env) except: exc_type,exc_value,tb=sys.exc_info() exc_lines=traceback.format_exception(exc_type,exc_value,tb) exc_value.child_traceback=''.join(exc_lines) os.write(errpipe_write,pickle.dumps(exc_value)) os._exit(255) if gc_was_enabled: gc.enable() os.close(errpipe_write) if p2cread and p2cwrite: os.close(p2cread) if c2pwrite and c2pread: os.close(c2pwrite) if errwrite and errread: os.close(errwrite) data=os.read(errpipe_read,1048576) os.close(errpipe_read) if data!="": os.waitpid(self.pid,0) child_exception=pickle.loads(data) raise child_exception def _handle_exitstatus(self,sts): if os.WIFSIGNALED(sts): self.returncode=-os.WTERMSIG(sts) elif os.WIFEXITED(sts): self.returncode=os.WEXITSTATUS(sts) else: raise RuntimeError("Unknown child exit status!") def poll(self,_deadstate=None): if self.returncode is None: try: pid,sts=os.waitpid(self.pid,os.WNOHANG) if pid==self.pid: self._handle_exitstatus(sts) except os.error: if _deadstate is not None: self.returncode=_deadstate return self.returncode def wait(self): if self.returncode is None: pid,sts=os.waitpid(self.pid,0) self._handle_exitstatus(sts) return self.returncode def _communicate(self,input): read_set=[] write_set=[] stdout=None stderr=None if self.stdin: self.stdin.flush() if input: write_set.append(self.stdin) else: self.stdin.close() if self.stdout: read_set.append(self.stdout) stdout=[] if self.stderr: read_set.append(self.stderr) stderr=[] input_offset=0 while read_set or write_set: rlist,wlist,xlist=select.select(read_set,write_set,[]) if self.stdin in wlist: bytes_written=os.write(self.stdin.fileno(),buffer(input,input_offset,512)) input_offset+=bytes_written if input_offset>=len(input): self.stdin.close() write_set.remove(self.stdin) if self.stdout in rlist: data=os.read(self.stdout.fileno(),1024) if data=="": self.stdout.close() read_set.remove(self.stdout) stdout.append(data) if self.stderr in rlist: data=os.read(self.stderr.fileno(),1024) if data=="": self.stderr.close() read_set.remove(self.stderr) stderr.append(data) if stdout is not None: stdout=''.join(stdout) if stderr is not None: stderr=''.join(stderr) if self.universal_newlines and hasattr(file,'newlines'): if stdout: stdout=self._translate_newlines(stdout) if stderr: stderr=self._translate_newlines(stderr) self.wait() return(stdout,stderr) slv2-0.6.6+dfsg1/wafadmin/__init__.py0000644000175000017500000000005311176703512017171 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 slv2-0.6.6+dfsg1/wafadmin/Logs.py0000644000175000017500000000453611176703512016350 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os,re,logging,traceback,sys from Constants import* zones='' verbose=0 colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;91m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',} got_tty=not os.environ.get('TERM','dumb')in['dumb','emacs'] if got_tty: try: got_tty=sys.stderr.isatty() except AttributeError: got_tty=False import Utils if not got_tty or sys.platform=='win32'or'NOCOLOR'in os.environ: colors_lst['USE']=False def get_color(cl): if not colors_lst['USE']:return'' return colors_lst.get(cl,'') class foo(object): def __getattr__(self,a): return get_color(a) def __call__(self,a): return get_color(a) colors=foo() re_log=re.compile(r'(\w+): (.*)',re.M) class log_filter(logging.Filter): def __init__(self,name=None): pass def filter(self,rec): rec.c1=colors.PINK rec.c2=colors.NORMAL rec.zone=rec.module if rec.levelno>=logging.INFO: if rec.levelno>=logging.ERROR: rec.c1=colors.RED elif rec.levelno>=logging.WARNING: rec.c1=colors.YELLOW else: rec.c1=colors.GREEN return True zone='' m=re_log.match(rec.msg) if m: zone=rec.zone=m.group(1) rec.msg=m.group(2) if zones: return getattr(rec,'zone','')in zones or'*'in zones elif not verbose>2: return False return True class formatter(logging.Formatter): def __init__(self): logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT) def format(self,rec): if rec.levelno>=logging.WARNING or rec.levelno==logging.INFO: return'%s%s%s'%(rec.c1,rec.msg,rec.c2) return logging.Formatter.format(self,rec) def debug(msg): if verbose: msg=msg.replace('\n',' ') logging.debug(msg) def error(msg): logging.error(msg) if verbose>1: if isinstance(msg,Utils.WafError): st=msg.stack else: st=traceback.extract_stack() if st: st=st[:-1] buf=[] for filename,lineno,name,line in st: buf.append(' File "%s", line %d, in %s'%(filename,lineno,name)) if line: buf.append(' %s'%line.strip()) if buf:logging.error("\n".join(buf)) warn=logging.warn info=logging.info def init_log(): log=logging.getLogger() log.handlers=[] hdlr=logging.StreamHandler() hdlr.setFormatter(formatter()) log.addHandler(hdlr) log.addFilter(log_filter()) log.setLevel(logging.DEBUG) slv2-0.6.6+dfsg1/wafadmin/TaskGen.py0000644000175000017500000002403311176703512016772 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os,traceback,copy import Build,Task,Utils,Logs,Options from Logs import debug,error,warn from Constants import* typos={'sources':'source','targets':'target','include':'includes','define':'defines','importpath':'importpaths','install_var':'install_path','install_subdir':'install_path','inst_var':'install_path','inst_dir':'install_path',} class register_obj(type): def __init__(cls,name,bases,dict): super(register_obj,cls).__init__(name,bases,dict) name=cls.__name__ suffix='_taskgen' if name.endswith(suffix): task_gen.classes[name.replace(suffix,'')]=cls class task_gen(object): __metaclass__=register_obj mappings={} mapped={} prec=Utils.DefaultDict(list) traits=Utils.DefaultDict(set) classes={} def __init__(self,*kw,**kwargs): self.prec=Utils.DefaultDict(list) self.source='' self.target='' self.meths=[] self.mappings={} self.features=list(kw) self.tasks=[] self.default_chmod=O644 self.default_install_path=None self.allnodes=[] self.bld=kwargs.get('bld',Build.bld) self.env=self.bld.env.copy() self.path=self.bld.path self.name='' self.idx=self.bld.idx[self.path.id]=self.bld.idx.get(self.path.id,0)+1 for key,val in kwargs.iteritems(): setattr(self,key,val) self.bld.task_manager.add_task_gen(self) self.bld.all_task_gen.append(self) def __str__(self): return(""%(self.name or self.target,self.__class__.__name__,str(self.path))) def __setattr__(self,name,attr): real=typos.get(name,name) if real!=name: warn('typo %s -> %s'%(name,real)) if Logs.verbose>0: traceback.print_stack() object.__setattr__(self,real,attr) def to_list(self,value): if isinstance(value,str):return value.split() else:return value def apply(self): keys=set(self.meths) self.features=Utils.to_list(self.features) for x in self.features+['*']: st=task_gen.traits[x] if not st: warn('feature %r does not exist - bind at least one method to it'%x) keys.update(st) prec={} prec_tbl=self.prec or task_gen.prec for x in prec_tbl: if x in keys: prec[x]=prec_tbl[x] tmp=[] for a in keys: for x in prec.values(): if a in x:break else: tmp.append(a) out=[] while tmp: e=tmp.pop() if e in keys:out.append(e) try: nlst=prec[e] except KeyError: pass else: del prec[e] for x in nlst: for y in prec: if x in prec[y]: break else: tmp.append(x) if prec:raise Utils.WafError("graph has a cycle %s"%str(prec)) out.reverse() self.meths=out debug('task_gen: posting %s %d'%(self,id(self))) for x in out: try: v=getattr(self,x) except AttributeError: raise Utils.WafError("tried to retrieve %s which is not a valid method"%x) debug('task_gen: -> %s (%d)'%(x,id(self))) v() def post(self): if not self.name: if isinstance(self.target,list): self.name=' '.join(self.target) else: self.name=self.target if getattr(self,'posted',None): return self.apply() debug('task_gen: posted %s'%self.name) self.posted=True def get_hook(self,ext): try:return self.mappings[ext] except KeyError: try:return task_gen.mappings[ext] except KeyError:return None def create_task(self,name,env=None): task=Task.TaskBase.classes[name](env or self.env,generator=self) self.tasks.append(task) return task def name_to_obj(self,name): return self.bld.name_to_obj(name,self.env) def find_sources_in_dirs(self,dirnames,excludes=[],exts=[]): err_msg="'%s' attribute must be a list" if not isinstance(excludes,list): raise Utils.WscriptError(err_msg%'excludes') if not isinstance(exts,list): raise Utils.WscriptError(err_msg%'exts') lst=[] dirnames=self.to_list(dirnames) ext_lst=exts or self.mappings.keys()+task_gen.mappings.keys() for name in dirnames: anode=self.path.find_dir(name) if not anode or not anode.is_child_of(self.bld.srcnode): raise Utils.WscriptError("Unable to use '%s' - either because it's not a relative path"", or it's not child of '%s'."%(name,self.bld.srcnode)) self.bld.rescan(anode) for name in self.bld.cache_dir_contents[anode.id]: if name.startswith('.'): continue (base,ext)=os.path.splitext(name) if ext in ext_lst and not name in lst and not name in excludes: lst.append((anode.relpath_gen(self.path)or'.')+os.path.sep+name) lst.sort() self.source=self.to_list(self.source) if not self.source:self.source=lst else:self.source+=lst def clone(self,env): newobj=task_gen(bld=self.bld) for x in self.__dict__: if x in['env','bld']: continue elif x in["path","features"]: setattr(newobj,x,getattr(self,x)) else: setattr(newobj,x,copy.copy(getattr(self,x))) newobj.__class__=self.__class__ if isinstance(env,str): newobj.env=self.bld.all_envs[env].copy() else: newobj.env=env.copy() return newobj def get_inst_path(self): return getattr(self,'_install_path',getattr(self,'default_install_path','')) def set_inst_path(self,val): self._install_path=val install_path=property(get_inst_path,set_inst_path) def get_chmod(self): return getattr(self,'_chmod',getattr(self,'default_chmod',O644)) def set_chmod(self,val): self._chmod=val chmod=property(get_chmod,set_chmod) def declare_extension(var,func): try: for x in Utils.to_list(var): task_gen.mappings[x]=func except: raise Utils.WscriptError('declare_extension takes either a list or a string %r'%var) task_gen.mapped[func.__name__]=func def declare_order(*k): assert(len(k)>1) n=len(k)-1 for i in xrange(n): f1=k[i] f2=k[i+1] if not f1 in task_gen.prec[f2]: task_gen.prec[f2].append(f1) def declare_chain(name='',action='',ext_in='',ext_out='',reentrant=1,color='BLUE',install=0,before=[],after=[],decider=None,rule=None,scan=None): action=action or rule if isinstance(action,str): act=Task.simple_task_type(name,action,color=color) else: act=Task.task_type_from_func(name,action,color=color) act.ext_in=tuple(Utils.to_list(ext_in)) act.ext_out=tuple(Utils.to_list(ext_out)) act.before=Utils.to_list(before) act.after=Utils.to_list(after) act.scan=scan def x_file(self,node): if decider: ext=decider(self,node) elif isinstance(ext_out,str): ext=ext_out if isinstance(ext,str): out_source=node.change_ext(ext) if reentrant: self.allnodes.append(out_source) elif isinstance(ext,list): out_source=[node.change_ext(x)for x in ext] if reentrant: for i in xrange(reentrant): self.allnodes.append(out_source[i]) else: raise Utils.WafError("do not know how to process %s"%str(ext)) tsk=self.create_task(name) tsk.set_inputs(node) tsk.set_outputs(out_source) if node.__class__.bld.is_install==INSTALL: tsk.install=install declare_extension(act.ext_in,x_file) def bind_feature(name,methods): lst=Utils.to_list(methods) task_gen.traits[name].update(lst) def taskgen(func): setattr(task_gen,func.__name__,func) def feature(*k): def deco(func): setattr(task_gen,func.__name__,func) for name in k: task_gen.traits[name].update([func.__name__]) return func return deco def before(*k): def deco(func): setattr(task_gen,func.__name__,func) for fun_name in k: if not func.__name__ in task_gen.prec[fun_name]: task_gen.prec[fun_name].append(func.__name__) return func return deco def after(*k): def deco(func): setattr(task_gen,func.__name__,func) for fun_name in k: if not fun_name in task_gen.prec[func.__name__]: task_gen.prec[func.__name__].append(fun_name) return func return deco def extension(var): def deco(func): setattr(task_gen,func.__name__,func) try: for x in Utils.to_list(var): task_gen.mappings[x]=func except: raise Utils.WafError('extension takes either a list or a string %r'%var) task_gen.mapped[func.__name__]=func return func return deco def apply_core(self): find_resource=self.path.find_resource for filename in self.to_list(self.source): x=self.get_hook(filename) if x: x(self,filename) else: node=find_resource(filename) if not node:raise Utils.WafError("source not found: '%s' in '%s'"%(filename,str(self.path))) self.allnodes.append(node) for node in self.allnodes: x=self.get_hook(node.suffix()) if not x: raise Utils.WafError("Do not know how to process %s in %s, mappings are %s"%(str(node),str(self.__class__),str(self.__class__.mappings))) x(self,node) feature('*')(apply_core) def exec_rule(self): if not getattr(self,'rule',None): return try: self.meths.remove('apply_core') except ValueError: pass func=self.rule vars2=[] if isinstance(func,str): (func,vars2)=Task.compile_fun('',self.rule,shell=getattr(self,'shell',True)) func.code=self.rule vars=getattr(self,'vars',vars2) if not vars: if isinstance(self.rule,str): vars=self.rule else: vars=Utils.h_fun(self.rule) name=getattr(self,'name',None)or self.target or self.rule cls=Task.task_type_from_func(name,func,vars) tsk=self.create_task(name) if getattr(self,'target',None): cls.quiet=True tsk.outputs=[self.path.find_or_declare(x)for x in self.to_list(self.target)] if getattr(self,'source',None): cls.quiet=True tsk.inputs=[] for x in self.to_list(self.source): y=self.path.find_resource(x) if not y: raise Utils.WafError('input file %r could not be found (%r)'%(x,self.path.abspath())) tsk.inputs.append(y) if getattr(self,'always',None): Task.always_run(cls) if getattr(self,'scan',None): cls.scan=self.scan if getattr(self,'install_path',None): tsk.install_path=self.install_path if getattr(self,'cwd',None): tsk.cwd=self.cwd if getattr(self,'on_results',None): Task.update_outputs(cls) for x in['after','before']: setattr(cls,x,getattr(self,x,[])) feature('*')(exec_rule) before('apply_core')(exec_rule) def sequence_order(self): if self.meths and self.meths[-1]!='sequence_order': self.meths.append('sequence_order') return if getattr(self,'seq_start',None): return if getattr(self.bld,'prev',None): self.bld.prev.post() for x in self.bld.prev.tasks: for y in self.tasks: y.set_run_after(x) self.bld.prev=self feature('seq')(sequence_order) slv2-0.6.6+dfsg1/wafadmin/py3kfixes.py0000644000175000017500000000322711176703512017365 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import os all_modifs={} def modif(filename,fun): f=open(filename,'r') txt=f.read() f.close() txt=fun(txt) f=open(filename,'w') f.write(txt) f.close() def subst(filename): def do_subst(fun): global all_modifs try: all_modifs[filename]+=fun except KeyError: all_modifs[filename]=[fun] return fun return do_subst def r1(code): code=code.replace("'iluvcuteoverload'","b'iluvcuteoverload'") code=code.replace("ABI=7","ABI=37") return code def r2(code): code=code.replace("p.stdin.write('\\n')","p.stdin.write(b'\\n')") code=code.replace("out=str(out)","out=out.decode('utf-8')") return code def r3(code): code=code.replace("m.update(str(lst))","m.update(str(lst).encode())") return code def r4(code): code=code.replace("up(self.__class__.__name__)","up(self.__class__.__name__.encode())") code=code.replace("up(self.env.variant())","up(self.env.variant().encode())") code=code.replace("up(x.parent.abspath())","up(x.parent.abspath().encode())") code=code.replace("up(x.name)","up(x.name.encode())") return code def r5(code): code=code.replace("cPickle.dump(data,file,-1)","cPickle.dump(data,file)") return code def fixdir(dir): import subprocess try: proc=subprocess.Popen("2to3 -x imports -x imports2 -x import -w -n wafadmin".split(),stdout=subprocess.PIPE,stderr=subprocess.PIPE) stdout,setderr=proc.communicate() except: import sys,shutil shutil.rmtree(dir) raise global all_modifs for k in all_modifs: for v in all_modifs[k]: modif(os.path.join(dir,'wafadmin',k),v) subst('Constants.py')(r1) subst('Tools/ccroot.py')(r2) subst('Utils.py')(r3) subst('Task.py')(r4) subst('Build.py')(r5) slv2-0.6.6+dfsg1/wafadmin/Environment.py0000644000175000017500000000714611176703512017750 0ustar alessioalessio#! /usr/bin/env python # encoding: utf-8 import sys if sys.hexversion < 0x020400f0: from sets import Set as set import os,copy,re import Logs,Options,Utils from Constants import* re_imp=re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$',re.M) class Environment(object): __slots__=("table","parent") def __init__(self,filename=None): self.table={} if filename: self.load(filename) def __contains__(self,key): if key in self.table:return True try:return self.parent.__contains__(key) except AttributeError:return False def __str__(self): keys=set() cur=self while cur: keys.update(cur.table.keys()) cur=getattr(cur,'parent',None) keys=list(keys) keys.sort() return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in keys]) def __getitem__(self,key): try: while 1: x=self.table.get(key,None) if not x is None: return x self=self.parent except AttributeError: return[] def __setitem__(self,key,value): self.table[key]=value def __delitem__(self,key,value): del self.table[key] def set_variant(self,name): self.table[VARIANT]=name def variant(self): try: while 1: x=self.table.get(VARIANT,None) if not x is None: return x self=self.parent except AttributeError: return DEFAULT def copy(self): newenv=Environment() newenv.parent=self return newenv def get_flat(self,key): s=self[key] if isinstance(s,str):return s return' '.join(s) def _get_list_value_for_modification(self,key): try: value=self.table[key] except KeyError: try:value=self.parent[key] except AttributeError:value=[] if isinstance(value,list): value=copy.copy(value) else: value=[value] else: if not isinstance(value,list): value=[value] self.table[key]=value return value def append_value(self,var,value): current_value=self._get_list_value_for_modification(var) if isinstance(value,list): current_value.extend(value) else: current_value.append(value) def prepend_value(self,var,value): current_value=self._get_list_value_for_modification(var) if isinstance(value,list): current_value=value+current_value self.table[var]=current_value else: current_value.insert(0,value) def append_unique(self,var,value): current_value=self._get_list_value_for_modification(var) if isinstance(value,list): for value_item in value: if value_item not in current_value: current_value.append(value_item) else: if value not in current_value: current_value.append(value) def get_merged_dict(self): table_list=[] env=self while 1: table_list.insert(0,env.table) try:env=env.parent except AttributeError:break merged_table={} for table in table_list: merged_table.update(table) return merged_table def store(self,filename): file=open(filename,'w') merged_table=self.get_merged_dict() keys=merged_table.keys() keys.sort() for k in keys:file.write('%s = %r\n'%(k,merged_table[k])) file.close() def load(self,filename): tbl=self.table code=Utils.readf(filename) for m in re_imp.finditer(code): g=m.group tbl[g(2)]=eval(g(3)) Logs.debug('env: %s'%str(self.table)) def get_destdir(self): if self.__getitem__('NOINSTALL'):return'' return Options.options.destdir def update(self,d): for k,v in d.iteritems(): self[k]=v def __getattr__(self,name): if name in self.__slots__: return object.__getattr__(self,name) else: return self[name] def __setattr__(self,name,value): if name in self.__slots__: object.__setattr__(self,name,value) else: self[name]=value def __detattr__(self,name): if name in self.__slots__: object.__detattr__(self,name) else: del self[name] slv2-0.6.6+dfsg1/README0000644000175000017500000000051311231361306014144 0ustar alessioalessioSLV2 ---- SLV2 is a library for LV2 hosts intended to make using LV2 Plugins as simple as possible (without sacrificing capabilities). More information about LV2 plugins can be found at . More information about SLV2 can be found at . -- Dave Robillard slv2-0.6.6+dfsg1/ChangeLog0000644000175000017500000000707611231361306015051 0ustar alessioalessioslv2 (0.6.6) unstable; urgency=low * Add manual pages for utilities * Reduce plugin load overhead (on-demand querying with finer granularity) * Fix compilation on Mac OS X -- Dave Robillard Mon, 25 May 2009 23:30:49 -0400 slv2 (0.6.4) unstable; urgency=low * Add generic query interface to allow arbitrary querying of data * Combine similar headers (reduce code duplication) * Upgrade to waf 1.5.6 * Add man pages for utilities -- Dave Robillard Mon, 04 May 2009 18:11:06 -0400 slv2 (0.6.3) unstable; urgency=low * Fix illegal output of slv2_value_get_turtle_token for floats. * Fix slv2_plugin_get_value_for_subject * Add test suite and coverage instrumentation * Upgrade to waf 1.5.1 -- Dave Robillard Sat, 13 Dec 2008 14:13:43 -0500 slv2 (0.6.2) unstable; urgency=high * Fix bug introduced with I18N in 0.6.1 which broke feature detection. * Add waf configure --no-jack option to avoid building Jack clients. -- Dave Robillard Sun, 30 Nov 2008 19:40:27 -0500 slv2 (0.6.1) unstable; urgency=low * I18N support. * Add slv2_port_get_value (analogous to slv2_plugin_get_value). * Add slv2_instance_get_extension_data. * Fix slv2_plugin_get_supported_features (previously non-functional). -- Dave Robillard Sat, 08 Nov 2008 14:27:10 -0500 slv2 (0.6.0) unstable; urgency=low * Rework API to reduce dependence of SLV2 on specific LV2 features * Use SLV2Value most everywhere in the API for type safety and performance reasons * Typical use case performance improvements * Add support for scale points * Use new Redland "trees" store for dramatic performance improvements * *** API BREAK *** -- Dave Robillard Sun, 06 Jul 2008 13:11:15 -0400 slv2 (0.5.0) unstable; urgency=low * Update LV2 UI header (API break) * *** API BREAK *** -- Dave Robillard Thu, 17 Jan 2008 18:34:29 -0500 slv2 (0.4.5) unstable; urgency=low * Fix redland librdf_free_query_results warning * Use "memory" store instead of "hashes" store for plugin RDF data, resulting in extreme speedups in some cases. -- Dave Robillard Tue, 15 Jan 2008 19:22:21 -0500 slv2 (0.4.4) unstable; urgency=low * Add slv2_port_has_property * Add slv2_plugin_has_feature * Add plugin template and port signature interface for much faster plugin discovery with port input/output/type inspection. -- Dave Robillard Tue, 15 Jan 2008 10:43:00 -0500 slv2 (0.4.3) unstable; urgency=low * Fix lv2_inspect command line handling bug (always prints help) * Fix case where multiple plugins are described in the same file (avoid port symbol clashing). -- Dave Robillard Thu, 10 Jan 2008 20:03:19 -0500 slv2 (0.4.2) unstable; urgency=low * Update for LV2 specification release 1 -- Dave Robillard Tue, 08 Jan 2008 20:16:56 -0500 slv2 (0.4.1) unstable; urgency=low * Debian packaging (no functional changes) -- Dave Robillard Sun, 6 Jan 2008 18:39:57 -0500 slv2 (0.4.0) unstable; urgency=low * Update for most recent LV2 GUI specification * Fix plugin detection bugs -- Dave Robillard Sun, 6 Jan 2008 17:11:18 -0500 slv2 (0.3.2) unstable; urgency=low * Build man pages -- Dave Robillard Wed, 30 Nov 2007 18:19:00 -0500 slv2 (0.3.1) unstable; urgency=low * Initial Debian Release. -- Dave Robillard Wed, 14 Nov 2007 22:29:49 -0500 slv2-0.6.6+dfsg1/test/0000755000175000017500000000000011231361306014244 5ustar alessioalessioslv2-0.6.6+dfsg1/test/wscript0000644000175000017500000000067511231361306015672 0ustar alessioalessio#!/usr/bin/env python def build(bld): tests = ''' slv2_test ''' if bld.env['BUILD_TESTS']: for i in tests.split(): obj = bld.new_task_gen('cc', 'program') obj.source = i + '.c' obj.includes = '..' obj.uselib_local = 'libslv2_static' obj.uselib = 'REDLAND LV2CORE' obj.libs = 'gcov' obj.target = i obj.install_path = '' obj.ccflags = [ '-fprofile-arcs', '-ftest-coverage' ] slv2-0.6.6+dfsg1/test/slv2_test.c0000644000175000017500000010055311231361306016341 0ustar alessioalessio/* SLV2 Tests * Copyright (C) 2008-2009 Dave Robillard * Copyright (C) 2008 Krzysztof Foltman * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include #include #include #include #include "slv2/slv2.h" #define TEST_PATH_MAX 1024 static char bundle_dir_name[TEST_PATH_MAX]; static char bundle_dir_uri[TEST_PATH_MAX]; static char manifest_name[TEST_PATH_MAX]; static char content_name[TEST_PATH_MAX]; static SLV2World world; int test_count = 0; int error_count = 0; void delete_bundle() { unlink(content_name); unlink(manifest_name); rmdir(bundle_dir_name); } void init_tests() { strncpy(bundle_dir_name, getenv("HOME"), 900); strcat(bundle_dir_name, "/.lv2/slv2-test.lv2"); sprintf(bundle_dir_uri, "file://%s/", bundle_dir_name); sprintf(manifest_name, "%s/manifest.ttl", bundle_dir_name); sprintf(content_name, "%s/plugin.ttl", bundle_dir_name); delete_bundle(); } void fatal_error(const char *err, const char *arg) { /* TODO: possibly change to vfprintf later */ fprintf(stderr, err, arg); /* IMHO, the bundle should be left in place after an error, for possible investigation */ /* delete_bundle(); */ exit(1); } void write_file(const char *name, const char *content) { FILE* f = fopen(name, "w"); size_t len = strlen(content); if (fwrite(content, 1, len, f) != len) fatal_error("Cannot write file %s\n", name); fclose(f); } int init_world() { world = slv2_world_new(); return world != NULL; } int load_all_bundles() { if (!init_world()) return 0; slv2_world_load_all(world); return 1; } void create_bundle(char *manifest, char *content) { if (mkdir(bundle_dir_name, 0700)) fatal_error("Cannot create directory %s\n", bundle_dir_name); write_file(manifest_name, manifest); write_file(content_name, content); } int start_bundle(char *manifest, char *content) { create_bundle(manifest, content); return load_all_bundles(); } void unload_bundle() { if (world) slv2_world_free(world); world = NULL; } void cleanup() { delete_bundle(); } /*****************************************************************************/ #define TEST_CASE(name) { #name, test_##name } #define TEST_ASSERT(check) do {\ test_count++;\ if (!(check)) {\ error_count++;\ fprintf(stderr, "Failure at slv2_test.c:%d: %s\n", __LINE__, #check);\ }\ } while (0) typedef int (*TestFunc)(); struct TestCase { const char *title; TestFunc func; }; #define PREFIX_LINE "@prefix : .\n" #define PREFIX_LV2 "@prefix lv2: .\n" #define PREFIX_LV2EV "@prefix lv2ev: . \n" #define PREFIX_LV2UI "@prefix lv2ui: .\n" #define PREFIX_RDFS "@prefix rdfs: .\n" #define PREFIX_FOAF "@prefix foaf: .\n" #define PREFIX_DOAP "@prefix doap: .\n" #define MANIFEST_PREFIXES PREFIX_LINE PREFIX_LV2 PREFIX_RDFS #define BUNDLE_PREFIXES PREFIX_LINE PREFIX_LV2 PREFIX_RDFS PREFIX_FOAF PREFIX_DOAP #define PLUGIN_NAME(name) "doap:name \"" name "\"" #define LICENSE_GPL "doap:license " static char *uris_plugin = "http://example.org/plug"; static SLV2Value plugin_uri_value, plugin2_uri_value; /*****************************************************************************/ void init_uris() { plugin_uri_value = slv2_value_new_uri(world, uris_plugin); plugin2_uri_value = slv2_value_new_uri(world, "http://example.org/foobar"); TEST_ASSERT(plugin_uri_value); TEST_ASSERT(plugin2_uri_value); } void cleanup_uris() { slv2_value_free(plugin2_uri_value); slv2_value_free(plugin_uri_value); plugin2_uri_value = NULL; plugin_uri_value = NULL; } /*****************************************************************************/ int test_utils() { TEST_ASSERT(!strcmp(slv2_uri_to_path("file:///tmp/blah"), "/tmp/blah")); TEST_ASSERT(!slv2_uri_to_path("file:/example.org/blah")); TEST_ASSERT(!slv2_uri_to_path("http://example.org/blah")); return 1; } /*****************************************************************************/ int test_value() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; " PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "lv2:port [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"Foo\" ; " "] .")) return 0; init_uris(); SLV2Value uval = slv2_value_new_uri(world, "http://example.org"); SLV2Value sval = slv2_value_new_string(world, "Foo"); SLV2Value ival = slv2_value_new_int(world, 42); SLV2Value fval = slv2_value_new_float(world, 1.6180); TEST_ASSERT(slv2_value_is_uri(uval)); TEST_ASSERT(slv2_value_is_string(sval)); TEST_ASSERT(slv2_value_is_int(ival)); TEST_ASSERT(slv2_value_is_float(fval)); TEST_ASSERT(!slv2_value_is_literal(uval)); TEST_ASSERT(slv2_value_is_literal(sval)); TEST_ASSERT(slv2_value_is_literal(ival)); TEST_ASSERT(slv2_value_is_literal(fval)); TEST_ASSERT(!strcmp(slv2_value_as_uri(uval), "http://example.org")); TEST_ASSERT(!strcmp(slv2_value_as_string(sval), "Foo")); TEST_ASSERT(slv2_value_as_int(ival) == 42); TEST_ASSERT(fabs(slv2_value_as_float(fval) - 1.6180) < FLT_EPSILON); char* tok = slv2_value_get_turtle_token(uval); TEST_ASSERT(!strcmp(tok, "")); free(tok); tok = slv2_value_get_turtle_token(sval); TEST_ASSERT(!strcmp(tok, "Foo")); free(tok); tok = slv2_value_get_turtle_token(ival); TEST_ASSERT(!strcmp(tok, "42")); free(tok); tok = slv2_value_get_turtle_token(fval); TEST_ASSERT(!strncmp(tok, "1.6180", 6)); free(tok); SLV2Value uval_e = slv2_value_new_uri(world, "http://example.org"); SLV2Value sval_e = slv2_value_new_string(world, "Foo"); SLV2Value ival_e = slv2_value_new_int(world, 42); SLV2Value fval_e = slv2_value_new_float(world, 1.6180); SLV2Value uval_ne = slv2_value_new_uri(world, "http://no-example.org"); SLV2Value sval_ne = slv2_value_new_string(world, "Bar"); SLV2Value ival_ne = slv2_value_new_int(world, 24); SLV2Value fval_ne = slv2_value_new_float(world, 3.14159); TEST_ASSERT(slv2_value_equals(uval, uval_e)); TEST_ASSERT(slv2_value_equals(sval, sval_e)); TEST_ASSERT(slv2_value_equals(ival, ival_e)); TEST_ASSERT(slv2_value_equals(fval, fval_e)); TEST_ASSERT(!slv2_value_equals(uval, uval_ne)); TEST_ASSERT(!slv2_value_equals(sval, sval_ne)); TEST_ASSERT(!slv2_value_equals(ival, ival_ne)); TEST_ASSERT(!slv2_value_equals(fval, fval_ne)); TEST_ASSERT(!slv2_value_equals(uval, sval)); TEST_ASSERT(!slv2_value_equals(sval, ival)); TEST_ASSERT(!slv2_value_equals(ival, fval)); SLV2Value uval_dup = slv2_value_duplicate(uval); TEST_ASSERT(slv2_value_equals(uval, uval_dup)); SLV2Value ifval = slv2_value_new_float(world, 42.0); TEST_ASSERT(!slv2_value_equals(ival, ifval)); slv2_value_free(ifval); SLV2Value nil = NULL; TEST_ASSERT(!slv2_value_equals(uval, nil)); TEST_ASSERT(!slv2_value_equals(nil, uval)); TEST_ASSERT(slv2_value_equals(nil, nil)); SLV2Value nil2 = slv2_value_duplicate(nil); TEST_ASSERT(slv2_value_equals(nil, nil2)); slv2_value_free(uval); slv2_value_free(sval); slv2_value_free(ival); slv2_value_free(fval); slv2_value_free(uval_e); slv2_value_free(sval_e); slv2_value_free(ival_e); slv2_value_free(fval_e); slv2_value_free(uval_ne); slv2_value_free(sval_ne); slv2_value_free(ival_ne); slv2_value_free(fval_ne); slv2_value_free(uval_dup); slv2_value_free(nil2); cleanup_uris(); return 1; } /*****************************************************************************/ int test_values() { init_world(); SLV2Value v0 = slv2_value_new_uri(world, "http://example.org/"); SLV2Values vs1 = slv2_values_new(); TEST_ASSERT(vs1); TEST_ASSERT(!slv2_values_size(vs1)); TEST_ASSERT(!slv2_values_contains(vs1, v0)); slv2_values_free(vs1); slv2_value_free(v0); return 1; } /*****************************************************************************/ static int discovery_plugin_found = 0; static bool discovery_plugin_filter_all(SLV2Plugin plugin) { return true; } static bool discovery_plugin_filter_none(SLV2Plugin plugin) { return false; } static bool discovery_plugin_filter_ours(SLV2Plugin plugin) { return slv2_value_equals(slv2_plugin_get_uri(plugin), plugin_uri_value); } static bool discovery_plugin_filter_fake(SLV2Plugin plugin) { return slv2_value_equals(slv2_plugin_get_uri(plugin), plugin2_uri_value); } static void discovery_verify_plugin(SLV2Plugin plugin) { SLV2Value value = slv2_plugin_get_uri(plugin); if (slv2_value_equals(value, plugin_uri_value)) { SLV2Value lib_uri = NULL; TEST_ASSERT(!slv2_value_equals(value, plugin2_uri_value)); discovery_plugin_found = 1; lib_uri = slv2_plugin_get_library_uri(plugin); TEST_ASSERT(lib_uri); TEST_ASSERT(slv2_value_is_uri(lib_uri)); TEST_ASSERT(slv2_value_as_uri(lib_uri)); TEST_ASSERT(strstr(slv2_value_as_uri(lib_uri), "foo.so")); /* this is already being tested as ticket291, but the discovery and ticket291 * may diverge at some point, so I'm duplicating it here */ TEST_ASSERT(slv2_plugin_verify(plugin)); } } int test_discovery() { SLV2Plugins plugins; if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES ":plug a lv2:Plugin ;" PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "lv2:port [ a lv2:ControlPort ; a lv2:InputPort ;" " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; ] .")) return 0; init_uris(); /* lookup 1: all plugins (get_all_plugins) * lookup 2: all plugins (get_plugins_by_filter, always true) * lookup 3: no plugins (get_plugins_by_filter, always false) * lookup 4: only example plugin (get_plugins_by_filter) * lookup 5: no plugins (get_plugins_by_filter, non-existing plugin) */ for (int lookup = 1; lookup <= 5; lookup++) { //printf("Lookup variant %d\n", lookup); int expect_found = 0; switch (lookup) { case 1: plugins = slv2_world_get_all_plugins(world); TEST_ASSERT(slv2_plugins_size(plugins) > 0); expect_found = 1; break; case 2: plugins = slv2_world_get_plugins_by_filter(world, discovery_plugin_filter_all); TEST_ASSERT(slv2_plugins_size(plugins) > 0); expect_found = 1; break; case 3: plugins = slv2_world_get_plugins_by_filter(world, discovery_plugin_filter_none); TEST_ASSERT(slv2_plugins_size(plugins) == 0); break; case 4: plugins = slv2_world_get_plugins_by_filter(world, discovery_plugin_filter_ours); TEST_ASSERT(slv2_plugins_size(plugins) == 1); expect_found = 1; break; case 5: plugins = slv2_world_get_plugins_by_filter(world, discovery_plugin_filter_fake); TEST_ASSERT(slv2_plugins_size(plugins) == 0); break; } SLV2Plugin explug = slv2_plugins_get_by_uri(plugins, plugin_uri_value); TEST_ASSERT((explug != NULL) == expect_found); SLV2Plugin explug2 = slv2_plugins_get_by_uri(plugins, plugin2_uri_value); TEST_ASSERT(explug2 == NULL); if (explug && expect_found) { SLV2Value name = slv2_plugin_get_name(explug); TEST_ASSERT(!strcmp(slv2_value_as_string(name), "Test plugin")); slv2_value_free(name); } discovery_plugin_found = 0; for (size_t i = 0; i < slv2_plugins_size(plugins); i++) discovery_verify_plugin(slv2_plugins_get_at(plugins, i)); TEST_ASSERT(discovery_plugin_found == expect_found); slv2_plugins_free(world, plugins); plugins = NULL; } TEST_ASSERT(slv2_plugins_get_at(plugins, (unsigned)INT_MAX + 1) == NULL); cleanup_uris(); return 1; } /*****************************************************************************/ int test_verify() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES ":plug a lv2:Plugin ; " PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "lv2:port [ a lv2:ControlPort ; a lv2:InputPort ;" " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ] .")) return 0; init_uris(); SLV2Plugins plugins = slv2_world_get_all_plugins(world); SLV2Plugin explug = slv2_plugins_get_by_uri(plugins, plugin_uri_value); TEST_ASSERT(explug); TEST_ASSERT(slv2_plugin_verify(explug)); slv2_plugins_free(world, plugins); cleanup_uris(); return 1; } /*****************************************************************************/ int test_no_verify() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES ":plug a lv2:Plugin . ")) return 0; init_uris(); SLV2Plugins plugins = slv2_world_get_all_plugins(world); SLV2Plugin explug = slv2_plugins_get_by_uri(plugins, plugin_uri_value); TEST_ASSERT(explug); TEST_ASSERT(!slv2_plugin_verify(explug)); slv2_plugins_free(world, plugins); cleanup_uris(); return 1; } /*****************************************************************************/ int test_classes() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; " PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "lv2:port [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"Foo\" ; " "] .")) return 0; init_uris(); SLV2PluginClass plugin = slv2_world_get_plugin_class(world); SLV2PluginClasses classes = slv2_world_get_plugin_classes(world); SLV2PluginClasses children = slv2_plugin_class_get_children(plugin); TEST_ASSERT(slv2_plugin_class_get_parent_uri(plugin) == NULL); TEST_ASSERT(slv2_plugin_classes_size(classes) > slv2_plugin_classes_size(children)); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_plugin_class_get_label(plugin)), "Plugin")); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_plugin_class_get_uri(plugin)), "http://lv2plug.in/ns/lv2core#Plugin")); for (unsigned i = 0; i < slv2_plugin_classes_size(children); ++i) { TEST_ASSERT(slv2_value_equals( slv2_plugin_class_get_parent_uri(slv2_plugin_classes_get_at(children, i)), slv2_plugin_class_get_uri(plugin))); } SLV2Value some_uri = slv2_value_new_uri(world, "http://example.org/whatever"); TEST_ASSERT(slv2_plugin_classes_get_by_uri(classes, some_uri) == NULL); slv2_value_free(some_uri); TEST_ASSERT(slv2_plugin_classes_get_at(classes, (unsigned)INT_MAX + 1) == NULL); slv2_plugin_classes_free(children); cleanup_uris(); return 1; } /*****************************************************************************/ int test_plugin() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; " PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "lv2:optionalFeature lv2:hardRtCapable ; " "lv2:requiredFeature ; " ":foo 1.6180 ; " "doap:maintainer [ foaf:name \"David Robillard\" ; " " foaf:homepage ; foaf:mbox ] ; " "lv2:port [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; " " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 " "] , [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; " " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 " "] , [ " " a lv2:ControlPort ; a lv2:OutputPort ; " " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; " " lv2:portProperty lv2:reportsLatency " "] . \n" ":thing doap:name \"Something else\" .\n")) return 0; init_uris(); SLV2Plugins plugins = slv2_world_get_all_plugins(world); SLV2Plugin plug = slv2_plugins_get_by_uri(plugins, plugin_uri_value); TEST_ASSERT(plug); SLV2PluginClass class = slv2_plugin_get_class(plug); SLV2Value class_uri = slv2_plugin_class_get_uri(class); TEST_ASSERT(!strcmp(slv2_value_as_string(class_uri), "http://lv2plug.in/ns/lv2core#CompressorPlugin")); SLV2Value plug_bundle_uri = slv2_plugin_get_bundle_uri(plug); TEST_ASSERT(!strcmp(slv2_value_as_string(plug_bundle_uri), bundle_dir_uri)); SLV2Values data_uris = slv2_plugin_get_data_uris(plug); TEST_ASSERT(slv2_values_size(data_uris) == 2); char* manifest_uri = (char*)malloc(TEST_PATH_MAX); char* data_uri = (char*)malloc(TEST_PATH_MAX); snprintf(manifest_uri, TEST_PATH_MAX, "%s%s", slv2_value_as_string(plug_bundle_uri), "manifest.ttl"); snprintf(data_uri, TEST_PATH_MAX, "%s%s", slv2_value_as_string(plug_bundle_uri), "plugin.ttl"); SLV2Value manifest_uri_val = slv2_value_new_uri(world, manifest_uri); TEST_ASSERT(slv2_values_contains(data_uris, manifest_uri_val)); slv2_value_free(manifest_uri_val); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_values_get_at(data_uris, 0)), manifest_uri)); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_values_get_at(data_uris, 1)), data_uri)); free(manifest_uri); free(data_uri); float mins[1]; float maxs[1]; float defs[1]; slv2_plugin_get_port_ranges_float(plug, mins, maxs, defs); TEST_ASSERT(mins[0] == -1.0f); TEST_ASSERT(maxs[0] == 1.0f); TEST_ASSERT(defs[0] == 0.5f); SLV2Value audio_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort"); SLV2Value control_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort"); SLV2Value in_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort"); SLV2Value out_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#OutputPort"); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, control_class, NULL) == 3); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, audio_class, NULL) == 0); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, in_class, NULL) == 2); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, out_class, NULL) == 1); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, control_class, in_class, NULL) == 2); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, control_class, out_class, NULL) == 1); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, audio_class, in_class, NULL) == 0); TEST_ASSERT(slv2_plugin_get_num_ports_of_class(plug, audio_class, out_class, NULL) == 0); TEST_ASSERT(slv2_plugin_has_latency(plug)); TEST_ASSERT(slv2_plugin_get_latency_port_index(plug) == 2); SLV2Value rt_feature = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#hardRtCapable"); SLV2Value event_feature = slv2_value_new_uri(world, "http://lv2plug.in/ns/ext/event"); SLV2Value pretend_feature = slv2_value_new_uri(world, "http://example.org/solvesWorldHunger"); TEST_ASSERT(slv2_plugin_has_feature(plug, rt_feature)); TEST_ASSERT(slv2_plugin_has_feature(plug, event_feature)); TEST_ASSERT(!slv2_plugin_has_feature(plug, pretend_feature)); slv2_value_free(rt_feature); slv2_value_free(event_feature); slv2_value_free(pretend_feature); SLV2Values supported = slv2_plugin_get_supported_features(plug); SLV2Values required = slv2_plugin_get_required_features(plug); SLV2Values optional = slv2_plugin_get_optional_features(plug); TEST_ASSERT(slv2_values_size(supported) == 2); TEST_ASSERT(slv2_values_size(required) == 1); TEST_ASSERT(slv2_values_size(optional) == 1); slv2_values_free(supported); slv2_values_free(required); slv2_values_free(optional); SLV2Value foo_p = slv2_value_new_uri(world, "http://example.org/foo"); SLV2Values foos = slv2_plugin_get_value(plug, foo_p); TEST_ASSERT(slv2_values_size(foos) == 1); TEST_ASSERT(fabs(slv2_value_as_float(slv2_values_get_at(foos, 0)) - 1.6180) < FLT_EPSILON); slv2_value_free(foo_p); slv2_values_free(foos); SLV2Value author_name = slv2_plugin_get_author_name(plug); TEST_ASSERT(!strcmp(slv2_value_as_string(author_name), "David Robillard")); slv2_value_free(author_name); SLV2Value author_email = slv2_plugin_get_author_email(plug); TEST_ASSERT(!strcmp(slv2_value_as_string(author_email), "mailto:dave@drobilla.net")); slv2_value_free(author_email); SLV2Value author_homepage = slv2_plugin_get_author_homepage(plug); TEST_ASSERT(!strcmp(slv2_value_as_string(author_homepage), "http://drobilla.net")); slv2_value_free(author_homepage); SLV2Value thing_uri = slv2_value_new_uri(world, "http://example.org/thing"); SLV2Value name_p = slv2_value_new_uri(world, "http://usefulinc.com/ns/doap#name"); SLV2Values thing_names = slv2_plugin_get_value_for_subject(plug, thing_uri, name_p); TEST_ASSERT(slv2_values_size(thing_names) == 1); SLV2Value thing_name = slv2_values_get_at(thing_names, 0); TEST_ASSERT(thing_name); TEST_ASSERT(slv2_value_is_string(thing_name)); TEST_ASSERT(!strcmp(slv2_value_as_string(thing_name), "Something else")); SLV2UIs uis = slv2_plugin_get_uis(plug); TEST_ASSERT(slv2_uis_size(uis) == 0); SLV2Results results = slv2_plugin_query_sparql(plug, "SELECT ?name WHERE { <> doap:maintainer [ foaf:name ?name ] }"); TEST_ASSERT(!slv2_results_finished(results)); TEST_ASSERT(!strcmp(slv2_results_get_binding_name(results, 0), "name")); SLV2Value val = slv2_results_get_binding_value(results, 0); TEST_ASSERT(!strcmp(slv2_value_as_string(val), "David Robillard")); slv2_value_free(val); val = slv2_results_get_binding_value_by_name(results, "name"); TEST_ASSERT(!strcmp(slv2_value_as_string(val), "David Robillard")); slv2_value_free(val); slv2_results_free(results); slv2_uis_free(uis); slv2_values_free(thing_names); slv2_value_free(thing_uri); slv2_value_free(name_p); slv2_value_free(control_class); slv2_value_free(audio_class); slv2_value_free(in_class); slv2_value_free(out_class); cleanup_uris(); return 1; } /*****************************************************************************/ int test_port() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES PREFIX_LV2EV ":plug a lv2:Plugin ; " PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "doap:homepage ; " "lv2:port [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 0 ; lv2:symbol \"foo\" ; " " lv2:name \"bar\" ; lv2:name \"le bar\"@fr ; " " lv2:portProperty lv2:integer ; " " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 ; " " lv2:scalePoint [ rdfs:label \"Sin\"; rdf:value 3 ] ; " " lv2:scalePoint [ rdfs:label \"Cos\"; rdf:value 4 ] " "] , [\n" " a lv2:EventPort ; a lv2:InputPort ; " " lv2:index 1 ; lv2:symbol \"event_in\" ; " " lv2:name \"Event Input\" ; " " lv2ev:supportsEvent " "] .")) return 0; init_uris(); SLV2Plugins plugins = slv2_world_get_all_plugins(world); SLV2Plugin plug = slv2_plugins_get_by_uri(plugins, plugin_uri_value); TEST_ASSERT(plug); SLV2Value psym = slv2_value_new_string(world, "foo"); SLV2Port p = slv2_plugin_get_port_by_index(plug, 0); SLV2Port p2 = slv2_plugin_get_port_by_symbol(plug, psym); slv2_value_free(psym); TEST_ASSERT(p != NULL); TEST_ASSERT(p2 != NULL); TEST_ASSERT(p == p2); SLV2Value nopsym = slv2_value_new_string(world, "thisaintnoportfoo"); SLV2Port p3 = slv2_plugin_get_port_by_symbol(plug, nopsym); TEST_ASSERT(p3 == NULL); slv2_value_free(nopsym); SLV2Value audio_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#AudioPort"); SLV2Value control_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#ControlPort"); SLV2Value in_class = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#InputPort"); TEST_ASSERT(slv2_values_size(slv2_port_get_classes(plug, p)) == 2); TEST_ASSERT(slv2_plugin_get_num_ports(plug) == 2); TEST_ASSERT(slv2_values_get_at(slv2_port_get_classes(plug, p), (unsigned)INT_MAX+1) == NULL); TEST_ASSERT(slv2_port_is_a(plug, p, control_class)); TEST_ASSERT(slv2_port_is_a(plug, p, in_class)); TEST_ASSERT(!slv2_port_is_a(plug, p, audio_class)); TEST_ASSERT(slv2_values_size(slv2_port_get_properties(plug, p)) == 0); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_port_get_symbol(plug, p)), "foo")); SLV2Value name = slv2_port_get_name(plug, p); TEST_ASSERT(!strcmp(slv2_value_as_string(name), "bar")); slv2_value_free(name); SLV2ScalePoints points = slv2_port_get_scale_points(plug, p); TEST_ASSERT(slv2_scale_points_size(points) == 2); TEST_ASSERT(slv2_scale_points_get_at(points, (unsigned)INT_MAX+1) == NULL); TEST_ASSERT(slv2_scale_points_get_at(points, 2) == NULL); SLV2ScalePoint sp0 = slv2_scale_points_get_at(points, 0); TEST_ASSERT(sp0); SLV2ScalePoint sp1 = slv2_scale_points_get_at(points, 1); TEST_ASSERT(sp1); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_scale_point_get_label(sp0)), "Sin")); TEST_ASSERT(slv2_value_as_float(slv2_scale_point_get_value(sp0)) == 3); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_scale_point_get_label(sp1)), "Cos")); TEST_ASSERT(slv2_value_as_float(slv2_scale_point_get_value(sp1)) == 4); SLV2Value homepage_p = slv2_value_new_uri(world, "http://usefulinc.com/ns/doap#homepage"); SLV2Values homepages = slv2_plugin_get_value(plug, homepage_p); TEST_ASSERT(slv2_values_size(homepages) == 1); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_values_get_at(homepages, 0)), "http://example.org/someplug")); TEST_ASSERT(slv2_plugin_query_count(plug, "SELECT DISTINCT ?bin WHERE {\n" "<> lv2:binary ?bin . }") == 1); TEST_ASSERT(slv2_plugin_query_count(plug, "SELECT DISTINCT ?parent WHERE {\n" "<> rdfs:subClassOf ?parent . }") == 0); SLV2Value min, max, def; slv2_port_get_range(plug, p, &def, &min, &max); TEST_ASSERT(def); TEST_ASSERT(min); TEST_ASSERT(max); TEST_ASSERT(slv2_value_as_float(def) == 0.5); TEST_ASSERT(slv2_value_as_float(min) == -1.0); TEST_ASSERT(slv2_value_as_float(max) == 1.0); SLV2Value integer_prop = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#integer"); SLV2Value toggled_prop = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#toggled"); TEST_ASSERT(slv2_port_has_property(plug, p, integer_prop)); TEST_ASSERT(!slv2_port_has_property(plug, p, toggled_prop)); SLV2Port ep = slv2_plugin_get_port_by_index(plug, 1); SLV2Value event_type = slv2_value_new_uri(world, "http://example.org/event"); SLV2Value event_type_2 = slv2_value_new_uri(world, "http://example.org/otherEvent"); TEST_ASSERT(slv2_port_supports_event(plug, ep, event_type)); TEST_ASSERT(!slv2_port_supports_event(plug, ep, event_type_2)); SLV2Value name_p = slv2_value_new_uri(world, "http://lv2plug.in/ns/lv2core#name"); SLV2Values names = slv2_port_get_value(plug, p, name_p); TEST_ASSERT(slv2_values_size(names) == 2); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_values_get_at(names, 0)), "bar")); slv2_values_free(names); names = slv2_port_get_value(plug, ep, name_p); TEST_ASSERT(slv2_values_size(names) == 1); TEST_ASSERT(!strcmp(slv2_value_as_string(slv2_values_get_at(names, 0)), "Event Input")); slv2_values_free(names); slv2_value_free(name_p); TEST_ASSERT(slv2_port_get_value(plug, p, min) == NULL); slv2_value_free(integer_prop); slv2_value_free(toggled_prop); slv2_value_free(event_type); slv2_value_free(event_type_2); slv2_value_free(min); slv2_value_free(max); slv2_value_free(def); slv2_value_free(homepage_p); slv2_values_free(homepages); slv2_scale_points_free(points); slv2_value_free(control_class); slv2_value_free(audio_class); slv2_value_free(in_class); slv2_plugins_free(world, plugins); cleanup_uris(); return 1; } /*****************************************************************************/ int test_ui() { if (!start_bundle(MANIFEST_PREFIXES ":plug a lv2:Plugin ; lv2:binary ; rdfs:seeAlso .\n", BUNDLE_PREFIXES PREFIX_LV2UI ":plug a lv2:Plugin ; a lv2:CompressorPlugin ; " PLUGIN_NAME("Test plugin") " ; " LICENSE_GPL " ; " "lv2:optionalFeature lv2:hardRtCapable ; " "lv2:requiredFeature ; " "lv2ui:ui :ui , :ui2 , :ui3 , :ui4 ; " "doap:maintainer [ foaf:name \"David Robillard\" ; " " foaf:homepage ; foaf:mbox ] ; " "lv2:port [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 0 ; lv2:symbol \"foo\" ; lv2:name \"bar\" ; " " lv2:minimum -1.0 ; lv2:maximum 1.0 ; lv2:default 0.5 " "] , [ " " a lv2:ControlPort ; a lv2:InputPort ; " " lv2:index 1 ; lv2:symbol \"bar\" ; lv2:name \"Baz\" ; " " lv2:minimum -2.0 ; lv2:maximum 2.0 ; lv2:default 1.0 " "] , [ " " a lv2:ControlPort ; a lv2:OutputPort ; " " lv2:index 2 ; lv2:symbol \"latency\" ; lv2:name \"Latency\" ; " " lv2:portProperty lv2:reportsLatency " "] .\n" ":ui a lv2ui:GtkUI ; " " lv2ui:requiredFeature lv2ui:makeResident ; " " lv2ui:binary ; " " lv2ui:optionalFeature lv2ui:ext_presets . " ":ui2 a lv2ui:GtkUI ; lv2ui:binary . " ":ui3 a lv2ui:GtkUI ; lv2ui:binary . " ":ui4 a lv2ui:GtkUI ; lv2ui:binary . ")) return 0; init_uris(); SLV2Plugins plugins = slv2_world_get_all_plugins(world); SLV2Plugin plug = slv2_plugins_get_by_uri(plugins, plugin_uri_value); TEST_ASSERT(plug); SLV2UIs uis = slv2_plugin_get_uis(plug); TEST_ASSERT(slv2_uis_size(uis) == 4); TEST_ASSERT(slv2_uis_get_at(uis, (unsigned)INT_MAX + 1) == NULL); SLV2UI ui0 = slv2_uis_get_at(uis, 0); TEST_ASSERT(ui0); SLV2Value ui_uri = slv2_value_new_uri(world, "http://example.org/ui"); SLV2Value ui2_uri = slv2_value_new_uri(world, "http://example.org/ui3"); SLV2Value ui3_uri = slv2_value_new_uri(world, "http://example.org/ui4"); SLV2Value noui_uri = slv2_value_new_uri(world, "http://example.org/notaui"); SLV2UI ui0_2 = slv2_uis_get_by_uri(uis, ui_uri); TEST_ASSERT(ui0 == ui0_2); SLV2UI ui2 = slv2_uis_get_by_uri(uis, ui2_uri); TEST_ASSERT(ui2 != ui0); SLV2UI ui3 = slv2_uis_get_by_uri(uis, ui3_uri); TEST_ASSERT(ui3 != ui0); SLV2UI noui = slv2_uis_get_by_uri(uis, noui_uri); TEST_ASSERT(noui == NULL); SLV2Values classes = slv2_ui_get_classes(ui0); TEST_ASSERT(slv2_values_size(classes) == 1); SLV2Value ui_class_uri = slv2_value_new_uri(world, "http://lv2plug.in/ns/extensions/ui#GtkUI"); TEST_ASSERT(slv2_value_equals(slv2_values_get_at(classes, 0), ui_class_uri)); TEST_ASSERT(slv2_ui_is_a(ui0, ui_class_uri)); SLV2Value plug_bundle_uri = slv2_plugin_get_bundle_uri(plug); SLV2Value ui_bundle_uri = slv2_ui_get_bundle_uri(ui0); TEST_ASSERT(slv2_value_equals(plug_bundle_uri, ui_bundle_uri)); char* ui_binary_uri_str = (char*)malloc(TEST_PATH_MAX); snprintf(ui_binary_uri_str, TEST_PATH_MAX, "%s%s", slv2_value_as_string(plug_bundle_uri), "ui.so"); SLV2Value ui_binary_uri = slv2_ui_get_binary_uri(ui0); SLV2Value expected_uri = slv2_value_new_uri(world, ui_binary_uri_str); TEST_ASSERT(slv2_value_equals(expected_uri, ui_binary_uri)); free(ui_binary_uri_str); slv2_value_free(ui_class_uri); slv2_value_free(ui_uri); slv2_value_free(ui2_uri); slv2_value_free(ui3_uri); slv2_value_free(noui_uri); slv2_value_free(expected_uri); slv2_uis_free(uis); cleanup_uris(); return 1; } /*****************************************************************************/ /* add tests here */ static struct TestCase tests[] = { TEST_CASE(utils), TEST_CASE(value), TEST_CASE(values), TEST_CASE(verify), TEST_CASE(no_verify), TEST_CASE(discovery), TEST_CASE(classes), TEST_CASE(plugin), TEST_CASE(port), TEST_CASE(plugin), TEST_CASE(ui), { NULL, NULL } }; void run_tests() { int i; for (i = 0; tests[i].title; i++) { printf("--- Test: %s\n", tests[i].title); if (!tests[i].func()) { printf("\nTest failed\n"); /* test case that wasn't able to be executed at all counts as 1 test + 1 error */ error_count++; test_count++; } unload_bundle(); cleanup(); } } int main(int argc, char *argv[]) { if (argc != 1) { printf("Syntax: %s\n", argv[0]); return 0; } init_tests(); run_tests(); cleanup(); printf("\n***\n*** Test Results: %d tests, %d errors\n***\n\n", test_count, error_count); return error_count ? 1 : 0; } slv2-0.6.6+dfsg1/test/test_coverage.sh0000755000175000017500000000062111231361306017434 0ustar alessioalessio#!/bin/sh # Run this script (from the directory it's in) after building # (with waf configure --debug --test) to run the # unit tests and generate a code coverage report cd ../build/default lcov -d ./src -z ./test/slv2_test lcov -d ./src -d ./test -b .. -c > coverage.lcov mkdir -p ./coverage genhtml -o coverage coverage.lcov echo "Report written to:" echo "../build/default/coverage/index.html" slv2-0.6.6+dfsg1/swig/0000755000175000017500000000000011231361306014236 5ustar alessioalessioslv2-0.6.6+dfsg1/swig/python/0000755000175000017500000000000011231361306015557 5ustar alessioalessioslv2-0.6.6+dfsg1/swig/python/Makefile.am0000644000175000017500000000054311231361306017615 0ustar alessioalessioEXTRA_DIST = lv2_list.py if WITH_PYTHON all: swig -DPYTHON -Wall -python -I../.. -o slv2_python.c -oh slv2_python.h ../slv2.i gcc -fPIC -shared -I../.. $(PYTHON_CPPFLAGS) $(PYTHON_EXTRA_LDFLAGS) \ $(PYTHON_EXTRA_LIBS) $(PYTHON_EXTRA_LDFLAGS) \ slv2_python.c ../../src/.libs/libslv2.so -o _slv2.so clean-local: rm -f *.[ch] *.so *.o slv2.py endif slv2-0.6.6+dfsg1/swig/python/lv2_list.py0000755000175000017500000000017711231361306017677 0ustar alessioalessio#!/usr/bin/env python import slv2; w = slv2.World() w.load_all() for p in w.get_all_plugins(): print p.uri(), "-", p.name() slv2-0.6.6+dfsg1/swig/Makefile.am0000644000175000017500000000013111231361306016265 0ustar alessioalessioEXTRA_DIST = slv2.i if WITH_SWIG SUBDIRS = python mzscheme chicken endif # WITH_SWIG slv2-0.6.6+dfsg1/swig/chicken/0000755000175000017500000000000011231361306015642 5ustar alessioalessioslv2-0.6.6+dfsg1/swig/chicken/Makefile.am0000644000175000017500000000053011231361306017674 0ustar alessioalessioEXTRA_DIST = slv2.setup lv2_list.scm if WITH_CHICKEN all: rm -f slv2.scm slv2_wrap.c swig -DCHICKEN -Wall -chicken -proxy -nounit -I../.. -o slv2_wrap.c -oh slv2_wrap.h ../slv2.i tar -czf slv2.egg slv2.setup slv2.scm slv2_wrap.c #install-exec-local: # chicken-setup ./slv2.egg clean-local: rm -f *.[ch] *.so *.o slv2.egg slv2.scm endif slv2-0.6.6+dfsg1/swig/chicken/slv2.setup0000644000175000017500000000013511231361306017611 0ustar alessioalessio(run (csc -s -o slv2.so slv2.scm slv2_wrap.c -lslv2)) (install-extension 'slv2 '("slv2.so")) slv2-0.6.6+dfsg1/swig/chicken/lv2_list.scm0000644000175000017500000000047611231361306020113 0ustar alessioalessio; Least idiomatic scheme bindings ever. Work in progress... (require-extension slv2) (define world (slv2-world-new)) (slv2-world-load-all world) (define plugins (slv2-world-get-all-plugins world)) (let ((p (slv2-plugins-get-at plugins 0))) (display (slv2-value-as-string (slv2-plugin-get-uri p))) (newline)) slv2-0.6.6+dfsg1/swig/slv2.i0000644000175000017500000000622511231361306015303 0ustar alessioalessio%module slv2 %{ #include "slv2/plugin.h" #include "slv2/pluginclass.h" #include "slv2/pluginclasses.h" #include "slv2/plugininstance.h" #include "slv2/plugins.h" #include "slv2/port.h" #include "slv2/slv2.h" #include "slv2/types.h" #include "slv2/value.h" #include "slv2/values.h" #include "slv2/world.h" typedef struct { SLV2World me; } World; typedef struct { SLV2World world; SLV2Plugins me; } Plugins; typedef struct { SLV2World world; SLV2Plugin me; } Plugin; %} %include "slv2/plugin.h" %include "slv2/pluginclass.h" %include "slv2/pluginclasses.h" %include "slv2/plugininstance.h" %include "slv2/plugins.h" %include "slv2/port.h" %include "slv2/slv2.h" %include "slv2/types.h" %include "slv2/value.h" %include "slv2/values.h" %include "slv2/world.h" typedef struct { SLV2Plugin me; } Plugin; %extend Plugin { Plugin(SLV2Plugin p) { Plugin* ret = (Plugin*)malloc(sizeof(Plugin)); ret->me = p; return ret; } ~Plugin() { /* FIXME: free SLV2Plugin here? */ free($self); } char* name() { SLV2Value nm = slv2_plugin_get_name($self->me); char* ret = nm ? strdup((char*)slv2_value_as_string(nm)) : strdup(""); slv2_value_free(nm); return ret; } const char* uri() { return strdup((char*)slv2_value_as_string(slv2_plugin_get_uri($self->me))); } }; typedef struct { SLV2World world; SLV2Plugins me; } Plugins; %extend Plugins { Plugins(SLV2World w, SLV2Plugins p) { Plugins* ret = (Plugins*)malloc(sizeof(Plugins)); ret->world = w; ret->me = p; return ret; } ~Plugins() { slv2_plugins_free($self->world, $self->me); free($self); } inline unsigned size() const { return slv2_plugins_size($self->me); } #ifdef PYTHON Plugin* __getitem__(unsigned i) { if (i < slv2_plugins_size($self->me)) return new_Plugin(slv2_plugins_get_at($self->me, i)); else return NULL; } inline unsigned __len__() const { return slv2_plugins_size($self->me); } %pythoncode %{ def __iter__(self): class Iterator(object): def __init__(self, plugins): self.plugins = plugins self.iter = 0 def next(self): if self.iter < self.plugins.size(): self.iter += 1 return Plugin(slv2_plugins_get_at(self.plugins.me, self.iter-1)) else: raise StopIteration return Iterator(self) %} #endif }; typedef struct { SLV2World me; } World; %extend World { World() { World* ret = (World*)malloc(sizeof(World)); ret->me = slv2_world_new(); return ret; } ~World() { slv2_world_free($self->me); free($self); } void load_all() { slv2_world_load_all($self->me); } void load_bundle(const char* uri) { SLV2Value bundle_uri = slv2_value_new_uri($self->me, uri); slv2_world_load_bundle($self->me, bundle_uri); slv2_value_free(bundle_uri); } Plugins* get_all_plugins() { return new_Plugins($self->me, slv2_world_get_all_plugins($self->me)); } }; slv2-0.6.6+dfsg1/swig/mzscheme/0000755000175000017500000000000011231361306016051 5ustar alessioalessioslv2-0.6.6+dfsg1/swig/mzscheme/Makefile.am0000644000175000017500000000037311231361306020110 0ustar alessioalessioif WITH_MZSCHEME all: swig -DMZSCHEME -Wall -mzscheme -I../.. -o slv2_mzscheme.c -oh slv2_mzscheme.h ../slv2.i gcc -fPIC -shared -Iplt -I../.. \ -I/usr/include/plt slv2_mzscheme.c -o libslv2_mzscheme.so clean-local: rm -f *.[ch] *.so *.o endif slv2-0.6.6+dfsg1/COPYING0000644000175000017500000004310611231361306014324 0ustar alessioalessio GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. slv2-0.6.6+dfsg1/slv2-0.6.6.tar.bz2.sig0000644000175000017500000000011011231361306016575 0ustar alessioalessioFJkq e)rp`C);![CMZ&Œ(ϫzi U:q}(/Āhslv2-0.6.6+dfsg1/hosts/0000755000175000017500000000000011231361306014425 5ustar alessioalessioslv2-0.6.6+dfsg1/hosts/lv2_simple_jack_host.c0000644000175000017500000001745411231361306020705 0ustar alessioalessio/* SLV2 Simple Jack Host Example * Copyright (C) 2007-2009 Dave Robillard * * 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 the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include "slv2/slv2.h" /** This program's data */ struct JackHost { jack_client_t* jack_client; /**< Jack client */ SLV2World world; /**< SLV2 "world" object */ SLV2Plugin plugin; /**< Plugin "class" (actually just a few strings) */ SLV2Instance instance; /**< Plugin "instance" (loaded shared lib) */ uint32_t num_ports; /**< Size of the two following arrays: */ jack_port_t** jack_ports; /**< For audio ports, otherwise NULL */ float* controls; /**< For control ports, otherwise 0.0f */ SLV2Value input_class; /**< Input port class (URI) */ SLV2Value control_class; /**< Control port class (URI) */ SLV2Value audio_class; /**< Audio port class (URI) */ }; void die(const char* msg); void create_port(struct JackHost* host, uint32_t port_index); int jack_process_cb(jack_nframes_t nframes, void* data); void list_plugins(SLV2Plugins list); int main(int argc, char** argv) { struct JackHost host; host.jack_client = NULL; host.num_ports = 0; host.jack_ports = NULL; host.controls = NULL; /* Find all installed plugins */ host.world = slv2_world_new(); slv2_world_load_all(host.world); SLV2Plugins plugins = slv2_world_get_all_plugins(host.world); /* Set up the port classes this app supports */ host.input_class = slv2_value_new_uri(host.world, SLV2_PORT_CLASS_INPUT); host.audio_class = slv2_value_new_uri(host.world, SLV2_PORT_CLASS_OUTPUT); /* Note that SLV2_PORT_CLASS_* are simply strings defined for convenience. * host.control_class = slv2_value_new(host.world, SLV2_PORT_CLASS_CONTROL); * is the same as: */ host.control_class = slv2_value_new_uri(host.world, "http://lv2plug.in/ns/lv2core#ControlPort"); /* Find the plugin to run */ const char* plugin_uri_str = (argc == 2) ? argv[1] : NULL; if (!plugin_uri_str) { fprintf(stderr, "\nYou must specify a plugin URI to load.\n"); fprintf(stderr, "\nKnown plugins:\n\n"); list_plugins(plugins); slv2_world_free(host.world); return EXIT_FAILURE; } printf("URI:\t%s\n", plugin_uri_str); SLV2Value plugin_uri = slv2_value_new_uri(host.world, plugin_uri_str); host.plugin = slv2_plugins_get_by_uri(plugins, plugin_uri); slv2_value_free(plugin_uri); if (!host.plugin) { fprintf(stderr, "Failed to find plugin %s.\n", plugin_uri_str); slv2_world_free(host.world); return EXIT_FAILURE; } /* Get the plugin's name */ SLV2Value name = slv2_plugin_get_name(host.plugin); const char* name_str = slv2_value_as_string(name); printf("Plugin Name:\t%s\n", slv2_value_as_string(name)); /* Truncate plugin name to suit JACK (if necessary) */ char* jack_name = NULL; if (strlen(name_str) >= (unsigned)jack_client_name_size() - 1) { jack_name = calloc(jack_client_name_size(), sizeof(char)); strncpy(jack_name, name_str, jack_client_name_size() - 1); } else { jack_name = strdup(name_str); } /* Connect to JACK */ printf("JACK Name:\t%s\n", jack_name); host.jack_client = jack_client_open(jack_name, JackNullOption, NULL); free(jack_name); slv2_value_free(name); if (!host.jack_client) die("Failed to connect to JACK."); else printf("Connected to JACK.\n"); /* Instantiate the plugin */ host.instance = slv2_plugin_instantiate( host.plugin, jack_get_sample_rate(host.jack_client), NULL); if (!host.instance) die("Failed to instantiate plugin.\n"); else printf("Succesfully instantiated plugin.\n"); jack_set_process_callback(host.jack_client, &jack_process_cb, (void*)(&host)); /* Create ports */ host.num_ports = slv2_plugin_get_num_ports(host.plugin); host.jack_ports = calloc((size_t)host.num_ports, sizeof(jack_port_t*)); host.controls = calloc((size_t)host.num_ports, sizeof(float*)); for (uint32_t i=0; i < host.num_ports; ++i) create_port(&host, i); /* Activate plugin and JACK */ slv2_instance_activate(host.instance); jack_activate(host.jack_client); /* Run */ printf("Press enter to quit: "); getc(stdin); printf("\n"); /* Deactivate JACK */ jack_deactivate(host.jack_client); printf("Shutting down JACK.\n"); for (unsigned long i=0; i < host.num_ports; ++i) { if (host.jack_ports[i] != NULL) { jack_port_unregister(host.jack_client, host.jack_ports[i]); host.jack_ports[i] = NULL; } } jack_client_close(host.jack_client); /* Deactivate plugin */ slv2_instance_deactivate(host.instance); slv2_instance_free(host.instance); /* Clean up */ slv2_value_free(host.input_class); slv2_value_free(host.audio_class); slv2_value_free(host.control_class); slv2_plugins_free(host.world, plugins); slv2_world_free(host.world); return 0; } /** Abort and exit on error */ void die(const char* msg) { fprintf(stderr, "%s\n", msg); exit(EXIT_FAILURE); } /** Creates a port and connects the plugin instance to it's data location. * * For audio ports, creates a jack port and connects plugin port to buffer. * * For control ports, sets controls array to default value and connects plugin * port to that element. */ void create_port(struct JackHost* host, uint32_t index) { SLV2Port port = slv2_plugin_get_port_by_index(host->plugin, index); /* Get the port symbol (label) for console printing */ SLV2Value symbol = slv2_port_get_symbol(host->plugin, port); const char* symbol_str = slv2_value_as_string(symbol); /* Initialize the port array elements */ host->jack_ports[index] = NULL; host->controls[index] = 0.0f; /* Connect control ports to controls array */ if (slv2_port_is_a(host->plugin, port, host->control_class)) { /* Set default control values for inputs */ if (slv2_port_is_a(host->plugin, port, host->input_class)) { SLV2Value def; slv2_port_get_range(host->plugin, port, &def, NULL, NULL); host->controls[index] = slv2_value_as_float(def); printf("Set %s to %f\n", symbol_str, host->controls[index]); slv2_value_free(def); } slv2_instance_connect_port(host->instance, index, &host->controls[index]); } else if (slv2_port_is_a(host->plugin, port, host->audio_class)) { host->jack_ports[index] = jack_port_register(host->jack_client, symbol_str, JACK_DEFAULT_AUDIO_TYPE, slv2_port_is_a(host->plugin, port, host->input_class) ? JackPortIsInput : JackPortIsOutput, 0); } else { // Simple examples don't have to be robust :) die("ERROR: Unknown port type, aborting messily!\n"); } } /** Jack process callback. */ int jack_process_cb(jack_nframes_t nframes, void* data) { struct JackHost* host = (struct JackHost*)data; /* Connect plugin ports directly to JACK buffers */ for (uint32_t i=0; i < host->num_ports; ++i) if (host->jack_ports[i] != NULL) slv2_instance_connect_port(host->instance, i, jack_port_get_buffer(host->jack_ports[i], nframes)); /* Run plugin for this cycle */ slv2_instance_run(host->instance, nframes); return 0; } void list_plugins(SLV2Plugins list) { for (unsigned i=0; i < slv2_plugins_size(list); ++i) { SLV2Plugin p = slv2_plugins_get_at(list, i); printf("%s\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); } } slv2-0.6.6+dfsg1/hosts/lv2_uri_map.h0000644000175000017500000000701011231361306017013 0ustar alessioalessio/* lv2_uri_map.h - C header file for the LV2 URI Map extension. * * Copyright (C) 2008-2009 Dave Robillard * * This header is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This header is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this header; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA */ #ifndef LV2_URI_MAP_H #define LV2_URI_MAP_H #define LV2_URI_MAP_URI "http://lv2plug.in/ns/ext/uri-map" #include /** @file * This header defines the LV2 URI Map extension with the URI * (preferred prefix 'lv2urimap'). * * This extension defines a simple mechanism for plugins to map URIs to * integers, usually for performance reasons (e.g. processing events * typed by URIs in real time). The expected use case is for plugins to * map URIs to integers for things they 'understand' at instantiation time, * and store those values for use in the audio thread without doing any string * comparison. This allows the extensibility of RDF with the performance of * integers (or centrally defined enumerations). */ /** Opaque pointer to host data. */ typedef void* LV2_URI_Map_Callback_Data; /** The data field of the LV2_Feature for this extension. * * To support this feature the host must pass an LV2_Feature struct to the * plugin's instantiate method with URI "http://lv2plug.in/ns/ext/uri-map" * and data pointed to an instance of this struct. */ typedef struct { /** Opaque pointer to host data. * * The plugin MUST pass this to any call to functions in this struct. * Otherwise, it must not be interpreted in any way. */ LV2_URI_Map_Callback_Data callback_data; /** Get the numeric ID of a URI from the host. * * @param callback_data Must be the callback_data member of this struct. * @param map The 'context' of this URI. Certain extensions may define a * URI that must be passed here with certain restrictions on the * return value (e.g. limited range). This value may be NULL if * the plugin needs an ID for a URI in general. * @param uri The URI to be mapped to an integer ID. * * This function is referentially transparent - any number of calls with * the same arguments is guaranteed to return the same value over the life * of a plugin instance (though the same URI may return different values * with a different map parameter). However, this function is not * necessarily very fast: plugins should cache any IDs they might need in * performance critical situations. * The return value 0 is reserved and means an ID for that URI could not * be created for whatever reason. Extensions may define more precisely * what this means, but in general plugins should gracefully handle 0 * and consider whatever they wanted the URI for "unsupported". */ uint32_t (*uri_to_id)(LV2_URI_Map_Callback_Data callback_data, const char* map, const char* uri); } LV2_URI_Map_Feature; #endif // LV2_URI_MAP_H slv2-0.6.6+dfsg1/hosts/lv2_event_helpers.h0000644000175000017500000001606011231361306020227 0ustar alessioalessio/* lv2_event_helpers.h - Helper functions for the LV2 events extension. * * Copyright (C) 2008-2009 Dave Robillard * * This header is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This header is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this header; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA */ #ifndef LV2_EVENT_HELPERS_H #define LV2_EVENT_HELPERS_H #include #include #include #include #include #include "lv2_event.h" /** @file * This header defines some helper functions for the the LV2 events extension * with URI ('lv2ev'). * * These functions are provided for convenience only, use of them is not * required for supporting lv2ev (i.e. the events extension is defined by the * raw buffer format described in lv2_event.h and NOT by this API). * * Note that these functions are all static inline which basically means: * do not take the address of these functions. */ /** Pad a size to 64 bits (for event sizes) */ static inline uint16_t lv2_event_pad_size(uint16_t size) { return (size + 7) & (~7); } /** Initialize (empty, reset..) an existing event buffer. * The contents of buf are ignored entirely and overwritten, except capacity * which is unmodified. */ static inline void lv2_event_buffer_reset(LV2_Event_Buffer* buf, uint16_t stamp_type, uint8_t *data) { buf->data = data; buf->header_size = sizeof(LV2_Event_Buffer); buf->stamp_type = stamp_type; buf->event_count = 0; buf->size = 0; } /** Allocate a new, empty event buffer. */ static inline LV2_Event_Buffer* lv2_event_buffer_new(uint32_t capacity, uint16_t stamp_type) { LV2_Event_Buffer* buf = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity); if (buf != NULL) { buf->capacity = capacity; lv2_event_buffer_reset(buf, stamp_type, (uint8_t *)(buf + 1)); return buf; } else { return NULL; } } /** An iterator over an LV2_Event_Buffer. * * Multiple simultaneous read iterators over a single buffer is fine, * but changing the buffer invalidates all iterators (e.g. RW Lock). */ typedef struct { LV2_Event_Buffer* buf; uint32_t offset; } LV2_Event_Iterator; /** Reset an iterator to point to the start of @a buf. * @return True if @a iter is valid, otherwise false (buffer is empty) */ static inline bool lv2_event_begin(LV2_Event_Iterator* iter, LV2_Event_Buffer* buf) { iter->buf = buf; iter->offset = 0; return (buf->size > 0); } /** Check if @a iter is valid.. * @return True if @a iter is valid, otherwise false (past end of buffer) */ static inline bool lv2_event_is_valid(LV2_Event_Iterator* iter) { return (iter->offset < iter->buf->size); } /** Advance @a iter forward one event. * @a iter must be valid. * @return True if @a iter is valid, otherwise false (reached end of buffer) */ static inline bool lv2_event_increment(LV2_Event_Iterator* iter) { assert(lv2_event_is_valid(iter)); LV2_Event* const ev = (LV2_Event*)( (uint8_t*)iter->buf->data + iter->offset); iter->offset += lv2_event_pad_size(sizeof(LV2_Event) + ev->size); return true; } /** Dereference an event iterator (get the event currently pointed at). * @a iter must be valid. * @a data if non-NULL, will be set to point to the contents of the event * returned. * @return A Pointer to the event @a iter is currently pointing at, or NULL * if the end of the buffer is reached (in which case @a data is * also set to NULL). */ static inline LV2_Event* lv2_event_get(LV2_Event_Iterator* iter, uint8_t** data) { assert(lv2_event_is_valid(iter)); LV2_Event* const ev = (LV2_Event*)( (uint8_t*)iter->buf->data + iter->offset); if (data) *data = (uint8_t*)ev + sizeof(LV2_Event); return ev; } /** Write an event at @a iter. * The event (if any) pointed to by @iter will be overwritten, and @a iter * incremented to point to the following event (i.e. several calls to this * function can be done in sequence without twiddling iter in-between). * @return True if event was written, otherwise false (buffer is full). */ static inline bool lv2_event_write(LV2_Event_Iterator* iter, uint32_t frames, uint32_t subframes, uint16_t type, uint16_t size, const uint8_t* data) { if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size) return false; LV2_Event* const ev = (LV2_Event*)( (uint8_t*)iter->buf->data + iter->offset); ev->frames = frames; ev->subframes = subframes; ev->type = type; ev->size = size; memcpy((uint8_t*)ev + sizeof(LV2_Event), data, size); ++iter->buf->event_count; size = lv2_event_pad_size(sizeof(LV2_Event) + size); iter->buf->size += size; iter->offset += size; return true; } /** Reserve space for an event in the buffer and return a pointer to the memory where the caller can write the event data, or NULL if there is not enough room in the buffer. */ static inline uint8_t* lv2_event_reserve(LV2_Event_Iterator* iter, uint32_t frames, uint32_t subframes, uint16_t type, uint16_t size) { size = lv2_event_pad_size(size); if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size) return NULL; LV2_Event* const ev = (LV2_Event*)((uint8_t*)iter->buf->data + iter->offset); ev->frames = frames; ev->subframes = subframes; ev->type = type; ev->size = size; ++iter->buf->event_count; size = lv2_event_pad_size(sizeof(LV2_Event) + size); iter->buf->size += size; iter->offset += size; return (uint8_t*)ev + sizeof(LV2_Event); } /** Write an event at @a iter. * The event (if any) pointed to by @iter will be overwritten, and @a iter * incremented to point to the following event (i.e. several calls to this * function can be done in sequence without twiddling iter in-between). * @return True if event was written, otherwise false (buffer is full). */ static inline bool lv2_event_write_event(LV2_Event_Iterator* iter, const LV2_Event* ev, const uint8_t* data) { if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + ev->size) return false; LV2_Event* const write_ev = (LV2_Event*)( (uint8_t*)iter->buf->data + iter->offset); *write_ev = *ev; memcpy((uint8_t*)write_ev + sizeof(LV2_Event), data, ev->size); ++iter->buf->event_count; const uint16_t size = lv2_event_pad_size(sizeof(LV2_Event) + ev->size); iter->buf->size += size; iter->offset += size; return true; } #endif // LV2_EVENT_HELPERS_H slv2-0.6.6+dfsg1/hosts/lv2_jack_host.c0000644000175000017500000003111211231361306017317 0ustar alessioalessio/* jack_host - SLV2 Jack Host * Copyright (C) 2007-2009 Dave Robillard * * 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 the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "slv2-config.h" #define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include "slv2/slv2.h" #include "lv2_uri_map.h" #include "lv2_event.h" #include "lv2_event_helpers.h" #include "jack_compat.h" #define MIDI_BUFFER_SIZE 1024 enum PortDirection { INPUT, OUTPUT }; enum PortType { CONTROL, AUDIO, EVENT }; struct Port { SLV2Port slv2_port; enum PortDirection direction; enum PortType type; jack_port_t* jack_port; /**< For audio and MIDI ports, otherwise NULL */ float control; /**< For control ports, otherwise 0.0f */ LV2_Event_Buffer* ev_buffer; /**< For midi ports, otherwise NULL */ }; /** This program's data */ struct JackHost { jack_client_t* jack_client; /**< Jack client */ SLV2Plugin plugin; /**< Plugin "class" (actually just a few strings) */ SLV2Instance instance; /**< Plugin "instance" (loaded shared lib) */ uint32_t num_ports; /**< Size of the two following arrays: */ struct Port* ports; /**< Port array of size num_ports */ SLV2Value input_class; /**< Input port class (URI) */ SLV2Value output_class; /**< Output port class (URI) */ SLV2Value control_class; /**< Control port class (URI) */ SLV2Value audio_class; /**< Audio port class (URI) */ SLV2Value event_class; /**< Event port class (URI) */ SLV2Value midi_class; /**< MIDI event class (URI) */ SLV2Value optional; /**< lv2:connectionOptional port property */ }; /** URI map feature, for event types (we use only MIDI) */ #define MIDI_EVENT_ID 1 uint32_t uri_to_id(LV2_URI_Map_Callback_Data callback_data, const char* map, const char* uri) { if (!strcmp(map, LV2_EVENT_URI) && !strcmp(uri, SLV2_EVENT_CLASS_MIDI)) return MIDI_EVENT_ID; else return 0; // no id for you! } static LV2_URI_Map_Feature uri_map = { NULL, &uri_to_id }; static const LV2_Feature uri_map_feature = { "http://lv2plug.in/ns/ext/uri-map", &uri_map }; /** We don't support type 0 events, so the ref and unref functions just point to the same empty function. */ uint32_t event_ref_func(LV2_Event_Callback_Data callback_data, LV2_Event* event) { return 0; } static LV2_Event_Feature event_ref = { NULL, &event_ref_func, &event_ref_func }; static const LV2_Feature event_ref_feature = { "http://lv2plug.in/ns/ext/event", &event_ref }; const LV2_Feature* features[3] = { &uri_map_feature, &event_ref_feature, NULL }; void die(const char* msg); void create_port(struct JackHost* host, uint32_t port_index, float default_value); int jack_process_cb(jack_nframes_t nframes, void* data); void list_plugins(SLV2Plugins list); int main(int argc, char** argv) { struct JackHost host; host.jack_client = NULL; host.num_ports = 0; host.ports = NULL; /* Find all installed plugins */ SLV2World world = slv2_world_new(); slv2_world_load_all(world); SLV2Plugins plugins = slv2_world_get_all_plugins(world); /* Set up the port classes this app supports */ host.input_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_INPUT); host.output_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_OUTPUT); host.control_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_CONTROL); host.audio_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_AUDIO); host.event_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_EVENT); host.midi_class = slv2_value_new_uri(world, SLV2_EVENT_CLASS_MIDI); host.optional = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "connectionOptional"); /* Find the plugin to run */ const char* plugin_uri_str = (argc == 2) ? argv[1] : NULL; if (!plugin_uri_str) { fprintf(stderr, "\nYou must specify a plugin URI to load.\n"); fprintf(stderr, "\nKnown plugins:\n\n"); list_plugins(plugins); slv2_world_free(world); return EXIT_FAILURE; } printf("URI:\t%s\n", plugin_uri_str); SLV2Value plugin_uri = slv2_value_new_uri(world, plugin_uri_str); host.plugin = slv2_plugins_get_by_uri(plugins, plugin_uri); slv2_value_free(plugin_uri); if (!host.plugin) { fprintf(stderr, "Failed to find plugin %s.\n", plugin_uri_str); slv2_world_free(world); return EXIT_FAILURE; } /* Get the plugin's name */ SLV2Value name = slv2_plugin_get_name(host.plugin); const char* name_str = slv2_value_as_string(name); printf("Plugin Name:\t%s\n", slv2_value_as_string(name)); /* Truncate plugin name to suit JACK (if necessary) */ char* jack_name = NULL; if (strlen(name_str) >= (unsigned)jack_client_name_size() - 1) { jack_name = calloc(jack_client_name_size(), sizeof(char)); strncpy(jack_name, name_str, jack_client_name_size() - 1); } else { jack_name = strdup(name_str); } /* Connect to JACK */ printf("JACK Name:\t%s\n", jack_name); host.jack_client = jack_client_open(jack_name, JackNullOption, NULL); free(jack_name); slv2_value_free(name); if (!host.jack_client) die("Failed to connect to JACK."); else printf("Connected to JACK.\n"); /* Instantiate the plugin */ host.instance = slv2_plugin_instantiate( host.plugin, jack_get_sample_rate(host.jack_client), features); if (!host.instance) die("Failed to instantiate plugin.\n"); else printf("Succesfully instantiated plugin.\n"); jack_set_process_callback(host.jack_client, &jack_process_cb, (void*)(&host)); /* Create ports */ host.num_ports = slv2_plugin_get_num_ports(host.plugin); host.ports = calloc((size_t)host.num_ports, sizeof(struct Port)); float* default_values = calloc(slv2_plugin_get_num_ports(host.plugin), sizeof(float)); slv2_plugin_get_port_ranges_float(host.plugin, NULL, NULL, default_values); for (uint32_t i=0; i < host.num_ports; ++i) create_port(&host, i, default_values[i]); free(default_values); /* Activate plugin and JACK */ slv2_instance_activate(host.instance); jack_activate(host.jack_client); /* Run */ printf("Press enter to quit: "); getc(stdin); printf("\n"); /* Deactivate JACK */ jack_deactivate(host.jack_client); printf("Shutting down JACK.\n"); for (unsigned long i=0; i < host.num_ports; ++i) { if (host.ports[i].jack_port != NULL) { jack_port_unregister(host.jack_client, host.ports[i].jack_port); host.ports[i].jack_port = NULL; } if (host.ports[i].ev_buffer != NULL) { free(host.ports[i].ev_buffer); } } jack_client_close(host.jack_client); /* Deactivate plugin */ slv2_instance_deactivate(host.instance); slv2_instance_free(host.instance); /* Clean up */ free(host.ports); slv2_value_free(host.input_class); slv2_value_free(host.output_class); slv2_value_free(host.control_class); slv2_value_free(host.audio_class); slv2_value_free(host.event_class); slv2_value_free(host.midi_class); slv2_value_free(host.optional); slv2_plugins_free(world, plugins); slv2_world_free(world); return 0; } /** Abort and exit on error */ void die(const char* msg) { fprintf(stderr, "%s\n", msg); exit(EXIT_FAILURE); } /** Creates a port and connects the plugin instance to it's data location. * * For audio ports, creates a jack port and connects plugin port to buffer. * * For control ports, sets controls array to default value and connects plugin * port to that element. */ void create_port(struct JackHost* host, uint32_t port_index, float default_value) { struct Port* const port = &host->ports[port_index]; port->slv2_port = slv2_plugin_get_port_by_index(host->plugin, port_index); port->jack_port = NULL; port->control = 0.0f; port->ev_buffer = NULL; slv2_instance_connect_port(host->instance, port_index, NULL); /* Get the port symbol for console printing */ SLV2Value symbol = slv2_port_get_symbol(host->plugin, port->slv2_port); const char* symbol_str = slv2_value_as_string(symbol); enum JackPortFlags jack_flags = 0; if (slv2_port_is_a(host->plugin, port->slv2_port, host->input_class)) { jack_flags = JackPortIsInput; port->direction = INPUT; } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->output_class)) { jack_flags = JackPortIsOutput; port->direction = OUTPUT; } else if (slv2_port_has_property(host->plugin, port->slv2_port, host->optional)) { slv2_instance_connect_port(host->instance, port_index, NULL); } else { die("Mandatory port has unknown type (neither input or output)"); } /* Set control values */ if (slv2_port_is_a(host->plugin, port->slv2_port, host->control_class)) { port->type = CONTROL; port->control = isnan(default_value) ? 0.0 : default_value; printf("Set %s to %f\n", symbol_str, host->ports[port_index].control); } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->audio_class)) { port->type = AUDIO; } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->event_class)) { port->type = EVENT; } /* Connect the port based on it's type */ switch (port->type) { case CONTROL: slv2_instance_connect_port(host->instance, port_index, &port->control); break; case AUDIO: port->jack_port = jack_port_register(host->jack_client, symbol_str, JACK_DEFAULT_AUDIO_TYPE, jack_flags, 0); break; case EVENT: port->jack_port = jack_port_register(host->jack_client, symbol_str, JACK_DEFAULT_MIDI_TYPE, jack_flags, 0); port->ev_buffer = lv2_event_buffer_new(MIDI_BUFFER_SIZE, LV2_EVENT_AUDIO_STAMP); slv2_instance_connect_port(host->instance, port_index, port->ev_buffer); break; default: // FIXME: check if port connection is is optional and die if not slv2_instance_connect_port(host->instance, port_index, NULL); fprintf(stderr, "WARNING: Unknown port type, port not connected.\n"); } } /** Jack process callback. */ int jack_process_cb(jack_nframes_t nframes, void* data) { struct JackHost* const host = (struct JackHost*)data; /* Connect inputs */ for (uint32_t p=0; p < host->num_ports; ++p) { if (!host->ports[p].jack_port) continue; if (host->ports[p].type == AUDIO) { slv2_instance_connect_port(host->instance, p, jack_port_get_buffer(host->ports[p].jack_port, nframes)); } else if (host->ports[p].type == EVENT) { lv2_event_buffer_reset(host->ports[p].ev_buffer, LV2_EVENT_AUDIO_STAMP, (uint8_t *)(host->ports[p].ev_buffer + 1)); if (host->ports[p].direction == INPUT) { void* jack_buffer = jack_port_get_buffer(host->ports[p].jack_port, nframes); LV2_Event_Iterator iter; lv2_event_begin(&iter, host->ports[p].ev_buffer); const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer); jack_midi_event_t ev; for (jack_nframes_t e=0; e < event_count; ++e) { jack_midi_event_get(&ev, jack_buffer, e); lv2_event_write(&iter, ev.time, 0, MIDI_EVENT_ID, ev.size, ev.buffer); } } } } /* Run plugin for this cycle */ slv2_instance_run(host->instance, nframes); /* Deliver output */ for (uint32_t p=0; p < host->num_ports; ++p) { if (host->ports[p].jack_port && host->ports[p].direction == INPUT && host->ports[p].type == EVENT) { void* jack_buffer = jack_port_get_buffer(host->ports[p].jack_port, nframes); jack_midi_clear_buffer(jack_buffer); LV2_Event_Iterator iter; lv2_event_begin(&iter, host->ports[p].ev_buffer); const uint32_t event_count = iter.buf->event_count; for (uint32_t i=0; i < event_count; ++i) { uint8_t* data; LV2_Event* ev = lv2_event_get(&iter, &data); #if defined(JACK_MIDI_NEEDS_NFRAMES) jack_midi_event_write(jack_buffer, (jack_nframes_t)ev->frames, data, ev->size, nframes); #else jack_midi_event_write(jack_buffer, (jack_nframes_t)ev->frames, data, ev->size); #endif lv2_event_increment(&iter); } } } return 0; } void list_plugins(SLV2Plugins list) { for (unsigned i=0; i < slv2_plugins_size(list); ++i) { SLV2Plugin p = slv2_plugins_get_at(list, i); printf("%s\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); } } slv2-0.6.6+dfsg1/hosts/lv2_event.h0000644000175000017500000002605411231361306016511 0ustar alessioalessio/* lv2_event.h - C header file for the LV2 events extension. * * Copyright (C) 2006-2007 Lars Luthman * Copyright (C) 2008-2009 Dave Robillard * * This header is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This header is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this header; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA */ #ifndef LV2_EVENT_H #define LV2_EVENT_H #define LV2_EVENT_URI "http://lv2plug.in/ns/ext/event" #define LV2_EVENT_AUDIO_STAMP 0 #include /** @file * This header defines the code portion of the LV2 events extension with URI * ('lv2ev'). * * This extension is a generic transport mechanism for time stamped events * of any type (e.g. MIDI, OSC, ramps, etc). Each port can transport mixed * events of any type; the type of events and timestamps are defined by a URI * which is mapped to an integer by the host for performance reasons. * * This extension requires the host to support the LV2 URI Map extension. * Any host which supports this extension MUST guarantee that any call to * the LV2 URI Map uri_to_id function with the URI of this extension as the * 'map' argument returns a value within the range of uint16_t. */ /** The best Pulses Per Quarter Note for tempo-based uint32_t timestmaps. * Equal to 2^12 * 5 * 7 * 9 * 11 * 13 * 17, which is evenly divisble * by all integers from 1 through 18 inclusive, and powers of 2 up to 2^12. */ static const uint32_t LV2_EVENT_PPQN = 3136573440U; /** An LV2 event (header only). * * LV2 events are generic time-stamped containers for any type of event. * The type field defines the format of a given event's contents. * * This struct defines the header of an LV2 event. An LV2 event is a single * chunk of POD (plain old data), usually contained in a flat buffer * (see LV2_EventBuffer below). Unless a required feature says otherwise, * hosts may assume a deep copy of an LV2 event can be created safely * using a simple: * * memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size); (or equivalent) */ typedef struct { /** The frames portion of timestamp. The units used here can optionally be * set for a port (with the lv2ev:timeUnits property), otherwise this * is audio frames, corresponding to the sample_count parameter of the * LV2 run method (e.g. frame 0 is the first frame for that call to run). */ uint32_t frames; /** The sub-frames portion of timestamp. The units used here can * optionally be set for a port (with the lv2ev:timeUnits property), * otherwise this is 1/(2^32) of an audio frame. */ uint32_t subframes; /** The type of this event, as a number which represents some URI * defining an event type. This value MUST be some value previously * returned from a call to the uri_to_id function defined in the LV2 * URI map extension (see lv2_uri_map.h). * There are special rules which must be followed depending on the type * of an event. If the plugin recognizes an event type, the definition * of that event type will describe how to interpret the event, and * any required behaviour. Otherwise, if the type is 0, this event is a * non-POD event and lv2_event_unref MUST be called if the event is * 'dropped' (see above). Even if the plugin does not understand an event, * it may pass the event through to an output by simply copying (and NOT * calling lv2_event_unref). These rules are designed to allow for generic * event handling plugins and large non-POD events, but with minimal hassle * on simple plugins that "don't care" about these more advanced features. */ uint16_t type; /** The size of the data portion of this event in bytes, which immediately * follows. The header size (12 bytes) is not included in this value. */ uint16_t size; /* size bytes of data follow here */ } LV2_Event; /** A buffer of LV2 events (header only). * * Like events (which this contains) an event buffer is a single chunk of POD: * the entire buffer (including contents) can be copied with a single memcpy. * The first contained event begins sizeof(LV2_EventBuffer) bytes after * the start of this struct. * * After this header, the buffer contains an event header (defined by struct * LV2_Event), followed by that event's contents (padded to 64 bits), followed by * another header, etc: * * | | | | | | | * | | | | | | | | | | | | | | | | | | | | | | | | | * |FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ... */ typedef struct { /** The contents of the event buffer. This may or may not reside in the * same block of memory as this header, plugins must not assume either. * The host guarantees this points to at least capacity bytes of allocated * memory (though only size bytes of that are valid events). */ uint8_t* data; /** The size of this event header in bytes (including everything). * * This is to allow for extending this header in the future without * breaking binary compatibility. Whenever this header is copied, * it MUST be done using this field (and NOT the sizeof this struct). */ uint16_t header_size; /** The type of the time stamps for events in this buffer. * As a special exception, '0' always means audio frames and subframes * (1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate. * INPUTS: The host must set this field to the numeric ID of some URI * defining the meaning of the frames/subframes fields of contained * events (obtained by the LV2 URI Map uri_to_id function with the URI * of this extension as the 'map' argument, see lv2_uri_map.h). * The host must never pass a plugin a buffer which uses a stamp type * the plugin does not 'understand'. The value of this field must * never change, except when connect_port is called on the input * port, at which time the host MUST have set the stamp_type field to * the value that will be used for all subsequent run calls. * OUTPUTS: The plugin may set this to any value that has been returned * from uri_to_id with the URI of this extension for a 'map' argument. * When connected to a buffer with connect_port, output ports MUST set * this field to the type of time stamp they will be writing. On any * call to connect_port on an event input port, the plugin may change * this field on any output port, it is the responsibility of the host * to check if any of these values have changed and act accordingly. */ uint16_t stamp_type; /** The number of events in this buffer. * INPUTS: The host must set this field to the number of events * contained in the data buffer before calling run(). * The plugin must not change this field. * OUTPUTS: The plugin must set this field to the number of events it * has written to the buffer before returning from run(). * Any initial value should be ignored by the plugin. */ uint32_t event_count; /** The size of the data buffer in bytes. * This is set by the host and must not be changed by the plugin. * The host is allowed to change this between run() calls. */ uint32_t capacity; /** The size of the initial portion of the data buffer containing data. * INPUTS: The host must set this field to the number of bytes used * by all events it has written to the buffer (including headers) * before calling the plugin's run(). * The plugin must not change this field. * OUTPUTS: The plugin must set this field to the number of bytes * used by all events it has written to the buffer (including headers) * before returning from run(). * Any initial value should be ignored by the plugin. */ uint32_t size; } LV2_Event_Buffer; /** Opaque pointer to host data. */ typedef void* LV2_Event_Callback_Data; /** The data field of the LV2_Feature for this extension. * * To support this feature the host must pass an LV2_Feature struct to the * plugin's instantiate method with URI "http://lv2plug.in/ns/ext/event" * and data pointed to an instance of this struct. */ typedef struct { /** Opaque pointer to host data. * * The plugin MUST pass this to any call to functions in this struct. * Otherwise, it must not be interpreted in any way. */ LV2_Event_Callback_Data callback_data; /** Take a reference to a non-POD event. * * If a plugin receives an event with type 0, it means the event is a * pointer to some object in memory and not a flat sequence of bytes * in the buffer. When receiving a non-POD event, the plugin already * has an implicit reference to the event. If the event is stored AND * passed to an output, lv2_event_ref MUST be called on that event. * If the event is only stored OR passed through, this is not necessary * (as the plugin already has 1 implicit reference). * * @param event An event received at an input that will not be copied to * an output or stored in any way. * @param context The calling context. (Like event types) this is a mapped * URI, see lv2_context.h. Simple plugin with just a run() * method should pass 0 here (the ID of the 'standard' LV2 * run context). The host guarantees that this function is * realtime safe iff @a context is realtime safe. * * PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS. */ uint32_t (*lv2_event_ref)(LV2_Event_Callback_Data callback_data, LV2_Event* event); /** Drop a reference to a non-POD event. * * If a plugin receives an event with type 0, it means the event is a * pointer to some object in memory and not a flat sequence of bytes * in the buffer. If the plugin does not pass the event through to * an output or store it internally somehow, it MUST call this function * on the event (more information on using non-POD events below). * * @param event An event received at an input that will not be copied to * an output or stored in any way. * @param context The calling context. (Like event types) this is a mapped * URI, see lv2_context.h. Simple plugin with just a run() * method should pass 0 here (the ID of the 'standard' LV2 * run context). The host guarantees that this function is * realtime safe iff @a context is realtime safe. * * PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS. */ uint32_t (*lv2_event_unref)(LV2_Event_Callback_Data callback_data, LV2_Event* event); } LV2_Event_Feature; #endif // LV2_EVENT_H slv2-0.6.6+dfsg1/hosts/jack_compat.h0000644000175000017500000000335311231361306017055 0ustar alessioalessio/* JACK MIDI API compatibility hacks. * Copyright (C) 2007 Nedko Arnaudov * * 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 * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef JACK_COMPAT_H #define JACK_COMPAT_H #if defined(JACK_MIDI_NEEDS_NFRAMES) jack_nframes_t jack_midi_get_event_count_compat( void * port_buffer) { #if defined(HAVE_OLD_JACK_MIDI) return jack_midi_port_get_info(port_buffer, 0)->event_count; #else return jack_midi_get_event_count(port_buffer, 0); #endif } #define jack_midi_get_event_count jack_midi_get_event_count_compat int jack_midi_event_get_compat( jack_midi_event_t * event, void * port_buffer, jack_nframes_t event_index) { return jack_midi_event_get(event, port_buffer, event_index, 0); } #define jack_midi_event_get jack_midi_event_get_compat void jack_midi_clear_buffer_compat( void * port_buffer) { jack_midi_clear_buffer(port_buffer, 0); } #define jack_midi_clear_buffer jack_midi_clear_buffer_compat #else #if defined(HAVE_OLD_JACK_MIDI) #error "Old (0.102.20) JACK MIDI API needs nframes (autotools probably gone mad)" #endif #endif /* #if defined(JACK_MIDI_NEEDS_NFRAMES) */ #endif /* JACK_COMPAT_H */ slv2-0.6.6+dfsg1/slv2/0000755000175000017500000000000011231361306014153 5ustar alessioalessioslv2-0.6.6+dfsg1/slv2/port.h0000644000175000017500000001171011231361306015310 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PORT_H__ #define __SLV2_PORT_H__ #ifdef __cplusplus extern "C" { #endif #include "slv2/types.h" #include "slv2/plugin.h" #include "slv2/port.h" #include "slv2/collections.h" /** \addtogroup slv2_data * @{ */ /** Port analog of slv2_plugin_get_value. * * Time = Query */ SLV2Values slv2_port_get_value(SLV2Plugin plugin, SLV2Port port, SLV2Value predicate); /** Port analog of slv2_plugin_get_value_by_qname. * * Time = Query */ SLV2Values slv2_port_get_value_by_qname(SLV2Plugin plugin, SLV2Port port, const char* property_uri); /** Port analog of slv2_plugin_get_value_by_qname_i18n. * * Time = Query */ SLV2Values slv2_port_get_value_by_qname_i18n(SLV2Plugin plugin, SLV2Port port, const char* property_uri); /** Return the LV2 port properties of a port. * * Time = Query */ SLV2Values slv2_port_get_properties(SLV2Plugin plugin, SLV2Port port); /** Return whether a port has a certain property. * * Time = Query */ bool slv2_port_has_property(SLV2Plugin p, SLV2Port port, SLV2Value property_uri); /** Return whether a port is an event port and supports a certain event type. * * Time = Query */ bool slv2_port_supports_event(SLV2Plugin p, SLV2Port port, SLV2Value event_uri); /** Get the symbol of a port. * * The 'symbol' is a short string, a valid C identifier. * Returned value is owned by \a port and must not be freed. * * Time = Query */ SLV2Value slv2_port_get_symbol(SLV2Plugin plugin, SLV2Port port); /** Get the name of a port. * * This is guaranteed to return the untranslated name (the doap:name in the * data file without a language tag). Returned value must be freed by * the caller. * * Time = Query */ SLV2Value slv2_port_get_name(SLV2Plugin plugin, SLV2Port port); /** Get all the classes of a port. * * This can be used to determine if a port is an input, output, audio, * control, midi, etc, etc, though it's simpler to use slv2_port_is_a. * The returned list does not include lv2:Port, which is implied. * * Returned value is shared and must not be destroyed by caller. * * Time = O(1) */ SLV2Values slv2_port_get_classes(SLV2Plugin plugin, SLV2Port port); /** Determine if a port is of a given class (input, output, audio, etc). * * For convenience/performance/extensibility reasons, hosts are expected to * create an SLV2Value for each port class they "care about". Well-known type * URI strings are defined (e.g. SLV2_PORT_CLASS_INPUT) for convenience, but * this function is designed so that SLV2 is usable with any port types * without requiring explicit support in SLV2. * * Time = O(n) (n pointer comparisons where n is the number of classes of * this port, so this method is suitable for realtime use on any sane port). */ bool slv2_port_is_a(SLV2Plugin plugin, SLV2Port port, SLV2Value port_class); /** Get the default, minimum, and maximum values of a port. * * @a def, @a min, and @a max are outputs, pass pointers to uninitialized * (i.e. NOT created with slv2_value_new) SLV2Value variables. These will * be set to point at new values (which must be freed by the caller using * slv2_value_free), or NULL if the value does not exist. * * Time = Query */ void slv2_port_get_range(SLV2Plugin plugin, SLV2Port port, SLV2Value* def, SLV2Value* min, SLV2Value* max); /** Get the scale points (enumeration values) of a port. * * This returns a collection of 'interesting' named values of a port * (e.g. appropriate entries for a UI selector associated with this port). * * Returned value may be NULL if @a port has no scale points, otherwise it * must be freed by caller with slv2_scale_points_free. */ SLV2ScalePoints slv2_port_get_scale_points(SLV2Plugin plugin, SLV2Port port); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_PORT_H__ */ slv2-0.6.6+dfsg1/slv2/scalepoint.h0000644000175000017500000000262611231361306016473 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_SCALE_POINT_H__ #define __SLV2_SCALE_POINT_H__ #ifdef __cplusplus extern "C" { #endif #include "slv2/types.h" /** \addtogroup slv2_data * @{ */ /** Get the label of this scale point (enumeration value) * * Returned value is owned by \a point and must not be freed. */ SLV2Value slv2_scale_point_get_label(SLV2ScalePoint point); /** Get the value of this scale point (enumeration value) * * Returned value is owned by \a point and must not be freed. */ SLV2Value slv2_scale_point_get_value(SLV2ScalePoint point); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_SCALE_POINT_H__ */ slv2-0.6.6+dfsg1/slv2/plugin.h0000644000175000017500000003225211231361306015626 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PLUGIN_H__ #define __SLV2_PLUGIN_H__ #ifdef __cplusplus extern "C" { #endif #include #include #include "slv2/types.h" #include "slv2/port.h" #include "slv2/collections.h" /** \defgroup slv2_data Plugin data access * * These functions work exclusively with the plugin's RDF data, * they do not access the plugin's shared library in any way. * * An SLV2Plugin contains an in-memory cache of the plugin data, loaded * on demand. Duplicating plugins should be avoided when possible for * performance reasons. * * @{ */ /** Check if this plugin is valid. * * This is used by plugin lists to avoid loading plugins that are not valid * and will not work with libslv2 (eg plugins missing required fields, or * having multiple values for mandatory single-valued fields, etc. * * Note that normal hosts do NOT need to use this - slv2 does not * load invalid plugins into plugin lists. This is included for plugin * testing utilities, etc. * * \return true if \a plugin is valid. * * Time = Query */ bool slv2_plugin_verify(SLV2Plugin plugin); /** Get the URI of \a plugin. * * Any serialization that refers to plugins should refer to them by this. * Hosts SHOULD NOT save any filesystem paths, plugin indexes, etc. in saved * files; save only the URI. * * The URI is a globally unique identifier for one specific plugin. Two * plugins with the same URI are compatible in port signature, and should * be guaranteed to work in a compatible and consistent way. If a plugin * is upgraded in an incompatible way (eg if it has different ports), it * MUST have a different URI than it's predecessor. * * \return a shared string which must not be modified or free()'d. * * Time = O(1) */ SLV2Value slv2_plugin_get_uri(SLV2Plugin plugin); /** Get the (resolvable) URI of the plugins "main" bundle. * * This returns the URI of the bundle where the plugin itself was found. * Note that the data for a plugin may be spread over many bundles, that is, * slv2_plugin_get_data_uris may returns URIs which are not below this one. * * Typical hosts should not need to use this function. * * Note this always returns a fully qualified URI. If you want a local * filesystem path, use slv2_uri_to_path. * * \return a shared string which must not be modified or freed. * * Time = O(1) */ SLV2Value slv2_plugin_get_bundle_uri(SLV2Plugin plugin); /** Get the (resolvable) URIs of the RDF data files that define a plugin. * * Typical hosts should not need to use this function. * * Note this always returns fully qualified URIs. If you want local * filesystem paths, use slv2_uri_to_path. * * \return a list of complete URLs eg. "file:///foo/ABundle.lv2/aplug.ttl", * which is shared and must not be modified or freed. * * Time = O(1) */ SLV2Values slv2_plugin_get_data_uris(SLV2Plugin plugin); /** Get the (resolvable) URI of the shared library for \a plugin. * * Note this always returns a fully qualified URI. If you want a local * filesystem path, use slv2_uri_to_path. * * \return a shared string which must not be modified or freed. * * Time = O(1) */ SLV2Value slv2_plugin_get_library_uri(SLV2Plugin plugin); /** Get the name of \a plugin. * * This is guaranteed to return the untranslated name (the doap:name in the * data file without a language tag). Returned value must be freed by * the caller. * * Time = Query */ SLV2Value slv2_plugin_get_name(SLV2Plugin plugin); /** Get the class this plugin belongs to (ie Filters). */ SLV2PluginClass slv2_plugin_get_class(SLV2Plugin plugin); /** Get a value associated with the plugin in a plugin's data files. * * Returns the ?object of all triples found of the form: * * <plugin-uri> predicate ?object * * May return NULL if the property was not found, or if object(s) is not * sensibly represented as an SLV2Values (e.g. blank nodes). * * Return value must be freed by caller with slv2_values_free. * * \a predicate must be either a URI or a QName. * See SLV2URIType documentation for examples. * * Time = Query */ SLV2Values slv2_plugin_get_value(SLV2Plugin p, SLV2Value predicate); /** Get a value associated with the plugin in a plugin's data files. * * This function is identical to slv2_plugin_get_value, but takes a QName * string parameter for a predicate instead of an SLV2Value, which may be * more convenient. */ SLV2Values slv2_plugin_get_value_by_qname(SLV2Plugin p, const char* predicate); /** Get a translated value associated with the plugin in a plugin's data files. * * This function is identical to slv2_plugin_get_value, but takes a QName * string parameter for a predicate instead of an SLV2Value, which may be * more convenient. It returns the value translated to the current language * if possible. */ SLV2Values slv2_plugin_get_value_by_qname_i18n(SLV2Plugin p, const char* predicate); /** Get a value associated with some subject in a plugin's data files. * * Returns the ?object of all triples found of the form: * * subject predicate ?object * * This can be used to investigate URIs returned by slv2_plugin_get_value * (if information about it is contained in the plugin's data files). * * May return NULL if the property was not found, or if object is not * sensibly represented as an SLV2Values (e.g. blank nodes). * * \a predicate must be either a URI or a QName. * See SLV2URIType documentation for examples. * * Return value must be freed by caller with slv2_values_free. * * Time = Query */ SLV2Values slv2_plugin_get_value_for_subject(SLV2Plugin p, SLV2Value subject_uri, SLV2Value predicate_uri); /** Return whether a feature is supported by a plugin. * * This will return true if the feature is an optional or required feature * of the plugin. * * Time = Query */ bool slv2_plugin_has_feature(SLV2Plugin p, SLV2Value feature_uri); /** Get the LV2 Features supported (required or optionally) by a plugin. * * A feature is "supported" by a plugin if it is required OR optional. * * Since required features have special rules the host must obey, this function * probably shouldn't be used by normal hosts. Using slv2_plugin_get_optional_features * and slv2_plugin_get_required_features separately is best in most cases. * * Returned value must be freed by caller with slv2_values_free. * * Time = Query */ SLV2Values slv2_plugin_get_supported_features(SLV2Plugin p); /** Get the LV2 Features required by a plugin. * * If a feature is required by a plugin, hosts MUST NOT use the plugin if they do not * understand (or are unable to support) that feature. * * All values returned here MUST be passed to the plugin's instantiate method * (along with data, if necessary, as defined by the feature specification) * or plugin instantiation will fail. * * Return value must be freed by caller with slv2_values_free. * * Time = Query */ SLV2Values slv2_plugin_get_required_features(SLV2Plugin p); /** Get the LV2 Features optionally supported by a plugin. * * Hosts MAY ignore optional plugin features for whatever reasons. Plugins * MUST operate (at least somewhat) if they are instantiated without being * passed optional features. * * Return value must be freed by caller with slv2_values_free. * * Time = Query */ SLV2Values slv2_plugin_get_optional_features(SLV2Plugin p); /** Get the number of ports on this plugin. * * Time = O(1) */ uint32_t slv2_plugin_get_num_ports(SLV2Plugin p); /** Get the port ranges (minimum, maximum and default values) for all ports. * * \a min_values, \a max_values and \a def_values must either point to an array * of N floats, where N is the value returned by slv2_plugin_get_num_ports() * for this plugin, or NULL. The elements of the array will be set to the * the minimum, maximum and default values of the ports on this plugin, * with array index corresponding to port index. If a port doesn't have a * minimum, maximum or default value, or the port's type is not float, the * corresponding array element will be set to NAN. * * This is a convenience method for the common case of getting the range of * all float ports on a plugin, and may be significantly faster than * repeated calls to slv2_port_get_range. */ void slv2_plugin_get_port_ranges_float(SLV2Plugin p, float* min_values, float* max_values, float* def_values); /** Get the number of ports on this plugin that are members of some class(es). * * Note that this is a varargs function so ports fitting any type 'profile' * desired can be found quickly. REMEMBER TO TERMINATE THE PARAMETER LIST * OF THIS FUNCTION WITH NULL OR VERY NASTY THINGS WILL HAPPEN. * * Time = O(1) */ uint32_t slv2_plugin_get_num_ports_of_class(SLV2Plugin p, SLV2Value class_1, ...); /** Return whether or not the plugin introduces (and reports) latency. * * The index of the latency port can be found with slv2_plugin_get_latency_port * ONLY if this function returns true. * * Time = Query */ bool slv2_plugin_has_latency(SLV2Plugin p); /** Return the index of the plugin's latency port. * * It is a fatal error to call this on a plugin without checking if the port * exists by first calling slv2_plugin_has_latency. * * Any plugin that introduces unwanted latency that should be compensated for * (by hosts with the ability/need) MUST provide this port, which is a control * rate output port that reports the latency for each cycle in frames. * * Time = Query */ uint32_t slv2_plugin_get_latency_port_index(SLV2Plugin p); /** Query a plugin for a single variable (i.e. SELECT a single ?value). * * \param plugin The plugin to query. * \param sparql_str A SPARQL SELECT query. * \param variable The index of the variable to return results for * (e.g. with "SELECT ?foo ?bar" foo=0, bar=1). * \return All matches for \a variable. * * Time = Query */ SLV2Values slv2_plugin_query_variable(SLV2Plugin plugin, const char* sparql_str, unsigned variable); /** Query a plugin and return the number of results found. * * Note that this function will work, but is mostly meaningless for queries * that are not SELECT DISTINCT. * * \param plugin The plugin to query. * \param sparql_str A SPARQL SELECT DISTINCT query. * * Time = Query */ unsigned slv2_plugin_query_count(SLV2Plugin plugin, const char* sparql_str); /** Get a port on this plugin by \a index. * * To perform multiple calls on a port, the returned value should * be cached and used repeatedly. * * Time = O(1) */ SLV2Port slv2_plugin_get_port_by_index(SLV2Plugin plugin, uint32_t index); /** Get a port on this plugin by \a symbol. * * To perform multiple calls on a port, the returned value should * be cached and used repeatedly. Note this function is slower * than slv2_plugin_get_port_by_index, especially on plugins * with a very large number of ports. * * Time = O(n) */ SLV2Port slv2_plugin_get_port_by_symbol(SLV2Plugin plugin, SLV2Value symbol); /** Get a list of all UIs available for this plugin. * * Note this returns the URI of the UI, and not the path/URI to its shared * library, use slv2_ui_get_library_uri with the values returned * here for that. * * Returned value must be freed by caller using slv2_uis_free. * * \param plugin The plugin to get the UIs for. * * Time = Query */ SLV2UIs slv2_plugin_get_uis(SLV2Plugin plugin); /** Get the full name of the plugin's author. * * Returns NULL if author name is not present. * Returned value must be freed by caller. * * Time = Query */ SLV2Value slv2_plugin_get_author_name(SLV2Plugin plugin); /** Get the email address of the plugin's author. * * Returns NULL if author email address is not present. * Returned value must be freed by caller. * * Time = Query */ SLV2Value slv2_plugin_get_author_email(SLV2Plugin plugin); /** Get the email address of the plugin's author. * * Returns NULL if author homepage is not present. * Returned value must be freed by caller. * * Time = Query */ SLV2Value slv2_plugin_get_author_homepage(SLV2Plugin plugin); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_PLUGIN_H__ */ slv2-0.6.6+dfsg1/slv2/types.h0000644000175000017500000000517411231361306015477 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_TYPES_H__ #define __SLV2_TYPES_H__ #ifdef __cplusplus extern "C" { #endif #include #include #define SLV2_NAMESPACE_LV2 "http://lv2plug.in/ns/lv2core#" #define SLV2_PORT_CLASS_PORT "http://lv2plug.in/ns/lv2core#Port" #define SLV2_PORT_CLASS_INPUT "http://lv2plug.in/ns/lv2core#InputPort" #define SLV2_PORT_CLASS_OUTPUT "http://lv2plug.in/ns/lv2core#OutputPort" #define SLV2_PORT_CLASS_CONTROL "http://lv2plug.in/ns/lv2core#ControlPort" #define SLV2_PORT_CLASS_AUDIO "http://lv2plug.in/ns/lv2core#AudioPort" #define SLV2_PORT_CLASS_EVENT "http://lv2plug.in/ns/ext/event#EventPort" #define SLV2_EVENT_CLASS_MIDI "http://lv2plug.in/ns/ext/midi#MidiEvent" /** A port on a plugin. Opaque, but valid to compare to NULL. */ typedef struct _SLV2Port* SLV2Port; /** A plugin. Opaque, but valid to compare to NULL. */ typedef struct _SLV2Plugin* SLV2Plugin; /** A collection of plugins. Opaque, but valid to compare to NULL. */ typedef void* SLV2Plugins; /** The world. Opaque, but valid to compare to NULL. */ typedef struct _SLV2World* SLV2World; /** A plugin class. Opaque, but valid to compare to NULL. */ typedef struct _SLV2PluginClass* SLV2PluginClass; /** A collection of plugin classes. Opaque, but valid to compare to NULL. */ typedef void* SLV2PluginClasses; /** A typed value */ typedef struct _SLV2Value* SLV2Value; /** A collection of typed values. */ typedef void* SLV2Values; /** A scale point */ typedef struct _SLV2ScalePoint* SLV2ScalePoint; /** A collection of scale points. */ typedef void* SLV2ScalePoints; /** A plugin UI */ typedef struct _SLV2UI* SLV2UI; /** A collection of plugin UIs. */ typedef void* SLV2UIs; /** A set of query results (conceptually a table) */ typedef struct _SLV2Results* SLV2Results; #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_TYPES_H__ */ slv2-0.6.6+dfsg1/slv2/plugininstance.h0000644000175000017500000001345111231361306017353 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PLUGININSTANCE_H__ #define __SLV2_PLUGININSTANCE_H__ #ifdef __cplusplus extern "C" { #endif #include #include #include "lv2.h" #include "slv2/plugin.h" #include "slv2/port.h" typedef struct _InstanceImpl* SLV2InstanceImpl; /** \cond IGNORE */ /* Instance of a plugin. * * The LV2 descriptor and handle of this are exposed to allow inlining of * performance critical functions like slv2_instance_run (which are exposed * in lv2.h anyway). This is for performance only, this struct is not * documented and should not be used directly. The remaining implementation * details are in the opaque pimpl member. */ typedef struct _Instance { const LV2_Descriptor* lv2_descriptor; LV2_Handle lv2_handle; SLV2InstanceImpl pimpl; ///< Private implementation }* SLV2Instance; /** \endcond */ /** \defgroup slv2_library Plugin library access * * An SLV2Instance is an instantiated SLV2Plugin (ie a loaded dynamic * library). These functions interact with the binary library code only, * they do not read data files in any way. * * @{ */ /** Instantiate a plugin. * * The returned object represents shared library objects loaded into memory, * it must be cleaned up with slv2_instance_free when no longer * needed. * * \a plugin is not modified or directly referenced by the returned object * (instances store only a copy of the plugin's URI). * * \a host_features NULL-terminated array of features the host supports. * NULL may be passed if the host supports no additional features (unlike * the LV2 specification - SLV2 takes care of it). * * \return NULL if instantiation failed. */ SLV2Instance slv2_plugin_instantiate(SLV2Plugin plugin, double sample_rate, const LV2_Feature*const* features); /** Free a plugin instance. * * \a instance is invalid after this call. */ void slv2_instance_free(SLV2Instance instance); #ifndef LIBSLV2_SOURCE /** Get the URI of the plugin which \a instance is an instance of. * * Returned string is shared and must not be modified or deleted. */ static inline const char* slv2_instance_get_uri(SLV2Instance instance) { return instance->lv2_descriptor->URI; } /** Connect a port to a data location. * * This may be called regardless of whether the plugin is activated, * activation and deactivation does not destroy port connections. */ static inline void slv2_instance_connect_port(SLV2Instance instance, uint32_t port_index, void* data_location) { instance->lv2_descriptor->connect_port (instance->lv2_handle, port_index, data_location); } /** Activate a plugin instance. * * This resets all state information in the plugin, except for port data * locations (as set by slv2_instance_connect_port). This MUST be called * before calling slv2_instance_run. */ static inline void slv2_instance_activate(SLV2Instance instance) { if (instance->lv2_descriptor->activate) instance->lv2_descriptor->activate(instance->lv2_handle); } /** Run \a instance for \a sample_count frames. * * If the hint lv2:hardRtCapable is set for this plugin, this function is * guaranteed not to block. */ static inline void slv2_instance_run(SLV2Instance instance, uint32_t sample_count) { /*if (instance->lv2_descriptor->run)*/ instance->lv2_descriptor->run(instance->lv2_handle, sample_count); } /** Deactivate a plugin instance. * * Note that to run the plugin after this you must activate it, which will * reset all state information (except port connections). */ static inline void slv2_instance_deactivate(SLV2Instance instance) { if (instance->lv2_descriptor->deactivate) instance->lv2_descriptor->deactivate(instance->lv2_handle); } /** Get extension data from the plugin instance. * * The type and semantics of the data returned is specific to the particular * extension, though in all cases it is shared and must not be deleted. */ static inline const void* slv2_instance_get_extension_data(SLV2Instance instance, const char* uri) { if (instance->lv2_descriptor->extension_data) return instance->lv2_descriptor->extension_data(uri); else return NULL; } /** Get the LV2_Descriptor of the plugin instance. * * Normally hosts should not need to access the LV2_Descriptor directly, * use the slv2_instance_* functions. * * The returned descriptor is shared and must not be deleted. */ static inline const LV2_Descriptor* slv2_instance_get_descriptor(SLV2Instance instance) { return instance->lv2_descriptor; } /** Get the LV2_Handle of the plugin instance. * * Normally hosts should not need to access the LV2_Handle directly, * use the slv2_instance_* functions. * * The returned handle is shared and must not be deleted. */ static inline LV2_Handle slv2_instance_get_handle(SLV2Instance instance) { return instance->lv2_handle; } #endif /* LIBSLV2_SOURCE */ /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_PLUGININSTANCE_H__ */ slv2-0.6.6+dfsg1/slv2/pluginui.h0000644000175000017500000000403011231361306016155 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PLUGIN_UI_H__ #define __SLV2_PLUGIN_UI_H__ #ifdef __cplusplus extern "C" { #endif /** \addtogroup slv2_data * @{ */ /** Get the URI of a Plugin UI. * * \param ui The Plugin UI * \return a shared value which must not be modified or freed. * * Time = O(1) */ SLV2Value slv2_ui_get_uri(SLV2UI ui); /** Get the types (URIs of RDF classes) of a Plugin UI. * * \param ui The Plugin UI * \return a shared value which must not be modified or freed. * * Time = O(1) */ SLV2Values slv2_ui_get_classes(SLV2UI ui); /** Check whether a plugin UI is a given type. * * \param ui The Plugin UI * \param class_uri The URI of the LV2 UI type to check this UI against * * Time = O(1) */ bool slv2_ui_is_a(SLV2UI ui, SLV2Value class_uri); /** Get the URI for a Plugin UI's bundle. * * \param ui The Plugin UI * \return a shared value which must not be modified or freed. * * Time = O(1) */ SLV2Value slv2_ui_get_bundle_uri(SLV2UI ui); /** Get the URI for a Plugin UI's shared library. * * \param ui The Plugin UI * \return a shared value which must not be modified or freed. * * Time = O(1) */ SLV2Value slv2_ui_get_binary_uri(SLV2UI ui); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_PLUGIN_UI_H__ */ slv2-0.6.6+dfsg1/slv2/pluginclass.h0000644000175000017500000000373111231361306016654 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PLUGIN_CLASS_H__ #define __SLV2_PLUGIN_CLASS_H__ #ifdef __cplusplus extern "C" { #endif #include "slv2/types.h" /** \addtogroup slv2_data * @{ */ /** Get the URI of this class' superclass. * * Returned value is owned by \a plugin_class and must not be freed by caller. * Returned value may be NULL, if class has no parent. * * Time = O(1) */ SLV2Value slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class); /** Get the URI of this plugin class. * * Returned value is owned by \a plugin_class and must not be freed by caller. * * Time = O(1) */ SLV2Value slv2_plugin_class_get_uri(SLV2PluginClass plugin_class); /** Get the label of this plugin class, ie "Oscillators". * * Returned value is owned by \a plugin_class and must not be freed by caller. * * Time = O(1) */ SLV2Value slv2_plugin_class_get_label(SLV2PluginClass plugin_class); /** Get the subclasses of this plugin class. * * Returned value must be freed by caller with slv2_plugin_classes_free. * * Time = O(nclasses) */ SLV2PluginClasses slv2_plugin_class_get_children(SLV2PluginClass plugin_class); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_PLUGIN_CLASS_H__ */ slv2-0.6.6+dfsg1/slv2/pluginuiinstance.h0000644000175000017500000000640211231361306017707 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PLUGINUIINSTANCE_H__ #define __SLV2_PLUGINUIINSTANCE_H__ #ifdef __cplusplus extern "C" { #endif #include #include "slv2/lv2_ui.h" #include "slv2/plugin.h" typedef struct _SLV2UIInstanceImpl* SLV2UIInstanceImpl; /* Instance of a plugin UI. * * All details are in hidden in the pimpl member to avoid making the * implementation a part of the ABI. */ typedef struct _SLV2UIInstance { SLV2UIInstanceImpl pimpl; ///< Private implementation }* SLV2UIInstance; /** \addtogroup slv2_library * @{ */ /** Instantiate a plugin UI. * * The returned object represents shared library objects loaded into memory, * it must be cleaned up with slv2_ui_instance_free when no longer * needed. * * \a plugin is not modified or directly referenced by the returned object * (instances store only a copy of the plugin's URI). * * \a host_features NULL-terminated array of features the host supports. * NULL may be passed if the host supports no additional features (unlike * the LV2 specification - SLV2 takes care of it). * * \return NULL if instantiation failed. */ SLV2UIInstance slv2_ui_instantiate(SLV2Plugin plugin, SLV2UI ui, LV2UI_Write_Function write_function, LV2UI_Controller controller, const LV2_Feature* const* features); /** Free a plugin UI instance. * * It is the caller's responsibility to ensure all references to the UI * instance (including any returned widgets) are cut before calling * this function. * * \a instance is invalid after this call. */ void slv2_ui_instance_free(SLV2UIInstance instance); /** Get the widget for the UI instance. */ LV2UI_Widget slv2_ui_instance_get_widget(SLV2UIInstance instance); /** Get the LV2UI_Descriptor of the plugin UI instance. * * Normally hosts should not need to access the LV2UI_Descriptor directly, * use the slv2_ui_instance_* functions. * * The returned descriptor is shared and must not be deleted. */ const LV2UI_Descriptor* slv2_ui_instance_get_descriptor(SLV2UIInstance instance); /** Get the LV2UI_Handle of the plugin UI instance. * * Normally hosts should not need to access the LV2UI_Handle directly, * use the slv2_ui_instance_* functions. * * The returned handle is shared and must not be deleted. */ LV2UI_Handle slv2_ui_instance_get_handle(SLV2UIInstance instance); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_PLUGINUIINSTANCE_H__ */ slv2-0.6.6+dfsg1/slv2/lv2_ui.h0000644000175000017500000004412511231361306015532 0ustar alessioalessio/************************************************************************ * * In-process UI extension for LV2 * * Copyright (C) 2006-2008 Lars Luthman * * Based on lv2.h, which was * * Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, * Stefan Westerfeld * Copyright (C) 2006 Steve Harris, Dave Robillard. * * This header is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, * or (at your option) any later version. * * This header is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA. * ***********************************************************************/ /** @file This extension defines an interface that can be used in LV2 plugins and hosts to create UIs for plugins. The UIs are plugins that reside in shared object files in an LV2 bundle and are referenced in the RDF data using the triples (Turtle shown)
    
    @@prefix uiext:  .
        uiext:ui      .
        a            uiext:GtkUI .
      uiext:binary  .
where is the URI of the plugin, is the URI of the plugin UI and is the relative URI to the shared object file. While it is possible to have the plugin UI and the plugin in the same shared object file it is probably a good idea to keep them separate so that hosts that don't want UIs don't have to load the UI code. A UI MUST specify its class in the RDF data, in this case uiext:GtkUI. The class defines what type the UI is, e.g. what graphics toolkit it uses. There are no UI classes defined in this extension, those are specified separately (and anyone can define their own). (Note: the prefix above is used throughout this file for the same URI) It's entirely possible to have multiple UIs for the same plugin, or to have the UI for a plugin in a different bundle from the actual plugin - this way people other than the plugin author can write plugin UIs independently without editing the original plugin bundle. Note that the process that loads the shared object file containing the UI code and the process that loads the shared object file containing the actual plugin implementation does not have to be the same. There are many valid reasons for having the plugin and the UI in different processes, or even on different machines. This means that you can _not_ use singletons and global variables and expect them to refer to the same objects in the UI and the actual plugin. The function callback interface defined in this header is all you can expect to work. Since the LV2 specification itself allows for extensions that may add new types of data and configuration parameters that plugin authors may want to control with a UI, this extension allows for meta-extensions that can extend the interface between the UI and the host. These extensions mirror the extensions used for plugins - there are required and optional "features" that you declare in the RDF data for the UI as
    
     uiext:requiredFeature  .
     uiext:optionalFeature  .
These predicates have the same semantics as lv2:requiredFeature and lv2:optionalFeature - if a UI is declaring a feature as required, the host is NOT allowed to load it unless it supports that feature, and if it does support a feature (required or optional) it MUST pass that feature's URI and any additional data (specified by the meta-extension that defines the feature) in a LV2_Feature struct (as defined in lv2.h) to the UI's instantiate() function. These features may be used to specify how to pass data between the UI and the plugin port buffers - see LV2UI_Write_Function for details. There are four features defined in this extension that hosts may want to implement:
    uiext:makeResident
If this feature is required by a UI the host MUST NEVER unload the shared library containing the UI implementation during the lifetime of the host process (e.g. never calling dlclose() on Linux). This feature may be needed by e.g. a Gtk UI that registers its own Glib types using g_type_register_static() - if it gets unloaded and then loaded again the type registration will break, since there is no way to unregister the types when the library is unloaded. The data pointer in the LV2_Feature for this feature should always be set to NULL.
    uiext:makeSONameResident
This feature is ELF specific - it should only be used by UIs that use the ELF file format for the UI shared object files (e.g. on Linux). If it is required by an UI the UI should also list a number of SO names (shared object names) for libraries that the UI shared object depends on and that may not be unloaded during the lifetime of the host process, using the predicate @c uiext:residentSONames, like this:
     uiext:residentSONames "libgtkmm-2.4.so.1", "libfoo.so.0"
The host MUST then make sure that the shared libraries with the given ELF SO names are not unloaded when the plugin UI is, but stay loaded during the entire lifetime of the host process. On Linux this can be accomplished by calling dlopen() on the shared library file with that SO name and never calling a matching dlclose(). However, if a plugin UI requires the @c uiext:makeSONameResident feature, it MUST ALWAYS be safe for the host to just never unload the shared object containing the UI implementation, i.e. act as if the UI required the @c uiext:makeResident feature instead. Thus the host only needs to find the shared library files corresponding to the given SO names if it wants to save RAM by unloading the UI shared object file when it is no longer needed. The data pointer for the LV2_Feature for this feature should always be set to NULL.
    uiext:noUserResize
If an UI requires this feature it indicates that it does not make sense to let the user resize the main widget, and the host should prevent that. This feature may not make sense for all UI types. The data pointer for the LV2_Feature for this feature should always be set to NULL.
    uiext:fixedSize
If an UI requires this feature it indicates the same thing as uiext:noUserResize, and additionally it means that the UI will not resize the main widget on its own - it will always remain the same size (e.g. a pixmap based GUI). This feature may not make sense for all UI types. The data pointer for the LV2_Feature for this feature should always be set to NULL. UIs written to this specification do not need to be threadsafe - the functions defined below may only be called in the same thread as the UI main loop is running in. Note that this UI extension is NOT a lv2:Feature. There is no way for a plugin to know whether the host that loads it supports UIs or not, and the plugin must ALWAYS work without the UI (although it may be rather useless unless it has been configured using the UI in a previous session). A UI does not have to be a graphical widget, it could just as well be a server listening for OSC input or an interface to some sort of hardware device, depending on the RDF class of the UI. */ #ifndef LV2_UI_H #define LV2_UI_H #include "lv2.h" #define LV2_UI_URI "http://lv2plug.in/ns/extensions/ui" #ifdef __cplusplus extern "C" { #endif /** A pointer to some widget or other type of UI handle. The actual type is defined by the type URI of the UI. All the functionality provided by this extension is toolkit independent, the host only needs to pass the necessary callbacks and display the widget, if possible. Plugins may have several UIs, in various toolkits. */ typedef void* LV2UI_Widget; /** This handle indicates a particular instance of a UI. It is valid to compare this to NULL (0 for C++) but otherwise the host MUST not attempt to interpret it. The UI plugin may use it to reference internal instance data. */ typedef void* LV2UI_Handle; /** This handle indicates a particular plugin instance, provided by the host. It is valid to compare this to NULL (0 for C++) but otherwise the UI plugin MUST not attempt to interpret it. The host may use it to reference internal plugin instance data. */ typedef void* LV2UI_Controller; /** This is the type of the host-provided function that the UI can use to send data to a plugin's input ports. The @c buffer parameter must point to a block of data, @c buffer_size bytes large. The contents of this buffer and what the host should do with it depends on the value of the @c format parameter. The @c format parameter should either be 0 or a numeric ID for a "Transfer mechanism". Transfer mechanisms are Features and may be defined in meta-extensions. They specify how to translate the data buffers passed to this function to input data for the plugin ports. If a UI wishes to write data to an input port, it must list a transfer mechanism Feature for that port's class as an optional or required feature (depending on whether the UI will work without being able to write to that port or not). The only exception is when the UI wants to write single float values to input ports of the class lv2:ControlPort, in which case @c buffer_size should always be 4, the buffer should always contain a single IEEE-754 float, and @c format should be 0. The numeric IDs for the transfer mechanisms are provided by a URI-to-integer mapping function provided by the host, using the URI Map feature with the map URI "http://lv2plug.in/ns/extensions/ui". Thus a UI that requires transfer mechanism features also requires the URI Map feature, but this is implicit - the UI does not have to list the URI map feature as a required or optional feature in it's RDF data. An UI MUST NOT pass a @c format parameter value (except 0) that has not been returned by the host-provided URI mapping function for a host-supported transfer mechanism feature URI. The UI MUST NOT try to write to a port for which there is no specified transfer mechanism, or to an output port. The UI is responsible for allocating the buffer and deallocating it after the call. */ typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer); /** This struct contains the implementation of an UI. A pointer to an object of this type is returned by the lv2ui_descriptor() function. */ typedef struct _LV2UI_Descriptor { /** The URI for this UI (not for the plugin it controls). */ const char* URI; /** Create a new UI object and return a handle to it. This function works similarly to the instantiate() member in LV2_Descriptor. @param descriptor The descriptor for the UI that you want to instantiate. @param plugin_uri The URI of the plugin that this UI will control. @param bundle_path The path to the bundle containing the RDF data file that references this shared object file, including the trailing '/'. @param write_function A function provided by the host that the UI can use to send data to the plugin's input ports. @param controller A handle for the plugin instance that should be passed as the first parameter of @c write_function. @param widget A pointer to an LV2UI_Widget. The UI will write a widget pointer to this location (what type of widget depends on the RDF class of the UI) that will be the main UI widget. @param features An array of LV2_Feature pointers. The host must pass all feature URIs that it and the UI supports and any additional data, just like in the LV2 plugin instantiate() function. Note that UI features and plugin features are NOT necessarily the same, they just share the same data structure - this will probably not be the same array as the one the plugin host passes to a plugin. */ LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor, const char* plugin_uri, const char* bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget* widget, const LV2_Feature* const* features); /** Destroy the UI object and the associated widget. The host must not try to access the widget after calling this function. */ void (*cleanup)(LV2UI_Handle ui); /** Tell the UI that something interesting has happened at a plugin port. What is interesting and how it is written to the buffer passed to this function is defined by the @c format parameter, which has the same meaning as in LV2UI_Write_Function. The only exception is ports of the class lv2:ControlPort, for which this function should be called when the port value changes (it does not have to be called for every single change if the host's UI thread has problems keeping up with the thread the plugin is running in), @c buffer_size should be 4 and the buffer should contain a single IEEE-754 float. In this case the @c format parameter should be 0. By default, the host should only call this function for input ports of the lv2:ControlPort class. However, the default setting can be modified by using the following URIs in the UI's RDF data:
      uiext:portNotification
      uiext:noPortNotification
      uiext:plugin
      uiext:portIndex
      
For example, if you want the UI with uri for the plugin with URI to get notified when the value of the output control port with index 4 changes, you would use the following in the RDF for your UI:
       uiext:portNotification [ uiext:plugin  ;
                                                      uiext:portIndex 4 ] .
      
and similarly with uiext:noPortNotification if you wanted to prevent notifications for a port for which it would be on by default otherwise. The UI is not allowed to request notifications for ports of types for which no transfer mechanism is specified, if it does it should be considered broken and the host should not load it. The @c buffer is only valid during the time of this function call, so if the UI wants to keep it for later use it has to copy the contents to an internal buffer. This member may be set to NULL if the UI is not interested in any port events. */ void (*port_event)(LV2UI_Handle ui, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer); /** Returns a data structure associated with an extension URI, for example a struct containing additional function pointers. Avoid returning function pointers directly since standard C++ has no valid way of casting a void* to a function pointer. This member may be set to NULL if the UI is not interested in supporting any extensions. This is similar to the extension_data() member in LV2_Descriptor. */ const void* (*extension_data)(const char* uri); } LV2UI_Descriptor; /** A plugin UI programmer must include a function called "lv2ui_descriptor" with the following function prototype within the shared object file. This function will have C-style linkage (if you are using C++ this is taken care of by the 'extern "C"' clause at the top of the file). This function will be accessed by the UI host using the @c dlsym() function and called to get a LV2UI_UIDescriptor for the wanted plugin. Just like lv2_descriptor(), this function takes an index parameter. The index should only be used for enumeration and not as any sort of ID number - the host should just iterate from 0 and upwards until the function returns NULL or a descriptor with an URI matching the one the host is looking for. */ const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); /** This is the type of the lv2ui_descriptor() function. */ typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index); #ifdef __cplusplus } #endif #endif slv2-0.6.6+dfsg1/slv2/world.h0000644000175000017500000001444611231361306015464 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_WORLD_H__ #define __SLV2_WORLD_H__ #ifdef __cplusplus extern "C" { #endif #include #include "slv2/collections.h" /** \defgroup slv2_world Global library state * * The "world" represents all library state, and the data found in bundles' * manifest.ttl (ie it is an in-memory index of all things LV2 found). * Plugins (and plugin extensions) and the LV2 specification (and LV2 * extensions) itself can be queried from the world for use. * * Normal hosts which just want to easily load plugins by URI are strongly * recommended to simply call \ref slv2_world_load_all to find all installed * data in the recommended way. * * Normal hosts should NOT have to refer to bundles directly under normal * circumstances. However, functions are provided to load individual bundles * explicitly, intended for hosts which depend on a specific bundle * (which is shipped with the application). * * @{ */ /** Initialize a new, empty world. * * If initialization fails, NULL is returned. */ SLV2World slv2_world_new(); /** Initialize a new, empty world, using an existing Redland context. */ SLV2World slv2_world_new_using_rdf_world(librdf_world* world); /** Destroy the world, mwahaha. * * NB: Destroying the world will leave dangling references in any plugin lists, * plugins, etc. Do not destroy the world until you are finished with all * objects that came from it. */ void slv2_world_free(SLV2World world); /** Load all installed LV2 bundles on the system. * * This is the recommended way for hosts to load LV2 data. It does the most * reasonable thing to find all installed plugins, extensions, etc. on the * system. The environment variable LV2_PATH may be used to set the * directories inside which this function will look for bundles. Otherwise * a sensible, standard default will be used. * * Use of other functions for loading bundles is \em highly discouraged * without a special reason to do so - use this one. * * Time = Query */ void slv2_world_load_all(SLV2World world); /** Load a specific bundle. * * \arg bundle_uri A fully qualified URI to the bundle directory, * with the trailing slash, eg. file:///usr/lib/lv2/someBundle/ * * Normal hosts should not use this function. * * Hosts should \b never attach any long-term significance to bundle paths * as there are no guarantees they will remain consistent whatsoever. * Plugins (and other things) are identified by URIs, \b not bundle or * file names. * * This function should only be used by apps which ship with a special * bundle (which it knows exists at some path because the bundle is * shipped with the application). * * Time = Query */ void slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri); /** Get the parent of all other plugin classes, lv2:Plugin. * * Time = O(1) */ SLV2PluginClass slv2_world_get_plugin_class(SLV2World world); /** Return a list of all found plugin classes. * * Returned list is owned by world and must not be freed by the caller. * * Time = O(1) */ SLV2PluginClasses slv2_world_get_plugin_classes(SLV2World world); /** Return a list of all found plugins. * * The returned list contains just enough references to query * or instantiate plugins. The data for a particular plugin will not be * loaded into memory until a call to an slv2_plugin_* function results in * a query (at which time the data is cached with the SLV2Plugin so future * queries are very fast). * * Returned list must be freed by user with slv2_plugins_free. The contained * plugins are owned by \a world and must not be freed by caller. * * Time = O(1) */ SLV2Plugins slv2_world_get_all_plugins(SLV2World world); /** Return a list of found plugins filtered by a user-defined filter function. * * All plugins currently found in \a world that return true when passed to * \a include (a pointer to a function which takes an SLV2Plugin and returns * a bool) will be in the returned list. * * Returned list must be freed by user with slv2_plugins_free. The contained * plugins are owned by \a world and must not be freed by caller. * * Time = O(n * Time(include)) */ SLV2Plugins slv2_world_get_plugins_by_filter(SLV2World world, bool (*include)(SLV2Plugin)); #if 0 /** Return a list of found plugins in a given class. * * Returned list must be freed by user with slv2_plugins_free. The contained * plugins are owned by \a world and must not be freed by caller. * * Time = O(n) */ SLV2Plugins slv2_world_get_plugins_by_class(SLV2World world, SLV2PluginClass plugin_class); #endif #if 0 /** Get plugins filtered by a user-defined SPARQL query. * * This is much faster than using slv2_world_get_plugins_by_filter with a * filter function which calls the various slv2_plugin_* functions. * * \param query A valid SPARQL query which SELECTs a single variable, which * should match the URI of plugins to be loaded. * * \b Example: Get all plugins with at least 1 audio input and output: \verbatim PREFIX : SELECT DISTINCT ?plugin WHERE { ?plugin :port [ a :AudioPort; a :InputPort ] ; :port [ a :AudioPort; a :OutputPort ] . } \endverbatim * * Returned plugins contain a reference to this world, world must not be * destroyed until plugins are finished with. */ SLV2Plugins slv2_world_get_plugins_by_query(SLV2World world, const char* query); #endif /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_WORLD_H__ */ slv2-0.6.6+dfsg1/slv2/collections.h0000644000175000017500000001105711231361306016646 0ustar alessioalessio/* SLV2 * Copyright (C) 2008-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_PLUGINS_H__ #define __SLV2_PLUGINS_H__ #ifdef __cplusplus extern "C" { #endif #include "slv2/types.h" #include "slv2/value.h" /** \defgroup slv2_collections Collections of values/objects * * Ordered collections of typed values which are fast for random * access by index (i.e. a fancy array). * * @{ */ /* **** GENERIC COLLECTION FUNCTIONS **** */ #define SLV2_COLLECTION(CollType, ElemType, prefix) \ \ /** Free a collection. * * Time = O(1) */ \ void \ prefix ## _free(CollType collection); \ \ \ /** Get the number of elements in the collection. * * Time = O(1) */ \ unsigned \ prefix ## _size(CollType collection); \ \ \ /** Get an element from the collection by index. * * \a index has no significance other than as an index into this collection. * Any \a index not less than the size of the collection will return NULL, * so all elements in a collection can be enumerated by repeated calls * to this function starting with \a index = 0. * * Time = O(1) * * \return NULL if \a index out of range. */ \ ElemType \ prefix ## _get_at(CollType collection, \ unsigned index); SLV2_COLLECTION(SLV2PluginClasses, SLV2PluginClass, slv2_plugin_classes) SLV2_COLLECTION(SLV2ScalePoints, SLV2ScalePoint, slv2_scale_points) SLV2_COLLECTION(SLV2Values, SLV2Value, slv2_values) SLV2_COLLECTION(SLV2UIs, SLV2UI, slv2_uis) /* **** PLUGINS **** */ /** Free a plugin collection. * * Freeing a plugin collection does not destroy the plugins it contains * (plugins are owned by the world). \a plugins is invalid after this call. * Time = O(1) */ void slv2_plugins_free(SLV2World world, SLV2Plugins plugins); /** Get the number of plugins in the collection. * Time = O(1) */ unsigned slv2_plugins_size(SLV2Plugins plugins); /** Get a plugin from the collection by URI. * * Return value is shared (stored in \a plugins) and must not be freed or * modified by the caller in any way. * * Time = O(log2(n)) * * \return NULL if plugin with \a url not found in \a plugins. */ SLV2Plugin slv2_plugins_get_by_uri(SLV2Plugins plugins, SLV2Value uri); /** Get a plugin from the plugins by index. * * \a index has no significance other than as an index into this plugins. * Any \a index not less than slv2_plugins_get_length(plugins) will return NULL, * so all plugins in a plugins can be enumerated by repeated calls * to this function starting with \a index = 0. * * Time = O(1) * * \return NULL if \a index out of range. */ SLV2Plugin slv2_plugins_get_at(SLV2Plugins plugins, unsigned index); /* **** PLUGIN CLASSES **** */ /** Get a plugin class from the collection by URI. * * Return value is shared (stored in \a classes) and must not be freed or * modified by the caller in any way. * * Time = O(log2(n)) * * \return NULL if plugin with \a url not found in \a classes. */ SLV2PluginClass slv2_plugin_classes_get_by_uri(SLV2PluginClasses classes, SLV2Value uri); /* **** SCALE POINTS **** */ /** Allocate a new, empty SLV2ScalePoints */ SLV2ScalePoints slv2_scale_points_new(); /* **** VALUES **** */ /** Allocate a new, empty SLV2Values */ SLV2Values slv2_values_new(); /** Return whether \a values contains \a value. * * Time = O(n) */ bool slv2_values_contains(SLV2Values values, SLV2Value value); /* **** PLUGIN UIS **** */ /** Get a plugin from the list by URI. * * Return value is shared (stored in \a list) and must not be freed or * modified by the caller in any way. * * Time = O(log2(n)) * * \return NULL if plugin with \a url not found in \a list. */ SLV2UI slv2_uis_get_by_uri(SLV2UIs list, SLV2Value uri); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_COLLECTIONS_H__ */ slv2-0.6.6+dfsg1/slv2/util.h0000644000175000017500000000246711231361306015312 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_UTIL_H__ #define __SLV2_UTIL_H__ #ifdef __cplusplus extern "C" { #endif #include /** \defgroup slv2_util Utility functions * * @{ */ /** Convert a full URI (eg file://foo/bar/baz.ttl) to a local path (e.g. /foo/bar/baz.ttl). * * Return value is shared and must not be deleted by caller. * \return \a uri converted to a path, or NULL on failure (URI is not local). */ const char* slv2_uri_to_path(const char* uri); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_UTIL_H__ */ slv2-0.6.6+dfsg1/slv2/query.h0000644000175000017500000000527511231361306015502 0ustar alessioalessio/* SLV2 * Copyright (C) 2008-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_QUERY_H__ #define __SLV2_QUERY_H__ #ifdef __cplusplus extern "C" { #endif /** \addtogroup slv2_data * @{ */ /** Query a plugin with an arbitrary SPARQL string. */ SLV2Results slv2_plugin_query_sparql(SLV2Plugin plugin, const char* sparql_str); /** Free query results. */ void slv2_results_free(SLV2Results results); /** Return the number of matches in \a results. * Note this should not be used to iterate over a result set (since it will * iterate to the end of \a results and rewinding is impossible). * Instead, use slv2_results_next and slv2_results_finished repeatedly. */ unsigned slv2_results_size(SLV2Results results); /** Return true iff the end of \a results has been reached. */ bool slv2_results_finished(SLV2Results results); /** Return a binding in \a results by index. * Indices correspond to selected variables in the query in order of appearance. * Returned value must be freed by caller with slv2_value_free. * \return NULL if binding value can not be expressed as an SLV2Value. */ SLV2Value slv2_results_get_binding_value(SLV2Results results, unsigned index); /** Return a binding in \a results by name. * \a name corresponds to the name of the SPARQL variable (without the '?'). * Returned value must be freed by caller with slv2_value_free. * \return NULL if binding value can not be expressed as an SLV2Value. */ SLV2Value slv2_results_get_binding_value_by_name(SLV2Results results, const char* name); /** Return the name of a binding in \a results. * Returned value is shared and must not be freed by caller. * Indices correspond to selected variables in the query in order of appearance. */ const char* slv2_results_get_binding_name(SLV2Results results, unsigned index); /** Increment \a results to the next match. */ void slv2_results_next(SLV2Results results); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_QUERY_H__ */ slv2-0.6.6+dfsg1/slv2/value.h0000644000175000017500000001037311231361306015444 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_VALUE_H__ #define __SLV2_VALUE_H__ #ifdef __cplusplus extern "C" { #endif #include #include "slv2/types.h" /** \addtogroup slv2_data * @{ */ /** Create a new URI value. * * Returned value must be freed by caller with slv2_value_free. */ SLV2Value slv2_value_new_uri(SLV2World world, const char* uri); /** Create a new string value (with no language). * * Returned value must be freed by caller with slv2_value_free. */ SLV2Value slv2_value_new_string(SLV2World world, const char* str); /** Create a new integer value. * * Returned value must be freed by caller with slv2_value_free. */ SLV2Value slv2_value_new_int(SLV2World world, int val); /** Create a new floating point value. * * Returned value must be freed by caller with slv2_value_free. */ SLV2Value slv2_value_new_float(SLV2World world, float val); /** Free an SLV2Value. */ void slv2_value_free(SLV2Value val); /** Duplicate an SLV2Value. */ SLV2Value slv2_value_duplicate(SLV2Value val); /** Return whether two values are equivalent. */ bool slv2_value_equals(SLV2Value value, SLV2Value other); /** Return this value as a Turtle/SPARQL token. * Examples: * * doap:name * "this is a string" * 1.0 * 1 * * Returned string is newly allocated and must be freed by caller. */ char* slv2_value_get_turtle_token(SLV2Value value); /** Return whether the value is a URI (resource). * * Time = O(1) */ bool slv2_value_is_uri(SLV2Value value); /** Return this value as a URI string, e.g. "http://example.org/foo". * * Valid to call only if slv2_value_is_uri(\a value) returns true. * Returned value is owned by \a value and must not be freed by caller. * * Time = O(1) */ const char* slv2_value_as_uri(SLV2Value value); #if 0 /** Return whether the value is a QName ("qualified name", a prefixed URI). * * A QName will return true for both this, and slv2_value_is_uri. * slv2_value_as_uri and slv2_value_as_qname will both return appropriately. * * Time = O(1) */ bool slv2_value_is_qname(SLV2Value value); /** Return this value as a QName string, e.g. "lv2:Plugin". * * Valid to call only if slv2_value_is_qname(\a value) returns true. * Returned value is owned by \a value and must not be freed by caller. * * Time = O(1) */ const char* slv2_value_as_qname(SLV2Value value); #endif /** Return whether this value is a literal (i.e. not a URI). * * Returns true if \a value is a string or numeric value. * * Time = O(1) */ bool slv2_value_is_literal(SLV2Value value); /** Return whether this value is a string literal. * * Returns true if \a value is a string (but not numeric) value. * * Time = O(1) */ bool slv2_value_is_string(SLV2Value value); /** Return \a value as a string. * * Time = O(1) */ const char* slv2_value_as_string(SLV2Value value); /** Return whether this value is a decimal literal. * * Time = O(1) */ bool slv2_value_is_float(SLV2Value value); /** Return \a value as a float. * * Valid to call only if slv2_value_is_float(\a value) or * slv2_value_is_int(\a value) returns true. * * Time = O(1) */ float slv2_value_as_float(SLV2Value value); /** Return whether this value is an integer literal. * * Time = O(1) */ bool slv2_value_is_int(SLV2Value value); /** Return \a value as an integer. * * Valid to call only if slv2_value_is_int(\a value) returns true. * * Time = O(1) */ int slv2_value_as_int(SLV2Value value); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_VALUE_H__ */ slv2-0.6.6+dfsg1/slv2/slv2.h0000644000175000017500000000241611231361306015215 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_H__ #define __SLV2_H__ #ifdef __cplusplus extern "C" { #endif #include "slv2/collections.h" #include "slv2/plugin.h" #include "slv2/pluginclass.h" #include "slv2/plugininstance.h" #include "slv2/pluginui.h" #include "slv2/pluginuiinstance.h" #include "slv2/port.h" #include "slv2/query.h" #include "slv2/scalepoint.h" #include "slv2/types.h" #include "slv2/util.h" #include "slv2/value.h" #include "slv2/world.h" #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __SLV2_H__ */ slv2-0.6.6+dfsg1/waf0000755000175000017500000000745111703115001013770 0ustar alessioalessio#!/usr/bin/env python # encoding: utf-8 # Thomas Nagy, 2005-2009 """ 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 name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS 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 THE AUTHOR 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. """ import os, sys if sys.hexversion<0x203000f: raise ImportError("Waf requires Python >= 2.3") if 'PSYCOWAF' in os.environ: try:import psyco;psyco.full() except:pass VERSION="1.5.6" REVISION="372ed0a3b8b521cebd3292e2fc45ec1c" INSTALL='' C1='#+' C2='#*' cwd = os.getcwd() join = os.path.join WAF='waf' def b(x): return x if sys.hexversion>0x300000f: WAF='waf3' def b(x): return x.encode() def err(m): print(('\033[91mError: %s\033[0m' % m)) sys.exit(1) def unpack_wafdir(dir): f = open(sys.argv[0],'rb') c = "corrupted waf (%d)" while 1: line = f.readline() if not line: err("run waf-light from a folder containing wafadmin") if line == b('#==>\n'): txt = f.readline() if not txt: err(c % 1) if f.readline()!=b('#<==\n'): err(c % 2) break if not txt: err(c % 3) txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')) import shutil, tarfile try: shutil.rmtree(dir) except OSError: pass try: os.makedirs(join(dir, 'wafadmin', 'Tools')) except OSError: err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir) os.chdir(dir) tmp = 't.tbz2' t = open(tmp,'wb') t.write(txt) t.close() try: t = tarfile.open(tmp) for x in t: t.extract(x) t.close() except: os.chdir(cwd) try: shutil.rmtree(dir) except OSError: pass err("Waf cannot be unpacked, check that bzip2 support is present") os.chmod(join('wafadmin','Tools'), 493) os.unlink(tmp) if sys.hexversion>0x300000f: sys.path = [join(dir, 'wafadmin')] + sys.path import py3kfixes py3kfixes.fixdir(dir) os.chdir(cwd) def test(dir): try: os.stat(join(dir, 'wafadmin')); return os.path.abspath(dir) except OSError: pass def find_lib(): name = sys.argv[0] base = os.path.dirname(os.path.abspath(name)) #devs use $WAFDIR w=test(os.environ.get('WAFDIR', '')) if w: return w #waf-light if name.endswith('waf-light'): w = test(base) if w: return w err("waf-light requires wafadmin -> export WAFDIR=/folder") dir = "/lib/%s-%s-%s/" % (WAF, VERSION, REVISION) for i in [INSTALL,'/usr','/usr/local','/opt']: w = test(i+dir) if w: return w #waf-local s = '.%s-%s-%s' if sys.platform == 'win32': s = s[1:] dir = join(base, s % (WAF, VERSION, REVISION)) w = test(dir) if w: return w #unpack unpack_wafdir(dir) return dir wafdir = find_lib() w = join(wafdir, 'wafadmin') t = join(w, 'Tools') sys.path = [w, t] + sys.path import Scripting Scripting.prepare(t, cwd, VERSION, wafdir) sys.exit(0) slv2-0.6.6+dfsg1/slv2.pc.in0000644000175000017500000000042411231361306015104 0ustar alessioalessioprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libslv2 Version: @SLV2_VERSION@ Description: Convenience library for hosts to simplify LV2 plugin support Libs: @REDLAND_LIBS@ -L${libdir} -lslv2 Cflags: @REDLAND_CFLAGS@ -I${includedir} slv2-0.6.6+dfsg1/src/0000755000175000017500000000000011231361306014054 5ustar alessioalessioslv2-0.6.6+dfsg1/src/port.c0000644000175000017500000002051311231361306015205 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/types.h" #include "slv2/collections.h" #include "slv2/port.h" #include "slv2/query.h" #include "slv2/util.h" #include "slv2_internal.h" /* private */ SLV2Port slv2_port_new(SLV2World world, uint32_t index, const char* symbol) { struct _SLV2Port* port = malloc(sizeof(struct _SLV2Port)); port->index = index; port->symbol = slv2_value_new(world, SLV2_VALUE_STRING, symbol); port->classes = slv2_values_new(); //port->node_id = strdup(node_id); return port; } /* private */ void slv2_port_free(SLV2Port port) { slv2_values_free(port->classes); slv2_value_free(port->symbol); free(port); } /* private */ #if 0 SLV2Port slv2_port_duplicate(SLV2Port port) { SLV2Port ret = malloc(sizeof(struct _SLV2Port)); ret->index = port->index; ret->symbol = slv2_value_duplicate(port->symbol); return ret; } #endif bool slv2_port_is_a(SLV2Plugin plugin, SLV2Port port, SLV2Value port_class) { for (unsigned i=0; i < slv2_values_size(port->classes); ++i) if (slv2_value_equals(slv2_values_get_at(port->classes, i), port_class)) return true; return false; } bool slv2_port_has_property(SLV2Plugin p, SLV2Port port, SLV2Value property) { assert(property); char* query = slv2_strjoin( "SELECT DISTINCT ?port WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ." "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n", " lv2:portProperty <", slv2_value_as_uri(property), "> .\n}", NULL); SLV2Values results = slv2_plugin_query_variable(p, query, 0); const bool ret = (slv2_values_size(results) > 0); slv2_values_free(results); free(query); return ret; } bool slv2_port_supports_event(SLV2Plugin p, SLV2Port port, SLV2Value event) { assert(event); char* query = slv2_strjoin( "ASK WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ." "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n", " lv2ev:supportsEvent <", slv2_value_as_uri(event), "> .\n" "}", NULL); SLV2Results results = slv2_plugin_query_sparql(p, query); assert(librdf_query_results_is_boolean(results->rdf_results)); const bool ret = librdf_query_results_get_boolean(results->rdf_results); free(query); slv2_results_free(results); return ret; } SLV2Values slv2_port_get_value_by_qname(SLV2Plugin p, SLV2Port port, const char* property) { assert(property); SLV2Values results = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", property, " ?value .\n" "FILTER(lang(?value) = \"\") }", NULL); results = slv2_plugin_query_variable(p, query, 0); free(query); return results; } SLV2Values slv2_port_get_value(SLV2Plugin p, SLV2Port port, SLV2Value predicate) { char* query = NULL; /* Hack around broken RASQAL, full URI predicates don't work :/ */ query = slv2_strjoin( "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">", "SELECT DISTINCT ?value WHERE { \n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", " slv2predicate: ?value .\n" "}\n", NULL); SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); return result; } SLV2Values slv2_port_get_value_by_qname_i18n(SLV2Plugin p, SLV2Port port, const char* property) { assert(property); SLV2Values results = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", property, " ?value .\n" "FILTER(lang(?value) = \"", slv2_get_lang(), "\") }", NULL); results = slv2_plugin_query_variable(p, query, 0); free(query); return results; } SLV2Value slv2_port_get_symbol(SLV2Plugin p, SLV2Port port) { return port->symbol; } SLV2Value slv2_port_get_name(SLV2Plugin p, SLV2Port port) { SLV2Value ret = NULL; SLV2Values results = slv2_port_get_value_by_qname_i18n(p, port, "lv2:name"); if (results && slv2_values_size(results) > 0) { ret = slv2_value_duplicate(slv2_values_get_at(results, 0)); } else { results = slv2_port_get_value_by_qname(p, port, "lv2:name"); if (results && slv2_values_size(results) > 0) ret = slv2_value_duplicate(slv2_values_get_at(results, 0)); } slv2_values_free(results); return ret; } SLV2Values slv2_port_get_classes(SLV2Plugin p, SLV2Port port) { return port->classes; } void slv2_port_get_range(SLV2Plugin p, SLV2Port port, SLV2Value* def, SLV2Value* min, SLV2Value* max) { if (def) *def = NULL; if (min) *min = NULL; if (max) *max = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?def ?min ?max WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\".\n", "OPTIONAL { ?port lv2:default ?def }\n", "OPTIONAL { ?port lv2:minimum ?min }\n", "OPTIONAL { ?port lv2:maximum ?max }\n", "\n}", NULL); SLV2Results results = slv2_plugin_query_sparql(p, query); while (!librdf_query_results_finished(results->rdf_results)) { librdf_node* def_node = librdf_query_results_get_binding_value(results->rdf_results, 0); librdf_node* min_node = librdf_query_results_get_binding_value(results->rdf_results, 1); librdf_node* max_node = librdf_query_results_get_binding_value(results->rdf_results, 2); if (def && def_node && !*def) *def = slv2_value_new_librdf_node(p->world, def_node); if (min && min_node && !*min) *min = slv2_value_new_librdf_node(p->world, min_node); if (max && max_node && !*max) *max = slv2_value_new_librdf_node(p->world, max_node); if ((!def || *def) && (!min || *min) && (!max || *max)) break; librdf_query_results_next(results->rdf_results); } slv2_results_free(results); free(query); } SLV2ScalePoints slv2_port_get_scale_points(SLV2Plugin p, SLV2Port port) { char* query = slv2_strjoin( "SELECT DISTINCT ?value ?label WHERE {\n" "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\" ;\n", " lv2:scalePoint ?point .\n" "?point rdf:value ?value ;\n" " rdfs:label ?label .\n" "\n} ORDER BY ?value", NULL); SLV2Results results = slv2_plugin_query_sparql(p, query); SLV2ScalePoints ret = NULL; if (!slv2_results_finished(results)) ret = slv2_scale_points_new(); while (!slv2_results_finished(results)) { SLV2Value value = slv2_results_get_binding_value(results, 0); SLV2Value label = slv2_results_get_binding_value(results, 1); if (value && label) raptor_sequence_push(ret, slv2_scale_point_new(value, label)); slv2_results_next(results); } slv2_results_free(results); free(query); assert(!ret || slv2_values_size(ret) > 0); return ret; } SLV2Values slv2_port_get_properties(SLV2Plugin p, SLV2Port port) { return slv2_port_get_value_by_qname(p, port, "lv2:portProperty"); } slv2-0.6.6+dfsg1/src/pluginuiinstance.c0000644000175000017500000001047011231361306017603 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * Author: Lars Luthman * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/types.h" #include "slv2/plugin.h" #include "slv2/pluginui.h" #include "slv2/pluginuiinstance.h" #include "slv2/util.h" #include "slv2_internal.h" SLV2UIInstance slv2_ui_instantiate(SLV2Plugin plugin, SLV2UI ui, LV2UI_Write_Function write_function, LV2UI_Controller controller, const LV2_Feature* const* features) { struct _SLV2UIInstance* result = NULL; bool local_features = (features == NULL); if (local_features) { features = malloc(sizeof(LV2_Feature)); ((LV2_Feature**)features)[0] = NULL; } const char* const lib_uri = slv2_value_as_string(slv2_ui_get_binary_uri(ui)); const char* const lib_path = slv2_uri_to_path(lib_uri); if (!lib_path) return NULL; dlerror(); void* lib = dlopen(lib_path, RTLD_NOW); if (!lib) { fprintf(stderr, "Unable to open UI library %s (%s)\n", lib_path, dlerror()); return NULL; } LV2UI_DescriptorFunction df = dlsym(lib, "lv2ui_descriptor"); if (!df) { fprintf(stderr, "Could not find symbol 'lv2ui_descriptor', " "%s is not a LV2 plugin UI.\n", lib_path); dlclose(lib); return NULL; } else { const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri(slv2_ui_get_bundle_uri(ui))); for (uint32_t i=0; 1; ++i) { const LV2UI_Descriptor* ld = df(i); if (!ld) { fprintf(stderr, "Did not find UI %s in %s\n", slv2_value_as_uri(slv2_ui_get_uri(ui)), lib_path); dlclose(lib); break; // return NULL } else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_ui_get_uri(ui)))) { assert(plugin->plugin_uri); printf("Found UI %s at index %u in:\n\t%s\n\n", slv2_value_as_uri(plugin->plugin_uri), i, lib_path); assert(ld->instantiate); // Create SLV2UIInstance to return result = malloc(sizeof(struct _SLV2UIInstance)); struct _SLV2UIInstanceImpl* impl = malloc(sizeof(struct _SLV2UIInstanceImpl)); impl->lv2ui_descriptor = ld; impl->lv2ui_handle = ld->instantiate(ld, slv2_value_as_uri(slv2_plugin_get_uri(plugin)), (char*)bundle_path, write_function, controller, &impl->widget, features); impl->lib_handle = lib; result->pimpl = impl; break; } } } // Failed to instantiate if (result == NULL || result->pimpl->lv2ui_handle == NULL) { //printf("Failed to instantiate %s\n", plugin->plugin_uri); free(result); return NULL; } // Failed to create a widget, but still got a handle - this means that // the plugin is buggy if (result->pimpl->widget == NULL) { slv2_ui_instance_free(result); return NULL; } if (local_features) free((LV2_Feature**)features); return result; } void slv2_ui_instance_free(SLV2UIInstance instance) { if (instance == NULL) return; struct _SLV2UIInstance* i = (struct _SLV2UIInstance*)instance; i->pimpl->lv2ui_descriptor->cleanup(i->pimpl->lv2ui_handle); i->pimpl->lv2ui_descriptor = NULL; dlclose(i->pimpl->lib_handle); i->pimpl->lib_handle = NULL; free(i->pimpl); i->pimpl = NULL; free(i); } LV2UI_Widget slv2_ui_instance_get_widget(SLV2UIInstance instance) { return instance->pimpl->widget; } const LV2UI_Descriptor* slv2_ui_instance_get_descriptor(SLV2UIInstance instance) { return instance->pimpl->lv2ui_descriptor; } LV2UI_Handle slv2_ui_instance_get_handle(SLV2UIInstance instance) { return instance->pimpl->lv2ui_handle; } slv2-0.6.6+dfsg1/src/plugin.c0000644000175000017500000005070011231361306015520 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/types.h" #include "slv2/collections.h" #include "slv2/plugin.h" #include "slv2/pluginclass.h" #include "slv2/query.h" #include "slv2/util.h" #include "slv2_internal.h" /* private * ownership of uri is taken */ SLV2Plugin slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri) { assert(bundle_uri); struct _SLV2Plugin* plugin = malloc(sizeof(struct _SLV2Plugin)); plugin->world = world; plugin->plugin_uri = uri; plugin->bundle_uri = slv2_value_new_librdf_uri(world, bundle_uri); plugin->binary_uri = NULL; plugin->plugin_class = NULL; plugin->data_uris = slv2_values_new(); plugin->ports = NULL; plugin->storage = NULL; plugin->rdf = NULL; return plugin; } /* private */ void slv2_plugin_free(SLV2Plugin p) { slv2_value_free(p->plugin_uri); p->plugin_uri = NULL; slv2_value_free(p->bundle_uri); p->bundle_uri = NULL; slv2_value_free(p->binary_uri); p->binary_uri = NULL; if (p->ports) raptor_free_sequence(p->ports); p->ports = NULL; if (p->rdf) { librdf_free_model(p->rdf); p->rdf = NULL; } if (p->storage) { librdf_free_storage(p->storage); p->storage = NULL; } slv2_values_free(p->data_uris); p->data_uris = NULL; free(p); } /** comparator for sorting */ #if 0 static int slv2_port_compare_by_index(const void* a, const void* b) { SLV2Port port_a = *(SLV2Port*)a; SLV2Port port_b = *(SLV2Port*)b; if (port_a->index < port_b->index) return -1; else if (port_a->index == port_b->index) return 0; else //if (port_a->index > port_b->index) return 1; } #endif /* private */ void slv2_plugin_load_if_necessary(SLV2Plugin p) { if (!p->rdf) slv2_plugin_load(p); } /* private */ void slv2_plugin_load_ports_if_necessary(SLV2Plugin p) { if (!p->rdf) slv2_plugin_load(p); if (!p->ports) { p->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL); const unsigned char* query = (const unsigned char*) "PREFIX : \n" "SELECT DISTINCT ?type ?symbol ?index WHERE {\n" "<> :port ?port .\n" "?port a ?type ;\n" " :symbol ?symbol ;\n" " :index ?index .\n" "} ORDER BY (?index)"; librdf_query* q = librdf_new_query(p->world->world, "sparql", NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); librdf_query_results* results = librdf_query_execute(q, p->rdf); int num_ports = 0; int last_index = -1; while (!librdf_query_results_finished(results)) { librdf_node* type_node = librdf_query_results_get_binding_value(results, 0); librdf_node* symbol_node = librdf_query_results_get_binding_value(results, 1); librdf_node* index_node = librdf_query_results_get_binding_value(results, 2); assert(librdf_node_is_literal(symbol_node)); assert(librdf_node_is_literal(index_node)); const char* symbol = (const char*)librdf_node_get_literal_value(symbol_node); const char* index = (const char*)librdf_node_get_literal_value(index_node); //printf("PORT: %s %s %s\n", type, index, symbol); const int this_index = atoi(index); SLV2Port this_port = NULL; // ORDER BY guarantees order assert(this_index <= num_ports); // Create a new SLV2Port, and add to template if (this_index == num_ports) { assert(this_index == last_index + 1); this_port = slv2_port_new(p->world, (unsigned)atoi(index), symbol); raptor_sequence_push(p->ports, this_port); ++num_ports; ++last_index; // More information about a port we already created } else if (this_index < num_ports) { this_port = slv2_plugin_get_port_by_index(p, this_index); } if (this_port) { raptor_sequence_push(this_port->classes, slv2_value_new_librdf_uri(p->world, librdf_node_get_uri(type_node))); } librdf_free_node(type_node); librdf_free_node(symbol_node); librdf_free_node(index_node); librdf_query_results_next(results); } librdf_free_query_results(results); librdf_free_query(q); } } void slv2_plugin_load(SLV2Plugin p) { //printf("Loading cache for %s\n", slv2_value_as_string(p->plugin_uri)); if (!p->storage) { assert(!p->rdf); p->storage = librdf_new_storage(p->world->world, "trees", NULL, NULL); if (!p->storage) p->storage = librdf_new_storage(p->world->world, "memory", NULL, NULL); p->rdf = librdf_new_model(p->world->world, p->storage, NULL); } // Parse all the plugin's data files into RDF model for (unsigned i=0; i < slv2_values_size(p->data_uris); ++i) { SLV2Value data_uri_val = slv2_values_get_at(p->data_uris, i); librdf_uri* data_uri = librdf_new_uri(p->world->world, (const unsigned char*)slv2_value_as_uri(data_uri_val)); librdf_parser_parse_into_model(p->world->parser, data_uri, NULL, p->rdf); librdf_free_uri(data_uri); } } SLV2Value slv2_plugin_get_uri(SLV2Plugin p) { assert(p); assert(p->plugin_uri); return p->plugin_uri; } SLV2Value slv2_plugin_get_bundle_uri(SLV2Plugin p) { assert(p); assert(p->bundle_uri); return p->bundle_uri; } SLV2Value slv2_plugin_get_library_uri(SLV2Plugin p) { assert(p); slv2_plugin_load_if_necessary(p); if (!p->binary_uri) { const unsigned char* query = (const unsigned char*) "PREFIX : \n" "SELECT ?binary WHERE { <> :binary ?binary . }"; librdf_query* q = librdf_new_query(p->world->world, "sparql", NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); librdf_query_results* results = librdf_query_execute(q, p->rdf); if (!librdf_query_results_finished(results)) { librdf_node* binary_node = librdf_query_results_get_binding_value(results, 0); librdf_uri* binary_uri = librdf_node_get_uri(binary_node); if (binary_uri) { SLV2Value binary = slv2_value_new_librdf_uri(p->world, binary_uri); p->binary_uri = binary; } librdf_free_node(binary_node); } librdf_free_query_results(results); librdf_free_query(q); } return p->binary_uri; } SLV2Values slv2_plugin_get_data_uris(SLV2Plugin p) { return p->data_uris; } SLV2PluginClass slv2_plugin_get_class(SLV2Plugin p) { slv2_plugin_load_if_necessary(p); if (!p->plugin_class) { const unsigned char* query = (const unsigned char*) "SELECT DISTINCT ?class WHERE { <> a ?class }"; librdf_query* q = librdf_new_query(p->world->world, "sparql", NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); librdf_query_results* results = librdf_query_execute(q, p->rdf); while (!librdf_query_results_finished(results)) { librdf_node* class_node = librdf_query_results_get_binding_value(results, 0); librdf_uri* class_uri = librdf_node_get_uri(class_node); if (!class_uri) { librdf_query_results_next(results); continue; } SLV2Value class = slv2_value_new_librdf_uri(p->world, class_uri); if ( ! slv2_value_equals(class, p->world->lv2_plugin_class->uri)) { SLV2PluginClass plugin_class = slv2_plugin_classes_get_by_uri( p->world->plugin_classes, class); librdf_free_node(class_node); if (plugin_class) { p->plugin_class = plugin_class; slv2_value_free(class); break; } } slv2_value_free(class); librdf_query_results_next(results); } if (p->plugin_class == NULL) p->plugin_class = p->world->lv2_plugin_class; librdf_free_query_results(results); librdf_free_query(q); } return p->plugin_class; } bool slv2_plugin_verify(SLV2Plugin plugin) { char* query_str = "SELECT DISTINCT ?type ?name ?license ?port WHERE {\n" "<> a ?type ;\n" "doap:name ?name ;\n" "doap:license ?license ;\n" "lv2:port [ lv2:index ?port ] .\n}"; SLV2Results results = slv2_plugin_query_sparql(plugin, query_str); bool has_type = false; bool has_name = false; bool has_license = false; bool has_port = false; while (!librdf_query_results_finished(results->rdf_results)) { librdf_node* type_node = librdf_query_results_get_binding_value(results->rdf_results, 0); librdf_node* name_node = librdf_query_results_get_binding_value(results->rdf_results, 1); librdf_node* license_node = librdf_query_results_get_binding_value(results->rdf_results, 2); librdf_node* port_node = librdf_query_results_get_binding_value(results->rdf_results, 3); if (librdf_node_get_type(type_node) == LIBRDF_NODE_TYPE_RESOURCE) has_type = true; if (name_node) has_name = true; if (license_node) has_license = true; if (port_node) has_port = true; librdf_free_node(type_node); librdf_free_node(name_node); librdf_free_node(license_node); librdf_free_node(port_node); librdf_query_results_next(results->rdf_results); } slv2_results_free(results); if ( ! (has_type && has_name && has_license && has_port) ) { fprintf(stderr, "Invalid LV2 Plugin %s\n", slv2_value_as_uri(slv2_plugin_get_uri(plugin))); return false; } else { return true; } } SLV2Value slv2_plugin_get_name(SLV2Plugin plugin) { SLV2Values results = slv2_plugin_get_value_by_qname_i18n(plugin, "doap:name"); SLV2Value ret = NULL; if (results) { SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_string(val)) ret = slv2_value_duplicate(val); slv2_values_free(results); } else { results = slv2_plugin_get_value_by_qname(plugin, "doap:name"); SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_string(val)) ret = slv2_value_duplicate(val); slv2_values_free(results); } return ret; } SLV2Values slv2_plugin_get_value(SLV2Plugin p, SLV2Value predicate) { char* query = NULL; /* Hack around broken RASQAL, full URI predicates don't work :/ */ query = slv2_strjoin( "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">\n", "SELECT DISTINCT ?value WHERE {\n" "<> slv2predicate: ?value .\n" "}\n", NULL); SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); return result; } /* internal */ SLV2Values slv2_plugin_get_value_by_qname(SLV2Plugin p, const char* predicate) { char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE { \n" "<> ", predicate, " ?value . \n" "}\n", NULL); SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); return result; } /* internal: get i18n value if possible */ SLV2Values slv2_plugin_get_value_by_qname_i18n(SLV2Plugin p, const char* predicate) { char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE { \n" "<> ", predicate, " ?value . \n" "FILTER(lang(?value) = \"", slv2_get_lang(), "\") \n" "}\n", NULL); SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); return result; } SLV2Values slv2_plugin_get_value_for_subject(SLV2Plugin p, SLV2Value subject, SLV2Value predicate) { if ( ! slv2_value_is_uri(subject)) { fprintf(stderr, "slv2_plugin_get_value_for_subject error: " "subject is not a URI\n"); return NULL; } char* query = NULL; char* subject_token = slv2_value_get_turtle_token(subject); /* Hack around broken RASQAL, full URI predicates don't work :/ */ query = slv2_strjoin( "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">\n", "SELECT DISTINCT ?value WHERE {\n", subject_token, " slv2predicate: ?value .\n" "}\n", NULL); SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); free(subject_token); return result; } SLV2Values slv2_plugin_get_properties(SLV2Plugin p) { // FIXME: APIBREAK: This predicate does not even exist. Remove this function. return slv2_plugin_get_value_by_qname(p, "lv2:pluginProperty"); } SLV2Values slv2_plugin_get_hints(SLV2Plugin p) { // FIXME: APIBREAK: This predicate does not even exist. Remove this function. return slv2_plugin_get_value_by_qname(p, "lv2:pluginHint"); } uint32_t slv2_plugin_get_num_ports(SLV2Plugin p) { slv2_plugin_load_ports_if_necessary(p); return raptor_sequence_size(p->ports); } void slv2_plugin_get_port_float_values(SLV2Plugin p, const char* qname, float* values) { slv2_plugin_load_ports_if_necessary(p); for (int i = 0; i < raptor_sequence_size(p->ports); ++i) values[i] = NAN; unsigned char* query = (unsigned char*)slv2_strjoin( "PREFIX : \n" "SELECT DISTINCT ?index ?value WHERE {\n" "<> :port ?port .\n" "?port :index ?index .\n" "?port ", qname, " ?value .\n" "} ", NULL); librdf_query* q = librdf_new_query(p->world->world, "sparql", NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); librdf_query_results* results = librdf_query_execute(q, p->rdf); while (!librdf_query_results_finished(results)) { librdf_node* idx_node = librdf_query_results_get_binding_value(results, 0); librdf_node* val_node = librdf_query_results_get_binding_value(results, 1); if (idx_node && val_node && librdf_node_is_literal(idx_node) && librdf_node_is_literal(val_node)) { const int idx = atoi((const char*)librdf_node_get_literal_value(idx_node)); const float val = atof((const char*)librdf_node_get_literal_value(val_node)); values[idx] = val; librdf_free_node(idx_node); librdf_free_node(val_node); } librdf_query_results_next(results); } librdf_free_query_results(results); librdf_free_query(q); free(query); } void slv2_plugin_get_port_ranges_float(SLV2Plugin p, float* min_values, float* max_values, float* def_values) { if (min_values) slv2_plugin_get_port_float_values(p, ":minimum", min_values); if (max_values) slv2_plugin_get_port_float_values(p, ":maximum", max_values); if (def_values) slv2_plugin_get_port_float_values(p, ":default", def_values); } uint32_t slv2_plugin_get_num_ports_of_class(SLV2Plugin p, SLV2Value class_1, ...) { slv2_plugin_load_ports_if_necessary(p); uint32_t ret = 0; va_list args; for (unsigned i=0; i < slv2_plugin_get_num_ports(p); ++i) { SLV2Port port = raptor_sequence_get_at(p->ports, i); if (!slv2_port_is_a(p, port, class_1)) continue; va_start(args, class_1); bool matches = true; for (SLV2Value class_i = NULL; (class_i = va_arg(args, SLV2Value)) != NULL ; ) { if (!slv2_port_is_a(p, port, class_i)) { va_end(args); matches = false; break; } } if (matches) ++ret; va_end(args); } return ret; } bool slv2_plugin_has_latency(SLV2Plugin p) { const char* const query = "SELECT ?index WHERE {\n" " <> lv2:port ?port .\n" " ?port lv2:portProperty lv2:reportsLatency ;\n" " lv2:index ?index .\n" "}\n"; SLV2Values results = slv2_plugin_query_variable(p, query, 0); const bool latent = (slv2_values_size(results) > 0); slv2_values_free(results); return latent; } uint32_t slv2_plugin_get_latency_port_index(SLV2Plugin p) { const char* const query = "SELECT ?index WHERE {\n" " <> lv2:port ?port .\n" " ?port lv2:portProperty lv2:reportsLatency ;\n" " lv2:index ?index .\n" "}\n"; SLV2Values result = slv2_plugin_query_variable(p, query, 0); // FIXME: need a sane error handling strategy assert(slv2_values_size(result) > 0); SLV2Value val = slv2_values_get_at(result, 0); assert(slv2_value_is_int(val)); int ret = slv2_value_as_int(val); slv2_values_free(result); return ret; } bool slv2_plugin_has_feature(SLV2Plugin p, SLV2Value feature) { SLV2Values features = slv2_plugin_get_supported_features(p); const bool ret = features && feature && slv2_values_contains(features, feature); slv2_values_free(features); return ret; } SLV2Values slv2_plugin_get_supported_features(SLV2Plugin p) { SLV2Values optional = slv2_plugin_get_optional_features(p); SLV2Values required = slv2_plugin_get_required_features(p); SLV2Values result = slv2_values_new(); unsigned n_optional = slv2_values_size(optional); unsigned n_required = slv2_values_size(required); unsigned i = 0; for ( ; i < n_optional; ++i) slv2_values_set_at(result, i, raptor_sequence_pop(optional)); for ( ; i < n_optional + n_required; ++i) slv2_values_set_at(result, i, raptor_sequence_pop(required)); slv2_values_free(optional); slv2_values_free(required); return result; } SLV2Values slv2_plugin_get_optional_features(SLV2Plugin p) { return slv2_plugin_get_value_by_qname(p, "lv2:optionalFeature"); } SLV2Values slv2_plugin_get_required_features(SLV2Plugin p) { return slv2_plugin_get_value_by_qname(p, "lv2:requiredFeature"); } SLV2Port slv2_plugin_get_port_by_index(SLV2Plugin p, uint32_t index) { slv2_plugin_load_ports_if_necessary(p); return raptor_sequence_get_at(p->ports, (int)index); } SLV2Port slv2_plugin_get_port_by_symbol(SLV2Plugin p, SLV2Value symbol) { slv2_plugin_load_ports_if_necessary(p); for (int i=0; i < raptor_sequence_size(p->ports); ++i) { SLV2Port port = raptor_sequence_get_at(p->ports, i); if (slv2_value_equals(port->symbol, symbol)) return port; } return NULL; } SLV2Value slv2_plugin_get_author_name(SLV2Plugin plugin) { SLV2Value ret = NULL; const char* const query = "SELECT ?name WHERE {\n" " <> doap:maintainer ?maint . \n" " ?maint foaf:name ?name . \n" "}\n"; SLV2Values results = slv2_plugin_query_variable(plugin, query, 0); if (results && slv2_values_size(results) > 0) { SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_string(val)) ret = slv2_value_duplicate(val); } if (results) slv2_values_free(results); return ret; } SLV2Value slv2_plugin_get_author_email(SLV2Plugin plugin) { SLV2Value ret = NULL; const char* const query = "SELECT ?email WHERE {\n" " <> doap:maintainer ?maint . \n" " ?maint foaf:mbox ?email . \n" "}\n"; SLV2Values results = slv2_plugin_query_variable(plugin, query, 0); if (results && slv2_values_size(results) > 0) { SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_uri(val)) ret = slv2_value_duplicate(val); } if (results) slv2_values_free(results); return ret; } SLV2Value slv2_plugin_get_author_homepage(SLV2Plugin plugin) { SLV2Value ret = NULL; const char* const query = "SELECT ?page WHERE {\n" " <> doap:maintainer ?maint . \n" " ?maint foaf:homepage ?page . \n" "}\n"; SLV2Values results = slv2_plugin_query_variable(plugin, query, 0); if (results && slv2_values_size(results) > 0) { SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_uri(val)) ret = slv2_value_duplicate(val); } if (results) slv2_values_free(results); return ret; } SLV2UIs slv2_plugin_get_uis(SLV2Plugin plugin) { const char* const query_str = "PREFIX uiext: \n" "SELECT DISTINCT ?uri ?type ?binary WHERE {\n" "<> uiext:ui ?uri .\n" "?uri a ?type ;\n" " uiext:binary ?binary .\n" "}\n"; SLV2Results results = slv2_plugin_query_sparql(plugin, query_str); SLV2UIs result = slv2_uis_new(); while (!librdf_query_results_finished(results->rdf_results)) { librdf_node* uri_node = librdf_query_results_get_binding_value(results->rdf_results, 0); librdf_node* type_node = librdf_query_results_get_binding_value(results->rdf_results, 1); librdf_node* binary_node = librdf_query_results_get_binding_value(results->rdf_results, 2); SLV2UI ui = slv2_ui_new(plugin->world, librdf_node_get_uri(uri_node), librdf_node_get_uri(type_node), librdf_node_get_uri(binary_node)); raptor_sequence_push(result, ui); librdf_free_node(uri_node); librdf_free_node(type_node); librdf_free_node(binary_node); librdf_query_results_next(results->rdf_results); } slv2_results_free(results); if (slv2_uis_size(result) > 0) { return result; } else { slv2_uis_free(result); return NULL; } } slv2-0.6.6+dfsg1/src/pluginclass.c0000644000175000017500000000507011231361306016546 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include "slv2/types.h" #include "slv2/pluginclass.h" #include "slv2/value.h" #include "slv2_internal.h" /* private */ SLV2PluginClass slv2_plugin_class_new(SLV2World world, librdf_uri* parent_uri, librdf_uri* uri, const char* label) { SLV2PluginClass pc = (SLV2PluginClass)malloc(sizeof(struct _SLV2PluginClass)); pc->world = world; pc->parent_uri = (parent_uri ? slv2_value_new_librdf_uri(world, parent_uri) : NULL); pc->uri = slv2_value_new_librdf_uri(world, uri); pc->label = slv2_value_new(world, SLV2_VALUE_STRING, label); return pc; } void slv2_plugin_class_free(SLV2PluginClass plugin_class) { assert(plugin_class->uri); slv2_value_free(plugin_class->uri); slv2_value_free(plugin_class->parent_uri); slv2_value_free(plugin_class->label); free(plugin_class); } SLV2Value slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class) { if (plugin_class->parent_uri) return plugin_class->parent_uri; else return NULL; } SLV2Value slv2_plugin_class_get_uri(SLV2PluginClass plugin_class) { assert(plugin_class->uri); return plugin_class->uri; } SLV2Value slv2_plugin_class_get_label(SLV2PluginClass plugin_class) { return plugin_class->label; } SLV2PluginClasses slv2_plugin_class_get_children(SLV2PluginClass plugin_class) { // Returned list doesn't own categories SLV2PluginClasses result = raptor_new_sequence(NULL, NULL); for (int i=0; i < raptor_sequence_size(plugin_class->world->plugin_classes); ++i) { SLV2PluginClass c = raptor_sequence_get_at(plugin_class->world->plugin_classes, i); SLV2Value parent = slv2_plugin_class_get_parent_uri(c); if (parent && slv2_value_equals(slv2_plugin_class_get_uri(plugin_class), parent)) raptor_sequence_push(result, c); } return result; } slv2-0.6.6+dfsg1/src/scalepoint.c0000644000175000017500000000304311231361306016361 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/types.h" #include "slv2/value.h" #include "slv2_internal.h" /* private - ownership of value and label is taken */ SLV2ScalePoint slv2_scale_point_new(SLV2Value value, SLV2Value label) { SLV2ScalePoint point = (SLV2ScalePoint)malloc(sizeof(struct _SLV2ScalePoint)); point->value = value; point->label= label; return point; } /* private */ void slv2_scale_point_free(SLV2ScalePoint point) { slv2_value_free(point->value); slv2_value_free(point->label); free(point); } SLV2Value slv2_scale_point_get_value(SLV2ScalePoint p) { return p->value; } SLV2Value slv2_scale_point_get_label(SLV2ScalePoint p) { return p->label; } slv2-0.6.6+dfsg1/src/plugins.c0000644000175000017500000000464111231361306015706 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include "slv2/types.h" #include "slv2/plugin.h" #include "slv2/collections.h" #include "slv2/util.h" #include "slv2_internal.h" SLV2Plugins slv2_plugins_new() { //return raptor_new_sequence((void (*)(void*))&slv2_plugin_free, NULL); return raptor_new_sequence(NULL, NULL); } void slv2_plugins_free(SLV2World world, SLV2Plugins list) { if (list && list != world->plugins) raptor_free_sequence(list); } #if 0 void slv2_plugins_filter(SLV2Plugins dest, SLV2Plugins source, bool (*include)(SLV2Plugin)) { assert(dest); for (int i=0; i < raptor_sequence_size(source); ++i) { SLV2Plugin p = raptor_sequence_get_at(source, i); if (include(p)) raptor_sequence_push(dest, slv2_plugin_duplicate(p)); } } #endif unsigned slv2_plugins_size(SLV2Plugins list) { return (list ? raptor_sequence_size(list) : 0); } SLV2Plugin slv2_plugins_get_by_uri(SLV2Plugins list, SLV2Value uri) { // good old fashioned binary search int lower = 0; int upper = raptor_sequence_size(list) - 1; int i; while (upper >= lower) { i = lower + ((upper - lower) / 2); SLV2Plugin p = raptor_sequence_get_at(list, i); const int cmp = strcmp(slv2_value_as_uri(slv2_plugin_get_uri(p)), slv2_value_as_uri(uri)); if (cmp == 0) return p; else if (cmp > 0) upper = i - 1; else lower = i + 1; } return NULL; } SLV2Plugin slv2_plugins_get_at(SLV2Plugins list, unsigned index) { if (index > INT_MAX) return NULL; else return (SLV2Plugin)raptor_sequence_get_at(list, (int)index); } slv2-0.6.6+dfsg1/src/value.c0000644000175000017500000001705011231361306015337 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/types.h" #include "slv2/value.h" #include "slv2_internal.h" /* private */ static void slv2_value_set_numerics_from_string(SLV2Value val) { // FIXME: locale kludges to work around librdf bug char* locale = strdup(setlocale(LC_NUMERIC, NULL)); if (val->type == SLV2_VALUE_INT) { char* endptr = 0; setlocale(LC_NUMERIC, "POSIX"); val->val.int_val = strtol(val->str_val, &endptr, 10); setlocale(LC_NUMERIC, locale); } else if (val->type == SLV2_VALUE_FLOAT) { char* endptr = 0; setlocale(LC_NUMERIC, "POSIX"); val->val.float_val = strtod(val->str_val, &endptr); setlocale(LC_NUMERIC, locale); } free(locale); } /* private */ SLV2Value slv2_value_new(SLV2World world, SLV2ValueType type, const char* str) { SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value)); val->type = type; if (type == SLV2_VALUE_URI) { val->val.uri_val = librdf_new_uri(world->world, (const unsigned char*)str); assert(val->val.uri_val); val->str_val = (char*)librdf_uri_as_string(val->val.uri_val); } else { val->str_val = strdup(str); } slv2_value_set_numerics_from_string(val); return val; } /* private */ SLV2Value slv2_value_new_librdf_node(SLV2World world, librdf_node* node) { SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value)); val->type = SLV2_VALUE_STRING; val->str_val = NULL; librdf_uri* datatype_uri = NULL; switch (librdf_node_get_type(node)) { case LIBRDF_NODE_TYPE_RESOURCE: val->type = SLV2_VALUE_URI; val->val.uri_val = librdf_node_get_uri(node); val->str_val = (char*)librdf_uri_as_string(val->val.uri_val); break; case LIBRDF_NODE_TYPE_LITERAL: datatype_uri = librdf_node_get_literal_value_datatype_uri(node); if (datatype_uri) { if (librdf_uri_equals(datatype_uri, librdf_node_get_uri(world->xsd_integer_node))) val->type = SLV2_VALUE_INT; else if (librdf_uri_equals(datatype_uri, librdf_node_get_uri(world->xsd_decimal_node))) val->type = SLV2_VALUE_FLOAT; else fprintf(stderr, "Unknown datatype %s\n", librdf_uri_as_string(datatype_uri)); } val->str_val = strdup((char*)librdf_node_get_literal_value(node)); break; case LIBRDF_NODE_TYPE_BLANK: case LIBRDF_NODE_TYPE_UNKNOWN: default: fprintf(stderr, "slv2_value_new_librdf_node error: Unknown node type."); free(val); val = NULL; break; } if (val) slv2_value_set_numerics_from_string(val); return val; } /* private */ SLV2Value slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri) { assert(uri); SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value)); val->type = SLV2_VALUE_URI; val->val.uri_val = librdf_new_uri_from_uri(uri); val->str_val = (char*)librdf_uri_as_string(val->val.uri_val); return val; } SLV2Value slv2_value_new_uri(SLV2World world, const char* uri) { return slv2_value_new(world, SLV2_VALUE_URI, uri); } SLV2Value slv2_value_new_string(SLV2World world, const char* str) { return slv2_value_new(world, SLV2_VALUE_STRING, str); } SLV2Value slv2_value_new_int(SLV2World world, int val) { char str[32]; snprintf(str, 32, "%d", val); return slv2_value_new(world, SLV2_VALUE_INT, str); } SLV2Value slv2_value_new_float(SLV2World world, float val) { char str[32]; snprintf(str, 32, "%f", val); return slv2_value_new(world, SLV2_VALUE_FLOAT, str); } SLV2Value slv2_value_duplicate(SLV2Value val) { if (val == NULL) return val; SLV2Value result = (SLV2Value)malloc(sizeof(struct _SLV2Value)); result->type = val->type; if (val->type == SLV2_VALUE_URI) { result->val.uri_val = librdf_new_uri_from_uri(val->val.uri_val); result->str_val = (char*)librdf_uri_as_string(val->val.uri_val); } else { result->str_val = strdup(val->str_val); result->val = val->val; } return result; } void slv2_value_free(SLV2Value val) { if (val) { if (val->type == SLV2_VALUE_URI) librdf_free_uri(val->val.uri_val); else free(val->str_val); free(val); } } bool slv2_value_equals(SLV2Value value, SLV2Value other) { if (value == NULL && other == NULL) return true; else if (value == NULL || other == NULL) return false; else if (value->type != other->type) return false; switch (value->type) { case SLV2_VALUE_URI: return (librdf_uri_equals(value->val.uri_val, other->val.uri_val) != 0); case SLV2_VALUE_STRING: case SLV2_VALUE_QNAME_UNUSED: return ! strcmp(value->str_val, other->str_val); case SLV2_VALUE_INT: return (value->val.int_val == other->val.int_val); case SLV2_VALUE_FLOAT: return (value->val.float_val == other->val.float_val); } return false; /* shouldn't get here */ } char* slv2_value_get_turtle_token(SLV2Value value) { size_t len = 0; char* result = NULL; char* locale = strdup(setlocale(LC_NUMERIC, NULL)); // FIXME: locale kludges to work around librdf bug switch (value->type) { case SLV2_VALUE_URI: len = strlen(value->str_val) + 3; result = calloc(len, sizeof(char)); snprintf(result, len, "<%s>", value->str_val); break; case SLV2_VALUE_STRING: case SLV2_VALUE_QNAME_UNUSED: result = strdup(value->str_val); break; case SLV2_VALUE_INT: // INT64_MAX is 9223372036854775807 (19 digits) + 1 for sign len = 20; result = calloc(len, sizeof(char)); setlocale(LC_NUMERIC, "POSIX"); snprintf(result, len, "%d", value->val.int_val); setlocale(LC_NUMERIC, locale); break; case SLV2_VALUE_FLOAT: len = 20; // FIXME: proper maximum value? result = calloc(len, sizeof(char)); setlocale(LC_NUMERIC, "POSIX"); snprintf(result, len, "%f", value->val.float_val); setlocale(LC_NUMERIC, locale); break; } free(locale); return result; } bool slv2_value_is_uri(SLV2Value value) { return (value && value->type == SLV2_VALUE_URI); } const char* slv2_value_as_uri(SLV2Value value) { assert(slv2_value_is_uri(value)); return value->str_val; } /* private */ librdf_uri* slv2_value_as_librdf_uri(SLV2Value value) { assert(slv2_value_is_uri(value)); return value->val.uri_val; } bool slv2_value_is_literal(SLV2Value value) { // No blank nodes return (value && value->type != SLV2_VALUE_URI); } bool slv2_value_is_string(SLV2Value value) { return (value && value->type == SLV2_VALUE_STRING); } const char* slv2_value_as_string(SLV2Value value) { return value->str_val; } bool slv2_value_is_int(SLV2Value value) { return (value && value->type == SLV2_VALUE_INT); } int slv2_value_as_int(SLV2Value value) { assert(value); assert(slv2_value_is_int(value)); return value->val.int_val; } bool slv2_value_is_float(SLV2Value value) { return (value && value->type == SLV2_VALUE_FLOAT); } float slv2_value_as_float(SLV2Value value) { assert(slv2_value_is_float(value) || slv2_value_is_int(value)); if (slv2_value_is_float(value)) return value->val.float_val; else // slv2_value_is_int(value) return (float)value->val.int_val; } slv2-0.6.6+dfsg1/src/world.c0000644000175000017500000004275611231361306015365 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "slv2-config.h" #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/types.h" #include "slv2/world.h" #include "slv2/slv2.h" #include "slv2/util.h" #include "slv2_internal.h" /* private */ static SLV2World slv2_world_new_internal(SLV2World world) { assert(world); assert(world->world); world->storage = librdf_new_storage(world->world, "trees", NULL, NULL); if (!world->storage) { fprintf(stderr, "Warning: Unable to create \"trees\" RDF storage.\n" "Performance can be improved by upgrading librdf.\n"); world->storage = librdf_new_storage(world->world, "hashes", NULL, "hash-type='memory'"); } if (!world->storage) goto fail; world->model = librdf_new_model(world->world, world->storage, NULL); if (!world->model) goto fail; world->parser = librdf_new_parser(world->world, "turtle", NULL, NULL); if (!world->parser) goto fail; world->plugin_classes = slv2_plugin_classes_new(); world->plugins = slv2_plugins_new(); world->lv2_specification_node = librdf_new_node_from_uri_string(world->world, (const unsigned char*)"http://lv2plug.in/ns/lv2core#Specification"); world->lv2_plugin_node = librdf_new_node_from_uri_string(world->world, (const unsigned char*)"http://lv2plug.in/ns/lv2core#Plugin"); world->rdf_a_node = librdf_new_node_from_uri_string(world->world, (const unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); world->xsd_integer_node = librdf_new_node_from_uri_string(world->world, (const unsigned char*)"http://www.w3.org/2001/XMLSchema#integer"); world->xsd_decimal_node = librdf_new_node_from_uri_string(world->world, (const unsigned char*)"http://www.w3.org/2001/XMLSchema#decimal"); world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, librdf_node_get_uri(world->lv2_plugin_node), "Plugin"); return world; fail: /* keep on rockin' in the */ free(world); return NULL; } SLV2World slv2_world_new() { SLV2World world = (SLV2World)malloc(sizeof(struct _SLV2World)); world->world = librdf_new_world(); if (!world->world) { free(world); return NULL; } world->local_world = true; librdf_world_open(world->world); return slv2_world_new_internal(world); } SLV2World slv2_world_new_using_rdf_world(librdf_world* rdf_world) { if (rdf_world == NULL) return slv2_world_new(); SLV2World world = (SLV2World)malloc(sizeof(struct _SLV2World)); world->world = rdf_world; world->local_world = false; return slv2_world_new_internal(world); } void slv2_world_free(SLV2World world) { slv2_plugin_class_free(world->lv2_plugin_class); world->lv2_plugin_class = NULL; librdf_free_node(world->lv2_specification_node); librdf_free_node(world->lv2_plugin_node); librdf_free_node(world->rdf_a_node); librdf_free_node(world->xsd_integer_node); librdf_free_node(world->xsd_decimal_node); for (int i=0; i < raptor_sequence_size(world->plugins); ++i) slv2_plugin_free(raptor_sequence_get_at(world->plugins, i)); raptor_free_sequence(world->plugins); world->plugins = NULL; raptor_free_sequence(world->plugin_classes); world->plugin_classes = NULL; librdf_free_parser(world->parser); world->parser = NULL; librdf_free_model(world->model); world->model = NULL; librdf_free_storage(world->storage); world->storage = NULL; if (world->local_world) librdf_free_world(world->world); world->world = NULL; free(world); } /** Load the entire contents of a file into the world model. */ void slv2_world_load_file(SLV2World world, librdf_uri* file_uri) { librdf_parser_parse_into_model(world->parser, file_uri, NULL, world->model); } void slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) { librdf_uri* manifest_uri = librdf_new_uri_relative_to_base( bundle_uri->val.uri_val, (const unsigned char*)"manifest.ttl"); /* Parse the manifest into a temporary model */ librdf_storage* manifest_storage = librdf_new_storage(world->world, "trees", NULL, NULL); if (manifest_storage == NULL) manifest_storage = librdf_new_storage(world->world, "memory", NULL, NULL); librdf_model* manifest_model = librdf_new_model(world->world, manifest_storage, NULL); librdf_parser_parse_into_model(world->parser, manifest_uri, NULL, manifest_model); /* Query statement: ?plugin a lv2:Plugin */ librdf_statement* q = librdf_new_statement_from_nodes(world->world, NULL, librdf_new_node_from_node(world->rdf_a_node), librdf_new_node_from_node(world->lv2_plugin_node)); librdf_stream* results = librdf_model_find_statements(manifest_model, q); while (!librdf_stream_end(results)) { librdf_statement* s = librdf_stream_get_object(results); librdf_node* plugin_node = librdf_new_node_from_node(librdf_statement_get_subject(s)); /* Add ?plugin rdfs:seeAlso */ librdf_node* subject = plugin_node; librdf_node* predicate = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://www.w3.org/2000/01/rdf-schema#seeAlso"); librdf_node* object = librdf_new_node_from_uri(world->world, manifest_uri); librdf_model_add(world->model, subject, predicate, object); /* Add ?plugin slv2:bundleURI */ subject = librdf_new_node_from_node(plugin_node); predicate = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://drobilla.net/ns/slv2#bundleURI"); object = librdf_new_node_from_uri(world->world, bundle_uri->val.uri_val); librdf_model_add(world->model, subject, predicate, object); librdf_stream_next(results); } librdf_free_stream(results); librdf_free_statement(q); /* Query statement: ?specification a lv2:Specification */ q = librdf_new_statement_from_nodes(world->world, NULL, librdf_new_node_from_node(world->rdf_a_node), librdf_new_node_from_node(world->lv2_specification_node)); results = librdf_model_find_statements(manifest_model, q); while (!librdf_stream_end(results)) { librdf_statement* s = librdf_stream_get_object(results); librdf_node* spec_node = librdf_new_node_from_node(librdf_statement_get_subject(s)); /* Add ?specification rdfs:seeAlso */ librdf_node* subject = spec_node; librdf_node* predicate = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://www.w3.org/2000/01/rdf-schema#seeAlso"); librdf_node* object = librdf_new_node_from_uri(world->world, manifest_uri); librdf_model_add(world->model, subject, predicate, object); /* Add ?specification slv2:bundleURI */ subject = librdf_new_node_from_node(spec_node); predicate = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://drobilla.net/ns/slv2#bundleURI"); object = librdf_new_node_from_uri(world->world, bundle_uri->val.uri_val); librdf_model_add(world->model, subject, predicate, object); librdf_stream_next(results); } librdf_free_stream(results); librdf_free_statement(q); /* Join the temporary model to the main model */ librdf_stream* manifest_stream = librdf_model_as_stream(manifest_model); librdf_model_add_statements(world->model, manifest_stream); librdf_free_stream(manifest_stream); librdf_free_model(manifest_model); librdf_free_storage(manifest_storage); librdf_free_uri(manifest_uri); } /** Load all bundles under a directory. * Private. */ void slv2_world_load_directory(SLV2World world, const char* dir) { DIR* pdir = opendir(dir); if (!pdir) return; struct dirent* pfile; while ((pfile = readdir(pdir))) { if (!strcmp(pfile->d_name, ".") || !strcmp(pfile->d_name, "..")) continue; char* uri = slv2_strjoin("file://", dir, "/", pfile->d_name, "/", NULL); // FIXME: Probably a better way to check if a dir exists DIR* bundle_dir = opendir(uri + 7); if (bundle_dir != NULL) { closedir(bundle_dir); SLV2Value uri_val = slv2_value_new_uri(world, uri); slv2_world_load_bundle(world, uri_val); slv2_value_free(uri_val); } free(uri); } closedir(pdir); } void slv2_world_load_path(SLV2World world, const char* lv2_path) { char* path = slv2_strjoin(lv2_path, ":", NULL); char* dir = path; // Pointer into path // Go through string replacing ':' with '\0', using the substring, // then replacing it with 'X' and moving on. i.e. strtok on crack. while (strchr(path, ':') != NULL) { char* delim = strchr(path, ':'); *delim = '\0'; slv2_world_load_directory(world, dir); *delim = 'X'; dir = delim + 1; } free(path); } /** Comparator for sorting SLV2Plugins */ int slv2_plugin_compare_by_uri(const void* a, const void* b) { SLV2Plugin plugin_a = *(SLV2Plugin*)a; SLV2Plugin plugin_b = *(SLV2Plugin*)b; return strcmp(slv2_value_as_uri(plugin_a->plugin_uri), slv2_value_as_uri(plugin_b->plugin_uri)); } /** Comparator for sorting SLV2PluginClasses */ int slv2_plugin_class_compare_by_uri(const void* a, const void* b) { SLV2PluginClass class_a = *(SLV2PluginClass*)a; SLV2PluginClass class_b = *(SLV2PluginClass*)b; return strcmp(slv2_value_as_uri(class_a->uri), slv2_value_as_uri(class_b->uri)); } void slv2_world_load_specifications(SLV2World world) { unsigned char* query_string = (unsigned char*) "PREFIX : \n" "PREFIX rdfs: \n" "SELECT DISTINCT ?spec ?data WHERE {\n" " ?spec a :Specification ;\n" " rdfs:seeAlso ?data .\n" "}\n"; librdf_query* q = librdf_new_query(world->world, "sparql", NULL, query_string, NULL); librdf_query_results* results = librdf_query_execute(q, world->model); while (!librdf_query_results_finished(results)) { librdf_node* spec_node = librdf_query_results_get_binding_value(results, 0); //librdf_uri* spec_uri = librdf_node_get_uri(spec_node); librdf_node* data_node = librdf_query_results_get_binding_value(results, 1); librdf_uri* data_uri = librdf_node_get_uri(data_node); slv2_world_load_file(world, data_uri); librdf_free_node(spec_node); librdf_free_node(data_node); librdf_query_results_next(results); } librdf_free_query_results(results); librdf_free_query(q); } void slv2_world_load_plugin_classes(SLV2World world) { // FIXME: This will need to be a bit more clever when more data is around // then the ontology (ie classes which aren't LV2 plugin_classes) // FIXME: This loads things that aren't plugin categories unsigned char* query_string = (unsigned char*) "PREFIX : \n" "PREFIX rdfs: \n" "SELECT DISTINCT ?class ?parent ?label WHERE {\n" //" ?plugin a ?class .\n" " ?class a rdfs:Class; rdfs:subClassOf ?parent; rdfs:label ?label\n" "}\n"; // ORDER BY ?class\n"; librdf_query* q = librdf_new_query(world->world, "sparql", NULL, query_string, NULL); librdf_query_results* results = librdf_query_execute(q, world->model); while (!librdf_query_results_finished(results)) { librdf_node* class_node = librdf_query_results_get_binding_value(results, 0); librdf_uri* class_uri = librdf_node_get_uri(class_node); librdf_node* parent_node = librdf_query_results_get_binding_value(results, 1); librdf_uri* parent_uri = librdf_node_get_uri(parent_node); librdf_node* label_node = librdf_query_results_get_binding_value(results, 2); const char* label = (const char*)librdf_node_get_literal_value(label_node); assert(class_uri); SLV2PluginClass plugin_class = slv2_plugin_class_new(world, parent_uri, class_uri, label); raptor_sequence_push(world->plugin_classes, plugin_class); // FIXME: Slow! ORDER BY broken in certain versions of redland? raptor_sequence_sort(world->plugin_classes, slv2_plugin_class_compare_by_uri); librdf_free_node(class_node); librdf_free_node(parent_node); librdf_free_node(label_node); librdf_query_results_next(results); } // FIXME: filter list here librdf_free_query_results(results); librdf_free_query(q); } void slv2_world_load_all(SLV2World world) { char* lv2_path = getenv("LV2_PATH"); /* 1. Read all manifest files into model */ if (lv2_path) { slv2_world_load_path(world, lv2_path); } else { const char* const home = getenv("HOME"); if (home) { #ifdef __APPLE__ const char* const suffix = "/Library/Audio/Plug-Ins/LV2:/Library/Audio/Plug-Ins/LV2" ":/usr/local/lib/lv2:/usr/lib/lv2"; #else const char* const suffix = "/.lv2:/usr/local/lib/lv2:/usr/lib/lv2"; #endif lv2_path = slv2_strjoin(home, suffix, NULL); } else { #ifdef __APPLE__ lv2_path = strdup("/Library/Audio/Plug-Ins/LV2:/usr/local/lib/lv2:/usr/lib/lv2"); #else lv2_path = strdup("/usr/local/lib/lv2:/usr/lib/lv2"); #endif } slv2_world_load_path(world, lv2_path); free(lv2_path); } /* 2. Query out things to cache */ slv2_world_load_specifications(world); slv2_world_load_plugin_classes(world); // Find all plugins and associated data files unsigned char* query_string = (unsigned char*) "PREFIX : \n" "PREFIX rdfs: \n" "PREFIX slv2: \n" "SELECT DISTINCT ?plugin ?data ?bundle\n" "WHERE { ?plugin a :Plugin; slv2:bundleURI ?bundle; rdfs:seeAlso ?data }\n"; //"ORDER BY ?plugin\n"; librdf_query* q = librdf_new_query(world->world, "sparql", NULL, query_string, NULL); librdf_query_results* results = librdf_query_execute(q, world->model); while (!librdf_query_results_finished(results)) { librdf_node* plugin_node = librdf_query_results_get_binding_value(results, 0); librdf_uri* plugin_uri = librdf_node_get_uri(plugin_node); librdf_node* data_node = librdf_query_results_get_binding_value(results, 1); librdf_uri* data_uri = librdf_node_get_uri(data_node); librdf_node* bundle_node = librdf_query_results_get_binding_value(results, 2); librdf_uri* bundle_uri = librdf_node_get_uri(bundle_node); assert(plugin_uri); assert(data_uri); SLV2Value uri = slv2_value_new_librdf_uri(world, plugin_uri); SLV2Plugin plugin = slv2_plugins_get_by_uri(world->plugins, uri); // Create a new SLV2Plugin if (!plugin) { plugin = slv2_plugin_new(world, uri, bundle_uri); raptor_sequence_push(world->plugins, plugin); // FIXME: Slow! ORDER BY broken in certain versions of redland? raptor_sequence_sort(world->plugins, slv2_plugin_compare_by_uri); } else { slv2_value_free(uri); } plugin->world = world; // FIXME: check for duplicates raptor_sequence_push(plugin->data_uris, slv2_value_new_librdf_uri(plugin->world, data_uri)); librdf_free_node(plugin_node); librdf_free_node(data_node); librdf_free_node(bundle_node); librdf_query_results_next(results); } if (results) librdf_free_query_results(results); librdf_free_query(q); } #if 0 void slv2_world_serialize(const char* filename) { librdf_uri* lv2_uri = librdf_new_uri(slv2_rdf_world, (unsigned char*)"http://lv2plug.in/ns/lv2core#"); librdf_uri* rdfs_uri = librdf_new_uri(slv2_rdf_world, (unsigned char*)"http://www.w3.org/2000/01/rdf-schema#"); // Write out test file librdf_serializer* serializer = librdf_new_serializer(slv2_rdf_world, "turtle", NULL, NULL); librdf_serializer_set_namespace(serializer, lv2_uri, ""); librdf_serializer_set_namespace(serializer, rdfs_uri, "rdfs"); librdf_serializer_serialize_world_to_file(serializer, filename, NULL, slv2_model); librdf_free_serializer(serializer); } #endif SLV2PluginClass slv2_world_get_plugin_class(SLV2World world) { return world->lv2_plugin_class; } SLV2PluginClasses slv2_world_get_plugin_classes(SLV2World world) { return world->plugin_classes; } SLV2Plugins slv2_world_get_all_plugins(SLV2World world) { return world->plugins; } SLV2Plugins slv2_world_get_plugins_by_filter(SLV2World world, bool (*include)(SLV2Plugin)) { SLV2Plugins result = slv2_plugins_new(); for (int i=0; i < raptor_sequence_size(world->plugins); ++i) { SLV2Plugin p = raptor_sequence_get_at(world->plugins, i); if (include(p)) raptor_sequence_push(result, p); } return result; } #if 0 SLV2Plugins slv2_world_get_plugins_by_query(SLV2World world, const char* query) { SLV2Plugins list = slv2_plugins_new(); librdf_query* rq = librdf_new_query(world->world, "sparql", NULL, (const unsigned char*)query, NULL); librdf_query_results* results = librdf_query_execute(rq, world->model); while (!librdf_query_results_finished(results)) { librdf_node* plugin_node = librdf_query_results_get_binding_value(results, 0); librdf_uri* plugin_uri = librdf_node_get_uri(plugin_node); SLV2Plugin plugin = slv2_plugins_get_by_uri(list, (const char*)librdf_uri_as_string(plugin_uri)); /* Create a new SLV2Plugin */ if (!plugin) { SLV2Plugin new_plugin = slv2_plugin_new(world, plugin_uri); raptor_sequence_push(list, new_plugin); } librdf_free_node(plugin_node); librdf_query_results_next(results); } if (results) librdf_free_query_results(results); librdf_free_query(rq); return list; } #endif slv2-0.6.6+dfsg1/src/pluginui.c0000644000175000017500000000467011231361306016063 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include "slv2/types.h" #include "slv2/collections.h" #include "slv2_internal.h" /* private */ SLV2UI slv2_ui_new(SLV2World world, librdf_uri* uri, librdf_uri* type_uri, librdf_uri* binary_uri) { assert(uri); assert(type_uri); assert(binary_uri); struct _SLV2UI* ui = malloc(sizeof(struct _SLV2UI)); ui->world = world; ui->uri = slv2_value_new_librdf_uri(world, uri); ui->binary_uri = slv2_value_new_librdf_uri(world, binary_uri); assert(ui->binary_uri); // FIXME: kludge char* bundle = strdup(slv2_value_as_string(ui->binary_uri)); char* last_slash = strrchr(bundle, '/') + 1; *last_slash = '\0'; ui->bundle_uri = slv2_value_new_uri(world, bundle); free(bundle); ui->classes = slv2_values_new(); raptor_sequence_push(ui->classes, slv2_value_new_librdf_uri(world, type_uri)); return ui; } /* private */ void slv2_ui_free(SLV2UI ui) { slv2_value_free(ui->uri); ui->uri = NULL; slv2_value_free(ui->bundle_uri); ui->bundle_uri = NULL; slv2_value_free(ui->binary_uri); ui->binary_uri = NULL; slv2_values_free(ui->classes); free(ui); } SLV2Value slv2_ui_get_uri(SLV2UI ui) { assert(ui); assert(ui->uri); return ui->uri; } SLV2Values slv2_ui_get_classes(SLV2UI ui) { return ui->classes; } bool slv2_ui_is_a(SLV2UI ui, SLV2Value ui_class_uri) { return slv2_values_contains(ui->classes, ui_class_uri); } SLV2Value slv2_ui_get_bundle_uri(SLV2UI ui) { assert(ui); assert(ui->bundle_uri); return ui->bundle_uri; } SLV2Value slv2_ui_get_binary_uri(SLV2UI ui) { assert(ui); assert(ui->binary_uri); return ui->binary_uri; } slv2-0.6.6+dfsg1/src/util.c0000644000175000017500000000402711231361306015200 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include "slv2/util.h" char* slv2_strjoin(const char* first, ...) { /* FIXME: This is, in fact, as stupid as it looks */ size_t len = strlen(first); char* result = NULL; va_list args; va_start(args, first); while (1) { const char* const s = va_arg(args, const char *); if (s == NULL) break; len += strlen(s); } va_end(args); result = malloc(len + 1); if (!result) return NULL; strcpy(result, first); va_start(args, first); while (1) { const char* const s = va_arg(args, const char *); if (s == NULL) break; strcat(result, s); } va_end(args); return result; } const char* slv2_uri_to_path(const char* uri) { if (!strncmp(uri, "file://", (size_t)7)) return (char*)(uri + 7); else return NULL; } char* slv2_get_lang() { static char lang[32]; lang[31] = '\0'; char* tmp = getenv("LANG"); if (!tmp) { lang[0] = '\0'; } else { strncpy(lang, tmp, 31); for (int i = 0; i < 31 && lang[i]; ++i) { if (lang[i] == '_') { lang[i] = '-'; } else if ( !(lang[i] >= 'a' && lang[i] <= 'z') && !(lang[i] >= 'A' && lang[i] <= 'Z')) { lang[i] = '\0'; break; } } } return lang; } slv2-0.6.6+dfsg1/src/slv2_internal.h0000644000175000017500000001437311231361306017017 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __SLV2_INTERNAL_H__ #define __SLV2_INTERNAL_H__ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include "slv2/types.h" #include "slv2/lv2_ui.h" /* ********* PORT ********* */ /** Reference to a port on some plugin. */ struct _SLV2Port { uint32_t index; ///< lv2:index SLV2Value symbol; ///< lv2:symbol SLV2Values classes; ///< rdf:type }; SLV2Port slv2_port_new(SLV2World world, uint32_t index, const char* symbol); //SLV2Port slv2_port_duplicate(SLV2Port port); void slv2_port_free(SLV2Port port); /* ********* Plugin ********* */ /** Record of an installed/available plugin. * * A simple reference to a plugin somewhere on the system. This just holds * paths of relevant files, the actual data therein isn't loaded into memory. */ struct _SLV2Plugin { struct _SLV2World* world; SLV2Value plugin_uri; SLV2Value bundle_uri; ///< Bundle directory plugin was loaded from SLV2Value binary_uri; ///< lv2:binary SLV2PluginClass plugin_class; raptor_sequence* data_uris; ///< rdfs::seeAlso raptor_sequence* ports; librdf_storage* storage; librdf_model* rdf; }; SLV2Plugin slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri); void slv2_plugin_load(SLV2Plugin p); void slv2_plugin_load_if_necessary(SLV2Plugin p); void slv2_plugin_load_ports_if_necessary(SLV2Plugin p); void slv2_plugin_free(SLV2Plugin plugin); void slv2_plugin_get_port_float_values(SLV2Plugin p, const char* qname, float* values); /* ********* Plugins ********* */ /** Create a new, empty plugin list. * * Returned object must be freed with slv2_plugins_free. */ SLV2Plugins slv2_plugins_new(); /* ********* Instance ********* */ /** Pimpl portion of SLV2Instance */ struct _InstanceImpl { void* lib_handle; }; /* ********* UI Instance ********* */ struct _SLV2UIInstanceImpl { void* lib_handle; const LV2UI_Descriptor* lv2ui_descriptor; LV2UI_Handle lv2ui_handle; LV2UI_Widget widget; }; /* ********* Plugin Class ********* */ struct _SLV2PluginClass { struct _SLV2World* world; SLV2Value parent_uri; SLV2Value uri; SLV2Value label; }; SLV2PluginClass slv2_plugin_class_new(SLV2World world, librdf_uri* parent_uri, librdf_uri* uri, const char* label); void slv2_plugin_class_free(SLV2PluginClass plugin_class); /* ********* Plugin Classes ********* */ SLV2PluginClasses slv2_plugin_classes_new(); void slv2_plugin_classes_free(); /* ********* World ********* */ /** Model of LV2 (RDF) data loaded from bundles. */ struct _SLV2World { bool local_world; librdf_world* world; librdf_storage* storage; librdf_model* model; librdf_parser* parser; SLV2PluginClass lv2_plugin_class; SLV2PluginClasses plugin_classes; SLV2Plugins plugins; librdf_node* lv2_specification_node; librdf_node* lv2_plugin_node; librdf_node* rdf_a_node; librdf_node* xsd_integer_node; librdf_node* xsd_decimal_node; }; /** Load all bundles found in \a search_path. * * \param search_path A colon-delimited list of directories. These directories * should contain LV2 bundle directories (ie the search path is a list of * parent directories of bundles, not a list of bundle directories). * * If \a search_path is NULL, \a world will be unmodified. * Use of this function is \b not recommended. Use \ref slv2_world_load_all. */ void slv2_world_load_path(SLV2World world, const char* search_path); void slv2_world_load_specifications(SLV2World world); void slv2_world_load_file(SLV2World world, librdf_uri* file_uri); /* ********* Plugin UI ********* */ struct _SLV2UI { struct _SLV2World* world; SLV2Value uri; SLV2Value bundle_uri; SLV2Value binary_uri; SLV2Values classes; }; SLV2UIs slv2_uis_new(); SLV2UI slv2_ui_new(SLV2World world, librdf_uri* uri, librdf_uri* type_uri, librdf_uri* binary_uri); void slv2_ui_free(SLV2UI ui); /* ********* Value ********* */ typedef enum _SLV2ValueType { SLV2_VALUE_URI, SLV2_VALUE_QNAME_UNUSED, ///< FIXME: APIBREAK: remove SLV2_VALUE_STRING, SLV2_VALUE_INT, SLV2_VALUE_FLOAT, } SLV2ValueType; struct _SLV2Value { SLV2ValueType type; char* str_val; ///< always present union { int int_val; float float_val; librdf_uri* uri_val; } val; }; SLV2Value slv2_value_new(SLV2World world, SLV2ValueType type, const char* val); SLV2Value slv2_value_new_librdf_node(SLV2World world, librdf_node* node); SLV2Value slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri); librdf_uri* slv2_value_as_librdf_uri(SLV2Value value); /* ********* Values ********* */ void slv2_values_set_at(SLV2Values list, unsigned index, void* value); /* ********* Scale Points ********* */ struct _SLV2ScalePoint { SLV2Value value; SLV2Value label; }; SLV2ScalePoint slv2_scale_point_new(SLV2Value value, SLV2Value label); void slv2_scale_point_free(SLV2ScalePoint point); /* ********* Query Results********* */ struct _SLV2Results { SLV2World world; librdf_query_results* rdf_results; }; /* ********* Utilities ********* */ char* slv2_strjoin(const char* first, ...); char* slv2_get_lang(); #ifdef __cplusplus } #endif #endif /* __SLV2_INTERNAL_H__ */ slv2-0.6.6+dfsg1/src/collections.c0000644000175000017500000000652511231361306016546 0ustar alessioalessio/* SLV2 * Copyright (C) 2008-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include "slv2/collections.h" #include "slv2/pluginclass.h" #include "slv2/pluginui.h" #include "slv2_internal.h" #define SLV2_COLLECTION_IMPL(CollType, ElemType, prefix, free_func) \ \ CollType \ prefix ## _new() \ { \ return raptor_new_sequence((void (*)(void*))free_func, NULL); \ } \ \ \ void \ prefix ## _free(CollType coll) \ { \ if (coll) \ raptor_free_sequence(coll); \ } \ \ \ unsigned \ prefix ## _size(CollType coll) \ { \ return (coll ? raptor_sequence_size(coll) : 0); \ } \ \ \ ElemType \ prefix ## _get_at(CollType coll, unsigned index) \ { \ if (index > INT_MAX) \ return NULL; \ else \ return (ElemType)raptor_sequence_get_at(coll, (int)index); \ } SLV2_COLLECTION_IMPL(SLV2PluginClasses, SLV2PluginClass, slv2_plugin_classes, &slv2_plugin_class_free) SLV2_COLLECTION_IMPL(SLV2ScalePoints, SLV2ScalePoint, slv2_scale_points, &slv2_scale_point_free) SLV2_COLLECTION_IMPL(SLV2Values, SLV2Value, slv2_values, &slv2_value_free) SLV2_COLLECTION_IMPL(SLV2UIs, SLV2UI, slv2_uis, &slv2_ui_free) /* **** PLUGIN CLASSES **** */ SLV2PluginClass slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, SLV2Value uri) { // good old fashioned binary search int lower = 0; int upper = raptor_sequence_size(list) - 1; int i; while (upper >= lower) { i = lower + ((upper - lower) / 2); SLV2PluginClass p = raptor_sequence_get_at(list, i); const int cmp = strcmp(slv2_value_as_uri(slv2_plugin_class_get_uri(p)), slv2_value_as_uri(uri)); if (cmp == 0) return p; else if (cmp > 0) upper = i - 1; else lower = i + 1; } return NULL; } /* **** VALUES **** */ bool slv2_values_contains(SLV2Values list, SLV2Value value) { for (unsigned i=0; i < slv2_values_size(list); ++i) if (slv2_value_equals(slv2_values_get_at(list, i), value)) return true; return false; } void slv2_values_set_at(SLV2Values list, unsigned index, void* value) { if (index <= INT_MAX) raptor_sequence_set_at(list, index, value); } /* **** PLUGIN UIS **** */ SLV2UI slv2_uis_get_by_uri(SLV2UIs list, SLV2Value uri) { // good old fashioned binary search int lower = 0; int upper = raptor_sequence_size(list) - 1; int i; while (upper >= lower) { i = lower + ((upper - lower) / 2); SLV2UI ui = raptor_sequence_get_at(list, i); const int cmp = strcmp(slv2_value_as_uri(slv2_ui_get_uri(ui)), slv2_value_as_uri(uri)); if (cmp == 0) return ui; else if (cmp > 0) upper = i - 1; else lower = i + 1; } return NULL; } slv2-0.6.6+dfsg1/src/query.c0000644000175000017500000001523111231361306015367 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include "slv2/types.h" #include "slv2/collections.h" #include "slv2/plugin.h" #include "slv2/query.h" #include "slv2/util.h" #include "slv2_internal.h" static const char* slv2_query_prefixes = "PREFIX rdf: \n" "PREFIX rdfs: \n" "PREFIX doap: \n" "PREFIX foaf: \n" "PREFIX lv2: \n" "PREFIX lv2ev: \n"; /** Create a new SLV2Value from a librdf_node, or return NULL if impossible */ SLV2Value slv2_value_from_librdf_node(SLV2World world, librdf_node* node) { SLV2Value result = NULL; librdf_uri* datatype_uri = NULL; SLV2ValueType type = SLV2_VALUE_STRING; switch (librdf_node_get_type(node)) { case LIBRDF_NODE_TYPE_RESOURCE: type = SLV2_VALUE_URI; result = slv2_value_new_librdf_uri(world, librdf_node_get_uri(node)); break; case LIBRDF_NODE_TYPE_LITERAL: datatype_uri = librdf_node_get_literal_value_datatype_uri(node); if (datatype_uri) { if (!strcmp((const char*)librdf_uri_as_string(datatype_uri), "http://www.w3.org/2001/XMLSchema#integer")) type = SLV2_VALUE_INT; else if (!strcmp((const char*)librdf_uri_as_string(datatype_uri), "http://www.w3.org/2001/XMLSchema#decimal")) type = SLV2_VALUE_FLOAT; else fprintf(stderr, "Unknown datatype %s\n", librdf_uri_as_string(datatype_uri)); } result = slv2_value_new(world, type, (const char*)librdf_node_get_literal_value(node)); break; case LIBRDF_NODE_TYPE_BLANK: type = SLV2_VALUE_STRING; result = slv2_value_new(world, type, (const char*)librdf_node_get_blank_identifier(node)); break; case LIBRDF_NODE_TYPE_UNKNOWN: default: fprintf(stderr, "Unknown RDF node type %d\n", librdf_node_get_type(node)); break; } return result; } SLV2Values slv2_query_get_variable_bindings(SLV2World world, SLV2Results results, int variable) { SLV2Values result = NULL; if (!librdf_query_results_finished(results->rdf_results)) result = slv2_values_new(); while (!librdf_query_results_finished(results->rdf_results)) { librdf_node* node = librdf_query_results_get_binding_value(results->rdf_results, variable); if (node == NULL) { fprintf(stderr, "SLV2 ERROR: Variable %d bound to NULL.\n", variable); librdf_query_results_next(results->rdf_results); continue; } SLV2Value val = slv2_value_from_librdf_node(world, node); if (val) raptor_sequence_push(result, val); librdf_free_node(node); librdf_query_results_next(results->rdf_results); } return result; } unsigned slv2_results_size(SLV2Results results) { size_t count = 0; while (!slv2_results_finished(results)) { ++count; slv2_results_next(results); } return count; } SLV2Results slv2_plugin_query_sparql(SLV2Plugin plugin, const char* sparql_str) { slv2_plugin_load_if_necessary(plugin); librdf_uri* base_uri = slv2_value_as_librdf_uri(plugin->plugin_uri); char* query_str = slv2_strjoin(slv2_query_prefixes, sparql_str, NULL); //printf("******** Query \n%s********\n", query_str); librdf_query* query = librdf_new_query(plugin->world->world, "sparql", NULL, (const unsigned char*)query_str, base_uri); if (!query) { fprintf(stderr, "ERROR: Could not create query\n"); return NULL; } // FIXME: locale kludges to work around librdf bug char* locale = strdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, "POSIX"); librdf_query_results* results = librdf_query_execute(query, plugin->rdf); setlocale(LC_NUMERIC, locale); free(locale); librdf_free_query(query); free(query_str); SLV2Results ret = (SLV2Results)malloc(sizeof(struct _SLV2Results)); ret->world = plugin->world; ret->rdf_results = results; return ret; } void slv2_results_free(SLV2Results results) { librdf_free_query_results(results->rdf_results); free(results); } bool slv2_results_finished(SLV2Results results) { return librdf_query_results_finished(results->rdf_results); } SLV2Value slv2_results_get_binding_value(SLV2Results results, unsigned index) { return slv2_value_from_librdf_node(results->world, librdf_query_results_get_binding_value( results->rdf_results, index)); } SLV2Value slv2_results_get_binding_value_by_name(SLV2Results results, const char* name) { return slv2_value_from_librdf_node(results->world, librdf_query_results_get_binding_value_by_name( results->rdf_results, name)); } const char* slv2_results_get_binding_name(SLV2Results results, unsigned index) { return librdf_query_results_get_binding_name(results->rdf_results, index); } void slv2_results_next(SLV2Results results) { librdf_query_results_next(results->rdf_results); } /** Query a single variable */ SLV2Values slv2_plugin_query_variable(SLV2Plugin plugin, const char* sparql_str, unsigned variable) { assert(variable < INT_MAX); SLV2Results results = slv2_plugin_query_sparql(plugin, sparql_str); SLV2Values ret = slv2_query_get_variable_bindings(plugin->world, results, (int)variable); slv2_results_free(results); return ret; } /** Run a query and count number of matches. * * More efficient than slv2_plugin_simple_query if you're only interested * in the number of results (ie slv2_plugin_num_ports). * * Note the result of this function is probably meaningless unless the query * is a SELECT DISTINCT. */ unsigned slv2_plugin_query_count(SLV2Plugin plugin, const char* sparql_str) { SLV2Results results = slv2_plugin_query_sparql(plugin, sparql_str); unsigned ret = 0; if (results) { ret = slv2_results_size(results); slv2_results_free(results); } return ret; } slv2-0.6.6+dfsg1/src/plugininstance.c0000644000175000017500000000757011231361306017254 0ustar alessioalessio/* SLV2 * Copyright (C) 2007-2009 Dave Robillard * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include "slv2/plugin.h" #include "slv2/plugininstance.h" #include "slv2/types.h" #include "slv2/util.h" #include "slv2/value.h" #include "slv2_internal.h" SLV2Instance slv2_plugin_instantiate(SLV2Plugin plugin, double sample_rate, const LV2_Feature*const* features) { struct _Instance* result = NULL; const LV2_Feature** local_features = NULL; if (features == NULL) { local_features = malloc(sizeof(LV2_Feature)); local_features[0] = NULL; } const char* const lib_uri = slv2_value_as_uri(slv2_plugin_get_library_uri(plugin)); const char* const lib_path = slv2_uri_to_path(lib_uri); if (!lib_path) return NULL; dlerror(); void* lib = dlopen(lib_path, RTLD_NOW); if (!lib) { fprintf(stderr, "Unable to open library %s (%s)\n", lib_path, dlerror()); return NULL; } LV2_Descriptor_Function df = dlsym(lib, "lv2_descriptor"); if (!df) { fprintf(stderr, "Could not find symbol 'lv2_descriptor', " "%s is not a LV2 plugin.\n", lib_path); dlclose(lib); return NULL; } else { // Search for plugin by URI // FIXME: Kludge to get bundle path (containing directory of binary) const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri( slv2_plugin_get_bundle_uri(plugin))); //printf("Bundle path: %s\n", bundle_path); for (uint32_t i=0; 1; ++i) { const LV2_Descriptor* ld = df(i); if (!ld) { fprintf(stderr, "Did not find plugin %s in %s\n", slv2_value_as_uri(slv2_plugin_get_uri(plugin)), lib_path); dlclose(lib); break; // return NULL } else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_plugin_get_uri(plugin)))) { assert(plugin->plugin_uri); //printf("Found %s at index %u in:\n\t%s\n\n", // librdf_uri_as_string(plugin->plugin_uri), i, lib_path); assert(ld->instantiate); // Create SLV2Instance to return result = malloc(sizeof(struct _Instance)); result->lv2_descriptor = ld; result->lv2_handle = ld->instantiate(ld, sample_rate, (char*)bundle_path, (features) ? features : local_features); struct _InstanceImpl* impl = malloc(sizeof(struct _InstanceImpl)); impl->lib_handle = lib; result->pimpl = impl; break; } } } if (result) { assert(slv2_plugin_get_num_ports(plugin) > 0); // Failed to instantiate if (result->lv2_handle == NULL) { //printf("Failed to instantiate %s\n", plugin->plugin_uri); free(result); return NULL; } // "Connect" all ports to NULL (catches bugs) for (uint32_t i=0; i < slv2_plugin_get_num_ports(plugin); ++i) result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL); } free(local_features); return result; } void slv2_instance_free(SLV2Instance instance) { if (!instance) return; struct _Instance* i = (struct _Instance*)instance; i->lv2_descriptor->cleanup(i->lv2_handle); i->lv2_descriptor = NULL; dlclose(i->pimpl->lib_handle); i->pimpl->lib_handle = NULL; free(i->pimpl); i->pimpl = NULL; free(i); }