diff options
author | Tamal Saha <tamal@appscode.com> | 2019-08-23 09:40:30 -0700 |
---|---|---|
committer | techknowlogick <techknowlogick@gitea.io> | 2019-08-23 12:40:29 -0400 |
commit | 171b3598778a1ecd0a921c71ed6755bfef68f7f0 (patch) | |
tree | 02857629ef9e8e26ee0ee559153f803f77b588b7 /vendor/github.com/unknwon/i18n | |
parent | ca6fb004ac50fc924861112403895d637c6a2d1d (diff) | |
download | gitea-171b3598778a1ecd0a921c71ed6755bfef68f7f0.tar.gz gitea-171b3598778a1ecd0a921c71ed6755bfef68f7f0.zip |
Use gitea forked macaron (#7933)
Signed-off-by: Tamal Saha <tamal@appscode.com>
Diffstat (limited to 'vendor/github.com/unknwon/i18n')
-rw-r--r-- | vendor/github.com/unknwon/i18n/.gitignore | 22 | ||||
-rw-r--r-- | vendor/github.com/unknwon/i18n/LICENSE | 191 | ||||
-rw-r--r-- | vendor/github.com/unknwon/i18n/Makefile | 12 | ||||
-rw-r--r-- | vendor/github.com/unknwon/i18n/README.md | 135 | ||||
-rw-r--r-- | vendor/github.com/unknwon/i18n/go.mod | 9 | ||||
-rw-r--r-- | vendor/github.com/unknwon/i18n/go.sum | 21 | ||||
-rw-r--r-- | vendor/github.com/unknwon/i18n/i18n.go | 231 |
7 files changed, 621 insertions, 0 deletions
diff --git a/vendor/github.com/unknwon/i18n/.gitignore b/vendor/github.com/unknwon/i18n/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/unknwon/i18n/.gitignore @@ -0,0 +1,22 @@ +# 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 diff --git a/vendor/github.com/unknwon/i18n/LICENSE b/vendor/github.com/unknwon/i18n/LICENSE new file mode 100644 index 0000000000..8405e89a0b --- /dev/null +++ b/vendor/github.com/unknwon/i18n/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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.
\ No newline at end of file diff --git a/vendor/github.com/unknwon/i18n/Makefile b/vendor/github.com/unknwon/i18n/Makefile new file mode 100644 index 0000000000..8ff1ac4399 --- /dev/null +++ b/vendor/github.com/unknwon/i18n/Makefile @@ -0,0 +1,12 @@ +.PHONY: build test bench vet + +build: vet bench + +test: + go test -v -cover + +bench: + go test -v -cover -test.bench=. -test.benchmem + +vet: + go vet
\ No newline at end of file diff --git a/vendor/github.com/unknwon/i18n/README.md b/vendor/github.com/unknwon/i18n/README.md new file mode 100644 index 0000000000..4e3bff7526 --- /dev/null +++ b/vendor/github.com/unknwon/i18n/README.md @@ -0,0 +1,135 @@ +# i18n [![GoDoc](https://godoc.org/github.com/unknwon/i18n?status.svg)](https://godoc.org/github.com/unknwon/i18n) + +Package i18n is for app Internationalization and Localization. + +## Introduction + +This package provides multiple-language options to improve user experience. Sites like [Go Walker](http://gowalker.org) and [gogs.io](http://gogs.io) are using this module to implement Chinese and English user interfaces. + +You can use following command to install this module: + + go get github.com/Unknwon/i18n + +## Usage + +First of all, you have to import this package: + +```go +import "github.com/unknwon/i18n" +``` + +The format of locale files is very like INI format configuration file, which is basically key-value pairs. But this module has some improvements. Every language corresponding to a locale file, for example, suppose there are two files called `locale_en-US.ini` and `locale_zh-CN.ini`. + +The name and extensions of locale files can be anything, but we strongly recommend you to follow the style of gogsweb. + +## Minimal example + +Here are two simplest locale file examples: + +File `locale_en-US.ini`: + +```ini +hi = hello, %s +bye = goodbye +``` + +File `locale_zh-CN.ini`: + +```ini +hi = 您好,%s +bye = 再见 +``` + +### Do Translation + +There are two ways to do translation depends on which way is the best fit for your application or framework. + +Directly use package function to translate: + +```go +i18n.Tr("en-US", "hi", "Unknwon") +i18n.Tr("en-US", "bye") +``` + +Or create a struct and embed it: + +```go +type MyController struct{ + // ...other fields + i18n.Locale +} + +//... + +func ... { + c := &MyController{ + Locale: i18n.Locale{"en-US"}, + } + _ = c.Tr("hi", "Unknwon") + _ = c.Tr("bye") +} +``` + +Code above will produce correspondingly: + +- English `en-US`:`hello, Unknwon`, `goodbye` +- Chinese `zh-CN`:`您好,Unknwon`, `再见` + +## Section + +For different pages, one key may map to different values. Therefore, i18n module also uses the section feature of INI format configuration to achieve section. + +For example, the key name is `about`, and we want to show `About` in the home page and `About Us` in about page. Then you can do following: + +Content in locale file: + +```ini +about = About + +[about] +about = About Us +``` + +Get `about` in home page: + +```go +i18n.Tr("en-US", "about") +``` + +Get `about` in about page: + +```go +i18n.Tr("en-US", "about.about") +``` + +### Ambiguity + +Because dot `.` is sign of section in both [INI parser](https://github.com/go-ini/ini) and locale files, so when your key name contains `.` will cause ambiguity. At this point, you just need to add one more `.` in front of the key. + +For example, the key name is `about.`, then we can use: + +```go +i18n.Tr("en-US", ".about.") +``` + +to get expect result. + +## Helper tool + +Module i18n provides a command line helper tool beei18n for simplify steps of your development. You can install it as follows: + + go get github.com/unknwon/i18n/ui18n + +### Sync locale files + +Command `sync` allows you use a exist local file as the template to create or sync other locale files: + + ui18n sync srouce_file.ini other1.ini other2.ini + +This command can operate 1 or more files in one command. + +## More information + +- The first locale you load to the module is considered as **default locale**. +- When matching non-default locale and didn't find the string, i18n will have a second try on default locale. +- If i18n still cannot find string in the default locale, raw string will be returned. For instance, when the string is `hi` and it does not exist in locale file, simply return `hi` as output. diff --git a/vendor/github.com/unknwon/i18n/go.mod b/vendor/github.com/unknwon/i18n/go.mod new file mode 100644 index 0000000000..4d252d68ea --- /dev/null +++ b/vendor/github.com/unknwon/i18n/go.mod @@ -0,0 +1,9 @@ +module github.com/unknwon/i18n + +go 1.12 + +require ( + github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect + github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e + gopkg.in/ini.v1 v1.46.0 +) diff --git a/vendor/github.com/unknwon/i18n/go.sum b/vendor/github.com/unknwon/i18n/go.sum new file mode 100644 index 0000000000..8bb9e76563 --- /dev/null +++ b/vendor/github.com/unknwon/i18n/go.sum @@ -0,0 +1,21 @@ +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM= +github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag= +gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/vendor/github.com/unknwon/i18n/i18n.go b/vendor/github.com/unknwon/i18n/i18n.go new file mode 100644 index 0000000000..38f0899dd3 --- /dev/null +++ b/vendor/github.com/unknwon/i18n/i18n.go @@ -0,0 +1,231 @@ +// Copyright 2013 Unknwon +// +// 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 i18n is for app Internationalization and Localization. +package i18n + +import ( + "errors" + "fmt" + "reflect" + "strings" + + "gopkg.in/ini.v1" +) + +var ( + ErrLangAlreadyExist = errors.New("Lang already exists") + + locales = &localeStore{store: make(map[string]*locale)} +) + +type locale struct { + id int + lang string + langDesc string + message *ini.File +} + +type localeStore struct { + langs []string + langDescs []string + store map[string]*locale + defaultLang string +} + +// Get target language string +func (d *localeStore) Get(lang, section, format string) (string, bool) { + if locale, ok := d.store[lang]; ok { + if key, err := locale.message.Section(section).GetKey(format); err == nil { + return key.Value(), true + } + } + + if len(d.defaultLang) > 0 && lang != d.defaultLang { + return d.Get(d.defaultLang, section, format) + } + + return "", false +} + +func (d *localeStore) Add(lc *locale) bool { + if _, ok := d.store[lc.lang]; ok { + return false + } + + lc.id = len(d.langs) + d.langs = append(d.langs, lc.lang) + d.langDescs = append(d.langDescs, lc.langDesc) + d.store[lc.lang] = lc + + return true +} + +func (d *localeStore) Reload(langs ...string) (err error) { + if len(langs) == 0 { + for _, lc := range d.store { + if err = lc.message.Reload(); err != nil { + return err + } + } + } else { + for _, lang := range langs { + if lc, ok := d.store[lang]; ok { + if err = lc.message.Reload(); err != nil { + return err + } + } + } + } + return nil +} + +// SetDefaultLang sets default language which is a indicator that +// when target language is not found, try find in default language again. +func SetDefaultLang(lang string) { + locales.defaultLang = lang +} + +// ReloadLangs reloads locale files. +func ReloadLangs(langs ...string) error { + return locales.Reload(langs...) +} + +// Count returns number of languages that are registered. +func Count() int { + return len(locales.langs) +} + +// ListLangs returns list of all locale languages. +func ListLangs() []string { + langs := make([]string, len(locales.langs)) + copy(langs, locales.langs) + return langs +} + +func ListLangDescs() []string { + langDescs := make([]string, len(locales.langDescs)) + copy(langDescs, locales.langDescs) + return langDescs +} + +// IsExist returns true if given language locale exists. +func IsExist(lang string) bool { + _, ok := locales.store[lang] + return ok +} + +// IndexLang returns index of language locale, +// it returns -1 if locale not exists. +func IndexLang(lang string) int { + if lc, ok := locales.store[lang]; ok { + return lc.id + } + return -1 +} + +// GetLangByIndex return language by given index. +func GetLangByIndex(index int) string { + if index < 0 || index >= len(locales.langs) { + return "" + } + return locales.langs[index] +} + +func GetDescriptionByIndex(index int) string { + if index < 0 || index >= len(locales.langDescs) { + return "" + } + + return locales.langDescs[index] +} + +func GetDescriptionByLang(lang string) string { + return GetDescriptionByIndex(IndexLang(lang)) +} + +func SetMessageWithDesc(lang, langDesc string, localeFile interface{}, otherLocaleFiles ...interface{}) error { + message, err := ini.LoadSources(ini.LoadOptions{ + IgnoreInlineComment: true, + UnescapeValueCommentSymbols: true, + }, localeFile, otherLocaleFiles...) + if err == nil { + message.BlockMode = false + lc := new(locale) + lc.lang = lang + lc.langDesc = langDesc + lc.message = message + + if locales.Add(lc) == false { + return ErrLangAlreadyExist + } + } + return err +} + +// SetMessage sets the message file for localization. +func SetMessage(lang string, localeFile interface{}, otherLocaleFiles ...interface{}) error { + return SetMessageWithDesc(lang, lang, localeFile, otherLocaleFiles...) +} + +// Locale represents the information of localization. +type Locale struct { + Lang string +} + +// Tr translates content to target language. +func (l Locale) Tr(format string, args ...interface{}) string { + return Tr(l.Lang, format, args...) +} + +// Index returns lang index of LangStore. +func (l Locale) Index() int { + return IndexLang(l.Lang) +} + +// Tr translates content to target language. +func Tr(lang, format string, args ...interface{}) string { + var section string + + idx := strings.IndexByte(format, '.') + if idx > 0 { + section = format[:idx] + format = format[idx+1:] + } + + value, ok := locales.Get(lang, section, format) + if ok { + format = value + } + + if len(args) > 0 { + params := make([]interface{}, 0, len(args)) + for _, arg := range args { + if arg == nil { + continue + } + + val := reflect.ValueOf(arg) + if val.Kind() == reflect.Slice { + for i := 0; i < val.Len(); i++ { + params = append(params, val.Index(i).Interface()) + } + } else { + params = append(params, arg) + } + } + return fmt.Sprintf(format, params...) + } + return format +} |