<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164560] trunk/Tools</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164560">164560</a></dd>
<dt>Author</dt> <dd>mrobinson@webkit.org</dd>
<dt>Date</dt> <dd>2014-02-23 13:41:11 -0800 (Sun, 23 Feb 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>[GTK] generate-gtkdoc should use argparse
https://bugs.webkit.org/show_bug.cgi?id=128418
Reviewed by Carlos Garcia Campos.
* gtk/generate-gtkdoc: Get all arguments from argparse, pass then as parameters
to all functions, and guard the main routine with a __name__ == __main__ check.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptswebkitdirspm">trunk/Tools/Scripts/webkitdirs.pm</a></li>
<li><a href="#trunkToolsgtkgenerategtkdoc">trunk/Tools/gtk/generate-gtkdoc</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (164559 => 164560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-02-23 21:39:58 UTC (rev 164559)
+++ trunk/Tools/ChangeLog        2014-02-23 21:41:11 UTC (rev 164560)
</span><span class="lines">@@ -1,5 +1,15 @@
</span><span class="cx"> 2014-02-23 Martin Robinson <mrobinson@igalia.com>
</span><span class="cx">
</span><ins>+ [GTK] generate-gtkdoc should use argparse
+ https://bugs.webkit.org/show_bug.cgi?id=128418
+
+ Reviewed by Carlos Garcia Campos.
+
+ * gtk/generate-gtkdoc: Get all arguments from argparse, pass then as parameters
+ to all functions, and guard the main routine with a __name__ == __main__ check.
+
+2014-02-23 Martin Robinson <mrobinson@igalia.com>
+
</ins><span class="cx"> [GTK][CMake] Many plugin tests fail when running WebKit1 layout tests
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=129191
</span><span class="cx">
</span></span></pre></div>
<a id="trunkToolsScriptswebkitdirspm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitdirs.pm (164559 => 164560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitdirs.pm        2014-02-23 21:39:58 UTC (rev 164559)
+++ trunk/Tools/Scripts/webkitdirs.pm        2014-02-23 21:41:11 UTC (rev 164560)
</span><span class="lines">@@ -1886,8 +1886,6 @@
</span><span class="cx"> if (!checkForArgumentAndRemoveFromARGV("--disable-gtk-doc")) {
</span><span class="cx"> if ($project eq 'WebKit' && !isCrossCompilation() && !($noWebKit1 && $noWebKit2)) {
</span><span class="cx"> my @docGenerationOptions = ("$sourceDir/Tools/gtk/generate-gtkdoc", "--skip-html");
</span><del>- push(@docGenerationOptions, productDir());
-
</del><span class="cx"> unshift(@docGenerationOptions, jhbuildWrapperPrefixIfNeeded());
</span><span class="cx">
</span><span class="cx"> if (system(@docGenerationOptions)) {
</span></span></pre></div>
<a id="trunkToolsgtkgenerategtkdoc"></a>
<div class="modfile"><h4>Modified: trunk/Tools/gtk/generate-gtkdoc (164559 => 164560)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/gtk/generate-gtkdoc        2014-02-23 21:39:58 UTC (rev 164559)
+++ trunk/Tools/gtk/generate-gtkdoc        2014-02-23 21:41:11 UTC (rev 164560)
</span><span class="lines">@@ -15,6 +15,7 @@
</span><span class="cx"> # License along with this library; if not, write to the Free Software
</span><span class="cx"> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</span><span class="cx">
</span><ins>+import argparse
</ins><span class="cx"> import common
</span><span class="cx"> import glob
</span><span class="cx"> import gtkdoc
</span><span class="lines">@@ -22,8 +23,8 @@
</span><span class="cx"> import os.path
</span><span class="cx"> import sys
</span><span class="cx">
</span><del>-def configure_logging():
- level = logging.DEBUG if '-v' in sys.argv else logging.INFO
</del><ins>+def configure_logging(verbose):
+ level = logging.DEBUG if verbose else logging.INFO
</ins><span class="cx"> logger = logging.getLogger('gtkdoc')
</span><span class="cx"> logger.setLevel(level)
</span><span class="cx"> handler = logging.StreamHandler()
</span><span class="lines">@@ -49,22 +50,6 @@
</span><span class="cx"> return deps
</span><span class="cx">
</span><span class="cx">
</span><del>-def get_common_options():
- # TODO: We should consider using an arguments parsing library if
- # we need more of these complex ones.
- virtual_root = ''
- for argument in sys.argv:
- if argument.startswith('--virtual-root='):
- virtual_root = argument.split('=')[1]
- break
-
- return {
- 'decorator': 'WEBKIT_API|WEBKIT_DEPRECATED|WEBKIT_DEPRECATED_FOR\(.+\)',
- 'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
- 'library_path' : common.library_build_path(),
- 'virtual_root' : virtual_root,
- }
-
</del><span class="cx"> def get_common_xref_deps():
</span><span class="cx"> return {
</span><span class="cx"> 'glib-2.0' : ['glib', 'gobject', 'gio'],
</span><span class="lines">@@ -75,7 +60,7 @@
</span><span class="cx"> def webkitdom_docs_html_path():
</span><span class="cx"> return common.build_path('Documentation', 'webkitdomgtk', 'html')
</span><span class="cx">
</span><del>-def get_webkit2_options():
</del><ins>+def get_webkit2_options(virtual_root):
</ins><span class="cx"> api_path = common.top_level_path('Source', 'WebKit2', 'UIProcess', 'API', 'gtk')
</span><span class="cx"> injected_bundle_api_path = common.top_level_path('Source', 'WebKit2', 'WebProcess', 'InjectedBundle', 'API', 'gtk')
</span><span class="cx">
</span><span class="lines">@@ -92,8 +77,11 @@
</span><span class="cx"> def src_path(*args):
</span><span class="cx"> return os.path.join(api_path, *args)
</span><span class="cx">
</span><del>- options = get_common_options().copy()
- options.update({
</del><ins>+ options = {
+ 'decorator': 'WEBKIT_API|WEBKIT_DEPRECATED|WEBKIT_DEPRECATED_FOR\(.+\)',
+ 'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
+ 'library_path' : common.library_build_path(),
+ 'virtual_root' : virtual_root,
</ins><span class="cx"> 'module_name' : 'webkit2gtk',
</span><span class="cx"> 'namespace' : 'webkit',
</span><span class="cx"> 'doc_dir' : src_path('docs'),
</span><span class="lines">@@ -122,10 +110,10 @@
</span><span class="cx"> glob.glob(os.path.join(generated_api_path, 'WebKitMarshal.*')) + \
</span><span class="cx"> glob.glob(os.path.join(generated_api_path, 'WebKitEnumTypes.*')) + \
</span><span class="cx"> glob.glob(src_path('tests/*.h'))
</span><del>- })
</del><ins>+ }
</ins><span class="cx"> return options
</span><span class="cx">
</span><del>-def get_webkit1_options(gtk_version):
</del><ins>+def get_webkit1_options(gtk_version, virtual_root):
</ins><span class="cx"> def src_path(*args):
</span><span class="cx"> return common.top_level_path(*(('Source', 'WebKit', 'gtk') + args))
</span><span class="cx">
</span><span class="lines">@@ -145,8 +133,11 @@
</span><span class="cx"> 'gtk+-2.0' : ['gtk', 'gdk']
</span><span class="cx"> })
</span><span class="cx">
</span><del>- options = get_common_options().copy()
- options.update({
</del><ins>+ options = {
+ 'decorator': 'WEBKIT_API|WEBKIT_DEPRECATED|WEBKIT_DEPRECATED_FOR\(.+\)',
+ 'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
+ 'library_path' : common.library_build_path(),
+ 'virtual_root' : virtual_root,
</ins><span class="cx"> 'module_name' : 'webkitgtk',
</span><span class="cx"> 'namespace' : 'webkit',
</span><span class="cx"> 'doc_dir' : src_path('docs'),
</span><span class="lines">@@ -161,10 +152,10 @@
</span><span class="cx"> 'ignored_files': glob.glob(src_path('webkit', '*private.*')) + \
</span><span class="cx"> glob.glob(src_path('webkit', 'webkitauthenticationdialog.*')) + \
</span><span class="cx"> glob.glob(src_path('webkit', 'webkitspellcheckerenchant.*'))
</span><del>- })
</del><ins>+ }
</ins><span class="cx"> return options
</span><span class="cx">
</span><del>-def get_webkitdom_options():
</del><ins>+def get_webkitdom_options(virtual_root):
</ins><span class="cx"> def derived_sources_path(*args):
</span><span class="cx"> return common.build_path(*(('DerivedSources', 'webkitdom') + args))
</span><span class="cx"> def src_path(*args):
</span><span class="lines">@@ -172,8 +163,11 @@
</span><span class="cx">
</span><span class="cx"> xref_deps = { 'glib-2.0' : ['glib', 'gobject', 'gio'] }
</span><span class="cx">
</span><del>- options = get_common_options().copy()
- options.update({
</del><ins>+ options = {
+ 'decorator': 'WEBKIT_API|WEBKIT_DEPRECATED|WEBKIT_DEPRECATED_FOR\(.+\)',
+ 'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
+ 'library_path' : common.library_build_path(),
+ 'virtual_root' : virtual_root,
</ins><span class="cx"> 'module_name' : 'webkitdomgtk',
</span><span class="cx"> 'namespace' : 'webkit_dom',
</span><span class="cx"> 'doc_dir' : derived_sources_path('docs'),
</span><span class="lines">@@ -184,7 +178,7 @@
</span><span class="cx"> ' -I' + common.top_level_path('Source'),
</span><span class="cx"> 'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps),
</span><span class="cx"> 'ignored_files': glob.glob(derived_sources_path('*Private.h'))
</span><del>- })
</del><ins>+ }
</ins><span class="cx"> return options
</span><span class="cx">
</span><span class="cx"> def print_missing_api(generator):
</span><span class="lines">@@ -195,85 +189,100 @@
</span><span class="cx"> for api in missing_api:
</span><span class="cx"> print("\t%s" % api)
</span><span class="cx">
</span><del>-def generate_doc(generator):
- generator.generate(html='--skip-html' not in sys.argv)
</del><ins>+def generate_doc(generator, skip_html):
+ generator.generate(not skip_html)
</ins><span class="cx"> if generator.saw_warnings:
</span><span class="cx"> print_missing_api(generator)
</span><span class="cx"> return generator.saw_warnings
</span><span class="cx">
</span><del>-configure_logging()
</del><ins>+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description='Generate gtkdoc for WebKit.')
+ parser.add_argument('-v', '--verbose', action='store_true',
+ help='Whether or not to run in verbose mode.')
+ parser.add_argument('--rebase', action='store_true',
+ help='When specified, run the tool in rebase mode.')
+ parser.add_argument('--skip-html', action='store_true',
+ help='Whether or not to skip HTML generation, which can be slow.')
+ parser.add_argument('--virtual-root', type=str, default='',
+ help='A temporary installation directory which is used as the root ' + \
+ 'where the actual installation prefix lives; this is mostly ' + \
+ 'useful for packagers, and should be set to what is given to ' + \
+ 'make install as DESTDIR.')
</ins><span class="cx">
</span><del>-# We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
-# so that pkgconfig can properly resolve the libjavascriptcore dependency.
-pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
-os.environ['PKG_CONFIG_PATH'] = common.build_path('Source', 'JavaScriptCore')
-if pkg_config_path:
- os.environ['PKG_CONFIG_PATH'] += ':' + pkg_config_path
</del><ins>+ arguments = parser.parse_args()
+ configure_logging(arguments.verbose)
</ins><span class="cx">
</span><del>-# Newer versions of glib have deprecated g_type_init, so we need to disable
-# that warning when running gtkdoc-scanobj by overriding the CFLAGS we use
-# to compile it.
-cflags = os.environ.get('CFLAGS', '')
-cflags += ' -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'
-os.environ['CFLAGS'] = cflags
</del><ins>+ # We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
+ # so that pkgconfig can properly resolve the libjavascriptcore dependency.
+ pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
+ os.environ['PKG_CONFIG_PATH'] = common.build_path('Source', 'JavaScriptCore')
+ if pkg_config_path:
+ os.environ['PKG_CONFIG_PATH'] += ':' + pkg_config_path
</ins><span class="cx">
</span><del>-# Clang can be noisy, throwing unnecessary warnings for unused arguments.
-if os.environ.get('CC') == "clang":
- os.environ['CFLAGS'] += ' -Qunused-arguments'
</del><ins>+ # Newer versions of glib have deprecated g_type_init, so we need to disable
+ # that warning when running gtkdoc-scanobj by overriding the CFLAGS we use
+ # to compile it.
+ cflags = os.environ.get('CFLAGS', '')
+ cflags += ' -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'
+ os.environ['CFLAGS'] = cflags
</ins><span class="cx">
</span><del>-saw_webkit1_warnings = saw_webkit2_warnings = False
-wk2_pkg_config_path = common.build_path('Source', 'WebKit2', 'webkit2gtk-3.0.pc')
-wk1_pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkitgtk-3.0.pc')
-if not os.path.exists(wk1_pkg_config_path):
- wk1_pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkit-1.0.pc')
</del><ins>+ # Clang can be noisy, throwing unnecessary warnings for unused arguments.
+ if os.environ.get('CC') == "clang":
+ os.environ['CFLAGS'] += ' -Qunused-arguments'
</ins><span class="cx">
</span><del>-if os.path.exists(wk2_pkg_config_path):
- pkg_config_path = wk2_pkg_config_path
-elif os.path.exists(wk1_pkg_config_path):
- pkg_config_path = wk1_pkg_config_path
</del><ins>+ saw_webkit1_warnings = saw_webkit2_warnings = False
+ wk2_pkg_config_path = common.build_path('Source', 'WebKit2', 'webkit2gtk-3.0.pc')
+ wk1_pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkitgtk-3.0.pc')
+ if not os.path.exists(wk1_pkg_config_path):
+ wk1_pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkit-1.0.pc')
</ins><span class="cx">
</span><del>-webkitdom_docs_path = common.build_path('DerivedSources', 'webkitdom', 'docs')
-if not common.is_cmake_build():
- generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkitdom_options())
- if '--rebase' not in sys.argv:
- print("\nGenerating WebKitDOM documentation...")
- saw_webkitdom_warnings = generate_doc(generator)
- else:
- print("\nRebasing WebKitDOM documentation...")
- try:
- generator.rebase_installed_docs()
- except Exception:
- print("Rebase did not happen, likely no documentation is present.")
</del><ins>+ if os.path.exists(wk2_pkg_config_path):
+ pkg_config_path = wk2_pkg_config_path
+ elif os.path.exists(wk1_pkg_config_path):
+ pkg_config_path = wk1_pkg_config_path
</ins><span class="cx">
</span><del>-pkg_config_path = wk1_pkg_config_path
-if os.path.exists(pkg_config_path):
- options = get_webkit1_options(common.gtk_version_of_pkg_config_file(pkg_config_path))
- generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, options)
- if '--rebase' not in sys.argv:
- print("Generating WebKit1 documentation...")
- saw_webkit1_warnings = generate_doc(generator)
- else:
- print("Rebasing WebKit1 documentation...")
- try:
- generator.rebase_installed_docs()
- except Exception:
- print("Rebase did not happen, likely no documentation is present.")
</del><ins>+ webkitdom_docs_path = common.build_path('DerivedSources', 'webkitdom', 'docs')
+ if not common.is_cmake_build():
+ generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkitdom_options(arguments.virtual_root))
+ if not arguments.rebase:
+ print("\nGenerating WebKitDOM documentation...")
+ saw_webkitdom_warnings = generate_doc(generator, arguments.skip_html)
+ else:
+ print("\nRebasing WebKitDOM documentation...")
+ try:
+ generator.rebase_installed_docs()
+ except Exception:
+ print("Rebase did not happen, likely no documentation is present.")
</ins><span class="cx">
</span><del>-# WebKit2 might not be enabled, so check for the pkg-config file before building documentation.
-pkg_config_path = wk2_pkg_config_path
-if os.path.exists(pkg_config_path):
- generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkit2_options())
- if '--rebase' not in sys.argv:
- print("\nGenerating WebKit2 documentation...")
- saw_webkit2_warnings = generate_doc(generator)
- else:
- print("\nRebasing WebKit2 documentation...")
- try:
- generator.rebase_installed_docs()
- except Exception:
- print("Rebase did not happen, likely no documentation is present.")
</del><ins>+ pkg_config_path = wk1_pkg_config_path
+ if os.path.exists(pkg_config_path):
+ options = get_webkit1_options(common.gtk_version_of_pkg_config_file(pkg_config_path), arguments.virtual_root)
+ generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, options)
+ if not arguments.rebase:
+ print("Generating WebKit1 documentation...")
+ saw_webkit1_warnings = generate_doc(generator, arguments.skip_html)
+ else:
+ print("Rebasing WebKit1 documentation...")
+ try:
+ generator.rebase_installed_docs()
+ except Exception:
+ print("Rebase did not happen, likely no documentation is present.")
</ins><span class="cx">
</span><del>-# For CMake we are still generating warnings because we lack DOM bindings docs,
-# so do not cause the build to fail for now.
-if not common.is_cmake_build():
- sys.exit(saw_webkit1_warnings or saw_webkit2_warnings)
</del><ins>+ # WebKit2 might not be enabled, so check for the pkg-config file before building documentation.
+ pkg_config_path = wk2_pkg_config_path
+ if os.path.exists(pkg_config_path):
+ generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkit2_options(arguments.virtual_root))
+ if not arguments.rebase:
+ print("\nGenerating WebKit2 documentation...")
+ saw_webkit2_warnings = generate_doc(generator, arguments.skip_html)
+ else:
+ print("\nRebasing WebKit2 documentation...")
+ try:
+ generator.rebase_installed_docs()
+ except Exception:
+ print("Rebase did not happen, likely no documentation is present.")
+
+ # For CMake we are still generating warnings because we lack DOM bindings docs,
+ # so do not cause the build to fail for now.
+ if not common.is_cmake_build():
+ sys.exit(saw_webkit1_warnings or saw_webkit2_warnings)
</ins></span></pre>
</div>
</div>
</body>
</html>