├── README.md ├── .gitignore ├── Makefile ├── LICENSE └── var_dump ├── print.go └── print_test.go /README.md: -------------------------------------------------------------------------------- 1 | Go 2 | == 3 | 4 | Imos' Go Library 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | libraries = var_dump 2 | 3 | .PHONY: all/% format/% test/% 4 | 5 | all: $(foreach library,$(libraries),all/$(library)) 6 | 7 | all/%: % 8 | cd "$*"; go build 9 | 10 | test: $(foreach library,$(libraries),test/$(library)) 11 | 12 | test/%: % 13 | cd "$*"; go test 14 | 15 | format: $(foreach library,$(libraries),format/$(library)) 16 | 17 | format/%: % 18 | cd "$*"; gofmt -d=true -tabs=false -tabwidth=2 -w=true . 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Kentaro IMAJO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /var_dump/print.go: -------------------------------------------------------------------------------- 1 | package var_dump 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func exportReflectValue( 9 | field_value reflect.Value, indent string, 10 | loop_detector map[uintptr]bool) string { 11 | defer func() { recover() }() 12 | var_type := field_value.Kind().String() 13 | inside_indent := indent + " " 14 | switch field_value.Kind() { 15 | case reflect.Bool: 16 | return fmt.Sprintf("%s(%t)", var_type, field_value.Bool()) 17 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 18 | return fmt.Sprintf("%s(%d)", var_type, field_value.Int()) 19 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, 20 | reflect.Uint64, reflect.Uintptr: 21 | return fmt.Sprintf("%s(%d)", var_type, field_value.Uint()) 22 | case reflect.Float32: 23 | return fmt.Sprintf("%s(%g)", var_type, float32(field_value.Float())) 24 | case reflect.Float64: 25 | return fmt.Sprintf("%s(%g)", var_type, field_value.Float()) 26 | case reflect.Complex64: 27 | return fmt.Sprintf("%s%g", var_type, complex64(field_value.Complex())) 28 | case reflect.Complex128: 29 | return fmt.Sprintf("%s%g", var_type, field_value.Complex()) 30 | case reflect.Ptr: 31 | if field_value.IsNil() { 32 | return fmt.Sprintf("(%s)nil", field_value.Type().String()) 33 | } 34 | pointer := field_value.Pointer() 35 | if _, present := loop_detector[pointer]; present { 36 | return "" 37 | } 38 | loop_detector[pointer] = true 39 | defer delete(loop_detector, field_value.Pointer()) 40 | return "&" + exportReflectValue(field_value.Elem(), indent, loop_detector) 41 | case reflect.Array, reflect.Slice: 42 | output := fmt.Sprintf("%s{", field_value.Type()) 43 | if field_value.Len() > 0 { 44 | output += "\n" 45 | for i := 0; i < field_value.Len(); i++ { 46 | output += inside_indent 47 | // output += exportReflectValue(field_value.Index(i), inside_indent) 48 | output += exportReflectValue( 49 | field_value.Index(i), inside_indent, loop_detector) 50 | output += ",\n" 51 | } 52 | output += indent 53 | } 54 | output += "}" 55 | return output 56 | case reflect.Map: 57 | output := fmt.Sprintf("%s{", field_value.Type()) 58 | keys := field_value.MapKeys() 59 | if len(keys) > 0 { 60 | output += "\n" 61 | for _, key := range keys { 62 | output += inside_indent 63 | output += exportReflectValue(key, inside_indent, loop_detector) 64 | output += ": " 65 | output += exportReflectValue( 66 | field_value.MapIndex(key), inside_indent, loop_detector) 67 | output += ",\n" 68 | } 69 | output += indent 70 | } 71 | output += "}" 72 | return output 73 | case reflect.String: 74 | return fmt.Sprintf("%s(%#v)", var_type, field_value.String()) 75 | case reflect.UnsafePointer: 76 | return fmt.Sprintf("unsafe.Pointer(%#v)", field_value.Pointer()) 77 | case reflect.Struct: 78 | output := fmt.Sprintf("%s{\n", field_value.Type()) 79 | for i := 0; i < field_value.NumField(); i++ { 80 | output += inside_indent + field_value.Type().Field(i).Name + ": " 81 | output += exportReflectValue( 82 | field_value.Field(i), inside_indent, loop_detector) 83 | output += "," 84 | if field_value.Type().Field(i).Tag != "" { 85 | output += fmt.Sprintf(" // Tag: %#v", field_value.Type().Field(i).Tag) 86 | } 87 | output += "\n" 88 | } 89 | output += indent + "}" 90 | return output 91 | case reflect.Interface: 92 | return exportReflectValue( 93 | reflect.ValueOf(field_value.Interface()), indent, loop_detector) 94 | case reflect.Chan: 95 | return fmt.Sprintf("(%s)%#v", field_value.Type(), field_value.Pointer()) 96 | case reflect.Invalid: 97 | return "" 98 | default: 99 | return "<" + var_type + " is not supported>" 100 | } 101 | } 102 | 103 | func Export(data interface{}) string { 104 | return exportReflectValue(reflect.ValueOf(data), "", map[uintptr]bool{}) 105 | } 106 | 107 | func Print(data interface{}) { 108 | fmt.Println(Export(data)) 109 | } 110 | -------------------------------------------------------------------------------- /var_dump/print_test.go: -------------------------------------------------------------------------------- 1 | package var_dump 2 | 3 | import ( 4 | "testing" 5 | "unsafe" 6 | ) 7 | 8 | func TestExportBool(t *testing.T) { 9 | value := true 10 | actual := Export(value) 11 | expected := "bool(true)" 12 | if actual != expected { 13 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 14 | } 15 | } 16 | 17 | func TestExportInt(t *testing.T) { 18 | value := int(123) 19 | actual := Export(value) 20 | expected := "int(123)" 21 | if actual != expected { 22 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 23 | } 24 | } 25 | 26 | func TestExportInt8(t *testing.T) { 27 | value := int8(123) 28 | actual := Export(value) 29 | expected := "int8(123)" 30 | if actual != expected { 31 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 32 | } 33 | } 34 | 35 | func TestExportInt16(t *testing.T) { 36 | value := int16(123) 37 | actual := Export(value) 38 | expected := "int16(123)" 39 | if actual != expected { 40 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 41 | } 42 | } 43 | 44 | func TestExportInt32(t *testing.T) { 45 | value := int32(123) 46 | actual := Export(value) 47 | expected := "int32(123)" 48 | if actual != expected { 49 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 50 | } 51 | } 52 | 53 | func TestExportInt64(t *testing.T) { 54 | value := int64(123) 55 | actual := Export(value) 56 | expected := "int64(123)" 57 | if actual != expected { 58 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 59 | } 60 | } 61 | 62 | func TestExportUint(t *testing.T) { 63 | value := uint(123) 64 | actual := Export(value) 65 | expected := "uint(123)" 66 | if actual != expected { 67 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 68 | } 69 | } 70 | 71 | func TestExportUint8(t *testing.T) { 72 | value := uint8(123) 73 | actual := Export(value) 74 | expected := "uint8(123)" 75 | if actual != expected { 76 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 77 | } 78 | } 79 | 80 | func TestExportUint16(t *testing.T) { 81 | value := uint16(123) 82 | actual := Export(value) 83 | expected := "uint16(123)" 84 | if actual != expected { 85 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 86 | } 87 | } 88 | 89 | func TestExportUint32(t *testing.T) { 90 | value := uint32(123) 91 | actual := Export(value) 92 | expected := "uint32(123)" 93 | if actual != expected { 94 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 95 | } 96 | } 97 | 98 | func TestExportUint64(t *testing.T) { 99 | value := uint64(123) 100 | actual := Export(value) 101 | expected := "uint64(123)" 102 | if actual != expected { 103 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 104 | } 105 | } 106 | 107 | func TestExportFloat32(t *testing.T) { 108 | value := float32(1.23) 109 | actual := Export(value) 110 | expected := "float32(1.23)" 111 | if actual != expected { 112 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 113 | } 114 | } 115 | 116 | func TestExportFloat64(t *testing.T) { 117 | value := float64(1.23) 118 | actual := Export(value) 119 | expected := "float64(1.23)" 120 | if actual != expected { 121 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 122 | } 123 | } 124 | 125 | func TestExportComplex64(t *testing.T) { 126 | value := complex64(1.23 + 4.56i) 127 | actual := Export(value) 128 | expected := "complex64(1.23+4.56i)" 129 | if actual != expected { 130 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 131 | } 132 | } 133 | 134 | func TestExportComplex128(t *testing.T) { 135 | value := complex128(1.23 + 4.56i) 136 | actual := Export(value) 137 | expected := "complex128(1.23+4.56i)" 138 | if actual != expected { 139 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 140 | } 141 | } 142 | 143 | func TestExportString(t *testing.T) { 144 | value := "foo" 145 | actual := Export(value) 146 | expected := "string(\"foo\")" 147 | if actual != expected { 148 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 149 | } 150 | } 151 | 152 | func TestExportArray(t *testing.T) { 153 | value := [...]int{1, 2, 3} 154 | actual := Export(value) 155 | expected := "" + // for gofmt 156 | "[3]int{\n" + 157 | " int(1),\n" + 158 | " int(2),\n" + 159 | " int(3),\n" + 160 | "}" 161 | if actual != expected { 162 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 163 | } 164 | } 165 | 166 | func TestExportSlice(t *testing.T) { 167 | value := []int{1, 2, 3} 168 | actual := Export(value) 169 | expected := "" + // for gofmt 170 | "[]int{\n" + 171 | " int(1),\n" + 172 | " int(2),\n" + 173 | " int(3),\n" + 174 | "}" 175 | if actual != expected { 176 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 177 | } 178 | } 179 | 180 | func TestExportMap(t *testing.T) { 181 | value := map[string]int{"C": 1, "B": 2, "A": 3} 182 | actual := Export(value) 183 | expected := "" + // for gofmt 184 | "map[string]int{\n" + 185 | " string(\"C\"): int(1),\n" + 186 | " string(\"B\"): int(2),\n" + 187 | " string(\"A\"): int(3),\n" + 188 | "}" 189 | if actual != expected { 190 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 191 | } 192 | } 193 | 194 | func TestExportPtr(t *testing.T) { 195 | base_value := "foo" 196 | value := &base_value 197 | actual := Export(value) 198 | expected := "&string(\"foo\")" 199 | if actual != expected { 200 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 201 | } 202 | } 203 | 204 | func TestExportNilPtr(t *testing.T) { 205 | var value *string 206 | actual := Export(value) 207 | expected := "(*string)nil" 208 | if actual != expected { 209 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 210 | } 211 | } 212 | 213 | func FunctionExample() {} 214 | 215 | func TestExportFunction(t *testing.T) { 216 | value := FunctionExample 217 | actual := Export(value) 218 | expected := "" 219 | if actual != expected { 220 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 221 | } 222 | } 223 | 224 | func TestExportChan(t *testing.T) { 225 | var value chan int 226 | actual := Export(value) 227 | expected := "(chan int)0x0" 228 | if actual != expected { 229 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 230 | } 231 | } 232 | 233 | func TestExportUnsafePointer(t *testing.T) { 234 | value := unsafe.Pointer(uintptr(0x1234)) 235 | actual := Export(value) 236 | expected := "unsafe.Pointer(0x1234)" 237 | if actual != expected { 238 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 239 | } 240 | } 241 | 242 | type InterfaceExample interface { 243 | PublicMethod() 244 | } 245 | 246 | type StructExampleChild struct { 247 | ChildPublicValue string 248 | child_private_value int 249 | } 250 | 251 | type StructExample struct { 252 | PublicValue string 253 | Self *StructExample 254 | private_value int 255 | child StructExampleChild 256 | } 257 | 258 | func (s StructExample) PublicMethod() {} 259 | func (s StructExample) private_method() {} 260 | 261 | func TestExportInterfaceAndStruct(t *testing.T) { 262 | value := []InterfaceExample{ 263 | StructExample{ 264 | PublicValue: "foo", 265 | private_value: 12345, 266 | child: StructExampleChild{ 267 | ChildPublicValue: "bar", 268 | child_private_value: 67890, 269 | }, 270 | Self: &StructExample{ 271 | PublicValue: "hoge", 272 | private_value: 11111, 273 | child: StructExampleChild{ 274 | ChildPublicValue: "piyo", 275 | child_private_value: 22222, 276 | }, 277 | }, 278 | }, 279 | } 280 | value[0].(StructExample).Self.Self = value[0].(StructExample).Self 281 | actual := Export(value) 282 | expected := "" + // for gofmt 283 | "[]var_dump.InterfaceExample{\n" + 284 | " var_dump.StructExample{\n" + 285 | " PublicValue: string(\"foo\"),\n" + 286 | " Self: &var_dump.StructExample{\n" + 287 | " PublicValue: string(\"hoge\"),\n" + 288 | " Self: ,\n" + 289 | " private_value: int(11111),\n" + 290 | " child: var_dump.StructExampleChild{\n" + 291 | " ChildPublicValue: string(\"piyo\"),\n" + 292 | " child_private_value: int(22222),\n" + 293 | " },\n" + 294 | " },\n" + 295 | " private_value: int(12345),\n" + 296 | " child: var_dump.StructExampleChild{\n" + 297 | " ChildPublicValue: string(\"bar\"),\n" + 298 | " child_private_value: int(67890),\n" + 299 | " },\n" + 300 | " },\n" + 301 | "}" 302 | if actual != expected { 303 | t.Errorf("Wrong format: %#v vs %#v", expected, actual) 304 | } 305 | } 306 | --------------------------------------------------------------------------------