MCPcopy Index your code
hub / github.com/elliotchance/c2go

github.com/elliotchance/c2go @v0.26.11

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.26.11 ↗ · + Follow
1,616 symbols 3,960 edges 354 files 863 documented · 53% updated 4mo agov0.26.11 · 2024-06-03★ 2,180181 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Build Status GitHub version Go Report Card codecov GitHub license Join the chat at https://gitter.im/c2goproject Twitter GoDoc

A tool for converting C to Go.

The goals of this project are:

  1. To create a generic tool that can convert C to Go.
  2. To be cross platform (linux and mac) and work against as many clang versions as possible (the clang AST API is not stable).
  3. To be a repeatable and predictable tool (rather than doing most of the work and you have to clean up the output to get it working.)
  4. To deliver quick and small version increments.
  5. The ultimate milestone is to be able to compile the SQLite3 source code and have it working without modification. This will be the 1.0.0 release.

Installation

c2go requires Go 1.9 or newer.

go get -u github.com/elliotchance/c2go

Usage

c2go transpile myfile.c

The c2go program processes a single C file and outputs the translated code in Go. Let's use an included example, prime.c:

#include <stdio.h>

int main()
{
   int n, c;

   printf("Enter a number\n");
   scanf("%d", &n);

   if ( n == 2 )
      printf("Prime number.\n");
   else
   {
       for ( c = 2 ; c <= n - 1 ; c++ )
       {
           if ( n % c == 0 )
              break;
       }
       if ( c != n )
          printf("Not prime.\n");
       else
          printf("Prime number.\n");
   }
   return 0;
}
c2go transpile prime.c
go run prime.go
Enter a number
23
Prime number.

prime.go looks like:

package main

import "unsafe"

import "github.com/elliotchance/c2go/noarch"

// ... lots of system types in Go removed for brevity.

var stdin *noarch.File
var stdout *noarch.File
var stderr *noarch.File

func main() {
    __init()
    var n int
    var c int
    noarch.Printf([]byte("Enter a number\n\x00"))
    noarch.Scanf([]byte("%d\x00"), (*[1]int)(unsafe.Pointer(&n))[:])
    if n == 2 {
        noarch.Printf([]byte("Prime number.\n\x00"))
    } else {
        for c = 2; c <= n-1; func() int {
            c += 1
            return c
        }() {
            if n%c == 0 {
                break
            }
        }
        if c != n {
            noarch.Printf([]byte("Not prime.\n\x00"))
        } else {
            noarch.Printf([]byte("Prime number.\n\x00"))
        }
    }
    return
}

func __init() {
    stdin = noarch.Stdin
    stdout = noarch.Stdout
    stderr = noarch.Stderr
}

How It Works

This is the process:

  1. The C code is preprocessed with clang. This generates a larger file (pp.c), but removes all the platform-specific directives and macros.

  2. pp.c is parsed with the clang AST and dumps it in a colourful text format that looks like this. Apart from just parsing the C and dumping an AST, the AST contains all of the resolved information that a compiler would need (such as data types). This means that the code must compile successfully under clang for the AST to also be usable.

  3. Since we have all the types in the AST it's just a matter of traversing the tree in a semi-intelligent way and producing Go. Easy, right!?

Testing

By default only unit tests are run with go test. You can also include the integration tests:

go test -tags=integration ./...

Integration tests in the form of complete C programs that can be found in the tests directory.

Integration tests work like this:

  1. Clang compiles the C to a binary as normal.
  2. c2go converts the C file to Go.
  3. The Go is built to produce another binary.
  4. Both binaries are executed and the output is compared. All C files will contain some output so the results can be verified.

Contributing

Contributing is done with pull requests. There is no help that is too small! :)

If you're looking for where to start I can suggest finding a simple C program (like the other examples) that does not successfully translate into Go.

Or, if you don't want to do that you can submit it as an issue so that it can be picked up by someone else.

Extension points exported contracts — how you extend this code

Node (Interface)
Node represents any node in the AST. [109 implementers]
ast/ast.go

Core symbols most depended-on inside this repo

NewPositionFromString
called by 311
ast/position.go
Children
called by 214
ast/ast.go
ParseAddress
called by 110
ast/ast.go
groupsFromRegex
called by 108
ast/ast.go
AddMessage
called by 92
program/program.go
NewIdent
called by 68
util/goast.go
GenerateWarningMessage
called by 67
program/warnings.go
atof
called by 55
ast/util.go

Shape

Function 893
Method 477
Struct 145
Class 89
Enum 6
TypeAlias 5
Interface 1

Languages

Go78%
C22%
C++1%

Modules by API surface

tests/struct.c79 symbols
noarch/stdio.go41 symbols
tests/function.c40 symbols
tests/stdio.c36 symbols
tests/array.c31 symbols
noarch/stdlib.go28 symbols
util/goast.go24 symbols
tests/switch.c22 symbols
tests/union.c18 symbols
program/program.go17 symbols
types/resolve.go15 symbols
noarch/util.go15 symbols

For agents

$ claude mcp add c2go \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page