summaryrefslogtreecommitdiff
path: root/src/pdflib/pdcore/pc_optparse.h
blob: ac9e6f2630acd5c6f917c4b3753b99b510b6bf55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*---------------------------------------------------------------------------*
 |              PDFlib - A library for generating PDF on the fly             |
 +---------------------------------------------------------------------------+
 | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
 +---------------------------------------------------------------------------+
 |                                                                           |
 |    This software is subject to the PDFlib license. It is NOT in the       |
 |    public domain. Extended versions and commercial licenses are           |
 |    available, please check http://www.pdflib.com.                         |
 |                                                                           |
 *---------------------------------------------------------------------------*/

/* $Id: pc_optparse.h,v 1.1 2008/10/17 06:10:43 scuri Exp $
 *
 * Definitions for option parser routines
 *
 */

#ifndef PC_OPTPARSE_H
#define PC_OPTPARSE_H

/*
 *  Optlist
 *  -------
 *  An optlist is a string containing pairs of the form
 *  "optionname optionvalue(s)". The separator characters
 *  are "\f\n\r\t\v =".
 *
 *  There are options of different types (see pdc_opttype):
 *
 *      Boolean         (pdc_booleanlist)
 *      Strings         (pdc_stringlist)
 *      Keywords        (pdc_keywordlist)
 *      Integers        (pdc_integerlist)
 *      Floats          (pdc_floatlist)
 *      Doubles         (pdc_doublelist)
 *      Scalars         (pdc_scalarlist)
 *      Unichars        (pdc_unicharlist)
 *      Polylinelist    (pdc_polylinelist)
 *      Handles         (pdc_colorhandle ...)
 *
 *  An option can have one or more values. Boolean options can be
 *  provided without any value. If an option has more than one value,
 *  then these values have to be set in braces. Examples:
 *
 *      dasharray {11 22 33}
 *
 *  Strings with white spaces have to be set in braces too.
 *  Examples:
 *
 *      fullname {Ludwig Wittgenstein}
 *      composers {{Gustav Mahler}}
 *      comment {}
 *
 *  The allowed option names and the limitations of their values
 *  must be defined in an array of enumeration type pdc_defopt
 *  (see below). Such an option definition specifies (in brackets
 *  the member name in the pdc_defopt struct)
 *
 *      - the name of the option (name)
 *      - the type of the option (type)
 *      - value restrictions by bit flags (flags)
 *      - the minimal and maximal permitted number of values
 *        (minnum, maxnum)
 *      - the minimal and maximal permitted value, or string
 *        length resp. (minval, maxval)
 *      - the permitted keywords in a keyword list (is required) or
 *        the permitted integer numbers in a integer list (is optional),
 *        resp. (keylist)
 *
 *  Remarks:
 *
 *      - minnum = maxnum = 1: The program expects a single value,
 *        otherwise an array. If an array consists of only one value
 *        the braces can be omitted - but not in the case of strings
 *        with white spaces (see example above).
 *      - Boolean options have the values "true" or "false". A shorter
 *        equivalent notation is "name" or "noname". for "name true"
 *        or "name false", resp.
 *      - White spaces in strings can be forbidden by the flag
 *        PDC_OPT_NOSPACES.
 *      - It's only possible to specify a single number interval (minval,
 *        maxval) which must contain the number. The flag PDC_OPT_NOZERO
 *        can forbid zero additionally.
 *      - Keywords will always be converted to integer numbers (keycodes)
 *        according to the specified pdc_keyconn array.
 *      - It is possible to specify keywords for integers, floats and
 *        doubles additionally by an optional keylist entry. For integers
 *        it is possible to specify the allowed integer values by an optional
 *        keylist and by the flag PDC_OPT_INTLIST.
 *      - If more than one keyword is permitted, then the flag
 *        PDC_OPT_BUILDOR decides, whether a bit pattern must be
 *        built by or-ing the single keycodes or not.
 *
 *  Program run:
 *
 *  An optlist is parsed by the function "pdc_parse_optionlist".
 *  After successfully parsing this function returns a pointer to the
 *  allocated "pdc_resopt" structures containing the option values.
 *  These structures must be freed by the function "pdc_cleanup_optionlist".
 *
 *  Values can be fetched by the function "pdc_get_optvalues". This can
 *  be achieved by specifying a variable pointer (lvalues) or by a pointer
 *  to a pointer (mvalues). In the first case the variable must be large
 *  enough to hold the values. In the second case the pointer is the pointer
 *  to the allocated array with the option values. This pointer will be
 *  freed in "pdc_cleanup_optionlist". To avoid this you can call the function
 *  "pdc_save_lastopt" after the call of "pdc_get_optvalues". Function
 *  "pdc_save_lastopt" returns the pointer which is protected now against
 *  freeing in "pdc_cleanup_optionlist". In the special case of type =
 *  pdc_stringlist, you can protect only the first element in the string
 *  list by calling "pdc_save_lastopt" with the flag PDC_OPT_SAVE1ELEM.
 *  Flag = PDC_OPT_SAVEALL defines the general case. The caller has the
 *  responsibility to free the protected pointers after use.
 *
 *  pdc_stringlist:
 *  maxnum = 1: lvalues: char s[maxval+1]  (defined char array)
 *  maxnum > 1: lvalues: char *s[maxnum]   (defined char pointer array)
 *              mvalues: char **s          (pointer to a char pointer array)
 *
 */

