Flags.c revision ed6184df
1/* 2 * Copyright (c) 1997 Metro Link Incorporated 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the Metro Link shall not be 23 * used in advertising or otherwise to promote the sale, use or other dealings 24 * in this Software without prior written authorization from Metro Link. 25 * 26 */ 27/* 28 * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 29 * 30 * Permission is hereby granted, free of charge, to any person obtaining a 31 * copy of this software and associated documentation files (the "Software"), 32 * to deal in the Software without restriction, including without limitation 33 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 34 * and/or sell copies of the Software, and to permit persons to whom the 35 * Software is furnished to do so, subject to the following conditions: 36 * 37 * The above copyright notice and this permission notice shall be included in 38 * all copies or substantial portions of the Software. 39 * 40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 43 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 46 * OTHER DEALINGS IN THE SOFTWARE. 47 * 48 * Except as contained in this notice, the name of the copyright holder(s) 49 * and author(s) shall not be used in advertising or otherwise to promote 50 * the sale, use or other dealings in this Software without prior written 51 * authorization from the copyright holder(s) and author(s). 52 */ 53 54#ifdef HAVE_XORG_CONFIG_H 55#include <xorg-config.h> 56#endif 57 58#include "xf86Parser.h" 59#include "xf86tokens.h" 60#include "Configint.h" 61#include <X11/Xfuncproto.h> 62#include "Xprintf.h" 63#include "optionstr.h" 64 65 66static const xf86ConfigSymTabRec ServerFlagsTab[] = { 67 {ENDSECTION, "endsection"}, 68 {DONTZAP, "dontzap"}, 69 {DONTZOOM, "dontzoom"}, 70 {DISABLEVIDMODE, "disablevidmodeextension"}, 71 {ALLOWNONLOCAL, "allownonlocalxvidtune"}, 72 {DISABLEMODINDEV, "disablemodindev"}, 73 {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"}, 74 {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"}, 75 {OPTION, "option"}, 76 {BLANKTIME, "blanktime"}, 77 {STANDBYTIME, "standbytime"}, 78 {SUSPENDTIME, "suspendtime"}, 79 {OFFTIME, "offtime"}, 80 {DEFAULTLAYOUT, "defaultserverlayout"}, 81 {-1, ""}, 82}; 83 84#define CLEANUP xf86freeFlags 85 86XF86ConfFlagsPtr 87xf86parseFlagsSection(void) 88{ 89 int token; 90 91 parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec) 92 93 while ((token = xf86getToken(ServerFlagsTab)) != ENDSECTION) { 94 int hasvalue = FALSE; 95 int strvalue = FALSE; 96 int tokentype; 97 98 switch (token) { 99 case COMMENT: 100 ptr->flg_comment = xf86addComment(ptr->flg_comment, xf86_lex_val.str); 101 break; 102 /* 103 * these old keywords are turned into standard generic options. 104 * we fall through here on purpose 105 */ 106 case DEFAULTLAYOUT: 107 strvalue = TRUE; 108 case BLANKTIME: 109 case STANDBYTIME: 110 case SUSPENDTIME: 111 case OFFTIME: 112 hasvalue = TRUE; 113 case DONTZAP: 114 case DONTZOOM: 115 case DISABLEVIDMODE: 116 case ALLOWNONLOCAL: 117 case DISABLEMODINDEV: 118 case MODINDEVALLOWNONLOCAL: 119 case ALLOWMOUSEOPENFAIL: 120 { 121 int i = 0; 122 123 while (ServerFlagsTab[i].token != -1) { 124 char *tmp; 125 126 if (ServerFlagsTab[i].token == token) { 127 char *valstr = NULL; 128 129 tmp = strdup(ServerFlagsTab[i].name); 130 if (hasvalue) { 131 tokentype = xf86getSubToken(&(ptr->flg_comment)); 132 if (strvalue) { 133 if (tokentype != STRING) 134 Error(QUOTE_MSG, tmp); 135 valstr = xf86_lex_val.str; 136 } 137 else { 138 if (tokentype != NUMBER) 139 Error(NUMBER_MSG, tmp); 140 if (asprintf(&valstr, "%d", xf86_lex_val.num) == -1) 141 valstr = NULL; 142 } 143 } 144 ptr->flg_option_lst = xf86addNewOption 145 (ptr->flg_option_lst, tmp, valstr); 146 } 147 i++; 148 } 149 } 150 break; 151 case OPTION: 152 ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst); 153 break; 154 155 case EOF_TOKEN: 156 Error(UNEXPECTED_EOF_MSG); 157 break; 158 default: 159 Error(INVALID_KEYWORD_MSG, xf86tokenString()); 160 break; 161 } 162 } 163 164#ifdef DEBUG 165 printf("Flags section parsed\n"); 166#endif 167 168 return ptr; 169} 170 171#undef CLEANUP 172 173void 174xf86printServerFlagsSection(FILE * f, XF86ConfFlagsPtr flags) 175{ 176 XF86OptionPtr p; 177 178 if ((!flags) || (!flags->flg_option_lst)) 179 return; 180 p = flags->flg_option_lst; 181 fprintf(f, "Section \"ServerFlags\"\n"); 182 if (flags->flg_comment) 183 fprintf(f, "%s", flags->flg_comment); 184 xf86printOptionList(f, p, 1); 185 fprintf(f, "EndSection\n\n"); 186} 187 188static XF86OptionPtr 189addNewOption2(XF86OptionPtr head, char *name, char *_val, int used) 190{ 191 XF86OptionPtr new, old = NULL; 192 193 /* Don't allow duplicates, free old strings */ 194 if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 195 new = old; 196 free(new->opt_name); 197 free(new->opt_val); 198 } 199 else 200 new = calloc(1, sizeof(*new)); 201 new->opt_name = name; 202 new->opt_val = _val; 203 new->opt_used = used; 204 205 if (old) 206 return head; 207 return ((XF86OptionPtr) xf86addListItem((glp) head, (glp) new)); 208} 209 210XF86OptionPtr 211xf86addNewOption(XF86OptionPtr head, char *name, char *_val) 212{ 213 return addNewOption2(head, name, _val, 0); 214} 215 216void 217xf86freeFlags(XF86ConfFlagsPtr flags) 218{ 219 if (flags == NULL) 220 return; 221 xf86optionListFree(flags->flg_option_lst); 222 TestFree(flags->flg_comment); 223 free(flags); 224} 225 226XF86OptionPtr 227xf86optionListDup(XF86OptionPtr opt) 228{ 229 XF86OptionPtr newopt = NULL; 230 char *_val; 231 232 while (opt) { 233 _val = opt->opt_val ? strdup(opt->opt_val) : NULL; 234 newopt = xf86addNewOption(newopt, strdup(opt->opt_name), _val); 235 newopt->opt_used = opt->opt_used; 236 if (opt->opt_comment) 237 newopt->opt_comment = strdup(opt->opt_comment); 238 opt = opt->list.next; 239 } 240 return newopt; 241} 242 243void 244xf86optionListFree(XF86OptionPtr opt) 245{ 246 XF86OptionPtr prev; 247 248 while (opt) { 249 TestFree(opt->opt_name); 250 TestFree(opt->opt_val); 251 TestFree(opt->opt_comment); 252 prev = opt; 253 opt = opt->list.next; 254 free(prev); 255 } 256} 257 258char * 259xf86optionName(XF86OptionPtr opt) 260{ 261 if (opt) 262 return opt->opt_name; 263 return 0; 264} 265 266char * 267xf86optionValue(XF86OptionPtr opt) 268{ 269 if (opt) 270 return opt->opt_val; 271 return 0; 272} 273 274XF86OptionPtr 275xf86newOption(char *name, char *value) 276{ 277 XF86OptionPtr opt; 278 279 opt = calloc(1, sizeof(*opt)); 280 if (!opt) 281 return NULL; 282 283 opt->opt_used = 0; 284 opt->list.next = 0; 285 opt->opt_name = name; 286 opt->opt_val = value; 287 288 return opt; 289} 290 291XF86OptionPtr 292xf86nextOption(XF86OptionPtr list) 293{ 294 if (!list) 295 return NULL; 296 return list->list.next; 297} 298 299/* 300 * this function searches the given option list for the named option and 301 * returns a pointer to the option rec if found. If not found, it returns 302 * NULL 303 */ 304 305XF86OptionPtr 306xf86findOption(XF86OptionPtr list, const char *name) 307{ 308 while (list) { 309 if (xf86nameCompare(list->opt_name, name) == 0) 310 return list; 311 list = list->list.next; 312 } 313 return NULL; 314} 315 316/* 317 * this function searches the given option list for the named option. If 318 * found and the option has a parameter, a pointer to the parameter is 319 * returned. If the option does not have a parameter an empty string is 320 * returned. If the option is not found, a NULL is returned. 321 */ 322 323const char * 324xf86findOptionValue(XF86OptionPtr list, const char *name) 325{ 326 XF86OptionPtr p = xf86findOption(list, name); 327 328 if (p) { 329 if (p->opt_val) 330 return p->opt_val; 331 else 332 return ""; 333 } 334 return NULL; 335} 336 337XF86OptionPtr 338xf86optionListCreate(const char **options, int count, int used) 339{ 340 XF86OptionPtr p = NULL; 341 char *t1, *t2; 342 int i; 343 344 if (count == -1) { 345 for (count = 0; options[count]; count++); 346 } 347 if ((count % 2) != 0) { 348 fprintf(stderr, 349 "xf86optionListCreate: count must be an even number.\n"); 350 return NULL; 351 } 352 for (i = 0; i < count; i += 2) { 353 t1 = strdup(options[i]); 354 t2 = strdup(options[i + 1]); 355 p = addNewOption2(p, t1, t2, used); 356 } 357 358 return p; 359} 360 361/* the 2 given lists are merged. If an option with the same name is present in 362 * both, the option from the user list - specified in the second argument - 363 * is used. The end result is a single valid list of options. Duplicates 364 * are freed, and the original lists are no longer guaranteed to be complete. 365 */ 366XF86OptionPtr 367xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail) 368{ 369 XF86OptionPtr a, b, ap = NULL, bp = NULL; 370 371 a = tail; 372 b = head; 373 while (tail && b) { 374 if (xf86nameCompare(a->opt_name, b->opt_name) == 0) { 375 if (b == head) 376 head = a; 377 else 378 bp->list.next = a; 379 if (a == tail) 380 tail = a->list.next; 381 else 382 ap->list.next = a->list.next; 383 a->list.next = b->list.next; 384 b->list.next = NULL; 385 xf86optionListFree(b); 386 b = a->list.next; 387 bp = a; 388 a = tail; 389 ap = NULL; 390 } 391 else { 392 ap = a; 393 if (!(a = a->list.next)) { 394 a = tail; 395 bp = b; 396 b = b->list.next; 397 ap = NULL; 398 } 399 } 400 } 401 402 if (head) { 403 for (a = head; a->list.next; a = a->list.next); 404 a->list.next = tail; 405 } 406 else 407 head = tail; 408 409 return head; 410} 411 412char * 413xf86uLongToString(unsigned long i) 414{ 415 char *s; 416 417 if (asprintf(&s, "%lu", i) == -1) 418 return NULL; 419 return s; 420} 421 422XF86OptionPtr 423xf86parseOption(XF86OptionPtr head) 424{ 425 XF86OptionPtr option, cnew, old; 426 char *name, *comment = NULL; 427 int token; 428 429 if ((token = xf86getSubToken(&comment)) != STRING) { 430 xf86parseError(BAD_OPTION_MSG); 431 free(comment); 432 return head; 433 } 434 435 name = xf86_lex_val.str; 436 if ((token = xf86getSubToken(&comment)) == STRING) { 437 option = xf86newOption(name, xf86_lex_val.str); 438 option->opt_comment = comment; 439 if ((token = xf86getToken(NULL)) == COMMENT) 440 option->opt_comment = xf86addComment(option->opt_comment, xf86_lex_val.str); 441 else 442 xf86unGetToken(token); 443 } 444 else { 445 option = xf86newOption(name, NULL); 446 option->opt_comment = comment; 447 if (token == COMMENT) 448 option->opt_comment = xf86addComment(option->opt_comment, xf86_lex_val.str); 449 else 450 xf86unGetToken(token); 451 } 452 453 old = NULL; 454 455 /* Don't allow duplicates */ 456 if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 457 cnew = old; 458 free(option->opt_name); 459 TestFree(option->opt_val); 460 TestFree(option->opt_comment); 461 free(option); 462 } 463 else 464 cnew = option; 465 466 if (old == NULL) 467 return ((XF86OptionPtr) xf86addListItem((glp) head, (glp) cnew)); 468 469 return head; 470} 471 472void 473xf86printOptionList(FILE * fp, XF86OptionPtr list, int tabs) 474{ 475 int i; 476 477 if (!list) 478 return; 479 while (list) { 480 for (i = 0; i < tabs; i++) 481 fputc('\t', fp); 482 if (list->opt_val) 483 fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, 484 list->opt_val); 485 else 486 fprintf(fp, "Option \"%s\"", list->opt_name); 487 if (list->opt_comment) 488 fprintf(fp, "%s", list->opt_comment); 489 else 490 fputc('\n', fp); 491 list = list->list.next; 492 } 493} 494