xref: /aosp_15_r20/external/pcre/maint/ucptest.c (revision 22dc650d8ae982c6770746019a6f94af92b0f024)
1*22dc650dSSadaf Ebrahimi /***************************************************
2*22dc650dSSadaf Ebrahimi * A program for testing the Unicode property table *
3*22dc650dSSadaf Ebrahimi ***************************************************/
4*22dc650dSSadaf Ebrahimi 
5*22dc650dSSadaf Ebrahimi /* Copyright (c) University of Cambridge 2008-2023 */
6*22dc650dSSadaf Ebrahimi 
7*22dc650dSSadaf Ebrahimi /* Compile thus:
8*22dc650dSSadaf Ebrahimi 
9*22dc650dSSadaf Ebrahimi    gcc -DHAVE_CONFIG_H -DPCRE2_CODE_UNIT_WIDTH=8 \
10*22dc650dSSadaf Ebrahimi      -fvisibility=hidden -o ucptest ucptest.c \
11*22dc650dSSadaf Ebrahimi      ../src/pcre2_ord2utf.c ../src/pcre2_ucd.c ../src/pcre2_tables.c
12*22dc650dSSadaf Ebrahimi 
13*22dc650dSSadaf Ebrahimi    Add -lreadline or -ledit if PCRE2 was configured with readline or libedit
14*22dc650dSSadaf Ebrahimi    support in pcre2test.
15*22dc650dSSadaf Ebrahimi */
16*22dc650dSSadaf Ebrahimi 
17*22dc650dSSadaf Ebrahimi /* This is a hacked-up program for testing the Unicode properties tables of
18*22dc650dSSadaf Ebrahimi PCRE2. It can also be used for finding characters with certain properties. I
19*22dc650dSSadaf Ebrahimi wrote it to help with debugging, and have added things that I found useful, in
20*22dc650dSSadaf Ebrahimi a rather haphazard way. The code has never been seriously tidied or checked for
21*22dc650dSSadaf Ebrahimi robustness, but it shouldn't now give compiler warnings.
22*22dc650dSSadaf Ebrahimi 
23*22dc650dSSadaf Ebrahimi There is only one option: "-s". If given, it applies only to the "findprop"
24*22dc650dSSadaf Ebrahimi command. It causes the UTF-8 sequence of bytes that encode the character to be
25*22dc650dSSadaf Ebrahimi output between angle brackets at the end of the line. On a UTF-8 terminal, this
26*22dc650dSSadaf Ebrahimi will show the appropriate graphic for the code point.
27*22dc650dSSadaf Ebrahimi 
28*22dc650dSSadaf Ebrahimi If the command has arguments, they are concatenated into a buffer, separated by
29*22dc650dSSadaf Ebrahimi spaces. If the first argument starts "U+" or consists entirely of hexadecimal
30*22dc650dSSadaf Ebrahimi digits, "findprop" is inserted at the start. The buffer is then processed as a
31*22dc650dSSadaf Ebrahimi single line file, after which the program exits. If there are no arguments, the
32*22dc650dSSadaf Ebrahimi program reads commands line by line on stdin and writes output to stdout. The
33*22dc650dSSadaf Ebrahimi return code is always zero.
34*22dc650dSSadaf Ebrahimi 
35*22dc650dSSadaf Ebrahimi There are three commands:
36*22dc650dSSadaf Ebrahimi 
37*22dc650dSSadaf Ebrahimi The command "findprop" must be followed by a space-separated list of Unicode
38*22dc650dSSadaf Ebrahimi code points as hex numbers, either without any prefix or starting with "U+", or
39*22dc650dSSadaf Ebrahimi as individual UTF-8 characters preceded by '+'. For example:
40*22dc650dSSadaf Ebrahimi 
41*22dc650dSSadaf Ebrahimi   findprop U+1234 5Abc +?
42*22dc650dSSadaf Ebrahimi 
43*22dc650dSSadaf Ebrahimi The output is one long line per character, listing Unicode properties that have
44*22dc650dSSadaf Ebrahimi values, followed by its other case or cases if one or more exist, followed by
45*22dc650dSSadaf Ebrahimi its Script Extension list if there is one. This list is in square brackets. A
46*22dc650dSSadaf Ebrahimi second list in square brackets gives all the Boolean properties of the
47*22dc650dSSadaf Ebrahimi character. The properties that come first are:
48*22dc650dSSadaf Ebrahimi 
49*22dc650dSSadaf Ebrahimi   Bidi class          e.g. NSM (most common is L)
50*22dc650dSSadaf Ebrahimi   General type        e.g. Letter
51*22dc650dSSadaf Ebrahimi   Specific type       e.g. Upper case letter
52*22dc650dSSadaf Ebrahimi   Script              e.g. Medefaidrin
53*22dc650dSSadaf Ebrahimi   Grapheme break type e.g. Extend (most common is Other)
54*22dc650dSSadaf Ebrahimi 
55*22dc650dSSadaf Ebrahimi Script names and Boolean property names are all in lower case, with underscores
56*22dc650dSSadaf Ebrahimi and hyphens removed, because that's how they are stored for "loose" matching.
57*22dc650dSSadaf Ebrahimi 
58*22dc650dSSadaf Ebrahimi The command "find" must be followed by a list of property types and their
59*22dc650dSSadaf Ebrahimi values. The values are case-sensitive, except for bidi class. This finds
60*22dc650dSSadaf Ebrahimi characters that have those properties. If multiple properties are listed, they
61*22dc650dSSadaf Ebrahimi must all be matched. Currently supported:
62*22dc650dSSadaf Ebrahimi 
63*22dc650dSSadaf Ebrahimi   script <name>    The character must have this script property. Only one
64*22dc650dSSadaf Ebrahimi                      such script may be given.
65*22dc650dSSadaf Ebrahimi   scriptx <name>   This script must be in the character's Script Extension
66*22dc650dSSadaf Ebrahimi                      property list. If this is used many times, all the given
67*22dc650dSSadaf Ebrahimi                      scripts must be present.
68*22dc650dSSadaf Ebrahimi   type <abbrev>    The character's specific type (e.g. Lu or Nd) must match.
69*22dc650dSSadaf Ebrahimi   gbreak <name>    The grapheme break property must match.
70*22dc650dSSadaf Ebrahimi   bidi <class>     The character's bidi class must match.
71*22dc650dSSadaf Ebrahimi   bool <name>      The character's Boolean property list must contain this
72*22dc650dSSadaf Ebrahimi                      property.
73*22dc650dSSadaf Ebrahimi 
74*22dc650dSSadaf Ebrahimi If a <name> or <abbrev> is preceded by !, the value must NOT be present. For
75*22dc650dSSadaf Ebrahimi Script Extensions and Boolean properties, there may be a mixture of positive
76*22dc650dSSadaf Ebrahimi and negative requirements. All must be satisfied.
77*22dc650dSSadaf Ebrahimi 
78*22dc650dSSadaf Ebrahimi Sequences of two or more characters are shown as ranges, for example
79*22dc650dSSadaf Ebrahimi U+0041..U+004A. No more than 100 lines are output. If there are more
80*22dc650dSSadaf Ebrahimi characters, the list ends with ...
81*22dc650dSSadaf Ebrahimi 
82*22dc650dSSadaf Ebrahimi The command "list" must be followed by one of property names script, bool,
83*22dc650dSSadaf Ebrahimi type, gbreak or bidi. The defined values for that property are listed. */
84*22dc650dSSadaf Ebrahimi 
85*22dc650dSSadaf Ebrahimi 
86*22dc650dSSadaf Ebrahimi #ifdef HAVE_CONFIG_H
87*22dc650dSSadaf Ebrahimi #include "../src/config.h"
88*22dc650dSSadaf Ebrahimi #endif
89*22dc650dSSadaf Ebrahimi 
90*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_UNICODE
91*22dc650dSSadaf Ebrahimi #error "Unicode support not enabled"
92*22dc650dSSadaf Ebrahimi #endif
93*22dc650dSSadaf Ebrahimi 
94*22dc650dSSadaf Ebrahimi #include <ctype.h>
95*22dc650dSSadaf Ebrahimi #include <stdio.h>
96*22dc650dSSadaf Ebrahimi #include <stdlib.h>
97*22dc650dSSadaf Ebrahimi #include <string.h>
98*22dc650dSSadaf Ebrahimi #include "../src/pcre2_internal.h"
99*22dc650dSSadaf Ebrahimi #include "../src/pcre2_ucp.h"
100*22dc650dSSadaf Ebrahimi 
101*22dc650dSSadaf Ebrahimi #ifdef HAVE_UNISTD_H
102*22dc650dSSadaf Ebrahimi #include <unistd.h>
103*22dc650dSSadaf Ebrahimi #endif
104*22dc650dSSadaf Ebrahimi 
105*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
106*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE)
107*22dc650dSSadaf Ebrahimi #include <readline/readline.h>
108*22dc650dSSadaf Ebrahimi #include <readline/history.h>
109*22dc650dSSadaf Ebrahimi #else
110*22dc650dSSadaf Ebrahimi #if defined(HAVE_EDITLINE_READLINE_H)
111*22dc650dSSadaf Ebrahimi #include <editline/readline.h>
112*22dc650dSSadaf Ebrahimi #else
113*22dc650dSSadaf Ebrahimi #include <readline/readline.h>
114*22dc650dSSadaf Ebrahimi #ifdef RL_VERSION_MAJOR
115*22dc650dSSadaf Ebrahimi #include <readline/history.h>
116*22dc650dSSadaf Ebrahimi #endif
117*22dc650dSSadaf Ebrahimi #endif
118*22dc650dSSadaf Ebrahimi #endif
119*22dc650dSSadaf Ebrahimi #endif
120*22dc650dSSadaf Ebrahimi 
121*22dc650dSSadaf Ebrahimi 
122*22dc650dSSadaf Ebrahimi /* -------------------------------------------------------------------*/
123*22dc650dSSadaf Ebrahimi 
124*22dc650dSSadaf Ebrahimi #define CS   (char *)
125*22dc650dSSadaf Ebrahimi #define CCS  (const char *)
126*22dc650dSSadaf Ebrahimi #define CSS  (char **)
127*22dc650dSSadaf Ebrahimi #define US   (unsigned char *)
128*22dc650dSSadaf Ebrahimi #define CUS  (const unsigned char *)
129*22dc650dSSadaf Ebrahimi 
130*22dc650dSSadaf Ebrahimi /* -------------------------------------------------------------------*/
131*22dc650dSSadaf Ebrahimi 
132*22dc650dSSadaf Ebrahimi static BOOL show_character = FALSE;
133*22dc650dSSadaf Ebrahimi 
134*22dc650dSSadaf Ebrahimi static const unsigned char *type_names[] = {
135*22dc650dSSadaf Ebrahimi   US"Cc", US"Control",
136*22dc650dSSadaf Ebrahimi   US"Cf", US"Format",
137*22dc650dSSadaf Ebrahimi   US"Cn", US"Unassigned",
138*22dc650dSSadaf Ebrahimi   US"Co", US"Private use",
139*22dc650dSSadaf Ebrahimi   US"Cs", US"Surrogate",
140*22dc650dSSadaf Ebrahimi   US"Ll", US"Lower case letter",
141*22dc650dSSadaf Ebrahimi   US"Lm", US"Modifier letter",
142*22dc650dSSadaf Ebrahimi   US"Lo", US"Other letter",
143*22dc650dSSadaf Ebrahimi   US"Lt", US"Title case letter",
144*22dc650dSSadaf Ebrahimi   US"Lu", US"Upper case letter",
145*22dc650dSSadaf Ebrahimi   US"Mc", US"Spacing mark",
146*22dc650dSSadaf Ebrahimi   US"Me", US"Enclosing mark",
147*22dc650dSSadaf Ebrahimi   US"Mn", US"Non-spacing mark",
148*22dc650dSSadaf Ebrahimi   US"Nd", US"Decimal number",
149*22dc650dSSadaf Ebrahimi   US"Nl", US"Letter number",
150*22dc650dSSadaf Ebrahimi   US"No", US"Other number",
151*22dc650dSSadaf Ebrahimi   US"Pc", US"Connector punctuation",
152*22dc650dSSadaf Ebrahimi   US"Pd", US"Dash punctuation",
153*22dc650dSSadaf Ebrahimi   US"Pe", US"Close punctuation",
154*22dc650dSSadaf Ebrahimi   US"Pf", US"Final punctuation",
155*22dc650dSSadaf Ebrahimi   US"Pi", US"Initial punctuation",
156*22dc650dSSadaf Ebrahimi   US"Po", US"Other punctuation",
157*22dc650dSSadaf Ebrahimi   US"Ps", US"Open punctuation",
158*22dc650dSSadaf Ebrahimi   US"Sc", US"Currency symbol",
159*22dc650dSSadaf Ebrahimi   US"Sk", US"Modifier symbol",
160*22dc650dSSadaf Ebrahimi   US"Sm", US"Mathematical symbol",
161*22dc650dSSadaf Ebrahimi   US"So", US"Other symbol",
162*22dc650dSSadaf Ebrahimi   US"Zl", US"Line separator",
163*22dc650dSSadaf Ebrahimi   US"Zp", US"Paragraph separator",
164*22dc650dSSadaf Ebrahimi   US"Zs", US"Space separator"
165*22dc650dSSadaf Ebrahimi };
166*22dc650dSSadaf Ebrahimi 
167*22dc650dSSadaf Ebrahimi static const unsigned char *gb_names[] = {
168*22dc650dSSadaf Ebrahimi   US"CR",                    US"carriage return",
169*22dc650dSSadaf Ebrahimi   US"LF",                    US"linefeed",
170*22dc650dSSadaf Ebrahimi   US"Control",               US"",
171*22dc650dSSadaf Ebrahimi   US"Extend",                US"",
172*22dc650dSSadaf Ebrahimi   US"Prepend",               US"",
173*22dc650dSSadaf Ebrahimi   US"SpacingMark",           US"",
174*22dc650dSSadaf Ebrahimi   US"L",                     US"Hangul syllable type L",
175*22dc650dSSadaf Ebrahimi   US"V",                     US"Hangul syllable type V",
176*22dc650dSSadaf Ebrahimi   US"T",                     US"Hangul syllable type T",
177*22dc650dSSadaf Ebrahimi   US"LV",                    US"Hangul syllable type LV",
178*22dc650dSSadaf Ebrahimi   US"LVT",                   US"Hangul syllable type LVT",
179*22dc650dSSadaf Ebrahimi   US"Regional_Indicator",    US"",
180*22dc650dSSadaf Ebrahimi   US"Other",                 US"",
181*22dc650dSSadaf Ebrahimi   US"ZWJ",                   US"zero width joiner",
182*22dc650dSSadaf Ebrahimi   US"Extended_Pictographic", US""
183*22dc650dSSadaf Ebrahimi };
184*22dc650dSSadaf Ebrahimi 
185*22dc650dSSadaf Ebrahimi static const unsigned char *bd_names[] = {
186*22dc650dSSadaf Ebrahimi   US"AL",   US"ArabicLetter",
187*22dc650dSSadaf Ebrahimi   US"AN",   US"ArabicNumber",
188*22dc650dSSadaf Ebrahimi   US"B",    US"ParagraphSeparator",
189*22dc650dSSadaf Ebrahimi   US"BN",   US"BoundaryNeutral",
190*22dc650dSSadaf Ebrahimi   US"CS",   US"CommonSeparator",
191*22dc650dSSadaf Ebrahimi   US"EN",   US"EuropeanNumber",
192*22dc650dSSadaf Ebrahimi   US"ES",   US"EuropeanSeparator",
193*22dc650dSSadaf Ebrahimi   US"ET",   US"EuropeanTerminator",
194*22dc650dSSadaf Ebrahimi   US"FSI",  US"FirstStrongIsolate",
195*22dc650dSSadaf Ebrahimi   US"L",    US"LeftToRight",
196*22dc650dSSadaf Ebrahimi   US"LRE",  US"LeftToRightEmbedding",
197*22dc650dSSadaf Ebrahimi   US"LRI",  US"LeftToRightIsolate",
198*22dc650dSSadaf Ebrahimi   US"LRO",  US"LeftToRightOverride",
199*22dc650dSSadaf Ebrahimi   US"NSM",  US"NonspacingMark",
200*22dc650dSSadaf Ebrahimi   US"ON",   US"OtherNeutral",
201*22dc650dSSadaf Ebrahimi   US"PDF",  US"PopDirectionalFormat",
202*22dc650dSSadaf Ebrahimi   US"PDI",  US"PopDirectionalIsolate",
203*22dc650dSSadaf Ebrahimi   US"R",    US"RightToLeft",
204*22dc650dSSadaf Ebrahimi   US"RLE",  US"RightToLeftEmbedding",
205*22dc650dSSadaf Ebrahimi   US"RLI",  US"RightToLeftIsolate",
206*22dc650dSSadaf Ebrahimi   US"RLO",  US"RightToLeftOverride",
207*22dc650dSSadaf Ebrahimi   US"S",    US"SegmentSeparator",
208*22dc650dSSadaf Ebrahimi   US"WS",   US"WhiteSpace"
209*22dc650dSSadaf Ebrahimi };
210*22dc650dSSadaf Ebrahimi 
211*22dc650dSSadaf Ebrahimi 
212*22dc650dSSadaf Ebrahimi /*************************************************
213*22dc650dSSadaf Ebrahimi *             Test for interaction               *
214*22dc650dSSadaf Ebrahimi *************************************************/
215*22dc650dSSadaf Ebrahimi 
216*22dc650dSSadaf Ebrahimi static BOOL
is_stdin_tty(void)217*22dc650dSSadaf Ebrahimi is_stdin_tty(void)
218*22dc650dSSadaf Ebrahimi {
219*22dc650dSSadaf Ebrahimi #if defined WIN32
220*22dc650dSSadaf Ebrahimi return _isatty(_fileno(stdin));
221*22dc650dSSadaf Ebrahimi #else
222*22dc650dSSadaf Ebrahimi return isatty(fileno(stdin));
223*22dc650dSSadaf Ebrahimi #endif
224*22dc650dSSadaf Ebrahimi }
225*22dc650dSSadaf Ebrahimi 
226*22dc650dSSadaf Ebrahimi 
227*22dc650dSSadaf Ebrahimi /*************************************************
228*22dc650dSSadaf Ebrahimi *            Get  name from ucp ident            *
229*22dc650dSSadaf Ebrahimi *************************************************/
230*22dc650dSSadaf Ebrahimi 
231*22dc650dSSadaf Ebrahimi /* The utt table contains both full names and abbreviations. So search for both
232*22dc650dSSadaf Ebrahimi and use the longer if two are found, unless the first one is only 3 characters
233*22dc650dSSadaf Ebrahimi and we are looking for a script (some scripts have 3-character names). If this
234*22dc650dSSadaf Ebrahimi were not just a test program it might be worth making some kind of reverse
235*22dc650dSSadaf Ebrahimi index. */
236*22dc650dSSadaf Ebrahimi 
237*22dc650dSSadaf Ebrahimi static const char *
get_propname(int prop,int type)238*22dc650dSSadaf Ebrahimi get_propname(int prop, int type)
239*22dc650dSSadaf Ebrahimi {
240*22dc650dSSadaf Ebrahimi size_t i, j, len;
241*22dc650dSSadaf Ebrahimi size_t foundlist[2];
242*22dc650dSSadaf Ebrahimi const char *yield;
243*22dc650dSSadaf Ebrahimi int typex = (type == PT_SC)? PT_SCX : type;
244*22dc650dSSadaf Ebrahimi 
245*22dc650dSSadaf Ebrahimi j = 0;
246*22dc650dSSadaf Ebrahimi for (i = 0; i < PRIV(utt_size); i++)
247*22dc650dSSadaf Ebrahimi   {
248*22dc650dSSadaf Ebrahimi   const ucp_type_table *u = PRIV(utt) + i;
249*22dc650dSSadaf Ebrahimi   if ((u->type == type || u->type == typex) && u->value == prop)
250*22dc650dSSadaf Ebrahimi     {
251*22dc650dSSadaf Ebrahimi     foundlist[j++] = i;
252*22dc650dSSadaf Ebrahimi     if (j >= 2) break;
253*22dc650dSSadaf Ebrahimi     }
254*22dc650dSSadaf Ebrahimi   }
255*22dc650dSSadaf Ebrahimi 
256*22dc650dSSadaf Ebrahimi if (j == 0) return "??";
257*22dc650dSSadaf Ebrahimi 
258*22dc650dSSadaf Ebrahimi yield = NULL;
259*22dc650dSSadaf Ebrahimi len = 0;
260*22dc650dSSadaf Ebrahimi 
261*22dc650dSSadaf Ebrahimi for (i = 0; i < j; i++)
262*22dc650dSSadaf Ebrahimi   {
263*22dc650dSSadaf Ebrahimi   const char *s = PRIV(utt_names) + (PRIV(utt) + foundlist[i])->name_offset;
264*22dc650dSSadaf Ebrahimi   size_t sl = strlen(s);
265*22dc650dSSadaf Ebrahimi 
266*22dc650dSSadaf Ebrahimi   if (sl > len)
267*22dc650dSSadaf Ebrahimi     {
268*22dc650dSSadaf Ebrahimi     yield = s;
269*22dc650dSSadaf Ebrahimi     if (sl == 3 && type == PT_SC) break;
270*22dc650dSSadaf Ebrahimi     len = sl;
271*22dc650dSSadaf Ebrahimi     }
272*22dc650dSSadaf Ebrahimi   }
273*22dc650dSSadaf Ebrahimi 
274*22dc650dSSadaf Ebrahimi return yield;
275*22dc650dSSadaf Ebrahimi }
276*22dc650dSSadaf Ebrahimi 
277*22dc650dSSadaf Ebrahimi 
278*22dc650dSSadaf Ebrahimi /*************************************************
279*22dc650dSSadaf Ebrahimi *      Print Unicode property info for a char    *
280*22dc650dSSadaf Ebrahimi *************************************************/
281*22dc650dSSadaf Ebrahimi 
282*22dc650dSSadaf Ebrahimi static void
print_prop(unsigned int c,BOOL is_just_one)283*22dc650dSSadaf Ebrahimi print_prop(unsigned int c, BOOL is_just_one)
284*22dc650dSSadaf Ebrahimi {
285*22dc650dSSadaf Ebrahimi unsigned int type = UCD_CATEGORY(c);
286*22dc650dSSadaf Ebrahimi int fulltype = UCD_CHARTYPE(c);
287*22dc650dSSadaf Ebrahimi int script = UCD_SCRIPT(c);
288*22dc650dSSadaf Ebrahimi int scriptx = UCD_SCRIPTX(c);
289*22dc650dSSadaf Ebrahimi int gbprop = UCD_GRAPHBREAK(c);
290*22dc650dSSadaf Ebrahimi int bidi = UCD_BIDICLASS(c);
291*22dc650dSSadaf Ebrahimi unsigned int othercase = UCD_OTHERCASE(c);
292*22dc650dSSadaf Ebrahimi int caseset = UCD_CASESET(c);
293*22dc650dSSadaf Ebrahimi int bprops = UCD_BPROPS(c);
294*22dc650dSSadaf Ebrahimi 
295*22dc650dSSadaf Ebrahimi const unsigned char *fulltypename = US"??";
296*22dc650dSSadaf Ebrahimi const unsigned char *typename = US"??";
297*22dc650dSSadaf Ebrahimi const unsigned char *graphbreak = US"??";
298*22dc650dSSadaf Ebrahimi const unsigned char *bidiclass = US"??";
299*22dc650dSSadaf Ebrahimi const unsigned char *scriptname = CUS get_propname(script, PT_SC);
300*22dc650dSSadaf Ebrahimi 
301*22dc650dSSadaf Ebrahimi switch (type)
302*22dc650dSSadaf Ebrahimi   {
303*22dc650dSSadaf Ebrahimi   case ucp_C: typename = US"Control"; break;
304*22dc650dSSadaf Ebrahimi   case ucp_L: typename = US"Letter"; break;
305*22dc650dSSadaf Ebrahimi   case ucp_M: typename = US"Mark"; break;
306*22dc650dSSadaf Ebrahimi   case ucp_N: typename = US"Number"; break;
307*22dc650dSSadaf Ebrahimi   case ucp_P: typename = US"Punctuation"; break;
308*22dc650dSSadaf Ebrahimi   case ucp_S: typename = US"Symbol"; break;
309*22dc650dSSadaf Ebrahimi   case ucp_Z: typename = US"Separator"; break;
310*22dc650dSSadaf Ebrahimi   }
311*22dc650dSSadaf Ebrahimi 
312*22dc650dSSadaf Ebrahimi switch (fulltype)
313*22dc650dSSadaf Ebrahimi   {
314*22dc650dSSadaf Ebrahimi   case ucp_Cc: fulltypename = US"Control"; break;
315*22dc650dSSadaf Ebrahimi   case ucp_Cf: fulltypename = US"Format"; break;
316*22dc650dSSadaf Ebrahimi   case ucp_Cn: fulltypename = US"Unassigned"; break;
317*22dc650dSSadaf Ebrahimi   case ucp_Co: fulltypename = US"Private use"; break;
318*22dc650dSSadaf Ebrahimi   case ucp_Cs: fulltypename = US"Surrogate"; break;
319*22dc650dSSadaf Ebrahimi   case ucp_Ll: fulltypename = US"Lower case letter"; break;
320*22dc650dSSadaf Ebrahimi   case ucp_Lm: fulltypename = US"Modifier letter"; break;
321*22dc650dSSadaf Ebrahimi   case ucp_Lo: fulltypename = US"Other letter"; break;
322*22dc650dSSadaf Ebrahimi   case ucp_Lt: fulltypename = US"Title case letter"; break;
323*22dc650dSSadaf Ebrahimi   case ucp_Lu: fulltypename = US"Upper case letter"; break;
324*22dc650dSSadaf Ebrahimi   case ucp_Mc: fulltypename = US"Spacing mark"; break;
325*22dc650dSSadaf Ebrahimi   case ucp_Me: fulltypename = US"Enclosing mark"; break;
326*22dc650dSSadaf Ebrahimi   case ucp_Mn: fulltypename = US"Non-spacing mark"; break;
327*22dc650dSSadaf Ebrahimi   case ucp_Nd: fulltypename = US"Decimal number"; break;
328*22dc650dSSadaf Ebrahimi   case ucp_Nl: fulltypename = US"Letter number"; break;
329*22dc650dSSadaf Ebrahimi   case ucp_No: fulltypename = US"Other number"; break;
330*22dc650dSSadaf Ebrahimi   case ucp_Pc: fulltypename = US"Connector punctuation"; break;
331*22dc650dSSadaf Ebrahimi   case ucp_Pd: fulltypename = US"Dash punctuation"; break;
332*22dc650dSSadaf Ebrahimi   case ucp_Pe: fulltypename = US"Close punctuation"; break;
333*22dc650dSSadaf Ebrahimi   case ucp_Pf: fulltypename = US"Final punctuation"; break;
334*22dc650dSSadaf Ebrahimi   case ucp_Pi: fulltypename = US"Initial punctuation"; break;
335*22dc650dSSadaf Ebrahimi   case ucp_Po: fulltypename = US"Other punctuation"; break;
336*22dc650dSSadaf Ebrahimi   case ucp_Ps: fulltypename = US"Open punctuation"; break;
337*22dc650dSSadaf Ebrahimi   case ucp_Sc: fulltypename = US"Currency symbol"; break;
338*22dc650dSSadaf Ebrahimi   case ucp_Sk: fulltypename = US"Modifier symbol"; break;
339*22dc650dSSadaf Ebrahimi   case ucp_Sm: fulltypename = US"Mathematical symbol"; break;
340*22dc650dSSadaf Ebrahimi   case ucp_So: fulltypename = US"Other symbol"; break;
341*22dc650dSSadaf Ebrahimi   case ucp_Zl: fulltypename = US"Line separator"; break;
342*22dc650dSSadaf Ebrahimi   case ucp_Zp: fulltypename = US"Paragraph separator"; break;
343*22dc650dSSadaf Ebrahimi   case ucp_Zs: fulltypename = US"Space separator"; break;
344*22dc650dSSadaf Ebrahimi   }
345*22dc650dSSadaf Ebrahimi 
346*22dc650dSSadaf Ebrahimi switch(gbprop)
347*22dc650dSSadaf Ebrahimi   {
348*22dc650dSSadaf Ebrahimi   case ucp_gbCR:           graphbreak = US"CR"; break;
349*22dc650dSSadaf Ebrahimi   case ucp_gbLF:           graphbreak = US"LF"; break;
350*22dc650dSSadaf Ebrahimi   case ucp_gbControl:      graphbreak = US"Control"; break;
351*22dc650dSSadaf Ebrahimi   case ucp_gbExtend:       graphbreak = US"Extend"; break;
352*22dc650dSSadaf Ebrahimi   case ucp_gbPrepend:      graphbreak = US"Prepend"; break;
353*22dc650dSSadaf Ebrahimi   case ucp_gbSpacingMark:  graphbreak = US"SpacingMark"; break;
354*22dc650dSSadaf Ebrahimi   case ucp_gbL:            graphbreak = US"Hangul syllable type L"; break;
355*22dc650dSSadaf Ebrahimi   case ucp_gbV:            graphbreak = US"Hangul syllable type V"; break;
356*22dc650dSSadaf Ebrahimi   case ucp_gbT:            graphbreak = US"Hangul syllable type T"; break;
357*22dc650dSSadaf Ebrahimi   case ucp_gbLV:           graphbreak = US"Hangul syllable type LV"; break;
358*22dc650dSSadaf Ebrahimi   case ucp_gbLVT:          graphbreak = US"Hangul syllable type LVT"; break;
359*22dc650dSSadaf Ebrahimi   case ucp_gbRegional_Indicator:
360*22dc650dSSadaf Ebrahimi                            graphbreak = US"Regional Indicator"; break;
361*22dc650dSSadaf Ebrahimi   case ucp_gbOther:        graphbreak = US"Other"; break;
362*22dc650dSSadaf Ebrahimi   case ucp_gbZWJ:          graphbreak = US"Zero Width Joiner"; break;
363*22dc650dSSadaf Ebrahimi   case ucp_gbExtended_Pictographic:
364*22dc650dSSadaf Ebrahimi                            graphbreak = US"Extended Pictographic"; break;
365*22dc650dSSadaf Ebrahimi   default:                 graphbreak = US"Unknown"; break;
366*22dc650dSSadaf Ebrahimi   }
367*22dc650dSSadaf Ebrahimi 
368*22dc650dSSadaf Ebrahimi switch(bidi)
369*22dc650dSSadaf Ebrahimi   {
370*22dc650dSSadaf Ebrahimi   case ucp_bidiAL:   bidiclass = US"AL "; break;
371*22dc650dSSadaf Ebrahimi   case ucp_bidiFSI:  bidiclass = US"FSI"; break;
372*22dc650dSSadaf Ebrahimi   case ucp_bidiL:    bidiclass = US"L  "; break;
373*22dc650dSSadaf Ebrahimi   case ucp_bidiLRE:  bidiclass = US"LRE"; break;
374*22dc650dSSadaf Ebrahimi   case ucp_bidiLRI:  bidiclass = US"LRI"; break;
375*22dc650dSSadaf Ebrahimi   case ucp_bidiLRO:  bidiclass = US"LRO"; break;
376*22dc650dSSadaf Ebrahimi   case ucp_bidiPDF:  bidiclass = US"PDF"; break;
377*22dc650dSSadaf Ebrahimi   case ucp_bidiPDI:  bidiclass = US"PDI"; break;
378*22dc650dSSadaf Ebrahimi   case ucp_bidiR:    bidiclass = US"R  "; break;
379*22dc650dSSadaf Ebrahimi   case ucp_bidiRLE:  bidiclass = US"RLE"; break;
380*22dc650dSSadaf Ebrahimi   case ucp_bidiRLI:  bidiclass = US"RLI"; break;
381*22dc650dSSadaf Ebrahimi   case ucp_bidiRLO:  bidiclass = US"RLO"; break;
382*22dc650dSSadaf Ebrahimi   case ucp_bidiAN:   bidiclass = US"AN "; break;
383*22dc650dSSadaf Ebrahimi   case ucp_bidiB:    bidiclass = US"B  "; break;
384*22dc650dSSadaf Ebrahimi   case ucp_bidiBN:   bidiclass = US"BN "; break;
385*22dc650dSSadaf Ebrahimi   case ucp_bidiCS:   bidiclass = US"CS "; break;
386*22dc650dSSadaf Ebrahimi   case ucp_bidiEN:   bidiclass = US"EN "; break;
387*22dc650dSSadaf Ebrahimi   case ucp_bidiES:   bidiclass = US"ES "; break;
388*22dc650dSSadaf Ebrahimi   case ucp_bidiET:   bidiclass = US"ET "; break;
389*22dc650dSSadaf Ebrahimi   case ucp_bidiNSM:  bidiclass = US"NSM"; break;
390*22dc650dSSadaf Ebrahimi   case ucp_bidiON:   bidiclass = US"ON "; break;
391*22dc650dSSadaf Ebrahimi   case ucp_bidiS:    bidiclass = US"S  "; break;
392*22dc650dSSadaf Ebrahimi   case ucp_bidiWS:   bidiclass = US"WS "; break;
393*22dc650dSSadaf Ebrahimi   default:           bidiclass = US"???"; break;
394*22dc650dSSadaf Ebrahimi   }
395*22dc650dSSadaf Ebrahimi 
396*22dc650dSSadaf Ebrahimi printf("U+%04X %s %s: %s, %s, %s", c, bidiclass, typename, fulltypename,
397*22dc650dSSadaf Ebrahimi   scriptname, graphbreak);
398*22dc650dSSadaf Ebrahimi 
399*22dc650dSSadaf Ebrahimi if (is_just_one && (othercase != c || caseset != 0))
400*22dc650dSSadaf Ebrahimi   {
401*22dc650dSSadaf Ebrahimi   if (othercase != c) printf(", U+%04X", othercase);
402*22dc650dSSadaf Ebrahimi   if (caseset != 0)
403*22dc650dSSadaf Ebrahimi     {
404*22dc650dSSadaf Ebrahimi     const uint32_t *p = PRIV(ucd_caseless_sets) + caseset - 1;
405*22dc650dSSadaf Ebrahimi     while (*(++p) < NOTACHAR)
406*22dc650dSSadaf Ebrahimi       {
407*22dc650dSSadaf Ebrahimi       unsigned int d = *p;
408*22dc650dSSadaf Ebrahimi       if (d != othercase && d != c) printf(", U+%04X", d);
409*22dc650dSSadaf Ebrahimi       }
410*22dc650dSSadaf Ebrahimi     }
411*22dc650dSSadaf Ebrahimi   }
412*22dc650dSSadaf Ebrahimi 
413*22dc650dSSadaf Ebrahimi if (scriptx != 0)
414*22dc650dSSadaf Ebrahimi   {
415*22dc650dSSadaf Ebrahimi   const char *sep = "";
416*22dc650dSSadaf Ebrahimi   const uint32_t *p = PRIV(ucd_script_sets) + scriptx;
417*22dc650dSSadaf Ebrahimi   printf(", [");
418*22dc650dSSadaf Ebrahimi   for (int i = 0; i < ucp_Unknown; i++)
419*22dc650dSSadaf Ebrahimi   if (MAPBIT(p, i) != 0)
420*22dc650dSSadaf Ebrahimi     {
421*22dc650dSSadaf Ebrahimi     printf("%s%s", sep, get_propname(i, PT_SC));
422*22dc650dSSadaf Ebrahimi     sep = ", ";
423*22dc650dSSadaf Ebrahimi     }
424*22dc650dSSadaf Ebrahimi   printf("]");
425*22dc650dSSadaf Ebrahimi   }
426*22dc650dSSadaf Ebrahimi 
427*22dc650dSSadaf Ebrahimi if (bprops != 0)
428*22dc650dSSadaf Ebrahimi   {
429*22dc650dSSadaf Ebrahimi   const char *sep = "";
430*22dc650dSSadaf Ebrahimi   const uint32_t *p = PRIV(ucd_boolprop_sets) + bprops;
431*22dc650dSSadaf Ebrahimi   printf(", [");
432*22dc650dSSadaf Ebrahimi   for (int i = 0; i < ucp_Bprop_Count; i++)
433*22dc650dSSadaf Ebrahimi   if (MAPBIT(p, i) != 0)
434*22dc650dSSadaf Ebrahimi     {
435*22dc650dSSadaf Ebrahimi     printf("%s%s", sep, get_propname(i, PT_BOOL));
436*22dc650dSSadaf Ebrahimi     sep = ", ";
437*22dc650dSSadaf Ebrahimi     }
438*22dc650dSSadaf Ebrahimi   printf("]");
439*22dc650dSSadaf Ebrahimi   }
440*22dc650dSSadaf Ebrahimi 
441*22dc650dSSadaf Ebrahimi if (show_character && is_just_one)
442*22dc650dSSadaf Ebrahimi   {
443*22dc650dSSadaf Ebrahimi   unsigned char buffer[8];
444*22dc650dSSadaf Ebrahimi   int len = (int)PRIV(ord2utf_8)(c, buffer);
445*22dc650dSSadaf Ebrahimi   printf(", >%.*s<", len, buffer);
446*22dc650dSSadaf Ebrahimi   }
447*22dc650dSSadaf Ebrahimi 
448*22dc650dSSadaf Ebrahimi printf("\n");
449*22dc650dSSadaf Ebrahimi }
450*22dc650dSSadaf Ebrahimi 
451*22dc650dSSadaf Ebrahimi 
452*22dc650dSSadaf Ebrahimi 
453*22dc650dSSadaf Ebrahimi /*************************************************
454*22dc650dSSadaf Ebrahimi *   Find character(s) with given property/ies    *
455*22dc650dSSadaf Ebrahimi *************************************************/
456*22dc650dSSadaf Ebrahimi 
457*22dc650dSSadaf Ebrahimi static void
find_chars(unsigned char * s)458*22dc650dSSadaf Ebrahimi find_chars(unsigned char *s)
459*22dc650dSSadaf Ebrahimi {
460*22dc650dSSadaf Ebrahimi unsigned char name[128];
461*22dc650dSSadaf Ebrahimi unsigned char value[128];
462*22dc650dSSadaf Ebrahimi unsigned char *t;
463*22dc650dSSadaf Ebrahimi unsigned int count= 0;
464*22dc650dSSadaf Ebrahimi int scriptx_list[128];
465*22dc650dSSadaf Ebrahimi unsigned int scriptx_count = 0;
466*22dc650dSSadaf Ebrahimi int bprop_list[128];
467*22dc650dSSadaf Ebrahimi unsigned int bprop_count = 0;
468*22dc650dSSadaf Ebrahimi uint32_t i, c;
469*22dc650dSSadaf Ebrahimi int script = -1;
470*22dc650dSSadaf Ebrahimi int type = -1;
471*22dc650dSSadaf Ebrahimi int gbreak = -1;
472*22dc650dSSadaf Ebrahimi int bidiclass = -1;
473*22dc650dSSadaf Ebrahimi BOOL script_not = FALSE;
474*22dc650dSSadaf Ebrahimi BOOL type_not = FALSE;
475*22dc650dSSadaf Ebrahimi BOOL gbreak_not = FALSE;
476*22dc650dSSadaf Ebrahimi BOOL bidiclass_not = FALSE;
477*22dc650dSSadaf Ebrahimi BOOL hadrange = FALSE;
478*22dc650dSSadaf Ebrahimi const ucd_record *ucd, *next_ucd;
479*22dc650dSSadaf Ebrahimi const char *pad = "        ";
480*22dc650dSSadaf Ebrahimi 
481*22dc650dSSadaf Ebrahimi while (*s != 0)
482*22dc650dSSadaf Ebrahimi   {
483*22dc650dSSadaf Ebrahimi   unsigned int offset = 0;
484*22dc650dSSadaf Ebrahimi 
485*22dc650dSSadaf Ebrahimi   for (t = name; *s != 0 && !isspace(*s); s++) *t++ = *s;
486*22dc650dSSadaf Ebrahimi   *t = 0;
487*22dc650dSSadaf Ebrahimi   while (isspace(*s)) s++;
488*22dc650dSSadaf Ebrahimi 
489*22dc650dSSadaf Ebrahimi   for (t = value; *s != 0 && !isspace(*s); s++)
490*22dc650dSSadaf Ebrahimi     {
491*22dc650dSSadaf Ebrahimi     if (*s != '_' && *s != '-') *t++ = *s;
492*22dc650dSSadaf Ebrahimi     }
493*22dc650dSSadaf Ebrahimi   *t = 0;
494*22dc650dSSadaf Ebrahimi   while (isspace(*s)) s++;
495*22dc650dSSadaf Ebrahimi 
496*22dc650dSSadaf Ebrahimi   if (strcmp(CS name, "script") == 0 ||
497*22dc650dSSadaf Ebrahimi       strcmp(CS name, "scriptx") == 0)
498*22dc650dSSadaf Ebrahimi     {
499*22dc650dSSadaf Ebrahimi     BOOL x = (name[6] == 'x');
500*22dc650dSSadaf Ebrahimi     BOOL scriptx_not = FALSE;
501*22dc650dSSadaf Ebrahimi     for (t = value; *t != 0; t++) *t = tolower(*t);
502*22dc650dSSadaf Ebrahimi 
503*22dc650dSSadaf Ebrahimi     if (value[0] == '!')
504*22dc650dSSadaf Ebrahimi       {
505*22dc650dSSadaf Ebrahimi       if (x) scriptx_not = TRUE; else script_not = TRUE;
506*22dc650dSSadaf Ebrahimi       offset = 1;
507*22dc650dSSadaf Ebrahimi       }
508*22dc650dSSadaf Ebrahimi 
509*22dc650dSSadaf Ebrahimi     for (i = 0; i < PRIV(utt_size); i++)
510*22dc650dSSadaf Ebrahimi       {
511*22dc650dSSadaf Ebrahimi       const ucp_type_table *u = PRIV(utt) + i;
512*22dc650dSSadaf Ebrahimi       if ((u->type == PT_SCX || u->type == PT_SC) && strcmp(CS(value + offset),
513*22dc650dSSadaf Ebrahimi             PRIV(utt_names) + u->name_offset) == 0)
514*22dc650dSSadaf Ebrahimi         {
515*22dc650dSSadaf Ebrahimi         c = u->value;
516*22dc650dSSadaf Ebrahimi         if (x && !scriptx_not && u->type == PT_SC)
517*22dc650dSSadaf Ebrahimi           {
518*22dc650dSSadaf Ebrahimi           if (script < 0)
519*22dc650dSSadaf Ebrahimi             {
520*22dc650dSSadaf Ebrahimi             x = FALSE;
521*22dc650dSSadaf Ebrahimi             script = -1;
522*22dc650dSSadaf Ebrahimi             script_not = scriptx_not;
523*22dc650dSSadaf Ebrahimi             }
524*22dc650dSSadaf Ebrahimi           else if (!script_not)
525*22dc650dSSadaf Ebrahimi             {
526*22dc650dSSadaf Ebrahimi             printf("No characters found\n");
527*22dc650dSSadaf Ebrahimi             return;
528*22dc650dSSadaf Ebrahimi             }
529*22dc650dSSadaf Ebrahimi           }
530*22dc650dSSadaf Ebrahimi         if (x)
531*22dc650dSSadaf Ebrahimi           {
532*22dc650dSSadaf Ebrahimi           scriptx_list[scriptx_count++] = scriptx_not? (-c):c;
533*22dc650dSSadaf Ebrahimi           }
534*22dc650dSSadaf Ebrahimi         else
535*22dc650dSSadaf Ebrahimi           {
536*22dc650dSSadaf Ebrahimi           if (script < 0) script = c; else
537*22dc650dSSadaf Ebrahimi             {
538*22dc650dSSadaf Ebrahimi             printf("** Only 1 script value allowed\n");
539*22dc650dSSadaf Ebrahimi             return;
540*22dc650dSSadaf Ebrahimi             }
541*22dc650dSSadaf Ebrahimi           }
542*22dc650dSSadaf Ebrahimi         break;
543*22dc650dSSadaf Ebrahimi         }
544*22dc650dSSadaf Ebrahimi       }
545*22dc650dSSadaf Ebrahimi 
546*22dc650dSSadaf Ebrahimi     if (i >= PRIV(utt_size))
547*22dc650dSSadaf Ebrahimi       {
548*22dc650dSSadaf Ebrahimi       printf("** Unrecognized script name \"%s\"\n", value);
549*22dc650dSSadaf Ebrahimi       return;
550*22dc650dSSadaf Ebrahimi       }
551*22dc650dSSadaf Ebrahimi     }
552*22dc650dSSadaf Ebrahimi 
553*22dc650dSSadaf Ebrahimi   else if (strcmp(CS name, "bool") == 0)
554*22dc650dSSadaf Ebrahimi     {
555*22dc650dSSadaf Ebrahimi     int not = 1;
556*22dc650dSSadaf Ebrahimi     if (value[0] == '!')
557*22dc650dSSadaf Ebrahimi       {
558*22dc650dSSadaf Ebrahimi       not = -1;
559*22dc650dSSadaf Ebrahimi       offset = 1;
560*22dc650dSSadaf Ebrahimi       }
561*22dc650dSSadaf Ebrahimi 
562*22dc650dSSadaf Ebrahimi     for (i = 0; i < PRIV(utt_size); i++)
563*22dc650dSSadaf Ebrahimi       {
564*22dc650dSSadaf Ebrahimi       const ucp_type_table *u = PRIV(utt) + i;
565*22dc650dSSadaf Ebrahimi       if (u->type == PT_BOOL && strcmp(CS(value + offset),
566*22dc650dSSadaf Ebrahimi             PRIV(utt_names) + u->name_offset) == 0)
567*22dc650dSSadaf Ebrahimi         {
568*22dc650dSSadaf Ebrahimi         bprop_list[bprop_count++] = u->value * not;
569*22dc650dSSadaf Ebrahimi         break;
570*22dc650dSSadaf Ebrahimi         }
571*22dc650dSSadaf Ebrahimi       }
572*22dc650dSSadaf Ebrahimi 
573*22dc650dSSadaf Ebrahimi     if (i >= PRIV(utt_size))
574*22dc650dSSadaf Ebrahimi       {
575*22dc650dSSadaf Ebrahimi       printf("** Unrecognized property name \"%s\"\n", value);
576*22dc650dSSadaf Ebrahimi       return;
577*22dc650dSSadaf Ebrahimi       }
578*22dc650dSSadaf Ebrahimi     }
579*22dc650dSSadaf Ebrahimi 
580*22dc650dSSadaf Ebrahimi   else if (strcmp(CS name, "type") == 0)
581*22dc650dSSadaf Ebrahimi     {
582*22dc650dSSadaf Ebrahimi     if (type >= 0)
583*22dc650dSSadaf Ebrahimi       {
584*22dc650dSSadaf Ebrahimi       printf("** Only 1 type value allowed\n");
585*22dc650dSSadaf Ebrahimi       return;
586*22dc650dSSadaf Ebrahimi       }
587*22dc650dSSadaf Ebrahimi     else
588*22dc650dSSadaf Ebrahimi       {
589*22dc650dSSadaf Ebrahimi       if (value[0] == '!')
590*22dc650dSSadaf Ebrahimi         {
591*22dc650dSSadaf Ebrahimi         type_not = TRUE;
592*22dc650dSSadaf Ebrahimi         offset = 1;
593*22dc650dSSadaf Ebrahimi         }
594*22dc650dSSadaf Ebrahimi 
595*22dc650dSSadaf Ebrahimi       for (i = 0; i < sizeof(type_names)/sizeof(char *); i += 2)
596*22dc650dSSadaf Ebrahimi         {
597*22dc650dSSadaf Ebrahimi         if (strcmp(CS (value + offset), CCS type_names[i]) == 0)
598*22dc650dSSadaf Ebrahimi           {
599*22dc650dSSadaf Ebrahimi           type = i/2;
600*22dc650dSSadaf Ebrahimi           break;
601*22dc650dSSadaf Ebrahimi           }
602*22dc650dSSadaf Ebrahimi         }
603*22dc650dSSadaf Ebrahimi       if (i >= sizeof(type_names)/sizeof(char *))
604*22dc650dSSadaf Ebrahimi         {
605*22dc650dSSadaf Ebrahimi         printf("** Unrecognized type name \"%s\"\n", value);
606*22dc650dSSadaf Ebrahimi         return;
607*22dc650dSSadaf Ebrahimi         }
608*22dc650dSSadaf Ebrahimi       }
609*22dc650dSSadaf Ebrahimi     }
610*22dc650dSSadaf Ebrahimi 
611*22dc650dSSadaf Ebrahimi   else if (strcmp(CS name, "gbreak") == 0)
612*22dc650dSSadaf Ebrahimi     {
613*22dc650dSSadaf Ebrahimi     if (gbreak >= 0)
614*22dc650dSSadaf Ebrahimi       {
615*22dc650dSSadaf Ebrahimi       printf("** Only 1 grapheme break value allowed\n");
616*22dc650dSSadaf Ebrahimi       return;
617*22dc650dSSadaf Ebrahimi       }
618*22dc650dSSadaf Ebrahimi     else
619*22dc650dSSadaf Ebrahimi       {
620*22dc650dSSadaf Ebrahimi       if (value[0] == '!')
621*22dc650dSSadaf Ebrahimi         {
622*22dc650dSSadaf Ebrahimi         gbreak_not = TRUE;
623*22dc650dSSadaf Ebrahimi         offset = 1;
624*22dc650dSSadaf Ebrahimi         }
625*22dc650dSSadaf Ebrahimi 
626*22dc650dSSadaf Ebrahimi       for (i = 0; i < sizeof(gb_names)/sizeof(char *); i += 2)
627*22dc650dSSadaf Ebrahimi         {
628*22dc650dSSadaf Ebrahimi         if (strcmp(CS (value + offset), CCS gb_names[i]) == 0)
629*22dc650dSSadaf Ebrahimi           {
630*22dc650dSSadaf Ebrahimi           gbreak = i/2;
631*22dc650dSSadaf Ebrahimi           break;
632*22dc650dSSadaf Ebrahimi           }
633*22dc650dSSadaf Ebrahimi         }
634*22dc650dSSadaf Ebrahimi       if (i >= sizeof(gb_names)/sizeof(char *))
635*22dc650dSSadaf Ebrahimi         {
636*22dc650dSSadaf Ebrahimi         printf("** Unrecognized gbreak name \"%s\"\n", value);
637*22dc650dSSadaf Ebrahimi         return;
638*22dc650dSSadaf Ebrahimi         }
639*22dc650dSSadaf Ebrahimi       }
640*22dc650dSSadaf Ebrahimi     }
641*22dc650dSSadaf Ebrahimi 
642*22dc650dSSadaf Ebrahimi   else if (strcmp(CS name, "bidi") == 0 ||
643*22dc650dSSadaf Ebrahimi            strcmp(CS name, "bidiclass") == 0 ||
644*22dc650dSSadaf Ebrahimi            strcmp(CS name, "bidi_class") == 0 )
645*22dc650dSSadaf Ebrahimi     {
646*22dc650dSSadaf Ebrahimi     if (bidiclass >= 0)
647*22dc650dSSadaf Ebrahimi       {
648*22dc650dSSadaf Ebrahimi       printf("** Only 1 bidi class value allowed\n");
649*22dc650dSSadaf Ebrahimi       return;
650*22dc650dSSadaf Ebrahimi       }
651*22dc650dSSadaf Ebrahimi     else
652*22dc650dSSadaf Ebrahimi       {
653*22dc650dSSadaf Ebrahimi       if (value[0] == '!')
654*22dc650dSSadaf Ebrahimi         {
655*22dc650dSSadaf Ebrahimi         bidiclass_not = TRUE;
656*22dc650dSSadaf Ebrahimi         offset = 1;
657*22dc650dSSadaf Ebrahimi         }
658*22dc650dSSadaf Ebrahimi       for (i = 0; i < sizeof(bd_names)/sizeof(char *); i++)
659*22dc650dSSadaf Ebrahimi         {
660*22dc650dSSadaf Ebrahimi         if (strcasecmp(CS (value + offset), CCS bd_names[i]) == 0)
661*22dc650dSSadaf Ebrahimi           {
662*22dc650dSSadaf Ebrahimi           bidiclass = i/2;
663*22dc650dSSadaf Ebrahimi           break;
664*22dc650dSSadaf Ebrahimi           }
665*22dc650dSSadaf Ebrahimi         }
666*22dc650dSSadaf Ebrahimi       if (i >= sizeof(bd_names)/sizeof(char *))
667*22dc650dSSadaf Ebrahimi         {
668*22dc650dSSadaf Ebrahimi         printf("** Unrecognized bidi class name \"%s\"\n", value);
669*22dc650dSSadaf Ebrahimi         return;
670*22dc650dSSadaf Ebrahimi         }
671*22dc650dSSadaf Ebrahimi       }
672*22dc650dSSadaf Ebrahimi     }
673*22dc650dSSadaf Ebrahimi 
674*22dc650dSSadaf Ebrahimi   else
675*22dc650dSSadaf Ebrahimi     {
676*22dc650dSSadaf Ebrahimi     printf("** Unrecognized property name \"%s\"\n", name);
677*22dc650dSSadaf Ebrahimi     return;
678*22dc650dSSadaf Ebrahimi     }
679*22dc650dSSadaf Ebrahimi   }
680*22dc650dSSadaf Ebrahimi 
681*22dc650dSSadaf Ebrahimi if (script < 0 && scriptx_count == 0 && bprop_count == 0 && type < 0 &&
682*22dc650dSSadaf Ebrahimi     gbreak < 0 && bidiclass < 0)
683*22dc650dSSadaf Ebrahimi   {
684*22dc650dSSadaf Ebrahimi   printf("** No properties specified\n");
685*22dc650dSSadaf Ebrahimi   return;
686*22dc650dSSadaf Ebrahimi   }
687*22dc650dSSadaf Ebrahimi 
688*22dc650dSSadaf Ebrahimi for (c = 0; c <= 0x10ffff; c++)
689*22dc650dSSadaf Ebrahimi   {
690*22dc650dSSadaf Ebrahimi   if (script >= 0 && (script == UCD_SCRIPT(c)) == script_not) continue;
691*22dc650dSSadaf Ebrahimi 
692*22dc650dSSadaf Ebrahimi   if (scriptx_count > 0)
693*22dc650dSSadaf Ebrahimi     {
694*22dc650dSSadaf Ebrahimi     const uint32_t *bits_scriptx = PRIV(ucd_script_sets) + UCD_SCRIPTX(c);
695*22dc650dSSadaf Ebrahimi     unsigned int found = 0;
696*22dc650dSSadaf Ebrahimi 
697*22dc650dSSadaf Ebrahimi     for (i = 0; i < scriptx_count; i++)
698*22dc650dSSadaf Ebrahimi       {
699*22dc650dSSadaf Ebrahimi       int x = scriptx_list[i]/32;
700*22dc650dSSadaf Ebrahimi       int y = scriptx_list[i]%32;
701*22dc650dSSadaf Ebrahimi 
702*22dc650dSSadaf Ebrahimi       /* Positive requirment */
703*22dc650dSSadaf Ebrahimi       if (scriptx_list[i] >= 0)
704*22dc650dSSadaf Ebrahimi         {
705*22dc650dSSadaf Ebrahimi         if (scriptx_list[i] == UCD_SCRIPT(c) ||
706*22dc650dSSadaf Ebrahimi             ((scriptx_list[i] < ucp_Unknown) &&
707*22dc650dSSadaf Ebrahimi              (bits_scriptx[x] & (1u<<y)) != 0)) found++;
708*22dc650dSSadaf Ebrahimi         }
709*22dc650dSSadaf Ebrahimi       /* Negative requirement */
710*22dc650dSSadaf Ebrahimi       else
711*22dc650dSSadaf Ebrahimi         {
712*22dc650dSSadaf Ebrahimi         if ((-(scriptx_list[i]) < ucp_Unknown) &&
713*22dc650dSSadaf Ebrahimi             (bits_scriptx[x] & (1u<<y)) == 0) found++;
714*22dc650dSSadaf Ebrahimi         }
715*22dc650dSSadaf Ebrahimi       }
716*22dc650dSSadaf Ebrahimi 
717*22dc650dSSadaf Ebrahimi     if (found != scriptx_count) continue;
718*22dc650dSSadaf Ebrahimi     }
719*22dc650dSSadaf Ebrahimi 
720*22dc650dSSadaf Ebrahimi   if (bprop_count > 0)
721*22dc650dSSadaf Ebrahimi     {
722*22dc650dSSadaf Ebrahimi     const uint32_t *bits_bprop = PRIV(ucd_boolprop_sets) + UCD_BPROPS(c);
723*22dc650dSSadaf Ebrahimi     unsigned int found = 0;
724*22dc650dSSadaf Ebrahimi 
725*22dc650dSSadaf Ebrahimi     for (i = 0; i < bprop_count; i++)
726*22dc650dSSadaf Ebrahimi       {
727*22dc650dSSadaf Ebrahimi       int x = bprop_list[i]/32;
728*22dc650dSSadaf Ebrahimi       int y = bprop_list[i]%32;
729*22dc650dSSadaf Ebrahimi 
730*22dc650dSSadaf Ebrahimi       /* Positive requirement */
731*22dc650dSSadaf Ebrahimi       if (bprop_list[i] >= 0)
732*22dc650dSSadaf Ebrahimi         {
733*22dc650dSSadaf Ebrahimi         if ((bits_bprop[x] & (1u<<y)) != 0) found++;
734*22dc650dSSadaf Ebrahimi         }
735*22dc650dSSadaf Ebrahimi       /* Negative requirement */
736*22dc650dSSadaf Ebrahimi       else
737*22dc650dSSadaf Ebrahimi         {
738*22dc650dSSadaf Ebrahimi         if ((bits_bprop[-x] & (1u<<(-y))) == 0) found++;
739*22dc650dSSadaf Ebrahimi         }
740*22dc650dSSadaf Ebrahimi       }
741*22dc650dSSadaf Ebrahimi 
742*22dc650dSSadaf Ebrahimi     if (found != bprop_count) continue;
743*22dc650dSSadaf Ebrahimi     }
744*22dc650dSSadaf Ebrahimi 
745*22dc650dSSadaf Ebrahimi   if (type >= 0)
746*22dc650dSSadaf Ebrahimi     {
747*22dc650dSSadaf Ebrahimi     if (type_not)
748*22dc650dSSadaf Ebrahimi       {
749*22dc650dSSadaf Ebrahimi       if (type == UCD_CHARTYPE(c)) continue;
750*22dc650dSSadaf Ebrahimi       }
751*22dc650dSSadaf Ebrahimi     else
752*22dc650dSSadaf Ebrahimi       {
753*22dc650dSSadaf Ebrahimi       if (type != UCD_CHARTYPE(c)) continue;
754*22dc650dSSadaf Ebrahimi       }
755*22dc650dSSadaf Ebrahimi     }
756*22dc650dSSadaf Ebrahimi 
757*22dc650dSSadaf Ebrahimi   if (gbreak >= 0)
758*22dc650dSSadaf Ebrahimi     {
759*22dc650dSSadaf Ebrahimi     if (gbreak_not)
760*22dc650dSSadaf Ebrahimi       {
761*22dc650dSSadaf Ebrahimi       if (gbreak == UCD_GRAPHBREAK(c)) continue;
762*22dc650dSSadaf Ebrahimi       }
763*22dc650dSSadaf Ebrahimi     else
764*22dc650dSSadaf Ebrahimi       {
765*22dc650dSSadaf Ebrahimi       if (gbreak != UCD_GRAPHBREAK(c)) continue;
766*22dc650dSSadaf Ebrahimi       }
767*22dc650dSSadaf Ebrahimi     }
768*22dc650dSSadaf Ebrahimi 
769*22dc650dSSadaf Ebrahimi   if (bidiclass >= 0)
770*22dc650dSSadaf Ebrahimi     {
771*22dc650dSSadaf Ebrahimi     if (bidiclass_not)
772*22dc650dSSadaf Ebrahimi       {
773*22dc650dSSadaf Ebrahimi       if (bidiclass == UCD_BIDICLASS(c)) continue;
774*22dc650dSSadaf Ebrahimi       }
775*22dc650dSSadaf Ebrahimi     else
776*22dc650dSSadaf Ebrahimi       {
777*22dc650dSSadaf Ebrahimi       if (bidiclass != UCD_BIDICLASS(c)) continue;
778*22dc650dSSadaf Ebrahimi       }
779*22dc650dSSadaf Ebrahimi     }
780*22dc650dSSadaf Ebrahimi 
781*22dc650dSSadaf Ebrahimi   /* All conditions are met. Look for runs. */
782*22dc650dSSadaf Ebrahimi 
783*22dc650dSSadaf Ebrahimi   ucd = GET_UCD(c);
784*22dc650dSSadaf Ebrahimi 
785*22dc650dSSadaf Ebrahimi   for (i = c + 1; i < 0x10ffff; i++)
786*22dc650dSSadaf Ebrahimi     {
787*22dc650dSSadaf Ebrahimi     next_ucd = GET_UCD(i);
788*22dc650dSSadaf Ebrahimi     if (memcmp(ucd, next_ucd, sizeof(ucd_record)) != 0) break;
789*22dc650dSSadaf Ebrahimi     }
790*22dc650dSSadaf Ebrahimi 
791*22dc650dSSadaf Ebrahimi   if (--i > c)
792*22dc650dSSadaf Ebrahimi     {
793*22dc650dSSadaf Ebrahimi     printf("U+%04X..", c);
794*22dc650dSSadaf Ebrahimi     c = i;
795*22dc650dSSadaf Ebrahimi     hadrange = TRUE;
796*22dc650dSSadaf Ebrahimi     }
797*22dc650dSSadaf Ebrahimi   else if (hadrange) printf("%s", pad);
798*22dc650dSSadaf Ebrahimi 
799*22dc650dSSadaf Ebrahimi   print_prop(c, FALSE);
800*22dc650dSSadaf Ebrahimi   if (c >= 0x100000) pad = "        ";
801*22dc650dSSadaf Ebrahimi     else if (c >= 0x10000) pad = "       ";
802*22dc650dSSadaf Ebrahimi   count++;
803*22dc650dSSadaf Ebrahimi   if (count >= 100)
804*22dc650dSSadaf Ebrahimi     {
805*22dc650dSSadaf Ebrahimi     printf("...\n");
806*22dc650dSSadaf Ebrahimi     break;
807*22dc650dSSadaf Ebrahimi     }
808*22dc650dSSadaf Ebrahimi   }
809*22dc650dSSadaf Ebrahimi 
810*22dc650dSSadaf Ebrahimi if (count == 0) printf("No characters found\n");
811*22dc650dSSadaf Ebrahimi }
812*22dc650dSSadaf Ebrahimi 
813*22dc650dSSadaf Ebrahimi 
814*22dc650dSSadaf Ebrahimi /*************************************************
815*22dc650dSSadaf Ebrahimi *        Process command line                    *
816*22dc650dSSadaf Ebrahimi *************************************************/
817*22dc650dSSadaf Ebrahimi 
818*22dc650dSSadaf Ebrahimi static void
process_command_line(unsigned char * buffer)819*22dc650dSSadaf Ebrahimi process_command_line(unsigned char *buffer)
820*22dc650dSSadaf Ebrahimi {
821*22dc650dSSadaf Ebrahimi unsigned char *s, *t;
822*22dc650dSSadaf Ebrahimi unsigned char name[24];
823*22dc650dSSadaf Ebrahimi 
824*22dc650dSSadaf Ebrahimi s = buffer;
825*22dc650dSSadaf Ebrahimi while (isspace(*s)) s++;
826*22dc650dSSadaf Ebrahimi if (*s == 0) return;
827*22dc650dSSadaf Ebrahimi 
828*22dc650dSSadaf Ebrahimi for (t = name; *s != 0 && !isspace(*s); s++) *t++ = *s;
829*22dc650dSSadaf Ebrahimi *t = 0;
830*22dc650dSSadaf Ebrahimi while (isspace(*s)) s++;
831*22dc650dSSadaf Ebrahimi 
832*22dc650dSSadaf Ebrahimi if (strcmp(CS name, "findprop") == 0)
833*22dc650dSSadaf Ebrahimi   {
834*22dc650dSSadaf Ebrahimi   while (*s != 0)
835*22dc650dSSadaf Ebrahimi     {
836*22dc650dSSadaf Ebrahimi     unsigned int c;
837*22dc650dSSadaf Ebrahimi     unsigned char *endptr;
838*22dc650dSSadaf Ebrahimi     t = s;
839*22dc650dSSadaf Ebrahimi 
840*22dc650dSSadaf Ebrahimi     if (*t == '+')
841*22dc650dSSadaf Ebrahimi       {
842*22dc650dSSadaf Ebrahimi       c = *(++t);
843*22dc650dSSadaf Ebrahimi       if (c > 0x7fu)
844*22dc650dSSadaf Ebrahimi         {
845*22dc650dSSadaf Ebrahimi         GETCHARINC(c, t);
846*22dc650dSSadaf Ebrahimi         endptr = t;
847*22dc650dSSadaf Ebrahimi         }
848*22dc650dSSadaf Ebrahimi       else endptr = t+1;
849*22dc650dSSadaf Ebrahimi       }
850*22dc650dSSadaf Ebrahimi     else
851*22dc650dSSadaf Ebrahimi       {
852*22dc650dSSadaf Ebrahimi       if (memcmp(t, "U+", 2) == 0) t += 2;
853*22dc650dSSadaf Ebrahimi       c = (uint32_t)strtoul(CS t, CSS(&endptr), 16);
854*22dc650dSSadaf Ebrahimi       }
855*22dc650dSSadaf Ebrahimi 
856*22dc650dSSadaf Ebrahimi     if (*endptr != 0 && !isspace(*endptr))
857*22dc650dSSadaf Ebrahimi       {
858*22dc650dSSadaf Ebrahimi       while (*endptr != 0 && !isspace(*endptr)) endptr++;
859*22dc650dSSadaf Ebrahimi       printf("** Invalid character specifier: ignored \"%.*s\"\n", (int)(endptr-s), s);
860*22dc650dSSadaf Ebrahimi       }
861*22dc650dSSadaf Ebrahimi     else
862*22dc650dSSadaf Ebrahimi       {
863*22dc650dSSadaf Ebrahimi       if (c > 0x10ffff)
864*22dc650dSSadaf Ebrahimi         printf("** U+%x is too big for a Unicode code point\n", c);
865*22dc650dSSadaf Ebrahimi       else
866*22dc650dSSadaf Ebrahimi         print_prop(c, TRUE);
867*22dc650dSSadaf Ebrahimi       }
868*22dc650dSSadaf Ebrahimi     s = endptr;
869*22dc650dSSadaf Ebrahimi     while (isspace(*s)) s++;
870*22dc650dSSadaf Ebrahimi     }
871*22dc650dSSadaf Ebrahimi   }
872*22dc650dSSadaf Ebrahimi 
873*22dc650dSSadaf Ebrahimi else if (strcmp(CS name, "find") == 0)
874*22dc650dSSadaf Ebrahimi   {
875*22dc650dSSadaf Ebrahimi   find_chars(s);
876*22dc650dSSadaf Ebrahimi   }
877*22dc650dSSadaf Ebrahimi 
878*22dc650dSSadaf Ebrahimi else if (strcmp(CS name, "list") == 0)
879*22dc650dSSadaf Ebrahimi   {
880*22dc650dSSadaf Ebrahimi   while (*s != 0)
881*22dc650dSSadaf Ebrahimi     {
882*22dc650dSSadaf Ebrahimi     size_t i;
883*22dc650dSSadaf Ebrahimi     for (t = name; *s != 0 && !isspace(*s); s++) *t++ = *s;
884*22dc650dSSadaf Ebrahimi     *t = 0;
885*22dc650dSSadaf Ebrahimi     while (isspace(*s)) s++;
886*22dc650dSSadaf Ebrahimi 
887*22dc650dSSadaf Ebrahimi     if (strcmp(CS name, "script") == 0 || strcmp(CS name, "scripts") == 0)
888*22dc650dSSadaf Ebrahimi       {
889*22dc650dSSadaf Ebrahimi       for (i = 0; i < PRIV(utt_size); i++)
890*22dc650dSSadaf Ebrahimi         if (PRIV(utt)[i].type == PT_SCX || PRIV(utt)[i].type == PT_SC)
891*22dc650dSSadaf Ebrahimi           printf("%s\n", PRIV(utt_names) + PRIV(utt)[i].name_offset);
892*22dc650dSSadaf Ebrahimi       }
893*22dc650dSSadaf Ebrahimi 
894*22dc650dSSadaf Ebrahimi     else if (strcmp(CS name, "bool") == 0)
895*22dc650dSSadaf Ebrahimi       {
896*22dc650dSSadaf Ebrahimi       for (i = 0; i < PRIV(utt_size); i++)
897*22dc650dSSadaf Ebrahimi         if (PRIV(utt)[i].type == PT_BOOL)
898*22dc650dSSadaf Ebrahimi           printf("%s\n", PRIV(utt_names) + PRIV(utt)[i].name_offset);
899*22dc650dSSadaf Ebrahimi       }
900*22dc650dSSadaf Ebrahimi 
901*22dc650dSSadaf Ebrahimi     else if (strcmp(CS name, "type") == 0 || strcmp(CS name, "types") == 0)
902*22dc650dSSadaf Ebrahimi       {
903*22dc650dSSadaf Ebrahimi       for (i = 0; i < sizeof(type_names)/sizeof(char *); i += 2)
904*22dc650dSSadaf Ebrahimi         printf("%s %s\n", type_names[i], type_names[i+1]);
905*22dc650dSSadaf Ebrahimi       }
906*22dc650dSSadaf Ebrahimi 
907*22dc650dSSadaf Ebrahimi     else if (strcmp(CS name, "gbreak") == 0 || strcmp(CS name, "gbreaks") == 0)
908*22dc650dSSadaf Ebrahimi       {
909*22dc650dSSadaf Ebrahimi       for (i = 0; i < sizeof(gb_names)/sizeof(char *); i += 2)
910*22dc650dSSadaf Ebrahimi         {
911*22dc650dSSadaf Ebrahimi         if (gb_names[i+1][0] != 0)
912*22dc650dSSadaf Ebrahimi           printf("%-3s (%s)\n", gb_names[i], gb_names[i+1]);
913*22dc650dSSadaf Ebrahimi         else
914*22dc650dSSadaf Ebrahimi           printf("%s\n", gb_names[i]);
915*22dc650dSSadaf Ebrahimi         }
916*22dc650dSSadaf Ebrahimi       }
917*22dc650dSSadaf Ebrahimi 
918*22dc650dSSadaf Ebrahimi     else if (strcmp(CS name, "bidi") == 0 ||
919*22dc650dSSadaf Ebrahimi              strcmp(CS name, "bidiclasses") == 0)
920*22dc650dSSadaf Ebrahimi       {
921*22dc650dSSadaf Ebrahimi       for (i = 0; i < sizeof(bd_names)/sizeof(char *); i += 2)
922*22dc650dSSadaf Ebrahimi         printf("%3s %s\n", bd_names[i], bd_names[i+1]);
923*22dc650dSSadaf Ebrahimi       }
924*22dc650dSSadaf Ebrahimi 
925*22dc650dSSadaf Ebrahimi     else
926*22dc650dSSadaf Ebrahimi       {
927*22dc650dSSadaf Ebrahimi       printf("** Unknown property \"%s\"\n", name);
928*22dc650dSSadaf Ebrahimi       break;
929*22dc650dSSadaf Ebrahimi       }
930*22dc650dSSadaf Ebrahimi     }
931*22dc650dSSadaf Ebrahimi   }
932*22dc650dSSadaf Ebrahimi 
933*22dc650dSSadaf Ebrahimi else printf("** Unknown test command \"%s\"\n", name);
934*22dc650dSSadaf Ebrahimi }
935*22dc650dSSadaf Ebrahimi 
936*22dc650dSSadaf Ebrahimi 
937*22dc650dSSadaf Ebrahimi 
938*22dc650dSSadaf Ebrahimi /*************************************************
939*22dc650dSSadaf Ebrahimi *               Main program                     *
940*22dc650dSSadaf Ebrahimi *************************************************/
941*22dc650dSSadaf Ebrahimi 
942*22dc650dSSadaf Ebrahimi int
main(int argc,char ** argv)943*22dc650dSSadaf Ebrahimi main(int argc, char **argv)
944*22dc650dSSadaf Ebrahimi {
945*22dc650dSSadaf Ebrahimi BOOL interactive;
946*22dc650dSSadaf Ebrahimi int first_arg = 1;
947*22dc650dSSadaf Ebrahimi unsigned char buffer[1024];
948*22dc650dSSadaf Ebrahimi 
949*22dc650dSSadaf Ebrahimi if (argc > 1 && strcmp(argv[1], "-s") == 0)
950*22dc650dSSadaf Ebrahimi   {
951*22dc650dSSadaf Ebrahimi   show_character = TRUE;
952*22dc650dSSadaf Ebrahimi   first_arg++;
953*22dc650dSSadaf Ebrahimi   }
954*22dc650dSSadaf Ebrahimi 
955*22dc650dSSadaf Ebrahimi if (argc > first_arg)
956*22dc650dSSadaf Ebrahimi   {
957*22dc650dSSadaf Ebrahimi   int i;
958*22dc650dSSadaf Ebrahimi   BOOL datafirst = TRUE;
959*22dc650dSSadaf Ebrahimi   char *arg = argv[first_arg];
960*22dc650dSSadaf Ebrahimi   unsigned char *s = buffer;
961*22dc650dSSadaf Ebrahimi 
962*22dc650dSSadaf Ebrahimi   if (*arg != '+' && memcmp(arg, "U+", 2) != 0 && !isdigit(*arg))
963*22dc650dSSadaf Ebrahimi     {
964*22dc650dSSadaf Ebrahimi     while (*arg != 0)
965*22dc650dSSadaf Ebrahimi       {
966*22dc650dSSadaf Ebrahimi       if (!isxdigit(*arg++)) { datafirst = FALSE; break; }
967*22dc650dSSadaf Ebrahimi       }
968*22dc650dSSadaf Ebrahimi     }
969*22dc650dSSadaf Ebrahimi 
970*22dc650dSSadaf Ebrahimi   if (datafirst)
971*22dc650dSSadaf Ebrahimi     {
972*22dc650dSSadaf Ebrahimi     strcpy(CS s, "findprop ");
973*22dc650dSSadaf Ebrahimi     s += 9;
974*22dc650dSSadaf Ebrahimi     }
975*22dc650dSSadaf Ebrahimi 
976*22dc650dSSadaf Ebrahimi   for (i = first_arg; i < argc; i++)
977*22dc650dSSadaf Ebrahimi     {
978*22dc650dSSadaf Ebrahimi     s += sprintf(CS s, "%s ", argv[i]);
979*22dc650dSSadaf Ebrahimi     }
980*22dc650dSSadaf Ebrahimi 
981*22dc650dSSadaf Ebrahimi   process_command_line(buffer);
982*22dc650dSSadaf Ebrahimi   return 0;
983*22dc650dSSadaf Ebrahimi   }
984*22dc650dSSadaf Ebrahimi 
985*22dc650dSSadaf Ebrahimi interactive = is_stdin_tty();
986*22dc650dSSadaf Ebrahimi 
987*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
988*22dc650dSSadaf Ebrahimi if (interactive) using_history();
989*22dc650dSSadaf Ebrahimi #endif
990*22dc650dSSadaf Ebrahimi 
991*22dc650dSSadaf Ebrahimi for(;;)
992*22dc650dSSadaf Ebrahimi   {
993*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
994*22dc650dSSadaf Ebrahimi   if (interactive)
995*22dc650dSSadaf Ebrahimi     {
996*22dc650dSSadaf Ebrahimi     size_t len;
997*22dc650dSSadaf Ebrahimi     unsigned char *s = US readline("> ");
998*22dc650dSSadaf Ebrahimi     if (s == NULL) break;
999*22dc650dSSadaf Ebrahimi     len = strlen(CS s);
1000*22dc650dSSadaf Ebrahimi     if (len > 0) add_history(CS s);
1001*22dc650dSSadaf Ebrahimi     memcpy(buffer, s, len);
1002*22dc650dSSadaf Ebrahimi     buffer[len] = '\n';
1003*22dc650dSSadaf Ebrahimi     buffer[len+1] = 0;
1004*22dc650dSSadaf Ebrahimi     free(s);
1005*22dc650dSSadaf Ebrahimi     }
1006*22dc650dSSadaf Ebrahimi   else
1007*22dc650dSSadaf Ebrahimi #endif
1008*22dc650dSSadaf Ebrahimi 
1009*22dc650dSSadaf Ebrahimi     {
1010*22dc650dSSadaf Ebrahimi     if (interactive) printf("> ");
1011*22dc650dSSadaf Ebrahimi     if (fgets(CS buffer, sizeof(buffer), stdin) == NULL) break;
1012*22dc650dSSadaf Ebrahimi     if (!interactive) printf("%s", buffer);
1013*22dc650dSSadaf Ebrahimi     }
1014*22dc650dSSadaf Ebrahimi 
1015*22dc650dSSadaf Ebrahimi   process_command_line(buffer);
1016*22dc650dSSadaf Ebrahimi   }
1017*22dc650dSSadaf Ebrahimi 
1018*22dc650dSSadaf Ebrahimi if (interactive) printf("\n");
1019*22dc650dSSadaf Ebrahimi 
1020*22dc650dSSadaf Ebrahimi #if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
1021*22dc650dSSadaf Ebrahimi if (interactive) clear_history();
1022*22dc650dSSadaf Ebrahimi #endif
1023*22dc650dSSadaf Ebrahimi 
1024*22dc650dSSadaf Ebrahimi return 0;
1025*22dc650dSSadaf Ebrahimi }
1026*22dc650dSSadaf Ebrahimi 
1027*22dc650dSSadaf Ebrahimi /* End */
1028