Skip to content
This repository was archived by the owner on Oct 31, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9c1a054
FreeBSD compatibility
hxw Dec 3, 2015
3ac2803
Support for signed/unsigned 64 bit integer types
hxw Dec 3, 2015
6e53e8a
fix the cmake command
hxw Dec 9, 2015
01271ff
Switch to pkg-config for CFLAGS and LDFLAGS
draringi Feb 8, 2016
7e3476a
Merge commit '3ac2803785192cbe35714567a3587bee00995732'
draringi Feb 9, 2016
84cdc89
Removed Makefiles for building libucl
draringi Feb 9, 2016
a3dbaf4
Add information about the fork to the readme file
draringi Feb 11, 2016
3e04cbb
Modernize gitignore and travis tests
draringi Feb 11, 2016
269fd58
Fix permissions on travis ucl build script
draringi Feb 11, 2016
007a2de
Fix typo in travit-ucl script
draringi Feb 11, 2016
59fe18d
Add build status image to readme
draringi Feb 11, 2016
9fead9e
Updates to documentation
draringi Feb 11, 2016
917379e
More documentation updates, and readme updates as well
draringi Feb 11, 2016
39dbadb
Added missing parser flag UCL_PARSER_NO_IMPLICIT_ARRAYS and missing s…
draringi Feb 14, 2016
a2a3fc4
Added UCL Object construction functions
draringi Feb 14, 2016
60350a1
Added validation funtionality
draringi Feb 14, 2016
1b751f9
Formatting changes to better show documentation on godoc.org
draringi Feb 14, 2016
95eb8f1
Added initial variable support
draringi Feb 14, 2016
e2cc02d
Various fixes
draringi Feb 14, 2016
28c472f
Added simple sorter to fix random ordering issue in test TestObjectDe…
draringi Feb 14, 2016
3253cb9
Add ability to use native go file implementation to with libucl
draringi Feb 18, 2016
ab81987
convert to pkg-config
hxw Apr 27, 2017
ec4935c
Merge branch 'master' of https://github.com/draringi/go-libucl into d…
hxw Aug 10, 2017
2734a5f
Merge branch 'draringi-master'
hxw Aug 10, 2017
4489d45
fix the macro call
hxw Aug 11, 2017
9b16c12
change URLs, add note about macro fixes
hxw Aug 11, 2017
700172f
make into go module
hxw Mar 8, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
.vagrant/
vendor/
/libucl.dll
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so

# Folders
_obj
_test

# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out

*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*

_testmain.go

*.exe
*.test
*.prof
9 changes: 9 additions & 0 deletions .travis-ucl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
UCL_VERSION=0.7.3
set -ex
mkdir /tmp/libucl
cd /tmp/libucl
wget https://github.com/vstakhov/libucl/archive/$UCL_VERSION.tar.gz
tar xzf $UCL_VERSION.tar.gz
cd libucl-$UCL_VERSION && ./autogen.sh && ./configure --prefix=/usr --enable-urls --enable-signatures && make && sudo make install
rm -fr /tmp/libucl
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
sudo: required
language: go

go:
- 1.2.1
- tip

script: make test
before_install:
- ./.travis-ucl.sh
35 changes: 0 additions & 35 deletions Makefile

This file was deleted.

