This commit is contained in:
softlandia 2019-01-29 01:40:16 +04:00
Родитель 80a3ecf574
Коммит a940052ea5
2 изменённых файлов: 114 добавлений и 132 удалений

Просмотреть файл

@ -7,23 +7,28 @@ programm automatically detected code page of input files
(c) softlandia@gmail.com
dependences:
dependences:
------------
>"github.com/softlandia/xLib"
>"golang.org/x/text/encoding/charmap"
>"golang.org/x/text/transform"
using
-----
>cpc 866 1251 .las
>cpc 866 1251 .las
all files with extention "las" founded in current folder and all subfolders will be converted from IBM CodePage 866 to Windows 1251 code page
if file already in 1251 code page then nothing is done
if file already in 1251 code page then nothing is done
>cpc 866 1251 st.las
convert one file
history
-------
0.0.1
* init commit
*init commit*
0.0.2
*can convert one file*
*optimization*

227
main.go
Просмотреть файл

@ -1,176 +1,153 @@
//(c) softlandia@gmail.com
//Convert text file code page
//using
//>cpc 866 1251 .las
//convert all las files from 866 to 1251
//search from current folder with recursion
//>cpc 866 1251 x:\prj\data\plat-1.las
//convert file "x:\prj\data\plat-1.las" from 866 to 1251 code page, if input file already 1251 code page then nothing to do
package main
import (
"bufio"
"errors"
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/softlandia/xLib"
"golang.org/x/text/encoding/charmap"
"golang.org/x/text/transform"
)
func parsParameters(icp, ocp *int64) error {
if len(os.Args) < 4 {
fmt.Println("using >cpc 866 1251 .las")
fmt.Println("where 866 input code page")
fmt.Println("where 1251 output code page")
fmt.Println("where .las file extention")
return errors.New("no enought parameters")
}
var err error
*icp, err = strconv.ParseInt(os.Args[1], 10, 32)
if err != nil {
fmt.Printf("input code page '%s' not recognize\n", os.Args[1])
return errors.New("input code page is bad")
}
*ocp, err = strconv.ParseInt(os.Args[2], 10, 32)
if err != nil {
fmt.Printf("output code page '%s' not recognize\n", os.Args[2])
return errors.New("output code page is bad")
}
switch *icp {
case 866:
*icp = xlib.Cp866
case 1251:
*icp = xlib.CpWindows1251
default:
fmt.Printf("input code page '%s' not support\n", os.Args[1])
return errors.New("error input code page")
}
switch *ocp {
case 866:
*ocp = xlib.Cp866
case 1251:
*ocp = xlib.CpWindows1251
default:
fmt.Printf("output code page '%s' not support\n", os.Args[2])
return errors.New("error output code page")
}
if *icp == *ocp {
fmt.Printf("input '%s' and output code page '%s' is equal, nothing to do\n", os.Args[1], os.Args[2])
return errors.New("last parameter error")
}
if len(os.Args[3]) < 2 {
fmt.Printf("path to search or ext of files '%s' to search to small\n", os.Args[3])
return errors.New("last parameter error")
}
return nil
}
func main() {
if len(os.Args) < 4 {
fmt.Println("using >cpc 866 1251")
os.Exit(-1)
}
var (
icp,
ocp int64
path string
)
icp, err := strconv.ParseInt(os.Args[1], 10, 32)
err := parsParameters(&icp, &ocp)
if err != nil {
fmt.Printf("input code page '%s' not recognize\n", os.Args[1])
os.Exit(-2)
log.Printf("program stop, error: %s", err)
os.Exit(1)
}
ocp, err := strconv.ParseInt(os.Args[2], 10, 32)
if err != nil {
fmt.Printf("output code page '%s' not recognize\n", os.Args[2])
os.Exit(-3)
}
path = os.Args[3]
log.Printf("input cp: %d\n", icp)
log.Printf("output cp: %d\n", ocp)
log.Printf("ext: %s", path)
switch icp {
case 866:
icp = xLib.Cp866
case 1251:
icp = xLib.CpWindows1251
default:
fmt.Printf("input code page '%s' not support\n", os.Args[1])
os.Exit(-4)
}
switch ocp {
case 866:
ocp = xLib.Cp866
case 1251:
ocp = xLib.CpWindows1251
default:
fmt.Printf("output code page '%s' not support\n", os.Args[2])
os.Exit(-5)
}
if icp == ocp {
fmt.Printf("input '%s' and output code page '%s' not equal\n", os.Args[1], os.Args[2])
os.Exit(-6)
}
fileList := make([]string, 0, 10)
i, _ := findFiles(&fileList, filepath.Dir(os.Args[0]), os.Args[3])
fmt.Printf("founded :%v files\n", i)
t0 := time.Now()
i, err = convertFiles(&fileList, int(icp), int(ocp))
fmt.Printf("elapsed time: %v\n", time.Since(t0))
os.Exit(0)
}
func fileTrust(ext, path string, i os.FileInfo) bool {
if i.IsDir() { //skip dir
return false
}
if strings.ToUpper(filepath.Ext(path)) != ext { //skip files with extention not equal extFileName
return false
}
return true
}
func findFiles(fileList *[]string, path, extFile string) (int, error) {
log.Println("start search")
log.Println("start path: " + path)
log.Println("file name mask: " + extFile)
extFile = strings.ToUpper(extFile)
i := 0 //index founded files
err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if xlib.FileExists(path) {
log.Println("change code page at one file")
fcp, err := xlib.CodePageDetect(path)
if err != nil {
log.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err)
return err
log.Printf("error file '%s'. %v", path, err)
}
if !fileTrust(extFile, path, info) {
return nil
if int64(fcp) == icp {
err = xlib.ReplaceCpFile(path, icp, ocp)
if err != nil {
log.Printf("error file '%s' convert. %v", path, err)
} else {
log.Printf("file '%s' converted", path)
}
} else {
log.Printf("file '%s' already converted.", path)
}
//file found
i++
*fileList = append(*fileList, path)
return nil
})
return i, err
} else {
log.Println("change code page at many files")
fileList := make([]string, 0, 10)
i, _ := xlib.FindFilesExt(&fileList, filepath.Dir(os.Args[0]), path)
fmt.Printf("founded :%v files\n", i)
i, err = convertFiles(&fileList, icp, ocp)
}
fmt.Printf("elapsed time: %v\n", time.Since(t0))
}
func convertFiles(fileList *[]string, fromCP, toCP int) (int, error) {
func convertFiles(fileList *[]string, fromCP, toCP int64) (int, error) {
fmt.Println("<start convert>")
fmt.Println("file count to look: ", len(*fileList))
for _, fn := range *fileList {
if (fn[0] == '~') && (fn[1] == '~') {
/*if (fn[0] == '~') && (fn[1] == '~') {
fmt.Printf("file '%s' removed from computer!\n", fn)
os.Remove(fn)
continue
}
}*/
newPath := ""
newFileName := "~~" + filepath.Base(fn)
dir := filepath.Dir(fn)
if dir == "." {
newPath = newFileName
} else {
newPath = fmt.Sprintf("%s\\%s", dir, newFileName)
}
fcp, err := xLib.CodePageDetect(fn)
fcp, err := xlib.CodePageDetect(fn)
if err != nil {
continue
}
fmt.Printf("file '%s' have code page: %v and ", fn, fcp)
if fcp == fromCP {
changeCpFile(fn, newPath, fromCP, toCP)
if int64(fcp) == fromCP {
fmt.Printf("convert from cp: %v to %v, file replaced'\n", fcp, toCP)
err = xlib.ReplaceCpFile(fn, fromCP, toCP)
if err != nil {
fmt.Println(err)
os.Exit(1)
//continue
os.Exit(1) //TODO need parameter to control. stop on error or continue
}
fmt.Printf("convert from cp: %v to %v, file replaced'\n", fcp, toCP)
os.Rename(newPath, fn)
} else {
fcp, _ = xLib.CodePageDetect(fn)
fmt.Println("skip")
}
}
return 0, nil
}
func changeCpFile(iFileName, oFileName string, fromCP, toCP int) error {
iFile, err := os.Open(iFileName)
if err != nil {
return err
}
defer iFile.Close()
oFile, err := os.Create(oFileName)
if err != nil {
return err
}
defer oFile.Close()
s := ""
iScanner := bufio.NewScanner(iFile)
for i := 0; iScanner.Scan(); i++ {
s = iScanner.Text()
s, _, err = transform.String(charmap.CodePage866.NewDecoder(), s)
s, _, err = transform.String(charmap.Windows1251.NewEncoder(), s)
if err != nil {
fmt.Printf("error on file '%s' convert\n", iFileName)
return err
}
fmt.Fprintf(oFile, "%s\n", s)
}
return nil
}