summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/compress.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-03-17 22:54:07 -0400
committerFranklin Wei <git@fwei.tk>2018-03-17 22:54:21 -0400
commit77641d59a7ece60554da6cc1337d885786e5fc3f (patch)
tree5ce575a78224ba993c9f31ba94734a8ebc56203f /apps/plugins/puzzles/compress.c
parent6039eb05ba6d82ef56f2868c96654c552d117bf9 (diff)
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.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 @@
* output. Do not directly compile or use this program, instead it
* will be automatically used by genhelp.sh */
+#include <assert.h>
#include <ctype.h>
#include <lz4hc.h>
-#include <string.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
#include "help.h"
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)
for(int i = LZ4HC_CLEVEL_MIN; i < LZ4HC_CLEVEL_MAX; ++i)
{
- *rc = LZ4_compress_HC(help_text, outbuf, inlen, maxsz, i);
+ *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, i);
if(!*rc)
{
fprintf(stderr, "compress failed\n");
@@ -30,7 +33,7 @@ char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev)
*minlev = i;
}
}
- *rc = LZ4_compress_HC(help_text, outbuf, inlen, maxsz, *minlev);
+ *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, *minlev);
return outbuf;
}
@@ -42,28 +45,121 @@ void dump_bytes(unsigned char *buf, int len)
int stop = i + 10;
for(;i < stop && i < len; ++i)
{
- printf("0x%02x, ", buf[i]);
+ unsigned char c = buf[i];
+ printf("0x%02x,", c);
+ if(i != stop - 1 && i != len - 1)
+ printf(" ");
}
printf("\n");
}
}
+/* Input: help text in help_text array (to be compiled against) as a
+ * standard C string
+ * Output: C source code on stdout defining the following:
+ *
+ * const char help_text_words[];
+ * const unsigned short help_text_len;
+ * const struct style_text help_text_style[];
+ *
+ * help_text_words consists of help_text_len bytes containing the
+ * words of the help text, delimited with NULs, not a standard C
+ * string. The rockbox frontend is responsible for generating an array
+ * of pointers into this array to pass to display_text. */
+
int main()
{
- int inlen = strlen(help_text) + 1, len;
+ int inlen = strlen(help_text) + 1, outlen;
int minsz, minlev;
- unsigned char *outbuf = compress(help_text, inlen, &len, &minsz, &minlev);
printf("/* auto-generated on " __DATE__ " by genhelp.sh */\n");
- printf("/* orig %d comp %d ratio %g level %d saved %d */\n", inlen, minsz, (double)minsz / inlen, minlev, inlen - minsz);
+ printf("/* help text is compressed using LZ4; see compress.c for details */\n");
printf("/* DO NOT EDIT! */\n\n");
+
+ printf("#include \"lib/display_text.h\"\n\n");
+
+ printf("const struct style_text help_text_style[] = {\n");
+
+ /* break up words on spaces and newline while printing indices of
+ * underlined words */
+ char *buf = strdup(help_text);
+ bool underline = false, center = false;
+ int word_idx = 0, help_text_len = inlen;
+
+ for(int i = 0; i < help_text_len; ++i)
+ {
+ switch(buf[i])
+ {
+ case '#':
+ case '_':
+ /* title or underlined portion */
+ if(buf[i] == '#')
+ {
+ center = !center;
+ if(center)
+ printf(" { %d, TEXT_CENTER | C_RED },\n", word_idx);
+ }
+ else
+ {
+ /* underline */
+ underline = !underline;
+
+ if(underline)
+ printf(" { %d, TEXT_UNDERLINE },\n", word_idx);
+ }
+
+ /* delete the formatting character */
+ memmove(buf + i, buf + i + 1, help_text_len - i - 1);
+ --help_text_len;
+ --i;
+ break;
+ case '$':
+ /* genhelp.sh replaces the dollar signs in URLs with
+ * dollar signs to help us out. */
+ buf[i] = '_';
+ break;
+ case '\n':
+ center = false;
+ /* fall through */
+ case ' ':
+ case '\0':
+ /* Groups of words that are centered or underlined are
+ * counted as a single "word". */
+ if(!underline && !center)
+ {
+ buf[i] = '\0';
+ ++word_idx;
+ }
+ break;
+ }
+ }
+ /* sanity check */
+ int words_check = 0;
+ for(int i = 0; i < help_text_len; ++i)
+ if(!buf[i])
+ {
+ ++words_check;
+ }
+
+ assert(words_check == word_idx);
+
+ printf(" LAST_STYLE_ITEM\n};\n\n");
+
+ /* remove trailing NULs */
+ for(int i = help_text_len - 2; i >= 0 && !buf[i]; --i, --help_text_len, --word_idx);
+
+ unsigned char *outbuf = compress(buf, help_text_len, &outlen, &minsz, &minlev);
+
+ 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);
printf("const char help_text[] = {\n");
- dump_bytes(outbuf, len);
+ dump_bytes(outbuf, outlen);
free(outbuf);
+ free(buf);
- printf("};\n");
- printf("const unsigned short help_text_len = %d;\n", inlen);
+ printf("};\n\n");
+ printf("const unsigned short help_text_len = %d;\n", help_text_len);
+ printf("const unsigned short help_text_words = %d;\n", word_idx);
return 0;
}