2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 #ifdef VERBOSE_REV_INFO
25 static char rcs_id[] = "$TOG: TermPrimParser.c /main/2 1999/10/15 12:23:41 mgreess $";
26 #endif /* VERBOSE_REV_INFO */
30 * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
31 * (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
32 * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
33 * (c) Copyright 1993, 1994, 1996 Novell, Inc. *
34 * (c) Copyright 1996 Digital Equipment Corporation. *
35 * (c) Copyright 1996 FUJITSU LIMITED. *
36 * (c) Copyright 1996 Hitachi. *
40 #include "TermHeader.h"
41 #include "TermPrimDebug.h"
42 #include "TermPrimP.h"
43 #include "TermPrimParserP.h"
44 #include "TermPrimBuffer.h"
48 * On HP MAXINT is defined in both <values.h> and <sys/param.h>
52 #if defined(CSRG_BASED)
53 #define MAXINT INT_MAX
70 ** Parse the character, tell the calling routine if we are not
71 ** in the start state.
77 unsigned char *parseChar,
81 ParserContext context = GetParserContext(w);
83 StateEntry thisPreParseEntry;
87 ** This decision should be made somewhere else.
89 if (tp->t_modes.disp_func == 1)
96 if (parseCharLen == 1) {
97 *context->inputChar = *parseChar;
99 (void) memmove(context->inputChar, parseChar, parseCharLen);
101 context->inputCharLen = parseCharLen;
103 if (isDebugFSet('p', 1)) {
107 static unsigned char debugChar;
108 static Boolean first = True;
111 if (parseCharLen == 1) {
112 _DtTermProcessLock();
114 if (!(c = getenv("dttermDebugParseChar"))) {
117 debugChar = strtol(c, (char **) 0, 0);
120 _DtTermProcessUnlock();
122 if (*parseChar == debugChar) {
130 ** Determine which state entry to use.
132 thisPreParseEntry = context->stateTable->statePreParseEntry;
133 thisEntry = context->stateTable->stateEntry;
135 /* first run through the preParse entry... */
136 if (thisPreParseEntry && (parseCharLen == 1)) {
137 while ((*parseChar < thisPreParseEntry->lower) ||
138 (*parseChar > thisPreParseEntry->upper)) {
141 /* if we hit the end, ignore it... */
142 if ((0x00 == thisPreParseEntry->lower) &&
143 (0xff == thisPreParseEntry->upper)) {
144 thisPreParseEntry = (StateEntry) 0;
148 /* if we hit a valid preParseEntry, then let's execute it and
151 if (thisPreParseEntry) {
153 ** Now change states. If the next state is NULL, stay in the
154 ** current state. This is for parse entries that do not break us
155 ** out of the current parse thread. If we need to bail out of the
156 ** current parse thread, then we have a new state specified and
157 ** will switch to it. We do this before we execute the function
158 ** incase the function needs to change the state as well...
160 if (thisPreParseEntry->nextState) {
161 context->stateTable = thisPreParseEntry->nextState;
165 ** Execute the action associated with the entry.
167 if (thisPreParseEntry->action) {
168 (*thisPreParseEntry->action)(w);
171 return(!context->stateTable->startState);
176 * We need two different search algorithms - the first to deal
177 * with single byte characters, the second to deal with multi-byte
178 * characters. For now, we will match multi-byte character with
179 * the parse entry that covers 0..255. If we find that this will
180 * not work for everything, we may need to rethink this.
182 if (parseCharLen == 1) {
183 while ((*parseChar < thisEntry->lower) ||
184 (*parseChar > thisEntry->upper))
189 while ((0x00 != thisEntry->lower) ||
190 (0xff != thisEntry->upper))
197 ** Now change states. We do this before we execute the function incase
198 ** the function needs to change the state as well...
200 context->stateTable = thisEntry->nextState;
203 ** Execute the action associated with the entry.
205 if (thisEntry->action) {
206 (*thisEntry->action)(w);
209 return(!context->stateTable->startState);
214 ** _DtTermPrimParserClrStrParm()
216 ** clrStrParm clears the string parameters.
220 _DtTermPrimParserClrStrParm
225 ParserContext context = GetParserContext(w);
227 context->stringParms[0].length = 0;
228 (void) memset(context->stringParms[0].str, 0x00, STR_SIZE + 1);
230 context->stringParms[1].length = 0;
231 (void) memset(context->stringParms[1].str, 0x00, STR_SIZE + 1);
236 ** _DtTermPrimParserNextState()
238 ** nextState is a do nothing routine. It is called when the only
239 ** action that needs to be preformed is changing states in the
244 _DtTermPrimParserNextState
253 ** _DtTermPrimParserClearParm()
255 ** _DtTermPrimParserClearParm clears all common parameters.
259 _DtTermPrimParserClearParm
264 ParserContext context = GetParserContext(w);
267 for (i = 0; i < NUM_PARMS; i++) {
268 context->parms[i] = 0;
270 context->workingNum = 0;
271 context->workingNumIsDefault = True;
272 context->sign = TermPARSER_SIGNnone;
279 ** enterNum enters a numerical parameter.
283 _DtTermPrimParserEnterNum
288 ParserContext context = GetParserContext(w);
290 if ( context->workingNum < MAXINT>>4 )
291 context->workingNum = context->workingNum * 10 +
292 (*context->inputChar - '0');
293 context->workingNumIsDefault = False;
297 _DtTermPrimParserSaveSign
302 ParserContext context = GetParserContext(w);
304 SetSign(context, (*GetInputChar(context) == '-') ? TermPARSER_SIGNnegative :
305 TermPARSER_SIGNpositive);
310 ** _DtTermPrimParserNumParmPush()
312 ** _DtTermPrimParserNumParmPush() takes the number in workingNum and
313 ** stores it in parm[parmNum].
317 _DtTermPrimParserNumParmPush
323 ParserContext context = GetParserContext(w);
325 if ( parmNum < NUM_PARMS ) {
326 context->parms[parmNum] = context->workingNum;
327 context->workingNum = 0;
328 context->workingNumIsDefault = False;
333 ** Initialize the context of the parser.
336 _DtTermPrimParserInitContext
341 DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
342 DtTermPrimData tpd = tw->term.tpd;
344 tpd->context = (ParserContext) XtMalloc(sizeof(ParserContextRec));
345 (void) memset(tpd->context, '\0', sizeof(ParserContextRec));
347 tpd->context->stateTable =
348 *(((DtTermPrimitiveClassRec *) (tw->core.widget_class))->
349 term_primitive_class.parser_start_state);
350 tpd->context->stateName = START;
357 #define testFunction(f) \
358 void f ( Widget w ) {printf(#f " called.\n");}
360 int cursor_col, cursor_row;
361 int logical_col, logical_row;
363 testFunction(_termCR)
364 testFunction(_termLF)
365 testFunction(_termTab)
366 testFunction(_termBackspace)
367 testFunction(RecordDC1Rcvd)
368 testFunction(_termWriteChar)
369 testFunction(_DtTermPrimBell)
370 testFunction(_termShiftOut)
371 testFunction(_termShiftIn)
372 testFunction(set_tab)
373 testFunction(clear_tab)
374 testFunction(clr_all_tab)
375 testFunction(set_left_marg)
376 testFunction(set_right_marg)
377 testFunction(clear_marg)
378 testFunction(curs_up)
379 testFunction(curs_down)
380 testFunction(curs_right)
381 testFunction(curs_left)
382 testFunction(home_down)
383 testFunction(home_up)
384 testFunction(clr_display)
385 testFunction(clear_line)
386 testFunction(insert_line)
387 testFunction(delete_line)
388 testFunction(delete_char)
389 testFunction(insert_char)
390 testFunction(off_insert_char)
391 testFunction(roll_up)
392 testFunction(roll_down)
393 testFunction(next_page)
394 testFunction(prev_page)
395 testFunction(format_mode_on)
396 testFunction(format_mode_off)
397 testFunction(display_func)
398 testFunction(term_status)
399 testFunction(rel_curs_pos)
400 testFunction(abs_curs_pos)
401 testFunction(enable_key)
402 testFunction(disable_key)
403 testFunction(enter_line)
404 testFunction(back_tab)
405 testFunction(user_key_menu_on)
406 testFunction(user_key_menu_off)
407 testFunction(second_status)
408 testFunction(mlock_on)
409 testFunction(mlock_off)
410 testFunction(start_unprotect)
411 testFunction(stop_field)
416 ParserContext context
419 printf(" inputChar : ");
420 if (isprint(*context->inputChar))
422 printf("'%c'\n", *context->inputChar);
426 printf("\x2X\n", *context->inputChar);
428 for (i = 0; i < 9; i++)
430 printf(" parm[%d] : %d\n", i, context->parm[i]);
432 printf(" workingNum : %d\n", context->workingNum);
439 unsigned char *string
442 ParserContext context = GetParserContext(w);
445 _parserPrintContext(context);
446 for (i = 0; i < strlen((char *)string); i++)
448 _DtTermPrimParse(context, string[i]);
449 _parserPrintContext(context);
453 /* the following is to allow for a single main function in the code... */
454 #define parserMain main
457 parserContext context;
459 _parserInitContext(&context);
467 printf("\nparsing <esc>&a5r5C\n");
468 parseString(&context, (unsigned char *)"\033&a5r5C");
470 printf("\nparsing <esc>a5r35C\n");
471 parseString(&context, (unsigned char *)"\033&a5r35C");
473 printf("\nparsing <esc>&a5r3r4c5C\n");
474 parseString(&context, (unsigned char *)"\033&a5r3r4c5C");
476 printf("\nparsing <esc>&arC\n");
477 parseString(&context, (unsigned char *)"\033&arC");
479 printf("\nparsing <esc>&a5C\n");
480 parseString(&context, (unsigned char *)"\033&a5C");
482 printf("\nparsing <esc>&a+5C\n");
483 parseString(&context, (unsigned char *)"\033&a+5C");