Example #1
0
func (this *binding_generator) generate(go_template string) {
	// this will fill the 'go_bindings' buffer
	repo := gi.DefaultRepository()
	for i, n := 0, repo.NumInfo(config.namespace); i < n; i++ {
		this.process_base_info(repo.Info(config.namespace, i))
	}

	t := must_template(go_template)
	t.Execute(this.out_go, map[string]interface{}{
		"g_object_ref_unref": g_object_ref_unref,
		"go_utils":           go_utils(true),
		"go_utils_no_cb":     go_utils(false),
		"go_bindings":        this.go_bindings.String(),
		"g_error_free":       g_error_free,
		"g_free":             g_free,
	})

	// write source/header preambles
	p := printer_to(this.out_h)
	p(c_header)

	// TODO: using config.pkg here is probably incorrect, we should use the
	// filename
	c_template.Execute(this.out_c, map[string]interface{}{
		"namespace": config.namespace,
		"package":   config.pkg,
	})
	p = printer_to(this.out_c)
	p("\n\n")

	// this will write the rest of .c/.h files
	this.c_forward_declarations()
}
func CForwardDeclarations() string {
	var out bytes.Buffer
	printf = PrinterTo(&out)

	repo := gi.DefaultRepository()
	deps := repo.Dependencies(Config.Namespace)
	for _, dep := range deps {
		depv := strings.Split(dep, "-")
		_, err := repo.Require(depv[0], depv[1], 0)
		if err != nil {
			panic(err)
		}

		for i, n := 0, repo.NumInfo(depv[0]); i < n; i++ {
			CForwardDeclaration10(repo.Info(depv[0], i))
			CForwardDeclaration30(repo.Info(depv[0], i))
		}
	}

	for i, n := 0, repo.NumInfo(Config.Namespace); i < n; i++ {
		CForwardDeclaration10(repo.Info(Config.Namespace, i))
	}
	for i, n := 0, repo.NumInfo(Config.Namespace); i < n; i++ {
		CForwardDeclaration20(repo.Info(Config.Namespace, i))
	}
	for i, n := 0, repo.NumInfo(Config.Namespace); i < n; i++ {
		CForwardDeclaration30(repo.Info(Config.Namespace, i))
	}

	return out.String()
}
Example #3
0
func (this *binding_generator) c_forward_declarations() {
	repo := gi.DefaultRepository()
	deps := repo.Dependencies(config.namespace)
	for _, dep := range deps {
		depv := strings.Split(dep, "-")
		_, err := repo.Require(depv[0], depv[1], 0)
		if err != nil {
			panic(err)
		}

		for i, n := 0, repo.NumInfo(depv[0]); i < n; i++ {
			this.c_forward_declaration10(repo.Info(depv[0], i))
			this.c_forward_declaration30(repo.Info(depv[0], i))
		}
	}

	for i, n := 0, repo.NumInfo(config.namespace); i < n; i++ {
		this.c_forward_declaration10(repo.Info(config.namespace, i))
	}
	for i, n := 0, repo.NumInfo(config.namespace); i < n; i++ {
		this.c_forward_declaration20(repo.Info(config.namespace, i))
	}
	for i, n := 0, repo.NumInfo(config.namespace); i < n; i++ {
		this.c_forward_declaration30(repo.Info(config.namespace, i))
	}
}
Example #4
0
func GoToCgoForInterface(bi *gi.BaseInfo, arg0, arg1 string, flags ConvFlags) string {
	var out bytes.Buffer
	printf := PrinterTo(&out)

	switch bi.Type() {
	case gi.INFO_TYPE_OBJECT:
		prefix := gi.DefaultRepository().CPrefix(bi.Namespace())
		printf("if %s != nil {\n", arg0)
		printf("\t%s = %s.InheritedFrom%s%s()\n",
			arg1, arg0, prefix, bi.Name())
		printf("}")
	case gi.INFO_TYPE_ENUM, gi.INFO_TYPE_FLAGS:
		ctype := CgoTypeForInterface(bi, TypeNone)
		printf("%s = %s(%s)", arg1, ctype, arg0)
	case gi.INFO_TYPE_INTERFACE:
		prefix := gi.DefaultRepository().CPrefix(bi.Namespace())
		printf("if %s != nil {\n", arg0)
		printf("\t%s = %s.Implements%s%s()",
			arg1, arg0, prefix, bi.Name())
		printf("}")
	case gi.INFO_TYPE_STRUCT:
		ns := bi.Namespace()
		if ns == "cairo" {
			printf(CairoGoToCgoForInterface(bi, arg0, arg1, flags))
			break
		}

		fullnm := strings.ToLower(ns) + "." + bi.Name()
		if _, ok := GConfig.Sys.DisguisedTypes[fullnm]; ok {
			flags &^= ConvPointer
		}
		ctype := CgoTypeForInterface(bi, TypeNone)
		if flags&ConvPointer != 0 {
			printf("%s = (*%s)(unsafe.Pointer(%s))",
				arg1, ctype, arg0)
		} else {
			printf("%s = *(*%s)(unsafe.Pointer(&%s))",
				arg1, ctype, arg0)
		}
	case gi.INFO_TYPE_CALLBACK:
		printf("if %s != nil {\n", arg0)
		printf("\t%s = unsafe.Pointer(&%s)", arg1, arg0)
		printf("}")
	}

	return out.String()
}
func GoBindings() string {
	var out bytes.Buffer
	printf = PrinterTo(&out)

	repo := gi.DefaultRepository()
	for i, n := 0, repo.NumInfo(Config.Namespace); i < n; i++ {
		ProcessBaseInfo(repo.Info(Config.Namespace, i))
	}

	return out.String()
}
Example #6
0
func (this *binding_generator) process_object_info(oi *gi.ObjectInfo) {
	p := printer_to(&this.go_bindings)

	parent := "C unsafe.Pointer"
	parentlike := ""
	if p := oi.Parent(); p != nil {
		parent = ""
		if ns := p.Namespace(); ns != config.namespace {
			parent += strings.ToLower(ns) + "."
		}
		parent += p.Name()
		parentlike = parent + "Like"
	}

	// interface that this class and its subclasses implement
	cprefix := gi.DefaultRepository().CPrefix(config.namespace)
	name := oi.Name()
	cgotype := cgo_type_for_interface(gi.ToBaseInfo(oi), type_pointer)

	var interfaces bytes.Buffer
	pi := printer_to(&interfaces)
	for i, n := 0, oi.NumInterface(); i < n; i++ {
		ii := oi.Interface(i)
		name := ii.Name()
		ns := ii.Namespace()
		if i != 0 {
			pi("\n\t")
		}
		if ns != config.namespace {
			pi("%s.", strings.ToLower(ns))
		}
		pi("%sImpl", name)
	}

	p("%s\n", execute_template(object_template, map[string]string{
		"name":       name,
		"cprefix":    cprefix,
		"cgotype":    cgotype,
		"parent":     parent,
		"parentlike": parentlike,
		"typeinit":   oi.TypeInit(),
		"gobjectns":  config.gns,
		"interfaces": interfaces.String(),
	}))

	for i, n := 0, oi.NumMethod(); i < n; i++ {
		meth := oi.Method(i)
		if config.is_method_blacklisted(name, meth.Name()) {
			p("// blacklisted: %s.%s (method)\n", name, meth.Name())
			continue
		}
		this.process_function_info(meth)
	}
}
func ProcessObjectInfo(oi *gi.ObjectInfo) {
	parent := "C unsafe.Pointer"
	parentlike := ""
	if p := oi.Parent(); p != nil {
		parent = ""
		if ns := p.Namespace(); ns != Config.Namespace {
			parent += strings.ToLower(ns) + "."
		}
		parent += p.Name()
		parentlike = parent + "Like"
	}

	// interface that this class and its subclasses implement
	cprefix := gi.DefaultRepository().CPrefix(Config.Namespace)
	name := oi.Name()
	cgotype := CgoTypeForInterface(gi.ToBaseInfo(oi), TypePointer)

	var interfaces bytes.Buffer
	for i, n := 0, oi.NumInterface(); i < n; i++ {
		ii := oi.Interface(i)
		name := ii.Name()
		ns := ii.Namespace()
		if i != 0 {
			interfaces.WriteString("\n\t")
		}
		if ns != Config.Namespace {
			fmt.Fprintf(&interfaces, "%s.", strings.ToLower(ns))
		}
		fmt.Fprintf(&interfaces, "%sImpl", name)
	}

	printf("%s\n", ExecuteTemplate(ObjectTemplate, map[string]string{
		"name":       name,
		"cprefix":    cprefix,
		"cgotype":    cgotype,
		"parent":     parent,
		"parentlike": parentlike,
		"typeinit":   oi.TypeInit(),
		"gobjectns":  Config.Sys.GNS,
		"interfaces": interfaces.String(),
	}))

	for i, n := 0, oi.NumMethod(); i < n; i++ {
		meth := oi.Method(i)
		if IsMethodBlacklisted(name, meth.Name()) {
			printf("// blacklisted: %s.%s (method)\n", name, meth.Name())
			continue
		}
		ProcessFunctionInfo(meth, gi.ToBaseInfo(oi))
	}
}
Example #8
0
func c_type_for_interface(bi *gi.BaseInfo, flags type_flags) string {
	var out bytes.Buffer

	ns := bi.Namespace()
	nm := bi.Name()
	fullnm := strings.ToLower(ns) + "." + nm
	out.WriteString(gi.DefaultRepository().CPrefix(ns))
	out.WriteString(bi.Name())

	if flags&type_pointer != 0 && !config.is_disguised(fullnm) {
		out.WriteString("*")
	}

	return out.String()
}
Example #9
0
func CTypeForInterface(bi *gi.BaseInfo, flags TypeFlags) string {
	var out bytes.Buffer

	ns := bi.Namespace()
	nm := bi.Name()
	fullnm := strings.ToLower(ns) + "." + nm
	out.WriteString(gi.DefaultRepository().CPrefix(ns))
	out.WriteString(bi.Name())

	_, disguised := GConfig.Sys.DisguisedTypes[fullnm]
	if flags&TypePointer != 0 && !disguised {
		out.WriteString("*")
	}

	return out.String()
}
Example #10
0
func main() {
	sysconfig_path := flag.String("config", "", "specify global config file")
	output_dir := flag.String("o", "", "override output directory")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [flags] <dir>\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		return
	}

	// figure in/out paths
	in_dir, in_base := filepath.Split(flag.Arg(0))
	in_path := flag.Arg(0)

	out_dir := in_dir
	if *output_dir != "" {
		out_dir = *output_dir
	}
	out_base := filepath.Join(out_dir, in_base[:len(in_base)-6])

	// parse system config file
	if *sysconfig_path != "" {
		config.load_sys(*sysconfig_path)
	}

	// parse local config
	config.load(filepath.Join(in_dir, "config.json"))

	// load namespace
	_, err := gi.DefaultRepository().Require(config.namespace, config.version, 0)
	panic_if_error(err)

	// load go template
	go_template, err := ioutil.ReadFile(in_path)
	panic_if_error(err)

	// generate bindings
	bg := new_binding_generator(out_base)
	defer bg.release()
	bg.generate(string(go_template))
}
Example #11
0
func cgo_type_for_interface(bi *gi.BaseInfo, flags type_flags) string {
	var out bytes.Buffer

	switch bi.Type() {
	case gi.INFO_TYPE_CALLBACK:
		out.WriteString("unsafe.Pointer")
	default:
		ns := bi.Namespace()
		nm := bi.Name()
		fullnm := strings.ToLower(ns) + "." + nm

		if flags&type_pointer != 0 && !config.is_disguised(fullnm) {
			out.WriteString("*")
		}

		out.WriteString("C.")
		out.WriteString(gi.DefaultRepository().CPrefix(ns))
		out.WriteString(bi.Name())
	}
	return out.String()
}
Example #12
0
func ProcessInterfaceInfo(ii *gi.InterfaceInfo) {
	name := ii.Name()
	cprefix := gi.DefaultRepository().CPrefix(ii.Namespace())
	cgotype := CgoTypeForInterface(gi.ToBaseInfo(ii), TypePointer)

	printf("%s\n", ExecuteTemplate(InterfaceTemplate, map[string]string{
		"name":      name,
		"cprefix":   cprefix,
		"cgotype":   cgotype,
		"typeinit":  ii.TypeInit(),
		"gobjectns": Config.Sys.GNS,
	}))

	for i, n := 0, ii.NumMethod(); i < n; i++ {
		meth := ii.Method(i)
		if IsMethodBlacklisted(name, meth.Name()) {
			printf("// blacklisted: %s.%s (method)\n", name, meth.Name())
			continue
		}
		ProcessFunctionInfo(meth, gi.ToBaseInfo(ii))
	}
}
Example #13
0
func CgoTypeForInterface(bi *gi.BaseInfo, flags TypeFlags) string {
	var out bytes.Buffer

	switch bi.Type() {
	case gi.INFO_TYPE_CALLBACK:
		out.WriteString("unsafe.Pointer")
	default:
		ns := bi.Namespace()
		nm := bi.Name()
		fullnm := strings.ToLower(ns) + "." + nm

		_, disguised := GConfig.Sys.DisguisedTypes[fullnm]
		if flags&TypePointer != 0 && !disguised {
			out.WriteString("*")
		}

		out.WriteString("C.")
		out.WriteString(gi.DefaultRepository().CPrefix(ns))
		out.WriteString(bi.Name())
	}
	return out.String()
}
Example #14
0
func (this *binding_generator) process_interface_info(ii *gi.InterfaceInfo) {
	p := printer_to(&this.go_bindings)

	name := ii.Name()
	cprefix := gi.DefaultRepository().CPrefix(ii.Namespace())
	cgotype := cgo_type_for_interface(gi.ToBaseInfo(ii), type_pointer)

	p("%s\n", execute_template(interface_template, map[string]string{
		"name":      name,
		"cprefix":   cprefix,
		"cgotype":   cgotype,
		"typeinit":  ii.TypeInit(),
		"gobjectns": config.gns,
	}))

	for i, n := 0, ii.NumMethod(); i < n; i++ {
		meth := ii.Method(i)
		if config.is_method_blacklisted(name, meth.Name()) {
			p("// blacklisted: %s.%s (method)\n", name, meth.Name())
			continue
		}
		this.process_function_info(meth)
	}
}
Example #15
0
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [flags] <dir>\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()

	if flag.NArg() != 1 {
		flag.Usage()
		return
	}

	// parse global config
	if *GConfigPath != "" {
		err := ParseJSONWithComments(*GConfigPath, &GConfig)
		if err != nil {
			panic(err)
		}

		GConfig.Sys.DisguisedTypes = ListToMap(GConfig.DisguisedTypes)
	}

	// parse config
	configPath := filepath.Join(flag.Arg(0), "config.json")
	err := ParseJSONWithComments(configPath, &Config)
	if err != nil {
		panic(err)
	}

	repo := gi.DefaultRepository()

	// load namespace
	_, err = repo.Require(Config.Namespace, Config.Version, 0)
	if err != nil {
		panic(err)
	}

	// setup some of the Sys vars
	Config.Sys.Package = strings.ToLower(Config.Namespace)
	Config.Sys.Outdir = filepath.Clean(flag.Arg(0))
	Config.Sys.Whitelist = MapListToMapMap(Config.Whitelist)
	Config.Sys.Blacklist = MapListToMapMap(Config.Blacklist)
	Config.Sys.MethodWhitelist = MapListToMapMap(Config.MethodWhitelist)
	Config.Sys.MethodBlacklist = MapListToMapMap(Config.MethodBlacklist)

	if Config.Namespace != "GObject" {
		Config.Sys.GNS = "gobject."
	}

	// prepare main output
	filename := filepath.Join(Config.Sys.Outdir,
		strings.ToLower(Config.Namespace)+".go")
	file, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	Config.Sys.Out = bufio.NewWriter(file)

	tpl, err := ioutil.ReadFile(filename + ".in")
	if err != nil {
		panic(err)
	}

	ProcessTemplate(string(tpl))

	Config.Sys.Out.Flush()
}