1706f2543Smrg/*
2706f2543Smrg * Copyright (c) 1997  Metro Link Incorporated
3706f2543Smrg *
4706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5706f2543Smrg * copy of this software and associated documentation files (the "Software"),
6706f2543Smrg * to deal in the Software without restriction, including without limitation
7706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
9706f2543Smrg * Software is furnished to do so, subject to the following conditions:
10706f2543Smrg *
11706f2543Smrg * The above copyright notice and this permission notice shall be included in
12706f2543Smrg * all copies or substantial portions of the Software.
13706f2543Smrg *
14706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17706f2543Smrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20706f2543Smrg * SOFTWARE.
21706f2543Smrg *
22706f2543Smrg * Except as contained in this notice, the name of the Metro Link shall not be
23706f2543Smrg * used in advertising or otherwise to promote the sale, use or other dealings
24706f2543Smrg * in this Software without prior written authorization from Metro Link.
25706f2543Smrg *
26706f2543Smrg */
27706f2543Smrg/*
28706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
29706f2543Smrg *
30706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
31706f2543Smrg * copy of this software and associated documentation files (the "Software"),
32706f2543Smrg * to deal in the Software without restriction, including without limitation
33706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
35706f2543Smrg * Software is furnished to do so, subject to the following conditions:
36706f2543Smrg *
37706f2543Smrg * The above copyright notice and this permission notice shall be included in
38706f2543Smrg * all copies or substantial portions of the Software.
39706f2543Smrg *
40706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
43706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
44706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
47706f2543Smrg *
48706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
49706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
50706f2543Smrg * the sale, use or other dealings in this Software without prior written
51706f2543Smrg * authorization from the copyright holder(s) and author(s).
52706f2543Smrg */
53706f2543Smrg
54706f2543Smrg
55706f2543Smrg/* View/edit this file with tab stops set to 4 */
56706f2543Smrg
57706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
58706f2543Smrg#include <xorg-config.h>
59706f2543Smrg#endif
60706f2543Smrg
61706f2543Smrg#include "xf86Parser.h"
62706f2543Smrg#include "xf86tokens.h"
63706f2543Smrg#include "Configint.h"
64706f2543Smrg#include <X11/Xfuncproto.h>
65706f2543Smrg#include "Xprintf.h"
66706f2543Smrg
67706f2543Smrgextern LexRec val;
68706f2543Smrg
69706f2543Smrgstatic xf86ConfigSymTabRec ServerFlagsTab[] =
70706f2543Smrg{
71706f2543Smrg	{ENDSECTION, "endsection"},
72706f2543Smrg	{NOTRAPSIGNALS, "notrapsignals"},
73706f2543Smrg	{DONTZAP, "dontzap"},
74706f2543Smrg	{DONTZOOM, "dontzoom"},
75706f2543Smrg	{DISABLEVIDMODE, "disablevidmodeextension"},
76706f2543Smrg	{ALLOWNONLOCAL, "allownonlocalxvidtune"},
77706f2543Smrg	{DISABLEMODINDEV, "disablemodindev"},
78706f2543Smrg	{MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
79706f2543Smrg	{ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
80706f2543Smrg	{OPTION, "option"},
81706f2543Smrg	{BLANKTIME, "blanktime"},
82706f2543Smrg	{STANDBYTIME, "standbytime"},
83706f2543Smrg	{SUSPENDTIME, "suspendtime"},
84706f2543Smrg	{OFFTIME, "offtime"},
85706f2543Smrg	{DEFAULTLAYOUT, "defaultserverlayout"},
86706f2543Smrg	{-1, ""},
87706f2543Smrg};
88706f2543Smrg
89706f2543Smrg#define CLEANUP xf86freeFlags
90706f2543Smrg
91706f2543SmrgXF86ConfFlagsPtr
92706f2543Smrgxf86parseFlagsSection (void)
93706f2543Smrg{
94706f2543Smrg	int token;
95706f2543Smrg	parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
96706f2543Smrg
97706f2543Smrg	while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION)
98706f2543Smrg	{
99706f2543Smrg		int hasvalue = FALSE;
100706f2543Smrg		int strvalue = FALSE;
101706f2543Smrg		int tokentype;
102706f2543Smrg		switch (token)
103706f2543Smrg		{
104706f2543Smrg		case COMMENT:
105706f2543Smrg			ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
106706f2543Smrg			break;
107706f2543Smrg			/*
108706f2543Smrg			 * these old keywords are turned into standard generic options.
109706f2543Smrg			 * we fall through here on purpose
110706f2543Smrg			 */
111706f2543Smrg		case DEFAULTLAYOUT:
112706f2543Smrg			strvalue = TRUE;
113706f2543Smrg		case BLANKTIME:
114706f2543Smrg		case STANDBYTIME:
115706f2543Smrg		case SUSPENDTIME:
116706f2543Smrg		case OFFTIME:
117706f2543Smrg			hasvalue = TRUE;
118706f2543Smrg		case NOTRAPSIGNALS:
119706f2543Smrg		case DONTZAP:
120706f2543Smrg		case DONTZOOM:
121706f2543Smrg		case DISABLEVIDMODE:
122706f2543Smrg		case ALLOWNONLOCAL:
123706f2543Smrg		case DISABLEMODINDEV:
124706f2543Smrg		case MODINDEVALLOWNONLOCAL:
125706f2543Smrg		case ALLOWMOUSEOPENFAIL:
126706f2543Smrg			{
127706f2543Smrg				int i = 0;
128706f2543Smrg				while (ServerFlagsTab[i].token != -1)
129706f2543Smrg				{
130706f2543Smrg					char *tmp;
131706f2543Smrg
132706f2543Smrg					if (ServerFlagsTab[i].token == token)
133706f2543Smrg					{
134706f2543Smrg						char *valstr = NULL;
135706f2543Smrg						tmp = strdup (ServerFlagsTab[i].name);
136706f2543Smrg						if (hasvalue)
137706f2543Smrg						{
138706f2543Smrg							tokentype = xf86getSubToken(&(ptr->flg_comment));
139706f2543Smrg							if (strvalue) {
140706f2543Smrg								if (tokentype != STRING)
141706f2543Smrg									Error (QUOTE_MSG, tmp);
142706f2543Smrg								valstr = val.str;
143706f2543Smrg							} else {
144706f2543Smrg								if (tokentype != NUMBER)
145706f2543Smrg									Error (NUMBER_MSG, tmp);
146706f2543Smrg								if (asprintf(&valstr, "%d", val.num) == -1)
147706f2543Smrg									valstr = NULL;
148706f2543Smrg							}
149706f2543Smrg						}
150706f2543Smrg						ptr->flg_option_lst = xf86addNewOption
151706f2543Smrg							(ptr->flg_option_lst, tmp, valstr);
152706f2543Smrg					}
153706f2543Smrg					i++;
154706f2543Smrg				}
155706f2543Smrg			}
156706f2543Smrg			break;
157706f2543Smrg		case OPTION:
158706f2543Smrg			ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst);
159706f2543Smrg			break;
160706f2543Smrg
161706f2543Smrg		case EOF_TOKEN:
162706f2543Smrg			Error (UNEXPECTED_EOF_MSG, NULL);
163706f2543Smrg			break;
164706f2543Smrg		default:
165706f2543Smrg			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
166706f2543Smrg			break;
167706f2543Smrg		}
168706f2543Smrg	}
169706f2543Smrg
170706f2543Smrg#ifdef DEBUG
171706f2543Smrg	printf ("Flags section parsed\n");
172706f2543Smrg#endif
173706f2543Smrg
174706f2543Smrg	return ptr;
175706f2543Smrg}
176706f2543Smrg
177706f2543Smrg#undef CLEANUP
178706f2543Smrg
179706f2543Smrgvoid
180706f2543Smrgxf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags)
181706f2543Smrg{
182706f2543Smrg	XF86OptionPtr p;
183706f2543Smrg
184706f2543Smrg	if ((!flags) || (!flags->flg_option_lst))
185706f2543Smrg		return;
186706f2543Smrg	p = flags->flg_option_lst;
187706f2543Smrg	fprintf (f, "Section \"ServerFlags\"\n");
188706f2543Smrg	if (flags->flg_comment)
189706f2543Smrg		fprintf (f, "%s", flags->flg_comment);
190706f2543Smrg	xf86printOptionList(f, p, 1);
191706f2543Smrg	fprintf (f, "EndSection\n\n");
192706f2543Smrg}
193706f2543Smrg
194706f2543Smrgstatic XF86OptionPtr
195706f2543SmrgaddNewOption2 (XF86OptionPtr head, char *name, char *val, int used)
196706f2543Smrg{
197706f2543Smrg	XF86OptionPtr new, old = NULL;
198706f2543Smrg
199706f2543Smrg	/* Don't allow duplicates, free old strings */
200706f2543Smrg	if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
201706f2543Smrg		new = old;
202706f2543Smrg		free(new->opt_name);
203706f2543Smrg		free(new->opt_val);
204706f2543Smrg	}
205706f2543Smrg	else
206706f2543Smrg		new = calloc (1, sizeof (XF86OptionRec));
207706f2543Smrg	new->opt_name = name;
208706f2543Smrg	new->opt_val = val;
209706f2543Smrg	new->opt_used = used;
210706f2543Smrg
211706f2543Smrg	if (old)
212706f2543Smrg		return head;
213706f2543Smrg	return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new));
214706f2543Smrg}
215706f2543Smrg
216706f2543SmrgXF86OptionPtr
217706f2543Smrgxf86addNewOption (XF86OptionPtr head, char *name, char *val)
218706f2543Smrg{
219706f2543Smrg	return addNewOption2(head, name, val, 0);
220706f2543Smrg}
221706f2543Smrg
222706f2543Smrgvoid
223706f2543Smrgxf86freeFlags (XF86ConfFlagsPtr flags)
224706f2543Smrg{
225706f2543Smrg	if (flags == NULL)
226706f2543Smrg		return;
227706f2543Smrg	xf86optionListFree (flags->flg_option_lst);
228706f2543Smrg	TestFree(flags->flg_comment);
229706f2543Smrg	free (flags);
230706f2543Smrg}
231706f2543Smrg
232706f2543SmrgXF86OptionPtr
233706f2543Smrgxf86optionListDup (XF86OptionPtr opt)
234706f2543Smrg{
235706f2543Smrg	XF86OptionPtr newopt = NULL;
236706f2543Smrg	char *val;
237706f2543Smrg
238706f2543Smrg	while (opt)
239706f2543Smrg	{
240706f2543Smrg		val = opt->opt_val ? strdup(opt->opt_val) : NULL;
241706f2543Smrg		newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val);
242706f2543Smrg		newopt->opt_used = opt->opt_used;
243706f2543Smrg		if (opt->opt_comment)
244706f2543Smrg			newopt->opt_comment = strdup(opt->opt_comment);
245706f2543Smrg		opt = opt->list.next;
246706f2543Smrg	}
247706f2543Smrg	return newopt;
248706f2543Smrg}
249706f2543Smrg
250706f2543Smrgvoid
251706f2543Smrgxf86optionListFree (XF86OptionPtr opt)
252706f2543Smrg{
253706f2543Smrg	XF86OptionPtr prev;
254706f2543Smrg
255706f2543Smrg	while (opt)
256706f2543Smrg	{
257706f2543Smrg		TestFree (opt->opt_name);
258706f2543Smrg		TestFree (opt->opt_val);
259706f2543Smrg		TestFree (opt->opt_comment);
260706f2543Smrg		prev = opt;
261706f2543Smrg		opt = opt->list.next;
262706f2543Smrg		free (prev);
263706f2543Smrg	}
264706f2543Smrg}
265706f2543Smrg
266706f2543Smrgchar *
267706f2543Smrgxf86optionName(XF86OptionPtr opt)
268706f2543Smrg{
269706f2543Smrg	if (opt)
270706f2543Smrg		return opt->opt_name;
271706f2543Smrg	return 0;
272706f2543Smrg}
273706f2543Smrg
274706f2543Smrgchar *
275706f2543Smrgxf86optionValue(XF86OptionPtr opt)
276706f2543Smrg{
277706f2543Smrg	if (opt)
278706f2543Smrg		return opt->opt_val;
279706f2543Smrg	return 0;
280706f2543Smrg}
281706f2543Smrg
282706f2543SmrgXF86OptionPtr
283706f2543Smrgxf86newOption(char *name, char *value)
284706f2543Smrg{
285706f2543Smrg	XF86OptionPtr opt;
286706f2543Smrg
287706f2543Smrg	opt = calloc(1, sizeof (XF86OptionRec));
288706f2543Smrg	if (!opt)
289706f2543Smrg		return NULL;
290706f2543Smrg
291706f2543Smrg	opt->opt_used = 0;
292706f2543Smrg	opt->list.next = 0;
293706f2543Smrg	opt->opt_name = name;
294706f2543Smrg	opt->opt_val = value;
295706f2543Smrg
296706f2543Smrg	return opt;
297706f2543Smrg}
298706f2543Smrg
299706f2543SmrgXF86OptionPtr
300706f2543Smrgxf86nextOption(XF86OptionPtr list)
301706f2543Smrg{
302706f2543Smrg	if (!list)
303706f2543Smrg		return NULL;
304706f2543Smrg	return list->list.next;
305706f2543Smrg}
306706f2543Smrg
307706f2543Smrg/*
308706f2543Smrg * this function searches the given option list for the named option and
309706f2543Smrg * returns a pointer to the option rec if found. If not found, it returns
310706f2543Smrg * NULL
311706f2543Smrg */
312706f2543Smrg
313706f2543SmrgXF86OptionPtr
314706f2543Smrgxf86findOption (XF86OptionPtr list, const char *name)
315706f2543Smrg{
316706f2543Smrg	while (list)
317706f2543Smrg	{
318706f2543Smrg		if (xf86nameCompare (list->opt_name, name) == 0)
319706f2543Smrg			return list;
320706f2543Smrg		list = list->list.next;
321706f2543Smrg	}
322706f2543Smrg	return NULL;
323706f2543Smrg}
324706f2543Smrg
325706f2543Smrg/*
326706f2543Smrg * this function searches the given option list for the named option. If
327706f2543Smrg * found and the option has a parameter, a pointer to the parameter is
328706f2543Smrg * returned.  If the option does not have a parameter an empty string is
329706f2543Smrg * returned.  If the option is not found, a NULL is returned.
330706f2543Smrg */
331706f2543Smrg
332706f2543Smrgchar *
333706f2543Smrgxf86findOptionValue (XF86OptionPtr list, const char *name)
334706f2543Smrg{
335706f2543Smrg	XF86OptionPtr p = xf86findOption (list, name);
336706f2543Smrg
337706f2543Smrg	if (p)
338706f2543Smrg	{
339706f2543Smrg		if (p->opt_val)
340706f2543Smrg			return p->opt_val;
341706f2543Smrg		else
342706f2543Smrg			return "";
343706f2543Smrg	}
344706f2543Smrg	return NULL;
345706f2543Smrg}
346706f2543Smrg
347706f2543SmrgXF86OptionPtr
348706f2543Smrgxf86optionListCreate( const char **options, int count, int used )
349706f2543Smrg{
350706f2543Smrg	XF86OptionPtr p = NULL;
351706f2543Smrg	char *t1, *t2;
352706f2543Smrg	int i;
353706f2543Smrg
354706f2543Smrg	if (count == -1)
355706f2543Smrg	{
356706f2543Smrg		for (count = 0; options[count]; count++)
357706f2543Smrg			;
358706f2543Smrg	}
359706f2543Smrg	if( (count % 2) != 0 )
360706f2543Smrg	{
361706f2543Smrg		fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" );
362706f2543Smrg		return NULL;
363706f2543Smrg	}
364706f2543Smrg	for (i = 0; i < count; i += 2)
365706f2543Smrg	{
366706f2543Smrg		t1 = strdup(options[i]);
367706f2543Smrg		t2 = strdup(options[i + 1]);
368706f2543Smrg		p = addNewOption2 (p, t1, t2, used);
369706f2543Smrg	}
370706f2543Smrg
371706f2543Smrg	return p;
372706f2543Smrg}
373706f2543Smrg
374706f2543Smrg/* the 2 given lists are merged. If an option with the same name is present in
375706f2543Smrg * both, the option from the user list - specified in the second argument -
376706f2543Smrg * is used. The end result is a single valid list of options. Duplicates
377706f2543Smrg * are freed, and the original lists are no longer guaranteed to be complete.
378706f2543Smrg */
379706f2543SmrgXF86OptionPtr
380706f2543Smrgxf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail)
381706f2543Smrg{
382706f2543Smrg	XF86OptionPtr a, b, ap = NULL, bp = NULL;
383706f2543Smrg
384706f2543Smrg	a = tail;
385706f2543Smrg	b = head;
386706f2543Smrg	while (tail && b) {
387706f2543Smrg		if (xf86nameCompare (a->opt_name, b->opt_name) == 0) {
388706f2543Smrg			if (b == head)
389706f2543Smrg				head = a;
390706f2543Smrg			else
391706f2543Smrg				bp->list.next = a;
392706f2543Smrg			if (a == tail)
393706f2543Smrg				tail = a->list.next;
394706f2543Smrg			else
395706f2543Smrg				ap->list.next = a->list.next;
396706f2543Smrg			a->list.next = b->list.next;
397706f2543Smrg			b->list.next = NULL;
398706f2543Smrg			xf86optionListFree (b);
399706f2543Smrg			b = a->list.next;
400706f2543Smrg			bp = a;
401706f2543Smrg			a = tail;
402706f2543Smrg			ap = NULL;
403706f2543Smrg		} else {
404706f2543Smrg			ap = a;
405706f2543Smrg			if (!(a = a->list.next)) {
406706f2543Smrg				a = tail;
407706f2543Smrg				bp = b;
408706f2543Smrg				b = b->list.next;
409706f2543Smrg				ap = NULL;
410706f2543Smrg			}
411706f2543Smrg		}
412706f2543Smrg	}
413706f2543Smrg
414706f2543Smrg	if (head) {
415706f2543Smrg		for (a = head; a->list.next; a = a->list.next)
416706f2543Smrg			;
417706f2543Smrg		a->list.next = tail;
418706f2543Smrg	} else
419706f2543Smrg		head = tail;
420706f2543Smrg
421706f2543Smrg	return head;
422706f2543Smrg}
423706f2543Smrg
424706f2543Smrgchar *
425706f2543Smrgxf86uLongToString(unsigned long i)
426706f2543Smrg{
427706f2543Smrg	char *s;
428706f2543Smrg
429706f2543Smrg	if (asprintf(&s, "%lu", i) == -1)
430706f2543Smrg		return NULL;
431706f2543Smrg	return s;
432706f2543Smrg}
433706f2543Smrg
434706f2543SmrgXF86OptionPtr
435706f2543Smrgxf86parseOption(XF86OptionPtr head)
436706f2543Smrg{
437706f2543Smrg	XF86OptionPtr option, cnew, old;
438706f2543Smrg	char *name, *comment = NULL;
439706f2543Smrg	int token;
440706f2543Smrg
441706f2543Smrg	if ((token = xf86getSubToken(&comment)) != STRING) {
442706f2543Smrg		xf86parseError(BAD_OPTION_MSG, NULL);
443706f2543Smrg		free(comment);
444706f2543Smrg		return head;
445706f2543Smrg	}
446706f2543Smrg
447706f2543Smrg	name = val.str;
448706f2543Smrg	if ((token = xf86getSubToken(&comment)) == STRING) {
449706f2543Smrg		option = xf86newOption(name, val.str);
450706f2543Smrg		option->opt_comment = comment;
451706f2543Smrg		if ((token = xf86getToken(NULL)) == COMMENT)
452706f2543Smrg			option->opt_comment = xf86addComment(option->opt_comment, val.str);
453706f2543Smrg		else
454706f2543Smrg			xf86unGetToken(token);
455706f2543Smrg	}
456706f2543Smrg	else {
457706f2543Smrg		option = xf86newOption(name, NULL);
458706f2543Smrg		option->opt_comment = comment;
459706f2543Smrg		if (token == COMMENT)
460706f2543Smrg			option->opt_comment = xf86addComment(option->opt_comment, val.str);
461706f2543Smrg		else
462706f2543Smrg			xf86unGetToken(token);
463706f2543Smrg	}
464706f2543Smrg
465706f2543Smrg	old = NULL;
466706f2543Smrg
467706f2543Smrg	/* Don't allow duplicates */
468706f2543Smrg	if (head != NULL && (old = xf86findOption(head, name)) != NULL) {
469706f2543Smrg		cnew = old;
470706f2543Smrg		free(option->opt_name);
471706f2543Smrg		TestFree(option->opt_val);
472706f2543Smrg		TestFree(option->opt_comment);
473706f2543Smrg		free(option);
474706f2543Smrg	}
475706f2543Smrg	else
476706f2543Smrg		cnew = option;
477706f2543Smrg
478706f2543Smrg	if (old == NULL)
479706f2543Smrg		return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew));
480706f2543Smrg
481706f2543Smrg	return head;
482706f2543Smrg}
483706f2543Smrg
484706f2543Smrgvoid
485706f2543Smrgxf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs)
486706f2543Smrg{
487706f2543Smrg	int i;
488706f2543Smrg
489706f2543Smrg	if (!list)
490706f2543Smrg		return;
491706f2543Smrg	while (list) {
492706f2543Smrg		for (i = 0; i < tabs; i++)
493706f2543Smrg			fputc('\t', fp);
494706f2543Smrg		if (list->opt_val)
495706f2543Smrg			fprintf(fp, "Option	    \"%s\" \"%s\"", list->opt_name, list->opt_val);
496706f2543Smrg		else
497706f2543Smrg			fprintf(fp, "Option	    \"%s\"", list->opt_name);
498706f2543Smrg		if (list->opt_comment)
499706f2543Smrg			fprintf(fp, "%s", list->opt_comment);
500706f2543Smrg		else
501706f2543Smrg			fputc('\n', fp);
502706f2543Smrg		list = list->list.next;
503706f2543Smrg	}
504706f2543Smrg}
505