Flags.c revision 1b5d61b8
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 {NOTRAPSIGNALS, "notrapsignals"}, 69 {DONTZAP, "dontzap"}, 70 {DONTZOOM, "dontzoom"}, 71 {DISABLEVIDMODE, "disablevidmodeextension"}, 72 {ALLOWNONLOCAL, "allownonlocalxvidtune"}, 73 {DISABLEMODINDEV, "disablemodindev"}, 74 {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"}, 75 {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"}, 76 {OPTION, "option"}, 77 {BLANKTIME, "blanktime"}, 78 {STANDBYTIME, "standbytime"}, 79 {SUSPENDTIME, "suspendtime"}, 80 {OFFTIME, "offtime"}, 81 {DEFAULTLAYOUT, "defaultserverlayout"}, 82 {-1, ""}, 83}; 84 85#define CLEANUP xf86freeFlags 86 87XF86ConfFlagsPtr 88xf86parseFlagsSection(void) 89{ 90 int token; 91 92 parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec) 93 94 while ((token = xf86getToken(ServerFlagsTab)) != ENDSECTION) { 95 int hasvalue = FALSE; 96 int strvalue = FALSE; 97 int tokentype; 98 99 switch (token) { 100 case COMMENT: 101 ptr->flg_comment = xf86addComment(ptr->flg_comment, xf86_lex_val.str); 102 break; 103 /* 104 * these old keywords are turned into standard generic options. 105 * we fall through here on purpose 106 */ 107 case DEFAULTLAYOUT: 108 strvalue = TRUE; 109 case BLANKTIME: 110 case STANDBYTIME: 111 case SUSPENDTIME: 112 case OFFTIME: 113 hasvalue = TRUE; 114 case NOTRAPSIGNALS: 115 case DONTZAP: 116 case DONTZOOM: 117 case DISABLEVIDMODE: 118 case ALLOWNONLOCAL: 119 case DISABLEMODINDEV: 120 case MODINDEVALLOWNONLOCAL: 121 case ALLOWMOUSEOPENFAIL: 122 { 123 int i = 0; 124 125 while (ServerFlagsTab[i].token != -1) { 126 char *tmp; 127 128 if (ServerFlagsTab[i].token == token) { 129 char *valstr = NULL; 130 131 tmp = strdup(ServerFlagsTab[i].name); 132 if (hasvalue) { 133 tokentype = xf86getSubToken(&(ptr->flg_comment)); 134 if (strvalue) { 135 if (tokentype != STRING) 136 Error(QUOTE_MSG, tmp); 137 valstr = xf86_lex_val.str; 138 } 139 else { 140 if (tokentype != NUMBER) 141 Error(NUMBER_MSG, tmp); 142 if (asprintf(&valstr, "%d", xf86_lex_val.num) == -1) 143 valstr = NULL; 144 } 145 } 146 ptr->flg_option_lst = xf86addNewOption 147 (ptr->flg_option_lst, tmp, valstr); 148 } 149 i++; 150 } 151 } 152 break; 153 case OPTION: 154 ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst); 155 break; 156 157 case EOF_TOKEN: 158 Error(UNEXPECTED_EOF_MSG); 159 break; 160 default: 161 Error(INVALID_KEYWORD_MSG, xf86tokenString()); 162 break; 163 } 164 } 165 166#ifdef DEBUG 167 printf("Flags section parsed\n"); 168#endif 169 170 return ptr; 171} 172 173#undef CLEANUP 174 175void 176xf86printServerFlagsSection(FILE * f, XF86ConfFlagsPtr flags) 177{ 178 XF86OptionPtr p; 179 180 if ((!flags) || (!flags->flg_option_lst)) 181 return; 182 p = flags->flg_option_lst; 183 fprintf(f, "Section \"ServerFlags\"\n"); 184 if (flags->flg_comment) 185 fprintf(f, "%s", flags->flg_comment); 186 xf86printOptionList(f, p, 1); 187 fprintf(f, "EndSection\n\n"); 188} 189 190static XF86OptionPtr 191addNewOption2(XF86OptionPtr head, char *name, char *_val, int used) 192{ 193 XF86OptionPtr new, old = NULL; 194 195 /* Don't allow duplicates, free old strings */ 196 if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 197 new = old; 198 free(new->opt_name); 199 free(new->opt_val); 200 } 201 else 202 new = calloc(1, sizeof(*new)); 203 new->opt_name = name; 204 new->opt_val = _val; 205 new->opt_used = used; 206 207 if (old) 208 return head; 209 return ((XF86OptionPtr) xf86addListItem((glp) head, (glp) new)); 210} 211 212XF86OptionPtr 213xf86addNewOption(XF86OptionPtr head, char *name, char *_val) 214{ 215 return addNewOption2(head, name, _val, 0); 216} 217 218void 219xf86freeFlags(XF86ConfFlagsPtr flags) 220{ 221 if (flags == NULL) 222 return; 223 xf86optionListFree(flags->flg_option_lst); 224 TestFree(flags->flg_comment); 225 free(flags); 226} 227 228XF86OptionPtr 229xf86optionListDup(XF86OptionPtr opt) 230{ 231 XF86OptionPtr newopt = NULL; 232 char *_val; 233 234 while (opt) { 235 _val = opt->opt_val ? strdup(opt->opt_val) : NULL; 236 newopt = xf86addNewOption(newopt, strdup(opt->opt_name), _val); 237 newopt->opt_used = opt->opt_used; 238 if (opt->opt_comment) 239 newopt->opt_comment = strdup(opt->opt_comment); 240 opt = opt->list.next; 241 } 242 return newopt; 243} 244 245void 246xf86optionListFree(XF86OptionPtr opt) 247{ 248 XF86OptionPtr prev; 249 250 while (opt) { 251 TestFree(opt->opt_name); 252 TestFree(opt->opt_val); 253 TestFree(opt->opt_comment); 254 prev = opt; 255 opt = opt->list.next; 256 free(prev); 257 } 258} 259 260char * 261xf86optionName(XF86OptionPtr opt) 262{ 263 if (opt) 264 return opt->opt_name; 265 return 0; 266} 267 268char * 269xf86optionValue(XF86OptionPtr opt) 270{ 271 if (opt) 272 return opt->opt_val; 273 return 0; 274} 275 276XF86OptionPtr 277xf86newOption(char *name, char *value) 278{ 279 XF86OptionPtr opt; 280 281 opt = calloc(1, sizeof(*opt)); 282 if (!opt) 283 return NULL; 284 285 opt->opt_used = 0; 286 opt->list.next = 0; 287 opt->opt_name = name; 288 opt->opt_val = value; 289 290 return opt; 291} 292 293XF86OptionPtr 294xf86nextOption(XF86OptionPtr list) 295{ 296 if (!list) 297 return NULL; 298 return list->list.next; 299} 300 301/* 302 * this function searches the given option list for the named option and 303 * returns a pointer to the option rec if found. If not found, it returns 304 * NULL 305 */ 306 307XF86OptionPtr 308xf86findOption(XF86OptionPtr list, const char *name) 309{ 310 while (list) { 311 if (xf86nameCompare(list->opt_name, name) == 0) 312 return list; 313 list = list->list.next; 314 } 315 return NULL; 316} 317 318/* 319 * this function searches the given option list for the named option. If 320 * found and the option has a parameter, a pointer to the parameter is 321 * returned. If the option does not have a parameter an empty string is 322 * returned. If the option is not found, a NULL is returned. 323 */ 324 325const char * 326xf86findOptionValue(XF86OptionPtr list, const char *name) 327{ 328 XF86OptionPtr p = xf86findOption(list, name); 329 330 if (p) { 331 if (p->opt_val) 332 return p->opt_val; 333 else 334 return ""; 335 } 336 return NULL; 337} 338 339XF86OptionPtr 340xf86optionListCreate(const char **options, int count, int used) 341{ 342 XF86OptionPtr p = NULL; 343 char *t1, *t2; 344 int i; 345 346 if (count == -1) { 347 for (count = 0; options[count]; count++); 348 } 349 if ((count % 2) != 0) { 350 fprintf(stderr, 351 "xf86optionListCreate: count must be an even number.\n"); 352 return NULL; 353 } 354 for (i = 0; i < count; i += 2) { 355 t1 = strdup(options[i]); 356 t2 = strdup(options[i + 1]); 357 p = addNewOption2(p, t1, t2, used); 358 } 359 360 return p; 361} 362 363/* the 2 given lists are merged. If an option with the same name is present in 364 * both, the option from the user list - specified in the second argument - 365 * is used. The end result is a single valid list of options. Duplicates 366 * are freed, and the original lists are no longer guaranteed to be complete. 367 */ 368XF86OptionPtr 369xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail) 370{ 371 XF86OptionPtr a, b, ap = NULL, bp = NULL; 372 373 a = tail; 374 b = head; 375 while (tail && b) { 376 if (xf86nameCompare(a->opt_name, b->opt_name) == 0) { 377 if (b == head) 378 head = a; 379 else 380 bp->list.next = a; 381 if (a == tail) 382 tail = a->list.next; 383 else 384 ap->list.next = a->list.next; 385 a->list.next = b->list.next; 386 b->list.next = NULL; 387 xf86optionListFree(b); 388 b = a->list.next; 389 bp = a; 390 a = tail; 391 ap = NULL; 392 } 393 else { 394 ap = a; 395 if (!(a = a->list.next)) { 396 a = tail; 397 bp = b; 398 b = b->list.next; 399 ap = NULL; 400 } 401 } 402 } 403 404 if (head) { 405 for (a = head; a->list.next; a = a->list.next); 406 a->list.next = tail; 407 } 408 else 409 head = tail; 410 411 return head; 412} 413 414char * 415xf86uLongToString(unsigned long i) 416{ 417 char *s; 418 419 if (asprintf(&s, "%lu", i) == -1) 420 return NULL; 421 return s; 422} 423 424XF86OptionPtr 425xf86parseOption(XF86OptionPtr head) 426{ 427 XF86OptionPtr option, cnew, old; 428 char *name, *comment = NULL; 429 int token; 430 431 if ((token = xf86getSubToken(&comment)) != STRING) { 432 xf86parseError(BAD_OPTION_MSG); 433 free(comment); 434 return head; 435 } 436 437 name = xf86_lex_val.str; 438 if ((token = xf86getSubToken(&comment)) == STRING) { 439 option = xf86newOption(name, xf86_lex_val.str); 440 option->opt_comment = comment; 441 if ((token = xf86getToken(NULL)) == COMMENT) 442 option->opt_comment = xf86addComment(option->opt_comment, xf86_lex_val.str); 443 else 444 xf86unGetToken(token); 445 } 446 else { 447 option = xf86newOption(name, NULL); 448 option->opt_comment = comment; 449 if (token == COMMENT) 450 option->opt_comment = xf86addComment(option->opt_comment, xf86_lex_val.str); 451 else 452 xf86unGetToken(token); 453 } 454 455 old = NULL; 456 457 /* Don't allow duplicates */ 458 if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 459 cnew = old; 460 free(option->opt_name); 461 TestFree(option->opt_val); 462 TestFree(option->opt_comment); 463 free(option); 464 } 465 else 466 cnew = option; 467 468 if (old == NULL) 469 return ((XF86OptionPtr) xf86addListItem((glp) head, (glp) cnew)); 470 471 return head; 472} 473 474void 475xf86printOptionList(FILE * fp, XF86OptionPtr list, int tabs) 476{ 477 int i; 478 479 if (!list) 480 return; 481 while (list) { 482 for (i = 0; i < tabs; i++) 483 fputc('\t', fp); 484 if (list->opt_val) 485 fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, 486 list->opt_val); 487 else 488 fprintf(fp, "Option \"%s\"", list->opt_name); 489 if (list->opt_comment) 490 fprintf(fp, "%s", list->opt_comment); 491 else 492 fputc('\n', fp); 493 list = list->list.next; 494 } 495} 496