xref: /aosp_15_r20/external/skia/tools/unicode_comparison/go/extract_info/main.go (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1// Copyright 2023 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// This executable for a given ICU implementation (from a hardcoded set)
6// collects performance, memory and actual data for comparison in a simple internal format
7
8package main
9
10import (
11	"flag"
12	"fmt"
13	"os"
14	"path/filepath"
15	"strconv"
16	"strings"
17
18	"go.skia.org/skia/tools/unicode_comparison/go/bridge"
19	"go.skia.org/skia/tools/unicode_comparison/go/helpers"
20)
21
22func createEmptyFile(name string) error {
23	d := []byte("")
24	return os.WriteFile(name, d, 0644)
25}
26
27func walkRecursively(input string, output string) error {
28	err := filepath.Walk(input,
29		func(inputPath string, info os.FileInfo, err error) error {
30			if err != nil {
31				fmt.Println(err)
32				return err
33			}
34			if info.IsDir() {
35				outputPath := strings.Replace(inputPath, input, output, 1)
36				fmt.Printf("%s -> %s\n", inputPath, outputPath)
37				err := os.MkdirAll(outputPath, os.ModePerm)
38				helpers.Check(err)
39			} else {
40				outputPath := strings.Replace(inputPath, input, output, 1)
41				if err := writeInfo(inputPath, outputPath); err != nil {
42					fmt.Println(err)
43					return err
44				}
45			}
46			return nil
47		})
48	return err
49}
50
51func writeInfo(inputPath string, outputPath string) error {
52
53	// Read file
54	fileContent, err := os.ReadFile(inputPath)
55	helpers.Check(err)
56
57	// Convert []byte to string
58	text := string(fileContent)
59
60	// Initialize file
61	time := bridge.PerfComputeCodeunitFlags(text)
62
63	outputFile, err := os.Create(outputPath)
64	helpers.Check(err)
65
66	// Collect info
67	line := fmt.Sprintf("%.2f", time)
68	_, err = outputFile.WriteString(line + "\n0.0\n")
69	helpers.Check(err)
70
71	graphemes := ""
72	softBreaks := ""
73	hardBreaks := ""
74	whitespaces := ""
75	words := ""
76	controls := ""
77
78	graphemesCount := 0
79	softBreaksCount := 0
80	hardBreaksCount := 0
81	whitespacesCount := 0
82	wordsCount := 0
83	controlsCount := 0
84	for i := 0; i <= len(fileContent); i++ {
85		flags := bridge.GetFlags(i)
86		str := bridge.FlagsToString(flags)
87		pos := strconv.Itoa(i)
88		if strings.Contains(str, "G") {
89			graphemes += " "
90			graphemes += pos
91			graphemesCount += 1
92		}
93		if strings.Contains(str, "S") {
94			softBreaks += " "
95			softBreaks += pos
96			softBreaksCount += 1
97		}
98		if strings.Contains(str, "H") {
99			hardBreaks += " "
100			hardBreaks += pos
101			hardBreaksCount += 1
102		}
103		if strings.Contains(str, "W") {
104			whitespaces += " "
105			whitespaces += pos
106			whitespacesCount += 1
107		}
108		if strings.Contains(str, "D") {
109			words += " "
110			words += pos
111			wordsCount += 1
112		}
113		if strings.Contains(str, "C") {
114			controls += " "
115			controls += pos
116			controlsCount += 1
117		}
118	}
119
120	_, err = outputFile.WriteString(strconv.Itoa(graphemesCount) + graphemes + "\n")
121	helpers.Check(err)
122
123	_, err = outputFile.WriteString(strconv.Itoa(softBreaksCount) + softBreaks + "\n")
124	helpers.Check(err)
125
126	_, err = outputFile.WriteString(strconv.Itoa(hardBreaksCount) + hardBreaks + "\n")
127	helpers.Check(err)
128
129	_, err = outputFile.WriteString(strconv.Itoa(whitespacesCount) + whitespaces + "\n")
130	helpers.Check(err)
131
132	_, err = outputFile.WriteString(strconv.Itoa(wordsCount) + words + "\n")
133	helpers.Check(err)
134
135	_, err = outputFile.WriteString(strconv.Itoa(controlsCount) + controls + "\n")
136	helpers.Check(err)
137
138	outputFile.Close()
139
140	return nil
141}
142
143func main() {
144	var (
145		root = flag.String("root", "~/datasets", "Folder (pages will be under <Folder>/input")
146		impl = flag.String("impl", "", "Unicode Implementation")
147	)
148	flag.Parse()
149
150	*root = helpers.ExpandPath(*root)
151	input := filepath.Join(*root, "input")
152	output := filepath.Join(*root, "output", *impl)
153	if *root == "" {
154		fmt.Println("Must set --root")
155		flag.PrintDefaults()
156	} else if *impl == "" {
157		fmt.Println("Must set --impl")
158		flag.PrintDefaults()
159	}
160	if !bridge.InitUnicode(*impl) {
161		return
162	}
163	err := walkRecursively(input, output)
164	defer bridge.CleanupUnicode()
165
166	if err != nil {
167		fmt.Println(err)
168	}
169}
170