1 #include "config.h"
2 #include "base.h"
3 #include "ascii.h"
4 #include "appnames.h"
5 
6 char const *ApplicationName;
7 
8 #define CFGDESC
9 #include "ykey.h"
10 #include "sysdep.h"
11 
addWorkspace(const char *,const char *,bool)12 void addWorkspace(const char *, const char *, bool) {}
addKeyboard(const char *,const char *,bool)13 void addKeyboard(const char *, const char *, bool) {}
setLook(const char *,const char *,bool)14 void setLook(const char *, const char *, bool) {}
addBgImage(const char *,const char *,bool)15 void addBgImage(const char *, const char *, bool) {}
16 
17 //#include "bindkey.h"
18 //#include "default.h"
19 #define CFGDEF
20 #define GENPREF
21 #define extern
22 #include "yprefs.h"
23 #undef extern
24 #include "bindkey.h"
25 #include "default.h"
26 #include "themable.h"
27 #include "icewmbg_prefs.h"
28 
29 static const char workspaceNames[] =
30     "\" 1 \", \" 2 \", \" 3 \", \" 4 \"";
31 static bool sorted, internal, themable;
32 
count(cfoption * options)33 static int count(cfoption* options) {
34     for (int i = 0; ; ++i)
35         if (options[i].type == cfoption::CF_NONE)
36             return i;
37 }
38 
compare(const void * p1,const void * p2)39 static int compare(const void* p1, const void* p2) {
40     const cfoption* o1 = (const cfoption *) p1;
41     const cfoption* o2 = (const cfoption *) p2;
42     return strcmp(o1->name, o2->name);
43 }
44 
sort(cfoption * options)45 static void sort(cfoption* options) {
46     qsort(options, count(options), sizeof(cfoption), compare);
47 }
48 
show(cfoption * options)49 static void show(cfoption *options) {
50     if (sorted)
51         sort(options);
52 
53     for (unsigned i = 0; options[i].type != cfoption::CF_NONE; i++) {
54         size_t deslen = strlen(Elvis(options[i].description, ""));
55         if (deslen < 13) {
56             die(13, "Invalid description for option \"%s\":\n"
57                     "Each icewm option must have a meaningful description\n"
58                     " and be documented in the manpage.\n",
59                 options[i].name);
60         }
61         const char* adddot = ASCII::isAlnum(options[i].description[deslen - 1])
62             ? "." : "";
63 
64         printf("#  %s%s\n", options[i].description, adddot);
65 
66         switch (options[i].type) {
67         case cfoption::CF_BOOL:
68             printf("# %s=%d # 0/1\n",
69                    options[i].name, options[i].boolval());
70             break;
71         case cfoption::CF_INT:
72             printf("# %s=%d # [%d-%d]\n",
73                    options[i].name, *options[i].v.i.int_value,
74                    options[i].v.i.min, options[i].v.i.max);
75             break;
76         case cfoption::CF_UINT:
77             printf("# %s=%u # [%u-%u]\n",
78                    options[i].name, *options[i].v.u.uint_value,
79                    options[i].v.u.min, options[i].v.u.max);
80             break;
81         case cfoption::CF_STR:
82             printf("# %s=\"%s\"\n", options[i].name, Elvis(options[i].str(), ""));
83             break;
84         case cfoption::CF_KEY:
85             printf("# %s=\"%s\"\n", options[i].name, options[i].key()->name);
86             break;
87         case cfoption::CF_FUNC:
88             if (0 == strcmp("WorkspaceNames", options[i].name)) {
89                 printf("WorkspaceNames=%s\n", workspaceNames);
90             }
91             else if (0 == strcmp("Look", options[i].name)) {
92                 char look[16] = QUOTE(CONFIG_DEFAULT_LOOK);
93                 look[4] = ASCII::toLower(look[4]);
94                 printf("# %s=\"%s\"\n", options[i].name, look + 4);
95             }
96 #ifdef CONFIG_DEFAULT_BACKGROUND
97             else if (0 == strcmp("DesktopBackgroundImage", options[i].name)) {
98                 char path[] = CONFIG_DEFAULT_BACKGROUND "";
99                 printf("# %s=\"%s\"\n", options[i].name, path);
100             }
101 #endif
102             else {
103                 printf("# %s=\"\"\n", options[i].name);
104             }
105             break;
106         case cfoption::CF_NONE:
107             break;
108         }
109 
110         puts("");
111     }
112 }
113 
ppod(cfoption * options)114 static void ppod(cfoption *options) {
115     if (sorted)
116         sort(options);
117 
118     for (unsigned int i = 0; options[i].type != cfoption::CF_NONE; i++) {
119         switch (options[i].type) {
120         case cfoption::CF_BOOL:
121             printf("=item B<%s>=%d\n",
122                    options[i].name, options[i].boolval());
123             break;
124         case cfoption::CF_INT:
125             printf("=item B<%s>=%d\n",
126                    options[i].name, *options[i].v.i.int_value);
127             break;
128         case cfoption::CF_UINT:
129             printf("=item B<%s>=%u\n",
130                    options[i].name, *options[i].v.u.uint_value);
131             break;
132         case cfoption::CF_STR:
133             printf("=item B<%s>=\"%s\"\n", options[i].name, Elvis(options[i].str(), ""));
134             break;
135         case cfoption::CF_KEY:
136             printf("=item B<%s>=\"%s\"\n", options[i].name, options[i].key()->name);
137             break;
138         case cfoption::CF_FUNC:
139             if (0 == strcmp("WorkspaceNames", options[i].name)) {
140                 printf("=item B<WorkspaceNames>=%s\n", workspaceNames);
141             }
142             else if (0 == strcmp("Look", options[i].name)) {
143                 char look[16] = QUOTE(CONFIG_DEFAULT_LOOK);
144                 look[4] = ASCII::toLower(look[4]);
145                 printf("=item B<%s>=\"%s\"\n", options[i].name, look + 4);
146             }
147             else {
148                 printf("=item B<%s>=\"\"\n", options[i].name);
149             }
150             break;
151         case cfoption::CF_NONE:
152             break;
153         }
154         puts("");
155 
156         size_t deslen = strlen(Elvis(options[i].description, ""));
157         if (deslen < 13) {
158             die(13, "Invalid description for option \"%s\":\n"
159                     "Each icewm option must have a meaningful description\n"
160                     " and be documented in the manpage.\n",
161                 options[i].name);
162         }
163         const char* adddot = ASCII::isAlnum(options[i].description[deslen - 1])
164             ? "." : "";
165         printf("%s%s\n\n", options[i].description, adddot);
166     }
167 }
168 
prepare()169 static void prepare()
170 {
171     const unsigned wmapp_count = ACOUNT(wmapp_preferences);
172     wmapp_preferences[wmapp_count - 2] = wmapp_preferences[wmapp_count - 1];
173 }
174 
genpref_header()175 static void genpref_header()
176 {
177     printf("# %s preferences(%s) - generated by genpref\n\n", PACKAGE, VERSION);
178     printf("# This file should be copied to %s or $HOME/.icewm/\n", CFGDIR);
179     printf("# NOTE: All settings are commented out by default.\n"
180            "# Be sure to uncomment them if you change them!\n"
181            "\n");
182 }
183 
genpref_internal()184 static void genpref_internal()
185 {
186     show(wmapp_preferences);
187 
188     show(icewm_preferences);
189 }
190 
genpref_themable()191 static void genpref_themable()
192 {
193     printf("# -----------------------------------------------------------\n"
194            "# Themable preferences. Themes will override these.\n"
195            "# To override the themes, place them in ~/.icewm/prefoverride\n"
196            "# -----------------------------------------------------------\n\n");
197 
198     show(icewm_themable_preferences);
199 
200     printf("#\n"
201            "# icewmbg preferences\n"
202            "#\n"
203            "\n"
204            );
205     show(icewmbg_prefs);
206 }
207 
genpref()208 static void genpref()
209 {
210     if (internal && themable)
211         genpref_header();
212     if (internal)
213         genpref_internal();
214     if (themable)
215         genpref_themable();
216 }
217 
podpref()218 static void podpref()
219 {
220     if (internal) {
221         ppod(wmapp_preferences);
222         ppod(icewm_preferences);
223     }
224     if (themable) {
225         ppod(icewm_themable_preferences);
226         ppod(icewmbg_prefs);
227     }
228 }
229 
help_text()230 static const char* help_text()
231 {
232     return
233         "  -n                  Print only non-themable preferences.\n"
234         "  -o, --output=FILE   Write preferences to FILE.\n"
235         "  -p                  Use perlpod output format.\n"
236         "  -s                  Sort preferences by name.\n"
237         "  -t                  Print only themable preferences.\n"
238         ;
239 }
240 
main(int argc,char ** argv)241 int main(int argc, char **argv)
242 {
243     bool pod = false;
244 
245     check_argv(argc, argv, help_text, VERSION);
246 
247     char* output = nullptr;
248     for (char **arg = argv + 1; arg < argv + argc; ++arg) {
249         if (**arg == '-') {
250             char *value(nullptr);
251             if (GetArgument(value, "o", "output", arg, argv + argc)) {
252                 output = value;
253             }
254             else if (is_short_switch(*arg, "n")) {
255                 internal = true;
256             }
257             else if (is_short_switch(*arg, "p")) {
258                 pod = true;
259             }
260             else if (is_short_switch(*arg, "s")) {
261                 sorted = true;
262             }
263             else if (is_short_switch(*arg, "t")) {
264                 themable = true;
265             }
266             else {
267                 warn("Unrecognized option '%s'.", *arg);
268             }
269         }
270     }
271     if (output) {
272         if (nullptr == freopen(output, "w", stdout)) {
273             fail("%s", output);
274             exit(1);
275         }
276     }
277     if ((internal | themable) == 0) {
278         internal = themable = true;
279     }
280 
281     prepare();
282     if (pod)
283         podpref();
284     else
285         genpref();
286     fflush(stdout);
287 
288     return 0;
289 }
290 
291 // vim: set sw=4 ts=4 et:
292