A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 164 lines 4.7 kB view raw
1/* This program compresses the help content found in help/ to standard 2 * output. Do not directly compile or use this program, instead it 3 * will be automatically used by genhelp.sh */ 4 5#include <assert.h> 6#include <ctype.h> 7#include <lz4hc.h> 8#include <stdbool.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12 13#include "help.h" 14 15char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) 16{ 17 int maxsz = LZ4_compressBound(inlen); 18 unsigned char *outbuf = malloc(maxsz); 19 *minsz = 9999999; 20 *minlev = 0; 21 22 for(int i = LZ4HC_CLEVEL_MIN; i < LZ4HC_CLEVEL_MAX; ++i) 23 { 24 *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, i); 25 if(!*rc) 26 { 27 fprintf(stderr, "compress failed\n"); 28 return NULL; 29 } 30 if(*rc < *minsz) 31 { 32 *minsz = *rc; 33 *minlev = i; 34 } 35 } 36 *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, *minlev); 37 return outbuf; 38} 39 40void dump_bytes(unsigned char *buf, int len) 41{ 42 int i = 0; 43 while(i < len) 44 { 45 int stop = i + 10; 46 for(;i < stop && i < len; ++i) 47 { 48 unsigned char c = buf[i]; 49 printf("0x%02x,", c); 50 if(i != stop - 1 && i != len - 1) 51 printf(" "); 52 } 53 printf("\n"); 54 } 55} 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 * 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 70int main() 71{ 72 int inlen = strlen(help_text) + 1, outlen; 73 int minsz, minlev; 74 75 printf("/* auto-generated by genhelp.sh */\n"); 76 printf("/* help text is compressed using LZ4; see compress.c for details */\n"); 77 printf("/* DO NOT EDIT! */\n\n"); 78 79 printf("#include \"lib/display_text.h\"\n\n"); 80 81 printf("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 underscores 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 ++words_check; 141 142 assert(words_check == word_idx); 143 144 printf(" LAST_STYLE_ITEM\n};\n\n"); 145 146 /* remove trailing NULs */ 147 for(int i = help_text_len - 2; i >= 0 && !buf[i]; --i, --help_text_len, --word_idx); 148 149 unsigned char *outbuf = compress(buf, help_text_len, &outlen, &minsz, &minlev); 150 151 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); 152 printf("const char help_text[] = {\n"); 153 154 dump_bytes(outbuf, outlen); 155 free(outbuf); 156 free(buf); 157 158 printf("};\n\n"); 159 printf("const unsigned short help_text_len = %d;\n", help_text_len); 160 printf("const unsigned short help_text_words = %d;\n", word_idx); 161 printf("const bool help_text_valid = true;\n"); 162 163 return 0; 164}