This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Ping! On Tue, Feb 11, 2014 at 10:02:02AM +0530, Siddhesh Poyarekar wrote: > Ping! > > On Thu, Jan 09, 2014 at 04:49:07PM +0530, Siddhesh Poyarekar wrote: > > Hi Mike, > > > > Did you get a chance to look at this? I'm not looking to push this > > into 2.19, so even if you ack it now, I'll hold on to it till 2.20 > > development opens. > > > > Thanks, > > Siddhesh > > > > On Tue, Dec 31, 2013 at 03:13:02PM +0530, Siddhesh Poyarekar wrote: > > > On Tue, Dec 31, 2013 at 03:45:30AM -0500, Mike Frysinger wrote: > > > > largely looks good. mostly nits below. > > > > > > > > when it comes to declaring coding style, i'm not sure the GNU project has one > > > > already for python (since they try to push Guile/scheme). GDB has been > > > > growing a python code base, but a scan of that tree doesn't turn up anything > > > > either :(. > > > > > > > > looking around the glibc tree, i think adding a section to manual/maint.texi > > > > would be the best bet. > > > > > > Wouldn't [1] be a good place for this kind of documentation? > > > > > > [1] https://sourceware.org/glibc/wiki/Style_and_Conventions > > > > > > However, I believe we should have an in-tree document that at least > > > points to the relevant wiki pages for occasional contributors. > > > > > > > > --- /dev/null > > > > > +++ b/scripts/pylintrc > > > > > > > > any reason for that vs generating a default one and tweaking it ? see > > > > pylint's --generate-rcfile option. > > > > > > In fact, I generated the default and dumped everything I didn't > > > change, thinking that it would be easier for you to review a smaller > > > file :) I've included the generated and tweaked rcfile now. How does > > > this iteration look? > > > > > > Siddhesh > > > > > > > > > * scripts/bench.pl: Remove file. > > > * scripts/bench.py: New benchmark script. > > > * benchtests/Makefile ($(objpfx)bench-%.c): Use it. > > > * benchtests/README: Mention python dependency. > > > * scripts/pylintrc: New file. > > > * scripts/pylint: New file. > > > > > > diff --git a/benchtests/Makefile b/benchtests/Makefile > > > index 117228b..3d41274 100644 > > > --- a/benchtests/Makefile > > > +++ b/benchtests/Makefile > > > @@ -127,5 +127,5 @@ $(objpfx)bench-%.c: %-inputs $(bench-deps) > > > { if [ -n "$($*-INCLUDE)" ]; then \ > > > cat $($*-INCLUDE); \ > > > fi; \ > > > - $(..)scripts/bench.pl $(patsubst %-inputs,%,$<); } > $@-tmp > > > + $(..)scripts/bench.py $(patsubst %-inputs,%,$<); } > $@-tmp > > > mv -f $@-tmp $@ > > > diff --git a/benchtests/README b/benchtests/README > > > index a5fd8da..2a940fa 100644 > > > --- a/benchtests/README > > > +++ b/benchtests/README > > > @@ -8,7 +8,9 @@ basic performance properties of the function. > > > Running the benchmark: > > > ===================== > > > > > > -The benchmark can be executed by invoking make as follows: > > > +The benchmark needs python 2.7 or later in addition to the > > > +dependencies required to build the GNU C Library. One may run the > > > +benchmark by invoking make as follows: > > > > > > $ make bench > > > > > > diff --git a/scripts/bench.pl b/scripts/bench.pl > > > deleted file mode 100755 > > > index 10f0ba4..0000000 > > > diff --git a/scripts/bench.py b/scripts/bench.py > > > new file mode 100755 > > > index 0000000..7c3ef04 > > > --- /dev/null > > > +++ b/scripts/bench.py > > > @@ -0,0 +1,299 @@ > > > +#!/usr/bin/python > > > +# Copyright (C) 2013 Free Software Foundation, Inc. > > > +# This file is part of the GNU C Library. > > > +# > > > +# The GNU C 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. > > > +# > > > +# The GNU C 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 the GNU C Library; if not, see > > > +# <http://www.gnu.org/licenses/>. > > > + > > > +"""Benchmark program generator script > > > + > > > +This script takes a function name as input and generates a program using > > > +an input file located in the benchtests directory. The name of the > > > +input file should be of the form foo-inputs where 'foo' is the name of > > > +the function. > > > +""" > > > + > > > +from __future__ import print_function > > > +import sys > > > +import os > > > +import itertools > > > + > > > +# Macro definitions for functions that take no arguments. For functions > > > +# that take arguments, the STRUCT_TEMPLATE, ARGS_TEMPLATE and > > > +# VARIANTS_TEMPLATE are used instead. > > > +DEFINES_TEMPLATE = ''' > > > +#define CALL_BENCH_FUNC(v, i) %(func)s () > > > +#define NUM_VARIANTS (1) > > > +#define NUM_SAMPLES(v) (1) > > > +#define VARIANT(v) FUNCNAME "()" > > > +''' > > > + > > > +# Structures to store arguments for the function call. A function may > > > +# have its inputs partitioned to represent distinct performance > > > +# characteristics or distinct flavors of the function. Each such > > > +# variant is represented by the _VARIANT structure. The ARGS structure > > > +# represents a single set of arguments. > > > +STRUCT_TEMPLATE = ''' > > > +#define CALL_BENCH_FUNC(v, i) %(func)s (%(func_args)s) > > > + > > > +struct args > > > +{ > > > +%(args)s > > > +}; > > > + > > > +struct _variants > > > +{ > > > + const char *name; > > > + int count; > > > + struct args *in; > > > +}; > > > +''' > > > + > > > +# The actual input arguments. > > > +ARGS_TEMPLATE = ''' > > > +struct args in%(argnum)d[%(num_args)d] = { > > > +%(args)s > > > +}; > > > +''' > > > + > > > +# The actual variants, along with macros defined to access the variants. > > > +VARIANTS_TEMPLATE = ''' > > > +struct _variants variants[%(num_variants)d] = { > > > +%(variants)s > > > +}; > > > + > > > +#define NUM_VARIANTS %(num_variants)d > > > +#define NUM_SAMPLES(i) (variants[i].count) > > > +#define VARIANT(i) (variants[i].name) > > > +''' > > > + > > > +# Epilogue for the generated source file. > > > +EPILOGUE = ''' > > > +#define BENCH_FUNC(i, j) ({%(getret)s CALL_BENCH_FUNC (i, j);}) > > > +#define FUNCNAME "%(func)s" > > > +#include "bench-skeleton.c"''' > > > + > > > + > > > +def gen_source(func, directives, all_vals): > > > + """Generate source for the function > > > + > > > + Generate the C source for the function from the values and > > > + directives. > > > + > > > + Args: > > > + func: The function name > > > + directives: A dictionary of directives applicable to this function > > > + all_vals: A dictionary input values > > > + """ > > > + # The includes go in first. > > > + for header in directives['includes']: > > > + print('#include <%s>' % header) > > > + > > > + for header in directives['include-sources']: > > > + print('#include "%s"' % header) > > > + > > > + # Print macros. This branches out to a separate routine if > > > + # the function takes arguments. > > > + if not directives['args']: > > > + print(DEFINES_TEMPLATE % {'func': func}) > > > + outargs = [] > > > + else: > > > + outargs = _print_arg_data(func, directives, all_vals) > > > + > > > + # Print the output variable definitions if necessary. > > > + for out in outargs: > > > + print(out) > > > + > > > + # If we have a return value from the function, make sure it is > > > + # assigned to prevent the compiler from optimizing out the > > > + # call. > > > + if directives['ret']: > > > + print('static %s volatile ret;' % directives['ret']) > > > + getret = 'ret = ' > > > + else: > > > + getret = '' > > > + > > > + print(EPILOGUE % {'getret': getret, 'func': func}) > > > + > > > + > > > +def _print_arg_data(func, directives, all_vals): > > > + """Print argument data > > > + > > > + This is a helper function for gen_source that prints structure and > > > + values for arguments and their variants and returns output arguments > > > + if any are found. > > > + > > > + Args: > > > + func: Function name > > > + directives: A dictionary of directives applicable to this function > > > + all_vals: A dictionary input values > > > + > > > + Returns: > > > + Returns a list of definitions for function arguments that act as > > > + output parameters. > > > + """ > > > + # First, all of the definitions. We process writing of > > > + # CALL_BENCH_FUNC, struct args and also the output arguments > > > + # together in a single traversal of the arguments list. > > > + func_args = [] > > > + arg_struct = [] > > > + outargs = [] > > > + > > > + for arg, i in zip(directives['args'], itertools.count()): > > > + if arg[0] == '<' and arg[-1] == '>': > > > + pos = arg.rfind('*') > > > + if pos == -1: > > > + die('Output argument must be a pointer type') > > > + > > > + outargs.append('static %s out%d;' % (arg[1:pos], i)) > > > + func_args.append(' &out%d' % i) > > > + else: > > > + arg_struct.append(' %s volatile arg%d;' % (arg, i)) > > > + func_args.append('variants[v].in[i].arg%d' % i) > > > + > > > + print(STRUCT_TEMPLATE % {'args' : '\n'.join(arg_struct), 'func': func, > > > + 'func_args': ', '.join(func_args)}) > > > + > > > + # Now print the values. > > > + variants = [] > > > + for (k, vals), i in zip(all_vals.items(), itertools.count()): > > > + out = [' {%s},' % v for v in vals] > > > + > > > + # Members for the variants structure list that we will > > > + # print later. > > > + variants.append(' {"%s(%s)", %d, in%d},' % (func, k, len(vals), i)) > > > + print(ARGS_TEMPLATE % {'argnum': i, 'num_args': len(vals), > > > + 'args': '\n'.join(out)}) > > > + > > > + # Print the variants and the last set of macros. > > > + print(VARIANTS_TEMPLATE % {'num_variants': len(all_vals), > > > + 'variants': '\n'.join(variants)}) > > > + return outargs > > > + > > > + > > > +def _process_directive(d_name, d_val): > > > + """Process a directive. > > > + > > > + Evaluate the directive name and value passed and return the > > > + processed value. This is a helper function for parse_file. > > > + > > > + Args: > > > + d_name: Name of the directive > > > + d_value: The string value to process > > > + > > > + Returns: > > > + The processed value, which may be the string as it is or an object > > > + that describes the directive. > > > + """ > > > + # Process the directive values if necessary. name and ret don't > > > + # need any processing. > > > + if d_name.startswith('include'): > > > + d_val = d_val.split(',') > > > + elif d_name == 'args': > > > + d_val = d_val.split(':') > > > + > > > + # Return the values. > > > + return d_val > > > + > > > + > > > +def parse_file(func): > > > + """Parse an input file > > > + > > > + Given a function name, open and parse an input file for the function > > > + and get the necessary parameters for the generated code and the list > > > + of inputs. > > > + > > > + Args: > > > + func: The function name > > > + > > > + Returns: > > > + A tuple of two elements, one a dictionary of directives and the > > > + other a dictionary of all input values. > > > + """ > > > + all_vals = {} > > > + # Valid directives. > > > + directives = { > > > + 'name': '', > > > + 'args': [], > > > + 'includes': [], > > > + 'include-sources': [], > > > + 'ret': '' > > > + } > > > + > > > + try: > > > + with open('%s-inputs' % func) as f: > > > + for line in f: > > > + # Look for directives and parse it if found. > > > + if line.startswith('##'): > > > + try: > > > + d_name, d_val = line[2:].split(':', 1) > > > + d_name = d_name.strip() > > > + d_val = d_val.strip() > > > + directives[d_name] = _process_directive(d_name, d_val) > > > + except (IndexError, KeyError): > > > + die('Invalid directive: %s' % line[2:]) > > > + > > > + # Skip blank lines and comments. > > > + line = line.split('#', 1)[0].rstrip() > > > + if not line: > > > + continue > > > + > > > + # Otherwise, we're an input. Add to the appropriate > > > + # input set. > > > + cur_name = directives['name'] > > > + all_vals.setdefault(cur_name, []) > > > + all_vals[cur_name].append(line) > > > + except IOError as ex: > > > + die("Failed to open input file (%s): %s" % (ex.filename, ex.strerror)) > > > + > > > + return directives, all_vals > > > + > > > + > > > +def die(msg): > > > + """Exit with an error > > > + > > > + Prints an error message to the standard error stream and exits with > > > + a non-zero status. > > > + > > > + Args: > > > + msg: The error message to print to standard error. > > > + """ > > > + print('%s\n' % msg, file=sys.stderr) > > > + sys.exit(os.EX_DATAERR) > > > + > > > + > > > +def main(args): > > > + """Main function > > > + > > > + Use the first command line argument as function name and parse its > > > + input file to generate C source that calls the function repeatedly > > > + for the input. > > > + > > > + Args: > > > + args: The command line arguments with the program name dropped. > > > + > > > + Returns: > > > + os.EX_USAGE on error and os.EX_OK on success. > > > + """ > > > + if len(args) != 1: > > > + print('Usage: %s <function>' % sys.argv[0]) > > > + return os.EX_USAGE > > > + > > > + directives, all_vals = parse_file(args[0]) > > > + gen_source(args[0], directives, all_vals) > > > + return os.EX_OK > > > + > > > + > > > +if __name__ == '__main__': > > > + sys.exit(main(sys.argv[1:])) > > > diff --git a/scripts/pylint b/scripts/pylint > > > new file mode 100755 > > > index 0000000..49a775e > > > --- /dev/null > > > +++ b/scripts/pylint > > > @@ -0,0 +1,5 @@ > > > +#!/bin/sh > > > +# Simple wrapper around the pylint program that uses the pylintrc file to > > > +# validate the source code in files passed on command line. > > > + > > > +exec pylint --rcfile "${0%/*}/pylintrc" "$@" > > > diff --git a/scripts/pylintrc b/scripts/pylintrc > > > new file mode 100644 > > > index 0000000..a05ddfd > > > --- /dev/null > > > +++ b/scripts/pylintrc > > > @@ -0,0 +1,274 @@ > > > +[MASTER] > > > + > > > +# Specify a configuration file. > > > +#rcfile= > > > + > > > +# Python code to execute, usually for sys.path manipulation such as > > > +# pygtk.require(). > > > +#init-hook= > > > + > > > +# Profiled execution. > > > +profile=no > > > + > > > +# Add files or directories to the blacklist. They should be base names, not > > > +# paths. > > > +ignore=CVS > > > + > > > +# Pickle collected data for later comparisons. > > > +persistent=yes > > > + > > > +# List of plugins (as comma separated values of python modules names) to load, > > > +# usually to register additional checkers. > > > +load-plugins= > > > + > > > + > > > +[MESSAGES CONTROL] > > > + > > > +# Enable the message, report, category or checker with the given id(s). You can > > > +# either give multiple identifier separated by comma (,) or put this option > > > +# multiple time. See also the "--disable" option for examples. > > > +#enable= > > > + > > > +# Disable the message, report, category or checker with the given id(s). You > > > +# can either give multiple identifiers separated by comma (,) or put this > > > +# option multiple times (only on the command line, not in the configuration > > > +# file where it should appear only once).You can also use "--disable=all" to > > > +# disable everything first and then reenable specific checks. For example, if > > > +# you want to run only the similarities checker, you can use "--disable=all > > > +# --enable=similarities". If you want to run only the classes checker, but have > > > +# no Warning level messages displayed, use"--disable=all --enable=classes > > > +# --disable=W" > > > +#disable= > > > + > > > + > > > +[REPORTS] > > > + > > > +# Set the output format. Available formats are text, parseable, colorized, msvs > > > +# (visual studio) and html. You can also give a reporter class, eg > > > +# mypackage.mymodule.MyReporterClass. > > > +output-format=text > > > + > > > +# Put messages in a separate file for each module / package specified on the > > > +# command line instead of printing them on stdout. Reports (if any) will be > > > +# written in a file name "pylint_global.[txt|html]". > > > +files-output=no > > > + > > > +# Tells whether to display a full report or only the messages > > > +reports=yes > > > + > > > +# Python expression which should return a note less than 10 (10 is the highest > > > +# note). You have access to the variables errors warning, statement which > > > +# respectively contain the number of errors / warnings messages and the total > > > +# number of statements analyzed. This is used by the global evaluation report > > > +# (RP0004). > > > +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) > > > + > > > +# Add a comment according to your evaluation note. This is used by the global > > > +# evaluation report (RP0004). > > > +comment=no > > > + > > > +# Template used to display messages. This is a python new-style format string > > > +# used to format the massage information. See doc for all details > > > +#msg-template= > > > + > > > + > > > +[MISCELLANEOUS] > > > + > > > +# List of note tags to take in consideration, separated by a comma. > > > +notes=FIXME,XXX,TODO > > > + > > > + > > > +[SIMILARITIES] > > > + > > > +# Minimum lines number of a similarity. > > > +min-similarity-lines=4 > > > + > > > +# Ignore comments when computing similarities. > > > +ignore-comments=yes > > > + > > > +# Ignore docstrings when computing similarities. > > > +ignore-docstrings=yes > > > + > > > +# Ignore imports when computing similarities. > > > +ignore-imports=no > > > + > > > + > > > +[BASIC] > > > + > > > +# Required attributes for module, separated by a comma > > > +required-attributes= > > > + > > > +# List of builtins function names that should not be used, separated by a comma > > > +bad-functions=map,filter,apply,input > > > + > > > +# Regular expression which should only match correct module names > > > +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ > > > + > > > +# Regular expression which should only match correct module level names > > > +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ > > > + > > > +# Regular expression which should only match correct class names > > > +class-rgx=[A-Z_][a-zA-Z0-9]+$ > > > + > > > +# Regular expression which should only match correct function names > > > +function-rgx=[a-z_][a-z0-9_]{2,30}$ > > > + > > > +# Regular expression which should only match correct method names > > > +method-rgx=[a-z_][a-z0-9_]{2,30}$ > > > + > > > +# Regular expression which should only match correct instance attribute names > > > +attr-rgx=[a-z_][a-z0-9_]{2,30}$ > > > + > > > +# Regular expression which should only match correct argument names > > > +argument-rgx=[a-z_][a-z0-9_]{2,30}$ > > > + > > > +# Regular expression which should only match correct variable names > > > +variable-rgx=[a-z_][a-z0-9_]{2,30}$ > > > + > > > +# Regular expression which should only match correct attribute names in class > > > +# bodies > > > +class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ > > > + > > > +# Regular expression which should only match correct list comprehension / > > > +# generator expression variable names > > > +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ > > > + > > > +# Good variable names which should always be accepted, separated by a comma > > > +# f is a useful name for a file descriptor > > > +good-names=f,i,j,k,ex,Run,_ > > > + > > > +# Bad variable names which should always be refused, separated by a comma > > > +bad-names=foo,bar,baz,toto,tutu,tata > > > + > > > +# Regular expression which should only match function or class names that do > > > +# not require a docstring. > > > +no-docstring-rgx=__.*__ > > > + > > > +# Minimum line length for functions/classes that require docstrings, shorter > > > +# ones are exempt. > > > +docstring-min-length=-1 > > > + > > > + > > > +[VARIABLES] > > > + > > > +# Tells whether we should check for unused import in __init__ files. > > > +init-import=no > > > + > > > +# A regular expression matching the beginning of the name of dummy variables > > > +# (i.e. not used). > > > +dummy-variables-rgx=_$|dummy > > > + > > > +# List of additional names supposed to be defined in builtins. Remember that > > > +# you should avoid to define new builtins when possible. > > > +additional-builtins= > > > + > > > + > > > +[FORMAT] > > > + > > > +# Maximum number of characters on a single line. > > > +max-line-length=79 > > > + > > > +# Regexp for a line that is allowed to be longer than the limit. > > > +ignore-long-lines=^\s*(# )?<?https?://\S+>?$ > > > + > > > +# Maximum number of lines in a module > > > +max-module-lines=1000 > > > + > > > +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 > > > +# tab). > > > +indent-string=' ' > > > + > > > + > > > +[TYPECHECK] > > > + > > > +# Tells whether missing members accessed in mixin class should be ignored. A > > > +# mixin class is detected if its name ends with "mixin" (case insensitive). > > > +ignore-mixin-members=yes > > > + > > > +# List of classes names for which member attributes should not be checked > > > +# (useful for classes with attributes dynamically set). > > > +ignored-classes=SQLObject > > > + > > > +# When zope mode is activated, add a predefined set of Zope acquired attributes > > > +# to generated-members. > > > +zope=no > > > + > > > +# List of members which are set dynamically and missed by pylint inference > > > +# system, and so shouldn't trigger E0201 when accessed. Python regular > > > +# expressions are accepted. > > > +generated-members=REQUEST,acl_users,aq_parent > > > + > > > + > > > +[CLASSES] > > > + > > > +# List of interface methods to ignore, separated by a comma. This is used for > > > +# instance to not check methods defines in Zope's Interface base class. > > > +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by > > > + > > > +# List of method names used to declare (i.e. assign) instance attributes. > > > +defining-attr-methods=__init__,__new__,setUp > > > + > > > +# List of valid names for the first argument in a class method. > > > +valid-classmethod-first-arg=cls > > > + > > > +# List of valid names for the first argument in a metaclass class method. > > > +valid-metaclass-classmethod-first-arg=mcs > > > + > > > + > > > +[IMPORTS] > > > + > > > +# Deprecated modules which should not be used, separated by a comma > > > +deprecated-modules=regsub,TERMIOS,Bastion,rexec > > > + > > > +# Create a graph of every (i.e. internal and external) dependencies in the > > > +# given file (report RP0402 must not be disabled) > > > +import-graph= > > > + > > > +# Create a graph of external dependencies in the given file (report RP0402 must > > > +# not be disabled) > > > +ext-import-graph= > > > + > > > +# Create a graph of internal dependencies in the given file (report RP0402 must > > > +# not be disabled) > > > +int-import-graph= > > > + > > > + > > > +[DESIGN] > > > + > > > +# Maximum number of arguments for function / method > > > +max-args=5 > > > + > > > +# Argument names that match this expression will be ignored. Default to name > > > +# with leading underscore > > > +ignored-argument-names=_.* > > > + > > > +# Maximum number of locals for function / method body > > > +max-locals=15 > > > + > > > +# Maximum number of return / yield for function / method body > > > +max-returns=6 > > > + > > > +# Maximum number of branch for function / method body > > > +max-branches=12 > > > + > > > +# Maximum number of statements in function / method body > > > +max-statements=50 > > > + > > > +# Maximum number of parents for a class (see R0901). > > > +max-parents=7 > > > + > > > +# Maximum number of attributes for a class (see R0902). > > > +max-attributes=7 > > > + > > > +# Minimum number of public methods for a class (see R0903). > > > +min-public-methods=2 > > > + > > > +# Maximum number of public methods for a class (see R0904). > > > +max-public-methods=20 > > > + > > > + > > > +[EXCEPTIONS] > > > + > > > +# Exceptions that will emit a warning when being caught. Defaults to > > > +# "Exception" > > > +overgeneral-exceptions=Exception
Attachment:
pgpeAr71W1KjW.pgp
Description: PGP signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |