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