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