summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/compress.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/puzzles/compress.c')
-rw-r--r--apps/plugins/puzzles/compress.c116
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
12char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) 15char *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
51int main() 70int 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}