typedef struct pdc_keyconn_s pdc_keyconn;
typedef struct pdc_clientdata_s pdc_clientdata;
typedef struct pdc_defopt_s pdc_defopt;
typedef struct pdc_resopt_s pdc_resopt;

/* types of option values */
typedef enum
{
    pdc_booleanlist = 0,
    pdc_stringlist,
    pdc_keywordlist,
    pdc_integerlist,
    pdc_floatlist,
    pdc_doublelist,
    pdc_scalarlist,
    pdc_unicharlist,
    pdc_polylinelist,

    /* correspondig member of pdc_clientdata_s must be specified */
    pdc_3ddatahandle,
    pdc_3dviewhandle,
    pdc_actionhandle,
    pdc_bookmarkhandle,
    pdc_colorhandle,
    pdc_documenthandle,
    pdc_fonthandle,
    pdc_gstatehandle,
    pdc_iccprofilehandle,
    pdc_imagehandle,
    pdc_layerhandle,
    pdc_pagehandle,
    pdc_patternhandle,
    pdc_shadinghandle,
    pdc_tablehandle,
    pdc_templatehandle,
    pdc_textflowhandle,
    pdc_stringhandle
}
pdc_opttype;

/* keyword - keycode */
struct pdc_keyconn_s
{
    char *word;
    int  code;
};

/* client data */
struct pdc_clientdata_s
{
    int compatibility;
    int max3ddata;
    int max3dview;
    int maxaction;
    int maxbookmark;
    int maxcolor;
    int maxdocument;
    int maxfont;
    int maxgstate;
    int maxiccprofile;
    int maximage;
    int maxlayer;
    int maxpage;
    int maxpattern;
    int maxshading;
    int maxtable;
    int maxtemplate;
    int maxtextflow;
    int maxstring;
};

/* definition of an option */
struct pdc_defopt_s
{
    const char        *name;    /* name of option keyword */
    pdc_opttype        type;    /* type of option */
    int                flags;   /* flags (see below) */
    int                minnum;  /* permitted minimal number of values */
    int                maxnum;  /* permitted maximal number of values */
    double             minval;  /* minimal permitted value / length of string */
    double             maxval;  /* maximal permitted value / length of string */
    const pdc_keyconn *keylist; /* list of permitted keywords - keycodes */
};

#define PDC_OPT_TERMINATE \
    {NULL, pdc_booleanlist, 0L, 0, 0, 0.0, 0.0, NULL}

#define PDC_OPT_NONE       (0)      /* no flag specified */
#define PDC_OPT_NOZERO     (1L<<0)  /* zero value not allowed */
#define PDC_OPT_NOSPACES   (1L<<1)  /* white spaces in strings not allowed */
#define PDC_OPT_REQUIRED   (1L<<2)  /* option is required */
#define PDC_OPT_BUILDOR    (1L<<3)  /* build an OR bit pattern by keycodes */
#define PDC_OPT_INTLIST    (1L<<4)  /* keylist is list of allowed integers */
#define PDC_OPT_IGNOREIF1  (1L<<5)  /* option is ignored if previous option is
                                     * specified */
#define PDC_OPT_IGNOREIF2  (1L<<6)  /* option is ignored if either of
                                     * previous two options is specified */
#define PDC_OPT_UNSUPP     (1L<<8)  /* option is not supported in this
                                     * configuration */
#define PDC_OPT_REQUIRIF1  (1L<<9)  /* option is required if previous option is
                                     * specified */
