├── .dockerignore ├── .gitattributes ├── .github └── workflows │ └── codecov.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── ast ├── access_spec_decl.go ├── access_spec_decl_test.go ├── aligned_attr.go ├── aligned_attr_test.go ├── alloc_align_attr.go ├── alloc_align_attr_test.go ├── alloc_size_attr.go ├── alloc_size_attr_test.go ├── always_inline_attr.go ├── always_inline_attr_test.go ├── annotate_attr.go ├── annotate_attr_test.go ├── array_filler.go ├── array_filler_test.go ├── array_subscript_expr.go ├── array_subscript_expr_test.go ├── asm_label_attr.go ├── asm_label_attr_test.go ├── ast.go ├── ast_test.go ├── attributed_type.go ├── attributed_type_test.go ├── availability_attr.go ├── availability_attr_test.go ├── binary_conditional_operator.go ├── binary_conditional_operator_test.go ├── binary_operator.go ├── binary_operator_test.go ├── block_command_comment.go ├── block_command_comment_test.go ├── break_stmt.go ├── break_stmt_test.go ├── builtin_attr.go ├── builtin_attr_test.go ├── builtin_type.go ├── builtin_type_test.go ├── c11_no_return_attr.go ├── c11_no_return_attr_test.go ├── c4go_error_node.go ├── c4go_error_node_test.go ├── c_style_cast_expr.go ├── c_style_cast_expr_test.go ├── call_expr.go ├── call_expr_test.go ├── case_stmt.go ├── case_stmt_test.go ├── character_literal.go ├── character_literal_test.go ├── compound_assign_operator.go ├── compound_assign_operator_test.go ├── compound_literal_expr.go ├── compound_literal_expr_test.go ├── compound_stmt.go ├── compound_stmt_test.go ├── conditional_operator.go ├── conditional_operator_test.go ├── const_attr.go ├── const_attr_test.go ├── constant_array_type.go ├── constant_array_type_test.go ├── constant_expr.go ├── constant_expr_test.go ├── continue_stmt.go ├── continue_stmt_test.go ├── cxx_construct_expr.go ├── cxx_construct_expr_test.go ├── cxx_constructor_decl.go ├── cxx_constructor_decl_test.go ├── cxx_member_call_expr.go ├── cxx_member_call_expr_test.go ├── cxx_method_decl.go ├── cxx_method_decl_test.go ├── cxx_record.go ├── cxx_record_decl.go ├── cxx_record_decl_test.go ├── cxx_record_test.go ├── cxx_this_expr.go ├── cxx_this_expr_test.go ├── decayed_type.go ├── decayed_type_test.go ├── decl_ref_expr.go ├── decl_ref_expr_test.go ├── decl_stmt.go ├── decl_stmt_test.go ├── default_stmt.go ├── default_stmt_test.go ├── deprecated_attr.go ├── deprecated_attr_test.go ├── disable_tail_calls_attr.go ├── disable_tail_calls_attr_test.go ├── do_stmt.go ├── do_stmt_test.go ├── elaborated_type.go ├── elaborated_type_test.go ├── empty_decl.go ├── empty_decl_test.go ├── enable_if_attr.go ├── enable_if_attr_test.go ├── enum.go ├── enum_constant_decl.go ├── enum_constant_decl_test.go ├── enum_decl.go ├── enum_decl_test.go ├── enum_test.go ├── enum_type.go ├── enum_type_test.go ├── field.go ├── field_decl.go ├── field_decl_test.go ├── field_test.go ├── floating_literal.go ├── floating_literal_test.go ├── for_stmt.go ├── for_stmt_test.go ├── format_arg_attr.go ├── format_arg_attr_test.go ├── format_attr.go ├── format_attr_test.go ├── full_comment.go ├── full_comment_test.go ├── function_decl.go ├── function_decl_test.go ├── function_no_proto_type.go ├── function_no_proto_type_test.go ├── function_proto_type.go ├── function_proto_type_test.go ├── gcc_asm_stmt.go ├── gcc_asm_stmt_test.go ├── generic_selection_expr.go ├── generic_selection_expr_test.go ├── go_stmt.go ├── go_stmt_test.go ├── html_end_tag_comment.go ├── html_end_tag_comment_test.go ├── html_start_tag_comment.go ├── html_start_tag_comment_test.go ├── if_stmt.go ├── if_stmt_test.go ├── implicit_cast_expr.go ├── implicit_cast_expr_test.go ├── implicit_value_init_expr.go ├── implicit_value_init_expr_test.go ├── incomplete_array_type.go ├── incomplete_array_type_test.go ├── indirect_field_decl.go ├── indirect_field_decl_test.go ├── init_list_expr.go ├── init_list_expr_test.go ├── inline_command_comment.go ├── inline_command_comment_test.go ├── integer_literal.go ├── integer_literal_test.go ├── label_stmt.go ├── label_stmt_test.go ├── linkage_spec_decl.go ├── linkage_spec_decl_test.go ├── malloc_attr.go ├── malloc_attr_test.go ├── max_field_alignment_attr.go ├── max_field_alignment_attr_test.go ├── member_expr.go ├── member_expr_test.go ├── mode_attr.go ├── mode_attr_test.go ├── no_alias_attr.go ├── no_alias_attr_test.go ├── no_inline_attr.go ├── no_inline_attr_test.go ├── no_throw_attr.go ├── no_throw_attr_test.go ├── non_null_attr.go ├── non_null_attr_test.go ├── not_tail_called_attr.go ├── not_tail_called_attr_test.go ├── offset_of_expr.go ├── offset_of_expr_test.go ├── opaque_value_expr.go ├── opaque_value_expr_test.go ├── overloadable_attr.go ├── overloadable_attr_test.go ├── packed_attr.go ├── packed_attr_test.go ├── paragraph_comment.go ├── paragraph_comment_test.go ├── param_command_comment.go ├── param_command_comment_test.go ├── paren_expr.go ├── paren_expr_test.go ├── paren_type.go ├── paren_type_test.go ├── parm_var_decl.go ├── parm_var_decl_test.go ├── pointer_type.go ├── pointer_type_test.go ├── position.go ├── position_test.go ├── predefined_expr.go ├── predefined_expr_test.go ├── pure_attr.go ├── pure_attr_test.go ├── qual_type.go ├── qual_type_test.go ├── record.go ├── record_decl.go ├── record_decl_test.go ├── record_test.go ├── record_type.go ├── record_type_test.go ├── restrict_attr.go ├── restrict_attr_test.go ├── return_stmt.go ├── return_stmt_test.go ├── returns_twice_attr.go ├── returns_twice_attr_test.go ├── sentinel_attr.go ├── sentinel_attr_test.go ├── static_assert_decl.go ├── static_assert_decl_test.go ├── stmt_expr.go ├── stmt_expr_test.go ├── string_literal.go ├── string_literal_test.go ├── switch_stmt.go ├── switch_stmt_test.go ├── text_comment.go ├── text_comment_test.go ├── translation_unit_decl.go ├── translation_unit_decl_test.go ├── transparent_union_attr.go ├── transparent_union_attr_test.go ├── traverse.go ├── typedef.go ├── typedef_decl.go ├── typedef_decl_test.go ├── typedef_test.go ├── typedef_type.go ├── typedef_type_test.go ├── unary_expr_or_type_trait_expr.go ├── unary_expr_or_type_trait_expr_test.go ├── unary_operator.go ├── unary_operator_test.go ├── unused_attr.go ├── unused_attr_test.go ├── used_attr.go ├── used_attr_test.go ├── util.go ├── util_test.go ├── va_arg_expr.go ├── va_arg_expr_test.go ├── var_decl.go ├── var_decl_test.go ├── verbatim_block_comment.go ├── verbatim_block_comment_test.go ├── verbatim_block_line_comment.go ├── verbatim_block_line_comment_test.go ├── verbatim_line_comment.go ├── verbatim_line_comment_test.go ├── visibility_attr.go ├── visibility_attr_test.go ├── warn_unused_result_attr.go ├── warn_unused_result_attr_test.go ├── weak_attr.go ├── weak_attr_test.go ├── while_stmt.go └── while_stmt_test.go ├── bind_test.go ├── cli_test.go ├── codecov.yml ├── cstd_test.go ├── debug.go ├── examples ├── ap.c ├── fib.c ├── math.c └── prime.c ├── go.mod ├── go.sum ├── main.go ├── main_test.go ├── noarch ├── ctype.go ├── errno.go ├── fcntl.go ├── ioctl.go ├── locale.go ├── noarch.go ├── signal.go ├── stddef.go ├── stdio.go ├── stdlib.go ├── string.go ├── sys_resource.go ├── sys_time.go ├── termios.go ├── time.go ├── unistd.go ├── util.go ├── util_test.go └── wchar.go ├── other_test.go ├── preprocessor ├── compiler.go ├── parse_comments_test.go ├── parse_include_list.go ├── parse_include_list_test.go ├── parse_include_preprocessor_line.go ├── parse_include_preprocessor_line_test.go ├── preprocessor.go └── preprocessor_test.go ├── program ├── cstd.go ├── definition_function.go ├── definition_struct.go ├── definition_type.go ├── definition_variable.go ├── import.go ├── program.go ├── struct.go └── warnings.go ├── scripts ├── 9wm.sh ├── brainfuck.sh ├── cis71.sh ├── code_quality.sh ├── easymesh.sh ├── ed.sh ├── gsl.sh ├── gtk.sh ├── kilo.sh ├── lint.sh ├── minmad.sh ├── neateqn.sh ├── neatmail.sh ├── neatmkfn.sh ├── neatpost.sh ├── neatrefer.sh ├── neatroff.sh ├── neatvi.sh ├── nuklear.sh ├── progress.sh ├── redis.sh ├── scripts.sh ├── scripts.txt ├── sqlite.sh ├── test.sh ├── tiny_web_server.sh ├── triangle.sh └── vorbis.sh ├── tests ├── ap.c ├── argv.c ├── array.c ├── asm.c ├── assert.c ├── ast │ └── ast.c ├── bind │ ├── bind.c │ ├── test.c │ └── test.h ├── c4go-TestCLI-func1-AstHelpFlag ├── c4go-TestCLI-func1-AstNoFilesHelp ├── c4go-TestCLI-func1-DebugHelpFlag ├── c4go-TestCLI-func1-DebugNoFilesHelp ├── c4go-TestCLI-func1-TranspileHelpFlag ├── c4go-TestCLI-func1-TranspileNoFilesHelp ├── c4go-TestCLI-func1-UnusedHelpFlag ├── c4go-TestCLI-func1-UnusedNoFilesHelp ├── c4go-TestCLI-func1-Version ├── cast.c ├── class.cpp.todo ├── code_quality │ ├── ap.c │ ├── ap.go.expected │ ├── comments.c │ ├── comments.go.expected │ ├── define.c │ ├── define.go.expected │ ├── for.c │ ├── for.go.expected │ ├── function.c │ ├── function.go.expected │ ├── generate.sh │ ├── if.c │ ├── if.go.expected │ ├── operators.c │ ├── operators.go.expected │ ├── paren.c │ ├── paren.go.expected │ ├── return.c │ ├── return.go.expected │ ├── stdio.c │ ├── stdio.go.expected │ ├── switch.c │ ├── switch.go.expected │ ├── ternary.c │ ├── ternary.go.expected │ ├── unsafe.c │ └── unsafe.go.expected ├── comment │ └── main.c ├── ctype.c ├── do.c ├── empty.txt ├── enum.c ├── errno.c ├── exit.c ├── exit_status.c ├── externalHeader │ ├── include │ │ └── head.h │ └── main │ │ └── main.c ├── for.c ├── function.c ├── getchar.c ├── goto.c ├── if.c ├── init.c ├── ioctl.c ├── locale.c ├── math.c ├── memory.c ├── multi │ ├── err.h │ ├── header.h │ ├── main1.c │ └── main2.c ├── not.c ├── operators.c ├── raylib │ ├── CMakeLists.txt │ ├── Makefile │ ├── build.zig │ ├── config.h │ ├── external │ │ ├── cgltf.h │ │ ├── dirent.h │ │ ├── dr_flac.h │ │ ├── dr_mp3.h │ │ ├── dr_wav.h │ │ ├── glad.h │ │ ├── glfw │ │ │ ├── .mailmap │ │ │ ├── CMake │ │ │ │ ├── GenerateMappings.cmake │ │ │ │ ├── Info.plist.in │ │ │ │ ├── cmake_uninstall.cmake.in │ │ │ │ ├── glfw3.pc.in │ │ │ │ ├── glfw3Config.cmake.in │ │ │ │ ├── i686-w64-mingw32-clang.cmake │ │ │ │ ├── i686-w64-mingw32.cmake │ │ │ │ ├── modules │ │ │ │ │ ├── FindEpollShim.cmake │ │ │ │ │ └── FindOSMesa.cmake │ │ │ │ ├── x86_64-w64-mingw32-clang.cmake │ │ │ │ └── x86_64-w64-mingw32.cmake │ │ │ ├── CMakeLists.txt │ │ │ ├── CONTRIBUTORS.md │ │ │ ├── LICENSE.md │ │ │ ├── README.md │ │ │ ├── deps │ │ │ │ ├── getopt.c │ │ │ │ ├── getopt.h │ │ │ │ ├── glad │ │ │ │ │ ├── gl.h │ │ │ │ │ ├── gles2.h │ │ │ │ │ └── vulkan.h │ │ │ │ ├── mingw │ │ │ │ │ ├── _mingw_dxhelper.h │ │ │ │ │ ├── dinput.h │ │ │ │ │ └── xinput.h │ │ │ │ └── vs2008 │ │ │ │ │ └── stdint.h │ │ │ ├── include │ │ │ │ └── GLFW │ │ │ │ │ ├── glfw3.h │ │ │ │ │ └── glfw3native.h │ │ │ └── src │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── cocoa_init.m │ │ │ │ ├── cocoa_joystick.h │ │ │ │ ├── cocoa_joystick.m │ │ │ │ ├── cocoa_monitor.m │ │ │ │ ├── cocoa_platform.h │ │ │ │ ├── cocoa_time.c │ │ │ │ ├── cocoa_time.h │ │ │ │ ├── cocoa_window.m │ │ │ │ ├── context.c │ │ │ │ ├── egl_context.c │ │ │ │ ├── glfw.rc.in │ │ │ │ ├── glx_context.c │ │ │ │ ├── init.c │ │ │ │ ├── input.c │ │ │ │ ├── internal.h │ │ │ │ ├── linux_joystick.c │ │ │ │ ├── linux_joystick.h │ │ │ │ ├── mappings.h │ │ │ │ ├── mappings.h.in │ │ │ │ ├── monitor.c │ │ │ │ ├── nsgl_context.m │ │ │ │ ├── null_init.c │ │ │ │ ├── null_joystick.c │ │ │ │ ├── null_joystick.h │ │ │ │ ├── null_monitor.c │ │ │ │ ├── null_platform.h │ │ │ │ ├── null_window.c │ │ │ │ ├── osmesa_context.c │ │ │ │ ├── platform.c │ │ │ │ ├── platform.h │ │ │ │ ├── posix_module.c │ │ │ │ ├── posix_poll.c │ │ │ │ ├── posix_poll.h │ │ │ │ ├── posix_thread.c │ │ │ │ ├── posix_thread.h │ │ │ │ ├── posix_time.c │ │ │ │ ├── posix_time.h │ │ │ │ ├── vulkan.c │ │ │ │ ├── wgl_context.c │ │ │ │ ├── win32_init.c │ │ │ │ ├── win32_joystick.c │ │ │ │ ├── win32_joystick.h │ │ │ │ ├── win32_module.c │ │ │ │ ├── win32_monitor.c │ │ │ │ ├── win32_platform.h │ │ │ │ ├── win32_thread.c │ │ │ │ ├── win32_thread.h │ │ │ │ ├── win32_time.c │ │ │ │ ├── win32_time.h │ │ │ │ ├── win32_window.c │ │ │ │ ├── window.c │ │ │ │ ├── wl_init.c │ │ │ │ ├── wl_monitor.c │ │ │ │ ├── wl_platform.h │ │ │ │ ├── wl_window.c │ │ │ │ ├── x11_init.c │ │ │ │ ├── x11_monitor.c │ │ │ │ ├── x11_platform.h │ │ │ │ ├── x11_window.c │ │ │ │ ├── xkb_unicode.c │ │ │ │ └── xkb_unicode.h │ │ ├── jar_mod.h │ │ ├── jar_xm.h │ │ ├── m3d.h │ │ ├── miniaudio.h │ │ ├── msf_gif.h │ │ ├── par_shapes.h │ │ ├── qoi.h │ │ ├── rl_gputex.h │ │ ├── sdefl.h │ │ ├── sinfl.h │ │ ├── stb_image.h │ │ ├── stb_image_resize.h │ │ ├── stb_image_write.h │ │ ├── stb_perlin.h │ │ ├── stb_rect_pack.h │ │ ├── stb_truetype.h │ │ ├── stb_vorbis.h │ │ ├── tinyobj_loader_c.h │ │ └── vox_loader.h │ ├── minshell.html │ ├── raudio.c │ ├── raygui.go │ ├── raygui.h │ ├── raylib.dll.rc │ ├── raylib.dll.rc.data │ ├── raylib.h │ ├── raylib.ico │ ├── raylib.rc │ ├── raylib.rc.data │ ├── raymath.h │ ├── rcamera.h │ ├── rcore.c │ ├── rgestures.h │ ├── rglfw.c │ ├── rlgl.h │ ├── rmodels.c │ ├── rshapes.c │ ├── rtext.c │ ├── rtextures.c │ ├── shell.html │ ├── utils.c │ └── utils.h ├── scanf.c ├── signal.c ├── sizeof.c ├── stdarg.c ├── stdbool.c ├── stddef.c ├── stdio.c ├── stdio.txt ├── stdio_fscan.txt ├── stdio_gets.c ├── stdlib.c ├── stdlib_atexit.c ├── string.c ├── struct.c ├── switch.c ├── sys_time.c ├── termios.c ├── ternary.c ├── tests.h ├── time.c ├── trigraph │ └── main.c ├── unary.c ├── union.c ├── unistd.c ├── vendor │ ├── csparce │ │ ├── README.md │ │ ├── csparse.c │ │ ├── csparse.h │ │ ├── csparse_demo1.c │ │ └── kershaw.st │ └── easymesh │ │ ├── README.md │ │ ├── anima2.gif │ │ ├── command.html │ │ ├── compilation.html │ │ ├── download.html │ │ ├── easymesh.c │ │ ├── easymesh.html │ │ ├── example1.d │ │ ├── example10.gif │ │ ├── example11.gif │ │ ├── example2.d │ │ ├── example20.gif │ │ ├── example21.gif │ │ ├── example3.d │ │ ├── example30.gif │ │ ├── example31.gif │ │ ├── example32.gif │ │ ├── features.html │ │ ├── index.html │ │ ├── input.html │ │ ├── output.html │ │ ├── output1.gif │ │ ├── output2.gif │ │ ├── references.html │ │ ├── showmesh.c │ │ └── using.html ├── wchar.c └── while.c ├── transpiler ├── binary.go ├── bind.go ├── branch.go ├── call.go ├── cast.go ├── declarations.go ├── enum.go ├── functions.go ├── goto.go ├── literals.go ├── literals_test.go ├── offset.go ├── operators.go ├── scope.go ├── switch.go ├── translation_unit.go ├── transpiler.go ├── unary.go ├── union.go ├── util.go ├── vaarg.go ├── value_to_pointer.go └── variables.go ├── types ├── binary_operator.go ├── binary_operator_test.go ├── cast.go ├── cast_test.go ├── dereference.go ├── dereference_test.go ├── resolve.go ├── resolve_test.go ├── sizeof.go └── sizeof_test.go ├── unused.go ├── util ├── diff.go ├── diff_test.go ├── errors.go ├── errors_test.go ├── goast.go ├── goast_test.go ├── regexp.go ├── util.go └── util_test.go └── version ├── make_version.go ├── version.go └── version_test.go /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | .dockerignore 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | tests/* linguist-vendored 2 | scripts/* linguist-vendored 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /pp.c 3 | /out.go 4 | /a.out 5 | /pp.json 6 | /out 7 | /.idea 8 | /build 9 | /testdata 10 | /bin 11 | /coverage.txt 12 | /c4go 13 | /.vscode 14 | *.coverprofile 15 | tests/*.go 16 | tests/debug*.c 17 | tests/debug*.h 18 | examples/*.go 19 | debug.txt 20 | tests/bind/debug.bind.h 21 | version/git_version.go 22 | tests/bind.result.go 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22 2 | WORKDIR /usr/src/app 3 | 4 | RUN apt update && apt install --yes clang && apt update && clang --version 5 | 6 | 7 | # pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change 8 | COPY go.mod go.sum ./ 9 | RUN go mod download && go mod verify 10 | 11 | 12 | 13 | COPY . . 14 | RUN go build -v -o /usr/local/bin/app . 15 | 16 | CMD ["app"] 17 | 18 | # create/build image: 19 | # 20 | # docker build --tag=c4go-app . 21 | 22 | # run image: 23 | # 24 | # docker run --rm c4go-app ./c4go -h 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Elliot Chance and Izyumov Konstantin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ast/access_spec_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAccessSpecDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2eff360 col:1 public`: &AccessSpecDecl{ 10 | Addr: 0x2eff360, 11 | Pos: NewPositionFromString("line:4:1, col:7"), 12 | Position2: "col:1", 13 | Name: "public", 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/aligned_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAlignedAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f8a1d8ccfd0 aligned`: &AlignedAttr{ 10 | Addr: 0x7f8a1d8ccfd0, 11 | Pos: NewPositionFromString("col:47, col:57"), 12 | IsAligned: true, 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x2c8ba10 `: &AlignedAttr{ 16 | Addr: 0x2c8ba10, 17 | Pos: NewPositionFromString("col:42"), 18 | IsAligned: false, 19 | ChildNodes: []Node{}, 20 | }, 21 | } 22 | 23 | runNodeTests(t, nodes) 24 | } 25 | -------------------------------------------------------------------------------- /ast/alloc_align_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAllocAlignAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc0a69091d1 1`: &AllocAlignAttr{ 10 | Addr: 0x7fc0a69091d1, 11 | Pos: NewPositionFromString("line:11:7, line:18:7"), 12 | Tags: " 1", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/alloc_size_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAllocSizeAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f8e390a5d38 1 2`: &AllocSizeAttr{ 10 | Addr: 0x7f8e390a5d38, 11 | Pos: NewPositionFromString("col:100, col:114"), 12 | A: 1, 13 | B: 2, 14 | ChildNodes: []Node{}, 15 | }, 16 | `0x7fbd1a167f48 Inherited 1 0`: &AllocSizeAttr{ 17 | Addr: 0x7fbd1a167f48, 18 | Pos: NewPositionFromString("/usr/include/stdlib.h:342:37"), 19 | IsInherited: true, 20 | A: 1, 21 | B: 0, 22 | ChildNodes: []Node{}, 23 | }, 24 | `0xb8abfd90 2`: &AllocSizeAttr{ 25 | Addr: 0xb8abfd90, 26 | Pos: NewPositionFromString("col:100, col:116"), 27 | IsInherited: false, 28 | A: 2, 29 | B: 0, 30 | ChildNodes: []Node{}, 31 | }, 32 | } 33 | 34 | runNodeTests(t, nodes) 35 | } 36 | -------------------------------------------------------------------------------- /ast/always_inline_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAlwaysInlineAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fce780f5018 always_inline`: &AlwaysInlineAttr{ 10 | Addr: 0x7fce780f5018, 11 | Pos: NewPositionFromString("/usr/include/sys/cdefs.h:313:68"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/annotate_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAnnotateAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0xb8a12b58 "introduced_in=17"`: &AnnotateAttr{ 10 | Addr: 0xb8a12b58, 11 | Pos: NewPositionFromString("col:62, col:92"), 12 | Text: "introduced_in=17", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/array_filler_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/Konstantin8105/c4go/util" 8 | ) 9 | 10 | func TestArrayFiller(t *testing.T) { 11 | expected := &ArrayFiller{ 12 | ChildNodes: []Node{}, 13 | } 14 | actual, err := Parse(`array filler`) 15 | 16 | if !reflect.DeepEqual(expected, actual) { 17 | t.Errorf("%s", util.ShowDiff(formatMultiLine(expected), 18 | formatMultiLine(actual))) 19 | } 20 | if err != nil { 21 | t.Errorf("Error parsing") 22 | } 23 | 24 | if uint64(actual.Address()) != 0 { 25 | t.Fatal("Address is not zero") 26 | } 27 | var v ArrayFiller 28 | actual.AddChild(&v) 29 | if len(actual.Children()) == 0 { 30 | t.Fatal("Childrens is not correct") 31 | } 32 | 33 | _ = actual.Position() 34 | } 35 | -------------------------------------------------------------------------------- /ast/array_subscript_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestArraySubscriptExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fe35b85d180 'char *' lvalue`: &ArraySubscriptExpr{ 10 | Addr: 0x7fe35b85d180, 11 | Pos: NewPositionFromString("col:63, col:69"), 12 | Type: "char *", 13 | Type2: "", 14 | IsLvalue: true, 15 | ChildNodes: []Node{}, 16 | }, 17 | `0x2416660 'u32':'unsigned int' lvalue`: &ArraySubscriptExpr{ 18 | Addr: 0x2416660, 19 | Pos: NewPositionFromString("col:2, col:5"), 20 | Type: "u32", 21 | Type2: "unsigned int", 22 | IsLvalue: true, 23 | ChildNodes: []Node{}, 24 | }, 25 | `0x3f147c0 'extCoord':'extCoord' lvalue`: &ArraySubscriptExpr{ 26 | Addr: 0x3f147c0, 27 | Pos: NewPositionFromString("col:39, col:55"), 28 | Type: "extCoord", 29 | Type2: "extCoord", 30 | IsLvalue: true, 31 | ChildNodes: []Node{}, 32 | }, 33 | } 34 | 35 | runNodeTests(t, nodes) 36 | } 37 | -------------------------------------------------------------------------------- /ast/asm_label_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAsmLabelAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7ff26d8224e8 "_fopen"`: &AsmLabelAttr{ 10 | Addr: 0x7ff26d8224e8, 11 | Pos: NewPositionFromString("/usr/include/sys/cdefs.h:569:36"), 12 | IsInherited: false, 13 | FunctionName: "_fopen", 14 | ChildNodes: []Node{}, 15 | }, 16 | `0x7fd55a169318 Inherited "_popen"`: &AsmLabelAttr{ 17 | Addr: 0x7fd55a169318, 18 | Pos: NewPositionFromString("/usr/include/stdio.h:325:47"), 19 | IsInherited: true, 20 | FunctionName: "_popen", 21 | ChildNodes: []Node{}, 22 | }, 23 | `0x1271fd0 "__xpg_sigpause" IsLiteralLabel`: &AsmLabelAttr{ 24 | Addr: 0x1271fd0, 25 | Pos: NewPositionFromString("col:42"), 26 | IsInherited: false, 27 | FunctionName: "__xpg_sigpause", 28 | IsLiteralLabel: true, 29 | ChildNodes: []Node{}, 30 | }, 31 | } 32 | 33 | runNodeTests(t, nodes) 34 | } 35 | -------------------------------------------------------------------------------- /ast/attributed_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // AttributedType is an attribute type 4 | type AttributedType struct { 5 | Addr Address 6 | Type string 7 | Sugar bool 8 | ChildNodes []Node 9 | } 10 | 11 | func parseAttributedType(line string) *AttributedType { 12 | groups := groupsFromRegex(`'(?P.*?)' sugar`, line) 13 | 14 | return &AttributedType{ 15 | Addr: ParseAddress(groups["address"]), 16 | Type: groups["type"], 17 | Sugar: true, 18 | ChildNodes: []Node{}, 19 | } 20 | } 21 | 22 | // AddChild adds a new child node. Child nodes can then be accessed with the 23 | // Children attribute. 24 | func (n *AttributedType) AddChild(node Node) { 25 | n.ChildNodes = append(n.ChildNodes, node) 26 | } 27 | 28 | // Address returns the numeric address of the node. See the documentation for 29 | // the Address type for more information. 30 | func (n *AttributedType) Address() Address { 31 | return n.Addr 32 | } 33 | 34 | // Children returns the child nodes. If this node does not have any children or 35 | // this node does not support children it will always return an empty slice. 36 | func (n *AttributedType) Children() []Node { 37 | return n.ChildNodes 38 | } 39 | 40 | // Position returns the position in the original source code. 41 | func (n *AttributedType) Position() Position { 42 | return Position{} 43 | } 44 | -------------------------------------------------------------------------------- /ast/attributed_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAttributedType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2b6c359e30 'int (void) __attribute__((cdecl))' sugar`: &AttributedType{ 10 | Addr: 0x2b6c359e30, 11 | Type: "int (void) __attribute__((cdecl))", 12 | Sugar: true, 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/binary_conditional_operator_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBinaryConditionalOperator(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2cdbf90 'int'`: &BinaryConditionalOperator{ 10 | Addr: 0x2cdbf90, 11 | Pos: NewPositionFromString("col:7, col:16"), 12 | Type: "int", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/binary_operator_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBinaryOperator(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fca2d8070e0 'unsigned char' '='`: &BinaryOperator{ 10 | Addr: 0x7fca2d8070e0, 11 | Pos: NewPositionFromString("col:11, col:23"), 12 | Type: "unsigned char", 13 | Operator: "=", 14 | ChildNodes: []Node{}, 15 | }, 16 | `0x1ff95b8 'T_ENUM':'T_ENUM' '='`: &BinaryOperator{ 17 | Addr: 0x1ff95b8, 18 | Pos: NewPositionFromString("line:78:2, col:7"), 19 | Type: "T_ENUM", 20 | Type2: "T_ENUM", 21 | Operator: "=", 22 | ChildNodes: []Node{}, 23 | }, 24 | `0x2fdedd0 'int' lvalue '='`: &BinaryOperator{ 25 | Addr: 0x2fdedd0, 26 | Pos: NewPositionFromString("col:204, col:223"), 27 | Type: "int", 28 | Type2: "", 29 | IsLvalue: true, 30 | Operator: "=", 31 | ChildNodes: []Node{}, 32 | }, 33 | } 34 | 35 | runNodeTests(t, nodes) 36 | } 37 | -------------------------------------------------------------------------------- /ast/block_command_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBlockCommandComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x1069fae60 Name="abstract"`: &BlockCommandComment{ 10 | Addr: 0x1069fae60, 11 | Pos: NewPositionFromString("col:4, line:163:57"), 12 | Name: "abstract", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/break_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // BreakStmt is node represent 'break' 4 | type BreakStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseBreakStmt(line string) *BreakStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &BreakStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *BreakStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *BreakStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *BreakStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *BreakStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/break_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBreakStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fca2d8070e0 `: &BreakStmt{ 10 | Addr: 0x7fca2d8070e0, 11 | Pos: NewPositionFromString("col:11, col:23"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/builtin_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBuiltinAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x22e4f60 <> Implicit 905`: &BuiltinAttr{ 10 | Addr: 0x22e4f60, 11 | Pos: NewPositionFromString(""), 12 | IsImplicit: true, 13 | IsInherited: false, 14 | Name: "905", 15 | ChildNodes: []Node{}, 16 | }, 17 | `0x22e51c8 <> Inherited Implicit 905`: &BuiltinAttr{ 18 | Addr: 0x22e51c8, 19 | Pos: NewPositionFromString(""), 20 | IsImplicit: true, 21 | IsInherited: true, 22 | Name: "905", 23 | ChildNodes: []Node{}, 24 | }, 25 | } 26 | 27 | runNodeTests(t, nodes) 28 | } 29 | -------------------------------------------------------------------------------- /ast/builtin_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // BuiltinType is builtin type 4 | type BuiltinType struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseBuiltinType(line string) *BuiltinType { 11 | groups := groupsFromRegex( 12 | "'(?P.*?)'", 13 | line, 14 | ) 15 | 16 | return &BuiltinType{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *BuiltinType) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *BuiltinType) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *BuiltinType) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *BuiltinType) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/builtin_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBuiltinType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f8a43023f40 '__int128'`: &BuiltinType{ 10 | Addr: 0x7f8a43023f40, 11 | Type: "__int128", 12 | ChildNodes: []Node{}, 13 | }, 14 | `0x7f8a43023ea0 'unsigned long long'`: &BuiltinType{ 15 | Addr: 0x7f8a43023ea0, 16 | Type: "unsigned long long", 17 | ChildNodes: []Node{}, 18 | }, 19 | } 20 | 21 | runNodeTests(t, nodes) 22 | } 23 | -------------------------------------------------------------------------------- /ast/c11_no_return_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestC11NoReturnAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x55a5fc736cf0 `: &C11NoReturnAttr{ 10 | Addr: 0x55a5fc736cf0, 11 | Pos: NewPositionFromString("col:1"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/c4go_error_node.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // C4goErrorNode is error node type 4 | type C4goErrorNode struct { 5 | } 6 | 7 | // AddChild adds a new child node. Child nodes can then be accessed with the 8 | // Children attribute. 9 | func (n C4goErrorNode) AddChild(_ Node) { 10 | panic("Not acceptable to use for that node") 11 | } 12 | 13 | // Address returns the numeric address of the node. See the documentation for 14 | // the Address type for more information. 15 | func (n C4goErrorNode) Address() (a Address) { 16 | panic("Not acceptable to use for that node") 17 | } 18 | 19 | // Children returns the child nodes. If this node does not have any children or 20 | // this node does not support children it will always return an empty slice. 21 | func (n C4goErrorNode) Children() (node []Node) { 22 | panic("Not acceptable to use for that node") 23 | } 24 | 25 | // Position returns the position in the original source code. 26 | func (n C4goErrorNode) Position() (p Position) { 27 | panic("Not acceptable to use for that node") 28 | } 29 | -------------------------------------------------------------------------------- /ast/c4go_error_node_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestC4GoErrorNode1(t *testing.T) { 9 | var c C4goErrorNode 10 | tcs := []func(){ 11 | func() { c.AddChild(c) }, 12 | func() { _ = c.Address() }, 13 | func() { _ = c.Children() }, 14 | func() { _ = c.Position() }, 15 | } 16 | 17 | for index, tc := range tcs { 18 | t.Run(fmt.Sprintf("%v", index), func(t *testing.T) { 19 | defer func() { 20 | if r := recover(); r == nil { 21 | t.Errorf("Cannot found panic") 22 | } 23 | }() 24 | tc() 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ast/c_style_cast_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCStyleCastExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fddc18fb2e0 'char' `: &CStyleCastExpr{ 10 | Addr: 0x7fddc18fb2e0, 11 | Pos: NewPositionFromString("col:50, col:56"), 12 | Type: "char", 13 | Kind: "IntegralCast", 14 | ChildNodes: []Node{}, 15 | }, 16 | `0x2781518 'T_ENUM':'T_ENUM' `: &CStyleCastExpr{ 17 | Addr: 0x2781518, 18 | Pos: NewPositionFromString("col:7, col:17"), 19 | Type: "T_ENUM", 20 | Type2: "T_ENUM", 21 | Kind: "IntegralCast", 22 | ChildNodes: []Node{}, 23 | }, 24 | } 25 | 26 | runNodeTests(t, nodes) 27 | } 28 | -------------------------------------------------------------------------------- /ast/call_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCallExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f9bf3033240 'int'`: &CallExpr{ 10 | Addr: 0x7f9bf3033240, 11 | Pos: NewPositionFromString("col:11, col:25"), 12 | Type: "int", 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x7f9bf3035c20 'int'`: &CallExpr{ 16 | Addr: 0x7f9bf3035c20, 17 | Pos: NewPositionFromString("line:7:4, col:64"), 18 | Type: "int", 19 | ChildNodes: []Node{}, 20 | }, 21 | `0x7f9bf3035c20 'intr':'enum rrr'`: &CallExpr{ 22 | Addr: 0x7f9bf3035c20, 23 | Pos: NewPositionFromString("line:7:4, col:64"), 24 | Type: "intr", 25 | Type2: "enum rrr", 26 | ChildNodes: []Node{}, 27 | }, 28 | } 29 | 30 | runNodeTests(t, nodes) 31 | } 32 | -------------------------------------------------------------------------------- /ast/case_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // CaseStmt is node represent 'case' 4 | type CaseStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseCaseStmt(line string) *CaseStmt { 11 | groups := groupsFromRegex(`<(?P.*)>`, line) 12 | 13 | return &CaseStmt{ 14 | Addr: ParseAddress(groups["address"]), 15 | Pos: NewPositionFromString(groups["position"]), 16 | ChildNodes: []Node{}, 17 | } 18 | } 19 | 20 | // AddChild adds a new child node. Child nodes can then be accessed with the 21 | // Children attribute. 22 | func (n *CaseStmt) AddChild(node Node) { 23 | n.ChildNodes = append(n.ChildNodes, node) 24 | } 25 | 26 | // Address returns the numeric address of the node. See the documentation for 27 | // the Address type for more information. 28 | func (n *CaseStmt) Address() Address { 29 | return n.Addr 30 | } 31 | 32 | // Children returns the child nodes. If this node does not have any children or 33 | // this node does not support children it will always return an empty slice. 34 | func (n *CaseStmt) Children() []Node { 35 | return n.ChildNodes 36 | } 37 | 38 | // Position returns the position in the original source code. 39 | func (n *CaseStmt) Position() Position { 40 | return n.Pos 41 | } 42 | -------------------------------------------------------------------------------- /ast/case_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCaseStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc8b5094688 `: &CaseStmt{ 10 | Addr: 0x7fc8b5094688, 11 | Pos: NewPositionFromString("line:11:5, line:12:21"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/character_literal_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCharacterLiteral(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f980b858308 'int' 10`: &CharacterLiteral{ 10 | Addr: 0x7f980b858308, 11 | Pos: NewPositionFromString("col:62"), 12 | Type: "int", 13 | Value: 10, 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/compound_assign_operator_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCompoundAssignOperator(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2dc5758 'int' '+=' ComputeLHSTy='int' ComputeResultTy='int'`: &CompoundAssignOperator{ 10 | Addr: 0x2dc5758, 11 | Pos: NewPositionFromString("line:5:2, col:7"), 12 | Type: "int", 13 | Opcode: "+=", 14 | ComputationLHSType: "int", 15 | ComputationResultType: "int", 16 | ChildNodes: []Node{}, 17 | }, 18 | `0x2f27888 'sqlite3_uint64':'unsigned long long' '>>=' ComputeLHSTy='sqlite3_uint64':'unsigned long long' ComputeResultTy='sqlite3_uint64':'unsigned long long'`: &CompoundAssignOperator{ 19 | Addr: 0x2f27888, 20 | Pos: NewPositionFromString("line:1975:15, col:21"), 21 | Type: "sqlite3_uint64", 22 | Type2: "unsigned long long", 23 | Opcode: ">>=", 24 | ComputationLHSType: "sqlite3_uint64", 25 | ComputationLHSType2: "unsigned long long", 26 | ComputationResultType: "sqlite3_uint64", 27 | ComputationResultType2: "unsigned long long", 28 | ChildNodes: []Node{}, 29 | }, 30 | } 31 | 32 | runNodeTests(t, nodes) 33 | } 34 | -------------------------------------------------------------------------------- /ast/compound_literal_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCompoundLiteralExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x5575acce81f0 'struct node':'struct node' lvalue`: &CompoundLiteralExpr{ 10 | Addr: 0x5575acce81f0, 11 | Pos: NewPositionFromString("col:21, col:40"), 12 | Type1: "struct node", 13 | Type2: "struct node", 14 | IsLvalue: true, 15 | ChildNodes: []Node{}, 16 | }, 17 | `0x350b398 '__CONST_SOCKADDR_ARG':'__CONST_SOCKADDR_ARG'`: &CompoundLiteralExpr{ 18 | Addr: 0x350b398, 19 | Pos: NewPositionFromString("col:24, col:31"), 20 | Type1: "__CONST_SOCKADDR_ARG", 21 | Type2: "__CONST_SOCKADDR_ARG", 22 | IsLvalue: false, 23 | ChildNodes: []Node{}, 24 | }, 25 | } 26 | 27 | runNodeTests(t, nodes) 28 | } 29 | -------------------------------------------------------------------------------- /ast/compound_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCompoundStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fbd0f014f18 `: &CompoundStmt{ 10 | Addr: 0x7fbd0f014f18, 11 | Pos: NewPositionFromString("col:54, line:358:1"), 12 | ChildNodes: []Node{}, 13 | }, 14 | `0x7fbd0f8360b8 `: &CompoundStmt{ 15 | Addr: 0x7fbd0f8360b8, 16 | Pos: NewPositionFromString("line:4:1, line:13:1"), 17 | ChildNodes: []Node{}, 18 | }, 19 | } 20 | 21 | runNodeTests(t, nodes) 22 | } 23 | -------------------------------------------------------------------------------- /ast/conditional_operator_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConditionalOperator(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc6ae0bc678 'void'`: &ConditionalOperator{ 10 | Addr: 0x7fc6ae0bc678, 11 | Pos: NewPositionFromString("col:6, col:89"), 12 | Type: "void", 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x2283ec0 'sqlite3_destructor_type':'void (*)(void *)'`: &ConditionalOperator{ 16 | Addr: 0x2283ec0, 17 | Pos: NewPositionFromString("line:20693:23, col:108"), 18 | Type: "sqlite3_destructor_type", 19 | Type2: "void (*)(void *)", 20 | ChildNodes: []Node{}, 21 | }, 22 | } 23 | 24 | runNodeTests(t, nodes) 25 | } 26 | -------------------------------------------------------------------------------- /ast/const_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConstAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa3b88bbb38 foo`: &ConstAttr{ 10 | Addr: 0x7fa3b88bbb38, 11 | Pos: NewPositionFromString("line:4:1, line:13:1"), 12 | Tags: "foo", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/constant_array_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConstantArrayType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f94ad016a40 'struct __va_list_tag [1]' 1 `: &ConstantArrayType{ 10 | Addr: 0x7f94ad016a40, 11 | Type: "struct __va_list_tag [1]", 12 | Size: 1, 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x7f8c5f059d20 'char [37]' 37 `: &ConstantArrayType{ 16 | Addr: 0x7f8c5f059d20, 17 | Type: "char [37]", 18 | Size: 37, 19 | ChildNodes: []Node{}, 20 | }, 21 | } 22 | 23 | runNodeTests(t, nodes) 24 | } 25 | -------------------------------------------------------------------------------- /ast/constant_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConstantExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x28f4a70 'int'`: &ConstantExpr{ 10 | Addr: 0x28f4a70, 11 | Pos: NewPositionFromString("line:223:7"), 12 | Type: "int", 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x1adecf0 'int' 0`: &ConstantExpr{ 16 | Addr: 0x1adecf0, 17 | Pos: NewPositionFromString("line:327:10, col:15"), 18 | Type: "int", 19 | Value: "0", 20 | ChildNodes: []Node{}, 21 | }, 22 | } 23 | 24 | runNodeTests(t, nodes) 25 | } 26 | -------------------------------------------------------------------------------- /ast/continue_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // ContinueStmt is node represent 'continue' 4 | type ContinueStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseContinueStmt(line string) *ContinueStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &ContinueStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *ContinueStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *ContinueStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *ContinueStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *ContinueStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/continue_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestContinueStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x1e044e0 `: &ContinueStmt{ 10 | Addr: 0x1e044e0, 11 | Pos: NewPositionFromString("col:20"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/cxx_construct_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCXXConstructExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x1f9ac68 'class person' 'void (void) throw()'`: &CXXConstructExpr{ 10 | Addr: 0x1f9ac68, 11 | Pos: NewPositionFromString("col:9"), 12 | Type: "class person", 13 | Type2: "void (void) throw()", 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/cxx_constructor_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCXXConstructorDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2fbf910 col:7 implicit used person 'void (void) throw()' inline`: &CXXConstructorDecl{ 10 | Addr: 0x2fbf910, 11 | Pos: NewPositionFromString("line:3:7"), 12 | Position2: "col:7", 13 | IsImplicit: true, 14 | IsUsed: true, 15 | Type: "person", 16 | Type2: "void (void) throw()", 17 | IsInline: true, 18 | Other: "", 19 | ChildNodes: []Node{}, 20 | }, 21 | `0x343dff8 parent 0x3475f10 prev 0x34761e0 line:28:12 used Rectangle 'void (void)'`: &CXXConstructorDecl{ 22 | Addr: 0x343dff8, 23 | Parent: "0x3475f10", 24 | Prev: "0x34761e0", 25 | Pos: NewPositionFromString("line:28:1, line:31:1"), 26 | Position2: "line:28:12", 27 | IsImplicit: false, 28 | IsUsed: true, 29 | Type: "Rectangle", 30 | Type2: "void (void)", 31 | IsInline: false, 32 | Other: "", 33 | ChildNodes: []Node{}, 34 | }, 35 | } 36 | 37 | runNodeTests(t, nodes) 38 | } 39 | -------------------------------------------------------------------------------- /ast/cxx_member_call_expr.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // CXXMemberCallExpr struct 4 | type CXXMemberCallExpr struct { 5 | *CallExpr 6 | } 7 | 8 | func parseCXXMemberCallExpr(line string) *CXXMemberCallExpr { 9 | return &CXXMemberCallExpr{parseCallExpr(line)} 10 | } 11 | 12 | // AddChild adds a new child node. Child nodes can then be accessed with the 13 | // Children attribute. 14 | func (n *CXXMemberCallExpr) AddChild(node Node) { 15 | n.ChildNodes = append(n.ChildNodes, node) 16 | } 17 | 18 | // Address returns the numeric address of the node. See the documentation for 19 | // the Address type for more information. 20 | func (n *CXXMemberCallExpr) Address() Address { 21 | return n.Addr 22 | } 23 | 24 | // Children returns the child nodes. If this node does not have any children or 25 | // this node does not support children it will always return an empty slice. 26 | func (n *CXXMemberCallExpr) Children() []Node { 27 | return n.ChildNodes 28 | } 29 | 30 | // Position returns the position in the original source code. 31 | func (n *CXXMemberCallExpr) Position() Position { 32 | return n.Pos 33 | } 34 | -------------------------------------------------------------------------------- /ast/cxx_member_call_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCXXMemberCallExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2067880 'int'`: &CXXMemberCallExpr{ 10 | CallExpr: &CallExpr{ 11 | Addr: 0x2067880, 12 | Pos: NewPositionFromString("col:43, col:54"), 13 | Type: "int", 14 | ChildNodes: []Node{}, 15 | }}, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/cxx_method_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCXXMethodDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x38a32c0 col:9 area 'int (void)'`: &CXXMethodDecl{ 10 | Addr: 0x38a32c0, 11 | Parent: "", 12 | Prev: "", 13 | Pos: NewPositionFromString("line:25:5, col:37"), 14 | Position2: "col:9", 15 | IsImplicit: false, 16 | IsUsed: false, 17 | MethodName: "area", 18 | Type: "int (void)", 19 | IsInline: false, 20 | Other: "", 21 | ChildNodes: []Node{}, 22 | }, 23 | `0x38a32c0 col:9 used area 'int (void)'`: &CXXMethodDecl{ 24 | Addr: 0x38a32c0, 25 | Parent: "", 26 | Prev: "", 27 | Pos: NewPositionFromString("line:25:5, col:37"), 28 | Position2: "col:9", 29 | IsImplicit: false, 30 | IsUsed: true, 31 | MethodName: "area", 32 | Type: "int (void)", 33 | IsInline: false, 34 | Other: "", 35 | ChildNodes: []Node{}, 36 | }, 37 | } 38 | 39 | runNodeTests(t, nodes) 40 | } 41 | -------------------------------------------------------------------------------- /ast/cxx_record.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // CXXRecord struct 4 | type CXXRecord struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseCXXRecord(line string) *CXXRecord { 11 | groups := groupsFromRegex( 12 | "'(?P.*)'", 13 | line, 14 | ) 15 | 16 | return &CXXRecord{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *CXXRecord) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *CXXRecord) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *CXXRecord) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *CXXRecord) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/cxx_record_decl.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // CXXRecordDecl is node represents a record declaration. 4 | type CXXRecordDecl struct { 5 | *RecordDecl 6 | } 7 | 8 | func parseCXXRecordDecl(line string) (res *CXXRecordDecl) { 9 | res = &CXXRecordDecl{parseRecordDecl(line)} 10 | return 11 | } 12 | 13 | // AddChild adds a new child node. Child nodes can then be accessed with the 14 | // Children attribute. 15 | func (n *CXXRecordDecl) AddChild(node Node) { 16 | n.ChildNodes = append(n.ChildNodes, node) 17 | } 18 | 19 | // Address returns the numeric address of the node. See the documentation for 20 | // the Address type for more information. 21 | func (n *CXXRecordDecl) Address() Address { 22 | return n.Addr 23 | } 24 | 25 | // Children returns the child nodes. If this node does not have any children or 26 | // this node does not support children it will always return an empty slice. 27 | func (n *CXXRecordDecl) Children() []Node { 28 | return n.ChildNodes 29 | } 30 | 31 | // Position returns the position in the original source code. 32 | func (n *CXXRecordDecl) Position() Position { 33 | return n.Pos 34 | } 35 | -------------------------------------------------------------------------------- /ast/cxx_record_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCXXRecord(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x34caec8 '__locale_struct'`: &CXXRecord{ 10 | Addr: 0x34caec8, 11 | Type: "__locale_struct", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/cxx_this_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCXXThisExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3a896e8 'class Rectangle3 *' this`: &CXXThisExpr{ 10 | Addr: 0x3a896e8, 11 | Pos: NewPositionFromString("col:30"), 12 | Type: "class Rectangle3 *", 13 | IsThis: true, 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/decayed_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // DecayedType is decayed type 4 | type DecayedType struct { 5 | Addr Address 6 | Type string 7 | Tags string 8 | ChildNodes []Node 9 | } 10 | 11 | func parseDecayedType(line string) *DecayedType { 12 | groups := groupsFromRegex( 13 | "'(?P.*)' (?P.+)", 14 | line, 15 | ) 16 | 17 | return &DecayedType{ 18 | Addr: ParseAddress(groups["address"]), 19 | Type: groups["type"], 20 | Tags: groups["tags"], 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *DecayedType) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *DecayedType) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *DecayedType) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *DecayedType) Position() Position { 45 | return Position{} 46 | } 47 | -------------------------------------------------------------------------------- /ast/decayed_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDecayedType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x1dfca42 'struct __va_list_tag *' sugar`: &DecayedType{ 10 | Addr: 0x1dfca42, 11 | Type: "struct __va_list_tag *", 12 | Tags: "sugar", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/decl_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // DeclStmt is node represents a declaration in a statement list. 4 | type DeclStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseDeclStmt(line string) *DeclStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &DeclStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *DeclStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *DeclStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *DeclStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *DeclStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/decl_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDeclStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fb791846e80 `: &DeclStmt{ 10 | Addr: 0x7fb791846e80, 11 | Pos: NewPositionFromString("line:11:4, col:31"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/default_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // DefaultStmt is node represent 'default' 4 | type DefaultStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseDefaultStmt(line string) *DefaultStmt { 11 | groups := groupsFromRegex(`<(?P.*)>`, line) 12 | 13 | return &DefaultStmt{ 14 | Addr: ParseAddress(groups["address"]), 15 | Pos: NewPositionFromString(groups["position"]), 16 | ChildNodes: []Node{}, 17 | } 18 | } 19 | 20 | // AddChild adds a new child node. Child nodes can then be accessed with the 21 | // Children attribute. 22 | func (n *DefaultStmt) AddChild(node Node) { 23 | n.ChildNodes = append(n.ChildNodes, node) 24 | } 25 | 26 | // Address returns the numeric address of the node. See the documentation for 27 | // the Address type for more information. 28 | func (n *DefaultStmt) Address() Address { 29 | return n.Addr 30 | } 31 | 32 | // Children returns the child nodes. If this node does not have any children or 33 | // this node does not support children it will always return an empty slice. 34 | func (n *DefaultStmt) Children() []Node { 35 | return n.ChildNodes 36 | } 37 | 38 | // Position returns the position in the original source code. 39 | func (n *DefaultStmt) Position() Position { 40 | return n.Pos 41 | } 42 | -------------------------------------------------------------------------------- /ast/default_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDefaultStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f951308bfb0 `: &DefaultStmt{ 10 | Addr: 0x7f951308bfb0, 11 | Pos: NewPositionFromString("line:17:5, line:18:34"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/disable_tail_calls_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDisableTailCallsAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc8fa094558 `: &DisableTailCallsAttr{ 10 | Addr: 0x7fc8fa094558, 11 | Pos: NewPositionFromString("col:107"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/do_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // DoStmt is node represent 'do' 4 | type DoStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseDoStmt(line string) *DoStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &DoStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *DoStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *DoStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *DoStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *DoStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/do_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDoStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7ff36d0a0938 `: &DoStmt{ 10 | Addr: 0x7ff36d0a0938, 11 | Pos: NewPositionFromString("line:11:5, line:14:23"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/elaborated_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestElaboratedType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f873686c120 'union __mbstate_t' sugar`: &ElaboratedType{ 10 | Addr: 0x7f873686c120, 11 | Type: "union __mbstate_t", 12 | Tags: "sugar", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/empty_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEmptyDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x480bec8 col:13`: &EmptyDecl{ 10 | Addr: 0x480bec8, 11 | Pos: NewPositionFromString("col:13"), 12 | Position2: NewPositionFromString("col:13"), 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/enable_if_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEnableIfAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0xb8add300 ""`: &EnableIfAttr{ 10 | Addr: 0xb8add300, 11 | Pos: NewPositionFromString("col:91, col:106"), 12 | Message1: "", 13 | IsInherited: false, 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/enum.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // Enum struct 4 | type Enum struct { 5 | Addr Address 6 | Name string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseEnum(line string) *Enum { 11 | groups := groupsFromRegex( 12 | "'(?P.*?)'", 13 | line, 14 | ) 15 | 16 | return &Enum{ 17 | Addr: ParseAddress(groups["address"]), 18 | Name: groups["name"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *Enum) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *Enum) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *Enum) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *Enum) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/enum_constant_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEnumConstantDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x1660db0 __codecvt_noconv 'int'`: &EnumConstantDecl{ 10 | Addr: 0x1660db0, 11 | Pos: NewPositionFromString("line:185:3"), 12 | Position2: "", 13 | IsReferenced: false, 14 | Name: "__codecvt_noconv", 15 | Type: "int", 16 | ChildNodes: []Node{}, 17 | }, 18 | `0x3c77ba8 col:3 referenced _ISalnum 'int'`: &EnumConstantDecl{ 19 | Addr: 0x3c77ba8, 20 | Pos: NewPositionFromString("line:59:3, col:65"), 21 | Position2: "col:3", 22 | IsReferenced: true, 23 | Name: "_ISalnum", 24 | Type: "int", 25 | ChildNodes: []Node{}, 26 | }, 27 | } 28 | 29 | runNodeTests(t, nodes) 30 | } 31 | -------------------------------------------------------------------------------- /ast/enum_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEnumDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x22a6c80 __codecvt_result`: &EnumDecl{ 10 | Addr: 0x22a6c80, 11 | Parent: 0, 12 | Pos: NewPositionFromString("line:180:1, line:186:1"), 13 | Position2: "", 14 | Name: "__codecvt_result", 15 | ChildNodes: []Node{}, 16 | }, 17 | `0x32fb5a0 col:6 week`: &EnumDecl{ 18 | Addr: 0x32fb5a0, 19 | Parent: 0, 20 | Pos: NewPositionFromString("enum.c:3:1, col:45"), 21 | Position2: " col:6", 22 | Name: "week", 23 | ChildNodes: []Node{}, 24 | }, 25 | `0x3a0f830 parent 0x392faf0 line:74:10 EnumTwo`: &EnumDecl{ 26 | Addr: 0x3a0f830, 27 | Parent: 0x392faf0, 28 | Pos: NewPositionFromString("line:74:5, line:76:5"), 29 | Position2: " line:74:10", 30 | Name: "EnumTwo", 31 | ChildNodes: []Node{}, 32 | }, 33 | `0x2b002c0 prev 0x2affd78 line:28:6 efoo`: &EnumDecl{ 34 | Addr: 0x2b002c0, 35 | Prev: "0x2affd78", 36 | Pos: NewPositionFromString("line:28:1, line:31:1"), 37 | Position2: " line:28:6", 38 | Name: "efoo", 39 | ChildNodes: []Node{}, 40 | }, 41 | } 42 | 43 | runNodeTests(t, nodes) 44 | } 45 | -------------------------------------------------------------------------------- /ast/enum_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEnum(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f980b858308 'foo'`: &Enum{ 10 | Addr: 0x7f980b858308, 11 | Name: "foo", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/enum_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // EnumType is enum type 4 | type EnumType struct { 5 | Addr Address 6 | Name string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseEnumType(line string) *EnumType { 11 | groups := groupsFromRegex( 12 | "'(?P.*?)'", 13 | line, 14 | ) 15 | 16 | return &EnumType{ 17 | Addr: ParseAddress(groups["address"]), 18 | Name: groups["name"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *EnumType) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *EnumType) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *EnumType) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *EnumType) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/enum_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestEnumType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f980b858309 'foo'`: &EnumType{ 10 | Addr: 0x7f980b858309, 11 | Name: "foo", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/field.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // Field struct 4 | type Field struct { 5 | Addr Address 6 | String1 string 7 | String2 string 8 | ChildNodes []Node 9 | } 10 | 11 | func parseField(line string) *Field { 12 | groups := groupsFromRegex( 13 | `'(?P.*?)' '(?P.*?)'`, 14 | line, 15 | ) 16 | 17 | return &Field{ 18 | Addr: ParseAddress(groups["address"]), 19 | String1: groups["string1"], 20 | String2: groups["string2"], 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *Field) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *Field) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *Field) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *Field) Position() Position { 45 | return Position{} 46 | } 47 | -------------------------------------------------------------------------------- /ast/field_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestField(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x44159a0 '' 'union sigcontext::(anonymous at /usr/include/x86_64-linux-gnu/bits/sigcontext.h:165:17)'`: &Field{ 10 | Addr: 0x44159a0, 11 | String1: "", 12 | String2: "union sigcontext::(anonymous at /usr/include/x86_64-linux-gnu/bits/sigcontext.h:165:17)", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/floating_literal_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Konstantin8105/c4go/preprocessor" 7 | ) 8 | 9 | func TestFloatingLiteral(t *testing.T) { 10 | nodes := map[string]Node{ 11 | `0x7febe106f5e8 'double' 1.230000e+00`: &FloatingLiteral{ 12 | Addr: 0x7febe106f5e8, 13 | Pos: NewPositionFromString("col:24"), 14 | Type: "double", 15 | Value: 1.23, 16 | ChildNodes: []Node{}, 17 | }, 18 | `0x21c65b8 'double' 2.718282e+00`: &FloatingLiteral{ 19 | Addr: 0x21c65b8, 20 | Pos: NewPositionFromString("col:41"), 21 | Type: "double", 22 | Value: 2.718282e+00, 23 | ChildNodes: []Node{}, 24 | }, 25 | } 26 | 27 | runNodeTests(t, nodes) 28 | } 29 | 30 | func TestFloatingLiteralRepairFL(t *testing.T) { 31 | var fl FloatingLiteral 32 | var file preprocessor.FilePP 33 | errs := RepairFloatingLiteralsFromSource(&fl, file) 34 | if len(errs) == 0 { 35 | t.Errorf("Error is empty") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ast/for_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // ForStmt is node represent 'for' 4 | type ForStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseForStmt(line string) *ForStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &ForStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *ForStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *ForStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *ForStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *ForStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/for_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestForStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f961e018848 `: &ForStmt{ 10 | Addr: 0x7f961e018848, 11 | Pos: NewPositionFromString("line:9:4, line:10:70"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/format_arg_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFormatArgAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f1234567890 1`: &FormatArgAttr{ 10 | Addr: 0x7f1234567890, 11 | Pos: NewPositionFromString("col:47, col:57"), 12 | Arg: "1", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/format_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFormatAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fcc8d8ecee8 Implicit printf 2 3`: &FormatAttr{ 10 | Addr: 0x7fcc8d8ecee8, 11 | Pos: NewPositionFromString("col:6"), 12 | IsImplicit: true, 13 | IsInherited: false, 14 | FunctionName: "printf", 15 | Unknown1: 2, 16 | Unknown2: 3, 17 | ChildNodes: []Node{}, 18 | }, 19 | `0x7fcc8d8ecff8 printf 2 3`: &FormatAttr{ 20 | Addr: 0x7fcc8d8ecff8, 21 | Pos: NewPositionFromString("/usr/include/sys/cdefs.h:351:18, col:61"), 22 | IsImplicit: false, 23 | IsInherited: false, 24 | FunctionName: "printf", 25 | Unknown1: 2, 26 | Unknown2: 3, 27 | ChildNodes: []Node{}, 28 | }, 29 | `0x273b4d0 Inherited printf 2 3`: &FormatAttr{ 30 | Addr: 0x273b4d0, 31 | Pos: NewPositionFromString("line:357:12"), 32 | IsImplicit: false, 33 | IsInherited: true, 34 | FunctionName: "printf", 35 | Unknown1: 2, 36 | Unknown2: 3, 37 | ChildNodes: []Node{}, 38 | }, 39 | } 40 | 41 | runNodeTests(t, nodes) 42 | } 43 | -------------------------------------------------------------------------------- /ast/full_comment.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // FullComment is a type of comment 4 | type FullComment struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseFullComment(line string) *FullComment { 11 | groups := groupsFromRegex( 12 | `<(?P.*)>`, 13 | line, 14 | ) 15 | 16 | return &FullComment{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *FullComment) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *FullComment) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *FullComment) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *FullComment) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/full_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFullComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3860920 `: &FullComment{ 10 | Addr: 0x3860920, 11 | Pos: NewPositionFromString("line:10176:4, line:10180:45"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/function_no_proto_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFunctionNoProtoType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3e48580 'struct S *()' cdecl`: &FunctionNoProtoType{ 10 | Addr: 0x3e48580, 11 | Type: "struct S *()", 12 | Kind: "cdecl", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/function_proto_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFunctionProtoType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa3b88bbb30 'struct _opaque_pthread_t *' foo`: &FunctionProtoType{ 10 | Addr: 0x7fa3b88bbb30, 11 | Type: "struct _opaque_pthread_t *", 12 | Kind: "foo", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/gcc_asm_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // GCCAsmStmt is node represent gcc assembler 4 | type GCCAsmStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseGCCAsmStmt(line string) *GCCAsmStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &GCCAsmStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *GCCAsmStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *GCCAsmStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *GCCAsmStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *GCCAsmStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/gcc_asm_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestGCCAsmStmtStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fad830c9e38 `: &GCCAsmStmt{ 10 | Addr: 0x7fad830c9e38, 11 | Pos: NewPositionFromString("line:13:5, col:57"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/generic_selection_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestGenericSelectionExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3085aa0 'char [5]' lvalue`: &GenericSelectionExpr{ 10 | Addr: 0x3085aa0, 11 | Pos: NewPositionFromString("line:65:17, line:66:27"), 12 | Type: "char [5]", 13 | IsLvalue: true, 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/go_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestGotoStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fb9cc1994d8 'end_getDigits' 0x7fb9cc199490`: &GotoStmt{ 10 | Addr: 0x7fb9cc1994d8, 11 | Pos: NewPositionFromString("line:18893:9, col:14"), 12 | Name: "end_getDigits", 13 | Position2: "0x7fb9cc199490", 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/html_end_tag_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestHTMLEndTagComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x4259670 Name="i"`: &HTMLEndTagComment{ 10 | Addr: 0x4259670, 11 | Pos: NewPositionFromString("col:27, col:30"), 12 | Name: "i", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/html_start_tag_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestHTMLStartTagComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x4259670 Name="i"`: &HTMLStartTagComment{ 10 | Addr: 0x4259670, 11 | Pos: NewPositionFromString("col:27, col:30"), 12 | Name: "i", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/if_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // IfStmt is node represent 'if' 4 | type IfStmt struct { 5 | Addr Address 6 | Pos Position 7 | HasElse bool 8 | ChildNodes []Node 9 | } 10 | 11 | func parseIfStmt(line string) *IfStmt { 12 | groups := groupsFromRegex( 13 | "<(?P.*)>(?P has_else)?", 14 | line, 15 | ) 16 | 17 | return &IfStmt{ 18 | Addr: ParseAddress(groups["address"]), 19 | Pos: NewPositionFromString(groups["position"]), 20 | HasElse: len(groups["hasElse"]) > 0, 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *IfStmt) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *IfStmt) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *IfStmt) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *IfStmt) Position() Position { 45 | return n.Pos 46 | } 47 | -------------------------------------------------------------------------------- /ast/if_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestIfStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc0a69091d0 `: &IfStmt{ 10 | Addr: 0x7fc0a69091d0, 11 | Pos: NewPositionFromString("line:11:7, line:18:7"), 12 | ChildNodes: []Node{}, 13 | }, 14 | `0x25a5f78 has_else`: &IfStmt{ 15 | Addr: 0x25a5f78, 16 | Pos: NewPositionFromString("line:1329:8, line:1337:26"), 17 | HasElse: true, 18 | ChildNodes: []Node{}, 19 | }, 20 | } 21 | 22 | runNodeTests(t, nodes) 23 | } 24 | -------------------------------------------------------------------------------- /ast/implicit_value_init_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestImplicitValueInitExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f8c3396fbd8 <> 'sqlite3StatValueType':'long long'`: &ImplicitValueInitExpr{ 10 | Addr: 0x7f8c3396fbd8, 11 | Pos: NewPositionFromString(""), 12 | Type1: "sqlite3StatValueType", 13 | Type2: "long long", 14 | ChildNodes: []Node{}, 15 | }, 16 | `0x7feecb0d6af0 <> 'char'`: &ImplicitValueInitExpr{ 17 | Addr: 0x7feecb0d6af0, 18 | Pos: NewPositionFromString(""), 19 | Type1: "char", 20 | Type2: "", 21 | ChildNodes: []Node{}, 22 | }, 23 | } 24 | 25 | runNodeTests(t, nodes) 26 | } 27 | -------------------------------------------------------------------------------- /ast/incomplete_array_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // IncompleteArrayType is incomplete array type 4 | type IncompleteArrayType struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseIncompleteArrayType(line string) *IncompleteArrayType { 11 | groups := groupsFromRegex( 12 | "'(?P.*)' ", 13 | line, 14 | ) 15 | 16 | return &IncompleteArrayType{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *IncompleteArrayType) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *IncompleteArrayType) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *IncompleteArrayType) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *IncompleteArrayType) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/incomplete_array_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestIncompleteArrayType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fcb7d005c20 'int []' `: &IncompleteArrayType{ 10 | Addr: 0x7fcb7d005c20, 11 | Type: "int []", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/indirect_field_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestIndirectFieldDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2be19a8 col:25 implicit fpstate 'struct _fpstate *'`: &IndirectFieldDecl{ 10 | Addr: 0x2be19a8, 11 | Pos: NewPositionFromString("line:167:25"), 12 | Position2: "col:25", 13 | IsImplicit: true, 14 | Name: "fpstate", 15 | Type: "struct _fpstate *", 16 | ChildNodes: []Node{}, 17 | }, 18 | } 19 | 20 | runNodeTests(t, nodes) 21 | } 22 | -------------------------------------------------------------------------------- /ast/init_list_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestInitListExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fbdd1906c20 'const unsigned char [256]'`: &InitListExpr{ 10 | Addr: 0x7fbdd1906c20, 11 | Pos: NewPositionFromString("col:52, line:17160:1"), 12 | Type1: "const unsigned char [256]", 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x32017f0 'struct node [2]'`: &InitListExpr{ 16 | Addr: 0x32017f0, 17 | Pos: NewPositionFromString("col:24, col:41"), 18 | Type1: "struct node [2]", 19 | ChildNodes: []Node{}, 20 | }, 21 | `0x3201840 'struct node':'struct node'`: &InitListExpr{ 22 | Addr: 0x3201840, 23 | Pos: NewPositionFromString("col:25, col:31"), 24 | Type1: "struct node", 25 | Type2: "struct node", 26 | ChildNodes: []Node{}, 27 | }, 28 | } 29 | 30 | runNodeTests(t, nodes) 31 | } 32 | -------------------------------------------------------------------------------- /ast/inline_command_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestInlineCommandComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x22e3510 Name="NOTE" RenderNormal`: &InlineCommandComment{ 10 | Addr: 0x22e3510, 11 | Pos: NewPositionFromString("col:2, col:6"), 12 | Other: "Name=\"NOTE\" RenderNormal", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/integer_literal_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestIntegerLiteral(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fbe9804bcc8 'int' 1`: &IntegerLiteral{ 10 | Addr: 0x7fbe9804bcc8, 11 | Pos: NewPositionFromString("col:14"), 12 | Type: "int", 13 | Value: "1", 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/label_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // LabelStmt is node represent a label 4 | type LabelStmt struct { 5 | Addr Address 6 | Pos Position 7 | Name string 8 | ChildNodes []Node 9 | } 10 | 11 | func parseLabelStmt(line string) *LabelStmt { 12 | groups := groupsFromRegex( 13 | "<(?P.*)> '(?P.*)'", 14 | line, 15 | ) 16 | 17 | return &LabelStmt{ 18 | Addr: ParseAddress(groups["address"]), 19 | Pos: NewPositionFromString(groups["position"]), 20 | Name: groups["name"], 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *LabelStmt) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *LabelStmt) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *LabelStmt) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *LabelStmt) Position() Position { 45 | return n.Pos 46 | } 47 | -------------------------------------------------------------------------------- /ast/label_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLabelStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fe3ba82edb8 'end_getDigits'`: &LabelStmt{ 10 | Addr: 0x7fe3ba82edb8, 11 | Pos: NewPositionFromString("line:18906:1, line:18907:22"), 12 | Name: "end_getDigits", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/linkage_spec_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLinkageSpecDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x2efe7d8 col:146 implicit C`: &LinkageSpecDecl{ 10 | Addr: 0x2efe7d8, 11 | Pos: NewPositionFromString("col:146"), 12 | Position2: "col:146", 13 | IsImplicit: true, 14 | Name: "C", 15 | ChildNodes: []Node{}, 16 | }, 17 | `0x266fad0 line:74:8 C++`: &LinkageSpecDecl{ 18 | Addr: 0x266fad0, 19 | Pos: NewPositionFromString("line:74:1, line:94:1"), 20 | Position2: "line:74:8", 21 | IsImplicit: false, 22 | Name: "C++", 23 | ChildNodes: []Node{}, 24 | }, 25 | } 26 | 27 | runNodeTests(t, nodes) 28 | } 29 | -------------------------------------------------------------------------------- /ast/malloc_attr.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // MallocAttr is a type of attribute that is optionally attached to a variable 4 | // or struct field definition. 5 | type MallocAttr struct { 6 | Addr Address 7 | Pos Position 8 | ChildNodes []Node 9 | } 10 | 11 | func parseMallocAttr(line string) *MallocAttr { 12 | groups := groupsFromRegex( 13 | "<(?P.*)>", 14 | line, 15 | ) 16 | 17 | return &MallocAttr{ 18 | Addr: ParseAddress(groups["address"]), 19 | Pos: NewPositionFromString(groups["position"]), 20 | ChildNodes: []Node{}, 21 | } 22 | } 23 | 24 | // AddChild adds a new child node. Child nodes can then be accessed with the 25 | // Children attribute. 26 | func (n *MallocAttr) AddChild(node Node) { 27 | n.ChildNodes = append(n.ChildNodes, node) 28 | } 29 | 30 | // Address returns the numeric address of the node. See the documentation for 31 | // the Address type for more information. 32 | func (n *MallocAttr) Address() Address { 33 | return n.Addr 34 | } 35 | 36 | // Children returns the child nodes. If this node does not have any children or 37 | // this node does not support children it will always return an empty slice. 38 | func (n *MallocAttr) Children() []Node { 39 | return n.ChildNodes 40 | } 41 | 42 | // Position returns the position in the original source code. 43 | func (n *MallocAttr) Position() Position { 44 | return n.Pos 45 | } 46 | -------------------------------------------------------------------------------- /ast/malloc_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestMallocAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc0a69091d1 `: &MallocAttr{ 10 | Addr: 0x7fc0a69091d1, 11 | Pos: NewPositionFromString("line:11:7, line:18:7"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/max_field_alignment_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestMaxFieldAlignmentAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fd4b7063ac0 <> Implicit 32`: &MaxFieldAlignmentAttr{ 10 | Addr: 0x7fd4b7063ac0, 11 | Pos: NewPositionFromString(""), 12 | Size: 32, 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x7fd4b7063ac0 <> Implicit 8`: &MaxFieldAlignmentAttr{ 16 | Addr: 0x7fd4b7063ac0, 17 | Pos: NewPositionFromString(""), 18 | Size: 8, 19 | ChildNodes: []Node{}, 20 | }, 21 | } 22 | 23 | runNodeTests(t, nodes) 24 | } 25 | -------------------------------------------------------------------------------- /ast/mode_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f980b858309 foo`: &ModeAttr{ 10 | Addr: 0x7f980b858309, 11 | Pos: NewPositionFromString("line:11:7, line:18:7"), 12 | Name: "foo", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/no_alias_attr.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // NoAliasAttr is a type of attribute that is optionally attached to a function declaration. 4 | type NoAliasAttr struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseNoAliasAttr(line string) *NoAliasAttr { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &NoAliasAttr{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *NoAliasAttr) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *NoAliasAttr) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *NoAliasAttr) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *NoAliasAttr) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/no_alias_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNoAliasAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa3b88bbb38 `: &NoAliasAttr{ 10 | Addr: 0x7fa3b88bbb38, 11 | Pos: NewPositionFromString("line:4:1, line:13:1"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/no_inline_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNoInlineAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc02a8a6730 `: &NoInlineAttr{ 10 | Addr: 0x7fc02a8a6730, 11 | Pos: NewPositionFromString("line:24619:23"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/no_throw_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNoThrowAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa1488273a0 `: &NoThrowAttr{ 10 | Addr: 0x7fa1488273a0, 11 | Pos: NewPositionFromString("line:7:4, line:11:4"), 12 | ChildNodes: []Node{}, 13 | IsInherited: false, 14 | IsImplicit: false, 15 | }, 16 | `0x5605ceaf4b88 Implicit`: &NoThrowAttr{ 17 | Addr: 0x5605ceaf4b88, 18 | Pos: NewPositionFromString("col:12"), 19 | ChildNodes: []Node{}, 20 | IsInherited: false, 21 | IsImplicit: true, 22 | }, 23 | `0x4153c50 Inherited`: &NoThrowAttr{ 24 | Addr: 0x4153c50, 25 | Pos: NewPositionFromString("/usr/include/unistd.h:779:46"), 26 | ChildNodes: []Node{}, 27 | IsInherited: true, 28 | IsImplicit: false, 29 | }, 30 | `0x1038b8828 Inherited Implicit`: &NoThrowAttr{ 31 | Addr: 0x1038b8828, 32 | Pos: NewPositionFromString("col:20"), 33 | ChildNodes: []Node{}, 34 | IsInherited: true, 35 | IsImplicit: true, 36 | }, 37 | } 38 | 39 | runNodeTests(t, nodes) 40 | } 41 | -------------------------------------------------------------------------------- /ast/not_tail_called_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNotTailCalledAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fc8fa094558 `: &NotTailCalledAttr{ 10 | Addr: 0x7fc8fa094558, 11 | Pos: NewPositionFromString("col:107"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/offset_of_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestOffsetOfExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa855aab838 'unsigned long'`: &OffsetOfExpr{ 10 | Addr: 0x7fa855aab838, 11 | Pos: NewPositionFromString("col:63, col:95"), 12 | Type: "unsigned long", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/opaque_value_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestOpaqueValueExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa855aab838 'unsigned long'`: &OpaqueValueExpr{ 10 | Addr: 0x7fa855aab838, 11 | Pos: NewPositionFromString("col:63, col:95"), 12 | Type: "unsigned long", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/overloadable_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestOverloadableAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa3b88bbb38 `: &OverloadableAttr{ 10 | Addr: 0x7fa3b88bbb38, 11 | Pos: NewPositionFromString("line:4:1, line:13:1"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/packed_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPackedAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fae33b1ed40 `: &PackedAttr{ 10 | Addr: 0x7fae33b1ed40, 11 | Pos: NewPositionFromString("line:551:18"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/paragraph_comment.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // ParagraphComment is a type of comment 4 | type ParagraphComment struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseParagraphComment(line string) *ParagraphComment { 11 | groups := groupsFromRegex( 12 | `<(?P.*)>`, 13 | line, 14 | ) 15 | 16 | return &ParagraphComment{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *ParagraphComment) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *ParagraphComment) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *ParagraphComment) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *ParagraphComment) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/paragraph_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestParagraphComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3860920 `: &ParagraphComment{ 10 | Addr: 0x3860920, 11 | Pos: NewPositionFromString("line:10176:4, line:10180:45"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/param_command_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestParamCommandComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x104bca8d0 [in] implicitly Param="__attr" ParamIndex=0`: &ParamCommandComment{ 10 | Addr: 0x104bca8d0, 11 | Pos: NewPositionFromString("col:4, line:59:45"), 12 | Other: "[in] implicitly Param=\"__attr\" ParamIndex=0", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/paren_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestParenExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fb0bc8b2308 'unsigned char'`: &ParenExpr{ 10 | Addr: 0x7fb0bc8b2308, 11 | Pos: NewPositionFromString("col:10, col:25"), 12 | Type: "unsigned char", 13 | Type2: "", 14 | IsLvalue: false, 15 | IsBitfield: false, 16 | ChildNodes: []Node{}, 17 | }, 18 | `0x1ff8708 'T_ENUM':'T_ENUM' lvalue`: &ParenExpr{ 19 | Addr: 0x1ff8708, 20 | Pos: NewPositionFromString("col:14, col:17"), 21 | Type: "T_ENUM", 22 | Type2: "T_ENUM", 23 | IsLvalue: true, 24 | IsBitfield: false, 25 | ChildNodes: []Node{}, 26 | }, 27 | `0x55efc60798b0 'bft':'unsigned int' lvalue bitfield`: &ParenExpr{ 28 | Addr: 0x55efc60798b0, 29 | Pos: NewPositionFromString("col:15, col:27"), 30 | Type: "bft", 31 | Type2: "unsigned int", 32 | IsLvalue: true, 33 | IsBitfield: true, 34 | ChildNodes: []Node{}, 35 | }, 36 | } 37 | 38 | runNodeTests(t, nodes) 39 | } 40 | -------------------------------------------------------------------------------- /ast/paren_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // ParenType is paren type 4 | type ParenType struct { 5 | Addr Address 6 | Type string 7 | Sugar bool 8 | ChildNodes []Node 9 | } 10 | 11 | func parseParenType(line string) *ParenType { 12 | groups := groupsFromRegex(`'(?P.*?)' sugar`, line) 13 | 14 | return &ParenType{ 15 | Addr: ParseAddress(groups["address"]), 16 | Type: groups["type"], 17 | Sugar: true, 18 | ChildNodes: []Node{}, 19 | } 20 | } 21 | 22 | // AddChild adds a new child node. Child nodes can then be accessed with the 23 | // Children attribute. 24 | func (n *ParenType) AddChild(node Node) { 25 | n.ChildNodes = append(n.ChildNodes, node) 26 | } 27 | 28 | // Address returns the numeric address of the node. See the documentation for 29 | // the Address type for more information. 30 | func (n *ParenType) Address() Address { 31 | return n.Addr 32 | } 33 | 34 | // Children returns the child nodes. If this node does not have any children or 35 | // this node does not support children it will always return an empty slice. 36 | func (n *ParenType) Children() []Node { 37 | return n.ChildNodes 38 | } 39 | 40 | // Position returns the position in the original source code. 41 | func (n *ParenType) Position() Position { 42 | return Position{} 43 | } 44 | -------------------------------------------------------------------------------- /ast/paren_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestParenType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7faf820a4c60 'void (int)' sugar`: &ParenType{ 10 | Addr: 0x7faf820a4c60, 11 | Type: "void (int)", 12 | Sugar: true, 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/pointer_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // PointerType is pointer type 4 | type PointerType struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parsePointerType(line string) *PointerType { 11 | groups := groupsFromRegex( 12 | "'(?P.*)'", 13 | line, 14 | ) 15 | 16 | return &PointerType{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *PointerType) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *PointerType) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *PointerType) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *PointerType) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/pointer_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPointerType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa3b88bbb30 'struct _opaque_pthread_t *'`: &PointerType{ 10 | Addr: 0x7fa3b88bbb30, 11 | Type: "struct _opaque_pthread_t *", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/predefined_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPredefinedExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x33d6e08 'const char [25]' lvalue __PRETTY_FUNCTION__`: &PredefinedExpr{ 10 | Addr: 0x33d6e08, 11 | Pos: NewPositionFromString("col:30"), 12 | Type: "const char [25]", 13 | IsLvalue: true, 14 | Name: "__PRETTY_FUNCTION__", 15 | ChildNodes: []Node{}, 16 | }, 17 | } 18 | 19 | runNodeTests(t, nodes) 20 | } 21 | -------------------------------------------------------------------------------- /ast/pure_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPureAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fe9eb899198 Implicit`: &PureAttr{ 10 | Addr: 0x7fe9eb899198, 11 | Pos: NewPositionFromString("col:1"), 12 | IsImplicit: true, 13 | IsInherited: false, 14 | ChildNodes: []Node{}, 15 | }, 16 | `0x7fe8d60992a0 Inherited Implicit`: &PureAttr{ 17 | Addr: 0x7fe8d60992a0, 18 | Pos: NewPositionFromString("col:1"), 19 | IsImplicit: true, 20 | IsInherited: true, 21 | ChildNodes: []Node{}, 22 | }, 23 | } 24 | 25 | runNodeTests(t, nodes) 26 | } 27 | -------------------------------------------------------------------------------- /ast/qual_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // QualType is qual type 4 | type QualType struct { 5 | Addr Address 6 | Type string 7 | Kind string 8 | ChildNodes []Node 9 | } 10 | 11 | func parseQualType(line string) *QualType { 12 | groups := groupsFromRegex( 13 | "'(?P.*)' (?P.*)", 14 | line, 15 | ) 16 | 17 | return &QualType{ 18 | Addr: ParseAddress(groups["address"]), 19 | Type: groups["type"], 20 | Kind: groups["kind"], 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *QualType) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *QualType) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *QualType) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *QualType) Position() Position { 45 | return Position{} 46 | } 47 | -------------------------------------------------------------------------------- /ast/qual_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestQualType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa3b88bbb31 'struct _opaque_pthread_t *' foo`: &QualType{ 10 | Addr: 0x7fa3b88bbb31, 11 | Type: "struct _opaque_pthread_t *", 12 | Kind: "foo", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/record.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // Record struct 4 | type Record struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseRecord(line string) *Record { 11 | groups := groupsFromRegex( 12 | "'(?P.*)'", 13 | line, 14 | ) 15 | 16 | return &Record{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *Record) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *Record) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *Record) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *Record) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/record_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestRecord(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fd3ab857950 '__sFILE'`: &Record{ 10 | Addr: 0x7fd3ab857950, 11 | Type: "__sFILE", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/record_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // RecordType is record type 4 | type RecordType struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseRecordType(line string) *RecordType { 11 | groups := groupsFromRegex( 12 | "'(?P.*)'", 13 | line, 14 | ) 15 | 16 | return &RecordType{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *RecordType) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *RecordType) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *RecordType) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *RecordType) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/record_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestRecordType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fd3ab84dda0 'struct _opaque_pthread_condattr_t'`: &RecordType{ 10 | Addr: 0x7fd3ab84dda0, 11 | Type: "struct _opaque_pthread_condattr_t", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/restrict_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestRestrictAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f980b858305 foo`: &RestrictAttr{ 10 | Addr: 0x7f980b858305, 11 | Pos: NewPositionFromString("line:11:7, line:18:7"), 12 | Name: "foo", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/return_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // ReturnStmt is node represent 'return' 4 | type ReturnStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseReturnStmt(line string) *ReturnStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &ReturnStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *ReturnStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *ReturnStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *ReturnStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *ReturnStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/return_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestReturnStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fbb7a8325e0 `: &ReturnStmt{ 10 | Addr: 0x7fbb7a8325e0, 11 | Pos: NewPositionFromString("line:13:4, col:11"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/returns_twice_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestReturnsTwiceAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7ff8e9091640 Implicit`: &ReturnsTwiceAttr{ 10 | Addr: 0x7ff8e9091640, 11 | Pos: NewPositionFromString("col:7"), 12 | ChildNodes: []Node{}, 13 | IsInherited: false, 14 | IsImplicit: true, 15 | }, 16 | `0x564a73a5ccc8 Inherited Implicit`: &ReturnsTwiceAttr{ 17 | Addr: 0x564a73a5ccc8, 18 | Pos: NewPositionFromString("col:16"), 19 | ChildNodes: []Node{}, 20 | IsInherited: true, 21 | IsImplicit: true, 22 | }, 23 | } 24 | 25 | runNodeTests(t, nodes) 26 | } 27 | -------------------------------------------------------------------------------- /ast/sentinel_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSentinelAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x346df70 0 0`: &SentinelAttr{ 10 | Addr: 0x346df70, 11 | Pos: NewPositionFromString("line:3571:19, col:33"), 12 | A: 0, 13 | B: 0, 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/static_assert_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestStaticAssertDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3526a70 col:1`: &StaticAssertDecl{ 10 | Addr: 0x3526a70, 11 | Pos: NewPositionFromString("line:3108:1, col:80"), 12 | Position2: "col:1", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/stmt_expr.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // StmtExpr is expression. 4 | type StmtExpr struct { 5 | Addr Address 6 | Pos Position 7 | Type string 8 | ChildNodes []Node 9 | } 10 | 11 | func parseStmtExpr(line string) *StmtExpr { 12 | groups := groupsFromRegex( 13 | "<(?P.*)> '(?P.*)'", 14 | line, 15 | ) 16 | 17 | return &StmtExpr{ 18 | Addr: ParseAddress(groups["address"]), 19 | Pos: NewPositionFromString(groups["position"]), 20 | Type: groups["type"], 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *StmtExpr) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *StmtExpr) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *StmtExpr) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *StmtExpr) Position() Position { 45 | return n.Pos 46 | } 47 | -------------------------------------------------------------------------------- /ast/stmt_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestStmtExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7ff4f9100d28 'int'`: &StmtExpr{ 10 | Addr: 0x7ff4f9100d28, 11 | Pos: NewPositionFromString("col:11, col:18"), 12 | Type: "int", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/switch_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // SwitchStmt is node represent 'switch' 4 | type SwitchStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseSwitchStmt(line string) *SwitchStmt { 11 | groups := groupsFromRegex(`<(?P.*)>`, line) 12 | 13 | return &SwitchStmt{ 14 | Addr: ParseAddress(groups["address"]), 15 | Pos: NewPositionFromString(groups["position"]), 16 | ChildNodes: []Node{}, 17 | } 18 | } 19 | 20 | // AddChild adds a new child node. Child nodes can then be accessed with the 21 | // Children attribute. 22 | func (n *SwitchStmt) AddChild(node Node) { 23 | n.ChildNodes = append(n.ChildNodes, node) 24 | } 25 | 26 | // Address returns the numeric address of the node. See the documentation for 27 | // the Address type for more information. 28 | func (n *SwitchStmt) Address() Address { 29 | return n.Addr 30 | } 31 | 32 | // Children returns the child nodes. If this node does not have any children or 33 | // this node does not support children it will always return an empty slice. 34 | func (n *SwitchStmt) Children() []Node { 35 | return n.ChildNodes 36 | } 37 | 38 | // Position returns the position in the original source code. 39 | func (n *SwitchStmt) Position() Position { 40 | return n.Pos 41 | } 42 | -------------------------------------------------------------------------------- /ast/switch_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSwitchStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fbca3894638 `: &SwitchStmt{ 10 | Addr: 0x7fbca3894638, 11 | Pos: NewPositionFromString("line:9:5, line:20:5"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/text_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTextComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3085bc0 Text="* CUSTOM AUXILIARY FUNCTIONS"`: &TextComment{ 10 | Addr: 0x3085bc0, 11 | Pos: NewPositionFromString("line:9950:2, col:29"), 12 | Text: "* CUSTOM AUXILIARY FUNCTIONS", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/translation_unit_decl.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // TranslationUnitDecl is node represents a translation unit declaration. 4 | type TranslationUnitDecl struct { 5 | Addr Address 6 | ChildNodes []Node 7 | } 8 | 9 | func parseTranslationUnitDecl(line string) *TranslationUnitDecl { 10 | groups := groupsFromRegex("<(?P.*)> <(?P.*)>", line) 11 | 12 | return &TranslationUnitDecl{ 13 | Addr: ParseAddress(groups["address"]), 14 | ChildNodes: []Node{}, 15 | } 16 | } 17 | 18 | // AddChild adds a new child node. Child nodes can then be accessed with the 19 | // Children attribute. 20 | func (n *TranslationUnitDecl) AddChild(node Node) { 21 | n.ChildNodes = append(n.ChildNodes, node) 22 | } 23 | 24 | // Address returns the numeric address of the node. See the documentation for 25 | // the Address type for more information. 26 | func (n *TranslationUnitDecl) Address() Address { 27 | return n.Addr 28 | } 29 | 30 | // Children returns the child nodes. If this node does not have any children or 31 | // this node does not support children it will always return an empty slice. 32 | func (n *TranslationUnitDecl) Children() []Node { 33 | return n.ChildNodes 34 | } 35 | 36 | // Position returns the position in the original source code. 37 | func (n *TranslationUnitDecl) Position() Position { 38 | return Position{} 39 | } 40 | -------------------------------------------------------------------------------- /ast/translation_unit_decl_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTranslationUnitDecl(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fe78a815ed0 <> `: &TranslationUnitDecl{ 10 | Addr: 0x7fe78a815ed0, 11 | ChildNodes: []Node{}, 12 | }, 13 | } 14 | 15 | runNodeTests(t, nodes) 16 | } 17 | -------------------------------------------------------------------------------- /ast/transparent_union_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTransparentUnionAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x304f700 `: &TransparentUnionAttr{ 10 | Addr: 0x304f700, 11 | Pos: NewPositionFromString("col:35"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/traverse.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // GetAllNodesOfType returns all of the nodes of the tree that match the type 8 | // provided. The type should be a pointer to an object in the ast package. 9 | // 10 | // The nodes returned may reference each other and there is no guaranteed order 11 | // in which the nodes are returned. 12 | func GetAllNodesOfType(root Node, t reflect.Type) []Node { 13 | nodes := []Node{} 14 | 15 | if root == nil { 16 | return []Node{} 17 | } 18 | 19 | if reflect.TypeOf(root) == t { 20 | nodes = append(nodes, root) 21 | } 22 | 23 | for _, c := range root.Children() { 24 | nodes = append(nodes, GetAllNodesOfType(c, t)...) 25 | } 26 | 27 | return nodes 28 | } 29 | -------------------------------------------------------------------------------- /ast/typedef.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // Typedef struct 4 | type Typedef struct { 5 | Addr Address 6 | Type string 7 | ChildNodes []Node 8 | } 9 | 10 | func parseTypedef(line string) *Typedef { 11 | groups := groupsFromRegex( 12 | "'(?P.*)'", 13 | line, 14 | ) 15 | 16 | return &Typedef{ 17 | Addr: ParseAddress(groups["address"]), 18 | Type: groups["type"], 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *Typedef) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *Typedef) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *Typedef) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *Typedef) Position() Position { 43 | return Position{} 44 | } 45 | -------------------------------------------------------------------------------- /ast/typedef_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTypedef(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f84d10dc1d0 '___ssize_t'`: &Typedef{ 10 | Addr: 0x7f84d10dc1d0, 11 | Type: "___ssize_t", 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/typedef_type.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // TypedefType is typedef type 4 | type TypedefType struct { 5 | Addr Address 6 | Type string 7 | Tags string 8 | ChildNodes []Node 9 | } 10 | 11 | func parseTypedefType(line string) *TypedefType { 12 | groups := groupsFromRegex( 13 | "'(?P.*)' (?P.+)", 14 | line, 15 | ) 16 | 17 | return &TypedefType{ 18 | Addr: ParseAddress(groups["address"]), 19 | Type: groups["type"], 20 | Tags: groups["tags"], 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild adds a new child node. Child nodes can then be accessed with the 26 | // Children attribute. 27 | func (n *TypedefType) AddChild(node Node) { 28 | n.ChildNodes = append(n.ChildNodes, node) 29 | } 30 | 31 | // Address returns the numeric address of the node. See the documentation for 32 | // the Address type for more information. 33 | func (n *TypedefType) Address() Address { 34 | return n.Addr 35 | } 36 | 37 | // Children returns the child nodes. If this node does not have any children or 38 | // this node does not support children it will always return an empty slice. 39 | func (n *TypedefType) Children() []Node { 40 | return n.ChildNodes 41 | } 42 | 43 | // Position returns the position in the original source code. 44 | func (n *TypedefType) Position() Position { 45 | return Position{} 46 | } 47 | -------------------------------------------------------------------------------- /ast/typedef_type_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestTypedefType(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7f887a0dc760 '__uint16_t' sugar`: &TypedefType{ 10 | Addr: 0x7f887a0dc760, 11 | Type: "__uint16_t", 12 | Tags: "sugar", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/unused_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestUnusedAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fe3e01416d0 unused`: &UnusedAttr{ 10 | Addr: 0x7fe3e01416d0, 11 | Pos: NewPositionFromString("col:47"), 12 | ChildNodes: []Node{}, 13 | IsUnused: true, 14 | }, 15 | `0x7fe3e01416d0 `: &UnusedAttr{ 16 | Addr: 0x7fe3e01416d0, 17 | Pos: NewPositionFromString("col:47"), 18 | ChildNodes: []Node{}, 19 | IsUnused: false, 20 | }, 21 | } 22 | 23 | runNodeTests(t, nodes) 24 | } 25 | -------------------------------------------------------------------------------- /ast/used_attr.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // UsedAttr is attribute 4 | type UsedAttr struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseUsedAttr(line string) *UsedAttr { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &UsedAttr{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *UsedAttr) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *UsedAttr) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *UsedAttr) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *UsedAttr) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/used_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestUsedAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x3be4e70 `: &UsedAttr{ 10 | Addr: 0x3be4e70, 11 | Pos: NewPositionFromString("col:44"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /ast/util_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestRemoveQuotes(t *testing.T) { 9 | tcs := []struct { 10 | in string 11 | out string 12 | }{ 13 | {" ", ""}, 14 | {" \"\" ", ""}, 15 | {"''", ""}, 16 | 17 | {" \"string\" ", "string"}, 18 | {"'string'", "string"}, 19 | } 20 | for index, tc := range tcs { 21 | t.Run(fmt.Sprintf("%v", index), func(t *testing.T) { 22 | a := removeQuotes(tc.in) 23 | if a != tc.out { 24 | t.Errorf("Not acceptable : `%v` `%v`", a, tc.out) 25 | } 26 | }) 27 | } 28 | } 29 | 30 | func TestAtof(t *testing.T) { 31 | defer func() { 32 | if r := recover(); r == nil { 33 | t.Errorf("Not acceptable result") 34 | } 35 | }() 36 | _ = atof("Some not float64") 37 | } 38 | 39 | func TestUnquote(t *testing.T) { 40 | defer func() { 41 | if r := recover(); r != nil { 42 | t.Errorf("Not acceptable result") 43 | } 44 | }() 45 | _ = unquote("\"") 46 | } 47 | 48 | func TestTypesTree(t *testing.T) { 49 | _ = typesTree(nil, 0) 50 | } 51 | -------------------------------------------------------------------------------- /ast/va_arg_expr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestVAArgExpr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7ff7d314bca8 'int *'`: &VAArgExpr{ 10 | Addr: 0x7ff7d314bca8, 11 | Pos: NewPositionFromString("col:6, col:31"), 12 | Type: "int *", 13 | ChildNodes: []Node{}, 14 | }, 15 | 16 | `0x46f93e8 'LOGFUNC_t':'void (*)(void *, int, const char *)'`: &VAArgExpr{ 17 | Addr: 0x46f93e8, 18 | Pos: NewPositionFromString("col:28, col:58"), 19 | Type: "LOGFUNC_t", 20 | Type2: "void (*)(void *, int, const char *)", 21 | ChildNodes: []Node{}, 22 | }, 23 | `0x46f99b8 'sqlite3_int64':'long long'`: &VAArgExpr{ 24 | Addr: 0x46f99b8, 25 | Pos: NewPositionFromString("col:30, col:64"), 26 | Type: "sqlite3_int64", 27 | Type2: "long long", 28 | ChildNodes: []Node{}, 29 | }, 30 | } 31 | 32 | runNodeTests(t, nodes) 33 | } 34 | -------------------------------------------------------------------------------- /ast/verbatim_block_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestVerbatimBlockComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x107781dd0 Name="link" CloseName=""`: &VerbatimBlockComment{ 10 | Addr: 0x107781dd0, 11 | Pos: NewPositionFromString("col:34, col:39"), 12 | Name: "link", 13 | CloseName: "", 14 | ChildNodes: []Node{}, 15 | }, 16 | } 17 | 18 | runNodeTests(t, nodes) 19 | } 20 | -------------------------------------------------------------------------------- /ast/verbatim_block_line_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestVerbatimBlockLineComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x10f8e8e20 Text=" OSAtomicAdd32}"`: &VerbatimBlockLineComment{ 10 | Addr: 0x10f8e8e20, 11 | Pos: NewPositionFromString("col:39, col:54"), 12 | Text: " OSAtomicAdd32}", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/verbatim_line_comment_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestVerbatimLineComment(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x108af4dd0 Text=" qos_class_self"`: &VerbatimLineComment{ 10 | Addr: 0x108af4dd0, 11 | Pos: NewPositionFromString("col:4, col:28"), 12 | Text: " qos_class_self", 13 | ChildNodes: []Node{}, 14 | }, 15 | } 16 | 17 | runNodeTests(t, nodes) 18 | } 19 | -------------------------------------------------------------------------------- /ast/warn_unused_result_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestWarnUnusedResultAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa1d704d420 warn_unused_result`: &WarnUnusedResultAttr{ 10 | Addr: 0x7fa1d704d420, 11 | Pos: NewPositionFromString("col:60"), 12 | Inherited: false, 13 | ChildNodes: []Node{}, 14 | }, 15 | `0x1fac810 `: &WarnUnusedResultAttr{ 16 | Addr: 0x1fac810, 17 | Pos: NewPositionFromString("line:481:52"), 18 | Inherited: false, 19 | ChildNodes: []Node{}, 20 | }, 21 | `0x3794590 Inherited`: &WarnUnusedResultAttr{ 22 | Addr: 0x3794590, 23 | Pos: NewPositionFromString("/home/kph/co/util-linux/libblkid/src/blkidP.h:374:19"), 24 | Inherited: true, 25 | ChildNodes: []Node{}, 26 | }, 27 | `0x1def418 warn_unused_result ""`: &WarnUnusedResultAttr{ 28 | Addr: 0x1def418, 29 | Pos: NewPositionFromString("col:53"), 30 | Inherited: false, 31 | Other: " \"\"", 32 | ChildNodes: []Node{}, 33 | }, 34 | } 35 | 36 | runNodeTests(t, nodes) 37 | } 38 | -------------------------------------------------------------------------------- /ast/weak_attr.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // WeakAttr for the WeakAttr node 4 | type WeakAttr struct { 5 | Addr Address 6 | Pos Position 7 | IsInherited bool 8 | ChildNodes []Node 9 | } 10 | 11 | func parseWeakAttr(line string) *WeakAttr { 12 | groups := groupsFromRegex( 13 | `<(?P.*)>(?P Inherited)?`, 14 | line, 15 | ) 16 | 17 | return &WeakAttr{ 18 | Addr: ParseAddress(groups["address"]), 19 | Pos: NewPositionFromString(groups["position"]), 20 | IsInherited: len(groups["inherited"]) > 0, 21 | ChildNodes: []Node{}, 22 | } 23 | } 24 | 25 | // AddChild method to implements Node interface 26 | func (n *WeakAttr) AddChild(node Node) { 27 | n.ChildNodes = append(n.ChildNodes, node) 28 | } 29 | 30 | // Address returns the numeric address of the node. See the documentation for 31 | // the Address type for more information. 32 | func (n *WeakAttr) Address() Address { 33 | return n.Addr 34 | } 35 | 36 | // Children returns the child nodes. If this node does not have any children or 37 | // this node does not support children it will always return an empty slice. 38 | func (n *WeakAttr) Children() []Node { 39 | return n.ChildNodes 40 | } 41 | 42 | // Position returns the position in the original source code. 43 | func (n *WeakAttr) Position() Position { 44 | return n.Pos 45 | } 46 | -------------------------------------------------------------------------------- /ast/weak_attr_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestWeakAttr(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x56069ece5110 `: &WeakAttr{ 10 | Addr: 0x56069ece5110, 11 | Pos: NewPositionFromString("line:736:22"), 12 | ChildNodes: []Node{}, 13 | }, 14 | `0x20c6ad0 Inherited`: &WeakAttr{ 15 | Addr: 0x20c6ad0, 16 | Pos: NewPositionFromString("/glibc-2.27/support/temp_file-internal.h:27:62"), 17 | IsInherited: true, 18 | ChildNodes: []Node{}, 19 | }, 20 | } 21 | 22 | runNodeTests(t, nodes) 23 | } 24 | -------------------------------------------------------------------------------- /ast/while_stmt.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | // WhileStmt is node represent 'while' 4 | type WhileStmt struct { 5 | Addr Address 6 | Pos Position 7 | ChildNodes []Node 8 | } 9 | 10 | func parseWhileStmt(line string) *WhileStmt { 11 | groups := groupsFromRegex( 12 | "<(?P.*)>", 13 | line, 14 | ) 15 | 16 | return &WhileStmt{ 17 | Addr: ParseAddress(groups["address"]), 18 | Pos: NewPositionFromString(groups["position"]), 19 | ChildNodes: []Node{}, 20 | } 21 | } 22 | 23 | // AddChild adds a new child node. Child nodes can then be accessed with the 24 | // Children attribute. 25 | func (n *WhileStmt) AddChild(node Node) { 26 | n.ChildNodes = append(n.ChildNodes, node) 27 | } 28 | 29 | // Address returns the numeric address of the node. See the documentation for 30 | // the Address type for more information. 31 | func (n *WhileStmt) Address() Address { 32 | return n.Addr 33 | } 34 | 35 | // Children returns the child nodes. If this node does not have any children or 36 | // this node does not support children it will always return an empty slice. 37 | func (n *WhileStmt) Children() []Node { 38 | return n.ChildNodes 39 | } 40 | 41 | // Position returns the position in the original source code. 42 | func (n *WhileStmt) Position() Position { 43 | return n.Pos 44 | } 45 | -------------------------------------------------------------------------------- /ast/while_stmt_test.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestWhileStmt(t *testing.T) { 8 | nodes := map[string]Node{ 9 | `0x7fa1478273a0 `: &WhileStmt{ 10 | Addr: 0x7fa1478273a0, 11 | Pos: NewPositionFromString("line:7:4, line:11:4"), 12 | ChildNodes: []Node{}, 13 | }, 14 | } 15 | 16 | runNodeTests(t, nodes) 17 | } 18 | -------------------------------------------------------------------------------- /bind_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestBinding(t *testing.T) { 6 | args := DefaultProgramArgs() 7 | args.inputFiles = []string{ 8 | "tests/raylib/raygui.h", 9 | "tests/raylib/rlgl.h", 10 | // "tests/raylib/raymath.h", 11 | "tests/raylib/rcamera.h", 12 | } 13 | args.outputFile = "./tests/bind.result.go" 14 | args.state = StateBinding 15 | args.verbose = false 16 | 17 | if err := Start(args); err != nil { 18 | t.Fatalf("Cannot transpile `%v`: %v", args, err) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | threshold: 100% 6 | if_no_uploads: error 7 | if_not_found: success 8 | if_ci_failed: error 9 | 10 | patch: 11 | default: 12 | enabled: yes 13 | target: 0% 14 | if_no_uploads: error 15 | if_not_found: success 16 | if_ci_failed: error 17 | -------------------------------------------------------------------------------- /examples/ap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // input argument - C-pointer 4 | void a(int* v1) { printf("a: %d\n", *v1); } 5 | 6 | // input argument - C-array 7 | void b(int v1[], int size) 8 | { 9 | for (size--; size >= 0; size--) { 10 | printf("b: %d %d\n", size, v1[size]); 11 | } 12 | } 13 | 14 | int main() 15 | { 16 | // value 17 | int i1 = 42; 18 | a(&i1); 19 | b(&i1, 1); 20 | 21 | // C-array 22 | int i2[] = { 11, 22 }; 23 | a(i2); 24 | b(i2, 2); 25 | 26 | // C-pointer from value 27 | int* i3 = &i1; 28 | a(i3); 29 | b(i3, 1); 30 | 31 | // C-pointer from array 32 | int* i4 = i2; 33 | a(i4); 34 | b(i4, 2); 35 | 36 | // C-pointer from array 37 | int* i5 = i2[1]; 38 | a(i5); 39 | b(i5, 1); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /examples/fib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int n = 5, first = 0, second = 1, next, c; 6 | 7 | printf("First %d terms of Fibonacci series are :-\n", n); 8 | 9 | for (c = 0; c < n; c++) { 10 | if (c <= 1) 11 | next = c; 12 | else { 13 | next = first + second; 14 | first = second; 15 | second = next; 16 | } 17 | printf("%d\n", next); 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /examples/math.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | int n; 7 | double param = 8.0, result; 8 | result = frexp(param, &n); 9 | printf("result = %5.2f\n", result); 10 | printf("n = %d\n", n); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /examples/prime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int n, c; 6 | 7 | printf("Enter a number\n"); 8 | // get value 9 | scanf("%d", &n); 10 | printf("The number is: %d\n", n); 11 | 12 | // ------- 13 | if (n == 2) 14 | printf("Prime number.\n"); 15 | else { 16 | for (c = 2; c <= n - 1; c++) { 17 | if (n % c == 0) 18 | break; 19 | } 20 | if (c != n) 21 | printf("Not prime.\n"); 22 | else 23 | printf("Prime number.\n"); 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Konstantin8105/c4go 2 | 3 | require ( 4 | github.com/Konstantin8105/cs v0.0.0-20190517091010-c069cc1cee1b 5 | github.com/Konstantin8105/errors v0.1.0 6 | github.com/Konstantin8105/tree v0.1.1 // indirect 7 | github.com/bradleyjkemp/cupaloy v2.3.0+incompatible 8 | github.com/davecgh/go-spew v1.1.1 // indirect 9 | github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 10 | github.com/pmezard/go-difflib v1.0.0 // indirect 11 | golang.org/x/sys v0.1.0 12 | ) 13 | 14 | go 1.13 15 | -------------------------------------------------------------------------------- /noarch/ctype.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | const ( 4 | ISupper uint16 = ((1 << 0) << 8) 5 | ISlower uint16 = ((1 << 1) << 8) 6 | ISalpha uint16 = ((1 << 2) << 8) 7 | ISdigit uint16 = ((1 << 3) << 8) 8 | ISxdigit uint16 = ((1 << 4) << 8) 9 | ISspace uint16 = ((1 << 5) << 8) 10 | ISprint uint16 = ((1 << 6) << 8) 11 | ISgraph uint16 = ((1 << 7) << 8) 12 | ISblank uint16 = ((1 << 8) >> 8) 13 | IScntrl uint16 = ((1 << 9) >> 8) 14 | ISpunct uint16 = ((1 << 10) >> 8) 15 | ISalnum uint16 = ((1 << 11) >> 8) 16 | ) 17 | -------------------------------------------------------------------------------- /noarch/errno.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | var errno int32 4 | 5 | func ErrnoLocation() []int32 { 6 | return []int32{errno} 7 | } 8 | -------------------------------------------------------------------------------- /noarch/fcntl.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import "syscall" 4 | 5 | type Flock = syscall.Flock_t 6 | 7 | func Open(pathname []byte, flags int32, mode ...int32) int32 { 8 | if len(mode) == 0 { 9 | mode = append(mode, 644) 10 | } 11 | fd, err := syscall.Open(CStringToString(pathname), int(flags), uint32(mode[0])) 12 | if err != nil { 13 | return -1 14 | } 15 | return int32(fd) 16 | } 17 | -------------------------------------------------------------------------------- /noarch/ioctl.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import ( 4 | "golang.org/x/sys/unix" 5 | ) 6 | 7 | type Winsize = unix.Winsize 8 | 9 | func Ioctl(fd int32, req int32, w []Winsize) int32 { 10 | wb, err := unix.IoctlGetWinsize(int(fd), uint(req)) 11 | if err != nil { 12 | return -1 13 | } 14 | w[0] = *wb 15 | return 0 16 | } 17 | -------------------------------------------------------------------------------- /noarch/locale.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | type Lconv struct { 4 | Currency_symbol []byte 5 | IntCurrSymbol []byte 6 | } 7 | 8 | func Setlocale(category int32, locale []byte) []byte { 9 | return []byte("dd") 10 | } 11 | 12 | func Localeconv() []Lconv { 13 | var l Lconv 14 | l.Currency_symbol = []byte("fake data") 15 | l.IntCurrSymbol = []byte("fake data") 16 | return append([]Lconv{}, l) 17 | } 18 | -------------------------------------------------------------------------------- /noarch/noarch.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import "fmt" 4 | 5 | // BoolToInt converts boolean value to an int, which is a common operation in C. 6 | // 0 and 1 represent false and true respectively. 7 | func BoolToInt(x bool) int32 { 8 | if x { 9 | return 1 10 | } 11 | 12 | return 0 13 | } 14 | 15 | // Not performs a logical not (!) on an integer and returns an integer. 16 | func Not(x interface{}) bool { 17 | switch v := x.(type) { 18 | case bool: 19 | return !v 20 | case int: 21 | return v == 0 22 | case int8: 23 | return v == 0 24 | case int16: 25 | return v == 0 26 | case int32: 27 | return v == 0 28 | case int64: 29 | return v == 0 30 | case uint: 31 | return v == 0 32 | case uint8: 33 | return v == 0 34 | case uint16: 35 | return v == 0 36 | case uint32: 37 | return v == 0 38 | case uint64: 39 | return v == 0 40 | case float32: 41 | return v == 0 42 | case float64: 43 | return v == 0 44 | } 45 | panic(fmt.Errorf("not support type %T", x)) 46 | } 47 | -------------------------------------------------------------------------------- /noarch/signal.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import ( 4 | "os" 5 | "syscall" 6 | ) 7 | 8 | var signals map[int32]func(int32) 9 | 10 | var c chan os.Signal 11 | 12 | func init() { 13 | signals = map[int32]func(int32){} 14 | c = make(chan os.Signal, 1) 15 | go func() { 16 | for ch := range c { 17 | s := ch.(syscall.Signal) 18 | Raise(int32(s)) 19 | } 20 | }() 21 | } 22 | 23 | func Raise(code int32) { 24 | if f, ok := signals[code]; ok { 25 | f(0) 26 | } 27 | } 28 | 29 | func Signal(code int32, f func(param int32)) (fr func(int32)) { 30 | fr, _ = signals[code] 31 | signals[code] = f 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /noarch/stddef.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | type PtrdiffT uint64 4 | -------------------------------------------------------------------------------- /noarch/sys_resource.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import "syscall" 4 | 5 | type Rusage = syscall.Rusage 6 | -------------------------------------------------------------------------------- /noarch/sys_time.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | // Timeval - struct from 4 | type Timeval struct { 5 | TvSec int32 6 | TvUsec int32 7 | } 8 | 9 | // Timezone - struct from 10 | type Timezone struct { 11 | TzMinuteswest int32 // minutes west of Greenwich 12 | TzDsttime int32 // type of DST correction 13 | } 14 | 15 | type Itimeval struct { 16 | ItInterval Timeval 17 | ItValue Timeval 18 | } 19 | 20 | // Gettimeofday - gettimeofday from 21 | func Gettimeofday(tv []Timeval, tz []Timezone) int32 { 22 | return -1 23 | } 24 | -------------------------------------------------------------------------------- /noarch/util_test.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestNullTerminatedByteSlice(t *testing.T) { 9 | type args struct { 10 | s []byte 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want string 16 | }{ 17 | {"nil slice", args{nil}, ""}, 18 | {"empty slice", args{[]byte{}}, ""}, 19 | {"single null-terminated", args{[]byte{0}}, ""}, 20 | {"multi null-terminated", args{[]byte{'a', 0, 'b', 0}}, "a"}, 21 | {"not null-terminated", args{[]byte{'a', 'b', 'c'}}, "abc"}, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := CStringToString(tt.args.s); !reflect.DeepEqual(got, tt.want) { 26 | t.Errorf("CStringToString() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /noarch/wchar.go: -------------------------------------------------------------------------------- 1 | package noarch 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type WcharT = rune 8 | 9 | func Wcscmp(w1, w2 []WcharT) int { 10 | var len1, len2 int 11 | for len1 = range w1 { 12 | if rune(w1[len1]) == '\x00' { 13 | break 14 | } 15 | } 16 | for len2 = range w2 { 17 | if rune(w2[len2]) == '\x00' { 18 | break 19 | } 20 | } 21 | if len1 > len2 { 22 | return -1 23 | } 24 | if len1 < len2 { 25 | return 1 26 | } 27 | for i := range w1 { 28 | if i == len1 { 29 | break 30 | } 31 | if r := strings.Compare(string(w1[i]), string(w2[i])); r != 0 { 32 | return r 33 | } 34 | } 35 | return 0 36 | } 37 | 38 | func Wcscpy(w1, w2 []WcharT) []WcharT { 39 | for i, c := range w2 { 40 | w1[i] = WcharT(rune(c)) 41 | if rune(w2[i]) == '\x00' { 42 | break 43 | } 44 | } 45 | return w2 46 | } 47 | 48 | func Wcslen(w []WcharT) int { 49 | return len(w) 50 | } 51 | -------------------------------------------------------------------------------- /preprocessor/compiler.go: -------------------------------------------------------------------------------- 1 | package preprocessor 2 | 3 | func Compiler(isCPP bool) (compiler string, compilerFlag []string) { 4 | compiler = "clang" 5 | compilerFlag = []string{"-O0"} 6 | if isCPP { 7 | compiler = "clang++" 8 | compilerFlag = []string{"-std=c++98"} 9 | } 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /preprocessor/parse_include_preprocessor_line.go: -------------------------------------------------------------------------------- 1 | package preprocessor 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | // typically parse that line: 10 | // # 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4 11 | func parseIncludePreprocessorLine(line string) (item *entity, err error) { 12 | if line[0] != '#' { 13 | err = fmt.Errorf("cannot parse: first symbol is not # in line %s", line) 14 | return 15 | } 16 | i := strings.Index(line, "\"") 17 | if i < 0 { 18 | err = fmt.Errorf("first index is not correct on line %s", line) 19 | return 20 | } 21 | l := strings.LastIndex(line, "\"") 22 | if i >= l { 23 | err = fmt.Errorf("not allowable positions of symbol \" (%d and %d) in line : %s", i, l, line) 24 | return 25 | } 26 | 27 | pos, err := strconv.ParseInt(strings.TrimSpace(line[1:i]), 10, 64) 28 | if err != nil { 29 | err = fmt.Errorf("cannot parse position in source : %v", err) 30 | return 31 | } 32 | 33 | if l+1 < len(line) { 34 | item = &entity{ 35 | positionInSource: int(pos), 36 | include: line[i+1 : l], 37 | other: line[l+1:], 38 | } 39 | } else { 40 | item = &entity{ 41 | positionInSource: int(pos), 42 | include: line[i+1 : l], 43 | } 44 | } 45 | 46 | return 47 | } 48 | -------------------------------------------------------------------------------- /preprocessor/preprocessor_test.go: -------------------------------------------------------------------------------- 1 | package preprocessor 2 | 3 | import "testing" 4 | 5 | func TestNewFilePPFail(t *testing.T) { 6 | _, err := NewFilePP([]string{""}, []string{""}, false) 7 | if err == nil { 8 | t.Fatalf("Haven`t error") 9 | } 10 | } 11 | 12 | func TestGetIncludeListFail(t *testing.T) { 13 | _, err := getIncludeList([]string{"@sdf s"}, []string{"wqq4 `?p"}, []string{"w3 fdws", "sdfsr 4"}, false) 14 | if err == nil { 15 | t.Fatalf("Haven`t error") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /program/warnings.go: -------------------------------------------------------------------------------- 1 | package program 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strings" 7 | 8 | "github.com/Konstantin8105/c4go/ast" 9 | ) 10 | 11 | var WarningMessage string = "// Warning " 12 | 13 | // GenerateWarningMessage - generate warning message 14 | func (p *Program) GenerateWarningMessage(e error, n ast.Node) string { 15 | message := WarningMessage 16 | if e == nil || len(e.Error()) == 0 { 17 | return "" 18 | } 19 | if n != nil { 20 | var prefix string 21 | if fd, ok := n.(*ast.FunctionDecl); ok { 22 | prefix = fmt.Sprintf("n:%s,t1:%s,t2:%s", fd.Name, fd.Type, fd.Type2) 23 | } 24 | if prefix == "" { 25 | message += fmt.Sprintf("(%T): %s:", n, n.Position().GetSimpleLocation()) 26 | } else { 27 | message += fmt.Sprintf("(%T): {prefix: %s}. %s:", n, prefix, n.Position().GetSimpleLocation()) 28 | } 29 | } 30 | message += fmt.Sprintf("%s", e.Error()) 31 | message = PathSimplification(message) 32 | return message 33 | } 34 | 35 | func PathSimplification(message string) string { 36 | if gopath := os.Getenv("GOPATH"); gopath != "" { 37 | message = strings.Replace(message, gopath, "GOPATH", -1) 38 | message = strings.Replace(message, "GOPATH/src/github.com/Konstantin8105/c4go", "C4GO", -1) 39 | } 40 | return message 41 | } 42 | -------------------------------------------------------------------------------- /scripts/code_quality.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # 5 | # DO NOT USE THAT SCRIPT ! 6 | # 7 | # 8 | 9 | set -e 10 | 11 | # clang-format version 12 | CLANG_FORMAT="clang-format" 13 | 14 | # Arguments menu 15 | echo " -r rewrite C test files in according to code-style" 16 | if [ "$1" == "-r" ]; then 17 | C_TEST_FILES=`ls ./tests/*.c ./tests/code_quality/*.c ./examples/*.c` 18 | for C_FILE in $C_TEST_FILES 19 | do 20 | echo "Formatting file '$C_FILE' ..." 21 | eval "$CLANG_FORMAT -style=WebKit -i $C_FILE" 22 | done 23 | fi 24 | 25 | # Check go fmt first 26 | # for all folders exclude testdata, vendor 27 | if [ -n "$(gofmt -l `find . -name "*.go" | grep -v testdata | grep -v vendor`)" ]; then 28 | echo "Go code is not properly formatted. Use 'gofmt'." 29 | gofmt -d . 30 | exit 1 31 | fi 32 | 33 | # Version of clang-format 34 | echo "Version of clang-format:" 35 | eval "$CLANG_FORMAT --version" 36 | 37 | # Check clang-format for C test source files 38 | C_TEST_FILES=`ls ./tests/*.c ./tests/code_quality/*.c ./examples/*.c` 39 | for C_FILE in $C_TEST_FILES 40 | do 41 | eval "$CLANG_FORMAT -style=WebKit $C_FILE > ./testdata/out" 42 | if [ -n "$(diff $C_FILE ./testdata/out)" ]; then 43 | echo "C test code '$C_FILE' is not properly formatted. Use '$CLANG_FORMAT -style=WebKit'." 44 | fi 45 | done 46 | -------------------------------------------------------------------------------- /scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | mkdir -p ./testdata/ 6 | 7 | file="./testdata/gofmt.list" 8 | eval "find ./ -name '*.go' | grep -v 'testdata' | grep -v 'vendor' > $file" 9 | 10 | while read line 11 | do 12 | # Check go fmt first 13 | if [ -n "$(gofmt -l $line)" ]; then 14 | echo "Go code is not properly formatted. Use 'gofmt' for: $line" 15 | gofmt -d . 16 | exit 1 17 | fi 18 | done < "$file" 19 | -------------------------------------------------------------------------------- /tests/argv.c: -------------------------------------------------------------------------------- 1 | // This file contains tests for the system arguments (argv). 2 | 3 | #include "tests.h" 4 | #include 5 | 6 | int main(int argc, const char** argv) 7 | { 8 | plan(2); 9 | 10 | // When this file is converted to go it is run through "go test" that needs 11 | // some extra arguments before the standard C arguments. We need to adjust 12 | // an offset so that the C program and the Go program read the same index 13 | // for the first index of the real arguments. 14 | int offset = 0; 15 | 16 | // More than three arguments means it must be run under "go test". If not 17 | // the assertion immediately below will fail. 18 | if (argc > 3) { 19 | offset = argc - 3; 20 | } 21 | 22 | // We cannot compare the zeroth argument because it will be different for C 23 | // and Go. 24 | // is_streq(argv[0], "build/go.out"); 25 | 26 | is_streq(argv[1 + offset], "some"); 27 | is_streq(argv[2 + offset], "args"); 28 | 29 | int os = 9; 30 | (void)(os); 31 | 32 | done_testing(); 33 | } 34 | 35 | void os() {} 36 | -------------------------------------------------------------------------------- /tests/asm.c: -------------------------------------------------------------------------------- 1 | // The functions in this file were adapted from: 2 | // http://read.cs.ucla.edu/sqlite-anvil/trunk/sqlite-3.6.0/src/hwtime.h 3 | // 4 | // For more information see the original issue: 5 | // https://github.com/Konstantin8105/c4go/issues/228 6 | 7 | #include "tests.h" 8 | 9 | __inline__ unsigned long sqlite3Hwtime1(void) 10 | { 11 | unsigned int lo, hi; 12 | __asm__ __volatile__("rdtsc" 13 | : "=a"(lo), "=d"(hi)); 14 | return (unsigned long)hi << 32 | lo; 15 | } 16 | 17 | // This has been disabled because clang cannot understand the asm{} syntax. 18 | //__inline sqlite_uint64 __cdecl sqlite3Hwtime2(void){ 19 | // __asm { 20 | // rdtsc 21 | // ret ; return value at EDX:EAX 22 | // } 23 | //} 24 | 25 | __inline__ unsigned long sqlite3Hwtime3(void) 26 | { 27 | unsigned long val; 28 | __asm__ __volatile__("rdtsc" 29 | : "=A"(val)); 30 | return val; 31 | } 32 | 33 | int main() 34 | { 35 | // There are no actual tests in this file because Go does not support inline 36 | // assembly. We will have to revisit this in the future. 37 | plan(0); 38 | 39 | done_testing(); 40 | } 41 | -------------------------------------------------------------------------------- /tests/assert.c: -------------------------------------------------------------------------------- 1 | // This file contains tests for assert.h. 2 | // 3 | // Note: assert() failures print directly. The output of this program will not 4 | // be valid TAP. 5 | 6 | #include "tests.h" 7 | #include 8 | #include 9 | 10 | void print_number(int* myInt) 11 | { 12 | assert(myInt != NULL); 13 | printf("%d\n", *myInt); 14 | } 15 | 16 | int main() 17 | { 18 | plan(0); 19 | 20 | int a = 10; 21 | int* b = NULL; 22 | int* c = NULL; 23 | 24 | b = &a; 25 | 26 | print_number(b); 27 | print_number(c); 28 | 29 | fail("%s", "It shouldn't make it to here!"); 30 | done_testing(); 31 | } 32 | 33 | void os() {} 34 | -------------------------------------------------------------------------------- /tests/ast/ast.c: -------------------------------------------------------------------------------- 1 | struct xx { 2 | int i; 3 | /** 4 | * Text 5 | */ 6 | struct yy { 7 | int j; 8 | struct zz { 9 | int k; 10 | } deep; 11 | } inner; 12 | }; 13 | 14 | int main() { 15 | int i = 0; 16 | int j = 1; 17 | if (i > j) 18 | return 1; 19 | if (i == j){ 20 | return 2; 21 | } 22 | 23 | ////////////// 24 | int value = 1; 25 | while (value <= 3) { 26 | value++; 27 | } 28 | 29 | ////////////// 30 | switch (1) { 31 | case 5: 32 | break; 33 | case 2: 34 | break; 35 | } 36 | 37 | for (; i < 30; i++) 38 | { 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | int i = 40; 45 | 46 | void function() 47 | { 48 | i += 2; 49 | } 50 | 51 | /* Text */ 52 | enum number { zero, 53 | one, 54 | two, 55 | three }; 56 | 57 | -------------------------------------------------------------------------------- /tests/bind/bind.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | int before(); 4 | 5 | int main(void) 6 | { 7 | int q = before(); 8 | view0(); 9 | view1(); 10 | view2(); 11 | return q; 12 | } 13 | 14 | int before() 15 | { 16 | int i = 0; 17 | int *q = &i; 18 | return *q; 19 | } 20 | -------------------------------------------------------------------------------- /tests/bind/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void view0() { printf("view0\n"); } 4 | void view1() { printf("view1\n"); } 5 | void view2() { printf("view2\n"); } 6 | -------------------------------------------------------------------------------- /tests/bind/test.h: -------------------------------------------------------------------------------- 1 | void view0(); 2 | void view1(); 3 | void view2(); 4 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-AstHelpFlag: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(Usage: test ast [-cpp] [-clang-flag values] file.c 2 | -clang-flag value 3 | Pass arguments to clang. You may provide multiple -clang-flag items. 4 | -cpp 5 | transpile CPP code 6 | -h print help information 7 | ) 8 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-AstNoFilesHelp: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(Usage: test ast [-cpp] [-clang-flag values] file.c 2 | -clang-flag value 3 | Pass arguments to clang. You may provide multiple -clang-flag items. 4 | -cpp 5 | transpile CPP code 6 | -h print help information 7 | ) 8 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-DebugHelpFlag: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(Usage: test debug [-cpp] [-clang-flag values] file.c 2 | -V print progress as comments 3 | -clang-flag value 4 | Pass arguments to clang. You may provide multiple -clang-flag items. 5 | -cpp 6 | transpile CPP code 7 | -h print help information 8 | -p string 9 | prefix of output C filename with addition debug information (default "debug.") 10 | ) 11 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-DebugNoFilesHelp: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(Usage: test debug [-cpp] [-clang-flag values] file.c 2 | -V print progress as comments 3 | -clang-flag value 4 | Pass arguments to clang. You may provide multiple -clang-flag items. 5 | -cpp 6 | transpile CPP code 7 | -h print help information 8 | -p string 9 | prefix of output C filename with addition debug information (default "debug.") 10 | ) 11 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-TranspileHelpFlag: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(Usage: test transpile [-V] [-o file.go] [-cpp] [-p package] [-clang-flag values] [-cpuprofile cpu.out] file1.c ... 2 | -V print progress as comments 3 | -clang-flag value 4 | Pass arguments to clang. You may provide multiple -clang-flag items. 5 | -cpp 6 | transpile CPP code 7 | -cpuprofile string 8 | write cpu profile to this file 9 | -h print help information 10 | -o string 11 | output Go generated code to the specified file 12 | -p string 13 | set the name of the generated package (default "main") 14 | -s transpile with structs(types, unions...) from all source headers 15 | ) 16 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-TranspileNoFilesHelp: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(Usage: test transpile [-V] [-o file.go] [-cpp] [-p package] [-clang-flag values] [-cpuprofile cpu.out] file1.c ... 2 | -V print progress as comments 3 | -clang-flag value 4 | Pass arguments to clang. You may provide multiple -clang-flag items. 5 | -cpp 6 | transpile CPP code 7 | -cpuprofile string 8 | write cpu profile to this file 9 | -h print help information 10 | -o string 11 | output Go generated code to the specified file 12 | -p string 13 | set the name of the generated package (default "main") 14 | -s transpile with structs(types, unions...) from all source headers 15 | ) 16 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-UnusedHelpFlag: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)( -h print help information 2 | ) 3 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-UnusedNoFilesHelp: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)( -h print help information 2 | ) 3 | -------------------------------------------------------------------------------- /tests/c4go-TestCLI-func1-Version: -------------------------------------------------------------------------------- 1 | (*bytes.Buffer)(development 2 | ) 3 | -------------------------------------------------------------------------------- /tests/code_quality/define.c: -------------------------------------------------------------------------------- 1 | #define A 1 2 | #define B "hello world" 3 | #define C a + 1 4 | 5 | void t() 6 | { 7 | int a = A; 8 | printf(B); 9 | int c = C; 10 | printf("%d", c); 11 | } 12 | -------------------------------------------------------------------------------- /tests/code_quality/define.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | // t - transpiled function from C4GO/tests/code_quality/define.c:5 11 | func t() { 12 | var a int32 = 1 13 | printf([]byte("hello world\x00")) 14 | var c int32 = a + 1 15 | printf([]byte("%d\x00"), c) 16 | } 17 | -------------------------------------------------------------------------------- /tests/code_quality/for.c: -------------------------------------------------------------------------------- 1 | void f1() 2 | { 3 | int i; 4 | for (i = 0; i < 10; i++) { 5 | ; 6 | } 7 | } 8 | 9 | void f2() 10 | { 11 | int i; 12 | for (i = 10; i > 0; i--) { 13 | ; 14 | } 15 | } 16 | 17 | void f3() 18 | { 19 | int i = 3; 20 | for (i = 0; i < 10; i++) { 21 | ; 22 | } 23 | } 24 | 25 | void f4() 26 | { 27 | for (int i = 0; i < 10; i++) { 28 | ; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/code_quality/for.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | // f1 - transpiled function from C4GO/tests/code_quality/for.c:1 11 | func f1() { 12 | var i int32 13 | for i = 0; i < 10; i++ { 14 | } 15 | } 16 | 17 | // f2 - transpiled function from C4GO/tests/code_quality/for.c:9 18 | func f2() { 19 | var i int32 20 | for i = 10; i > 0; i-- { 21 | } 22 | } 23 | 24 | // f3 - transpiled function from C4GO/tests/code_quality/for.c:17 25 | func f3() { 26 | var i int32 = 3 27 | for i = 0; i < 10; i++ { 28 | } 29 | } 30 | 31 | // f4 - transpiled function from C4GO/tests/code_quality/for.c:25 32 | func f4() { 33 | var i int32 34 | for ; i < 10; i++ { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/code_quality/function.c: -------------------------------------------------------------------------------- 1 | static char *sstr_s; 2 | char sstr_bufs[10]; 3 | int sstr_n; 4 | 5 | char *sstr_pop(void) 6 | { 7 | char *ret = sstr_s; 8 | sstr_s = &sstr_bufs[--sstr_n]; 9 | return ret; 10 | } 11 | 12 | int sstr_next(void) 13 | { 14 | return *sstr_s ? (unsigned char) *sstr_s++ : -1; 15 | } 16 | 17 | void sstr_back(int c) 18 | { 19 | sstr_s--; 20 | } 21 | 22 | int sf1() { 23 | sstr_n++; 24 | return *sstr_s == sstr_bufs[sstr_n] ? 1: 0; 25 | } 26 | 27 | int st2() { 28 | sstr_n++; 29 | int s = *sstr_s == sstr_bufs[sstr_n] ? 1: 0; 30 | sstr_n--; 31 | return s; 32 | } 33 | 34 | int st2a() { 35 | sstr_n++; 36 | int s; 37 | s = *sstr_s == sstr_bufs[sstr_n] ? 1: 0; 38 | sstr_n--; 39 | return s; 40 | } 41 | 42 | int st3() { 43 | sstr_n++; 44 | int s = (*sstr_s == sstr_bufs[sstr_n] ? sstr_n+1: sstr_n-1); 45 | sstr_n--; 46 | return s; 47 | } 48 | 49 | int st4() { 50 | return (*sstr_s == sstr_bufs[sstr_n] ? sstr_n+1: sstr_n-1); 51 | } 52 | -------------------------------------------------------------------------------- /tests/code_quality/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | go build 4 | 5 | # Generate code quality Go code 6 | FILES='tests/code_quality/*.c' 7 | for file in $FILES 8 | do 9 | filename=$(basename "$file") 10 | ext="${filename#*.}" 11 | if [ "$ext" = "go.expected" ]; then 12 | continue 13 | fi 14 | 15 | echo "Processing $file file..." 16 | filename=${file%.*}".go.expected" 17 | ./c4go transpile -o="$filename" -p="code_quality" $file 18 | done 19 | -------------------------------------------------------------------------------- /tests/code_quality/if.c: -------------------------------------------------------------------------------- 1 | void if_1() 2 | { 3 | int a = 5; 4 | int b = 2; 5 | int c = 4; 6 | if (a > b) { 7 | return; 8 | } else if (c <= a) { 9 | a = 0; 10 | } 11 | (void)(a); 12 | (void)(b); 13 | (void)(c); 14 | 15 | int w = 2 > 1 ? -1 : 5; 16 | int r; 17 | r = 2 > 1 ? -1 : 5; 18 | r = (2 > 1) ? -1 : 5; 19 | r = (w > 1) ? -1 : 5; 20 | r = w > 1 ? -1 : 5; 21 | r = (w > 1) + (r == 4) ? -1 : 5; 22 | if (w > 0) { 23 | r = 3; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/code_quality/if.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | import "github.com/Konstantin8105/c4go/noarch" 11 | 12 | // if_1 - transpiled function from C4GO/tests/code_quality/if.c:1 13 | func if_1() { 14 | var a int32 = 5 15 | var b int32 = 2 16 | var c int32 = 4 17 | if a > b { 18 | return 19 | } else if c <= a { 20 | a = 0 21 | } 22 | _ = a 23 | _ = b 24 | _ = c 25 | var w int32 = func() int32 { 26 | if 2 > 1 { 27 | return -1 28 | } 29 | return 5 30 | }() 31 | var r int32 32 | if 2 > 1 { 33 | r = -1 34 | } else { 35 | r = 5 36 | } 37 | if 2 > 1 { 38 | r = -1 39 | } else { 40 | r = 5 41 | } 42 | if w > 1 { 43 | r = -1 44 | } else { 45 | r = 5 46 | } 47 | if w > 1 { 48 | r = -1 49 | } else { 50 | r = 5 51 | } 52 | if noarch.BoolToInt(w > 1)+noarch.BoolToInt(r == 4) != 0 { 53 | r = -1 54 | } else { 55 | r = 5 56 | } 57 | if w > 0 { 58 | r = 3 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/code_quality/operators.c: -------------------------------------------------------------------------------- 1 | void f(unsigned d) 2 | { 3 | (void)(d); 4 | } 5 | 6 | #define NULL (void*)0 7 | 8 | void operators_equals() 9 | { 10 | int a, b, c, d; 11 | a = b = c = d = 42; 12 | 13 | int q1 = 42; 14 | unsigned q2 = 42; 15 | long q3 = 42; 16 | long long q4 = 42; 17 | short q5 = 42; 18 | 19 | int w1 = (long long)(42); 20 | unsigned w2 = (long long)(42); 21 | long w3 = (long long)(42); 22 | long long w4 = (long long)(42); 23 | short w5 = (long long)(42); 24 | 25 | // zero value 26 | int s1 = 0; 27 | unsigned s2 = 0; 28 | long s3 = 0; 29 | long long s4 = 0; 30 | short s5 = 0; 31 | 32 | double d1 = 0; 33 | float d2 = 0; 34 | 35 | double v1 = 0.0; 36 | float v2 = 0.0; 37 | 38 | int x1 = (0); 39 | unsigned x2 = (0); 40 | long x3 = (0); 41 | long long x4 = (0); 42 | short x5 = (0); 43 | 44 | double z1 = (0); 45 | float z2 = (0); 46 | 47 | double t1 = (0.0); 48 | float t2 = (0.0); 49 | 50 | int* r1 = NULL; 51 | int** r2 = NULL; 52 | int*** r3 = NULL; 53 | int**** r4 = NULL; 54 | int***** r5 = NULL; 55 | int****** r6 = NULL; 56 | 57 | // function 58 | f(42); 59 | 60 | // array 61 | float arr[500]; 62 | 63 | // simplificator 64 | char* ss = "words"; 65 | int cc = (unsigned char)*ss++; 66 | } 67 | -------------------------------------------------------------------------------- /tests/code_quality/paren.c: -------------------------------------------------------------------------------- 1 | void function() 2 | { 3 | int t; 4 | t = ((((int)((0))))); 5 | int a; 6 | a = (((((t))))); 7 | (void)(t); 8 | (void)(((((a))))); 9 | 10 | (((function()))); 11 | } 12 | -------------------------------------------------------------------------------- /tests/code_quality/paren.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | // function - transpiled function from C4GO/tests/code_quality/paren.c:1 11 | func function() { 12 | var t int32 13 | t = 0 14 | var a int32 15 | a = t 16 | _ = t 17 | _ = a 18 | (function()) 19 | } 20 | -------------------------------------------------------------------------------- /tests/code_quality/return.c: -------------------------------------------------------------------------------- 1 | void a() 2 | { 3 | return; 4 | } 5 | 6 | void r(int y) 7 | { 8 | (void)(y); 9 | return; 10 | } 11 | 12 | int b() 13 | { 14 | return 0; 15 | } 16 | 17 | float c() 18 | { 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tests/code_quality/return.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | // a - transpiled function from C4GO/tests/code_quality/return.c:1 11 | func a() { 12 | } 13 | 14 | // r - transpiled function from C4GO/tests/code_quality/return.c:6 15 | func r(y int32) { 16 | _ = y 17 | } 18 | 19 | // b - transpiled function from C4GO/tests/code_quality/return.c:12 20 | func b() int32 { 21 | return 0 22 | } 23 | 24 | // c - transpiled function from C4GO/tests/code_quality/return.c:17 25 | func c() float32 { 26 | return 0 27 | } 28 | -------------------------------------------------------------------------------- /tests/code_quality/stdio.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print() 4 | { 5 | printf("Hello"); 6 | printf("Hello, %d", 42); 7 | } 8 | -------------------------------------------------------------------------------- /tests/code_quality/stdio.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | import "github.com/Konstantin8105/c4go/noarch" 11 | import "fmt" 12 | 13 | // print_ - transpiled function from C4GO/tests/code_quality/stdio.c:3 14 | func print_() { 15 | fmt.Printf("Hello") 16 | noarch.Printf([]byte("Hello, %d\x00"), 42) 17 | } 18 | -------------------------------------------------------------------------------- /tests/code_quality/switch.c: -------------------------------------------------------------------------------- 1 | void switch_function() 2 | { 3 | int i = 34; 4 | switch (i) { 5 | case (0): 6 | case (1): 7 | return; 8 | case (2): 9 | (void)(i); 10 | return; 11 | case 3: { 12 | int c; 13 | return; 14 | } 15 | case 4: 16 | break; 17 | case 5: { 18 | break; 19 | } 20 | case 6: { 21 | } 22 | case 7: { 23 | int d; 24 | break; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/code_quality/switch.go.expected: -------------------------------------------------------------------------------- 1 | // 2 | // Package - transpiled by c4go 3 | // 4 | // If you have found any issues, please raise an issue at: 5 | // https://github.com/Konstantin8105/c4go/ 6 | // 7 | 8 | package code_quality 9 | 10 | // switch_function - transpiled function from C4GO/tests/code_quality/switch.c:1 11 | func switch_function() { 12 | var i int32 = 34 13 | switch i { 14 | case (0): 15 | fallthrough 16 | case (1): 17 | return 18 | case (2): 19 | _ = i 20 | return 21 | case 3: 22 | var c int32 23 | return 24 | case 4: 25 | case 5: 26 | case 6: 27 | fallthrough 28 | case 7: 29 | var d int32 30 | break 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/code_quality/ternary.c: -------------------------------------------------------------------------------- 1 | #define MaxMinTest(type) \ 2 | { \ 3 | diag(#type); \ 4 | type a = 54; \ 5 | type b = -4; \ 6 | type c; \ 7 | c = a > b ? a : b ;\ 8 | c = a < b ? a : b; \ 9 | c = b < a ? a : b ;\ 10 | c = b > a ? a : b; \ 11 | \ 12 | c = a > b ? a : b + 1 ;\ 13 | c = a < b ? a + 1 : b; \ 14 | c = b < a ? a : b + 1 ;\ 15 | c = b > a ? a + 1 : b; \ 16 | } 17 | 18 | void test_min_max() 19 | { 20 | MaxMinTest(char); 21 | MaxMinTest(short); 22 | MaxMinTest(int); 23 | MaxMinTest(float); 24 | MaxMinTest(double); 25 | MaxMinTest(long double); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /tests/code_quality/unsafe.c: -------------------------------------------------------------------------------- 1 | #define unsafetype(type, name) \ 2 | void name() \ 3 | { \ 4 | type t; \ 5 | type* pt = &t; \ 6 | (void)(t); \ 7 | (void)(pt); \ 8 | } 9 | 10 | struct str { 11 | int i; 12 | }; 13 | 14 | union un { 15 | int i; 16 | double d; 17 | }; 18 | 19 | typedef double db; 20 | 21 | // integers 22 | unsafetype(char, test_char); 23 | unsafetype(short, test_short); 24 | unsafetype(int, test_int); 25 | unsafetype(long, test_long); 26 | unsafetype(long int, test_li); 27 | unsafetype(long long, test_ll); 28 | unsafetype(long long int, test_lli); 29 | 30 | // floats 31 | unsafetype(float, test_f); 32 | unsafetype(double, test_d); 33 | unsafetype(long double, test_ld); 34 | 35 | // struct 36 | unsafetype(struct str, test_struct); 37 | 38 | // union 39 | unsafetype(union un, test_un); 40 | 41 | // typedef 42 | unsafetype(db, test_typedef); 43 | -------------------------------------------------------------------------------- /tests/comment/main.c: -------------------------------------------------------------------------------- 1 | // comment1 2 | 3 | /* comment2 */ 4 | 5 | /* 6 | * comment3 7 | */ 8 | 9 | void /* comment4 */ a /* comment5 */( /* comment6 */ int /* comment7 */ i /*comment8*/) // comment9 10 | { 11 | // comment10 12 | // comment11 13 | (/* comment12 */ void /* comment13 */)/*comment14*/(/*comment15*/ i /*comment16 */)/*comment17*/; 14 | } 15 | // comment18 16 | //comment19 17 | 18 | void b //comment20 19 | ( // comment21 20 | )//comment22 21 | { //comment23 22 | //comment24 23 | int i = 9; 24 | (void)(i); 25 | }//comment25 26 | 27 | 28 | int /* comment26 */ main () 29 | { 30 | int i = 0; 31 | for ( i = 0 ; i < 5 ; i++) 32 | { 33 | if (i > 2) 34 | {/*comment27*/ 35 | a(i); 36 | } else { 37 | /* 38 | * * * // comment28 39 | */ 40 | b(); 41 | } 42 | } 43 | return 0; 44 | } 45 | /* 46 | * comment29 47 | * 48 | * 49 | * 50 | */ 51 | // comment30 52 | 53 | -------------------------------------------------------------------------------- /tests/do.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | int main() 5 | { 6 | plan(7); 7 | 8 | int i = 0; 9 | 10 | // There will be 4 checks in the first loop. 11 | do { 12 | pass("%s", "first do statement"); 13 | i = i + 1; 14 | } while (i < 4); 15 | 16 | // Only one check in the second loop. 17 | i = 0; 18 | do { 19 | i++; 20 | if (i < 3) 21 | continue; 22 | pass("%s", "second do statement"); 23 | } while (i < 3); 24 | 25 | diag("check while"); 26 | i = 1000; 27 | do { 28 | i--; 29 | if (i < 10) { 30 | break; 31 | } 32 | } while ((i /= 10) > 0); 33 | is_eq(i, 8); 34 | 35 | diag("do without CompoundStmt"); 36 | int s = 1; 37 | do 38 | s++; 39 | while (s < 10); 40 | is_eq(s, 10); 41 | 42 | done_testing(); 43 | } 44 | -------------------------------------------------------------------------------- /tests/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/empty.txt -------------------------------------------------------------------------------- /tests/errno.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | plan(1); 9 | 10 | if (__errno_location() == NULL) { 11 | fail("not ok"); 12 | } else { 13 | pass("ok"); 14 | } 15 | 16 | done_testing(); 17 | } 18 | -------------------------------------------------------------------------------- /tests/exit.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | int main() 5 | { 6 | plan(0); 7 | 8 | exit(123); 9 | 10 | // done_testing() is not needed because this is unreachable. 11 | } 12 | -------------------------------------------------------------------------------- /tests/exit_status.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | int main() 5 | { 6 | plan(0); 7 | 8 | // There is no done_testing() becuase we want to return an error code without 9 | // checks that fail. 10 | return 1; 11 | } 12 | -------------------------------------------------------------------------------- /tests/externalHeader/include/head.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Checking case with header on another folder then main function 4 | void print(){ 5 | // tests that functions can be declared in the header. 6 | printf("42\n"); 7 | } 8 | -------------------------------------------------------------------------------- /tests/externalHeader/main/main.c: -------------------------------------------------------------------------------- 1 | #include "head.h" 2 | 3 | // Checking case with header on another folder then main function 4 | int main(){ 5 | print(); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/getchar.c: -------------------------------------------------------------------------------- 1 | // getchar() needs to be in it's own file because it takes input from stdin. 2 | 3 | #include "tests.h" 4 | #include 5 | 6 | int main() 7 | { 8 | plan(1); 9 | 10 | int c; 11 | c = getchar(); 12 | is_eq(c, '7'); 13 | 14 | done_testing(); 15 | } 16 | -------------------------------------------------------------------------------- /tests/goto.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "tests.h" 5 | 6 | #define START_TEST(t) \ 7 | diag(#t); \ 8 | test_##t(); 9 | 10 | void test_goto1() 11 | { 12 | int i = 0; 13 | 14 | mylabel: 15 | i++; 16 | 17 | if (i > 5) { 18 | fail("Parameter i = %d, but expect 1", i); 19 | return; 20 | } 21 | 22 | if (i == 1) { 23 | goto mylabel; 24 | } 25 | 26 | is_eq(i, 2); 27 | } 28 | 29 | void test_goto2() 30 | { 31 | int i = 0; 32 | int j = 0; 33 | 34 | mylabel: 35 | i++, j++; 36 | 37 | if (j > 5) { 38 | fail("Parameter j = %d, but expect 1", j); 39 | return; 40 | } 41 | if (i == 1) { 42 | goto mylabel; 43 | } 44 | 45 | is_eq(i, 2); 46 | is_eq(j, 2); 47 | } 48 | 49 | void test_goto_stmt() 50 | { 51 | int i = 0, j = 0; 52 | 53 | mylabel: 54 | for (j = 0; j < 5; j++) 55 | i++; 56 | 57 | if (i < 15) { 58 | goto mylabel; 59 | } 60 | 61 | is_eq(i, 15); 62 | } 63 | 64 | int main() 65 | { 66 | plan(4); 67 | 68 | START_TEST(goto1) 69 | START_TEST(goto2) 70 | START_TEST(goto_stmt) 71 | 72 | done_testing(); 73 | } 74 | -------------------------------------------------------------------------------- /tests/ioctl.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | plan(0); 11 | 12 | //------- 13 | struct winsize sz; 14 | printf("Call:%d\n", TIOCGWINSZ); 15 | (void)sz; 16 | int res = ioctl(STDIN_FILENO, TIOCGWINSZ, &sz); 17 | printf("Res :%d\n", res); 18 | if (res > 0) { 19 | printf("Desr:%d\n", STDIN_FILENO); 20 | is_true(sz.ws_col > 0); 21 | is_true(sz.ws_row > 0); 22 | printf("%5d %5d\n", sz.ws_col, sz.ws_row); 23 | fail("Not acceptable"); 24 | } 25 | //------- 26 | 27 | done_testing(); 28 | } 29 | -------------------------------------------------------------------------------- /tests/locale.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | int main() 5 | { 6 | plan(0);// 2); 7 | // TODO: commented for github action 8 | 9 | // setlocale(LC_MONETARY, ""); 10 | // struct lconv* lc; 11 | // lc = localeconv(); 12 | // // Local Currency Symbol 13 | // is_true(strlen(lc->currency_symbol) > 0); 14 | // // International Currency Symbol 15 | // is_true(strlen(lc->int_curr_symbol) > 0); 16 | 17 | done_testing(); 18 | } 19 | -------------------------------------------------------------------------------- /tests/memory.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | void test_struct_pointer() 5 | { 6 | typedef struct row { 7 | double* t; 8 | } row; 9 | row r; 10 | unsigned poi = r.t; 11 | is_true(poi >= 0); 12 | (void)(r); 13 | } 14 | 15 | int main() 16 | { 17 | plan(1); 18 | 19 | test_struct_pointer(); 20 | 21 | done_testing(); 22 | } 23 | -------------------------------------------------------------------------------- /tests/multi/err.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void ERROR_FUNC(){ 4 | printf("ERROR!"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/multi/header.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // This header file is included by multiple C files. Make sure the preprocessor 4 | // is working correctly by not declaring duplicates. 5 | #ifndef HEADER 6 | #define HEADER 7 | 8 | // Headers usually do not contain whole functions, but we want to make sure this 9 | // is still OK to do. 10 | void say_four() { 11 | printf("4"); 12 | } 13 | 14 | // Forward-declared prototypes that are defined in one of our other C files. 15 | void say_two(); // main1.c 16 | void say_three(); // main2.c 17 | 18 | #endif /* HEADER */ 19 | -------------------------------------------------------------------------------- /tests/multi/main1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "header.h" 3 | 4 | #define ERROR_FUNC error 5 | #include "err.h" 6 | #undef ERROR_FUNC 7 | #define ERROR_FUNC errorANOTHER 8 | #include "err.h" 9 | 10 | int main() { 11 | say_two(); 12 | say_three(); 13 | say_four(); 14 | 15 | ERROR_FUNC(); 16 | error(); 17 | errorANOTHER(); 18 | printf("\n"); 19 | return 0; 20 | } 21 | 22 | // The body for the definition (declared in the header). Notice this is declared 23 | // after using the forward declaration above. 24 | void say_two() { 25 | printf("2"); 26 | } 27 | -------------------------------------------------------------------------------- /tests/multi/main2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "header.h" 3 | 4 | void say_three() { 5 | printf("3"); 6 | } 7 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/.mailmap: -------------------------------------------------------------------------------- 1 | Camilla Löwy 2 | Camilla Löwy 3 | Camilla Löwy 4 | 5 | Emmanuel Gil Peyrot 6 | 7 | Marcus Geelnard 8 | Marcus Geelnard 9 | Marcus Geelnard 10 | 11 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | if (NOT EXISTS "@GLFW_BINARY_DIR@/install_manifest.txt") 3 | message(FATAL_ERROR "Cannot find install manifest: \"@GLFW_BINARY_DIR@/install_manifest.txt\"") 4 | endif() 5 | 6 | file(READ "@GLFW_BINARY_DIR@/install_manifest.txt" files) 7 | string(REGEX REPLACE "\n" ";" files "${files}") 8 | 9 | foreach (file ${files}) 10 | message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 11 | if (EXISTS "$ENV{DESTDIR}${file}") 12 | exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 13 | OUTPUT_VARIABLE rm_out 14 | RETURN_VALUE rm_retval) 15 | if (NOT "${rm_retval}" STREQUAL 0) 16 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 17 | endif() 18 | elseif (IS_SYMLINK "$ENV{DESTDIR}${file}") 19 | EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 20 | OUTPUT_VARIABLE rm_out 21 | RETURN_VALUE rm_retval) 22 | if (NOT "${rm_retval}" STREQUAL 0) 23 | message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"") 24 | endif() 25 | else() 26 | message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 27 | endif() 28 | endforeach() 29 | 30 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/glfw3.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 4 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 5 | 6 | Name: GLFW 7 | Description: A multi-platform library for OpenGL, window and input 8 | Version: @GLFW_VERSION@ 9 | URL: https://www.glfw.org/ 10 | Requires.private: @GLFW_PKG_CONFIG_REQUIRES_PRIVATE@ 11 | Libs: -L${libdir} -l@GLFW_LIB_NAME@ 12 | Libs.private: @GLFW_PKG_CONFIG_LIBS_PRIVATE@ 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/glfw3Config.cmake.in: -------------------------------------------------------------------------------- 1 | include(CMakeFindDependencyMacro) 2 | find_dependency(Threads) 3 | include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake") 4 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/i686-w64-mingw32-clang.cmake: -------------------------------------------------------------------------------- 1 | # Define the environment for cross-compiling with 32-bit MinGW-w64 Clang 2 | SET(CMAKE_SYSTEM_NAME Windows) # Target system name 3 | SET(CMAKE_SYSTEM_VERSION 1) 4 | SET(CMAKE_C_COMPILER "i686-w64-mingw32-clang") 5 | SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-clang++") 6 | SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres") 7 | SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib") 8 | 9 | # Configure the behaviour of the find commands 10 | SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32") 11 | SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 12 | SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 13 | SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 14 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/i686-w64-mingw32.cmake: -------------------------------------------------------------------------------- 1 | # Define the environment for cross-compiling with 32-bit MinGW-w64 GCC 2 | SET(CMAKE_SYSTEM_NAME Windows) # Target system name 3 | SET(CMAKE_SYSTEM_VERSION 1) 4 | SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc") 5 | SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++") 6 | SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres") 7 | SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib") 8 | 9 | # Configure the behaviour of the find commands 10 | SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32") 11 | SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 12 | SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 13 | SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 14 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/modules/FindEpollShim.cmake: -------------------------------------------------------------------------------- 1 | # Find EpollShim 2 | # Once done, this will define 3 | # 4 | # EPOLLSHIM_FOUND - System has EpollShim 5 | # EPOLLSHIM_INCLUDE_DIRS - The EpollShim include directories 6 | # EPOLLSHIM_LIBRARIES - The libraries needed to use EpollShim 7 | 8 | find_path(EPOLLSHIM_INCLUDE_DIRS NAMES sys/epoll.h sys/timerfd.h HINTS /usr/local/include/libepoll-shim) 9 | find_library(EPOLLSHIM_LIBRARIES NAMES epoll-shim libepoll-shim HINTS /usr/local/lib) 10 | 11 | if (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES) 12 | set(EPOLLSHIM_FOUND TRUE) 13 | endif (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES) 14 | 15 | include(FindPackageHandleStandardArgs) 16 | find_package_handle_standard_args(EpollShim DEFAULT_MSG EPOLLSHIM_LIBRARIES EPOLLSHIM_INCLUDE_DIRS) 17 | mark_as_advanced(EPOLLSHIM_INCLUDE_DIRS EPOLLSHIM_LIBRARIES) 18 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/modules/FindOSMesa.cmake: -------------------------------------------------------------------------------- 1 | # Try to find OSMesa on a Unix system 2 | # 3 | # This will define: 4 | # 5 | # OSMESA_LIBRARIES - Link these to use OSMesa 6 | # OSMESA_INCLUDE_DIR - Include directory for OSMesa 7 | # 8 | # Copyright (c) 2014 Brandon Schaefer 9 | 10 | if (NOT WIN32) 11 | 12 | find_package (PkgConfig) 13 | pkg_check_modules (PKG_OSMESA QUIET osmesa) 14 | 15 | set (OSMESA_INCLUDE_DIR ${PKG_OSMESA_INCLUDE_DIRS}) 16 | set (OSMESA_LIBRARIES ${PKG_OSMESA_LIBRARIES}) 17 | 18 | endif () 19 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/x86_64-w64-mingw32-clang.cmake: -------------------------------------------------------------------------------- 1 | # Define the environment for cross-compiling with 64-bit MinGW-w64 Clang 2 | SET(CMAKE_SYSTEM_NAME Windows) # Target system name 3 | SET(CMAKE_SYSTEM_VERSION 1) 4 | SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-clang") 5 | SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-clang++") 6 | SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres") 7 | SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib") 8 | 9 | # Configure the behaviour of the find commands 10 | SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32") 11 | SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 12 | SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 13 | SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 14 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/CMake/x86_64-w64-mingw32.cmake: -------------------------------------------------------------------------------- 1 | # Define the environment for cross-compiling with 64-bit MinGW-w64 GCC 2 | SET(CMAKE_SYSTEM_NAME Windows) # Target system name 3 | SET(CMAKE_SYSTEM_VERSION 1) 4 | SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc") 5 | SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++") 6 | SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres") 7 | SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib") 8 | 9 | # Configure the behaviour of the find commands 10 | SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32") 11 | SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 12 | SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 13 | SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 14 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2002-2006 Marcus Geelnard 2 | 3 | Copyright (c) 2006-2019 Camilla Löwy 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would 16 | be appreciated but is not required. 17 | 18 | 2. Altered source versions must be plainly marked as such, and must not 19 | be misrepresented as being the original software. 20 | 21 | 3. This notice may not be removed or altered from any source 22 | distribution. 23 | 24 | -------------------------------------------------------------------------------- /tests/raylib/external/glfw/src/glfw.rc.in: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0 6 | PRODUCTVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE 0 12 | { 13 | BLOCK "StringFileInfo" 14 | { 15 | BLOCK "040904B0" 16 | { 17 | VALUE "CompanyName", "GLFW" 18 | VALUE "FileDescription", "GLFW @GLFW_VERSION@ DLL" 19 | VALUE "FileVersion", "@GLFW_VERSION@" 20 | VALUE "OriginalFilename", "glfw3.dll" 21 | VALUE "ProductName", "GLFW" 22 | VALUE "ProductVersion", "@GLFW_VERSION@" 23 | } 24 | } 25 | BLOCK "VarFileInfo" 26 | { 27 | VALUE "Translation", 0x409, 1200 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /tests/raylib/raylib.dll.rc: -------------------------------------------------------------------------------- 1 | GLFW_ICON ICON "raylib.ico" 2 | 3 | 1 VERSIONINFO 4 | FILEVERSION 4,2,0,0 5 | PRODUCTVERSION 4,2,0,0 6 | BEGIN 7 | BLOCK "StringFileInfo" 8 | BEGIN 9 | //BLOCK "080904E4" // English UK 10 | BLOCK "040904E4" // English US 11 | BEGIN 12 | //VALUE "CompanyName", "raylib technologies" 13 | VALUE "FileDescription", "raylib dynamic library (www.raylib.com)" 14 | VALUE "FileVersion", "4.2.0" 15 | VALUE "InternalName", "raylib.dll" 16 | VALUE "LegalCopyright", "(c) 2022 Ramon Santamaria (@raysan5)" 17 | VALUE "OriginalFilename", "raylib.dll" 18 | VALUE "ProductName", "raylib" 19 | VALUE "ProductVersion", "4.2.0" 20 | END 21 | END 22 | BLOCK "VarFileInfo" 23 | BEGIN 24 | //VALUE "Translation", 0x809, 1252 // English UK 25 | VALUE "Translation", 0x409, 1252 // English US 26 | END 27 | END 28 | -------------------------------------------------------------------------------- /tests/raylib/raylib.dll.rc.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/raylib/raylib.dll.rc.data -------------------------------------------------------------------------------- /tests/raylib/raylib.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/raylib/raylib.ico -------------------------------------------------------------------------------- /tests/raylib/raylib.rc: -------------------------------------------------------------------------------- 1 | GLFW_ICON ICON "raylib.ico" 2 | 3 | 1 VERSIONINFO 4 | FILEVERSION 4,2,0,0 5 | PRODUCTVERSION 4,2,0,0 6 | BEGIN 7 | BLOCK "StringFileInfo" 8 | BEGIN 9 | //BLOCK "080904E4" // English UK 10 | BLOCK "040904E4" // English US 11 | BEGIN 12 | //VALUE "CompanyName", "raylib technologies" 13 | VALUE "FileDescription", "raylib application (www.raylib.com)" 14 | VALUE "FileVersion", "4.2.0" 15 | VALUE "InternalName", "raylib app" 16 | VALUE "LegalCopyright", "(c) 2022 Ramon Santamaria (@raysan5)" 17 | //VALUE "OriginalFilename", "raylib_app.exe" 18 | VALUE "ProductName", "raylib app" 19 | VALUE "ProductVersion", "4.2.0" 20 | END 21 | END 22 | BLOCK "VarFileInfo" 23 | BEGIN 24 | //VALUE "Translation", 0x809, 1252 // English UK 25 | VALUE "Translation", 0x409, 1252 // English US 26 | END 27 | END 28 | -------------------------------------------------------------------------------- /tests/raylib/raylib.rc.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/raylib/raylib.rc.data -------------------------------------------------------------------------------- /tests/scanf.c: -------------------------------------------------------------------------------- 1 | // scanf() needs to be in it's own file because it takes input from stdin. 2 | 3 | #include "tests.h" 4 | #include 5 | 6 | int main() 7 | { 8 | plan(1); 9 | 10 | int i; 11 | scanf("%d", &i); 12 | is_eq(i, 7); 13 | 14 | done_testing(); 15 | } 16 | -------------------------------------------------------------------------------- /tests/signal.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include /* signal, raise, sig_atomic_t */ 3 | #include /* printf */ 4 | 5 | sig_atomic_t signaled = 0; 6 | 7 | void my_handler(int param) 8 | { 9 | signaled = 1; 10 | } 11 | 12 | int main() 13 | { 14 | plan(0); 15 | 16 | signal(SIGINT, my_handler); 17 | raise(SIGINT); 18 | printf("signaled is %d.\n", signaled); 19 | 20 | done_testing(); 21 | } 22 | -------------------------------------------------------------------------------- /tests/stdio.txt: -------------------------------------------------------------------------------- 1 | Test file for testing 2 | -------------------------------------------------------------------------------- /tests/stdio_fscan.txt: -------------------------------------------------------------------------------- 1 | 2 | #-----------# 3 | # Example 1 # 4 | #-----------# 5 | 6 | #========= | POINTS | =========# 7 | 9 # number of points 8 | -------------------------------------------------------------------------------- /tests/stdio_gets.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | int main() 5 | { 6 | plan(1); 7 | // check function `gets` only 8 | char str[50]; 9 | int i; 10 | for (i = 0; i < 50; i++) 11 | str[i] = '\0'; 12 | gets(str); 13 | is_streq(str, "7"); 14 | 15 | done_testing(); 16 | } 17 | -------------------------------------------------------------------------------- /tests/stdlib_atexit.c: -------------------------------------------------------------------------------- 1 | /* atexit example */ 2 | #include "tests.h" 3 | #include 4 | #include /* atexit */ 5 | 6 | int r_value = 3; 7 | 8 | void fnExit1(void) 9 | { 10 | r_value += 2; 11 | } 12 | 13 | void fnExit2(void) 14 | { 15 | r_value *= 5; 16 | } 17 | 18 | void done(void) 19 | { 20 | printf("%d\n", r_value); 21 | } 22 | 23 | int main() 24 | { 25 | plan(0); 26 | atexit(done); 27 | atexit(fnExit1); 28 | atexit(fnExit2); 29 | done_testing(); 30 | } 31 | -------------------------------------------------------------------------------- /tests/sys_time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "tests.h" 8 | 9 | void handler(int signo) 10 | { 11 | static const char msg[] = "\n*** Timer expired, you lose ***\n"; 12 | assert(signo == SIGALRM); 13 | write(2, msg, sizeof(msg) - 1); 14 | exit(1); 15 | } 16 | 17 | int main(void) 18 | { 19 | plan(0);// 1); 20 | // TODO: commented for github action 21 | 22 | // struct itimerval tval; 23 | // char string[BUFSIZ]; 24 | 25 | // timerclear(&tval.it_interval); /* zero interval means no reset of timer */ 26 | // timerclear(&tval.it_value); 27 | 28 | // tval.it_value.tv_sec = 10; /* 10 second timeout */ 29 | 30 | // (void)signal(SIGALRM, handler); 31 | 32 | // printf("You have ten seconds to enter\nyour name, rank, and serial number: "); 33 | 34 | // (void)setitimer(ITIMER_REAL, &tval, NULL); 35 | // if (fgets(string, sizeof string, stdin) != NULL) { 36 | // (void)setitimer(ITIMER_REAL, NULL, NULL); /* turn off timer */ 37 | // /* process rest of data, diagnostic print for illustration */ 38 | // printf("I'm glad you are being cooperative.\n"); 39 | // pass("ok"); 40 | // } else 41 | // printf("\nEOF, eh? We won't give up so easily!\n"); 42 | 43 | done_testing(); 44 | } 45 | -------------------------------------------------------------------------------- /tests/termios.c: -------------------------------------------------------------------------------- 1 | // termios checking 2 | 3 | #include "tests.h" 4 | #include 5 | 6 | int main() 7 | { 8 | plan(0); 9 | 10 | struct termios t; 11 | 12 | (void)t; 13 | 14 | done_testing(); 15 | }; 16 | -------------------------------------------------------------------------------- /tests/trigraph/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(){ 3 | // Trigraph tests require the `-trigraph` clang option, so it cannot be amount other general tests. 4 | printf("??=\n"); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /tests/vendor/csparce/README.md: -------------------------------------------------------------------------------- 1 | See https://people.sc.fsu.edu/~jburkardt/c_src/csparse/ 2 | -------------------------------------------------------------------------------- /tests/vendor/csparce/kershaw.st: -------------------------------------------------------------------------------- 1 | 0 0 0.300000000000000000E+01 2 | 1 0 -0.200000000000000000E+01 3 | 3 0 0.200000000000000000E+01 4 | 0 1 -0.200000000000000000E+01 5 | 1 1 0.300000000000000000E+01 6 | 2 1 -0.200000000000000000E+01 7 | 1 2 -0.200000000000000000E+01 8 | 2 2 0.300000000000000000E+01 9 | 3 2 -0.200000000000000000E+01 10 | 0 3 0.200000000000000000E+01 11 | 2 3 -0.200000000000000000E+01 12 | 3 3 0.300000000000000000E+01 13 | -------------------------------------------------------------------------------- /tests/vendor/easymesh/README.md: -------------------------------------------------------------------------------- 1 | See http://www.ae.metu.edu.tr/~ae305/Easymesh/easymesh.c 2 | -------------------------------------------------------------------------------- /tests/vendor/easymesh/anima2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/anima2.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/easymesh.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/easymesh.c -------------------------------------------------------------------------------- /tests/vendor/easymesh/example1.d: -------------------------------------------------------------------------------- 1 | #-----------# 2 | # Example 1 # 3 | #-----------# 4 | 5 | #========= 6 | | POINTS | 7 | =========# 8 | 9 # number of points # 9 | 10 | # Nodes which define the boundary # 11 | 0: 0.0 0.0 0.25 1 12 | 1: 5.0 0.0 0.25 2 13 | 2: 5.0 2.0 0.25 2 14 | 3: 4.0 3.0 0.25 3 15 | 4: 0.0 3.0 0.25 3 16 | 17 | # Nodes which define the hole # 18 | 5: 1.0 1.0 0.1 4 19 | 6: 1.0 2.0 0.1 4 20 | 7: 2.0 2.0 0.1 4 21 | 8: 2.0 1.0 0.1 4 22 | 23 | #=========== 24 | | SEGMENTS | 25 | ===========# 26 | 9 # Number of segments # 27 | 28 | # Boundary segments # 29 | 0: 0 1 1 30 | 1: 1 2 2 31 | 2: 2 3 2 32 | 3: 3 4 3 33 | 4: 4 0 3 34 | 35 | # Hole segments # 36 | 5: 5 6 4 37 | 6: 6 7 4 38 | 7: 7 8 4 39 | 8: 8 5 4 40 | -------------------------------------------------------------------------------- /tests/vendor/easymesh/example10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example10.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/example11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example11.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/example20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example20.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/example21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example21.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/example3.d: -------------------------------------------------------------------------------- 1 | #-----------# 2 | # Example 3 # 3 | #-----------# 4 | 5 | #********# 6 | 17 # Points # 7 | #********# 8 | 9 | 0: 0 0 0.5 1 10 | 1: 5 0 0.5 1 11 | 2: 0 1 0.1 1 12 | 3: 5 1 0.1 1 13 | 4: 1.5 1.5 0.1 4 14 | 5: 3.5 1.5 0.1 4 15 | 6: 0 2.5 0.25 1 16 | 7: 1.5 2.5 0.1 2 17 | 8: 3.5 2.5 0.1 2 18 | 9: 5 2.5 0.25 1 19 | 10: 2.5 4 0.1 2 20 | 11: 3.5 4 0.1 2 21 | 22 | # line for coarsening # 23 | 12: 2.5 2 0.4 0 24 | 13: 3 3.5 0.4 0 25 | 26 | # material markers # 27 | 14: 3 3 0 1 # material 1 (red) # 28 | 15: 3 1.25 0 2 # material 2 (blue) # 29 | 16: 3 0.5 0 3 # material 3 (green) # 30 | 31 | #**********# 32 | 15 # Segments # 33 | #**********# 34 | 35 | # domain contour # 36 | 0: 0 1 1 37 | 1: 1 3 1 38 | 2: 3 9 1 39 | 3: 9 8 1 40 | 4: 8 11 2 41 | 5: 11 10 2 42 | 6: 10 7 2 43 | 7: 7 6 1 44 | 8: 6 2 1 45 | 9: 2 0 1 46 | 47 | # frontier between green and blue # 48 | 10: 3 2 3 49 | 50 | # frontier between blue and red# 51 | 11: 8 5 4 52 | 12: 5 4 4 53 | 13: 4 7 4 54 | 14: 12 13 0 55 | -------------------------------------------------------------------------------- /tests/vendor/easymesh/example30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example30.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/example31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example31.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/example32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/example32.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/output1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/output1.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/output2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/output2.gif -------------------------------------------------------------------------------- /tests/vendor/easymesh/showmesh.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Konstantin8105/c4go/5bf367b9678adff0c634b0d6daddc58a1c7eb7c3/tests/vendor/easymesh/showmesh.c -------------------------------------------------------------------------------- /tests/wchar.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include 3 | 4 | int main() 5 | { 6 | plan(5); 7 | 8 | { 9 | diag("wcscmp"); 10 | wchar_t wsKey[] = L"jilia"; 11 | if (wcscmp(wsKey, L"jilia") == 0) { 12 | pass("0k - equal"); 13 | } 14 | if (wcscmp(wsKey, L"jiiia") != 0) { 15 | pass("0k - not equal"); 16 | } 17 | } 18 | 19 | { 20 | diag("wcscpy"); 21 | wchar_t wcs1[] = L"Sample string"; 22 | wchar_t wcs2[40]; 23 | wchar_t wcs3[40]; 24 | wcscpy(wcs2, wcs1); 25 | wcscpy(wcs3, L"copy successful"); 26 | is_wchareq(wcs1, L"Sample string"); 27 | is_wchareq(wcs2, L"Sample string"); 28 | is_wchareq(wcs3, L"copy successful"); 29 | } 30 | 31 | done_testing(); 32 | } 33 | -------------------------------------------------------------------------------- /transpiler/goto.go: -------------------------------------------------------------------------------- 1 | // This file contains functions for transpiling goto/label statements. 2 | 3 | package transpiler 4 | 5 | import ( 6 | goast "go/ast" 7 | "go/token" 8 | 9 | "github.com/Konstantin8105/c4go/ast" 10 | "github.com/Konstantin8105/c4go/program" 11 | "github.com/Konstantin8105/c4go/util" 12 | ) 13 | 14 | func transpileLabelStmt(n *ast.LabelStmt, p *program.Program) (*goast.LabeledStmt, []goast.Stmt, []goast.Stmt, error) { 15 | 16 | var post []goast.Stmt 17 | for _, node := range n.Children() { 18 | var stmt goast.Stmt 19 | stmt, preStmts, postStmts, err := transpileToStmt(node, p) 20 | if err != nil { 21 | return nil, nil, nil, err 22 | } 23 | post = combineStmts(preStmts, stmt, postStmts) 24 | } 25 | 26 | return &goast.LabeledStmt{ 27 | Label: util.NewIdent(n.Name), 28 | Stmt: &goast.EmptyStmt{}, 29 | }, []goast.Stmt{}, post, nil 30 | } 31 | 32 | func transpileGotoStmt(n *ast.GotoStmt, p *program.Program) (*goast.BranchStmt, error) { 33 | return &goast.BranchStmt{ 34 | Label: util.NewIdent(n.Name), 35 | Tok: token.GOTO, 36 | }, nil 37 | } 38 | -------------------------------------------------------------------------------- /transpiler/translation_unit.go: -------------------------------------------------------------------------------- 1 | package transpiler 2 | 3 | import ( 4 | goast "go/ast" 5 | 6 | "github.com/Konstantin8105/c4go/ast" 7 | "github.com/Konstantin8105/c4go/program" 8 | errorTree "github.com/Konstantin8105/errors" 9 | ) 10 | 11 | func transpileTranslationUnitDecl(p *program.Program, n *ast.TranslationUnitDecl) ( 12 | decls []goast.Decl, err error) { 13 | 14 | childs := n.Children() 15 | et := errorTree.New("transpileTranslationUnitDecl") 16 | for i := range childs { 17 | ds, err := transpileToNode(childs[i], p) 18 | if err != nil { 19 | et.Add(err) 20 | continue 21 | } 22 | decls = append(decls, ds...) 23 | } 24 | if et.IsError() { 25 | err = et 26 | } 27 | 28 | return 29 | } 30 | -------------------------------------------------------------------------------- /types/binary_operator.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/Konstantin8105/c4go/program" 5 | ) 6 | 7 | // ResolveTypeForBinaryOperator determines the result Go type when performing a 8 | // binary expression. 9 | func ResolveTypeForBinaryOperator(p *program.Program, operator, leftType, rightType string) string { 10 | if operator == "==" || 11 | operator == "!=" || 12 | operator == ">" || 13 | operator == ">=" || 14 | operator == "<" || 15 | operator == "<=" { 16 | return "bool" 17 | } 18 | 19 | return leftType 20 | } 21 | -------------------------------------------------------------------------------- /types/dereference_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGetDereferenceType(t *testing.T) { 9 | type args struct { 10 | cType string 11 | } 12 | tests := []struct { 13 | args args 14 | want string 15 | wantErr bool 16 | }{ 17 | {args{"char [8]"}, "char", false}, 18 | {args{"char**"}, "char*", false}, 19 | {args{"char *[8]"}, "char *", false}, 20 | {args{"char *[8][7]"}, "char *[7]", false}, 21 | {args{"char *[8][7][6]"}, "char *[7][6]", false}, 22 | {args{"char **[8]"}, "char **", false}, 23 | {args{"char ***[8]"}, "char ***", false}, 24 | } 25 | for _, tt := range tests { 26 | name := fmt.Sprintf("%#v", tt.args) 27 | 28 | t.Run(name, func(t *testing.T) { 29 | got, err := GetDereferenceType(tt.args.cType) 30 | if (err != nil) != tt.wantErr { 31 | t.Errorf("GetDereferenceType() error = %v, wantErr %v", err, tt.wantErr) 32 | return 33 | } 34 | if got != tt.want { 35 | t.Errorf("GetDereferenceType() = %v, want %v", got, tt.want) 36 | } 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /types/sizeof_test.go: -------------------------------------------------------------------------------- 1 | package types_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/Konstantin8105/c4go/program" 7 | "github.com/Konstantin8105/c4go/types" 8 | ) 9 | 10 | type sizeofTestCase struct { 11 | cType string 12 | size int 13 | isError bool 14 | } 15 | 16 | var sizeofTestCases = []sizeofTestCase{ 17 | {"int", 4, true}, 18 | {"int [2]", 4 * 2, true}, 19 | {"int [2][3]", 4 * 2 * 3, true}, 20 | {"int [2][3][4]", 4 * 2 * 3 * 4, true}, 21 | {"int *[2]", 8 * 2, true}, 22 | {"int *[2][3]", 8 * 2 * 3, true}, 23 | {"int *[2][3][4]", 8 * 2 * 3 * 4, true}, 24 | {"int *", 8, true}, 25 | {"int **", 8, true}, 26 | {"int ***", 8, true}, 27 | {"char *const", 8, true}, 28 | {"char *const [3]", 24, true}, 29 | {"struct c [2]", 0, true}, 30 | } 31 | 32 | func TestSizeOf(t *testing.T) { 33 | p := program.NewProgram() 34 | 35 | for _, testCase := range sizeofTestCases { 36 | t.Run(testCase.cType, func(t *testing.T) { 37 | size, err := types.SizeOf(p, testCase.cType) 38 | if !((err != nil && testCase.isError == false) || 39 | (err == nil && testCase.isError == true)) { 40 | t.Fatal(err) 41 | } 42 | 43 | if size != testCase.size { 44 | t.Errorf("Expected '%s' -> '%d', got '%d'", 45 | testCase.cType, testCase.size, size) 46 | } 47 | }) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /util/diff.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | // ShowDiff will print two strings vertically next to each other so that line 11 | // differences are easier to read. 12 | func ShowDiff(a, b string) string { 13 | aLines := strings.Split(a, "\n") 14 | bLines := strings.Split(b, "\n") 15 | maxLines := int(math.Max(float64(len(aLines)), float64(len(bLines)))) 16 | out := "\n" 17 | 18 | for lineNumber := 0; lineNumber < maxLines; lineNumber++ { 19 | aLine := "" 20 | bLine := "" 21 | 22 | // Replace NULL characters with a dot. Otherwise the strings will look 23 | // exactly the same but have different length (and therefore not be 24 | // equal). 25 | if lineNumber < len(aLines) { 26 | aLine = strconv.Quote(aLines[lineNumber]) 27 | } 28 | if lineNumber < len(bLines) { 29 | bLine = strconv.Quote(bLines[lineNumber]) 30 | } 31 | 32 | diffFlag := " " 33 | if aLine != bLine { 34 | diffFlag = "*" 35 | } 36 | out += fmt.Sprintf("%s %3d %-40s%s\n", diffFlag, lineNumber+1, aLine, bLine) 37 | 38 | if lineNumber > len(aLines) || lineNumber > len(bLines) { 39 | out += "and more other ..." 40 | break 41 | } 42 | } 43 | 44 | return out 45 | } 46 | -------------------------------------------------------------------------------- /util/diff_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestDiff(t *testing.T) { 10 | tcs := []struct { 11 | a string 12 | b string 13 | 14 | expect string 15 | }{ 16 | { 17 | a: "a", 18 | b: "b", 19 | expect: "* 1 \"a\" \"b\"", 20 | }, 21 | { 22 | a: "a", 23 | b: "a", 24 | expect: "1 \"a\" \"a\"", 25 | }, 26 | } 27 | 28 | for i, tc := range tcs { 29 | t.Run(fmt.Sprintf("Test %d : %s", i, tc.a+tc.b), func(t *testing.T) { 30 | act := ShowDiff(tc.a, tc.b) 31 | if strings.TrimSpace(act) != strings.TrimSpace(tc.expect) { 32 | t.Errorf("Not correct result.\nExpected:%s\nActual:%s\n", 33 | tc.expect, act) 34 | t.Errorf("Length\nExpected:%d\nActual:%d\n", 35 | len(tc.expect), len(act)) 36 | } 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /util/errors.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "fmt" 4 | 5 | // PanicIfNil will panic with the message provided if the check is nil. This is 6 | // a convenience method to avoid many similar if statements. 7 | func PanicIfNil(check interface{}, message string) { 8 | if check == nil { 9 | panic(message) 10 | } 11 | } 12 | 13 | // PanicOnError will panic with the message and error if the error is not nil. 14 | // If the error is nil (no error) then nothing happens. 15 | func PanicOnError(err error, message string) { 16 | if err != nil { 17 | panic(fmt.Sprintf("%s: %s", message, err.Error())) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /util/errors_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestPanicIfNil(t *testing.T) { 9 | defer func() { 10 | if r := recover(); r == nil { 11 | t.Errorf("Cannot check panic") 12 | } 13 | }() 14 | PanicIfNil(nil, "Check on nil : PanicIfNil") 15 | } 16 | 17 | func TestPanicOnError(t *testing.T) { 18 | defer func() { 19 | if r := recover(); r == nil { 20 | t.Errorf("Cannot check panic") 21 | } 22 | }() 23 | PanicOnError(fmt.Errorf("some error"), "Check on nil : PanicOnError") 24 | } 25 | -------------------------------------------------------------------------------- /util/goast_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var floats = []struct { 8 | in float64 9 | out string 10 | }{ 11 | 12 | // Zeros have no decimal 13 | {0, "0"}, 14 | {-0, "0"}, 15 | 16 | {3.14159265, "3.14159265"}, 17 | 18 | // + sign is included in positive exponents 19 | {3.14159265e123, "3.14159265e+123"}, 20 | {3.14159265e+123, "3.14159265e+123"}, 21 | 22 | {3.14159265e-123, "3.14159265e-123"}, 23 | 24 | // "Small" exponents are not stored as exponents 25 | {3.14159265e+2, "314.159265"}, 26 | {3.14159265e+5, "314159.265"}, 27 | } 28 | 29 | func TestFloatLit(t *testing.T) { 30 | for _, tt := range floats { 31 | actual := NewFloatLit(tt.in).Value 32 | if tt.out != actual { 33 | t.Errorf("input: %v", tt.in) 34 | t.Errorf(" expected: %v", tt.out) 35 | t.Errorf(" actual: %v", actual) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /util/regexp.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "regexp" 5 | "sync" 6 | ) 7 | 8 | // cachedRegex - structure for saving regexp`s 9 | type cachedRegex struct { 10 | sync.RWMutex 11 | m map[string]*regexp.Regexp 12 | } 13 | 14 | // Global variable 15 | var cr = cachedRegex{m: map[string]*regexp.Regexp{}} 16 | 17 | // GetRegex return regexp 18 | // added for minimaze regexp compilation 19 | func GetRegex(rx string) *regexp.Regexp { 20 | cr.RLock() 21 | v, ok := cr.m[rx] 22 | cr.RUnlock() 23 | if ok { 24 | return v 25 | } 26 | // if regexp is not in map 27 | cr.Lock() 28 | cr.m[rx] = regexp.MustCompile(rx) 29 | cr.Unlock() 30 | return GetRegex(rx) 31 | } 32 | -------------------------------------------------------------------------------- /version/make_version.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | 3 | // The make_version program is run by go generate to compile a version stamp 4 | // to be compiled into the c4go binary. 5 | // It does nothing unless $COMMIT_SHA is set, which is true only during 6 | // the release process. 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "io/ioutil" 12 | "log" 13 | "os" 14 | "os/exec" 15 | "time" 16 | ) 17 | 18 | func main() { 19 | log.SetPrefix("make_version") 20 | log.SetFlags(0) 21 | 22 | // get commit SHA 23 | version := os.Getenv("COMMIT_SHA") 24 | if version == "" { 25 | // git log -1 --format="%H" 26 | out, err := exec.Command("git", "log", "-1", "--format=\"%H\"").Output() 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | version = string(out) 31 | } 32 | 33 | output := fmt.Sprintf(outputFormat, time.Now().In(time.UTC).Format(time.UnixDate), version) 34 | 35 | err := ioutil.WriteFile("git_version.go", []byte(output), 0664) 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | } 40 | 41 | const outputFormat = `// Code generated by 'go run makeversion.go'. DO NOT EDIT. 42 | package version 43 | import ( 44 | "fmt" 45 | "time" 46 | ) 47 | 48 | func init() { 49 | var err error 50 | BuildTime, err = time.Parse(time.UnixDate, %[1]q) 51 | if err != nil { 52 | panic(err) 53 | } 54 | GitSHA = fmt.Sprintf("%%s", %[2]q) 55 | }` 56 | -------------------------------------------------------------------------------- /version/version.go: -------------------------------------------------------------------------------- 1 | //go:generate go run ./make_version.go 2 | 3 | // The version package is used by the release process to add an 4 | // informative version string to some commands. 5 | package version 6 | 7 | import ( 8 | "fmt" 9 | "time" 10 | ) 11 | 12 | // These strings will be overwritten by an init function in 13 | // created by make_version.go during the release process. 14 | var ( 15 | BuildTime = time.Time{} 16 | GitSHA = "" 17 | ) 18 | 19 | // Version returns a newline-terminated string describing the current 20 | // version of the build. 21 | func Version() string { 22 | if GitSHA == "" { 23 | return "development\n" 24 | } 25 | str := fmt.Sprintf("Build time: %s\n", BuildTime.In(time.UTC).Format(time.Stamp+" 2006 UTC")) 26 | str += fmt.Sprintf("Git hash: %s\n", GitSHA) 27 | return str 28 | } 29 | -------------------------------------------------------------------------------- /version/version_test.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import "testing" 4 | 5 | func TestVersion(t *testing.T) { 6 | 7 | tempVersion := Version() 8 | 9 | GitSHA = "test" 10 | tempVersion2 := Version() 11 | 12 | t.Log(tempVersion) 13 | t.Log(tempVersion2) 14 | 15 | if tempVersion == tempVersion2 { 16 | t.Errorf("Version has not changed with different Git hash.") 17 | } 18 | } 19 | --------------------------------------------------------------------------------