mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
271 lines
6.0 KiB
Go
271 lines
6.0 KiB
Go
// Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package po
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Comment represents every message's comments.
|
|
type Comment struct {
|
|
StartLine int // comment start line
|
|
TranslatorComment string // # translator-comments // TrimSpace
|
|
ExtractedComment string // #. extracted-comments
|
|
ReferenceFile []string // #: src/msgcmp.c:338 src/po-lex.c:699
|
|
ReferenceLine []int // #: src/msgcmp.c:338 src/po-lex.c:699
|
|
Flags []string // #, fuzzy,c-format,range:0..10
|
|
PrevMsgContext string // #| msgctxt previous-context
|
|
PrevMsgId string // #| msgid previous-untranslated-string
|
|
}
|
|
|
|
func (p *Comment) less(q *Comment) bool {
|
|
if p.StartLine != 0 || q.StartLine != 0 {
|
|
return p.StartLine < q.StartLine
|
|
}
|
|
if a, b := len(p.ReferenceFile), len(q.ReferenceFile); a != b {
|
|
return a < b
|
|
}
|
|
for i := 0; i < len(p.ReferenceFile); i++ {
|
|
if a, b := p.ReferenceFile[i], q.ReferenceFile[i]; a != b {
|
|
return a < b
|
|
}
|
|
if a, b := p.ReferenceLine[i], q.ReferenceLine[i]; a != b {
|
|
return a < b
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (p *Comment) readPoComment(r *lineReader) (err error) {
|
|
*p = Comment{}
|
|
if err = r.skipBlankLine(); err != nil {
|
|
return err
|
|
}
|
|
defer func(oldPos int) {
|
|
newPos := r.currentPos()
|
|
if newPos != oldPos && err == io.EOF {
|
|
err = nil
|
|
}
|
|
}(r.currentPos())
|
|
|
|
p.StartLine = r.currentPos() + 1
|
|
for {
|
|
var s string
|
|
if s, _, err = r.currentLine(); err != nil {
|
|
return
|
|
}
|
|
if len(s) == 0 || s[0] != '#' {
|
|
return
|
|
}
|
|
|
|
if err = p.readTranslatorComment(r); err != nil {
|
|
return
|
|
}
|
|
if err = p.readExtractedComment(r); err != nil {
|
|
return
|
|
}
|
|
if err = p.readReferenceComment(r); err != nil {
|
|
return
|
|
}
|
|
if err = p.readFlagsComment(r); err != nil {
|
|
return
|
|
}
|
|
if err = p.readPrevMsgContext(r); err != nil {
|
|
return
|
|
}
|
|
if err = p.readPrevMsgId(r); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *Comment) readTranslatorComment(r *lineReader) (err error) {
|
|
const prefix = "# " // .,:|
|
|
for {
|
|
var s string
|
|
if s, _, err = r.readLine(); err != nil {
|
|
return err
|
|
}
|
|
if len(s) < 1 || s[0] != '#' {
|
|
r.unreadLine()
|
|
return nil
|
|
}
|
|
if len(s) >= 2 {
|
|
switch s[1] {
|
|
case '.', ',', ':', '|':
|
|
r.unreadLine()
|
|
return nil
|
|
}
|
|
}
|
|
if p.TranslatorComment != "" {
|
|
p.TranslatorComment += "\n"
|
|
}
|
|
p.TranslatorComment += strings.TrimSpace(s[1:])
|
|
}
|
|
}
|
|
|
|
func (p *Comment) readExtractedComment(r *lineReader) (err error) {
|
|
const prefix = "#."
|
|
for {
|
|
var s string
|
|
if s, _, err = r.readLine(); err != nil {
|
|
return err
|
|
}
|
|
if len(s) < len(prefix) || s[:len(prefix)] != prefix {
|
|
r.unreadLine()
|
|
return nil
|
|
}
|
|
if p.ExtractedComment != "" {
|
|
p.ExtractedComment += "\n"
|
|
}
|
|
p.ExtractedComment += strings.TrimSpace(s[len(prefix):])
|
|
}
|
|
}
|
|
|
|
func (p *Comment) readReferenceComment(r *lineReader) (err error) {
|
|
const prefix = "#:"
|
|
for {
|
|
var s string
|
|
if s, _, err = r.readLine(); err != nil {
|
|
return err
|
|
}
|
|
if len(s) < len(prefix) || s[:len(prefix)] != prefix {
|
|
r.unreadLine()
|
|
return nil
|
|
}
|
|
ss := strings.Split(strings.TrimSpace(s[len(prefix):]), " ")
|
|
for i := 0; i < len(ss); i++ {
|
|
idx := strings.Index(ss[i], ":")
|
|
if idx <= 0 {
|
|
continue
|
|
}
|
|
name := strings.TrimSpace(ss[i][:idx])
|
|
line, _ := strconv.Atoi(strings.TrimSpace(ss[i][idx+1:]))
|
|
p.ReferenceFile = append(p.ReferenceFile, name)
|
|
p.ReferenceLine = append(p.ReferenceLine, line)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *Comment) readFlagsComment(r *lineReader) (err error) {
|
|
const prefix = "#,"
|
|
for {
|
|
var s string
|
|
if s, _, err = r.readLine(); err != nil {
|
|
return err
|
|
}
|
|
if len(s) < len(prefix) || s[:len(prefix)] != prefix {
|
|
r.unreadLine()
|
|
return nil
|
|
}
|
|
ss := strings.Split(strings.TrimSpace(s[len(prefix):]), ",")
|
|
for i := 0; i < len(ss); i++ {
|
|
p.Flags = append(p.Flags, strings.TrimSpace(ss[i]))
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *Comment) readPrevMsgContext(r *lineReader) (err error) {
|
|
var s string
|
|
if s, _, err = r.currentLine(); err != nil {
|
|
return
|
|
}
|
|
if !rePrevMsgContextComments.MatchString(s) {
|
|
return
|
|
}
|
|
p.PrevMsgContext, err = p.readString(r)
|
|
return
|
|
}
|
|
|
|
func (p *Comment) readPrevMsgId(r *lineReader) (err error) {
|
|
var s string
|
|
if s, _, err = r.currentLine(); err != nil {
|
|
return
|
|
}
|
|
if !rePrevMsgIdComments.MatchString(s) {
|
|
return
|
|
}
|
|
p.PrevMsgId, err = p.readString(r)
|
|
return
|
|
}
|
|
|
|
func (p *Comment) readString(r *lineReader) (msg string, err error) {
|
|
var s string
|
|
if s, _, err = r.readLine(); err != nil {
|
|
return
|
|
}
|
|
msg += decodePoString(s)
|
|
for {
|
|
if s, _, err = r.readLine(); err != nil {
|
|
return
|
|
}
|
|
if !reStringLineComments.MatchString(s) {
|
|
r.unreadLine()
|
|
break
|
|
}
|
|
msg += decodePoString(s)
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetFuzzy gets the fuzzy flag.
|
|
func (p *Comment) GetFuzzy() bool {
|
|
for _, s := range p.Flags {
|
|
if s == "fuzzy" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// SetFuzzy sets the fuzzy flag.
|
|
func (p *Comment) SetFuzzy(fuzzy bool) {
|
|
//
|
|
}
|
|
|
|
// String returns the po format comment string.
|
|
func (p Comment) String() string {
|
|
var buf bytes.Buffer
|
|
if p.TranslatorComment != "" {
|
|
ss := strings.Split(p.TranslatorComment, "\n")
|
|
for i := 0; i < len(ss); i++ {
|
|
fmt.Fprintf(&buf, "# %s\n", ss[i])
|
|
}
|
|
}
|
|
if p.ExtractedComment != "" {
|
|
ss := strings.Split(p.ExtractedComment, "\n")
|
|
for i := 0; i < len(ss); i++ {
|
|
fmt.Fprintf(&buf, "#. %s\n", ss[i])
|
|
}
|
|
}
|
|
if a, b := len(p.ReferenceFile), len(p.ReferenceLine); a != 0 && a == b {
|
|
fmt.Fprintf(&buf, "#:")
|
|
for i := 0; i < len(p.ReferenceFile); i++ {
|
|
fmt.Fprintf(&buf, " %s:%d", p.ReferenceFile[i], p.ReferenceLine[i])
|
|
}
|
|
fmt.Fprintf(&buf, "\n")
|
|
}
|
|
if len(p.Flags) != 0 {
|
|
fmt.Fprintf(&buf, "#, %s", p.Flags[0])
|
|
for i := 1; i < len(p.Flags); i++ {
|
|
fmt.Fprintf(&buf, ", %s", p.Flags[i])
|
|
}
|
|
fmt.Fprintf(&buf, "\n")
|
|
}
|
|
if p.PrevMsgContext != "" {
|
|
s := encodeCommentPoString(p.PrevMsgContext)
|
|
fmt.Fprintf(&buf, "#| msgctxt %s\n", s)
|
|
}
|
|
if p.PrevMsgId != "" {
|
|
s := encodeCommentPoString(p.PrevMsgId)
|
|
fmt.Fprintf(&buf, "#| msgid %s\n", s)
|
|
}
|
|
return buf.String()
|
|
}
|