Flags.c revision 4642e01f
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#include <X11/Xfuncproto.h> 67 68extern LexRec val; 69 70static xf86ConfigSymTabRec ServerFlagsTab[] = 71{ 72 {ENDSECTION, "endsection"}, 73 {NOTRAPSIGNALS, "notrapsignals"}, 74 {DONTZAP, "dontzap"}, 75 {DONTZOOM, "dontzoom"}, 76 {DISABLEVIDMODE, "disablevidmodeextension"}, 77 {ALLOWNONLOCAL, "allownonlocalxvidtune"}, 78 {DISABLEMODINDEV, "disablemodindev"}, 79 {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"}, 80 {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"}, 81 {OPTION, "option"}, 82 {BLANKTIME, "blanktime"}, 83 {STANDBYTIME, "standbytime"}, 84 {SUSPENDTIME, "suspendtime"}, 85 {OFFTIME, "offtime"}, 86 {DEFAULTLAYOUT, "defaultserverlayout"}, 87 {-1, ""}, 88}; 89 90#define CLEANUP xf86freeFlags 91 92XF86ConfFlagsPtr 93xf86parseFlagsSection (void) 94{ 95 int token; 96 parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec) 97 98 while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION) 99 { 100 int hasvalue = FALSE; 101 int strvalue = FALSE; 102 int tokentype; 103 switch (token) 104 { 105 case COMMENT: 106 ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str); 107 break; 108 /* 109 * these old keywords are turned into standard generic options. 110 * we fall through here on purpose 111 */ 112 case DEFAULTLAYOUT: 113 strvalue = TRUE; 114 case BLANKTIME: 115 case STANDBYTIME: 116 case SUSPENDTIME: 117 case OFFTIME: 118 hasvalue = TRUE; 119 case NOTRAPSIGNALS: 120 case DONTZAP: 121 case DONTZOOM: 122 case DISABLEVIDMODE: 123 case ALLOWNONLOCAL: 124 case DISABLEMODINDEV: 125 case MODINDEVALLOWNONLOCAL: 126 case ALLOWMOUSEOPENFAIL: 127 { 128 int i = 0; 129 while (ServerFlagsTab[i].token != -1) 130 { 131 char *tmp; 132 133 if (ServerFlagsTab[i].token == token) 134 { 135 char *valstr = NULL; 136 /* can't use strdup because it calls malloc */ 137 tmp = xf86configStrdup (ServerFlagsTab[i].name); 138 if (hasvalue) 139 { 140 tokentype = xf86getSubToken(&(ptr->flg_comment)); 141 if (strvalue) { 142 if (tokentype != STRING) 143 Error (QUOTE_MSG, tmp); 144 valstr = val.str; 145 } else { 146 if (tokentype != NUMBER) 147 Error (NUMBER_MSG, tmp); 148 valstr = xf86confmalloc(16); 149 if (valstr) 150 sprintf(valstr, "%d", val.num); 151 } 152 } 153 ptr->flg_option_lst = xf86addNewOption 154 (ptr->flg_option_lst, tmp, valstr); 155 } 156 i++; 157 } 158 } 159 break; 160 case OPTION: 161 ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst); 162 break; 163 164 case EOF_TOKEN: 165 Error (UNEXPECTED_EOF_MSG, NULL); 166 break; 167 default: 168 Error (INVALID_KEYWORD_MSG, xf86tokenString ()); 169 break; 170 } 171 } 172 173#ifdef DEBUG 174 printf ("Flags section parsed\n"); 175#endif 176 177 return ptr; 178} 179 180#undef CLEANUP 181 182void 183xf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags) 184{ 185 XF86OptionPtr p; 186 187 if ((!flags) || (!flags->flg_option_lst)) 188 return; 189 p = flags->flg_option_lst; 190 fprintf (f, "Section \"ServerFlags\"\n"); 191 if (flags->flg_comment) 192 fprintf (f, "%s", flags->flg_comment); 193 xf86printOptionList(f, p, 1); 194 fprintf (f, "EndSection\n\n"); 195} 196 197static XF86OptionPtr 198addNewOption2 (XF86OptionPtr head, char *name, char *val, int used) 199{ 200 XF86OptionPtr new, old = NULL; 201 202 /* Don't allow duplicates, free old strings */ 203 if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 204 new = old; 205 xf86conffree(new->opt_name); 206 xf86conffree(new->opt_val); 207 } 208 else 209 new = xf86confcalloc (1, sizeof (XF86OptionRec)); 210 new->opt_name = name; 211 new->opt_val = val; 212 new->opt_used = used; 213 214 if (old) 215 return head; 216 return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new)); 217} 218 219XF86OptionPtr 220xf86addNewOption (XF86OptionPtr head, char *name, char *val) 221{ 222 return addNewOption2(head, name, val, 0); 223} 224 225void 226xf86freeFlags (XF86ConfFlagsPtr flags) 227{ 228 if (flags == NULL) 229 return; 230 xf86optionListFree (flags->flg_option_lst); 231 TestFree(flags->flg_comment); 232 xf86conffree (flags); 233} 234 235XF86OptionPtr 236xf86optionListDup (XF86OptionPtr opt) 237{ 238 XF86OptionPtr newopt = NULL; 239 240 while (opt) 241 { 242 newopt = xf86addNewOption(newopt, xf86configStrdup(opt->opt_name), 243 xf86configStrdup(opt->opt_val)); 244 newopt->opt_used = opt->opt_used; 245 if (opt->opt_comment) 246 newopt->opt_comment = xf86configStrdup(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 xf86conffree (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 = xf86confcalloc(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 334_X_EXPORT char * 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 = xf86confmalloc (sizeof (char) * 370 (strlen (options[i]) + 1)); 371 strcpy (t1, options[i]); 372 t2 = xf86confmalloc (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 = (int)(ceil(log10((double)i) + 2.5)); 438 s = xf86confmalloc(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 if (comment) 455 xf86conffree(comment); 456 return (head); 457 } 458 459 name = val.str; 460 if ((token = xf86getSubToken(&comment)) == STRING) { 461 option = xf86newOption(name, val.str); 462 option->opt_comment = comment; 463 if ((token = xf86getToken(NULL)) == COMMENT) 464 option->opt_comment = xf86addComment(option->opt_comment, val.str); 465 else 466 xf86unGetToken(token); 467 } 468 else { 469 option = xf86newOption(name, NULL); 470 option->opt_comment = comment; 471 if (token == COMMENT) 472 option->opt_comment = xf86addComment(option->opt_comment, val.str); 473 else 474 xf86unGetToken(token); 475 } 476 477 old = NULL; 478 479 /* Don't allow duplicates */ 480 if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 481 cnew = old; 482 xf86conffree(option->opt_name); 483 TestFree(option->opt_val); 484 TestFree(option->opt_comment); 485 xf86conffree(option); 486 } 487 else 488 cnew = option; 489 490 if (old == NULL) 491 return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew)); 492 493 return (head); 494} 495 496void 497xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs) 498{ 499 int i; 500 501 if (!list) 502 return; 503 while (list) { 504 for (i = 0; i < tabs; i++) 505 fputc('\t', fp); 506 if (list->opt_val) 507 fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, list->opt_val); 508 else 509 fprintf(fp, "Option \"%s\"", list->opt_name); 510 if (list->opt_comment) 511 fprintf(fp, "%s", list->opt_comment); 512 else 513 fputc('\n', fp); 514 list = list->list.next; 515 } 516} 517