Code Monkey home page Code Monkey logo

c2v's Introduction

C2V

C => V source code translator.

Demo Video: Translating DOOM from C to V, building and running it.

https://www.youtube.com/watch?v=6oXrz3oRoEg

Building

v .

... or if you want to debug c2v behaviour:

v -d trace_verbose .

No dependencies other than a clang binary.

Usage

c2v accepts the following arguments:

-keep_ast           keep ast files
-print_tree         print the entire tree
c2v file.c

This will generate file.v.

c2v project

This will translate each C file in the project directory.

project/   ==>  project/
  a.c              a.c
  foo.c            a.v
                   foo.c
		   foo.v

You may need to run translated code with v -translated file.v until early 2023.

Wrapper generation

C2V can also generate V wrappers on top of C libraries.

c2v wrapper file.c

Notes

C2V is using Clang's AST to generate V. This allowed us to avoid writing a C parser.

In order to avoid LLVM dependencies/C++ complexity, C2V parses AST generated by the clang binary.

Configuration

C2V supports reading from a project configuration file named c2v.toml, located in one of these places, in this order:

  1. if C2V_CONFIG is set, it should contain the c2v.toml path.
  2. the project folder (the last folder passed to c2v) + /c2v.toml
  3. the project folder (the folder of the file that is last passed to c2v) + /c2v.toml

That file has the following format:

[project]
uses_sdl = true
output_dirname = "c2v_out.dir"
additional_flags = "-I. -I.. -I../.."

["info.c"]
additional_flags = "-I/some/folder/used/only/for/that/specific/file"

In the above: uses_sdl is a boolean, that defaults to false. When it is true, c2v will append the result of sdl2-config --cflags to additional_flags . output_dirname is a string, that defaults to c2v_output. c2v will create that folder, if it does not exist, and it will put all the translated .v files there. additional_flags is a string, that will be passed verbatim to the clang parser for each .c file. It can be used to pass additional -I flags, that are specific to your project, so that clang can find all the headers needed by that project.

Note: all these are global to the project.

The c2v.toml configuration file also supports file specific overrides, for the additional_flags option, just put them in their own sections, titled as the file name.

c2v's People

Contributors

akvadrako avatar artemkakun avatar dedesite avatar felipensp avatar larpon avatar medvednikov avatar prantlf avatar rilysh avatar spytheman avatar tauraamui avatar trollkarlen avatar ttytm avatar wertzui123 avatar xn0px90 avatar yuyi98 avatar zakuro9715 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c2v's Issues

Finding clang in windows path

Not sure if I am doing something wrong, but when compiling c2v I get this error:

$ v translate test.c
Compiling c2v ...
================ V panic ================
   module: main
 function: find_clang_in_path()
  message: cannot find clang in PATH
     file: ./c2v.v:98
   v hash: 5cd5d55
=========================================
C:/Users/User/AppData/Local/Temp/v_0/../../../../../..C:\Users\User\V_FOLDER\v\vlib\builtin\builtin.c.v:53: at panic_debug: Backtrace
C:/Users/User/AppData/Local/Temp/v_0/../../../../../..C:\Users\User\.vmodules\c2v\c2v.v:98: by main__find_clang_in_path
C:/Users/User/AppData/Local/Temp/v_0/../../../../../..C:\Users\User\AppData\Local\Temp\v_0\c2v.tmp.c:17576: by _vinit
C:/Users/User/AppData/Local/Temp/v_0/../../../../../..C:\Users\User\AppData\Local\Temp\v_0\c2v.tmp.c:17596: by wmain
0056d868 : by ???
0056d9cb : by ???
7ffd793c7034 : by ???
C2V failed to translate the C files. Please report it via GitHub.

As you can see the error is because of this. I guess it's because my clang command is clang.exe (screenshot) and not just clang, but I don't know.

I tried adding 'clang.exe' to the array but it gives another error (don't know if it's related or not).

$ cat test.c
#include <stdio.h>

int main() {
    puts("Test...\n");
}

$ v translate test.c
Compiling c2v ...
C to V translator 0.3.1
  translating test.c          ... The system cannot find the path specified.
 took   422 ms ; output .v file: test.v
Translated   1 files in   422 ms.

$ cat test.v
[translated]
module main

type Uintptr_t = i64
type Va_list = &i8
type Size_t = i64
type Ptrdiff_t = i64
type Intptr_t = i64
type Wchar_t = U16
type Errno_t = int
type Wint_t = U16
type Wctype_t = U16
struct Crt_locale_data_public {
        _locale_pctype &u16
        _locale_mb_cur_max int
        _locale_lc_codepage u32
}
struct Crt_locale_pointers {
        locinfo &crt_locale_data
        mbcinfo &crt_multibyte_data
}
type _locale_t = &crt_locale_pointers
struct Mbstatet {
        _Wchar u32
        _Byte u16
        _State u16
}
type Mbstate_t = Mbstatet
type Time_t = Time64_t
type Rsize_t = Usize
struct FILE {
        _Placeholder voidptr
}
type Fpos_t = i64
fn main()  {
        C.puts(c'Test...\n')
}

operator precedence with bitwise operations

OS: linux, "Arch Linux"
V full version: V 0.2.4 e5bbb23.ccc3271

C and V have difference operator precedence for bitwise operations, programs converted using C2V are inherently broken.

Take this C code as an example:

#include <stdio.h>

int main(){
    if ( 0b00001000 & 1 << 3 ) {
        printf("*** is ***\n");
    } else {
        printf("*** is not ***\n");
    }
}

Creates the following output:

> $ gcc bug.c && ./a.out
*** is ***
> $ v translate bug.c && v run bug.v                                        
C to V translator 0.3.1
  translating bug.c           ... Reformatted file: /home/liaml/bug.v
 took    57 ms ; output .v file: bug.v
