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