32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
# Libucl Library for Go
[![Build Status](https://travis-ci.org/bitmark-inc/go-libucl.svg?branch=master)](https://travis-ci.org/bitmark-inc/go-libucl)
[![GoDoc](https://godoc.org/github.com/bitmark-inc/go-libucl?status.svg)](https://godoc.org/github.com/bitmark-inc/go-libucl)

This version of go-libucl is forked from the[mitchellh version](https://github.com/mitchellh/go-libucl),
and [draring version](http://godoc.org/github.com/draringi/go-libucl)
with the goal of having a version with a focus on using the OS's copy of libucl, in a portable manner,
as well as improve the Documentation quality.
As such, it uses pkg-config to determine the location of libucl.

go-libucl is a [libucl](https://github.com/vstakhov/libucl) library for
[Go](http://golang.org). Rather than re-implement libucl in Go, this library
uses cgo to bind directly to libucl. This allows the libucl project to be
the central source of knowledge. This project works on Mac OS X, Linux, and
Windows.
the central source of knowledge. This project has been tested on Linux and FreeBSD.

**Warning:** This library is still under development and API compatibility
is not guaranteed. Additionally, it is not feature complete yet, though
it is certainly usable for real purposes (we do!).

## Installation
## Notes
* macro calling convention changed
* macro callback now gets paramters object in addion to body text

Because we vendor the source of libucl, you can go ahead and get it directly.
We'll keep up to date with libucl. The package name is `libucl`.
## Prerequisites
* libucl (This is a wrapper for this library)
* pkg-config (cgo uses this for locate where libucl is)

## Installation

```
$ go get github.com/mitchellh/go-libucl
$ go get github.com/bitmark-inc/go-libucl
```

Documentation is available on GoDoc: http://godoc.org/github.com/mitchellh/go-libucl

### Compiling Libucl

Libucl should compile easily and cleanly on POSIX systems.

On Windows, msys should be used. msys-regex needs to be compiled.
Documentation is available on GoDoc: http://godoc.org/github.com/bitmark-inc/go-libucl
62 changes: 44 additions & 18 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ func decode(name string, o *Object, result reflect.Value) error {
return decodeIntoInterface(name, o, result)
case reflect.Int:
return decodeIntoInt(name, o, result)
case reflect.Int64:
return decodeIntoInt(name, o, result)
case reflect.Uint:
return decodeIntoUint(name, o, result)
case reflect.Uint64:
return decodeIntoUint(name, o, result)
case reflect.Map:
return decodeIntoMap(name, o, result)
case reflect.Ptr:
Expand All @@ -37,8 +43,6 @@ func decode(name string, o *Object, result reflect.Value) error {
default:
return fmt.Errorf("%s: unsupported type: %s", name, result.Kind())
}

return nil
}

func decodeIntoBool(name string, o *Object, result reflect.Value) error {
Expand Down Expand Up @@ -73,6 +77,22 @@ func decodeIntoInt(name string, o *Object, result reflect.Value) error {
return nil
}

func decodeIntoUint(name string, o *Object, result reflect.Value) error {
switch o.Type() {
case ObjectTypeString:
i, err := strconv.ParseUint(o.ToString(), 0, result.Type().Bits())
if err == nil {
result.SetUint(i)
} else {
return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
}
default:
result.SetUint(o.ToUint())
}

return nil
}

func decodeIntoInterface(name string, o *Object, result reflect.Value) error {
var set reflect.Value
redecode := true
Expand Down Expand Up @@ -114,12 +134,13 @@ func decodeIntoInterface(name string, o *Object, result reflect.Value) error {
for o := outer.Next(); o != nil; o = outer.Next() {
m := make(map[string]interface{})
inner := o.Iterate(true)
inner_loop:
for o2 := inner.Next(); o2 != nil; o2 = inner.Next() {
var raw interface{}
err = decode(name, o2, reflect.Indirect(reflect.ValueOf(&raw)))
o2.Close()
if err != nil {
break
break inner_loop
}

m[o2.Key()] = raw
Expand All @@ -139,7 +160,7 @@ func decodeIntoInterface(name string, o *Object, result reflect.Value) error {
set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
default:
return fmt.Errorf(
"%s: unsupported type to interface: %s", name, o.Type())
"%s: unsupported type to interface: %v", name, o.Type())
}

if redecode {
Expand Down Expand Up @@ -269,7 +290,7 @@ func decodeIntoString(name string, o *Object, result reflect.Value) error {
case ObjectTypeInt:
result.SetString(strconv.FormatInt(o.ToInt(), 10))
default:
return fmt.Errorf("%s: unsupported type to string: %s", name, objType)
return fmt.Errorf("%s: unsupported type to string: %v", name, objType)
}

return nil
Expand All @@ -290,6 +311,7 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {
structs = structs[1:]

structType := structVal.Type()
struct_loop:
for i := 0; i < structType.NumField(); i++ {
fieldType := structType.Field(i)

Expand All @@ -305,16 +327,17 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {
// if specified in the tag.
squash := false
tagParts := strings.Split(fieldType.Tag.Get(tagName), ",")
tag_loop:
for _, tag := range tagParts[1:] {
if tag == "squash" {
squash = true
break
break tag_loop
}
}

if squash {
structs = append(structs, result.FieldByName(fieldType.Name))
continue
continue struct_loop
}
}

Expand All @@ -325,8 +348,9 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {

usedKeys := make(map[string]struct{})
decodedFields := make([]string, 0, len(fields))
decodedFieldsVal := make([]reflect.Value, 0)
unusedKeysVal := make([]reflect.Value, 0)
var decodedFieldsVal []reflect.Value
var unusedKeysVal []reflect.Value
field_loop:
for fieldType, field := range fields {
if !field.IsValid() {
// This should never happen
Expand All @@ -336,7 +360,7 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {
// If we can't set the field, then it is unexported or something,
// and we just continue onwards.
if !field.CanSet() {
continue
continue field_loop
}

fieldName := fieldType.Name
Expand All @@ -347,20 +371,20 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {
switch tagParts[1] {
case "decodedFields":
decodedFieldsVal = append(decodedFieldsVal, field)
continue
continue field_loop
case "key":
field.SetString(o.Key())
continue
continue field_loop
case "object":
// Increase the ref count
o.Ref()

// Sete the object
field.Set(reflect.ValueOf(o))
continue
continue field_loop
case "unusedKeys":
unusedKeysVal = append(unusedKeysVal, field)
continue
continue field_loop
}
}

Expand All @@ -373,9 +397,10 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {
// Do a slower search by iterating over each key and
// doing case-insensitive search.
iter := o.Iterate(true)
element_loop:
for elem = iter.Next(); elem != nil; elem = iter.Next() {
if strings.EqualFold(elem.Key(), fieldName) {
break
break element_loop
}

elem.Close()
Expand All @@ -384,7 +409,7 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {

if elem == nil {
// No key matching this field.
continue
continue field_loop
}
}

Expand All @@ -402,16 +427,17 @@ func decodeIntoStruct(name string, o *Object, result reflect.Value) error {
err = decode(fieldName, elem, field)
} else {
iter := elem.Iterate(false)
iteration_loop:
for {
obj := iter.Next()
if obj == nil {
break
break iteration_loop
}

err = decode(fieldName, obj, field)
obj.Close()
if err != nil {
break
break iteration_loop
}
}
iter.Close()
Expand Down
Loading