1 /*************************************************************************/
2 /*                                                                       */
3 /*                  Language Technologies Institute                      */
4 /*                     Carnegie Mellon University                        */
5 /*                        Copyright (c) 2001                             */
6 /*                        All Rights Reserved.                           */
7 /*                                                                       */
8 /*  Permission is hereby granted, free of charge, to use and distribute  */
9 /*  this software and its documentation without restriction, including   */
10 /*  without limitation the rights to use, copy, modify, merge, publish,  */
11 /*  distribute, sublicense, and/or sell copies of this work, and to      */
12 /*  permit persons to whom this work is furnished to do so, subject to   */
13 /*  the following conditions:                                            */
14 /*   1. The code must retain the above copyright notice, this list of    */
15 /*      conditions and the following disclaimer.                         */
16 /*   2. Any modifications must be clearly marked as such.                */
17 /*   3. Original authors' names are not deleted.                         */
18 /*   4. The authors' names are not used to endorse or promote products   */
19 /*      derived from this software without specific prior written        */
20 /*      permission.                                                      */
21 /*                                                                       */
22 /*  CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK         */
23 /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
24 /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
25 /*  SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE      */
26 /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
27 /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
28 /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
29 /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
30 /*  THIS SOFTWARE.                                                       */
31 /*                                                                       */
32 /*************************************************************************/
33 /*             Author:  Alan W Black (awb@cs.cmu.edu)                    */
34 /*               Date:  November 2001                                    */
35 /*************************************************************************/
36 /*                                                                       */
37 /*  Argument/usage command parser (like that in EST)                     */
38 /*                                                                       */
39 /*************************************************************************/
40 #include "cst_tokenstream.h"
41 #include "cst_features.h"
42 
43 static void parse_description(const char *description, cst_features *f);
44 static void parse_usage(const char *progname,
45 			const char *s1, const char *s2,
46 			const char *description);
47 
cst_args(char ** argv,int argc,const char * description,cst_features * args)48 cst_val *cst_args(char **argv, int argc,
49 		  const char *description,
50 		  cst_features *args)
51 {
52     /* parses the given arguments wrt the description */
53     cst_features *op_types = new_features();
54     cst_val *files = NULL;
55     int i;
56     const char *type;
57 
58     parse_description(description,op_types);
59 
60     for (i=1; i<argc; i++)
61     {
62 	if (argv[i][0] == '-')
63 	{
64 	    if ((!feat_present(op_types,argv[i])) ||
65 		(cst_streq("-h",argv[i])) ||
66 		(cst_streq("-?",argv[i])) ||
67 		(cst_streq("--help",argv[i])) ||
68 		(cst_streq("-help",argv[i])))
69 		parse_usage(argv[0],"","",description);
70 	    else
71 	    {
72 		type = feat_string(op_types,argv[i]);
73 		if (cst_streq("<binary>",type))
74 		    feat_set_string(args,argv[i],"true");
75 		else
76 		{
77 		    if (i+1 == argc)
78 			parse_usage(argv[0],
79 				    "missing argument for ",argv[i],
80 				    description);
81 		    if (cst_streq("<int>",type))
82 			feat_set_int(args,argv[i],atoi(argv[i+1]));
83 		    else if (cst_streq("<float>",type))
84 			feat_set_float(args,argv[i],atof(argv[i+1]));
85 		    else if (cst_streq("<string>",type))
86 			feat_set_string(args,argv[i],argv[i+1]);
87 		    else
88 			parse_usage(argv[0],
89 				    "unknown arg type ",type,
90 				    description);
91 		    i++;
92 		}
93 	    }
94 	}
95 	else
96 	    files = cons_val(string_val(argv[i]),files);
97     }
98     delete_features(op_types);
99 
100     return val_reverse(files);
101 }
102 
parse_usage(const char * progname,const char * s1,const char * s2,const char * description)103 static void parse_usage(const char *progname,
104 			const char *s1, const char *s2,
105 			const char *description)
106 {
107     cst_errmsg("%s: %s %s\n", progname,s1,s2);
108     cst_errmsg("%s\n",description);
109     exit(0);
110 }
111 
parse_description(const char * description,cst_features * f)112 static void parse_description(const char *description, cst_features *f)
113 {
114     /* parse the description into something more usable */
115     cst_tokenstream *ts;
116     const char *arg;
117     char *op;
118     const char *xop;
119 
120     ts = ts_open_string(description,
121 			" \t\r\n", /* whitespace */
122 			"{}[]|",   /* singlecharsymbols */
123 			"",        /* prepunctuation */
124 			"");       /* postpunctuation */
125     while (!ts_eof(ts))
126     {
127 	op = cst_strdup(ts_get(ts));
128 	if ((op[0] == '-') && (cst_strchr(ts->whitespace,'\n') != 0))
129 	{   /* got an option */
130             xop = feat_own_string(f,op);
131 	    arg = ts_get(ts);
132 	    if (arg[0] == '<')
133 		feat_set_string(f,xop,arg);
134 	    else
135 		feat_set_string(f,xop,"<binary>");
136         }
137         cst_free(op);
138     }
139 
140     ts_close(ts);
141 
142 }
143