Commit 7e5a553e authored by Garrett Regier's avatar Garrett Regier Committed by Colin Walters

scanner: Add --symbol-filter-cmd

Add the command line flag --symbol-filter-cmd to g-ir-scanner
which allows running symbol names through a filtering shell
command. The symbol is sent as stdin to the filter command
and expects a filtered result written to stdout.

https://bugzilla.gnome.org/show_bug.cgi?id=744534Signed-off-by: 's avatarGarrett Regier <garrett.regier@riftio.com>
parent 564e3b1b
......@@ -83,6 +83,7 @@ tests/scanner/Utility-1.0.gir
tests/scanner/WarnLib-1.0.gir
tests/scanner/barapp
tests/scanner/Identfilter-1.0.gir
tests/scanner/Symbolfilter-1.0.gir
tests/scanner/Typedefs-1.0.gir
tests/doctool/DocExamples-1.0.gir
tests/offsets/Offsets-1.0.gir
......
......@@ -164,6 +164,11 @@ the latter is not specified.""")
parser.add_option("", "--symbol-prefix",
action="append", dest="symbol_prefixes", default=[],
help="Remove this prefix from C symbols (function names)")
parser.add_option("", "--symbol-filter-cmd",
action="store", dest="symbol_filter_cmd", default='',
help='Filter symbols (function names) through the given '
'shell command which will receive the symbol name as input '
'to stdin and is expected to output the filtered results to stdout.')
parser.add_option("", "--accept-unprefixed",
action="store_true", dest="accept_unprefixed", default=False,
help="""If specified, accept symbols and identifiers that do not
......@@ -367,7 +372,8 @@ see --identifier-prefix and --symbol-prefix."""
def create_transformer(namespace, options):
transformer = Transformer(namespace,
accept_unprefixed=options.accept_unprefixed,
identifier_filter_cmd=options.identifier_filter_cmd)
identifier_filter_cmd=options.identifier_filter_cmd,
symbol_filter_cmd=options.symbol_filter_cmd)
transformer.set_include_paths(options.include_paths)
if options.passthrough_gir:
transformer.disable_cache()
......
......@@ -50,7 +50,8 @@ if os.name != 'nt':
class Transformer(object):
namespace = property(lambda self: self._namespace)
def __init__(self, namespace, accept_unprefixed=False, identifier_filter_cmd=''):
def __init__(self, namespace, accept_unprefixed=False,
identifier_filter_cmd='', symbol_filter_cmd=''):
self._cachestore = CacheStore()
self._accept_unprefixed = accept_unprefixed
self._namespace = namespace
......@@ -60,6 +61,7 @@ class Transformer(object):
self._includepaths = []
self._passthrough_mode = False
self._identifier_filter_cmd = identifier_filter_cmd
self._symbol_filter_cmd = symbol_filter_cmd
# Cache a list of struct/unions in C's "tag namespace". This helps
# manage various orderings of typedefs and structs. See:
......@@ -242,6 +244,18 @@ currently-scanned namespace is first."""
return cmp(x[2], y[2])
def _split_c_string_for_namespace_matches(self, name, is_identifier=False):
if not is_identifier and self._symbol_filter_cmd:
proc = subprocess.Popen(self._symbol_filter_cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
_name = name
name, err = proc.communicate(name)
if proc.returncode:
raise ValueError('filter: "%s" exited: %d with error: %s' %
(self._symbol_filter_cmd, proc.returncode, err))
matches = [] # Namespaces which might contain this name
unprefixed_namespaces = [] # Namespaces with no prefix, last resort
for ns in self._iter_namespaces():
......
......@@ -188,6 +188,20 @@ Identfilter-1.0.gir: identfilter.h
--identifier-filter-cmd="$(PYTHON) $(srcdir)/identfilter.py" \
--output=$@ $<
EXTRA_DIST += \
symbolfilter.py \
symbolfilter.h \
Symbolfilter-1.0-expected.gir
CLEANFILES += Symbolfilter-1.0.gir
CHECKGIRS += Symbolfilter-1.0.gir
Symbolfilter-1.0.gir: symbolfilter.h
$(AM_V_GEN) $(INTROSPECTION_SCANNER) $(INTROSPECTION_SCANNER_ARGS) \
--warn-all --reparse-validate \
--namespace=Symbolfilter --accept-unprefixed --nsversion=1.0 --header-only \
--symbol-filter-cmd="$(PYTHON) $(srcdir)/symbolfilter.py" \
--output=$@ $<
if BUILD_DOCTOOL
DOCGIRS = Regress-1.0.gir
CHECKDOCS = $(DOCGIRS:.gir=-C) $(DOCGIRS:.gir=-Python) $(DOCGIRS:.gir=-Gjs) $(DOCGIRS:.gir=-sections.txt)
......
<?xml version="1.0"?>
<!-- This file was automatically generated from C sources - DO NOT EDIT!
To affect the contents of this file, edit the original C definitions,
and/or use gtk-doc annotations. -->
<repository version="1.2"
xmlns="http://www.gtk.org/introspection/core/1.0"
xmlns:c="http://www.gtk.org/introspection/c/1.0"
xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
<namespace name="Symbolfilter"
version="1.0"
shared-library=""
c:identifier-prefixes="Symbolfilter"
c:symbol-prefixes="symbolfilter">
<record name="Object" c:type="SymbolfilterObject" disguised="1">
<method name="filterObjectFooMethod"
c:identifier="SymbolfilterObjectFooMethod">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
<parameters>
<instance-parameter name="self" transfer-ownership="none">
<type name="Object" c:type="SymbolfilterObject*"/>
</instance-parameter>
</parameters>
</method>
<method name="filterObjectFree" c:identifier="SymbolfilterObjectFree">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
<parameters>
<instance-parameter name="self" transfer-ownership="none">
<type name="Object" c:type="SymbolfilterObject*"/>
</instance-parameter>
</parameters>
</method>
<function name="new"
c:identifier="SymbolfilterObjectNew"
introspectable="0">
<return-value>
<type name="Object" c:type="SymbolfilterObject*"/>
</return-value>
</function>
</record>
</namespace>
</repository>
#ifndef __SYMBOLFILTER_H__
#define __SYMBOLFILTER_H__
typedef struct _SymbolfilterObject SymbolfilterObject;
SymbolfilterObject *SymbolfilterObjectNew (void);
void SymbolfilterObjectFooMethod (SymbolfilterObject *self);
void SymbolfilterObjectFree (SymbolfilterObject *self);
#endif
# -*- Mode: Python; py-indent-offset: 4 -*-
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (C) 2015 Garrett Regier <garrett.regier@riftio.com>
#
# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
"""
Script which reads symbols in the form of "FooBar" from stdin and
translates them to snake case like "foo_bar".
"""
import sys
def ensure_snake_case(text):
text = ''.join(x if x.islower() else '_' + x.lower() for x in text)
# Remove the extra '_' for the starting uppercase letter
return text[1:]
if __name__ == '__main__':
text = ensure_snake_case(sys.stdin.read())
sys.stdout.write(text)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment