aboutsummaryrefslogtreecommitdiffstats
path: root/test/netlib/test_strutils.py
blob: 7c3eacc697be2e41dd2937683afeedaa0b0bb074 (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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import six

from netlib import strutils, tutils


def test_always_bytes():
    assert strutils.always_bytes(bytes(bytearray(range(256)))) == bytes(bytearray(range(256)))
    assert strutils.always_bytes("foo") == b"foo"
    with tutils.raises(ValueError):
        strutils.always_bytes(u"\u2605", "ascii")


def test_native():
    with tutils.raises(TypeError):
        strutils.native(42)
    if six.PY2:
        assert strutils.native(u"foo") == b"foo"
        assert strutils.native(b"foo") == b"foo"
    else:
        assert strutils.native(u"foo") == u"foo"
        assert strutils.native(b"foo") == u"foo"


def test_escape_control_characters():
    assert strutils.escape_control_characters(u"one") == u"one"
    assert strutils.escape_control_characters(u"\00ne") == u".ne"
    assert strutils.escape_control_characters(u"\nne") == u"\nne"
    assert strutils.escape_control_characters(u"\nne", False) == u".ne"
    assert strutils.escape_control_characters(u"\u2605") == u"\u2605"
    assert (
        strutils.escape_control_characters(bytes(bytearray(range(128))).decode()) ==
        u'.........\t\n..\r.................. !"#$%&\'()*+,-./0123456789:;<'
        u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
    )
    assert (
        strutils.escape_control_characters(bytes(bytearray(range(128))).decode(), False) ==
        u'................................ !"#$%&\'()*+,-./0123456789:;<'
        u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
    )

    if not six.PY2:
        with tutils.raises(ValueError):
            strutils.escape_control_characters(b"foo")


def test_bytes_to_escaped_str():
    assert strutils.bytes_to_escaped_str(b"foo") == "foo"
    assert strutils.bytes_to_escaped_str(b"\b") == r"\x08"
    assert strutils.bytes_to_escaped_str(br"&!?=\)") == r"&!?=\\)"
    assert strutils.bytes_to_escaped_str(b'\xc3\xbc') == r"\xc3\xbc"
    assert strutils.bytes_to_escaped_str(b"'") == r"\'"
    assert strutils.bytes_to_escaped_str(b'"') == r'"'

    assert strutils.bytes_to_escaped_str(b"\r\n\t") == "\\r\\n\\t"
    assert strutils.bytes_to_escaped_str(b"\r\n\t", True) == "\r\n\t"

    assert strutils.bytes_to_escaped_str(b"\n", True) == "\n"
    assert strutils.bytes_to_escaped_str(b"\\n", True) == "\\ \\ n".replace(" ", "")
    assert strutils.bytes_to_escaped_str(b"\\\n", True) == "\\ \\ \n".replace(" ", "")
    assert strutils.bytes_to_escaped_str(b"\\\\n", True) == "\\ \\ \\ \\ n".replace(" ", "")

    with tutils.raises(ValueError):
        strutils.bytes_to_escaped_str(u"such unicode")


def test_escaped_str_to_bytes():
    assert strutils.escaped_str_to_bytes("foo") == b"foo"
    assert strutils.escaped_str_to_bytes("\x08") == b"\b"
    assert strutils.escaped_str_to_bytes("&!?=\\\\)") == br"&!?=\)"
    assert strutils.escaped_str_to_bytes(u"\\x08") == b"\b"
    assert strutils.escaped_str_to_bytes(u"&!?=\\\\)") == br"&!?=\)"
    assert strutils.escaped_str_to_bytes(u"\u00fc") == b'\xc3\xbc'

    if six.PY2:
        with tutils.raises(ValueError):
            strutils.escaped_str_to_bytes(42)
    else:
        with tutils.raises(ValueError):
            strutils.escaped_str_to_bytes(b"very byte")


def test_is_mostly_bin():
    assert not strutils.is_mostly_bin(b"foo\xFF")
    assert strutils.is_mostly_bin(b"foo" + b"\xFF" * 10)


def test_is_xml():
    assert not strutils.is_xml(b"foo")
    assert strutils.is_xml(b"<foo")
    assert strutils.is_xml(b"  \n<foo")


def test_clean_hanging_newline():
    s = "foo\n"
    assert strutils.clean_hanging_newline(s) == "foo"
    assert strutils.clean_hanging_newline("foo") == "foo"


def test_hexdump():
    assert list(strutils.hexdump(b"one\0" * 10))
child); } struct VerilogFrontend : public Frontend { VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" read_verilog [options] [filename]\n"); log("\n"); log("Load modules from a Verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); log("\n"); log(" -sv\n"); log(" enable support for SystemVerilog features. (only a small subset\n"); log(" of SystemVerilog is supported)\n"); log("\n"); log(" -formal\n"); log(" enable support for SystemVerilog assertions and some Yosys extensions\n"); log(" replace the implicit -D SYNTHESIS with -D FORMAL\n"); log("\n"); log(" -noassert\n"); log(" ignore assert() statements\n"); log("\n"); log(" -noassume\n"); log(" ignore assume() statements\n"); log("\n"); log(" -norestrict\n"); log(" ignore restrict() statements\n"); log("\n"); log(" -assume-asserts\n"); log(" treat all assert() statements like assume() statements\n"); log("\n"); log(" -assert-assumes\n"); log(" treat all assume() statements like assert() statements\n"); log("\n"); log(" -debug\n"); log(" alias for -dump_ast1 -dump_ast2 -dump_vlog1 -dump_vlog2 -yydebug\n"); log("\n"); log(" -dump_ast1\n"); log(" dump abstract syntax tree (before simplification)\n"); log("\n"); log(" -dump_ast2\n"); log(" dump abstract syntax tree (after simplification)\n"); log("\n"); log(" -no_dump_ptr\n"); log(" do not include hex memory addresses in dump (easier to diff dumps)\n"); log("\n"); log(" -dump_vlog1\n"); log(" dump ast as Verilog code (before simplification)\n"); log("\n"); log(" -dump_vlog2\n"); log(" dump ast as Verilog code (after simplification)\n"); log("\n"); log(" -dump_rtlil\n"); log(" dump generated RTLIL netlist\n"); log("\n"); log(" -yydebug\n"); log(" enable parser debug output\n"); log("\n"); log(" -nolatches\n"); log(" usually latches are synthesized into logic loops\n"); log(" this option prohibits this and sets the output to 'x'\n"); log(" in what would be the latches hold condition\n"); log("\n"); log(" this behavior can also be achieved by setting the\n"); log(" 'nolatches' attribute on the respective module or\n"); log(" always block.\n"); log("\n"); log(" -nomem2reg\n"); log(" under certain conditions memories are converted to registers\n"); log(" early during simplification to ensure correct handling of\n"); log(" complex corner cases. this option disables this behavior.\n"); log("\n"); log(" this can also be achieved by setting the 'nomem2reg'\n"); log(" attribute on the respective module or register.\n"); log("\n"); log(" This is potentially dangerous. Usually the front-end has good\n"); log(" reasons for converting an array to a list of registers.\n"); log(" Prohibiting this step will likely result in incorrect synthesis\n"); log(" results.\n"); log("\n"); log(" -mem2reg\n"); log(" always convert memories to registers. this can also be\n"); log(" achieved by setting the 'mem2reg' attribute on the respective\n"); log(" module or register.\n"); log("\n"); log(" -nomeminit\n"); log(" do not infer $meminit cells and instead convert initialized\n"); log(" memories to registers directly in the front-end.\n"); log("\n"); log(" -ppdump\n"); log(" dump Verilog code after pre-processor\n"); log("\n"); log(" -nopp\n"); log(" do not run the pre-processor\n"); log("\n"); log(" -nodpi\n"); log(" disable DPI-C support\n"); log("\n"); log(" -noblackbox\n"); log(" do not automatically add a (* blackbox *) attribute to an\n"); log(" empty module.\n"); log("\n"); log(" -lib\n"); log(" only create empty blackbox modules. This implies -DBLACKBOX.\n"); log(" modules with the (* whitebox *) attribute will be preserved.\n"); log(" (* lib_whitebox *) will be treated like (* whitebox *).\n"); log("\n"); log(" -nowb\n"); log(" delete (* whitebox *) and (* lib_whitebox *) attributes from\n"); log(" all modules.\n"); log("\n"); log(" -noopt\n"); log(" don't perform basic optimizations (such as const folding) in the\n"); log(" high-level front-end.\n"); log("\n"); log(" -icells\n"); log(" interpret cell types starting with '$' as internal cell types\n"); log("\n"); log(" -nooverwrite\n"); log(" ignore re-definitions of modules. (the default behavior is to\n"); log(" create an error message if the existing module is not a black box\n"); log(" module, and overwrite the existing module otherwise.)\n"); log("\n"); log(" -overwrite\n"); log(" overwrite existing modules with the same name\n"); log("\n"); log(" -defer\n"); log(" only read the abstract syntax tree and defer actual compilation\n"); log(" to a later 'hierarchy' command. Useful in cases where the default\n"); log(" parameters of modules yield invalid or not synthesizable code.\n"); log("\n"); log(" -noautowire\n"); log(" make the default of `default_nettype be \"none\" instead of \"wire\".\n"); log("\n"); log(" -setattr <attribute_name>\n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); log(" -Dname[=definition]\n"); log(" define the preprocessor symbol 'name' and set its optional value\n"); log(" 'definition'\n"); log("\n"); log(" -Idir\n"); log(" add 'dir' to the directories which are used when searching include\n"); log(" files\n"); log("\n"); log("The command 'verilog_defaults' can be used to register default options for\n"); log("subsequent calls to 'read_verilog'.\n"); log("\n"); log("Note that the Verilog frontend does a pretty good job of processing valid\n"); log("verilog input, but has not very good error reporting. It generally is\n"); log("recommended to use a simulator (for example Icarus Verilog) for checking\n"); log("the syntax of the code, rather than to rely on read_verilog for that.\n"); log("\n"); log("Depending on if read_verilog is run in -formal mode, either the macro\n"); log("SYNTHESIS or FORMAL is defined automatically. In addition, read_verilog\n"); log("always defines the macro YOSYS.\n"); log("\n"); log("See the Yosys README file for a list of non-standard Verilog features\n"); log("supported by the Yosys Verilog front-end.\n"); log("\n"); } void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { bool flag_dump_ast1 = false; bool flag_dump_ast2 = false; bool flag_no_dump_ptr = false; bool flag_dump_vlog1 = false; bool flag_dump_vlog2 = false; bool flag_dump_rtlil = false; bool flag_nolatches = false; bool flag_nomeminit = false; bool flag_nomem2reg = false; bool flag_mem2reg = false; bool flag_ppdump = false; bool flag_nopp = false; bool flag_nodpi = false; bool flag_noopt = false; bool flag_icells = false; bool flag_nooverwrite = false; bool flag_overwrite = false; bool flag_defer = false; std::map<std::string, std::string> defines_map; std::list<std::string> include_dirs; std::list<std::string> attributes; frontend_verilog_yydebug = false; sv_mode = false; formal_mode = false; norestrict_mode = false; assume_asserts_mode = false; noblackbox_mode = false; lib_mode = false; nowb_mode = false; default_nettype_wire = true; args.insert(args.begin()+1, verilog_defaults.begin(), verilog_defaults.end()); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-sv") { sv_mode = true; continue; } if (arg == "-formal") { formal_mode = true; continue; } if (arg == "-noassert") { noassert_mode = true; continue; } if (arg == "-noassume") { noassume_mode = true; continue; } if (arg == "-norestrict") { norestrict_mode = true; continue; } if (arg == "-assume-asserts") { assume_asserts_mode = true; continue; } if (arg == "-assert-assumes") { assert_assumes_mode = true; continue; } if (arg == "-debug") { flag_dump_ast1 = true; flag_dump_ast2 = true; flag_dump_vlog1 = true; flag_dump_vlog2 = true; frontend_verilog_yydebug = true; continue; } if (arg == "-dump_ast1") { flag_dump_ast1 = true; continue; } if (arg == "-dump_ast2") { flag_dump_ast2 = true; continue; } if (arg == "-no_dump_ptr") { flag_no_dump_ptr = true; continue; } if (arg == "-dump_vlog1") { flag_dump_vlog1 = true; continue; } if (arg == "-dump_vlog2") { flag_dump_vlog2 = true; continue; } if (arg == "-dump_rtlil") { flag_dump_rtlil = true; continue; } if (arg == "-yydebug") { frontend_verilog_yydebug = true; continue; } if (arg == "-nolatches") { flag_nolatches = true; continue; } if (arg == "-nomeminit") { flag_nomeminit = true; continue; } if (arg == "-nomem2reg") { flag_nomem2reg = true; continue; } if (arg == "-mem2reg") { flag_mem2reg = true; continue; } if (arg == "-ppdump") { flag_ppdump = true; continue; } if (arg == "-nopp") { flag_nopp = true; continue; } if (arg == "-nodpi") { flag_nodpi = true; continue; } if (arg == "-noblackbox") { noblackbox_mode = true; continue; } if (arg == "-lib") { lib_mode = true; defines_map["BLACKBOX"] = string(); continue; } if (arg == "-nowb") { nowb_mode = true; continue; } if (arg == "-noopt") { flag_noopt = true; continue; } if (arg == "-icells") { flag_icells = true; continue; } if (arg == "-ignore_redef" || arg == "-nooverwrite") { flag_nooverwrite = true; flag_overwrite = false; continue; } if (arg == "-overwrite") { flag_nooverwrite = false; flag_overwrite = true; continue; } if (arg == "-defer") { flag_defer = true; continue; } if (arg == "-noautowire") { default_nettype_wire = false; continue; } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; } if (arg == "-D" && argidx+1 < args.size()) { std::string name = args[++argidx], value; size_t equal = name.find('='); if (equal != std::string::npos) { value = name.substr(equal+1); name = name.substr(0, equal); } defines_map[name] = value; continue; } if (arg.compare(0, 2, "-D") == 0) { size_t equal = arg.find('=', 2); std::string name = arg.substr(2, equal-2); std::string value; if (equal != std::string::npos) value = arg.substr(equal+1); defines_map[name] = value; continue; } if (arg == "-I" && argidx+1 < args.size()) { include_dirs.push_back(args[++argidx]); continue; } if (arg.compare(0, 2, "-I") == 0) { include_dirs.push_back(arg.substr(2)); continue; } break; } extra_args(f, filename, args, argidx); log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str()); log("Parsing %s%s input from `%s' to AST representation.\n", formal_mode ? "formal " : "", sv_mode ? "SystemVerilog" : "Verilog", filename.c_str()); AST::current_filename = filename; AST::set_line_num = &frontend_verilog_yyset_lineno; AST::get_line_num = &frontend_verilog_yyget_lineno; current_ast = new AST::AstNode(AST::AST_DESIGN); lexin = f; std::string code_after_preproc; if (!flag_nopp) { code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, design->verilog_defines, include_dirs); if (flag_ppdump) log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str()); lexin = new std::istringstream(code_after_preproc); } frontend_verilog_yyset_lineno(1); frontend_verilog_yyrestart(NULL); frontend_verilog_yyparse(); frontend_verilog_yylex_destroy(); for (auto &child : current_ast->children) { if (child->type == AST::AST_MODULE) for (auto &attr : attributes) if (child->attributes.count(attr) == 0) child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } if (flag_nodpi) error_on_dpi_function(current_ast); AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, noblackbox_mode, lib_mode, nowb_mode, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire); if (!flag_nopp) delete lexin; delete current_ast; current_ast = NULL; log("Successfully finished Verilog frontend.\n"); } } VerilogFrontend; struct VerilogDefaults : public Pass { VerilogDefaults() : Pass("verilog_defaults", "set default options for read_verilog") { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" verilog_defaults -add [options]\n"); log("\n"); log("Add the specified options to the list of default options to read_verilog.\n"); log("\n"); log("\n"); log(" verilog_defaults -clear\n"); log("\n"); log("Clear the list of Verilog default options.\n"); log("\n"); log("\n"); log(" verilog_defaults -push\n"); log(" verilog_defaults -pop\n"); log("\n"); log("Push or pop the list of default options to a stack. Note that -push does\n"); log("not imply -clear.\n"); log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE { if (args.size() < 2) cmd_error(args, 1, "Missing argument."); if (args[1] == "-add") { verilog_defaults.insert(verilog_defaults.end(), args.begin()+2, args.end()); return; } if (args.size() != 2) cmd_error(args, 2, "Extra argument."); if (args[1] == "-clear") { verilog_defaults.clear(); return; } if (args[1] == "-push") { verilog_defaults_stack.push_back(verilog_defaults); return; } if (args[1] == "-pop") { if (verilog_defaults_stack.empty()) { verilog_defaults.clear(); } else { verilog_defaults.swap(verilog_defaults_stack.back()); verilog_defaults_stack.pop_back(); } return; } } } VerilogDefaults; struct VerilogDefines : public Pass { VerilogDefines() : Pass("verilog_defines", "define and undefine verilog defines") { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" verilog_defines [options]\n"); log("\n"); log("Define and undefine verilog preprocessor macros.\n"); log("\n"); log(" -Dname[=definition]\n"); log(" define the preprocessor symbol 'name' and set its optional value\n"); log(" 'definition'\n"); log("\n"); log(" -Uname[=definition]\n"); log(" undefine the preprocessor symbol 'name'\n"); log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-D" && argidx+1 < args.size()) { std::string name = args[++argidx], value; size_t equal = name.find('='); if (equal != std::string::npos) { value = name.substr(equal+1); name = name.substr(0, equal); } design->verilog_defines[name] = std::pair<std::string, bool>(value, false); continue; } if (arg.compare(0, 2, "-D") == 0) { size_t equal = arg.find('=', 2); std::string name = arg.substr(2, equal-2); std::string value; if (equal != std::string::npos) value = arg.substr(equal+1); design->verilog_defines[name] = std::pair<std::string, bool>(value, false); continue; } if (arg == "-U" && argidx+1 < args.size()) { std::string name = args[++argidx]; design->verilog_defines.erase(name); continue; } if (arg.compare(0, 2, "-U") == 0) { std::string name = arg.substr(2); design->verilog_defines.erase(name); continue; } break; } if (args.size() != argidx) cmd_error(args, argidx, "Extra argument."); } } VerilogDefines; YOSYS_NAMESPACE_END // the yyerror function used by bison to report parser errors void frontend_verilog_yyerror(char const *fmt, ...) { va_list ap; char buffer[1024]; char *p = buffer; va_start(ap, fmt); p += vsnprintf(p, buffer + sizeof(buffer) - p, fmt, ap); va_end(ap); p += snprintf(p, buffer + sizeof(buffer) - p, "\n"); YOSYS_NAMESPACE_PREFIX log_file_error(YOSYS_NAMESPACE_PREFIX AST::current_filename, frontend_verilog_yyget_lineno(), "%s", buffer); exit(1); }