aboutsummaryrefslogtreecommitdiffstats
path: root/tests/check_help.c
blob: 5a2f28d9c9797b9efd93858c022fbc361f47fe21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdlib.h>
#include <glib.h>
#include <gmodule.h>
#include <check.h>
#include <string.h>
#include <stdio.h>
#include "help.h"

START_TEST(test_help_initfree)
	help_t *h, *r;
	r = help_init(&h, "/dev/null");
	fail_if(r == NULL);
	fail_if(r != h);
	
	help_free(&h);
	fail_if(h != NULL);
END_TEST

START_TEST(test_help_nonexistent)
	help_t *h, *r;
	r = help_init(&h, "/dev/null");
	fail_unless(help_get(&h, "nonexistent") == NULL);
END_TEST

Suite *help_suite (void)
{
	Suite *s = suite_create("Help");
	TCase *tc_core = tcase_create("Core");
	suite_add_tcase (s, tc_core);
	tcase_add_test (tc_core, test_help_initfree);
	tcase_add_test (tc_core, test_help_nonexistent);
	return s;
}
fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#!/usr/bin/env python

# Usage: python genhelp.py input.xml output.txt
# (Both python2 (>=2.5) or python3 work)

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program 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 General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA  02110-1301, USA.


import re
import sys
import xml.etree.ElementTree as ET

NORMALIZE_RE = re.compile(r"([^<>\s\t])[\s\t]+([^<>\s\t])")

# Helpers

def normalize(x):
    """Normalize whitespace of a string.

    The regexp turns any sequence of whitespace into a single space if it's in
    the middle of the tag text, and then all newlines and tabs are removed,
    keeping spaces.
    """

    x = NORMALIZE_RE.sub(r"\1 \2", x or '')
    return x.replace("\n", "").replace("\t", "")

def join(list):
    """Turns any iterator into a string"""
    return ''.join([str(x) for x in list])

def fix_tree(tag, debug=False, lvl=''):
    """Walks the XML tree and modifies it in-place fixing various details"""

    # The include tags have an ugly namespace in the tag name. Simplify that.
    if tag.tag.count("XInclude"):
        tag.tag = 'include'

    # Print a pretty tree-like representation of the processed tags
    if debug:
        print("%s<%s>%r" % (lvl, tag.tag, [tag.text, normalize(tag.text)]))

    for subtag in tag:
        fix_tree(subtag, debug, lvl + "  ")

    if debug:
        print("%s</%s>%r" % (lvl, tag.tag, [tag.tail, normalize(tag.tail)]))

    # Actually normalize whitespace
    tag.text = normalize(tag.text)
    tag.tail = normalize(tag.tail)


# Main logic

def process_file(filename, parent=None):
    tree = ET.parse(open(filename)).getroot()
    fix_tree(tree)
    return parse_tag(tree, parent)

def parse_tag(tag, parent):
    """Calls a tag_... function based on the tag name"""

    fun = globals()["tag_%s" % tag.tag.replace("-", "_")]
    return join(fun(tag, parent))

def parse_subtags(tag, parent=None):
    yield tag.text

    for subtag in tag:
        yield parse_tag(subtag, tag)

    yield tag.tail


# Main tag handlers

def handle_subject(tag, parent):
    """Tag handler for preface, chapter, sect1 and sect2 (aliased below)"""

    yield '?%s\n' % tag.attrib['id']

    first = True
    for element in tag:
        if element.tag in ["para", "variablelist", "simplelist",
                           "command-list", "ircexample"]:
            if not first:
                # Spaces between paragraphs
                yield "\n"
            first = False

            if element.attrib.get('title', ''):
                yield element.attrib['title']
                yield "\n"
            yield join(parse_tag(element, tag)).rstrip("\n")
            yield "\n"

    yield "%\n"

    for element in tag:
        if element.tag in ["sect1", "sect2"]:
            yield join(handle_subject(element, tag))

    for element in tag.findall("bitlbee-command"):
        yield join(handle_command(element))

    for element in tag.findall("bitlbee-setting"):
        yield join(handle_setting(element))

def handle_command(tag, prefix=''):
    """Tag handler for <bitlbee-command> (called from handle_subject)"""

    this_cmd = prefix + tag.attrib['name']

    yield "?%s\n" % this_cmd
    for syntax in tag.findall("syntax"):
        yield '\x02Syntax:\x02 %s\n' % syntax.text

    yield "\n"
    yield join(parse_subtags(tag.find("description"))).rstrip()
    yield "\n"

    for example in tag.findall("ircexample"):
        yield "\n\x02Example:\x02\n"
        yield join(parse_subtags(example)).rstrip()
        yield "\n"

    yield "%\n"

    for element in tag.findall("bitlbee-command"):
        yield join(handle_command(element, this_cmd + " "))

def handle_setting(tag):
    """Tag handler for <bitlbee-setting> (called from handle_subject)"""

    yield "?set %s\n" % tag.attrib['name']
    yield "\x02Type:\x02 %s\n" % tag.attrib["type"]
    yield "\x02Scope:\x02 %s\n" % tag.attrib["scope"]

    if tag.find("default") is not None:
        yield "\x02Default:\x02 %s\n" % tag.findtext("default")

    if tag.find("possible-values") is not None:
        yield "\x02Possible Values:\x02 %s\n" % tag.findtext("possible-values")

    yield "\n"
    yield join(parse_subtags(tag.find("description"))).rstrip()
    yield "\n%\n"


# Aliases for tags that behave like subjects
tag_preface = handle_subject
tag_chapter = handle_subject
tag_sect1 = handle_subject
tag_sect2 = handle_subject

# Aliases for tags that don't have any special behavior
tag_ulink = parse_subtags
tag_note = parse_subtags
tag_book = parse_subtags
tag_ircexample = parse_subtags


# Handlers for specific tags

def tag_include(tag, parent):
    return process_file(tag.attrib['href'], tag)

def tag_para(tag, parent):
    return join(parse_subtags(tag)) + "\n\n"

def tag_emphasis(tag, parent):
    return "\x02%s\x02%s" % (tag.text, tag.tail)

def tag_ircline(tag, parent):
    return "\x02<%s>\x02 %s\n" % (tag.attrib['nick'], join(parse_subtags(tag)))

def tag_ircaction(tag, parent):
    return "\x02* %s\x02 %s\n" % (tag.attrib['nick'], join(parse_subtags(tag)))

def tag_command_list(tag, parent):
    yield "These are all root commands. See \x02help <command name>\x02 " \
          "for more details on each command.\n\n"

    for subtag in parent.findall("bitlbee-command"):
        yield " * \x02%s\x02 - %s\n" % \
            (subtag.attrib['name'],
             subtag.findtext("short-description"))

    yield "\nMost commands can be shortened. For example instead of " \
          "\x02account list\x02, try \x02ac l\x02.\n\n"

def tag_variablelist(tag, parent):
    for subtag in tag:
        yield " \x02%s\x02 - %s\n" % \
            (subtag.findtext("term"),
             join(parse_subtags(subtag.find("listitem/para"))))
    yield '\n'

def tag_simplelist(tag, parent):
    for subtag in tag:
        yield " - %s\n" % join(parse_subtags(subtag))
    yield '\n'


def main():
    if len(sys.argv) != 3:
        print("Usage: python genhelp.py input.xml output.txt")
        return

    txt = process_file(sys.argv[1])
    open(sys.argv[2], "w").write(txt)

if __name__ == '__main__':
    main()