diff --git a/LICENSES.txt b/LICENSES.txt index 545e9bc7..170f2d2d 100644 --- a/LICENSES.txt +++ b/LICENSES.txt @@ -4,17 +4,17 @@ per-file license information). There are copies of various JavaScript and CSS libraries embedded within the source tree, which have their own licenses as follows: - libcpychecker/html/extlib/jquery-1.7.1.min.js: + libcpychecker_html/extlib/jquery-1.7.1.min.js: jquery.org/license (MIT or GPLv2) - libcpychecker/html/extlib/prefixfree-1.0.4.min.js: + libcpychecker_html/extlib/prefixfree-1.0.4.min.js: MIT license - libcpychecker/html/extlib/reset-20110126.css: + libcpychecker_html/extlib/reset-20110126.css: Public Domain There are also various images within: - libcpychecker/html/images + libcpychecke_/html/images These were taken from: http://code.google.com/p/fugue-icons-src/ and are: @@ -25,6 +25,6 @@ and are: The test code contains historical examples of reference-count bugs: - * libcpychecker/html/test/example2 + * libcpychecker_html/test/example2 contains an embedded copy of part of an old version of pylibmc, which is under a 3-clause BSD license diff --git a/Makefile b/Makefile index 1e8a58a5..6ad5ff40 100644 --- a/Makefile +++ b/Makefile @@ -287,7 +287,7 @@ demo: plugin $(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-cpychecker -c $(PYTHON_INCLUDES) demo.c json-examples: plugin - $(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-cpychecker -I/usr/include/python2.7 -c libcpychecker/html/test/example1/bug.c + $(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-cpychecker -I/usr/include/python2.7 -c libcpychecker_html/test/example1/bug.c test-suite: plugin print-gcc-version $(INVOCATION_ENV_VARS) $(PYTHON) run-test-suite.py diff --git a/libcpychecker/refcounts.py b/libcpychecker/refcounts.py index 5e654cea..bce42ac0 100644 --- a/libcpychecker/refcounts.py +++ b/libcpychecker/refcounts.py @@ -4386,7 +4386,7 @@ def check_refcounts(fun, dump_traces=False, show_traces=False, filename_v2 = ('%s.%s-refcount-errors.v2.html' % (gcc.get_dump_base_name(), fun.decl.name)) - from libcpychecker.html.make_html import HtmlPage + from libcpychecker_html.make_html import HtmlPage data = rep.to_json(fun) srcfile = open(fun.start.file) htmlfile = open(filename_v2, 'w') diff --git a/libcpychecker/html/TODO b/libcpychecker_html/TODO similarity index 100% rename from libcpychecker/html/TODO rename to libcpychecker_html/TODO diff --git a/libcpychecker/html/__init__.py b/libcpychecker_html/__init__.py similarity index 100% rename from libcpychecker/html/__init__.py rename to libcpychecker_html/__init__.py diff --git a/libcpychecker/html/c-api.txt b/libcpychecker_html/c-api.txt similarity index 100% rename from libcpychecker/html/c-api.txt rename to libcpychecker_html/c-api.txt diff --git a/libcpychecker/html/capi.py b/libcpychecker_html/capi.py similarity index 100% rename from libcpychecker/html/capi.py rename to libcpychecker_html/capi.py diff --git a/libcpychecker/html/extlib/jquery-1.7.1.min.js b/libcpychecker_html/extlib/jquery-1.7.1.min.js similarity index 100% rename from libcpychecker/html/extlib/jquery-1.7.1.min.js rename to libcpychecker_html/extlib/jquery-1.7.1.min.js diff --git a/libcpychecker/html/extlib/prefixfree-1.0.4.min.js b/libcpychecker_html/extlib/prefixfree-1.0.4.min.js similarity index 100% rename from libcpychecker/html/extlib/prefixfree-1.0.4.min.js rename to libcpychecker_html/extlib/prefixfree-1.0.4.min.js diff --git a/libcpychecker/html/extlib/reset-20110126.css b/libcpychecker_html/extlib/reset-20110126.css similarity index 100% rename from libcpychecker/html/extlib/reset-20110126.css rename to libcpychecker_html/extlib/reset-20110126.css diff --git a/libcpychecker/html/html_to_lxml.py b/libcpychecker_html/html_to_lxml.py similarity index 100% rename from libcpychecker/html/html_to_lxml.py rename to libcpychecker_html/html_to_lxml.py diff --git a/libcpychecker/html/images/arrow-180.png b/libcpychecker_html/images/arrow-180.png similarity index 100% rename from libcpychecker/html/images/arrow-180.png rename to libcpychecker_html/images/arrow-180.png diff --git a/libcpychecker/html/images/arrow.png b/libcpychecker_html/images/arrow.png similarity index 100% rename from libcpychecker/html/images/arrow.png rename to libcpychecker_html/images/arrow.png diff --git a/libcpychecker/html/images/bug--arrow.png b/libcpychecker_html/images/bug--arrow.png similarity index 100% rename from libcpychecker/html/images/bug--arrow.png rename to libcpychecker_html/images/bug--arrow.png diff --git a/libcpychecker/html/images/bug.png b/libcpychecker_html/images/bug.png similarity index 100% rename from libcpychecker/html/images/bug.png rename to libcpychecker_html/images/bug.png diff --git a/libcpychecker/html/images/exclamation.png b/libcpychecker_html/images/exclamation.png similarity index 100% rename from libcpychecker/html/images/exclamation.png rename to libcpychecker_html/images/exclamation.png diff --git a/libcpychecker/html/images/footer-bg.png b/libcpychecker_html/images/footer-bg.png similarity index 100% rename from libcpychecker/html/images/footer-bg.png rename to libcpychecker_html/images/footer-bg.png diff --git a/libcpychecker/html/images/header-bg.png b/libcpychecker_html/images/header-bg.png similarity index 100% rename from libcpychecker/html/images/header-bg.png rename to libcpychecker_html/images/header-bg.png diff --git a/libcpychecker/html/json.rst b/libcpychecker_html/json.rst similarity index 99% rename from libcpychecker/html/json.rst rename to libcpychecker_html/json.rst index c48aa5c0..91117e5a 100644 --- a/libcpychecker/html/json.rst +++ b/libcpychecker_html/json.rst @@ -5,7 +5,7 @@ At the top level:: { # Path to the source file being analyzed: - "filename": "libcpychecker/html/test/example1/bug.c", + "filename": "libcpychecker_html/test/example1/bug.c", # The particular function containing the error: "function": { diff --git a/libcpychecker/html/make_html.py b/libcpychecker_html/make_html.py similarity index 85% rename from libcpychecker/html/make_html.py rename to libcpychecker_html/make_html.py index 7e6727a8..5453a323 100755 --- a/libcpychecker/html/make_html.py +++ b/libcpychecker_html/make_html.py @@ -1,6 +1,12 @@ #!/usr/bin/env python -"""Make our data into HTML!""" +"""Make our data into HTML! +These reports should be usable as email attachments, offline. +This means we need to embed *all* our assets. + +TODO: #11 optimize the filesize +""" from __future__ import print_function +from __future__ import unicode_literals # Copyright 2012 Buck Golemon # @@ -17,6 +23,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see # . +from os.path import realpath, dirname, join +HERE = dirname(realpath(__file__)) from . import capi @@ -31,6 +39,16 @@ from copy import deepcopy from itertools import islice + +def open(filename, mode='r'): + """All files are treated as UTF-8, unless explicitly binary.""" + from io import open + if 'b' in mode: + return open(filename, mode) + else: + return open(filename, mode, encoding='UTF-8') + + class HtmlPage(object): """Represent one html page.""" def __init__(self, codefile, data): @@ -54,11 +72,18 @@ def head(self): E.TITLE('%s -- GCC Python Plugin' % self.data['filename']), ) head.extend( - E.LINK(rel='stylesheet', href=css + '.css', type='text/css') + E.STYLE( + file_contents(css + '.css'), + media='screen', + type='text/css' + ) for css in ('extlib/reset-20110126', 'pygments_c', 'style') ) head.extend( - E.SCRIPT(src=js + '.js') + E.SCRIPT( + file_contents(js + '.js'), + type='text/javascript', + ) for js in ( 'extlib/prefixfree-1.0.4.min', 'extlib/jquery-1.7.1.min', @@ -136,7 +161,7 @@ def header(self): E.DIV( E.ATTR(id='bug-toggle'), E.IMG( - src='images/bug.png', + src=data_uri('image/png', 'images/bug.png'), ), E.H3('Bug'), ' [count]', @@ -144,30 +169,18 @@ def header(self): E.DIV( E.ATTR(id='prev'), E.IMG( - src='images/arrow-180.png', + src=data_uri('image/png', 'images/arrow-180.png'), ), ), E.DIV( E.ATTR(id='next'), E.IMG( - src='images/arrow.png', + src=data_uri('image/png', 'images/arrow.png'), ), ), ), ) - @staticmethod - def footer(): - """make the footer""" - return E.E.footer( - E.ATTR(id='footer'), - E.P('  |  '.join(( - 'Hackathon 7.0', - 'Buck G, Alex M, Jason M', - 'Yelp HQ 2012', - ))) - ) - def states(self): """Return an ordered-list of states, for each report.""" for report in self.data['reports']: @@ -247,9 +260,18 @@ def body(self): return E.BODY( self.header(), reports, - self.footer(), ) +def data_uri(mimetype, filename): + "represent a file as a data uri" + data = open(join(HERE, filename), 'rb').read().encode('base64').replace('\n', '') + return 'data:%s;base64,%s' % (mimetype, data) + +def file_contents(filename): + # The leading newline makes the first line show up in the right spot. + return '\n' + open(join(HERE, filename)).read() + + class CodeHtmlFormatter(HtmlFormatter): """Format our HTML!""" diff --git a/libcpychecker/html/pygments_c.css b/libcpychecker_html/pygments_c.css similarity index 100% rename from libcpychecker/html/pygments_c.css rename to libcpychecker_html/pygments_c.css diff --git a/libcpychecker/html/script.js b/libcpychecker_html/script.js similarity index 100% rename from libcpychecker/html/script.js rename to libcpychecker_html/script.js diff --git a/libcpychecker/html/style.css b/libcpychecker_html/style.css similarity index 83% rename from libcpychecker/html/style.css rename to libcpychecker_html/style.css index f12ac05f..24d44e8a 100755 --- a/libcpychecker/html/style.css +++ b/libcpychecker_html/style.css @@ -56,14 +56,7 @@ img { #reports { box-flex: 1; overflow-y: auto; -} -#footer { - background: hsl(0, 0%, 30%); - box-shadow: inset 0 3px 3px -3px black; - color: white; - padding: 0.83em; - text-shadow: 0px 1px 0px black; - background-color: #09f; + overflow-x: hidden; } @@ -72,7 +65,7 @@ img { display: box; box-orient: horizontal; width: 100%; - padding: 1em; + padding: 0.5em; box-sizing: border-box; color: white; } @@ -190,6 +183,8 @@ img { line-height: 1.33; min-width: 40em; box-flex: 3; + overflow-x: auto; + border-right: 1px solid hsl(0, 0%, 70%); } .source > header { display: box; @@ -285,9 +280,10 @@ img { text-align: right; user-select: none; color: hsl(0, 0%, 60%); + vertical-align: middle; } .source .code { - white-space: pre-wrap; + white-space: pre; } @@ -394,7 +390,15 @@ td.selected .flow-dot { min-width: 200px; } +.note { + font-weight: bolder; +} .note:first-of-type::before { - content: url('images/exclamation.png'); + /* content: url('images/exclamation.png'); + * to regenerate: + * from libcpychecker_html.make_html import data_uri + * data_uri('image/png', 'images/exclamation.png') + */ + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAjBJREFUeNqkk0trE1EUx8/cO49OfGTSRNJMYsA0aVonoYh13YW71uJCKFQhKqibfgFLwYULsR/AhY+VG1d+C124kJiFIGipmoIZNUXtZDKTycz1njGpaRNU8MJv7txzzv/c5xEYY/A/TRQEAW5c5KwM+aKcR73/a5zvg84HT371wv07Apwuj0x+PZW/vArA4NO7x/f4+OGoIHLKAAiC/fBdHadSbCGZPTeTzC7OUElbQNvBOISMMnIqeqFSYs57mTkfZD1/qYS2f0rAZ5pVDmXnY/FSbn3jM6xvfAEtfjKnRDLz6BtK4PPPADi+ms6vGK71lti2DUintUVSJ84b6OvF7GlI4PNMPVgAZ49oxpyqRnXf+wGWZYX4ngWRiKYfPpqfw5hBjej7eweqCkSo6JOLhmd/hI7vQLVaBdM0YXt1FgK2CeJ40fCbmxUWsGc8vh3egtcFQPhyLsQnzpQJcbVmuw5mawtqtRo0Gg3wJQeY7ALIrqZEM2WM7esIPkROAgR5OZEpTTV3X4IXNEGiLnw1b4fItBNCBQuiqeQUA7qMGtSSLt8C38aVRLo47QVvVJFYoFAnJJG8FdIfI6rSVWMTx6ZRg1rS7UKeSspSMj2Wk+AbjPGZ+vTboA1JZbQcEcUl1Iq2zdZyxURBpruUMTzR38Vl79wM+9bO0/3vlwLVs+OF16/MNdFug/vi+Xadm+vDL/3uHyuR16Er4E3gKvEaOTLa/1LBuEQPF8hxfgowAINnMqTBUH7hAAAAAElFTkSuQmCC'); padding: 5px; } diff --git a/libcpychecker/html/test/example1/bug.c b/libcpychecker_html/test/example1/bug.c similarity index 100% rename from libcpychecker/html/test/example1/bug.c rename to libcpychecker_html/test/example1/bug.c diff --git a/libcpychecker/html/test/example1/bug.c.make_a_list_of_random_ints_badly.json b/libcpychecker_html/test/example1/bug.c.make_a_list_of_random_ints_badly.json similarity index 99% rename from libcpychecker/html/test/example1/bug.c.make_a_list_of_random_ints_badly.json rename to libcpychecker_html/test/example1/bug.c.make_a_list_of_random_ints_badly.json index 3fc882a9..5961c4a7 100644 --- a/libcpychecker/html/test/example1/bug.c.make_a_list_of_random_ints_badly.json +++ b/libcpychecker_html/test/example1/bug.c.make_a_list_of_random_ints_badly.json @@ -1,5 +1,5 @@ { - "filename": "libcpychecker/html/test/example1/bug.c", + "filename": "libcpychecker_html/test/example1/bug.c", "function": { "lines": [ 3, @@ -4354,7 +4354,7 @@ "line": 16 } ], - "message": "when considering count.0 == (int)1 from libcpychecker/html/test/example1/bug.c:10", + "message": "when considering count.0 == (int)1 from libcpychecker_html/test/example1/bug.c:10", "variables": { "": { "gcctype": "struct PyObject *", @@ -6399,7 +6399,7 @@ ] }, { - "message": "calling PyList_Append with NULL as argument 1 (list) at libcpychecker/html/test/example1/bug.c:18", + "message": "calling PyList_Append with NULL as argument 1 (list) at libcpychecker_html/test/example1/bug.c:18", "notes": [ { "location": [ @@ -9202,4 +9202,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/libcpychecker/html/test/example2/_pylibmcmodule.h b/libcpychecker_html/test/example2/_pylibmcmodule.h similarity index 100% rename from libcpychecker/html/test/example2/_pylibmcmodule.h rename to libcpychecker_html/test/example2/_pylibmcmodule.h diff --git a/libcpychecker/html/test/example2/pylibmc-issue-68.c b/libcpychecker_html/test/example2/pylibmc-issue-68.c similarity index 100% rename from libcpychecker/html/test/example2/pylibmc-issue-68.c rename to libcpychecker_html/test/example2/pylibmc-issue-68.c diff --git a/libcpychecker/html/test/example2/pylibmc-issue-68.c.PylibMC_Client_get_multi.json b/libcpychecker_html/test/example2/pylibmc-issue-68.c.PylibMC_Client_get_multi.json similarity index 99% rename from libcpychecker/html/test/example2/pylibmc-issue-68.c.PylibMC_Client_get_multi.json rename to libcpychecker_html/test/example2/pylibmc-issue-68.c.PylibMC_Client_get_multi.json index 04f9bba1..3ccd6a3c 100644 --- a/libcpychecker/html/test/example2/pylibmc-issue-68.c.PylibMC_Client_get_multi.json +++ b/libcpychecker_html/test/example2/pylibmc-issue-68.c.PylibMC_Client_get_multi.json @@ -1,5 +1,5 @@ { - "filename": "libcpychecker/html/test/example2/pylibmc-issue-68.c", + "filename": "libcpychecker_html/test/example2/pylibmc-issue-68.c", "function": { "lines": [ 52, @@ -822,7 +822,7 @@ "line": 114 } ], - "message": "when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL" + "message": "when treating unknown const char * from libcpychecker_html/test/example2/pylibmc-issue-68.c:68 as non-NULL" }, { "location": [ @@ -1446,7 +1446,7 @@ "line": 154 } ], - "message": "when considering value == (int)0 from libcpychecker/html/test/example2/pylibmc-issue-68.c:148" + "message": "when considering value == (int)0 from libcpychecker_html/test/example2/pylibmc-issue-68.c:148" }, { "location": [ @@ -1771,7 +1771,7 @@ "line": 177 } ], - "message": "when treating unknown struct PyObject * from libcpychecker/html/test/example2/pylibmc-issue-68.c:176 as non-NULL" + "message": "when treating unknown struct PyObject * from libcpychecker_html/test/example2/pylibmc-issue-68.c:176 as non-NULL" }, { "location": [ @@ -2065,7 +2065,7 @@ "line": 190 } ], - "message": "calling tp_dealloc on PyDictObject allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:159" + "message": "calling tp_dealloc on PyDictObject allocated at libcpychecker_html/test/example2/pylibmc-issue-68.c:159" }, { "location": null, @@ -2086,7 +2086,7 @@ "line": 195 } ], - "message": "calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77" + "message": "calling PyMem_Free on PyMem_Malloc allocated at libcpychecker_html/test/example2/pylibmc-issue-68.c:77" }, { "location": [ @@ -2099,7 +2099,7 @@ "line": 196 } ], - "message": "calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76" + "message": "calling PyMem_Free on PyMem_Malloc allocated at libcpychecker_html/test/example2/pylibmc-issue-68.c:76" }, { "location": [ @@ -2307,7 +2307,7 @@ "line": 200 } ], - "message": "calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78" + "message": "calling PyMem_Free on PyMem_Malloc allocated at libcpychecker_html/test/example2/pylibmc-issue-68.c:78" }, { "location": [ @@ -2333,7 +2333,7 @@ "line": 202 } ], - "message": "when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL" + "message": "when treating unknown struct memcached_result_st * * from libcpychecker_html/test/example2/pylibmc-issue-68.c:148 as non-NULL" }, { "location": [ @@ -2593,4 +2593,4 @@ ] } ] -} \ No newline at end of file +}