1706f2543Smrg/* 2706f2543Smrg * Copyright (c) 1997 Metro Link Incorporated 3706f2543Smrg * 4706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5706f2543Smrg * copy of this software and associated documentation files (the "Software"), 6706f2543Smrg * to deal in the Software without restriction, including without limitation 7706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 9706f2543Smrg * Software is furnished to do so, subject to the following conditions: 10706f2543Smrg * 11706f2543Smrg * The above copyright notice and this permission notice shall be included in 12706f2543Smrg * all copies or substantial portions of the Software. 13706f2543Smrg * 14706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17706f2543Smrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20706f2543Smrg * SOFTWARE. 21706f2543Smrg * 22706f2543Smrg * Except as contained in this notice, the name of the Metro Link shall not be 23706f2543Smrg * used in advertising or otherwise to promote the sale, use or other dealings 24706f2543Smrg * in this Software without prior written authorization from Metro Link. 25706f2543Smrg * 26706f2543Smrg */ 27706f2543Smrg/* 28706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 29706f2543Smrg * 30706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 31706f2543Smrg * copy of this software and associated documentation files (the "Software"), 32706f2543Smrg * to deal in the Software without restriction, including without limitation 33706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 34706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 35706f2543Smrg * Software is furnished to do so, subject to the following conditions: 36706f2543Smrg * 37706f2543Smrg * The above copyright notice and this permission notice shall be included in 38706f2543Smrg * all copies or substantial portions of the Software. 39706f2543Smrg * 40706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 43706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 44706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 45706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 46706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE. 47706f2543Smrg * 48706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s) 49706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote 50706f2543Smrg * the sale, use or other dealings in this Software without prior written 51706f2543Smrg * authorization from the copyright holder(s) and author(s). 52706f2543Smrg */ 53706f2543Smrg 54706f2543Smrg 55706f2543Smrg/* View/edit this file with tab stops set to 4 */ 56706f2543Smrg 57706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 58706f2543Smrg#include <xorg-config.h> 59706f2543Smrg#endif 60706f2543Smrg 61706f2543Smrg#include "xf86Parser.h" 62706f2543Smrg#include "xf86tokens.h" 63706f2543Smrg#include "Configint.h" 64706f2543Smrg#include <X11/Xfuncproto.h> 65706f2543Smrg#include "Xprintf.h" 66706f2543Smrg 67706f2543Smrgextern LexRec val; 68706f2543Smrg 69706f2543Smrgstatic xf86ConfigSymTabRec ServerFlagsTab[] = 70706f2543Smrg{ 71706f2543Smrg {ENDSECTION, "endsection"}, 72706f2543Smrg {NOTRAPSIGNALS, "notrapsignals"}, 73706f2543Smrg {DONTZAP, "dontzap"}, 74706f2543Smrg {DONTZOOM, "dontzoom"}, 75706f2543Smrg {DISABLEVIDMODE, "disablevidmodeextension"}, 76706f2543Smrg {ALLOWNONLOCAL, "allownonlocalxvidtune"}, 77706f2543Smrg {DISABLEMODINDEV, "disablemodindev"}, 78706f2543Smrg {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"}, 79706f2543Smrg {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"}, 80706f2543Smrg {OPTION, "option"}, 81706f2543Smrg {BLANKTIME, "blanktime"}, 82706f2543Smrg {STANDBYTIME, "standbytime"}, 83706f2543Smrg {SUSPENDTIME, "suspendtime"}, 84706f2543Smrg {OFFTIME, "offtime"}, 85706f2543Smrg {DEFAULTLAYOUT, "defaultserverlayout"}, 86706f2543Smrg {-1, ""}, 87706f2543Smrg}; 88706f2543Smrg 89706f2543Smrg#define CLEANUP xf86freeFlags 90706f2543Smrg 91706f2543SmrgXF86ConfFlagsPtr 92706f2543Smrgxf86parseFlagsSection (void) 93706f2543Smrg{ 94706f2543Smrg int token; 95706f2543Smrg parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec) 96706f2543Smrg 97706f2543Smrg while ((token = xf86getToken (ServerFlagsTab)) != ENDSECTION) 98706f2543Smrg { 99706f2543Smrg int hasvalue = FALSE; 100706f2543Smrg int strvalue = FALSE; 101706f2543Smrg int tokentype; 102706f2543Smrg switch (token) 103706f2543Smrg { 104706f2543Smrg case COMMENT: 105706f2543Smrg ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str); 106706f2543Smrg break; 107706f2543Smrg /* 108706f2543Smrg * these old keywords are turned into standard generic options. 109706f2543Smrg * we fall through here on purpose 110706f2543Smrg */ 111706f2543Smrg case DEFAULTLAYOUT: 112706f2543Smrg strvalue = TRUE; 113706f2543Smrg case BLANKTIME: 114706f2543Smrg case STANDBYTIME: 115706f2543Smrg case SUSPENDTIME: 116706f2543Smrg case OFFTIME: 117706f2543Smrg hasvalue = TRUE; 118706f2543Smrg case NOTRAPSIGNALS: 119706f2543Smrg case DONTZAP: 120706f2543Smrg case DONTZOOM: 121706f2543Smrg case DISABLEVIDMODE: 122706f2543Smrg case ALLOWNONLOCAL: 123706f2543Smrg case DISABLEMODINDEV: 124706f2543Smrg case MODINDEVALLOWNONLOCAL: 125706f2543Smrg case ALLOWMOUSEOPENFAIL: 126706f2543Smrg { 127706f2543Smrg int i = 0; 128706f2543Smrg while (ServerFlagsTab[i].token != -1) 129706f2543Smrg { 130706f2543Smrg char *tmp; 131706f2543Smrg 132706f2543Smrg if (ServerFlagsTab[i].token == token) 133706f2543Smrg { 134706f2543Smrg char *valstr = NULL; 135706f2543Smrg tmp = strdup (ServerFlagsTab[i].name); 136706f2543Smrg if (hasvalue) 137706f2543Smrg { 138706f2543Smrg tokentype = xf86getSubToken(&(ptr->flg_comment)); 139706f2543Smrg if (strvalue) { 140706f2543Smrg if (tokentype != STRING) 141706f2543Smrg Error (QUOTE_MSG, tmp); 142706f2543Smrg valstr = val.str; 143706f2543Smrg } else { 144706f2543Smrg if (tokentype != NUMBER) 145706f2543Smrg Error (NUMBER_MSG, tmp); 146706f2543Smrg if (asprintf(&valstr, "%d", val.num) == -1) 147706f2543Smrg valstr = NULL; 148706f2543Smrg } 149706f2543Smrg } 150706f2543Smrg ptr->flg_option_lst = xf86addNewOption 151706f2543Smrg (ptr->flg_option_lst, tmp, valstr); 152706f2543Smrg } 153706f2543Smrg i++; 154706f2543Smrg } 155706f2543Smrg } 156706f2543Smrg break; 157706f2543Smrg case OPTION: 158706f2543Smrg ptr->flg_option_lst = xf86parseOption(ptr->flg_option_lst); 159706f2543Smrg break; 160706f2543Smrg 161706f2543Smrg case EOF_TOKEN: 162706f2543Smrg Error (UNEXPECTED_EOF_MSG, NULL); 163706f2543Smrg break; 164706f2543Smrg default: 165706f2543Smrg Error (INVALID_KEYWORD_MSG, xf86tokenString ()); 166706f2543Smrg break; 167706f2543Smrg } 168706f2543Smrg } 169706f2543Smrg 170706f2543Smrg#ifdef DEBUG 171706f2543Smrg printf ("Flags section parsed\n"); 172706f2543Smrg#endif 173706f2543Smrg 174706f2543Smrg return ptr; 175706f2543Smrg} 176706f2543Smrg 177706f2543Smrg#undef CLEANUP 178706f2543Smrg 179706f2543Smrgvoid 180706f2543Smrgxf86printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags) 181706f2543Smrg{ 182706f2543Smrg XF86OptionPtr p; 183706f2543Smrg 184706f2543Smrg if ((!flags) || (!flags->flg_option_lst)) 185706f2543Smrg return; 186706f2543Smrg p = flags->flg_option_lst; 187706f2543Smrg fprintf (f, "Section \"ServerFlags\"\n"); 188706f2543Smrg if (flags->flg_comment) 189706f2543Smrg fprintf (f, "%s", flags->flg_comment); 190706f2543Smrg xf86printOptionList(f, p, 1); 191706f2543Smrg fprintf (f, "EndSection\n\n"); 192706f2543Smrg} 193706f2543Smrg 194706f2543Smrgstatic XF86OptionPtr 195706f2543SmrgaddNewOption2 (XF86OptionPtr head, char *name, char *val, int used) 196706f2543Smrg{ 197706f2543Smrg XF86OptionPtr new, old = NULL; 198706f2543Smrg 199706f2543Smrg /* Don't allow duplicates, free old strings */ 200706f2543Smrg if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 201706f2543Smrg new = old; 202706f2543Smrg free(new->opt_name); 203706f2543Smrg free(new->opt_val); 204706f2543Smrg } 205706f2543Smrg else 206706f2543Smrg new = calloc (1, sizeof (XF86OptionRec)); 207706f2543Smrg new->opt_name = name; 208706f2543Smrg new->opt_val = val; 209706f2543Smrg new->opt_used = used; 210706f2543Smrg 211706f2543Smrg if (old) 212706f2543Smrg return head; 213706f2543Smrg return ((XF86OptionPtr) xf86addListItem ((glp) head, (glp) new)); 214706f2543Smrg} 215706f2543Smrg 216706f2543SmrgXF86OptionPtr 217706f2543Smrgxf86addNewOption (XF86OptionPtr head, char *name, char *val) 218706f2543Smrg{ 219706f2543Smrg return addNewOption2(head, name, val, 0); 220706f2543Smrg} 221706f2543Smrg 222706f2543Smrgvoid 223706f2543Smrgxf86freeFlags (XF86ConfFlagsPtr flags) 224706f2543Smrg{ 225706f2543Smrg if (flags == NULL) 226706f2543Smrg return; 227706f2543Smrg xf86optionListFree (flags->flg_option_lst); 228706f2543Smrg TestFree(flags->flg_comment); 229706f2543Smrg free (flags); 230706f2543Smrg} 231706f2543Smrg 232706f2543SmrgXF86OptionPtr 233706f2543Smrgxf86optionListDup (XF86OptionPtr opt) 234706f2543Smrg{ 235706f2543Smrg XF86OptionPtr newopt = NULL; 236706f2543Smrg char *val; 237706f2543Smrg 238706f2543Smrg while (opt) 239706f2543Smrg { 240706f2543Smrg val = opt->opt_val ? strdup(opt->opt_val) : NULL; 241706f2543Smrg newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val); 242706f2543Smrg newopt->opt_used = opt->opt_used; 243706f2543Smrg if (opt->opt_comment) 244706f2543Smrg newopt->opt_comment = strdup(opt->opt_comment); 245706f2543Smrg opt = opt->list.next; 246706f2543Smrg } 247706f2543Smrg return newopt; 248706f2543Smrg} 249706f2543Smrg 250706f2543Smrgvoid 251706f2543Smrgxf86optionListFree (XF86OptionPtr opt) 252706f2543Smrg{ 253706f2543Smrg XF86OptionPtr prev; 254706f2543Smrg 255706f2543Smrg while (opt) 256706f2543Smrg { 257706f2543Smrg TestFree (opt->opt_name); 258706f2543Smrg TestFree (opt->opt_val); 259706f2543Smrg TestFree (opt->opt_comment); 260706f2543Smrg prev = opt; 261706f2543Smrg opt = opt->list.next; 262706f2543Smrg free (prev); 263706f2543Smrg } 264706f2543Smrg} 265706f2543Smrg 266706f2543Smrgchar * 267706f2543Smrgxf86optionName(XF86OptionPtr opt) 268706f2543Smrg{ 269706f2543Smrg if (opt) 270706f2543Smrg return opt->opt_name; 271706f2543Smrg return 0; 272706f2543Smrg} 273706f2543Smrg 274706f2543Smrgchar * 275706f2543Smrgxf86optionValue(XF86OptionPtr opt) 276706f2543Smrg{ 277706f2543Smrg if (opt) 278706f2543Smrg return opt->opt_val; 279706f2543Smrg return 0; 280706f2543Smrg} 281706f2543Smrg 282706f2543SmrgXF86OptionPtr 283706f2543Smrgxf86newOption(char *name, char *value) 284706f2543Smrg{ 285706f2543Smrg XF86OptionPtr opt; 286706f2543Smrg 287706f2543Smrg opt = calloc(1, sizeof (XF86OptionRec)); 288706f2543Smrg if (!opt) 289706f2543Smrg return NULL; 290706f2543Smrg 291706f2543Smrg opt->opt_used = 0; 292706f2543Smrg opt->list.next = 0; 293706f2543Smrg opt->opt_name = name; 294706f2543Smrg opt->opt_val = value; 295706f2543Smrg 296706f2543Smrg return opt; 297706f2543Smrg} 298706f2543Smrg 299706f2543SmrgXF86OptionPtr 300706f2543Smrgxf86nextOption(XF86OptionPtr list) 301706f2543Smrg{ 302706f2543Smrg if (!list) 303706f2543Smrg return NULL; 304706f2543Smrg return list->list.next; 305706f2543Smrg} 306706f2543Smrg 307706f2543Smrg/* 308706f2543Smrg * this function searches the given option list for the named option and 309706f2543Smrg * returns a pointer to the option rec if found. If not found, it returns 310706f2543Smrg * NULL 311706f2543Smrg */ 312706f2543Smrg 313706f2543SmrgXF86OptionPtr 314706f2543Smrgxf86findOption (XF86OptionPtr list, const char *name) 315706f2543Smrg{ 316706f2543Smrg while (list) 317706f2543Smrg { 318706f2543Smrg if (xf86nameCompare (list->opt_name, name) == 0) 319706f2543Smrg return list; 320706f2543Smrg list = list->list.next; 321706f2543Smrg } 322706f2543Smrg return NULL; 323706f2543Smrg} 324706f2543Smrg 325706f2543Smrg/* 326706f2543Smrg * this function searches the given option list for the named option. If 327706f2543Smrg * found and the option has a parameter, a pointer to the parameter is 328706f2543Smrg * returned. If the option does not have a parameter an empty string is 329706f2543Smrg * returned. If the option is not found, a NULL is returned. 330706f2543Smrg */ 331706f2543Smrg 332706f2543Smrgchar * 333706f2543Smrgxf86findOptionValue (XF86OptionPtr list, const char *name) 334706f2543Smrg{ 335706f2543Smrg XF86OptionPtr p = xf86findOption (list, name); 336706f2543Smrg 337706f2543Smrg if (p) 338706f2543Smrg { 339706f2543Smrg if (p->opt_val) 340706f2543Smrg return p->opt_val; 341706f2543Smrg else 342706f2543Smrg return ""; 343706f2543Smrg } 344706f2543Smrg return NULL; 345706f2543Smrg} 346706f2543Smrg 347706f2543SmrgXF86OptionPtr 348706f2543Smrgxf86optionListCreate( const char **options, int count, int used ) 349706f2543Smrg{ 350706f2543Smrg XF86OptionPtr p = NULL; 351706f2543Smrg char *t1, *t2; 352706f2543Smrg int i; 353706f2543Smrg 354706f2543Smrg if (count == -1) 355706f2543Smrg { 356706f2543Smrg for (count = 0; options[count]; count++) 357706f2543Smrg ; 358706f2543Smrg } 359706f2543Smrg if( (count % 2) != 0 ) 360706f2543Smrg { 361706f2543Smrg fprintf( stderr, "xf86optionListCreate: count must be an even number.\n" ); 362706f2543Smrg return NULL; 363706f2543Smrg } 364706f2543Smrg for (i = 0; i < count; i += 2) 365706f2543Smrg { 366706f2543Smrg t1 = strdup(options[i]); 367706f2543Smrg t2 = strdup(options[i + 1]); 368706f2543Smrg p = addNewOption2 (p, t1, t2, used); 369706f2543Smrg } 370706f2543Smrg 371706f2543Smrg return p; 372706f2543Smrg} 373706f2543Smrg 374706f2543Smrg/* the 2 given lists are merged. If an option with the same name is present in 375706f2543Smrg * both, the option from the user list - specified in the second argument - 376706f2543Smrg * is used. The end result is a single valid list of options. Duplicates 377706f2543Smrg * are freed, and the original lists are no longer guaranteed to be complete. 378706f2543Smrg */ 379706f2543SmrgXF86OptionPtr 380706f2543Smrgxf86optionListMerge (XF86OptionPtr head, XF86OptionPtr tail) 381706f2543Smrg{ 382706f2543Smrg XF86OptionPtr a, b, ap = NULL, bp = NULL; 383706f2543Smrg 384706f2543Smrg a = tail; 385706f2543Smrg b = head; 386706f2543Smrg while (tail && b) { 387706f2543Smrg if (xf86nameCompare (a->opt_name, b->opt_name) == 0) { 388706f2543Smrg if (b == head) 389706f2543Smrg head = a; 390706f2543Smrg else 391706f2543Smrg bp->list.next = a; 392706f2543Smrg if (a == tail) 393706f2543Smrg tail = a->list.next; 394706f2543Smrg else 395706f2543Smrg ap->list.next = a->list.next; 396706f2543Smrg a->list.next = b->list.next; 397706f2543Smrg b->list.next = NULL; 398706f2543Smrg xf86optionListFree (b); 399706f2543Smrg b = a->list.next; 400706f2543Smrg bp = a; 401706f2543Smrg a = tail; 402706f2543Smrg ap = NULL; 403706f2543Smrg } else { 404706f2543Smrg ap = a; 405706f2543Smrg if (!(a = a->list.next)) { 406706f2543Smrg a = tail; 407706f2543Smrg bp = b; 408706f2543Smrg b = b->list.next; 409706f2543Smrg ap = NULL; 410706f2543Smrg } 411706f2543Smrg } 412706f2543Smrg } 413706f2543Smrg 414706f2543Smrg if (head) { 415706f2543Smrg for (a = head; a->list.next; a = a->list.next) 416706f2543Smrg ; 417706f2543Smrg a->list.next = tail; 418706f2543Smrg } else 419706f2543Smrg head = tail; 420706f2543Smrg 421706f2543Smrg return head; 422706f2543Smrg} 423706f2543Smrg 424706f2543Smrgchar * 425706f2543Smrgxf86uLongToString(unsigned long i) 426706f2543Smrg{ 427706f2543Smrg char *s; 428706f2543Smrg 429706f2543Smrg if (asprintf(&s, "%lu", i) == -1) 430706f2543Smrg return NULL; 431706f2543Smrg return s; 432706f2543Smrg} 433706f2543Smrg 434706f2543SmrgXF86OptionPtr 435706f2543Smrgxf86parseOption(XF86OptionPtr head) 436706f2543Smrg{ 437706f2543Smrg XF86OptionPtr option, cnew, old; 438706f2543Smrg char *name, *comment = NULL; 439706f2543Smrg int token; 440706f2543Smrg 441706f2543Smrg if ((token = xf86getSubToken(&comment)) != STRING) { 442706f2543Smrg xf86parseError(BAD_OPTION_MSG, NULL); 443706f2543Smrg free(comment); 444706f2543Smrg return head; 445706f2543Smrg } 446706f2543Smrg 447706f2543Smrg name = val.str; 448706f2543Smrg if ((token = xf86getSubToken(&comment)) == STRING) { 449706f2543Smrg option = xf86newOption(name, val.str); 450706f2543Smrg option->opt_comment = comment; 451706f2543Smrg if ((token = xf86getToken(NULL)) == COMMENT) 452706f2543Smrg option->opt_comment = xf86addComment(option->opt_comment, val.str); 453706f2543Smrg else 454706f2543Smrg xf86unGetToken(token); 455706f2543Smrg } 456706f2543Smrg else { 457706f2543Smrg option = xf86newOption(name, NULL); 458706f2543Smrg option->opt_comment = comment; 459706f2543Smrg if (token == COMMENT) 460706f2543Smrg option->opt_comment = xf86addComment(option->opt_comment, val.str); 461706f2543Smrg else 462706f2543Smrg xf86unGetToken(token); 463706f2543Smrg } 464706f2543Smrg 465706f2543Smrg old = NULL; 466706f2543Smrg 467706f2543Smrg /* Don't allow duplicates */ 468706f2543Smrg if (head != NULL && (old = xf86findOption(head, name)) != NULL) { 469706f2543Smrg cnew = old; 470706f2543Smrg free(option->opt_name); 471706f2543Smrg TestFree(option->opt_val); 472706f2543Smrg TestFree(option->opt_comment); 473706f2543Smrg free(option); 474706f2543Smrg } 475706f2543Smrg else 476706f2543Smrg cnew = option; 477706f2543Smrg 478706f2543Smrg if (old == NULL) 479706f2543Smrg return ((XF86OptionPtr)xf86addListItem((glp)head, (glp)cnew)); 480706f2543Smrg 481706f2543Smrg return head; 482706f2543Smrg} 483706f2543Smrg 484706f2543Smrgvoid 485706f2543Smrgxf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs) 486706f2543Smrg{ 487706f2543Smrg int i; 488706f2543Smrg 489706f2543Smrg if (!list) 490706f2543Smrg return; 491706f2543Smrg while (list) { 492706f2543Smrg for (i = 0; i < tabs; i++) 493706f2543Smrg fputc('\t', fp); 494706f2543Smrg if (list->opt_val) 495706f2543Smrg fprintf(fp, "Option \"%s\" \"%s\"", list->opt_name, list->opt_val); 496706f2543Smrg else 497706f2543Smrg fprintf(fp, "Option \"%s\"", list->opt_name); 498706f2543Smrg if (list->opt_comment) 499706f2543Smrg fprintf(fp, "%s", list->opt_comment); 500706f2543Smrg else 501706f2543Smrg fputc('\n', fp); 502706f2543Smrg list = list->list.next; 503706f2543Smrg } 504706f2543Smrg} 505