#define PDC_OPT_REQUIRIF2  (1L<<10) /* option is required if either of
                                     * previous two options is specified */
#define PDC_OPT_EVENNUM    (1L<<11) /* array has even number of elements */
#define PDC_OPT_ODDNUM     (1L<<12) /* array has odd number of elements */

/* member "compatibility" of pdc_clientdata_s must be specified (1L<<13) ... */
#define PDC_OPT_PDC_1_3    (1L<<PDC_1_3) /* compatibility PDC_1_3 */
#define PDC_OPT_PDC_1_4    (1L<<PDC_1_4) /* compatibility PDC_1_4 */
#define PDC_OPT_PDC_1_5    (1L<<PDC_1_5) /* compatibility PDC_1_5 */
#define PDC_OPT_PDC_1_6    (1L<<PDC_1_6) /* compatibility PDC_1_6 */
#define PDC_OPT_PDC_1_7    (1L<<PDC_1_7) /* compatibility PDC_1_7 */

#define PDC_OPT_CASESENS   (1L<<20) /* case-sensitive keywords */
#define PDC_OPT_PERCENT    (1L<<21) /* number maybe with percent sign (123%) */
#define PDC_OPT_DUPORIGVAL (1L<<22) /* duplicate original value */
#define PDC_OPT_SUBOPTLIST (1L<<23) /* string list is a suboptlist */
#define PDC_OPT_CONVUTF8   (1L<<24) /* string has to be converted to UTF-8 */
#define PDC_OPT_ISBOX      (1L<<25) /* polyline is a box (four coordinates) */
#define PDC_OPT_PERCRANGE  (1L<<26) /* number only in the range 0% - 100% */

#define PDC_OPT_KEYLIST1   (1L<<27) /* use key list only for first element */
#define PDC_OPT_CLOSEPOLY  (1L<<28) /* close polyline, minimal vertices = 3 */

/* flags for single result */
#define PDC_OPT_SAVEALL    (1L<<0)  /* save all pointers */
#define PDC_OPT_SAVE1ELEM  (1L<<1)  /* save only first string list element */
#define PDC_OPT_SAVEORIG   (1L<<2)  /* save original value string */

/* flag for UTF-8 value */
#define PDC_OPT_ISUTF8     (1L<<9)  /* string[list] is UTF-8 */

/* key word not found */
#define PDC_KEY_NOTFOUND  -1234567890

/* key word abbreviation not unique */
#define PDC_KEY_NOTUNIQUE -1234567891

/* separator signs in option lists */
#define PDC_OPT_LISTSEPS    "\f\n\r\t\v ="

/* pc_optparse.c */
int pdc_get_keycode(const char *keyword, const pdc_keyconn *keyconn);
int pdc_get_keycode_ci(const char *keyword, const pdc_keyconn *keyconn);
int pdc_get_keycode_unique(const char *keyword, const pdc_keyconn *keyconn);
int pdc_get_keymask_ci(pdc_core *pdc, const char *option,
        const char *keywordlist, const pdc_keyconn *keyconn);
int pdc_get_keycode_num(pdc_core *pdc, const char *option,
        const char *i_keyword, int flags, const pdc_keyconn *keyconn,
        int *o_num);
const char *pdc_get_keyword(int keycode, const pdc_keyconn *keyconn);
const char *pdc_get_int_keyword(const char *keyword,
	const pdc_keyconn *keyconn);
pdc_resopt *pdc_parse_optionlist(pdc_core *pdc, const char *optlist,
        const pdc_defopt *defopt, const pdc_clientdata *clientdata,
        pdc_bool verbose);
int pdc_get_optvalues(const char *keyword, pdc_resopt *resopt,
        void *lvalues, char ***mvalues);
void *pdc_save_lastopt(pdc_resopt *resopt, int flags);
int pdc_get_lastopt_index(pdc_resopt *resopt);
pdc_bool pdc_is_lastopt_percent(pdc_resopt *resopt, int ind);
pdc_bool pdc_is_lastopt_utf8(pdc_resopt *resopt);
int pdc_get_opt_utf8strings(pdc_core *pdc, const char *keyword,
        pdc_resopt *resopt, int flags, char ***strings);
void pdc_cleanup_optionlist(pdc_core *pdc, pdc_resopt *resopt);
void pdc_cleanup_optstringlist(pdc_core *pdc, char **stringlist, int ns);
const char *pdc_get_handletype(pdc_opttype type);

#endif  /* PC_OPTPARSE_H */