Flags.c revision 05b261ec
1/* 2 * 3 * Copyright (c) 1997 Metro Link Incorporated 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Except as contained in this notice, the name of the Metro Link shall not be 24 * used in advertising or otherwise to promote the sale, use or other dealings 25 * in this Software without prior written authorization from Metro Link. 26 * 27 */ 28/* 29 * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 30 * 31 * Permission is hereby granted, free of charge, to any person obtaining a 32 * copy of this software and associated documentation files (the "Software"), 33 * to deal in the Software without restriction, including without limitation 34 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 35 * and/or sell copies of the Software, and to permit persons to whom the 36 * Software is furnished to do so, subject to the following conditions: 37 * 38 * The above copyright notice and this permission notice shall be included in 39 * all copies or substantial portions of the Software. 40 * 41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 44 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 45 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 46 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 47 * OTHER DEALINGS IN THE SOFTWARE. 48 * 49 * Except as contained in this notice, the name of the copyright holder(s) 50 * and author(s) shall not be used in advertising or otherwise to promote 51 * the sale, use or other dealings in this Software without prior written 52 * authorization from the copyright holder(s) and author(s). 53 */ 54 55 56/* View/edit this file with tab stops set to 4 */ 57 58#ifdef HAVE_XORG_CONFIG_H 59#include <xorg-config.h> 60#endif 61 62#include "xf86Parser.h" 63#include "xf86tokens.h" 64#include "Configint.h" 65#include <math.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 = xf86configStrdup (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 = xf86confmalloc(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 xf86conffree(new->opt_name); 205 xf86conffree(new->opt_val); 206 } 207 else 208 new = xf86confcalloc (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 xf86conffree (flags); 232} 233 234XF86OptionPtr 235xf86optionListDup (XF86OptionPtr opt) 236{ 237 XF86OptionPtr newopt = NULL; 238 239 while (opt) 240 { 241 newopt = xf86addNewOption(newopt, xf86configStrdup(opt->opt_name), 242 xf86configStrdup(opt->opt_val)); 243 newopt->opt_used = opt->opt_used; 244 if (opt->opt_comment) 245 newopt->opt_comment = xf86configStrdup(opt->opt_comment); 246 opt = opt->list.next; 247 } 248 return newopt; 249} 250 251void 252xf86optionListFree (XF86OptionPtr opt) 253{ 254 XF86OptionPtr prev; 255 256 while (opt) 257 { 258 TestFree (opt->opt_name); 259 TestFree (opt->opt_val); 260 TestFree (opt->opt_comment); 261 prev = opt; 262 opt = opt->list.next; 263 xf86conffree (prev); 264 } 265} 266 267char * 268xf86optionName(XF86OptionPtr opt) 269{ 270 if (opt) 271 return opt->opt_name; 272 return 0; 273} 274 275char * 276xf86optionValue(XF86OptionPtr opt) 277{ 278 if (opt) 279 return opt->opt_val; 280 return 0; 281} 282 283XF86OptionPtr 284xf86newOption(char *name, char *value) 285{ 286 XF86OptionPtr opt; 287 288 opt = xf86confcalloc(1, sizeof (XF86OptionRec)); 289 if (!opt) 290 return NULL; 291 292 opt->opt_used = 0; 293 opt->list.next = 0; 294 opt->opt_name = name; 295 opt->opt_val = value; 296 297 return opt; 298} 299 300XF86OptionPtr 301xf86nextOption(XF86OptionPtr list) 302{ 303 if (!list) 304 return NULL; 305 return list->list.next; 306} 307 308/* 309 * this function searches the given option list for the named option and 310 * returns a pointer to the option rec if found. If not found, it returns 311 * NULL 312 */ 313 314XF86OptionPtr 315xf86findOption (XF86OptionPtr list, const char *name) 316{ 317 while (list) 318 { 319 if (xf86nameCompare (list->opt_name, name) == 0) 320 return (list); 321 list = list->list.next; 322 } 323 return (NULL); 324} 325 326/* 327 * this function searches the given option list for the named option. If 328 * found and the option has a parameter, a pointer to the parameter is 329 * returned. If the option does not have a parameter an empty string is 330 * returned. If the option is not found, a NULL is returned. 331 */ 332 333char * 334xf86findOptionValue (XF86OptionPtr list, const char *name) 335{ 336 XF86OptionPtr p = xf86findOption (list, name); 337 338 if (p) 339 { 340 if (p->opt_val) 341 return (p->opt_val); 342 else 343 return ""; 344 } 345 return (NULL); 346} 347 348XF86OptionPtr 349xf86optionListCreate( const char **options, int count, int used ) 350{ 351 XF86OptionPtr p = NULL; 352 char *t1, *t2; 353 int i; 354 355 if (count == -1) 356 { 357 for (count = 0; options[count]; count++) 358 ; 359 } 360 if( (count % 2) != 0 ) 361 { 362 fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" ); 363 return (NULL); 364 } 365 for (i = 0; i < count; i += 2) 366 { 367 /* can't use strdup because it calls malloc */ 368 t1 = xf86confmalloc (sizeof (char) * 369 (strlen (options[i]) + 1)); 370 strcpy (t1, options[i]); 371 t2 = xf86confmalloc (sizeof (char) * 372 (strlen (options[i + 1]) + 1)); 373 strcpy (t2, options[i + 1]); 374 p = addNewOption2 (p, t1, t2, used); 375 } 376 377 return (p); 378} 379 380/* the 2 given lists are merged. If an option with the same name is present in 381 * both, the option from the user list - specified in the second argument - 382 * is used. The end result is a single valid list of options. Duplicates 383 * are freed, and the original lists are no longer guaranteed to be complete. 384 */ 385XF86OptionPtr 386xf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail) 387{ 388 XF86OptionPtr a, b, ap = NULL, bp = NULL; 389 390 a = tail; 391 b = head; 392 while (tail && b) { 393 if (xf86nameCompare (a->opt_name, b->opt_name) == 0) { 394 if (b == head) 395 head = a; 396 else 397 bp->list.next = a; 398 if (a == tail) 399 tail = a->list.next; 400 else 401 ap->list.next = a->list.next; 402 a->list.next = b->list.next; 403 b->list.next = NULL; 404 xf86optionListFree (b); 405 b = a->list.next; 406 bp = a; 407 a = tail; 408 ap = NULL; 409 } else { 410 ap = a; 411 if (!(a = a->list.next)) { 412 a = tail; 413 bp = b; 414 b = b->list.next; 415 ap = NULL; 416 } 417 } 418 } 419 420 if (head) { 421 for (a = head; a->list.next; a = a->list.next) 422 ; 423 a->list.next = tail; 424 } else 425 head = tail; 426 427 return (head); 428} 429 430char * 431xf86uLongToString(unsigned long i) 432{ 433 char *s; 434 int l; 435 436 l = (int)(ceil(log10((double)i) + 2.5)); 437 s = xf86confmalloc(l); 438 if (!s) 439 return NULL; 440 sprintf(s, "%lu", i); 441 return s; 442} 443 444XF86OptionPtr 445xf86parseOption(XF86OptionPtr head) 446{ 447 XF86OptionPtr option, cnew, old; 448 char *name, *comment = NULL; 449 int token; 450 451 if ((token = xf86getSubToken(&comment)) != STRING) { 452 xf86parseError(BAD_OPTION_MSG, NULL); 453 if (comment) 454 xf86conffree(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 xf86conffree(option->opt_name); 482 TestFree(option->opt_val); 483 TestFree(option->opt_comment); 484 xf86conffree(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