Translated   1 files in    57 ms.
*** is not ***

This is because of the line inside the if statement being translated as it is.
0b00001000 & 1 << 3 should be 0b00001000 & (1 << 3) inside the V programming language. There is no need for the brackets in C.

Having differing operator precedence is not a bug, however translated code has to account for this.

Thank you for reviewing this issue.

Functions with uppercases are wrongly wrap

When calling c2v wrapper test.h on this file :

void testFunc() {
    
}

It generates this file :

[translated]
module .

fn C.testFunc() 

pub [c:'testFunc']
fn testfunc()  {
        C.testfunc()
}

There is two errors here :

  • pub keyword should be right before the fn keyword
  • the call to C.testfunc() should be C.testFunc()

Strange error message about binary number with unsuitable digit

  1. Download source to sqlite release: https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release
  2. Extract source.
  3. cd sqlite
  4. v translate tool/sqldiff.c
C to V translator 0.3.1
  translating tool/sqldiff.c  ... tool/sqldiff.v:1145:17: error: this binary number has unsuitable digit `e`
 1143 |         iblock := 0
 1144 |         
 1145 |         bestcnt := 0
      |                     ^
 1146 |         bestofst := 0bestlitsz := 0
 1147 |         hash_init(&h, &zout [base] )

Internal vfmt error while formatting file: tool/sqldiff.v.
Encountered a total of: 1 errors.
 took   347 ms ; output .v file: tool/sqldiff.v
Translated   1 files in   347 ms.

Error when translating multiple variable assignments on one line

Seems like c2v has a hard time with multiple, comma separated variable assignments on the same line

Test case

fn aes256_set_encryption_key(key &u8, expandedkey &u32)  {
	nb := 4, nr := 14, nk := 8, i := u32(0)
	tmp := u32(0)
        // ...
}

Output

