1117N/A/*
1117N/A *
1117N/A * Copyright (c) 1997 Metro Link Incorporated
1117N/A *
1117N/A * Permission is hereby granted, free of charge, to any person obtaining a
1117N/A * copy of this software and associated documentation files (the "Software"),
1117N/A * to deal in the Software without restriction, including without limitation
1117N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1117N/A * and/or sell copies of the Software, and to permit persons to whom the
1117N/A * Software is furnished to do so, subject to the following conditions:
1117N/A *
1117N/A * The above copyright notice and this permission notice shall be included in
1117N/A * all copies or substantial portions of the Software.
1117N/A *
1117N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1117N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1117N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1117N/A * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1117N/A * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
1117N/A * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1117N/A * SOFTWARE.
1117N/A *
1117N/A * Except as contained in this notice, the name of the Metro Link shall not be
1117N/A * used in advertising or otherwise to promote the sale, use or other dealings
1117N/A * in this Software without prior written authorization from Metro Link.
1117N/A *
1117N/A */
1117N/A/*
1117N/A * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
1117N/A *
1117N/A * Permission is hereby granted, free of charge, to any person obtaining a
1117N/A * copy of this software and associated documentation files (the "Software"),
1117N/A * to deal in the Software without restriction, including without limitation
1117N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1117N/A * and/or sell copies of the Software, and to permit persons to whom the
1117N/A * Software is furnished to do so, subject to the following conditions:
1117N/A *
1117N/A * The above copyright notice and this permission notice shall be included in
1117N/A * all copies or substantial portions of the Software.
1117N/A *
1117N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1117N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1117N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1117N/A * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1117N/A * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1117N/A * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1117N/A * OTHER DEALINGS IN THE SOFTWARE.
1117N/A *
1117N/A * Except as contained in this notice, the name of the copyright holder(s)
1117N/A * and author(s) shall not be used in advertising or otherwise to promote
1117N/A * the sale, use or other dealings in this Software without prior written
1117N/A * authorization from the copyright holder(s) and author(s).
1117N/A */
1117N/A
1117N/A
1117N/A/* View/edit this file with tab stops set to 4 */
1117N/A
1117N/A#include <math.h>
1117N/A
1117N/A#ifdef HAVE_XORG_CONFIG_H
1117N/A#include <xorg-config.h>
1117N/A#endif
1117N/A#include "xf86Parser.h"
1117N/A#include "xf86tokens.h"
1117N/A#include "Configint.h"
1117N/A
1117N/A#include "fields.h" /* Config file output line fields */
1117N/A#if defined(SMI_FBCONFIG)
1117N/A#include "fbc_edit_config.h" /* Write an updated configuration file */
1117N/A#include "fbc_line_er.h" /* External Representation of config lines */
1117N/A#endif
1117N/A
1117N/A
1117N/Aextern LexRec val;
1117N/A
1117N/Astatic xf86ConfigSymTabRec ServerFlagsTab[] =
1117N/A{
1117N/A {ENDSECTION, "endsection"},
1117N/A {NOTRAPSIGNALS, "notrapsignals"},
1117N/A {DONTZAP, "dontzap"},
1117N/A {DONTZOOM, "dontzoom"},
1117N/A {DISABLEVIDMODE, "disablevidmodeextension"},
1117N/A {ALLOWNONLOCAL, "allownonlocalxvidtune"},
1117N/A {DISABLEMODINDEV, "disablemodindev"},
1117N/A {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
1117N/A {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
1117N/A {OPTION, "option"},
1117N/A {BLANKTIME, "blanktime"},
1117N/A {STANDBYTIME, "standbytime"},
1117N/A {SUSPENDTIME, "suspendtime"},
1117N/A {OFFTIME, "offtime"},
1117N/A {DEFAULTLAYOUT, "defaultserverlayout"},
1117N/A {-1, ""},
1117N/A};
1117N/A
1117N/A#define CLEANUP xf86freeFlags
1117N/A
1117N/AXF86ConfFlagsPtr
1117N/Axf86parseFlagsSection (void)
1117N/A{
1117N/A int token;
1117N/A parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
1117N/A
1117N/A while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION)
1117N/A {
1117N/A int hasvalue = FALSE;
1117N/A int strvalue = FALSE;
1117N/A int tokentype;
1117N/A switch (token)
1117N/A {
1117N/A case COMMENT:
1117N/A ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
1117N/A break;
1117N/A /*
1117N/A * these old keywords are turned into standard generic options.
1117N/A * we fall through here on purpose
1117N/A */
1117N/A case DEFAULTLAYOUT:
1117N/A strvalue = TRUE;
1117N/A case BLANKTIME:
1117N/A case STANDBYTIME:
1117N/A case SUSPENDTIME:
1117N/A case OFFTIME:
1117N/A hasvalue = TRUE;
1117N/A case NOTRAPSIGNALS:
1117N/A case DONTZAP:
1117N/A case DONTZOOM:
1117N/A case DISABLEVIDMODE:
1117N/A case ALLOWNONLOCAL:
1117N/A case DISABLEMODINDEV:
1117N/A case MODINDEVALLOWNONLOCAL:
1117N/A case ALLOWMOUSEOPENFAIL:
1117N/A {
1117N/A int i = 0;
1117N/A while (ServerFlagsTab[i].token != -1)
1117N/A {
1117N/A char *tmp;
1117N/A
1117N/A if (ServerFlagsTab[i].token == token)
1117N/A {
1117N/A char *valstr = NULL;
1117N/A /* can't use strdup because it calls malloc */
1117N/A tmp = xf86configStrdup (ServerFlagsTab[i].name);
1117N/A if (hasvalue)
1117N/A {
1117N/A tokentype = xf86getSubToken(&(ptr->flg_comment));
1117N/A if (strvalue) {
1117N/A if (tokentype != STRING)
1117N/A Error (QUOTE_MSG, tmp);
1117N/A valstr = val.str;
1117N/A } else {
1117N/A if (tokentype != NUMBER)
1117N/A Error (NUMBER_MSG, tmp);
1117N/A valstr = xf86confmalloc(16);
1117N/A if (valstr)
1117N/A sprintf(valstr, "%d", val.num);
1117N/A }
1117N/A }
1117N/A ptr->flg_option_lst = xf86addNewOption
1117N/A (ptr->flg_option_lst, tmp, valstr);
1117N/A }
1117N/A i++;
1117N/A }
1117N/A }
1117N/A break;
1117N/A case OPTION:
1117N/A ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst);
1117N/A break;
1117N/A
1117N/A case EOF_TOKEN:
1117N/A Error (UNEXPECTED_EOF_MSG, NULL);
1117N/A break;
1117N/A default:
1117N/A Error (INVALID_KEYWORD_MSG, xf86tokenString ());
1117N/A break;
1117N/A }
1117N/A }
1117N/A
1117N/A#ifdef DEBUG
1117N/A printf ("ServerFlags section parsed\n");
1117N/A#endif
1117N/A
1117N/A return ptr;
1117N/A}
1117N/A
1117N/A#undef CLEANUP
1117N/A
1117N/Avoid
1117N/Axf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags)
1117N/A{
1117N/A XF86OptionPtr p;
1117N/A
1117N/A if ((!flags) || (!flags->flg_option_lst))
1117N/A return;
1117N/A p = flags->flg_option_lst;
1117N/A fprintf (f, "Section \"ServerFlags\"\n");
1117N/A if (flags->flg_comment)
1117N/A fprintf (f, "%s", flags->flg_comment);
1117N/A xf86printOptionList(f, p, xf86whitespace_1);
1117N/A fprintf (f, "EndSection\n\n");
1117N/A}
1117N/A
1117N/A
1117N/A/*
1117N/A * xf86addNewOptionOrValue()
1117N/A *
1117N/A * Append a new Option record to the specified Option list if the
1117N/A * option name is not already present in the list. If the option
1117N/A * name is already present, replace the value, etc. of the existing
1117N/A * option. Return a pointer to the head of the list.
1117N/A */
1117N/A#if !defined(SMI_FBCONFIG)
1117N/Astatic
1117N/A#endif
1117N/AXF86OptionPtr
1117N/Axf86addNewOptionOrValue(
1117N/A XF86OptionPtr head, /* Ptr to head of option list */
1117N/A char *name, /* Ptr to new option name string */
1117N/A char *val, /* Ptr to new option value string */
1117N/A#if !defined(SMI_FBCONFIG)
1117N/A int used)
1117N/A#else
1117N/A int used, /* Not used w/ SMI_FBCONFIG */
1117N/A void *end_line_er) /* Ptr to End[Sub]Section, else NULL */
1117N/A#endif
1117N/A{
1117N/A XF86OptionPtr new; /* Ptr to new or existing option */
1117N/A XF86OptionPtr old; /* Ptr to existing option, if any */
1117N/A
1117N/A /*
1117N/A * Disallow duplicate option names, discarding any but the last one
1117N/A *
1117N/A * Note that xf86findOption() accepts NULL as the list head
1117N/A * and returns NULL in that case.
1117N/A */
1117N/A old = xf86findOption(head, name);
1117N/A if (old == NULL) {
1117N/A new = xf86confcalloc (1, sizeof (XF86OptionRec));
1117N/A new->list.next = NULL;
1117N/A } else {
1117N/A//??? Memory leak in some or all cases (e.g. when old->used==1) ???
1117N/A//??? xf86freeconfig(old->opt_name);
1117N/A//??? xf86freeconfig(old->opt_val);
1117N/A//??? Memory leak in some or all cases (e.g. when old->used==1) ???
1117N/A new = old;
1117N/A }
1117N/A
1117N/A new->opt_name = name;
1117N/A new->opt_val = val;
1117N/A new->opt_used = used;
1117N/A
1117N/A if (old == NULL) {
1117N/A#if defined(SMI_FBCONFIG)
1117N/A /*
1117N/A * Insert and link the External Representation of this option
1117N/A *
1117N/A * The External Representation of this new Option
1117N/A * line will be inserted just before the EndSection
1117N/A * or EndSubSection line (assuming our caller has
1117N/A * provided a pointer to the ER for the end line).
1117N/A */
1117N/A if (end_line_er != NULL) {
1117N/A fbc_insert_line_ER(end_line_er, (void *)new,
1117N/A (xf86_print_fn_t *)&xf86printOption,
1117N/A FBC_INDENT_ENTRY);
1117N/A }
1117N/A
1117N/A#endif
1117N/A /*
1117N/A * Add the new option and return the (new) list head
1117N/A */
1117N/A return ((XF86OptionPtr) xf86addListItem((glp)head, (glp)new));
1117N/A }
1117N/A
1117N/A#if defined(SMI_FBCONFIG)
1117N/A /*
1117N/A * Mark the External Representation of this option as modified
1117N/A *
1117N/A * If our caller hasn't provided a pointer (end_line_er) to
1117N/A * the External Representation of an EndSection or
1117N/A * EndSubSection line then it's likely that our caller isn't
1117N/A * on an SMI_FBCONFIG code path.
1117N/A */
1117N/A if (end_line_er != NULL) {
1117N/A fbc_modify_line_ER(new->opt_line_er);
1117N/A }
1117N/A
1117N/A#endif
1117N/A /*
1117N/A * Return the unchanged list head, having modified an existing option
1117N/A */
1117N/A return (head);
1117N/A}
1117N/A
1117N/A
1117N/A/*
1117N/A * xf86addNewOption()
1117N/A *
1117N/A * Append a new Option record to the specified Option list if the
1117N/A * option name is not already present in the list. If the option
1117N/A * name is already present, replace the value, etc. of the existing
1117N/A * option. Return a pointer to the head of the list.
1117N/A */
1117N/AXF86OptionPtr
1117N/Axf86addNewOption (XF86OptionPtr head, char *name, char *val)
1117N/A{
1117N/A#if !defined(SMI_FBCONFIG)
1117N/A return (xf86addNewOptionOrValue(head, name, val, 0));
1117N/A#else
1117N/A return (xf86addNewOptionOrValue(head, name, val, 0, NULL));
1117N/A#endif
1117N/A}
1117N/A
1117N/A
1117N/Avoid
1117N/Axf86freeFlags (XF86ConfFlagsPtr flags)
1117N/A{
1117N/A if (flags == NULL)
1117N/A return;
1117N/A xf86optionListFree (flags->flg_option_lst);
1117N/A TestFree(flags->flg_comment);
1117N/A xf86conffree (flags);
1117N/A}
1117N/A
1117N/AXF86OptionPtr
1117N/Axf86optionListDup (XF86OptionPtr opt)
1117N/A{
1117N/A XF86OptionPtr newopt = NULL;
1117N/A
1117N/A while (opt)
1117N/A {
1117N/A newopt = xf86addNewOption(newopt, xf86configStrdup(opt->opt_name),
1117N/A xf86configStrdup(opt->opt_val));
1117N/A newopt->opt_used = opt->opt_used;
1117N/A if (opt->opt_comment)
1117N/A newopt->opt_comment = xf86configStrdup(opt->opt_comment);
1117N/A opt = opt->list.next;
1117N/A }
1117N/A return newopt;
1117N/A}
1117N/A
1117N/Avoid
1117N/Axf86optionListFree (XF86OptionPtr opt)
1117N/A{
1117N/A XF86OptionPtr prev;
1117N/A
1117N/A while (opt)
1117N/A {
1117N/A TestFree (opt->opt_name);
1117N/A TestFree (opt->opt_val);
1117N/A TestFree (opt->opt_comment);
1117N/A prev = opt;
1117N/A opt = opt->list.next;
1117N/A xf86conffree (prev);
1117N/A }
1117N/A}
1117N/A
1117N/Achar *
1117N/Axf86optionName(XF86OptionPtr opt)
1117N/A{
1117N/A if (opt)
1117N/A return opt->opt_name;
1117N/A return 0;
1117N/A}
1117N/A
1117N/Achar *
1117N/Axf86optionValue(XF86OptionPtr opt)
1117N/A{
1117N/A if (opt)
1117N/A return opt->opt_val;
1117N/A return 0;
1117N/A}
1117N/A
1117N/AXF86OptionPtr
1117N/Axf86newOption(char *name, char *value)
1117N/A{
1117N/A XF86OptionPtr opt;
1117N/A
1117N/A opt = xf86confcalloc(1, sizeof (XF86OptionRec));
1117N/A if (!opt)
1117N/A return NULL;
1117N/A
1117N/A opt->opt_used = 0;
1117N/A opt->list.next = 0;
1117N/A opt->opt_name = name;
1117N/A opt->opt_val = value;
1117N/A
1117N/A return opt;
1117N/A}
1117N/A
1117N/AXF86OptionPtr
1117N/Axf86nextOption(XF86OptionPtr list)
1117N/A{
1117N/A if (!list)
1117N/A return NULL;
1117N/A return list->list.next;
1117N/A}
1117N/A
1117N/A/*
1117N/A * This function searches the given option list for the named option and
1117N/A * returns a pointer to the option rec if found. If not found, it returns
1117N/A * NULL.
1117N/A */
1117N/A
1117N/AXF86OptionPtr
1117N/Axf86findOption (XF86OptionPtr list, const char *name)
1117N/A{
1117N/A /*
1117N/A * Known Boolean option names, which accept a "No" prefix
1117N/A *
1117N/A * This table is arranged in xorg.conf(4) man page order,
1117N/A * merely for ease of its creation and potential maintenance.
1117N/A *
1117N/A * What should the opposites of the following Boolean option
1117N/A * names be?
1117N/A * "NoTrapSignals" - "NoNoTrapSignals" or "TrapSignals"
1117N/A * "NoPM" - "NoNoPM" or "PM"
1117N/A * "NoInt10" - "NoNoInt10" or "Int10"
1117N/A */
1117N/A static const char * const bool_option_names[] =
1117N/A {
1117N/A /*
1117N/A * ServerFlags Section
1117N/A */
1117N/A "NoTrapSignals", /* ??? Not a negated option name */
1117N/A "DontVTSwitch",
1117N/A "DontZap",
1117N/A "DontZoom",
1117N/A "DisableVidModeExtension",
1117N/A "AllowNonLocalXvidtune",
1117N/A "DisableModInDev",
1117N/A "AllowNonLocalModInDev",
1117N/A "AllowMouseOpenFail",
1117N/A "VTSysReq",
1117N/A "XkbDisable",
1117N/A "PC98",
1117N/A "NoPM", /* ??? Not a negated option name */
1117N/A "Xinerama",
1117N/A "AllowDeactivateGrabs",
1117N/A "AllowClosedownGrabs",
1117N/A /*
1117N/A * InputDevice section
1117N/A */
1117N/A "AIGLX",
1117N/A "IgnoreABI",
1117N/A /*
1117N/A * Module section
1117N/A */
1117N/A "AlwaysCore",
1117N/A "SendCoreEvents",
1117N/A "SendDragEvents",
1117N/A /*
1117N/A * Monitor section
1117N/A */
1117N/A "DPMS",
1117N/A "SyncOnGreen",
1117N/A "Enable",
1117N/A "Ignore",
1117N/A /*
1117N/A * Screen section
1117N/A */
1117N/A "InitPrimary",
1117N/A "NoInt10", /* ??? Not a negated option name */
1117N/A "SingleCard",
1117N/A#if defined(SMI_FBCONFIG)
1117N/A FBC_KEYWD_DefLinear, /* Display subsection */
1117N/A FBC_KEYWD_DefOverlay, /* Display subsection */
1117N/A FBC_KEYWD_DefTransparent, /* Display subsection */
1117N/A FBC_KEYWD_DoubleHigh, /* ??? Is this really a Boolean ??? */
1117N/A FBC_KEYWD_DoubleWide, /* ??? Is this really a Boolean ??? */
1117N/A#endif
1117N/A NULL /* End-of-table marker */
1117N/A };
1117N/A
1117N/A for ( ; list != NULL; list = list->list.next)
1117N/A {
1117N/A if (xf86optionNameCompare (
1117N/A bool_option_names, list->opt_name, name) == 0)
1117N/A {
1117N/A return (list);
1117N/A }
1117N/A }
1117N/A return (NULL);
1117N/A}
1117N/A
1117N/A/*
1117N/A * This function searches the given option list for the named option. If
1117N/A * found and the option has a parameter, a pointer to the parameter is
1117N/A * returned. If the option does not have a parameter, an empty string
1117N/A * is returned. If the option is not found, a NULL is returned.
1117N/A */
1117N/A
1117N/Achar *
1117N/Axf86findOptionValue (XF86OptionPtr list, const char *name)
1117N/A{
1117N/A XF86OptionPtr p = xf86findOption (list, name);
1117N/A
1117N/A if (p)
1117N/A {
1117N/A if (p->opt_val)
1117N/A return (p->opt_val);
1117N/A else
1117N/A return "";
1117N/A }
1117N/A return (NULL);
1117N/A}
1117N/A
1117N/A/*
1117N/A * xf86optionListCreate()
1117N/A *
1117N/A * Create and return a list of options from an array of option &
1117N/A * value string pairs. The size of the array is specified by a
1117N/A * non-negative "count" value or else by a NULL as the last element
1117N/A * of the array. The purpose of "used," which appears to be Boolean,
1117N/A * has been documented only by its name.
1117N/A */
1117N/AXF86OptionPtr
1117N/Axf86optionListCreate( const char **options, int count, int used )
1117N/A{
1117N/A XF86OptionPtr p = NULL;
1117N/A char *t1, *t2;
1117N/A int i;
1117N/A
1117N/A if (count == -1)
1117N/A {
1117N/A for (count = 0; options[count]; count++)
1117N/A ;
1117N/A }
1117N/A if( (count % 2) != 0 )
1117N/A {
1117N/A fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" );
1117N/A return (NULL);
1117N/A }
1117N/A for (i = 0; i < count; i += 2)
1117N/A {
1117N/A /* can't use strdup because it calls malloc */
1117N/A t1 = xf86confmalloc (sizeof (char) *
1117N/A (strlen (options[i]) + 1));
1117N/A strcpy (t1, options[i]);
1117N/A t2 = xf86confmalloc (sizeof (char) *
1117N/A (strlen (options[i + 1]) + 1));
1117N/A strcpy (t2, options[i + 1]);
1117N/A#if !defined(SMI_FBCONFIG)
1117N/A p = xf86addNewOptionOrValue(p, t1, t2, used);
1117N/A#else
1117N/A p = xf86addNewOptionOrValue(p, t1, t2, used, NULL);
1117N/A#endif
1117N/A }
1117N/A
1117N/A return (p);
1117N/A}
1117N/A
1117N/A/* the 2 given lists are merged. If an option with the same name is present in
1117N/A * both, the option from the user list - specified in the second argument -
1117N/A * is used. The end result is a single valid list of options. Duplicates
1117N/A * are freed, and the original lists are no longer guaranteed to be complete.
1117N/A */
1117N/AXF86OptionPtr
1117N/Axf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail)
1117N/A{
1117N/A XF86OptionPtr a, b, ap = NULL, bp = NULL;
1117N/A
1117N/A a = tail;
1117N/A b = head;
1117N/A while (tail && b) {
1117N/A if (xf86nameCompare (a->opt_name, b->opt_name) == 0) {
1117N/A if (b == head)
1117N/A head = a;
1117N/A else
1117N/A bp->list.next = a;
1117N/A if (a == tail)
1117N/A tail = a->list.next;
1117N/A else
1117N/A ap->list.next = a->list.next;
1117N/A a->list.next = b->list.next;
1117N/A b->list.next = NULL;
1117N/A xf86optionListFree (b);
1117N/A b = a->list.next;
1117N/A bp = a;
1117N/A a = tail;
1117N/A ap = NULL;
1117N/A } else {
1117N/A ap = a;
1117N/A if (!(a = a->list.next)) {
1117N/A a = tail;
1117N/A bp = b;
1117N/A b = b->list.next;
1117N/A ap = NULL;
1117N/A }
1117N/A }
1117N/A }
1117N/A
1117N/A if (head) {
1117N/A for (a = head; a->list.next; a = a->list.next)
1117N/A ;
1117N/A a->list.next = tail;
1117N/A } else
1117N/A head = tail;
1117N/A
1117N/A return (head);
1117N/A}
1117N/A
1117N/Achar *
1117N/Axf86uLongToString(unsigned long i)
1117N/A{
1117N/A char *s;
1117N/A int l;
1117N/A
1117N/A l = (int)(ceil(log10((double)i) + 2.5));
1117N/A s = xf86confmalloc(l);
1117N/A if (!s)
1117N/A return NULL;
1117N/A sprintf(s, "%lu", i);
1117N/A return s;
1117N/A}
1117N/A
1117N/Avoid
1117N/Axf86debugListOptions(XF86OptionPtr Options)
1117N/A{
1117N/A while (Options) {
1117N/A ErrorF("Option: %s Value: %s\n",Options->opt_name,Options->opt_val);
1117N/A Options = Options->list.next;
1117N/A }
1117N/A}
1117N/A
1117N/A
1117N/A/*
1117N/A * xf86parseOption()
1117N/A *
1117N/A * Parse the current Option line. Complain about bad Option lines.
1117N/A * Discard duplicate option names. Otherwise, append the new option
1117N/A * to the Option list specified by "head."
1117N/A */
1117N/AXF86OptionPtr
1117N/Axf86parseOption(XF86OptionPtr head)
1117N/A{
1117N/A XF86OptionPtr option, old;
1117N/A char *name, *comment = NULL;
1117N/A int token;
1117N/A#if defined(SMI_FBCONFIG)
1117N/A void *line_er; /* Ptr to External Rep of Option line */
1117N/A
1117N/A /*
1117N/A * Get a pointer to the External Representation of this Option line
1117N/A */
1117N/A line_er = fbc_get_current_line_ER();
1117N/A#endif
1117N/A
1117N/A /*
1117N/A * Get the option name token
1117N/A */
1117N/A if ((token = xf86getSubToken(&comment)) != STRING) {
1117N/A xf86parseError(BAD_OPTION_MSG, NULL);
1117N/A if (comment)
1117N/A xf86conffree(comment);
1117N/A return (head);
1117N/A }
1117N/A name = val.str;
1117N/A
1117N/A /*
1117N/A * Get the option value token, if any, and comment string, if any
1117N/A */
1117N/A if ((token = xf86getSubToken(&comment)) == STRING) {
1117N/A option = xf86newOption(name, val.str);
1117N/A option->opt_comment = comment;
1117N/A if ((token = xf86getToken(NULL)) == COMMENT)
1117N/A option->opt_comment = xf86addComment(option->opt_comment, val.str);
1117N/A else
1117N/A xf86unGetToken(token);
1117N/A }
1117N/A else {
1117N/A option = xf86newOption(name, NULL);
1117N/A option->opt_comment = comment;
1117N/A if (token == COMMENT)
1117N/A option->opt_comment = xf86addComment(option->opt_comment, val.str);
1117N/A else
1117N/A xf86unGetToken(token);
1117N/A }
1117N/A
1117N/A /*
1117N/A * Disallow duplicate option names, discarding any but the first one
1117N/A *
1117N/A * Note that xf86findOption() accepts NULL as the list head
1117N/A * and returns NULL in that case.
1117N/A */
1117N/A old = xf86findOption(head, name);
1117N/A if (old != NULL) {
1117N/A xf86conffree(option->opt_name);
1117N/A TestFree(option->opt_val);
1117N/A TestFree(option->opt_comment);
1117N/A xf86conffree(option);
1117N/A#if defined(SMI_FBCONFIG)
1117N/A fbc_delete_line_ER(line_er); /* Delete config line from ER */
1117N/A#endif
1117N/A return (head);
1117N/A }
1117N/A
1117N/A#if defined(SMI_FBCONFIG)
1117N/A /*
1117N/A * Link the Internal and External Representations of this Option line
1117N/A */
1117N/A option->opt_line_er = line_er;
1117N/A fbc_link_line_ER(line_er,
1117N/A (void *)option,
1117N/A (xf86_print_fn_t*)&xf86printOption,
1117N/A FBC_INDENT_ENTRY);
1117N/A
1117N/A#endif
1117N/A return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)option));
1117N/A}
1117N/A
1117N/A
1117N/A/*
1117N/A * xf86printOption()
1117N/A *
1117N/A * Write an Option line to the output configuration file.
1117N/A */
1117N/Avoid
1117N/Axf86printOption(
1117N/A FILE *fp, XF86OptionPtr option, const char * const whitespace[])
1117N/A{
1117N/A char *comment; /* Comment or end-of-line text */
1117N/A
1117N/A /*
1117N/A * Comment or end-of-line text
1117N/A */
1117N/A comment = "\n";
1117N/A if (option->opt_comment != NULL) {
1117N/A comment = option->opt_comment;
1117N/A }
1117N/A
1117N/A /*
1117N/A * Write the Option line, which may include an Option value
1117N/A */
1117N/A xf86printFields(fp, whitespace, "Option", NULL);
1117N/A if (option->opt_val != NULL) {
1117N/A fprintf(fp, "\"%s\" \"%s\"%s",
1117N/A option->opt_name, option->opt_val, comment);
1117N/A } else {
1117N/A fprintf(fp, "\"%s\"%s", option->opt_name, comment);
1117N/A }
1117N/A}
1117N/A
1117N/A
1117N/A/*
1117N/A * xf86printOptionList()
1117N/A *
1117N/A * Write all of the Option lines of a (sub)section to the output
1117N/A * configuration file.
1117N/A */
1117N/Avoid
1117N/Axf86printOptionList(
1117N/A FILE *fp, XF86OptionPtr list, const char * const whitespace[])
1117N/A{
1117N/A
1117N/A for ( ; list != NULL; list = list->list.next) {
1117N/A xf86printOption(fp, list, whitespace);
1117N/A }
1117N/A}
1117N/A