Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/config/util.c

Source at commit 1808 created 12 years 3 months ago.
By blackosx, Revise layout of package installer 'Welcome' file so it looks cleaner. Change the copyright notice to begin from 2009 as seen in the Chameleon 2.0 r431 installer. Should this date be set earlier?
1/*
2 * util.c
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <stdarg.h>
23
24#include "dialog.h"
25
26struct dialog_info dlg;
27
28static void set_mono_theme(void)
29{
30dlg.screen.atr = A_NORMAL;
31dlg.shadow.atr = A_NORMAL;
32dlg.dialog.atr = A_NORMAL;
33dlg.title.atr = A_BOLD;
34dlg.border.atr = A_NORMAL;
35dlg.button_active.atr = A_REVERSE;
36dlg.button_inactive.atr = A_DIM;
37dlg.button_key_active.atr = A_REVERSE;
38dlg.button_key_inactive.atr = A_BOLD;
39dlg.button_label_active.atr = A_REVERSE;
40dlg.button_label_inactive.atr = A_NORMAL;
41dlg.inputbox.atr = A_NORMAL;
42dlg.inputbox_border.atr = A_NORMAL;
43dlg.searchbox.atr = A_NORMAL;
44dlg.searchbox_title.atr = A_BOLD;
45dlg.searchbox_border.atr = A_NORMAL;
46dlg.position_indicator.atr = A_BOLD;
47dlg.menubox.atr = A_NORMAL;
48dlg.menubox_border.atr = A_NORMAL;
49dlg.item.atr = A_NORMAL;
50dlg.item_selected.atr = A_REVERSE;
51dlg.tag.atr = A_BOLD;
52dlg.tag_selected.atr = A_REVERSE;
53dlg.tag_key.atr = A_BOLD;
54dlg.tag_key_selected.atr = A_REVERSE;
55dlg.check.atr = A_BOLD;
56dlg.check_selected.atr = A_REVERSE;
57dlg.uarrow.atr = A_BOLD;
58dlg.darrow.atr = A_BOLD;
59}
60
61#define DLG_COLOR(dialog, f, b, h) \
62do { \
63dlg.dialog.fg = (f); \
64dlg.dialog.bg = (b); \
65dlg.dialog.hl = (h); \
66} while (0)
67
68static void set_classic_theme(void)
69{
70DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true);
71DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true);
72DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false);
73DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true);
74DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true);
75DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true);
76DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false);
77DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true);
78DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false);
79DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true);
80DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true);
81DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false);
82DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false);
83DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false);
84DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true);
85DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true);
86DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true);
87DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false);
88DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true);
89DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false);
90DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true);
91DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true);
92DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true);
93DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true);
94DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true);
95DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false);
96DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true);
97DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true);
98DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true);
99}
100
101static void set_blackbg_theme(void)
102{
103DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true);
104DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
105DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
106DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false);
107DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
108
109DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false);
110DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false);
111DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true);
112DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false);
113DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false);
114DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true);
115
116DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false);
117DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false);
118
119DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false);
120DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true);
121DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true);
122
123DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false);
124
125DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false);
126DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true);
127
128DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false);
129DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false);
130
131DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false);
132DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true);
133DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false);
134DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true);
135
136DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false);
137DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true);
138
139DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
140DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
141}
142
143static void set_bluetitle_theme(void)
144{
145set_classic_theme();
146DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true);
147DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true);
148DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true);
149DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true);
150DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true);
151DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true);
152DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true);
153
154}
155
156/*
157 * Select color theme
158 */
159static int set_theme(const char *theme)
160{
161int use_color = 1;
162if (!theme)
163set_bluetitle_theme();
164else if (strcmp(theme, "classic") == 0)
165set_classic_theme();
166else if (strcmp(theme, "bluetitle") == 0)
167set_bluetitle_theme();
168else if (strcmp(theme, "blackbg") == 0)
169set_blackbg_theme();
170else if (strcmp(theme, "mono") == 0)
171use_color = 0;
172
173return use_color;
174}
175
176static void init_one_color(struct dialog_color *color)
177{
178static int pair = 0;
179
180pair++;
181init_pair(pair, color->fg, color->bg);
182if (color->hl)
183color->atr = A_BOLD | COLOR_PAIR(pair);
184else
185color->atr = COLOR_PAIR(pair);
186}
187
188static void init_dialog_colors(void)
189{
190init_one_color(&dlg.screen);
191init_one_color(&dlg.shadow);
192init_one_color(&dlg.dialog);
193init_one_color(&dlg.title);
194init_one_color(&dlg.border);
195init_one_color(&dlg.button_active);
196init_one_color(&dlg.button_inactive);
197init_one_color(&dlg.button_key_active);
198init_one_color(&dlg.button_key_inactive);
199init_one_color(&dlg.button_label_active);
200init_one_color(&dlg.button_label_inactive);
201init_one_color(&dlg.inputbox);
202init_one_color(&dlg.inputbox_border);
203init_one_color(&dlg.searchbox);
204init_one_color(&dlg.searchbox_title);
205init_one_color(&dlg.searchbox_border);
206init_one_color(&dlg.position_indicator);
207init_one_color(&dlg.menubox);
208init_one_color(&dlg.menubox_border);
209init_one_color(&dlg.item);
210init_one_color(&dlg.item_selected);
211init_one_color(&dlg.tag);
212init_one_color(&dlg.tag_selected);
213init_one_color(&dlg.tag_key);
214init_one_color(&dlg.tag_key_selected);
215init_one_color(&dlg.check);
216init_one_color(&dlg.check_selected);
217init_one_color(&dlg.uarrow);
218init_one_color(&dlg.darrow);
219}
220
221/*
222 * Setup for color display
223 */
224static void color_setup(const char *theme)
225{
226int use_color;
227
228use_color = set_theme(theme);
229if (use_color && has_colors()) {
230start_color();
231init_dialog_colors();
232} else
233set_mono_theme();
234}
235
236/*
237 * Set window to attribute 'attr'
238 */
239void attr_clear(WINDOW * win, int height, int width, chtype attr)
240{
241int i, j;
242
243wattrset(win, attr);
244for (i = 0; i < height; i++) {
245wmove(win, i, 0);
246for (j = 0; j < width; j++)
247waddch(win, ' ');
248}
249touchwin(win);
250}
251
252void dialog_clear(void)
253{
254attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
255/* Display background title if it exists ... - SLH */
256if (dlg.backtitle != NULL) {
257int i;
258
259wattrset(stdscr, dlg.screen.atr);
260mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
261wmove(stdscr, 1, 1);
262for (i = 1; i < COLS - 1; i++)
263waddch(stdscr, ACS_HLINE);
264}
265wnoutrefresh(stdscr);
266}
267
268/*
269 * Do some initialization for dialog
270 */
271int init_dialog(const char *backtitle)
272{
273int height, width;
274
275initscr();/* Init curses */
276getmaxyx(stdscr, height, width);
277if (height < 19 || width < 80) {
278endwin();
279return -ERRDISPLAYTOOSMALL;
280}
281
282dlg.backtitle = backtitle;
283color_setup(getenv("MENUCONFIG_COLOR"));
284
285keypad(stdscr, TRUE);
286cbreak();
287noecho();
288dialog_clear();
289
290return 0;
291}
292
293void set_dialog_backtitle(const char *backtitle)
294{
295dlg.backtitle = backtitle;
296}
297
298/*
299 * End using dialog functions.
300 */
301void end_dialog(int x, int y)
302{
303/* move cursor back to original position */
304move(y, x);
305refresh();
306endwin();
307}
308
309/* Print the title of the dialog. Center the title and truncate
310 * tile if wider than dialog (- 2 chars).
311 **/
312void print_title(WINDOW *dialog, const char *title, int width)
313{
314if (title) {
315int tlen = MIN(width - 2, strlen(title));
316wattrset(dialog, dlg.title.atr);
317mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
318mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
319waddch(dialog, ' ');
320}
321}
322
323/*
324 * Print a string of text in a window, automatically wrap around to the
325 * next line if the string is too long to fit on one line. Newline
326 * characters '\n' are replaced by spaces. We start on a new line
327 * if there is no room for at least 4 nonblanks following a double-space.
328 */
329void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
330{
331int newl, cur_x, cur_y;
332int i, prompt_len, room, wlen;
333char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
334
335strcpy(tempstr, prompt);
336
337prompt_len = strlen(tempstr);
338
339/*
340 * Remove newlines
341 */
342for (i = 0; i < prompt_len; i++) {
343if (tempstr[i] == '\n')
344tempstr[i] = ' ';
345}
346
347if (prompt_len <= width - x * 2) {/* If prompt is short */
348wmove(win, y, (width - prompt_len) / 2);
349waddstr(win, tempstr);
350} else {
351cur_x = x;
352cur_y = y;
353newl = 1;
354word = tempstr;
355while (word && *word) {
356sp = strchr(word, ' ');
357if (sp)
358*sp++ = 0;
359
360/* Wrap to next line if either the word does not fit,
361 or it is the first word of a new sentence, and it is
362 short, and the next word does not fit. */
363room = width - cur_x;
364wlen = strlen(word);
365if (wlen > room ||
366 (newl && wlen < 4 && sp
367 && wlen + 1 + strlen(sp) > room
368 && (!(sp2 = strchr(sp, ' '))
369 || wlen + 1 + (sp2 - sp) > room))) {
370cur_y++;
371cur_x = x;
372}
373wmove(win, cur_y, cur_x);
374waddstr(win, word);
375getyx(win, cur_y, cur_x);
376cur_x++;
377if (sp && *sp == ' ') {
378cur_x++;/* double space */
379while (*++sp == ' ') ;
380newl = 1;
381} else
382newl = 0;
383word = sp;
384}
385}
386}
387
388/*
389 * Print a button
390 */
391void print_button(WINDOW * win, const char *label, int y, int x, int selected)
392{
393int i, temp;
394
395wmove(win, y, x);
396wattrset(win, selected ? dlg.button_active.atr
397 : dlg.button_inactive.atr);
398waddstr(win, "<");
399temp = strspn(label, " ");
400label += temp;
401wattrset(win, selected ? dlg.button_label_active.atr
402 : dlg.button_label_inactive.atr);
403for (i = 0; i < temp; i++)
404waddch(win, ' ');
405wattrset(win, selected ? dlg.button_key_active.atr
406 : dlg.button_key_inactive.atr);
407waddch(win, label[0]);
408wattrset(win, selected ? dlg.button_label_active.atr
409 : dlg.button_label_inactive.atr);
410waddstr(win, (char *)label + 1);
411wattrset(win, selected ? dlg.button_active.atr
412 : dlg.button_inactive.atr);
413waddstr(win, ">");
414wmove(win, y, x + temp + 1);
415}
416
417/*
418 * Draw a rectangular box with line drawing characters
419 */
420void
421draw_box(WINDOW * win, int y, int x, int height, int width,
422 chtype box, chtype border)
423{
424int i, j;
425
426wattrset(win, 0);
427for (i = 0; i < height; i++) {
428wmove(win, y + i, x);
429for (j = 0; j < width; j++)
430if (!i && !j)
431waddch(win, border | ACS_ULCORNER);
432else if (i == height - 1 && !j)
433waddch(win, border | ACS_LLCORNER);
434else if (!i && j == width - 1)
435waddch(win, box | ACS_URCORNER);
436else if (i == height - 1 && j == width - 1)
437waddch(win, box | ACS_LRCORNER);
438else if (!i)
439waddch(win, border | ACS_HLINE);
440else if (i == height - 1)
441waddch(win, box | ACS_HLINE);
442else if (!j)
443waddch(win, border | ACS_VLINE);
444else if (j == width - 1)
445waddch(win, box | ACS_VLINE);
446else
447waddch(win, box | ' ');
448}
449}
450
451/*
452 * Draw shadows along the right and bottom edge to give a more 3D look
453 * to the boxes
454 */
455void draw_shadow(WINDOW * win, int y, int x, int height, int width)
456{
457int i;
458
459if (has_colors()) {/* Whether terminal supports color? */
460wattrset(win, dlg.shadow.atr);
461wmove(win, y + height, x + 2);
462for (i = 0; i < width; i++)
463waddch(win, winch(win) & A_CHARTEXT);
464for (i = y + 1; i < y + height + 1; i++) {
465wmove(win, i, x + width);
466waddch(win, winch(win) & A_CHARTEXT);
467waddch(win, winch(win) & A_CHARTEXT);
468}
469wnoutrefresh(win);
470}
471}
472
473/*
474 * Return the position of the first alphabetic character in a string.
475 */
476int first_alpha(const char *string, const char *exempt)
477{
478int i, in_paren = 0, c;
479
480for (i = 0; i < strlen(string); i++) {
481c = tolower(string[i]);
482
483if (strchr("<[(", c))
484++in_paren;
485if (strchr(">])", c) && in_paren > 0)
486--in_paren;
487
488if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
489return i;
490}
491
492return 0;
493}
494
495/*
496 * ncurses uses ESC to detect escaped char sequences. This resutl in
497 * a small timeout before ESC is actually delivered to the application.
498 * lxdialog suggest <ESC> <ESC> which is correctly translated to two
499 * times esc. But then we need to ignore the second esc to avoid stepping
500 * out one menu too much. Filter away all escaped key sequences since
501 * keypad(FALSE) turn off ncurses support for escape sequences - and thats
502 * needed to make notimeout() do as expected.
503 */
504int on_key_esc(WINDOW *win)
505{
506int key;
507int key2;
508int key3;
509
510nodelay(win, TRUE);
511keypad(win, FALSE);
512key = wgetch(win);
513key2 = wgetch(win);
514do {
515key3 = wgetch(win);
516} while (key3 != ERR);
517nodelay(win, FALSE);
518keypad(win, TRUE);
519if (key == KEY_ESC && key2 == ERR)
520return KEY_ESC;
521else if (key != ERR && key != KEY_ESC && key2 == ERR)
522ungetch(key);
523
524return -1;
525}
526
527/* redraw screen in new size */
528int on_key_resize(void)
529{
530dialog_clear();
531return KEY_RESIZE;
532}
533
534struct dialog_list *item_cur;
535struct dialog_list item_nil;
536struct dialog_list *item_head;
537
538void item_reset(void)
539{
540struct dialog_list *p, *next;
541
542for (p = item_head; p; p = next) {
543next = p->next;
544free(p);
545}
546item_head = NULL;
547item_cur = &item_nil;
548}
549
550void item_make(const char *fmt, ...)
551{
552va_list ap;
553struct dialog_list *p = malloc(sizeof(*p));
554
555if (item_head)
556item_cur->next = p;
557else
558item_head = p;
559item_cur = p;
560memset(p, 0, sizeof(*p));
561
562va_start(ap, fmt);
563vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
564va_end(ap);
565}
566
567void item_add_str(const char *fmt, ...)
568{
569va_list ap;
570 size_t avail;
571
572avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
573
574va_start(ap, fmt);
575vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
576 avail, fmt, ap);
577item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
578va_end(ap);
579}
580
581void item_set_tag(char tag)
582{
583item_cur->node.tag = tag;
584}
585void item_set_data(void *ptr)
586{
587item_cur->node.data = ptr;
588}
589
590void item_set_selected(int val)
591{
592item_cur->node.selected = val;
593}
594
595int item_activate_selected(void)
596{
597item_foreach()
598if (item_is_selected())
599return 1;
600return 0;
601}
602
603void *item_data(void)
604{
605return item_cur->node.data;
606}
607
608char item_tag(void)
609{
610return item_cur->node.tag;
611}
612
613int item_count(void)
614{
615int n = 0;
616struct dialog_list *p;
617
618for (p = item_head; p; p = p->next)
619n++;
620return n;
621}
622
623void item_set(int n)
624{
625int i = 0;
626item_foreach()
627if (i++ == n)
628return;
629}
630
631int item_n(void)
632{
633int n = 0;
634struct dialog_list *p;
635
636for (p = item_head; p; p = p->next) {
637if (p == item_cur)
638return n;
639n++;
640}
641return 0;
642}
643
644const char *item_str(void)
645{
646return item_cur->node.str;
647}
648
649int item_is_selected(void)
650{
651return (item_cur->node.selected != 0);
652}
653
654int item_is_tag(char tag)
655{
656return (item_cur->node.tag == tag);
657}
658
659/*
660 * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
661 * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
662 *
663 * Released under the terms of the GNU GPL v2.0.
664 */
665
666//#include <string.h>
667//#include "lkc.h"
668
669/* file already present in list? If not add it */
670struct file *file_lookup(const char *name)
671{
672struct file *file;
673const char *file_name = sym_expand_string_value(name);
674
675for (file = file_list; file; file = file->next) {
676if (!strcmp(name, file->name)) {
677free((void *)file_name);
678return file;
679}
680}
681
682file = malloc(sizeof(*file));
683memset(file, 0, sizeof(*file));
684file->name = file_name;
685file->next = file_list;
686file_list = file;
687return file;
688}
689
690/* write a dependency file as used by kbuild to track dependencies */
691int file_write_dep(const char *name)
692{
693struct symbol *sym, *env_sym;
694struct expr *e;
695struct file *file;
696FILE *out;
697
698if (!name)
699name = ".kconfig.d";
700out = fopen("..config.tmp", "w");
701if (!out)
702return 1;
703fprintf(out, "deps_config := \\\n");
704for (file = file_list; file; file = file->next) {
705if (file->next)
706fprintf(out, "\t%s \\\n", file->name);
707else
708fprintf(out, "\t%s\n", file->name);
709}
710fprintf(out, "\n%s: \\\n"
711 "\t$(deps_config)\n\n", conf_get_autoconfig_name());
712
713expr_list_for_each_sym(sym_env_list, e, sym) {
714struct property *prop;
715const char *value;
716
717prop = sym_get_env_prop(sym);
718env_sym = prop_get_symbol(prop);
719if (!env_sym)
720continue;
721value = getenv(env_sym->name);
722if (!value)
723value = "";
724fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
725fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());
726fprintf(out, "endif\n");
727}
728
729fprintf(out, "\n$(deps_config): ;\n");
730fclose(out);
731rename("..config.tmp", name);
732return 0;
733}
734
735
736/* Allocate initial growable string */
737struct gstr str_new(void)
738{
739struct gstr gs;
740gs.s = malloc(sizeof(char) * 64);
741gs.len = 64;
742gs.max_width = 0;
743strcpy(gs.s, "\0");
744return gs;
745}
746
747/* Allocate and assign growable string */
748struct gstr str_assign(const char *s)
749{
750struct gstr gs;
751gs.s = strdup(s);
752gs.len = strlen(s) + 1;
753gs.max_width = 0;
754return gs;
755}
756
757/* Free storage for growable string */
758void str_free(struct gstr *gs)
759{
760if (gs->s)
761free(gs->s);
762gs->s = NULL;
763gs->len = 0;
764}
765
766/* Append to growable string */
767void str_append(struct gstr *gs, const char *s)
768{
769size_t l;
770if (s) {
771l = strlen(gs->s) + strlen(s) + 1;
772if (l > gs->len) {
773gs->s = realloc(gs->s, l);
774gs->len = l;
775}
776strcat(gs->s, s);
777}
778}
779
780/* Append printf formatted string to growable string */
781void str_printf(struct gstr *gs, const char *fmt, ...)
782{
783va_list ap;
784char s[10000]; /* big enough... */
785va_start(ap, fmt);
786vsnprintf(s, sizeof(s), fmt, ap);
787str_append(gs, s);
788va_end(ap);
789}
790
791/* Retrieve value of growable string */
792const char *str_get(struct gstr *gs)
793{
794return gs->s;
795}
796
797

Archive Download this file

Revision: 1808