1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
// +build !linux
// This file is systemdependent because not all versions
// of iconv have the iconvlist function.
package iconv
//#cgo darwin LDFLAGS: -liconv
//#cgo freebsd LDFLAGS: -liconv
//#cgo windows LDFLAGS: -liconv
//#include <stdlib.h>
//#include <string.h>
//#include <iconv.h>
//#include <errno.h>
//
//typedef struct nameList nameList;
//struct nameList {
// int n;
// char **names;
// nameList *next;
//};
//
//int
//addNames(unsigned int n, const char *const *names, void *data) {
// // we can't call back to Go because of the stack size issue,
// // so copy all the names.
// nameList *hd, *e;
// int i;
//
// hd = data;
// e = malloc(sizeof(nameList));
// e->n = n;
// e->names = malloc(sizeof(char*) * n);
// for(i = 0; i < n; i++){
// e->names[i] = strdup(names[i]);
// }
// e->next = hd->next;
// hd->next = e;
// return 0;
//}
//
//nameList *
//listNames(void) {
// nameList hd;
// hd.next = 0;
// iconvlist(addNames, &hd);
// return hd.next;
//}
import "C"
import (
"strings"
"sync"
"unsafe"
)
var getAliasesOnce sync.Once
var allAliases = map[string][]string{}
func aliases() map[string][]string {
getAliasesOnce.Do(getAliases)
return allAliases
}
func getAliases() {
var next *C.nameList
for p := C.listNames(); p != nil; p = next {
next = p.next
aliases := make([]string, p.n)
pnames := (*[1e9]*C.char)(unsafe.Pointer(p.names))
for i := range aliases {
aliases[i] = strings.ToLower(C.GoString(pnames[i]))
C.free(unsafe.Pointer(pnames[i]))
}
C.free(unsafe.Pointer(p.names))
C.free(unsafe.Pointer(p))
for _, alias := range aliases {
allAliases[alias] = aliases
}
}
}
|