Permalink
Browse files

Bundle of modifications done to ohcount to support Python only (no de…

…pendencies made to CMake, the building are done using default Python building using setup.py file). MinGW/MSYS and Windows compiling and fixes were applied too.
  • Loading branch information...
1 parent 3a2d28f commit ce08d14ebe1ac2587d6162540b69d2d799db421d Guilherme Balena Versiani committed Jan 5, 2010
Showing with 745 additions and 10 deletions.
  1. +2 −0 .gitignore
  2. +100 −0 mingw_setup.py
  3. +234 −0 python/__init__.py
  4. +173 −0 ruby/ohcount.i
  5. +146 −0 setup.py
  6. +5 −0 src/detector.c
  7. +5 −0 src/diff.c
  8. +1 −1 src/ohcount.c
  9. +9 −7 src/sourcefile.c
  10. +1 −1 test/unit/license_test.h
  11. +1 −1 test/unit/parser_test.h
  12. +68 −0 test/unit/python/python_test.py
View
@@ -13,3 +13,5 @@ bin/
ruby/ohcount.so
ruby/ohcount_wrap.c
test/unit/run_tests.dSYM/
+build-python/
+python/ohcount.py
View
@@ -0,0 +1,100 @@
+#=== mingw_setup.py by Phillip J. Eby
+"""Create pythonNN.def and libpythonNN.a in 'PythonNN/libs' directory
+
+This script makes it possible to use the MinGW compiler tools to
+build C extensions that work with the standard Windows Python
+distribution.
+
+Before running, you should have installed the MinGW compiler toolset,
+and placed its 'bin' directory on your PATH. An easy way to do this
+is to install Cygwin's "binutils", "gcc", and "mingw-*" packages,
+then run this script from the Cygwin shell. (Be sure to use *Windows*
+Python, not Cygwin python!)
+
+Once this script has been run, you should be able to build extensions
+using distutils in the standard way, as long as you select the
+'mingw32' compiler, and the required tools are on your PATH. See
+the "Installing Python Modules" manual for more information on
+selecting a compiler.
+"""
+
+
+from distutils.spawn import find_executable
+from distutils.sysconfig import get_config_var
+from distutils import __file__ as distutils_file
+import os, re, sys
+
+if sys.platform=='cygwin':
+ print "Please run this script using Windows python,",
+ print "not Cygwin python. E.g, try:"
+ print
+ print "/cygdrive/c/PythonNN/python", " ".join(sys.argv)
+ print
+ print "(where NN is the major/minor python version number)"
+ sys.exit()
+
+basename = 'python%d%d' % sys.version_info[:2]
+
+libs_dir = os.path.join(get_config_var('prefix'),'libs')
+lib_file = os.path.join(libs_dir,basename+'.lib')
+def_file = os.path.join(libs_dir,basename+'.def')
+ming_lib = os.path.join(libs_dir,'lib%s.a' % basename)
+
+distutils_cfg = os.path.join(os.path.dirname(distutils_file),'distutils.cfg')
+
+export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match
+
+nm = find_executable('nm')
+dlltool = find_executable('dlltool')
+
+if not nm or not dlltool:
+ print "'nm' and/or 'dlltool' were not found;"
+ print "Please make sure they're on your PATH."
+ sys.exit()
+
+nm_command = '%s -Cs %s' % (nm, lib_file)
+
+print "Building", def_file, "using", nm_command
+f = open(def_file,'w')
+print >>f, "LIBRARY %s.dll" % basename
+print >>f, "EXPORTS"
+
+
+nm_pipe = os.popen(nm_command)
+for line in nm_pipe.readlines():
+ m = export_match(line)
+ if m:
+ print >>f, m.group(1)
+f.close()
+
+exit = nm_pipe.close()
+if exit:
+ print "nm exited with status", exit
+ print "Please check that", lib_file, "exists and is valid."
+ sys.exit()
+
+
+print "Building",ming_lib,"using",dlltool
+dlltool_pipe = os.popen(
+ "%s --dllname %s.dll --def %s --output-lib %s" %
+ (dlltool, basename, def_file, ming_lib)
+)
+
+dlltool_pipe.readlines()
+exit = dlltool_pipe.close()
+if exit:
+ print "dlltool exited with status", exit
+ print "Unable to proceed."
+ sys.exit()
+
+print
+print "Installation complete. You may wish to add the following"
+print "lines to", distutils_cfg, ':'
+print
+print "[build]"
+print "compiler = mingw32"
+print
+print "This will make the distutils use MinGW as the default"
+print "compiler, so that you don't need to configure this for"
+print "every 'setup.py' you run."
+
View
@@ -0,0 +1,234 @@
+import os, collections
+from abc import abstractmethod
+import ohcount
+
+class _OhcountBase(object):
+
+ def __init__(self, base):
+ self._base = base
+
+ def __getattr__(self, name):
+ if name == '_base':
+ return object.__getattr__(self, name)
+ raise AttributeError
+
+ def __setattr__(self, name, value):
+ if name == '_base':
+ return object.__setattr__(self, name, value)
+ raise AttributeError
+
+class _OhcountDict(_OhcountBase, collections.Mapping, collections.KeysView):
+
+ def __init__(self, base, mapping):
+ _OhcountBase.__init__(self, base)
+ collections.KeysView.__init__(self, mapping)
+
+ def __getattr__(self, name):
+ if name == '_mapping':
+ return collections.KeysView.__getattr__(self, name)
+ try:
+ return _OhcountBase.__getattr__(self, name)
+ except AttributeError:
+ try:
+ return self.__getitem__(name)
+ except KeyError:
+ raise AttributeError
+ except:
+ raise
+
+ def __setattr__(self, name, value):
+ if name == '_mapping':
+ return collections.KeysView.__setattr__(self, name, value)
+ try:
+ return _OhcountBase.__setattr__(self, name, value)
+ except AttributeError:
+ try:
+ return self.__setitem__(name, value)
+ except KeyError:
+ raise AttributeError
+ except:
+ raise
+
+ def keys(self):
+ return self._mapping
+
+ def __setitem__(self, key, item):
+ raise KeyError
+
+ def __delitem__(self, key):
+ raise KeyError
+
+ def __str__(self):
+ return dict([(key, self[key]) for key in self.keys()]).__str__()
+
+ def iterkeys(self):
+ return iter(self.keys())
+
+ def itervalues(self):
+ for key in self.keys():
+ yield self[key]
+
+ def iteritems(self):
+ for key in self.keys():
+ yield (key, self[key])
+
+ def items(self):
+ return [(key, self[key]) for key in self.keys()]
+
+ def values(self):
+ return [self[key] for key in self.keys()]
+
+class _OhcountList(_OhcountBase):
+
+ @abstractmethod
+ def _get_value(self, inner):
+ raise NotImplementedError
+
+ def __len__(self):
+ count = 0
+ for e in self:
+ count += 1
+ return count
+
+ def __iter__(self):
+ return self.next()
+
+ def next(self):
+ iter = self._base.head
+ while iter is not None:
+ yield self._get_value(iter)
+ iter = iter.next
+
+ def __str__(self):
+ return [v for v in self].__str__()
+
+class License(_OhcountDict):
+
+ def __init__(self, base):
+ _OhcountDict.__init__(self, base,
+ ['name','url','nice_name'])
+
+ def __getitem__(self, key):
+ if key == 'name':
+ return self._base.name
+ if key == 'url':
+ return self._base.url
+ if key == 'nice_name':
+ return self._base.nice_name
+ raise KeyError
+
+class Loc(_OhcountDict):
+
+ def __init__(self, base):
+ _OhcountDict.__init__(self, base,
+ ['lang','code','comments','blanks','filecount','total'])
+
+ def __getitem__(self, key):
+ if key == 'lang' or key == 'language':
+ return self._base.language
+ if key == 'code':
+ return self._base.code
+ if key == 'comments':
+ return self._base.comments
+ if key == 'blanks':
+ return self._base.blanks
+ if key == 'filecount':
+ return self._base.filecount
+ if key == 'total':
+ return self._base.total()
+ raise KeyError
+
+class LocList(_OhcountDict, _OhcountList):
+
+ def __init__(self, base):
+ _OhcountDict.__init__(self, base,
+ ['code','comments','blanks','filecount','total'])
+
+ def _get_value(self, inner):
+ return Loc(inner.loc)
+
+ def __getitem__(self, key):
+ if key == 'code':
+ return self._base.code()
+ if key == 'comments':
+ return self._base.comments()
+ if key == 'blanks':
+ return self._base.blanks()
+ if key == 'filecount':
+ return self._base.filecount()
+ if key == 'total':
+ return self._base.total()
+ raise KeyError
+
+ def __str__(self):
+ return _OhcountDict.__str__(self)
+
+ def compact(self):
+ return LocList(self._base.compact())
+
+class SourceFile(_OhcountDict):
+
+ def __init__(self, base):
+ _OhcountDict.__init__(self, base,
+ ['filepath','filename','ext','contents','size','language',
+ 'licenses','locs'])
+
+ def _get_licenses(self):
+ result = []
+ list = self._base.get_license_list()
+ if list is not None:
+ iter = list.head
+ while iter is not None:
+ result.append(License(iter.lic))
+ iter = iter.next
+ return result
+
+ def _get_locs(self):
+ return LocList(self._base.get_loc_list())
+
+ def __getitem__(self, key):
+ if key == 'filepath':
+ return self._base.filepath
+ if key == 'filename':
+ return self._base.filename
+ if key == 'ext':
+ return self._base.ext
+ if key == 'contents':
+ return self._base.get_contents()
+ if key == 'size':
+ return self._base.contents_size()
+ if key == 'language':
+ return self._base.get_language()
+ if key == 'licenses':
+ return self._get_licenses()
+ if key == 'locs':
+ return self._get_locs()
+ raise AttributeError
+
+ def annotate(self):
+ return self._base.annotate()
+
+ def raw_entities(self):
+ return self._base.raw_entities()
+
+class SourceFileList(_OhcountList):
+
+ def __init__(self, **kwargs):
+ _OhcountList.__init__(self, ohcount.SourceFileList(kwargs))
+
+ def _get_value(self, inner):
+ return SourceFile(inner.sf)
+
+ def analyze_languages(self):
+ return LocList( self._base.analyze_languages() )
+
+ def add_directory(self, path):
+ if not os.path.isdir(path):
+ raise SyntaxError('Input path is not a directory: %s' % path)
+ self._base.add_directory(path)
+
+ def add_file(self, filepath):
+ if not os.path.isfile(filepath):
+ raise SyntaxError('Input path is not a file: %s' % filepath)
+ self._base.add_file(filepath)
+
Oops, something went wrong.

0 comments on commit ce08d14

Please sign in to comment.