mv llcppg => github.com/goplus/llcppg
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
llcppg - Autogen tool for C/C++ libraries
|
||||
====
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
llcppg [config-file]
|
||||
```
|
||||
|
||||
If `config-file` is not specified, a `llcppg.cfg` file is used in current directory. The configuration file format is as follows:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inireader",
|
||||
"cflags": "$(pkg-config --cflags inireader)",
|
||||
"include": [
|
||||
"INIReader.h",
|
||||
"AnotherHeaderFile.h"
|
||||
],
|
||||
"libs": "$(pkg-config --libs inireader)",
|
||||
"trimPrefixes": ["Ini", "INI"]
|
||||
}
|
||||
```
|
||||
|
||||
## Design
|
||||
|
||||
See [llcppg Design](design.md).
|
||||
@@ -1,379 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ast
|
||||
|
||||
import "github.com/goplus/llgo/chore/llcppg/token"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
type Node interface {
|
||||
}
|
||||
|
||||
type Expr interface {
|
||||
Node
|
||||
exprNode()
|
||||
}
|
||||
|
||||
type Decl interface {
|
||||
Node
|
||||
declNode()
|
||||
}
|
||||
|
||||
type Stmt interface {
|
||||
Node
|
||||
stmtNode()
|
||||
}
|
||||
|
||||
type PPD interface { // preprocessing directive
|
||||
Node
|
||||
ppdNode()
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
type AccessSpecifier uint
|
||||
|
||||
const (
|
||||
Invalid AccessSpecifier = iota
|
||||
Public
|
||||
Protected
|
||||
Private
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Expressions (Types are also expressions)
|
||||
|
||||
type BasicLitKind uint
|
||||
|
||||
const (
|
||||
IntLit BasicLitKind = iota
|
||||
FloatLit
|
||||
CharLit
|
||||
StringLit
|
||||
)
|
||||
|
||||
type BasicLit struct {
|
||||
Kind BasicLitKind
|
||||
Value string
|
||||
}
|
||||
|
||||
func (*BasicLit) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type TypeKind uint
|
||||
|
||||
const (
|
||||
Void TypeKind = iota
|
||||
Bool
|
||||
Char
|
||||
Char16
|
||||
Char32
|
||||
WChar
|
||||
Int
|
||||
Int128
|
||||
Float
|
||||
Float16
|
||||
Float128
|
||||
Complex
|
||||
)
|
||||
|
||||
type TypeFlag uint
|
||||
|
||||
const (
|
||||
Signed TypeFlag = 1 << iota
|
||||
Unsigned
|
||||
Long
|
||||
LongLong
|
||||
Double
|
||||
Short
|
||||
)
|
||||
|
||||
// [signed/unsigned/short/long/long long/double] [int]/char/float/complex/bool
|
||||
type BuiltinType struct {
|
||||
Kind TypeKind
|
||||
Flags TypeFlag
|
||||
}
|
||||
|
||||
func (*BuiltinType) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// Name
|
||||
type Ident struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (*Ident) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type Tag int
|
||||
|
||||
const (
|
||||
Struct Tag = iota
|
||||
Union
|
||||
Enum
|
||||
Class
|
||||
)
|
||||
|
||||
// struct/union/enum/class (A::B::)Name
|
||||
type TagExpr struct {
|
||||
Tag Tag
|
||||
Name Expr // ScopingExpr, Ident
|
||||
}
|
||||
|
||||
func (*TagExpr) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// type a, ...
|
||||
type Variadic struct {
|
||||
}
|
||||
|
||||
func (*Variadic) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// (X)
|
||||
type ParenExpr struct {
|
||||
X Expr
|
||||
}
|
||||
|
||||
func (*ParenExpr) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// Parent::X
|
||||
type ScopingExpr struct {
|
||||
Parent Expr
|
||||
X Expr
|
||||
}
|
||||
|
||||
func (*ScopingExpr) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// X*
|
||||
type PointerType struct {
|
||||
X Expr
|
||||
}
|
||||
|
||||
func (*PointerType) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// X&
|
||||
type LvalueRefType struct {
|
||||
X Expr
|
||||
}
|
||||
|
||||
func (*LvalueRefType) exprNode() {}
|
||||
|
||||
// X&&
|
||||
type RvalueRefType struct {
|
||||
X Expr
|
||||
}
|
||||
|
||||
func (*RvalueRefType) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// Elt[Len]
|
||||
// Elt[]
|
||||
type ArrayType struct {
|
||||
Elt Expr
|
||||
Len Expr // optional
|
||||
}
|
||||
|
||||
func (*ArrayType) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type Comment struct {
|
||||
Text string // comment text (excluding '\n' for //-style comments)
|
||||
}
|
||||
|
||||
func (*Comment) exprNode() {}
|
||||
|
||||
type CommentGroup struct {
|
||||
List []*Comment // len(List) > 0
|
||||
}
|
||||
|
||||
func (*CommentGroup) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type Field struct {
|
||||
Doc *CommentGroup // associated documentation; or nil
|
||||
Type Expr // field/method/parameter type; or nil
|
||||
Names []*Ident // field/method/(type) parameter names; or nil
|
||||
Comment *CommentGroup // line comments; or nil
|
||||
Access AccessSpecifier // field access(Record Type); Struct Field default is Public,Class Field default is Private
|
||||
IsStatic bool // static field
|
||||
}
|
||||
|
||||
func (*Field) exprNode() {}
|
||||
|
||||
type FieldList struct {
|
||||
List []*Field // field list; or nil
|
||||
}
|
||||
|
||||
func (*FieldList) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// Ret (*)(Params)
|
||||
type FuncType struct {
|
||||
Params *FieldList
|
||||
Ret Expr
|
||||
}
|
||||
|
||||
func (*FuncType) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type RecordType struct {
|
||||
Tag Tag
|
||||
Fields *FieldList
|
||||
Methods []*FuncDecl
|
||||
}
|
||||
|
||||
func (*RecordType) exprNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// Template<Arg1, Arg2, ...>
|
||||
type InstantiationType struct {
|
||||
Template Expr
|
||||
Args *FieldList
|
||||
}
|
||||
|
||||
func (*InstantiationType) exprNode() {}
|
||||
|
||||
// =============================================================================
|
||||
// Declarations
|
||||
|
||||
type Location struct {
|
||||
File string
|
||||
}
|
||||
|
||||
type DeclBase struct {
|
||||
Doc *CommentGroup // associated documentation; or nil
|
||||
Loc *Location
|
||||
Parent Expr // namespace or class
|
||||
}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// typedef Type Name;
|
||||
type TypedefDecl struct {
|
||||
DeclBase
|
||||
Type Expr
|
||||
Name *Ident
|
||||
}
|
||||
|
||||
func (*TypedefDecl) declNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type EnumItem struct {
|
||||
Name *Ident
|
||||
Value Expr // optional
|
||||
}
|
||||
|
||||
func (*EnumItem) exprNode() {}
|
||||
|
||||
type EnumType struct {
|
||||
Items []*EnumItem
|
||||
}
|
||||
|
||||
func (*EnumType) exprNode() {}
|
||||
|
||||
// enum Name { Item1, Item2, ... };
|
||||
type EnumTypeDecl struct {
|
||||
DeclBase
|
||||
Name *Ident
|
||||
Type *EnumType
|
||||
}
|
||||
|
||||
func (*EnumTypeDecl) declNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// Ret Name(Params);
|
||||
type FuncDecl struct {
|
||||
DeclBase
|
||||
Name *Ident
|
||||
MangledName string // C: same as Name, C++: mangled
|
||||
Type *FuncType
|
||||
IsInline bool
|
||||
IsStatic bool
|
||||
|
||||
// Class method specific fields
|
||||
IsConst bool // const member function
|
||||
IsExplicit bool // explicit constructor
|
||||
IsConstructor bool
|
||||
IsDestructor bool
|
||||
IsVirtual bool
|
||||
IsOverride bool
|
||||
}
|
||||
|
||||
func (*FuncDecl) declNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
// struct/union/class Name { Field1, Field2, ... };
|
||||
type TypeDecl struct {
|
||||
DeclBase
|
||||
Name *Ident
|
||||
Type *RecordType
|
||||
}
|
||||
|
||||
func (*TypeDecl) declNode() {}
|
||||
|
||||
// =============================================================================
|
||||
// AST File
|
||||
|
||||
type Include struct {
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
func (*Include) ppdNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type Token struct {
|
||||
Token token.Token
|
||||
Lit string
|
||||
}
|
||||
|
||||
type Macro struct {
|
||||
Name string
|
||||
Tokens []*Token // Tokens[0].Lit is the macro name
|
||||
}
|
||||
|
||||
func (*Macro) ppdNode() {}
|
||||
|
||||
// ------------------------------------------------
|
||||
|
||||
type File struct {
|
||||
Decls []Decl `json:"decls"`
|
||||
Includes []*Include `json:"includes,omitempty"`
|
||||
Macros []*Macro `json:"macros,omitempty"`
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -1,85 +0,0 @@
|
||||
llcppg Design
|
||||
=====
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
llcppg [config-file]
|
||||
```
|
||||
|
||||
If `config-file` is not specified, a `llcppg.cfg` file is used in current directory. The configuration file format is as follows:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inih",
|
||||
"cflags": "$(pkg-config --cflags inireader)",
|
||||
"include": [
|
||||
"INIReader.h",
|
||||
"AnotherHeaderFile.h"
|
||||
],
|
||||
"libs": "$(pkg-config --libs inireader)",
|
||||
"trimPrefixes": ["Ini", "INI"],
|
||||
"cplusplus":true
|
||||
}
|
||||
```
|
||||
|
||||
## Steps
|
||||
|
||||
1. llcppsymg: Generate symbol table for a C/C++ library
|
||||
2. Manually modify the desired Go symbols in symbol table
|
||||
3. llcppsigfetch: Fetch information of C/C++ symbols
|
||||
4. gogensig: Generate a go package by information of symbols
|
||||
|
||||
|
||||
### llcppsymg
|
||||
|
||||
```sh
|
||||
llcppsymg config-file
|
||||
llcppsymg - # read config from stdin
|
||||
```
|
||||
|
||||
It generates a symbol table file named `llcppg.symb.json`. Its file format is as follows:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"mangle": "_ZN9INIReaderC1EPKcm",
|
||||
"c++": "INIReader::INIReader(char const*, unsigned long)",
|
||||
"go": "(*Reader).Init__0"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
### llcppsigfetch
|
||||
|
||||
```sh
|
||||
llcppsigfetch config-file
|
||||
llcppsigfetch - # read config from stdin
|
||||
```
|
||||
|
||||
It fetches information of C/C++ symbols and print to stdout. Its format is as follows:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"path": "/path/to/file.h",
|
||||
"doc": {
|
||||
"decls": [],
|
||||
"macros": [],
|
||||
"includes": [
|
||||
{
|
||||
"path": "incfile.h"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### gogensig
|
||||
|
||||
```sh
|
||||
gogensig ast-file
|
||||
gogensig - # read AST from stdin
|
||||
```
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/goplus/llgo/chore/llcppg/types"
|
||||
"github.com/goplus/llgo/xtool/env"
|
||||
)
|
||||
|
||||
func llcppsymg(conf []byte) error {
|
||||
cmd := exec.Command("llcppsymg", "-")
|
||||
cmd.Stdin = bytes.NewReader(conf)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func llcppsigfetch(conf []byte, out *io.PipeWriter) {
|
||||
cmd := exec.Command("llcppsigfetch", "-")
|
||||
cmd.Stdin = bytes.NewReader(conf)
|
||||
cmd.Stdout = out
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
check(err)
|
||||
out.Close()
|
||||
}
|
||||
|
||||
func gogensig(in io.Reader) error {
|
||||
cmd := exec.Command("gogensig", "-")
|
||||
cmd.Stdin = in
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfgFile := "llcppg.cfg"
|
||||
if len(os.Args) > 1 {
|
||||
cfgFile = os.Args[1]
|
||||
}
|
||||
if cfgFile == "-h" || cfgFile == "--help" {
|
||||
fmt.Fprintln(os.Stderr, "Usage: llcppg [config-file]")
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Open(cfgFile)
|
||||
check(err)
|
||||
defer f.Close()
|
||||
|
||||
var conf types.Config
|
||||
json.NewDecoder(f).Decode(&conf)
|
||||
conf.CFlags = env.ExpandEnv(conf.CFlags)
|
||||
conf.Libs = env.ExpandEnv(conf.Libs)
|
||||
|
||||
b, err := json.MarshalIndent(&conf, "", " ")
|
||||
check(err)
|
||||
|
||||
err = llcppsymg(b)
|
||||
check(err)
|
||||
|
||||
r, w := io.Pipe()
|
||||
go llcppsigfetch(b, w)
|
||||
|
||||
err = gogensig(r)
|
||||
check(err)
|
||||
}
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package token
|
||||
|
||||
type Token uint
|
||||
|
||||
const (
|
||||
ILLEGAL Token = iota
|
||||
|
||||
/**
|
||||
* A token that contains some kind of punctuation.
|
||||
*/
|
||||
PUNCT
|
||||
|
||||
/**
|
||||
* A language keyword.
|
||||
*/
|
||||
KEYWORD
|
||||
|
||||
/**
|
||||
* An identifier (that is not a keyword).
|
||||
*/
|
||||
IDENT
|
||||
|
||||
/**
|
||||
* A numeric, string, or character literal.
|
||||
*/
|
||||
LITERAL
|
||||
|
||||
/**
|
||||
* A comment.
|
||||
*/
|
||||
COMMENT
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package types
|
||||
|
||||
// Config represents a configuration for the llcppg tool.
|
||||
type Config struct {
|
||||
Name string `json:"name"`
|
||||
CFlags string `json:"cflags"`
|
||||
Libs string `json:"libs"`
|
||||
Include []string `json:"include"`
|
||||
TrimPrefixes []string `json:"trimPrefixes"`
|
||||
Cplusplus bool `json:"cplusplus"`
|
||||
}
|
||||
|
||||
type SymbolInfo struct {
|
||||
Mangle string `json:"mangle"` // C++ Symbol
|
||||
CPP string `json:"c++"` // C++ function name
|
||||
Go string `json:"go"` // Go function name
|
||||
}
|
||||
Reference in New Issue
Block a user