diff options
author | Franklin Wei <git@fwei.tk> | 2018-03-17 22:54:07 -0400 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2018-03-17 22:54:21 -0400 |
commit | 77641d59a7ece60554da6cc1337d885786e5fc3f (patch) | |
tree | 5ce575a78224ba993c9f31ba94734a8ebc56203f /apps/plugins/puzzles/compress.c | |
parent | 6039eb05ba6d82ef56f2868c96654c552d117bf9 (diff) | |
download | rockbox-77641d59a7ece60554da6cc1337d885786e5fc3f.tar.gz rockbox-77641d59a7ece60554da6cc1337d885786e5fc3f.zip |
puzzles: add formatting to help viewer
The help text is now processed to generate a style array to pass to the
display_text library in addition to the text itself. The help text is still
compressed using LZ4, and still fits on the c200v2.
Change-Id: I7a3a664f90f67a1a018956c72d2b62d92b8ffd17
Diffstat (limited to 'apps/plugins/puzzles/compress.c')
-rw-r--r-- | apps/plugins/puzzles/compress.c | 116 |
1 files changed, 106 insertions, 10 deletions
diff --git a/apps/plugins/puzzles/compress.c b/apps/plugins/puzzles/compress.c index 96f0be5232..04df077e53 100644 --- a/apps/plugins/puzzles/compress.c +++ b/apps/plugins/puzzles/compress.c | |||
@@ -2,11 +2,14 @@ | |||
2 | * output. Do not directly compile or use this program, instead it | 2 | * output. Do not directly compile or use this program, instead it |
3 | * will be automatically used by genhelp.sh */ | 3 | * will be automatically used by genhelp.sh */ |
4 | 4 | ||
5 | #include <assert.h> | ||
5 | #include <ctype.h> | 6 | #include <ctype.h> |
6 | #include <lz4hc.h> | 7 | #include <lz4hc.h> |
7 | #include <string.h> | 8 | #include <stdbool.h> |
8 | #include <stdio.h> | 9 | #include <stdio.h> |
9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <string.h> | ||
12 | |||
10 | #include "help.h" | 13 | #include "help.h" |
11 | 14 | ||
12 | char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) | 15 | char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) |
@@ -18,7 +21,7 @@ char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) | |||
18 | 21 | ||
19 | for(int i = LZ4HC_CLEVEL_MIN; i < LZ4HC_CLEVEL_MAX; ++i) | 22 | for(int i = LZ4HC_CLEVEL_MIN; i < LZ4HC_CLEVEL_MAX; ++i) |
20 | { | 23 | { |
21 | *rc = LZ4_compress_HC(help_text, outbuf, inlen, maxsz, i); | 24 | *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, i); |
22 | if(!*rc) | 25 | if(!*rc) |
23 | { | 26 | { |
24 | fprintf(stderr, "compress failed\n"); | 27 | fprintf(stderr, "compress failed\n"); |
@@ -30,7 +33,7 @@ char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) | |||
30 | *minlev = i; | 33 | *minlev = i; |
31 | } | 34 | } |
32 | } | 35 | } |
33 | *rc = LZ4_compress_HC(help_text, outbuf, inlen, maxsz, *minlev); | 36 | *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, *minlev); |
34 | return outbuf; | 37 | return outbuf; |
35 | } | 38 | } |
36 | 39 | ||
@@ -42,28 +45,121 @@ void dump_bytes(unsigned char *buf, int len) | |||
42 | int stop = i + 10; | 45 | int stop = i + 10; |
43 | for(;i < stop && i < len; ++i) | 46 | for(;i < stop && i < len; ++i) |
44 | { | 47 | { |
45 | printf("0x%02x, ", buf[i]); | 48 | unsigned char c = buf[i]; |
49 | printf("0x%02x,", c); | ||
50 | if(i != stop - 1 && i != len - 1) | ||
51 | printf(" "); | ||
46 | } | 52 | } |
47 | printf("\n"); | 53 | printf("\n"); |
48 | } | 54 | } |
49 | } | 55 | } |
50 | 56 | ||
57 | /* Input: help text in help_text array (to be compiled against) as a | ||
58 | * standard C string | ||
59 | * Output: C source code on stdout defining the following: | ||
60 | * | ||
61 | * const char help_text_words[]; | ||
62 | * const unsigned short help_text_len; | ||
63 | * const struct style_text help_text_style[]; | ||
64 | * | ||
65 | * help_text_words consists of help_text_len bytes containing the | ||
66 | * words of the help text, delimited with NULs, not a standard C | ||
67 | * string. The rockbox frontend is responsible for generating an array | ||
68 | * of pointers into this array to pass to display_text. */ | ||
69 | |||
51 | int main() | 70 | int main() |
52 | { | 71 | { |
53 | int inlen = strlen(help_text) + 1, len; | 72 | int inlen = strlen(help_text) + 1, outlen; |
54 | int minsz, minlev; | 73 | int minsz, minlev; |
55 | unsigned char *outbuf = compress(help_text, inlen, &len, &minsz, &minlev); | ||
56 | 74 | ||
57 | printf("/* auto-generated on " __DATE__ " by genhelp.sh */\n"); | 75 | printf("/* auto-generated on " __DATE__ " by genhelp.sh */\n"); |
58 | printf("/* orig %d comp %d ratio %g level %d saved %d */\n", inlen, minsz, (double)minsz / inlen, minlev, inlen - minsz); | 76 | printf("/* help text is compressed using LZ4; see compress.c for details */\n"); |
59 | printf("/* DO NOT EDIT! */\n\n"); | 77 | printf("/* DO NOT EDIT! */\n\n"); |
78 | |||
79 | printf("#include \"lib/display_text.h\"\n\n"); | ||
80 | |||
81 | printf("const struct style_text help_text_style[] = {\n"); | ||
82 | |||
83 | /* break up words on spaces and newline while printing indices of | ||
84 | * underlined words */ | ||
85 | char *buf = strdup(help_text); | ||
86 | bool underline = false, center = false; | ||
87 | int word_idx = 0, help_text_len = inlen; | ||
88 | |||
89 | for(int i = 0; i < help_text_len; ++i) | ||
90 | { | ||
91 | switch(buf[i]) | ||
92 | { | ||
93 | case '#': | ||
94 | case '_': | ||
95 | /* title or underlined portion */ | ||
96 | if(buf[i] == '#') | ||
97 | { | ||
98 | center = !center; | ||
99 | if(center) | ||
100 | printf(" { %d, TEXT_CENTER | C_RED },\n", word_idx); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | /* underline */ | ||
105 | underline = !underline; | ||
106 | |||
107 | if(underline) | ||
108 | printf(" { %d, TEXT_UNDERLINE },\n", word_idx); | ||
109 | } | ||
110 | |||
111 | /* delete the formatting character */ | ||
112 | memmove(buf + i, buf + i + 1, help_text_len - i - 1); | ||
113 | --help_text_len; | ||
114 | --i; | ||
115 | break; | ||
116 | case '$': | ||
117 | /* genhelp.sh replaces the dollar signs in URLs with | ||
118 | * dollar signs to help us out. */ | ||
119 | buf[i] = '_'; | ||
120 | break; | ||
121 | case '\n': | ||
122 | center = false; | ||
123 | /* fall through */ | ||
124 | case ' ': | ||
125 | case '\0': | ||
126 | /* Groups of words that are centered or underlined are | ||
127 | * counted as a single "word". */ | ||
128 | if(!underline && !center) | ||
129 | { | ||
130 | buf[i] = '\0'; | ||
131 | ++word_idx; | ||
132 | } | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | /* sanity check */ | ||
137 | int words_check = 0; | ||
138 | for(int i = 0; i < help_text_len; ++i) | ||
139 | if(!buf[i]) | ||
140 | { | ||
141 | ++words_check; | ||
142 | } | ||
143 | |||
144 | assert(words_check == word_idx); | ||
145 | |||
146 | printf(" LAST_STYLE_ITEM\n};\n\n"); | ||
147 | |||
148 | /* remove trailing NULs */ | ||
149 | for(int i = help_text_len - 2; i >= 0 && !buf[i]; --i, --help_text_len, --word_idx); | ||
150 | |||
151 | unsigned char *outbuf = compress(buf, help_text_len, &outlen, &minsz, &minlev); | ||
152 | |||
153 | printf("/* orig %d comp %d ratio %g level %d saved %d */\n", help_text_len, minsz, (double)minsz / help_text_len, minlev, help_text_len - minsz); | ||
60 | printf("const char help_text[] = {\n"); | 154 | printf("const char help_text[] = {\n"); |
61 | 155 | ||
62 | dump_bytes(outbuf, len); | 156 | dump_bytes(outbuf, outlen); |
63 | free(outbuf); | 157 | free(outbuf); |
158 | free(buf); | ||
64 | 159 | ||
65 | printf("};\n"); | 160 | printf("};\n\n"); |
66 | printf("const unsigned short help_text_len = %d;\n", inlen); | 161 | printf("const unsigned short help_text_len = %d;\n", help_text_len); |
162 | printf("const unsigned short help_text_words = %d;\n", word_idx); | ||
67 | 163 | ||
68 | return 0; | 164 | return 0; |
69 | } | 165 | } |