ParseCmd.c revision 1ab64890
11ab64890Smrg/* $Xorg: ParseCmd.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */ 21ab64890Smrg 31ab64890Smrg/*********************************************************** 41ab64890Smrg 51ab64890SmrgCopyright 1987, 1988, 1998 The Open Group 61ab64890Smrg 71ab64890SmrgPermission to use, copy, modify, distribute, and sell this software and its 81ab64890Smrgdocumentation for any purpose is hereby granted without fee, provided that 91ab64890Smrgthe above copyright notice appear in all copies and that both that 101ab64890Smrgcopyright notice and this permission notice appear in supporting 111ab64890Smrgdocumentation. 121ab64890Smrg 131ab64890SmrgThe above copyright notice and this permission notice shall be included in 141ab64890Smrgall copies or substantial portions of the Software. 151ab64890Smrg 161ab64890SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 171ab64890SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 181ab64890SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 191ab64890SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 201ab64890SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 211ab64890SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 221ab64890Smrg 231ab64890SmrgExcept as contained in this notice, the name of The Open Group shall not be 241ab64890Smrgused in advertising or otherwise to promote the sale, use or other dealings 251ab64890Smrgin this Software without prior written authorization from The Open Group. 261ab64890Smrg 271ab64890Smrg 281ab64890SmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. 291ab64890Smrg 301ab64890Smrg All Rights Reserved 311ab64890Smrg 321ab64890SmrgPermission to use, copy, modify, and distribute this software and its 331ab64890Smrgdocumentation for any purpose and without fee is hereby granted, 341ab64890Smrgprovided that the above copyright notice appear in all copies and that 351ab64890Smrgboth that copyright notice and this permission notice appear in 361ab64890Smrgsupporting documentation, and that the name of Digital not be 371ab64890Smrgused in advertising or publicity pertaining to distribution of the 381ab64890Smrgsoftware without specific, written prior permission. 391ab64890Smrg 401ab64890SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 411ab64890SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 421ab64890SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 431ab64890SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 441ab64890SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 451ab64890SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 461ab64890SmrgSOFTWARE. 471ab64890Smrg 481ab64890Smrg******************************************************************/ 491ab64890Smrg/* $XFree86: xc/lib/X11/ParseCmd.c,v 1.5 2001/12/14 19:54:03 dawes Exp $ */ 501ab64890Smrg 511ab64890Smrg/* XrmParseCommand() 521ab64890Smrg 531ab64890Smrg Parse command line and store argument values into resource database 541ab64890Smrg 551ab64890Smrg Allows any un-ambiguous abbreviation for an option name, but requires 561ab64890Smrg that the table be ordered with any options that are prefixes of 571ab64890Smrg other options appearing before the longer version in the table. 581ab64890Smrg*/ 591ab64890Smrg 601ab64890Smrg#ifdef HAVE_CONFIG_H 611ab64890Smrg#include <config.h> 621ab64890Smrg#endif 631ab64890Smrg#include "Xlibint.h" 641ab64890Smrg#include <X11/Xresource.h> 651ab64890Smrg#include <stdio.h> 661ab64890Smrg 671ab64890Smrg 681ab64890Smrgstatic void _XReportParseError(XrmOptionDescRec *arg, const char *msg) 691ab64890Smrg{ 701ab64890Smrg (void) fprintf(stderr, "Error parsing argument \"%s\" (%s); %s\n", 711ab64890Smrg arg->option, arg->specifier, msg); 721ab64890Smrg exit(1); 731ab64890Smrg} 741ab64890Smrg 751ab64890Smrgvoid 761ab64890SmrgXrmParseCommand( 771ab64890Smrg XrmDatabase *pdb, /* data base */ 781ab64890Smrg register XrmOptionDescList options, /* pointer to table of valid options */ 791ab64890Smrg int num_options, /* number of options */ 801ab64890Smrg _Xconst char *prefix, /* name to prefix resources with */ 811ab64890Smrg int *argc, /* address of argument count */ 821ab64890Smrg char **argv) /* argument list (command line) */ 831ab64890Smrg{ 841ab64890Smrg int foundOption; 851ab64890Smrg char **argsave; 861ab64890Smrg register int i, myargc; 871ab64890Smrg XrmBinding bindings[100]; 881ab64890Smrg XrmQuark quarks[100]; 891ab64890Smrg XrmBinding *start_bindings; 901ab64890Smrg XrmQuark *start_quarks; 911ab64890Smrg char *optP, *argP = NULL, optchar, argchar = 0; 921ab64890Smrg int matches; 931ab64890Smrg enum {DontCare, Check, NotSorted, Sorted} table_is_sorted; 941ab64890Smrg char **argend; 951ab64890Smrg 961ab64890Smrg#define PutCommandResource(value_str) \ 971ab64890Smrg { \ 981ab64890Smrg XrmStringToBindingQuarkList( \ 991ab64890Smrg options[i].specifier, start_bindings, start_quarks); \ 1001ab64890Smrg XrmQPutStringResource(pdb, bindings, quarks, value_str); \ 1011ab64890Smrg } /* PutCommandResource */ 1021ab64890Smrg 1031ab64890Smrg myargc = (*argc); 1041ab64890Smrg argend = argv + myargc; 1051ab64890Smrg argsave = ++argv; 1061ab64890Smrg 1071ab64890Smrg /* Initialize bindings/quark list with prefix (typically app name). */ 1081ab64890Smrg quarks[0] = XrmStringToName(prefix); 1091ab64890Smrg bindings[0] = XrmBindTightly; 1101ab64890Smrg start_quarks = quarks+1; 1111ab64890Smrg start_bindings = bindings+1; 1121ab64890Smrg 1131ab64890Smrg table_is_sorted = (myargc > 2) ? Check : DontCare; 1141ab64890Smrg for (--myargc; myargc > 0; --myargc, ++argv) { 1151ab64890Smrg foundOption = False; 1161ab64890Smrg matches = 0; 1171ab64890Smrg for (i=0; i < num_options; ++i) { 1181ab64890Smrg /* checking the sort order first insures we don't have to 1191ab64890Smrg re-do the check if the arg hits on the last entry in 1201ab64890Smrg the table. Useful because usually '=' is the last entry 1211ab64890Smrg and users frequently specify geometry early in the command */ 1221ab64890Smrg if (table_is_sorted == Check && i > 0 && 1231ab64890Smrg strcmp(options[i].option, options[i-1].option) < 0) { 1241ab64890Smrg table_is_sorted = NotSorted; 1251ab64890Smrg } 1261ab64890Smrg for (argP = *argv, optP = options[i].option; 1271ab64890Smrg (optchar = *optP++) && 1281ab64890Smrg (argchar = *argP++) && 1291ab64890Smrg argchar == optchar;); 1301ab64890Smrg if (!optchar) { 1311ab64890Smrg if (!*argP || 1321ab64890Smrg options[i].argKind == XrmoptionStickyArg || 1331ab64890Smrg options[i].argKind == XrmoptionIsArg) { 1341ab64890Smrg /* give preference to exact matches, StickyArg and IsArg */ 1351ab64890Smrg matches = 1; 1361ab64890Smrg foundOption = i; 1371ab64890Smrg break; 1381ab64890Smrg } 1391ab64890Smrg } 1401ab64890Smrg else if (!argchar) { 1411ab64890Smrg /* may be an abbreviation for this option */ 1421ab64890Smrg matches++; 1431ab64890Smrg foundOption = i; 1441ab64890Smrg } 1451ab64890Smrg else if (table_is_sorted == Sorted && optchar > argchar) { 1461ab64890Smrg break; 1471ab64890Smrg } 1481ab64890Smrg if (table_is_sorted == Check && i > 0 && 1491ab64890Smrg strcmp(options[i].option, options[i-1].option) < 0) { 1501ab64890Smrg table_is_sorted = NotSorted; 1511ab64890Smrg } 1521ab64890Smrg } 1531ab64890Smrg if (table_is_sorted == Check && i >= (num_options-1)) 1541ab64890Smrg table_is_sorted = Sorted; 1551ab64890Smrg if (matches == 1) { 1561ab64890Smrg i = foundOption; 1571ab64890Smrg switch (options[i].argKind){ 1581ab64890Smrg case XrmoptionNoArg: 1591ab64890Smrg --(*argc); 1601ab64890Smrg PutCommandResource(options[i].value); 1611ab64890Smrg break; 1621ab64890Smrg 1631ab64890Smrg case XrmoptionIsArg: 1641ab64890Smrg --(*argc); 1651ab64890Smrg PutCommandResource(*argv); 1661ab64890Smrg break; 1671ab64890Smrg 1681ab64890Smrg case XrmoptionStickyArg: 1691ab64890Smrg --(*argc); 1701ab64890Smrg PutCommandResource(argP); 1711ab64890Smrg break; 1721ab64890Smrg 1731ab64890Smrg case XrmoptionSepArg: 1741ab64890Smrg if (myargc > 1) { 1751ab64890Smrg ++argv; --myargc; --(*argc); --(*argc); 1761ab64890Smrg PutCommandResource(*argv); 1771ab64890Smrg } else 1781ab64890Smrg (*argsave++) = (*argv); 1791ab64890Smrg break; 1801ab64890Smrg 1811ab64890Smrg case XrmoptionResArg: 1821ab64890Smrg if (myargc > 1) { 1831ab64890Smrg ++argv; --myargc; --(*argc); --(*argc); 1841ab64890Smrg XrmPutLineResource(pdb, *argv); 1851ab64890Smrg } else 1861ab64890Smrg (*argsave++) = (*argv); 1871ab64890Smrg break; 1881ab64890Smrg 1891ab64890Smrg case XrmoptionSkipArg: 1901ab64890Smrg if (myargc > 1) { 1911ab64890Smrg --myargc; 1921ab64890Smrg (*argsave++) = (*argv++); 1931ab64890Smrg } 1941ab64890Smrg (*argsave++) = (*argv); 1951ab64890Smrg break; 1961ab64890Smrg 1971ab64890Smrg case XrmoptionSkipLine: 1981ab64890Smrg for (; myargc > 0; myargc--) 1991ab64890Smrg (*argsave++) = (*argv++); 2001ab64890Smrg break; 2011ab64890Smrg 2021ab64890Smrg case XrmoptionSkipNArgs: 2031ab64890Smrg { 2041ab64890Smrg register int j = 1 + (long) options[i].value; 2051ab64890Smrg 2061ab64890Smrg if (j > myargc) j = myargc; 2071ab64890Smrg for (; j > 0; j--) { 2081ab64890Smrg (*argsave++) = (*argv++); 2091ab64890Smrg myargc--; 2101ab64890Smrg } 2111ab64890Smrg argv--; /* went one too far before */ 2121ab64890Smrg myargc++; 2131ab64890Smrg } 2141ab64890Smrg break; 2151ab64890Smrg 2161ab64890Smrg default: 2171ab64890Smrg _XReportParseError (&options[i], "unknown kind"); 2181ab64890Smrg break; 2191ab64890Smrg } 2201ab64890Smrg } 2211ab64890Smrg else 2221ab64890Smrg (*argsave++) = (*argv); /*compress arglist*/ 2231ab64890Smrg } 2241ab64890Smrg 2251ab64890Smrg if (argsave < argend) 2261ab64890Smrg (*argsave)=NULL; /* put NULL terminator on compressed argv */ 2271ab64890Smrg} 228