diff options
Diffstat (limited to 'hw/xfree86/parser/Flags.c')
-rw-r--r-- | hw/xfree86/parser/Flags.c | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/hw/xfree86/parser/Flags.c b/hw/xfree86/parser/Flags.c new file mode 100644 index 000000000..dfd3ab0bd --- /dev/null +++ b/hw/xfree86/parser/Flags.c @@ -0,0 +1,494 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Flags.c,v 1.22 2003/01/04 20:20:22 paulo Exp $ */ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" +#include <math.h> + +extern LexRec val; + +static xf86ConfigSymTabRec ServerFlagsTab[] = +{ + {ENDSECTION, "endsection"}, + {NOTRAPSIGNALS, "notrapsignals"}, + {DONTZAP, "dontzap"}, + {DONTZOOM, "dontzoom"}, + {DISABLEVIDMODE, "disablevidmodeextension"}, + {ALLOWNONLOCAL, "allownonlocalxvidtune"}, + {DISABLEMODINDEV, "disablemodindev"}, + {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"}, + {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"}, + {OPTION, "option"}, + {BLANKTIME, "blanktime"}, + {STANDBYTIME, "standbytime"}, + {SUSPENDTIME, "suspendtime"}, + {OFFTIME, "offtime"}, + {DEFAULTLAYOUT, "defaultserverlayout"}, + {-1, ""}, +}; + +#define CLEANUP xf86freeFlags + +XF86ConfFlagsPtr +xf86parseFlagsSection (void) +{ + int token; + parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec) + + while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION) + { + int hasvalue = FALSE; + int strvalue = FALSE; + int tokentype; + switch (token) + { + case COMMENT: + ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str); + break; + /* + * these old keywords are turned into standard generic options. + * we fall through here on purpose + */ + case DEFAULTLAYOUT: + strvalue = TRUE; + case BLANKTIME: + case STANDBYTIME: + case SUSPENDTIME: + case OFFTIME: + hasvalue = TRUE; + case NOTRAPSIGNALS: + case DONTZAP: + case DONTZOOM: + case DISABLEVIDMODE: + case ALLOWNONLOCAL: + case DISABLEMODINDEV: + case MODINDEVALLOWNONLOCAL: + case ALLOWMOUSEOPENFAIL: + { + int i = 0; + while (ServerFlagsTab[i].token != -1) + { + char *tmp; + + if (ServerFlagsTab[i].token == token) + { + char *valstr = NULL; + /* can't use strdup because it calls malloc */ + tmp = xf86configStrdup (ServerFlagsTab[i].name); + if (hasvalue) + { + tokentype = xf86getSubToken(&(ptr->flg_comment)); + if (strvalue) { + if (tokentype != STRING) + Error (QUOTE_MSG, tmp); + valstr = val.str; + } else { + if (tokentype != NUMBER) + Error (NUMBER_MSG, tmp); + valstr = xf86confmalloc(16); + if (valstr) + sprintf(valstr, "%d", val.num); + } + } + ptr->flg_option_lst = xf86addNewOption + (ptr->flg_option_lst, tmp, valstr); + } + i++; + } + } + break; + case OPTION: + ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst); + break; + + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xf86tokenString ()); + break; + } + } + +#ifdef DEBUG + printf ("Flags section parsed\n"); +#endif + + return ptr; +} + +#undef CLEANUP + +void +xf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags) +{ + XF86OptionPtr p; + + if ((!flags) || (!flags->flg_option_lst)) + return; + p = flags->flg_option_lst; + fprintf (f, "Section \"ServerFlags\"\n"); + if (flags->flg_comment) + fprintf (f, "%s", flags->flg_comment); + xf86printOptionList(f, p, 1); + fprintf (f, "EndSection\n\n"); +} + +static XF86OptionPtr +addNewOption2 (XF86OptionPtr head, char *name, char *val, int used) +{ + XF86OptionPtr new, old = NULL; + + /* Don't allow duplicates */ + if (head != NULL && (old = xf86findOption(head, name)) != NULL) + new = old; + else { + new = xf86confcalloc (1, sizeof (XF86OptionRec)); + new->list.next = NULL; + } + new->opt_name = name; + new->opt_val = val; + new->opt_used = used; + + if (old == NULL) + return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new)); + else + return head; +} + +XF86OptionPtr +xf86addNewOption (XF86OptionPtr head, char *name, char *val) +{ + return addNewOption2(head, name, val, 0); +} + +void +xf86freeFlags (XF86ConfFlagsPtr flags) +{ + if (flags == NULL) + return; + xf86optionListFree (flags->flg_option_lst); + TestFree(flags->flg_comment); + xf86conffree (flags); +} + +XF86OptionPtr +xf86optionListDup (XF86OptionPtr opt) +{ + XF86OptionPtr newopt = NULL; + + while (opt) + { + newopt = xf86addNewOption(newopt, xf86configStrdup(opt->opt_name), + xf86configStrdup(opt->opt_val)); + newopt->opt_used = opt->opt_used; + if (opt->opt_comment) + newopt->opt_comment = xf86configStrdup(opt->opt_comment); + opt = opt->list.next; + } + return newopt; +} + +void +xf86optionListFree (XF86OptionPtr opt) +{ + XF86OptionPtr prev; + + while (opt) + { + TestFree (opt->opt_name); + TestFree (opt->opt_val); + TestFree (opt->opt_comment); + prev = opt; + opt = opt->list.next; + xf86conffree (prev); + } +} + +char * +xf86optionName(XF86OptionPtr opt) +{ + if (opt) + return opt->opt_name; + return 0; +} + +char * +xf86optionValue(XF86OptionPtr opt) +{ + if (opt) + return opt->opt_val; + return 0; +} + +XF86OptionPtr +xf86newOption(char *name, char *value) +{ + XF86OptionPtr opt; + + opt = xf86confcalloc(1, sizeof (XF86OptionRec)); + if (!opt) + return NULL; + + opt->opt_used = 0; + opt->list.next = 0; + opt->opt_name = name; + opt->opt_val = value; + + return opt; +} + +XF86OptionPtr +xf86nextOption(XF86OptionPtr list) +{ + if (!list) + return NULL; + return list->list.next; +} + +/* + * this function searches the given option list for the named option and + * returns a pointer to the option rec if found. If not found, it returns + * NULL + */ + +XF86OptionPtr +xf86findOption (XF86OptionPtr list, const char *name) +{ + while (list) + { + if (xf86nameCompare (list->opt_name, name) == 0) + return (list); + list = list->list.next; + } + return (NULL); +} + +/* + * this function searches the given option list for the named option. If + * found and the option has a parameter, a pointer to the parameter is + * returned. If the option does not have a parameter an empty string is + * returned. If the option is not found, a NULL is returned. + */ + +char * +xf86findOptionValue (XF86OptionPtr list, const char *name) +{ + XF86OptionPtr p = xf86findOption (list, name); + + if (p) + { + if (p->opt_val) + return (p->opt_val); + else + return ""; + } + return (NULL); +} + +XF86OptionPtr +xf86optionListCreate( const char **options, int count, int used ) +{ + XF86OptionPtr p = NULL; + char *t1, *t2; + int i; + + if (count == -1) + { + for (count = 0; options[count]; count++) + ; + } + if( (count % 2) != 0 ) + { + fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" ); + return (NULL); + } + for (i = 0; i < count; i += 2) + { + /* can't use strdup because it calls malloc */ + t1 = xf86confmalloc (sizeof (char) * + (strlen (options[i]) + 1)); + strcpy (t1, options[i]); + t2 = xf86confmalloc (sizeof (char) * + (strlen (options[i + 1]) + 1)); + strcpy (t2, options[i + 1]); + p = addNewOption2 (p, t1, t2, used); + } + + return (p); +} + +/* the 2 given lists are merged. If an option with the same name is present in + * both, the option from the user list - specified in the second argument - + * is used. The end result is a single valid list of options. Duplicates + * are freed, and the original lists are no longer guaranteed to be complete. + */ +XF86OptionPtr +xf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail) +{ + XF86OptionPtr a, b, ap = NULL, bp = NULL; + + a = tail; + b = head; + while (tail && b) { + if (xf86nameCompare (a->opt_name, b->opt_name) == 0) { + if (b == head) + head = a; + else + bp->list.next = a; + if (a == tail) + tail = a->list.next; + else + ap->list.next = a->list.next; + a->list.next = b->list.next; + b->list.next = NULL; + xf86optionListFree (b); + b = a->list.next; + bp = a; + a = tail; + ap = NULL; + } else { + ap = a; + if (!(a = a->list.next)) { + a = tail; + bp = b; + b = b->list.next; + ap = NULL; + } + } + } + + if (head) { + for (a = head; a->list.next; a = a->list.next) + ; + a->list.next = tail; + } else + head = tail; + + return (head); +} + +char * +xf86uLongToString(unsigned long i) +{ + char *s; + int l; + + l = (int)(ceil(log10((double)i) + 2.5)); + s = xf86confmalloc(l); + if (!s) + return NULL; + sprintf(s, "%lu", i); + return s; +} + +void +xf86debugListOptions(XF86OptionPtr Options) +{ + while (Options) { + ErrorF("Option: %s Value: %s\n",Options->opt_name,Options->opt_val); + Options = Options->list.next; + } +} + +XF86OptionPtr +xf86parseOption(XF86OptionPtr head) +{ + XF86OptionPtr option, cnew, old; + char *name, *comment = NULL; + int token; + + if ((token = xf86getSubToken(&comment)) != STRING) { + xf86parseError(BAD_OPTION_MSG, NULL); + if (comment) + xf86conffree(comment); + return (head); + } + + name = val.str; + if ((token = xf86getSubToken(&comment)) == STRING) { + option = xf86newOption(name, val.str); + option->opt_comment = comment; + if ((token = xf86getToken(NULL)) == COMMENT) + option->opt_comment = xf86addComment(option->opt_comment, val.str); + else + xf86unGetToken(token); + } + else { + option = xf86newOption(name, NULL); + option->opt_comment = comment; + if (token == COMMENT) + option->opt_comment = xf86addComment(option->opt_comment, val.str); + else + xf86unGetToken(token); + } + + old = NULL; + + /* Don't allow duplicates */ + if (head != NULL && (old = xf86findOption(head, name)) != NULL) { + cnew = old; + xf86conffree(option->opt_name); + TestFree(option->opt_val); + TestFree(option->opt_comment); + xf86conffree(option); + } + else + cnew = option; + + if (old == NULL) + return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew)); + + return (head); +} + +void +xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs) +{ + int i; + + if (!list) + return; + while (list) { + for (i = 0; i < tabs; i++) + fputc('\t', fp); + if (list->opt_val) + fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, list->opt_val); + else + fprintf(fp, "Option \"%s\"", list->opt_name); + if (list->opt_comment) + fprintf(fp, "%s", list->opt_comment); + else + fputc('\n', fp); + list = list->list.next; + } +} |