C to V translator 0.3.1
  translating ./tgcrypto/aes256.c ... tgcrypto/aes256.v:119:9: error: this number has unsuitable digit `n`
  117 |
  118 | fn aes256_set_encryption_key(key &u8, expandedkey &u32)  {
  119 |     nb := 4nr := 14nk := 8i := u32(0)
      |            ^
  120 |     tmp := u32(0)
  121 |

SDL error

macos m1

Repo
https://github.com/odunboye/pong_game

c2v.toml

[project]
additional_flags = "-I/opt/homebrew/include -L/opt/homebrew/lib -lSDL2"
% ./c2v ../../../lab/pong_game
C to V translator 0.3.1
"../../../lab/pong_game" is a directory, processing all C files in it recursively...

  translating ./racket.c      ... 

Unhandled expr() node {CompoundLiteralExpr} (ast line nr node.ast_line_nr "./racket.c"):
{CompoundLiteralExpr} name:"" value:"" loc:Loc{
    offset: 0
    file: ''
    line: 0
    col: 0
    tokLen: 0
    included_from: IncludedFrom{
        file: ''
    }
    spelling_loc: IncludedFrom{
        file: ''
    }
    range: Range{
        begin: Begin{
            spelling_loc: IncludedFrom{
                file: ''
            }
        }
    }
}  #c: 1 typ:"SDL_Rect"
0   c2v                                 0x00000001047f7830 main__C2V_expr + 2920
1   c2v                                 0x00000001047f724c main__C2V_expr + 1412
2   c2v                                 0x00000001047fd764 main__C2V_statement + 1048
3   c2v                                 0x00000001047fb944 main__C2V_statements + 124
4   c2v                                 0x00000001047f906c main__C2V_fn_decl + 2836
5   c2v                                 0x0000000104804104 main__C2V_top_level + 156
6   c2v                                 0x00000001048038c0 main__C2V_translate_file + 2640
7   c2v                                 0x0000000104802d48 main__main + 1088
8   c2v                                 0x000000010480757c main + 84
9   dyld                                0x0000000104a5108c start + 520 

`doom_regression` GitHub Action random fails

Randomly throws the following error

2s
Run ./imgur.sh /tmp/fail.png
Delete page: https://imgur.com/delete/r54LbMGifWieLxc
https://i.imgur.com/6wA7qov.png
Haven't copied to the clipboard: no xsel or xclip
https://i.imgur.com/PmdV4LZ.png
Delete page: https://imgur.com/delete/Ypna8rul9At2rno
Haven't copied to the clipboard: no xsel or xclip
Error: Process completed with exit code 1.

@Larpon

Doom translation - m_menu.v - `invalid expression: unexpected token '='`

doom_v/m_menu.v:1137:18: error: invalid expression: unexpected token `=`
 1135 |                     key = 13
 1136 |                 }
 1137 |                 else {
      |                       ^
  translating ./m_menu.c      ...  took   930 ms ; output .v file: ./doom_v/m_menu.v
 1138 |                     if currentMenu == &SaveDef {
 1139 |                         joypadSave = true

Internal vfmt error while formatting file: /home/runner/code/doom/chocolate-doom/src/doom/./doom_v/m_menu.v.
Encountered a total of: 1 errors.

This is on actual c2v repo, doom-regressions GitHub Action, step "Translate the whole game in project/folder mode"
I suppose this is not that should happen

Get a weird V panic when translating stivale2

i get this:

$ v translate .
C to V translator 0.3.1
"." is a directory, processing all C files in it recursively...

  translating ./stivale2.c    ... ================ V panic ================
   module: builtin
 function: get()
  message: array.get: index out of range (i == 134, a.len == 134)
     file: /home/vox/Documents/v/vlib/builtin/array.v:384
   v hash: 298dc77
=========================================
/tmp/v_1000/../../../../../../home/vox/Documents/v/vlib/builtin/builtin.c.v:53: at panic_debug: Backtrace
/tmp/v_1000/../../../../../../home/vox/Documents/v/vlib/builtin/array.v:384: by array_get
/tmp/v_1000/../../../../../../home/vox/.vmodules/c2v/c2v.v:875: by main__C2V_record_decl
/tmp/v_1000/../../../../../../home/vox/.vmodules/c2v/c2v.v:2316: by main__C2V_top_level
/tmp/v_1000/../../../../../../home/vox/.vmodules/c2v/c2v.v:2271: by main__C2V_translate_file
/tmp/v_1000/../../../../../../home/vox/.vmodules/c2v/c2v.v:2196: by main__main
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17589: by main
C2V failed to translate the C files. Please report it via GitHub.

Link to stivale2

wrapper doesn't wrap function declaration

When trying to use wrapper command on header files, I realize that wrapper doesn't wrap function declaration but needs a function definition.

It would be very convenient if it were able to create wrapper only based on function declaration.

Example test.h :

void test();

c2v wrapper test.h Sould lead to :

[translated]
module .

fn C.test() 

pub fn test()  {
	C.test()
}

But it lead to nothing for now.

[translated]
module .

C2V generates invalid sourcecode on Windows

#include <stdio.h>

int main(){
    printf("Hello World!\n");
    return 0;
}

translates to:

[translated]
module main

type Size_t = i64
type Ssize_t = i64
type Rsize_t = Usize
type Intptr_t = i64
type Uintptr_t = i64
type Ptrdiff_t = i64
type Wchar_t = U16
type Wint_t = U16
type Wctype_t = U16
type Errno_t = int
type Time_t = Time64_t
type Pthreadlocinfo = &Threadlocaleinfo*
type Pthreadmbcinfo = &Threadmbcinfo*
struct Locale_tstruct { 
	locinfo Pthreadlocinfo
	mbcinfo Pthreadmbcinfo
}
type _locale_t = &Localeinfo_*
struct LC_ID { 
	wLanguage u16
	wCountry u16
	wCodePage u16
}
type LPLC_ID = &TagLC_ID
struct Threadlocinfo { 
	_locale_pctype &u16
	_locale_mb_cur_max int
	_locale_lc_codepage u32
}
struct FILE { 
	_Placeholder voidptr
}
type _off_t = int
type Off32_t = int
type _off64_t = i64
type Off64_t = i64
type Off_t = Off32_t
type Fpos_t = i64
fn main()  {
	C.printf(c'Hello World!\n')
	return 
}

which cannot compile due to:

main.v:15:40: notice: script mode started here
   13 | type Errno_t = int
   14 | type Time_t = Time64_t
   15 | type Pthreadlocinfo = &Threadlocaleinfo*
      |                                        ^
   16 | type Pthreadmbcinfo = &Threadmbcinfo*
   17 | struct Locale_tstruct {
main.v:16:1: error: all definitions must occur before code in script mode
   14 | type Time_t = Time64_t
   15 | type Pthreadlocinfo = &Threadlocaleinfo*
   16 | type Pthreadmbcinfo = &Threadmbcinfo*
      | ~~~~
   17 | struct Locale_tstruct {
   18 |     locinfo Pthreadlocinfo

Cannot translate switch without explicit break

this translates:

const int a = 0;

void f() 
{ 
    switch(a)
    {
    default:
    break;
    case 0:
        break;
    }
}

this fails:

const int a = 0;

void f() 
{ 
    switch(a)
    {
    default:
    //break; // this line is the only change
    case 0:
        break;
    }
}

Unhandled expr() node {AtomicExpr}

  1. Download source to sqlite release: https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release
  2. Extract source.
  3. cd sqlite
  4. ./configure
  5. make
  6. v translate .
C to V translator 0.3.1
"." is a directory, processing all C files in it recursively...

  translating ./sqlite3.c     ... 

Unhandled expr() node {AtomicExpr} (ast line nr node.ast_line_nr "./sqlite3.c"):
{AtomicExpr} name:"" value:"" loc:Loc{
    offset: 0
    file: ''
    line: 0
    col: 0
    tokLen: 0
    included_from: IncludedFrom{
        file: ''
    }
    spelling_loc: IncludedFrom{
        file: ''
    }
    range: Range{
        begin: Begin{
            spelling_loc: IncludedFrom{
                file: ''
            }
        }
    }
}  #c: 3 typ:"void"
/tmp/v_1000/../../../../../../home/jamie/git/v/vlib/builtin/builtin.c.v:639: at print_backtrace: Backtrace
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:2013: by main__C2V_expr
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:1141: by main__C2V_statement
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:1091: by main__C2V_statements
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:537: by main__C2V_fn_decl
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:2314: by main__C2V_top_level
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:2271: by main__C2V_translate_file
/tmp/v_1000/../../../../../../home/jamie/.vmodules/c2v/c2v.v:2196: by main__main
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17589: by main
C2V command: '/home/jamie/.vmodules/c2v/c2v' '.'
C2V failed to translate the C files. Please report it via GitHub.

Problem with "complex" for loop

  1. Download source to sqlite release: https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release
  2. Extract source.
  3. cd sqlite
  4. v translate tool/varint.c
C to V translator 0.3.1
  translating tool/varint.c   ... tool/varint.v:70:2: error: unexpected name `j`, expecting `;`
   68 |     buf [0]  &= 127
   69 |     for i = 0 , n - 1
   70 |     j = i = 0 ; j >= 0 ; j -- , i ++ {
      |     ^
   71 |         p [i]  = buf [j] 
   72 |     }

Internal vfmt error while formatting file: tool/varint.v.
Encountered a total of: 1 errors.
 took    79 ms ; output .v file: tool/varint.v
Translated   1 files in    79 ms.

C2V fails to translate C file

Steps to reproduce:

$ git clone --depth=1 https://github.com/Genymobile/scrcpy
$ cd scrcpy/app/src
$ v translate clock.c

C2V is not installed. Cloning C2V to /Users/tedstoychev/.vmodules/c2v ...
Compiling c2v ...
C to V translator 0.3.1
  translating clock.c         ... In file included from clock.c:1:
In file included from ./clock.h:4:
./common.h:4:10: fatal error: 'config.h' file not found
#include "config.h"
         ^~~~~~~~~~
1 error generated.

The file clock.c could not be parsed as a C source file.
C2V failed to translate the C files. Please report it via GitHub.

V: v0.3.0 00dfce6
OS: macOS Monterey 12.4

Error: `c++ top level` when Translating C Files & Memory Leak Warning

Was trying to run v translate (which compiled c2v automatically) on raudio.c from: https://github.com/raysan5/raylib/blob/master/src/raudio.c
and it failed like this:

neko-san@ARCH /m/e/D/raylib (master)> v translate *
C to V translator 0.3.1
"src" is a directory, processing all C files in it recursively...

  translating ./raudio.c      ... GC Warning: Repeated allocation of very large block (appr. size 576020480):
        May lead to memory leak and poor performance
C++ top level
C2V failed to translate the C files. Please report it via GitHub.
neko-san@ARCH /m/e/D/raylib (master) [4]> cd src
neko-san@ARCH /m/e/D/r/src (master)> v translate raudio.c 
C to V translator 0.3.1
  translating raudio.c        ... GC Warning: Repeated allocation of very large block (appr. size 574701568):
        May lead to memory leak and poor performance
C++ top level
C2V failed to translate the C files. Please report it via GitHub.
neko-san@ARCH /m/e/D/r/src (master) [4]> cd ../../
neko-san@ARCH /m/e/Development> git clone --recurse --recurse-submodules https://github.com/vlang/c2v
Cloning into 'c2v'...
remote: Enumerating objects: 233, done.
remote: Counting objects: 100% (108/108), done.
remote: Compressing objects: 100% (67/67), done.
remote: Total 233 (delta 46), reused 67 (delta 23), pack-reused 125
Receiving objects: 100% (233/233), 151.90 KiB | 1.58 MiB/s, done.
Resolving deltas: 100% (87/87), done.
neko-san@ARCH /m/e/Development>  cd /mnt/extraStorage/Development/c2v
neko-san@ARCH /m/e/D/c2v (master)> v -gc none .
neko-san@ARCH /m/e/D/c2v (master)>  cd /mnt/extraStorage/Development
neko-san@ARCH /m/e/Development>  cd /mnt/extraStorage/Development/raylib-vlang
neko-san@ARCH /m/e/D/raylib-vlang (master)>  cd /mnt/extraStorage/Development/raylib-vlang/src
neko-san@ARCH /m/e/D/r/src (master)> mv ../../c2v/c2v .
neko-san@ARCH /m/e/D/r/src (master)> ./c2v raudio.c 
C to V translator 0.3.1
  translating raudio.c        ... C++ top level
neko-san@ARCH /m/e/D/r/src (master) [1]>

(I just moved the aforementioned glfw folder somewhere else temporarily, so this shouldn't be related?
I mention that because leaving the "glfw" folder in the project throws other errors)

@ medvednikov said this about it on Discord:
"it sounds like a bug, it shouldn't allocate this much memory"

Problem with parentheses in for loop params

  1. Download source to sqlite release: https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release
  2. Extract source.
  3. cd sqlite
  4. v translate tool/srcck1.c
C to V translator 0.3.1
  translating tool/srcck1.c   ... tool/srcck1.v:103:17: error: unexpected token `=`, expecting `)`
  101 |     c := i8(0)
  102 |     prevc := 0
  103 |     for i = 0 ; (c = z [i] ) != 0 ; prevc = c , i ++ {
      |                    ^
  104 |         if c == `
  105 | ` {

Internal vfmt error while formatting file: tool/srcck1.v.
Encountered a total of: 1 errors.
 took    92 ms ; output .v file: tool/srcck1.v
Translated   1 files in    92 ms.

[WORKAROUND] cannot find clang in PATH error Windows 10

X:\v>v doctor
OS: windows, Microsoft Windows 10 Home v19044 64-bit
Processor: 24 cpus, 64bit, little endian, AMD Ryzen 9 3900X 12-Core Processor
CC version: Error: exec failed (CreateProcess) with code 2: The system cannot find the file specified.
cmd: cc --version

getwd: X:\v
vmodules: C:\Users\argit.vmodules
vroot: F:(PROGRAMMING)\Hydrus\v
vexe: F:(PROGRAMMING)\Hydrus\v\v.exe
vexe mtime: 2022-07-13 05:38:33
is vroot writable: true
is vmodules writable: true
V full version: V 0.3.0 d12a8ae.28fd176

Git version: git version 2.30.1.windows.1
Git vroot status: 0.3-121-g28fd1765
.git/config present: true
thirdparty/tcc status: thirdparty-windows-amd64 125e21e2

try to translate c

What did you expect to see?
a translated primes.c

What did you see instead?

X:\v>v translate primes.c
================ V panic ================
   module: main
 function: find_clang_in_path()
  message: cannot find clang in PATH
     file: ./c2v.v:97
   v hash: 16a6972
=========================================
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..F:\(PROGRAMMING)\Hydrus\v\vlib\builtin\builtin.c.v:53: at panic_debug: Backtrace
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\.vmodules\c2v\c2v.v:97: by main__find_clang_in_path
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\AppData\Local\Temp\v_0\c2v.exe.tmp.c:17578: by _vinit
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\AppData\Local\Temp\v_0\c2v.exe.tmp.c:17590: by wmain
0056ded8 : by ???
0056e03b : by ???
7fffa64b7034 : by ???
C2V failed to translate the C files. Please report it via GitHub.

Block comment cause `translate` to fail

Flecs repo - https://github.com/SanderMertens/flecs
V 0.2.4 (fe673e7 commit)

Error message

[๐Ÿ”ด] ร— v translate ~/Projects/KolciaEngine/flecs-v/
C to V translator 0.3.1
"/home/yuart/Projects/KolciaEngine/flecs-v/" is a directory, processing all C files in it recursively...

  translating ./flecs.c       ...

Unhandled expr() node {FullComment} (ast line nr node.ast_line_nr "./flecs.c"):
{FullComment} name:"" value:"" loc:Loc{
    offset: 120754
    file: ''
    line: 3883
    col: 4
    tokLen: 0
    included_from: IncludedFrom{
        file: './flecs.c'
    }
    spelling_loc: IncludedFrom{
        file: ''
    }
    range: Range{
        begin: Begin{
            spelling_loc: IncludedFrom{
                file: ''
            }
        }
    }
}  #c: 1 typ:""
/tmp/v_1000/../../../../../../home/yuart/Projects/v/vlib/builtin/builtin.c.v:639: at print_backtrace: Backtrace
/tmp/v_1000/../../../../../../home/yuart/.vmodules/c2v/c2v.v:2013: by main__C2V_expr
/tmp/v_1000/../../../../../../home/yuart/.vmodules/c2v/c2v.v:1711: by main__C2V_global_var_decl
/tmp/v_1000/../../../../../../home/yuart/.vmodules/c2v/c2v.v:2318: by main__C2V_top_level
/tmp/v_1000/../../../../../../home/yuart/.vmodules/c2v/c2v.v:2271: by main__C2V_translate_file
/tmp/v_1000/../../../../../../home/yuart/.vmodules/c2v/c2v.v:2196: by main__main
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17588: by main
C2V failed to translate the C files. Please report it via GitHub.

C2V repo Github Workflows are broken

  • expected V code after translation probably in an old version (now C2V also adds [translated] attribute and module main)
  • make sure Ubuntu runs .vsh files with tests too (but not Doom translation since it requires Chocolatey and complex setup)

Add ability to translate comments with `translate wrapper` command

For now, when using translate wrapper command on .h file, it creates methods without comments. I think copying original comments will be a good idea in some cases.

I think a flag preserve-comments need to be used, and this feature will be turned off by default.

What do you think?

Fix translation of assign expression in parens

You can run this test in C2V folder -> tests -> v run run_tests.vsh

tests/5.if_paren_call.v:6:8: error: unexpected token `=`, expecting `)`
    4 | fn main()  {
    5 |     a := 0
    6 |     if (a = C.puts(c'Hello World')) {
      |           ^
    7 |         C.puts(c'noes')
    8 |     }
 
Internal vfmt error while formatting file: /home/yuart/Projects/c2v/tests/5.if_paren_call.v.
Encountered a total of: 1 errors.
tests/5.if_paren_call.v:6:8: error: unexpected token `=`, expecting `)`
    4 | fn main()  {
    5 |     a := 0
    6 |     if (a = C.puts(c'Hello World')) {
      |           ^
    7 |         C.puts(c'noes')
    8 |     }
 
Internal vfmt error while formatting file: /home/yuart/Projects/c2v/tests/5.if_paren_call.v.
Encountered a total of: 1 errors.
/home/yuart/Projects/c2v/tests/5.if_paren_call.c...
FAIL
expected:
[translated]
module main
 
fn main() {
	a := 0
	a = C.puts(c'Hello World')
	if a {
		C.puts(c'noes')
	}
	a = C.puts(c'Hello World')
	if a != 0 {
		C.puts(c'noes')
	}
	cacatua := 0
	cacatua = C.puts(c'Hello World')
	if cacatua {
		C.puts(c'noes')
	}
}
 
===got:
[translated]
module main
 
fn main()  {
	a := 0
	if (a = C.puts(c'Hello World')) {
		C.puts(c'noes')
	}
	if (a = C.puts(c'Hello World')) != 0 {
		C.puts(c'noes')
	}
	cacatua := 0
	if (cacatua = C.puts(c'Hello World')) {
		C.puts(c'noes')
	}
}
 
====diff=====
--- /tmp/expected.txt	2022-06-30 20:06:52.722390175 +0200
+++ /tmp/got.txt	2022-06-30 20:06:52.722390175 +0200
@@ -1,19 +1,16 @@
 [translated]
 module main
 
-fn main() {
+fn main()  {
 	a := 0
-	a = C.puts(c'Hello World')
-	if a {
+	if (a = C.puts(c'Hello World')) {
 		C.puts(c'noes')
 	}
-	a = C.puts(c'Hello World')
-	if a != 0 {
+	if (a = C.puts(c'Hello World')) != 0 {
 		C.puts(c'noes')
 	}
 	cacatua := 0
-	cacatua = C.puts(c'Hello World')
-	if cacatua {
+	if (cacatua = C.puts(c'Hello World')) {
 		C.puts(c'noes')
 	}
 }
\ No newline at end of file

cannot find clang in PATH from v translate

V version: 0.3.1 1c63ce4
OS: Ubuntu 22.04.1 LTS

What did you do?

Execute command v translate Kml.c

What did you expect to see?

Generated code in v

What did you see instead?


Compiling c2v ...
================ V panic ================
   module: main
 function: find_clang_in_path()
  message: cannot find clang in PATH
     file: ./c2v.v:96
   v hash: 4bd49a0
=========================================
/tmp/v_1000/../../../../../../opt/v/vlib/builtin/builtin.c.v:53: at panic_debug: Backtrace
/tmp/v_1000/../../../../../../home/cristovao/.vmodules/c2v/c2v.v:96: by main__find_clang_in_path
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17579: by _vinit
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17591: by main
C2V command: '/home/cristovao/.vmodules/c2v/c2v' 'Kml.c'
C2V failed to translate the C files. Please report it via GitHub.

`translate wrapper` doesn't generate module name

C2V - c08add0
V - 0.2.4 (ccc3271493019feb13ed1c96b035199e159fe863)

.h file - https://github.com/SanderMertens/flecs/blob/master/flecs.h

cat flecs.v

File: flecs.v
[translated]
module                            <- no module name!

type Ecs_flags8_t = u8
type Ecs_flags16_t = Uint16_t
type Ecs_flags32_t = u32
type Ecs_flags64_t = i64
type Ecs_size_t = int
type Ecs_comparator_t = fn (voidptr, voidptr) int
type Ecs_map_key_t = i64
struct Ecs_bucket_entry_t {
    next &Ecs_bucket_entry_t
    key Ecs_map_key_t
}
struct Ecs_block_allocator_block_t {
    memory voidptr
    next &Ecs_block_allocator_block_t
}
struct Ecs_block_allocator_chunk_header_t {
    next &Ecs_block_allocator_chunk_header_t
}

...

c2v cannot translate bool

OS: windows, Microsoft Windows 10 Home v19044 64-bit
Processor: 24 cpus, 64bit, little endian, AMD Ryzen 9 3900X 12-Core Processor
CC version: Error: exec failed (CreateProcess) with code 2: The system cannot find the file specified.
 cmd: cc --version

getwd: C:\Users\argit
vmodules: C:\Users\argit\.vmodules
vroot: F:\(PROGRAMMING)\Hydrus\v
vexe: F:\(PROGRAMMING)\Hydrus\v\v.exe
vexe mtime: 2022-07-13 18:32:29
is vroot writable: true
is vmodules writable: true
V full version: V 0.3.0 28fd176

Git version: git version 2.30.1.windows.1
Git vroot status: 0006e8d1-dirty (13553 commit(s) behind V master)
.git/config present: false
thirdparty/tcc: N/A
bool a_bool; // this cannot be translated to V apparently

What did you expect to see?
translated to V

What did you see instead?

C to V translator 0.3.1
  translating c:/SoEm_Chaos.c ... c:/SoEm_Chaos.c:944:1: error: unknown type name 'bool'
bool a_bool;
^
1 error generated.

The file c:/SoEm_Chaos.c could not be parsed as a C source file.
C2V failed to translate the C files. Please report it via GitHub.

C2V cannot translate wayland-egl-backend.h

Error:

C to V translator 0.3.1
  translating ./wayland-egl-backend.h ... ================ V panic ================
   module: builtin
 function: get()
  message: array.get: index out of range (i == 99, a.len == 99)
     file: /home/aakash/.local/bin/v_lang/vlib/builtin/array.v:384
   v hash: ac7e809
=========================================
/tmp/v_1000/../../../../../../home/aakash/.local/bin/v_lang/vlib/builtin/builtin.c.v:53: at panic_debug: Backtrace
/tmp/v_1000/../../../../../../home/aakash/.local/bin/v_lang/vlib/builtin/array.v:384: by array_get
/tmp/v_1000/../../../../../../home/aakash/.vmodules/c2v/c2v.v:788: by main__C2V_record_decl
/tmp/v_1000/../../../../../../home/aakash/.vmodules/c2v/c2v.v:2049: by main__C2V_top_level
/tmp/v_1000/../../../../../../home/aakash/.vmodules/c2v/c2v.v:2004: by main__C2V_translate_file
/tmp/v_1000/../../../../../../home/aakash/.vmodules/c2v/c2v.v:1938: by main__main
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17582: by main
C2V failed to translate the C files. Please report it via GitHub.

Source file: http://0x0.st/o1yR.h

Cannot translate v.c

I downloaded v.c from vc repo and then: v translate v.c

getting the following output:

C to V translator 0.3.1
  translating v.c             ... V panic: 2352798600 cast to int results in -1942168696)
v hash: a75a12e
/tmp/v_1000/../../../../../../path/to/vlang/vlib/builtin/builtin.c.v:104: at _v_panic: Backtrace
/tmp/v_1000/../../../../../../path/to/.vmodules/c2v/c2v.v:1983: by main__C2V_translate_file
/tmp/v_1000/../../../../../../path/to/.vmodules/c2v/c2v.v:1940: by main__main
/tmp/v_1000/../../../../../../tmp/v_1000/c2v.tmp.c:17592: by main
C2V command: '/path/to/.vmodules/c2v/c2v' 'v.c'
C2V failed to translate the C files. Please report it via GitHub.

Translation with is_prime example not working correctly on windows 10 64

this what i get

[translated]
module main

type Uintptr_t = i64
type Va_list = &i8
type Size_t = i64
type Ptrdiff_t = i64
type Intptr_t = i64
type Wchar_t = U16
type Errno_t = int
type Wint_t = U16
type Wctype_t = U16
struct Crt_locale_data_public { 
	_locale_pctype &u16
	_locale_mb_cur_max int
	_locale_lc_codepage u32
}
struct Crt_locale_pointers { 
	locinfo &crt_locale_data
	mbcinfo &crt_multibyte_data
}
type _locale_t = &crt_locale_pointers
struct Mbstatet { 
	_Wchar u32
	_Byte u16
	_State u16
}
type Mbstate_t = Mbstatet
type Time_t = Time64_t
type Rsize_t = Usize
struct FILE { 
	_Placeholder voidptr
}
type Fpos_t = i64
fn is_prime(x int) bool {
	for i := 2 ; i <= x / 2 ; i ++ {
		if x % i == 0 {
		return false
		}
	}
	return true
}

fn main()  {
	for i := 2 ; i < 100 ; i ++ {
		if is_prime(i) {
			C.printf(c'%i\n', i)
		}
	}
	return 
}

and error

v main.v
main.v:9:16: error: unknown type `U16`.
Did you mean `FILE`?
    7 | type Ptrdiff_t = i64
    8 | type Intptr_t = i64
    9 | type Wchar_t = U16
      |                ~~~
   10 | type Errno_t = int
   11 | type Wint_t = U16
main.v:11:15: error: unknown type `U16`.
Did you mean `FILE`?
    9 | type Wchar_t = U16
   10 | type Errno_t = int
   11 | type Wint_t = U16
      |               ~~~
   12 | type Wctype_t = U16
   13 | struct Crt_locale_data_public {
main.v:12:17: error: unknown type `U16`.
Did you mean `FILE`?
   10 | type Errno_t = int
   11 | type Wint_t = U16
   12 | type Wctype_t = U16
      |                 ~~~
   13 | struct Crt_locale_data_public {
   14 |     _locale_pctype &u16
main.v:19:11: error: unknown type `crt_locale_data`.
Did you mean `Crt_locale_data_public`?
   17 | }
   18 | struct Crt_locale_pointers {
   19 |     locinfo &crt_locale_data
      |              ~~~~~~~~~~~~~~~
   20 |     mbcinfo &crt_multibyte_data
   21 | }
main.v:20:11: error: unknown type `crt_multibyte_data`
   18 | struct Crt_locale_pointers {
   19 |     locinfo &crt_locale_data
   20 |     mbcinfo &crt_multibyte_data
      |              ~~~~~~~~~~~~~~~~~~
   21 | }
   22 | type _locale_t = &crt_locale_pointers
main.v:22:18: error: unknown type `crt_locale_pointers`.
Did you mean `Crt_locale_pointers`?
   20 |     mbcinfo &crt_multibyte_data
   21 | }
   22 | type _locale_t = &crt_locale_pointers
      |                  ~~~~~~~~~~~~~~~~~~~~
   23 | struct Mbstatet {
   24 |     _Wchar u32
main.v:29:15: error: unknown type `Time64_t`.
Did you mean `Time_t`?
   27 | }
   28 | type Mbstate_t = Mbstatet
   29 | type Time_t = Time64_t
      |               ~~~~~~~~
   30 | type Rsize_t = Usize
   31 | struct FILE {
main.v:30:16: error: unknown type `Usize`.
Did you mean `Rsize_t`?
   28 | type Mbstate_t = Mbstatet
   29 | type Time_t = Time64_t
   30 | type Rsize_t = Usize
      |                ~~~~~
   31 | struct FILE {
   32 |     _Placeholder voidptr

Incorrect output when translating function header for fputs

Hello,

Here's a minimal example showing incorrect output when translating fputs on MacOS:


#include <stdio.h>

int main()
{
   FILE *f;
   f = fopen("file.txt", "w+");
   fputs("test", f);
   fclose(f);
   
   return 0;
}

The output from c2v:

C to V translator 0.3.1
  translating test.c          ... test.v:4:11: error: parameter name must not begin with upper case letter (`Char`)
    2 | module main
    3 | 
    4 | fn fputs( Char *restrict,  FILE *restrict) int
      |           ~~~~
    5 | 
    6 | fn main()  {

Steps to reproduce:

  1. Copy C segment into a new file, test.c
  2. Run v translate test.c

unexpected token `*`, expecting `,` Translating `OpenDoas` "timestamp.c"

Translating timestamp.c from the Arch Linux opendoas repo throws an "unexpected token" error.

v version: 0.3.0 3ad22eb

C to V translator 0.3.1
  translating timestamp.c     ... timestamp.v:34:24: error: unexpected token `*`, expecting `,`
   32 | fn strtoul( &i8,  &&u8,  int) u32
   33 | 
   34 | fn strtoul(__nptr Char *restrict, __endptr Char **restrict, __base int) u32
      |                        ^
   35 | 
   36 | fn strtoull( &i8,  &&u8,  int) i64

Internal vfmt error while formatting file: timestamp.v.
Encountered a total of: 1 errors.
 took   206 ms ; output .v file: timestamp.v
Translated   1 files in   206 ms.

Steps to reproduce:

  1. git clone https://github.com/Duncaen/OpenDoas/
  2. Enter the project directory
  3. Place this c2v.toml in the root project directory and the libopendoas directory:
[project]
uses_sdl = false
output_dirname = "c2v_out.dir"
additional_flags = "-I. -I.. -I../.. -I./libopenbsd"
  1. Run ./configure --with-timestamp
  2. Run v translate *

System Info:
OS: Arch Linux x86_64

c2v cannot translate enums

fails to translate

enum OSC_VARIABLES
{
	OSC_NUMVARS
};

error

C to V translator 0.3.1
  translating c:/library/variable.h ... ================ V panic ================
   module: builtin
 function: get()
  message: array.get: index out of range (i == 8, a.len == 8)
     file: F:/(PROGRAMMING)/Hydrus/v/vlib/builtin/array.v:384
   v hash: 16a6972
=========================================
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..F:\(PROGRAMMING)\Hydrus\v\vlib\builtin\builtin.c.v:53: at panic_debug: Backtrace
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..F:\(PROGRAMMING)\Hydrus\v\vlib\builtin\array.v:384: by array_get
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\.vmodules\c2v\c2v.v:1031: by main__C2V_enum_decl
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\.vmodules\c2v\c2v.v:2323: by main__C2V_top_level
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\.vmodules\c2v\c2v.v:2274: by main__C2V_translate_file
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\.vmodules\c2v\c2v.v:2205: by main__main
C:/Users/argit/AppData/Local/Temp/v_0/../../../../../..C:\Users\argit\AppData\Local\Temp\v_0\c2v.exe.tmp.c:17591: by wmain
0056ded8 : by ???
0056e03b : by ???
7ff802197034 : by ???
C2V failed to translate the C files. Please report it via GitHub.

Wrong anonymous enums values translation

C code

enum myEnum {
    A,
    B,
    C
};

typedef enum {
    D,
    E,
    F
} myAnotherEnum;

typedef enum myStrangeEnum {
    G,
    H,
    I
} myStrangeEnum;

enum { J = 1 };

int main() {
    enum myEnum myEnumVar = A;
    myAnotherEnum myEnumVar2 = D;
    myStrangeEnum myEnumVar3 = G;
    int myIntVar = J;
    return 0;
}

V translated

[translated]
module main

enum MyEnum {
	a
	b
	c
}

enum MyAnotherEnum {
	d
	e
	f
}

enum MyStrangeEnum {
	g
	h
	i
}

const ( // empty enum
	j = 0
)

fn main() {
	myenumvar := MyEnum.a
	myenumvar2 := MyAnotherEnum.d
	myenumvar3 := MyStrangeEnum.g
	myintvar := j
	return
}

Expected

[translated]
module main

enum MyEnum {
	a
	b
	c
}

enum MyAnotherEnum {
	d
	e
	f
}

enum MyStrangeEnum {
	g
	h
	i
}

const ( // empty enum
	j = 1
)

fn main() {
	myenumvar := MyEnum.a
	myenumvar2 := MyAnotherEnum.d
	myenumvar3 := MyStrangeEnum.g
	myintvar := j
	return
}

j value must be 1, but in V version it's 0

A `wrapper` commands adds `C.` prefix for method that is not actually a C method in that case

Test file (for which wrapper was generated; The Machinery header api_registry,h) -> https://pastebin.com/NF6RjVaN

Error message

api_registry.v:94:2: error: struct embedding must be declared at the beginning of the struct body
   92 |     api_registry_version fn () Tm_version_t
   93 |     set fn (&i8, Tm_version_t, voidptr, u32)
   94 |     C.remove fn (voidptr)
      |     ~~~~~~~~
   95 |     get fn (&i8, Tm_version_t) voidptr
   96 |     get_optional fn (&voidptr, &i8, Tm_version_t)

Internal vfmt error while formatting file: ./api_registry.v.
Encountered a total of: 1 errors.

c2v wrap sql.h encountered error (typedef enum)

Hi, I am wrapping the odbc sql.h in linux using c2v but seems like the out file does not compile.

Repro steps: (I copied the sql.h from /usr/include to v repo)

bash:~/code/vlang/v/vlib/mssql$ ~/code/vlang/c2v/c2v wrap ./sql.h 
C to V translator 0.3.1
  translating ./sql.h         ... sql.v:101:15: error: unexpected token `(`, expecting name
   99 |     interval_type SQLINTERVAL
  100 |     interval_sign SQLSMALLINT
  101 |     intval Union (anonymous union at /usr/include/sqltypes.h
      |                  ^
  102 | }
  103 | type SQLBIGINT = int

Internal vfmt error while formatting file: ./sql.v.
Encountered a total of: 1 errors.
 took  1254 ms ; output .v file: ./sql.v
Translated   1 files in  1254 ms.

Problematic c code is this typedef enum in sqltypes.h

#if (ODBCVER >= 0x0300)
typedef enum
{
	SQL_IS_YEAR						= 1,
	SQL_IS_MONTH					= 2,
	SQL_IS_DAY						= 3,
	SQL_IS_HOUR						= 4,
	SQL_IS_MINUTE					= 5,
	SQL_IS_SECOND					= 6,
	SQL_IS_YEAR_TO_MONTH			= 7,
	SQL_IS_DAY_TO_HOUR				= 8,
	SQL_IS_DAY_TO_MINUTE			= 9,
	SQL_IS_DAY_TO_SECOND			= 10,
	SQL_IS_HOUR_TO_MINUTE			= 11,
	SQL_IS_HOUR_TO_SECOND			= 12,
	SQL_IS_MINUTE_TO_SECOND			= 13
} SQLINTERVAL;

#endif

Corresponding v code is :

struct SQL_INTERVAL_STRUCT { 
	interval_type SQLINTERVAL
	interval_sign SQLSMALLINT
	intval Union (anonymous union at /usr/include/sqltypes.h
}

c2v commit:

commit d7ac0c7b6830943c5441c94e17e62667a62e4934 (HEAD -> master, origin/master, origin/HEAD)
Author: Alexander Medvednikov <[email protected]>
Date:   Sun Jun 26 17:06:18 2022 +0300

    tests: remove unused files

v version:

V 0.2.4 28068e8

A `wrapper` translates enum parameter in a wrong way

Test code -> TheMachinery log.h - https://pastebin.com/rQMAfnFb

Error message

log.v:101:12: error: parameter name must not begin with upper case letter (`Enum`)
   99 |     add_logger fn (&Tm_logger_i)
  100 |     remove_logger fn (&Tm_logger_i)
  101 |     print fn (Enum tm_log_type, &i8)
      |               ~~~~
  102 |     C.printf fn (Enum tm_log_type, &i8, ...) int
  103 |     default_logger &Tm_logger_i

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.