Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

185 lines
4.5 KiB
C

static char sccsid[] = "@(#)73 1.4 src/bos/usr/bin/capture/vtparse.c, cmdsh, bos411, 9428A410j 3/24/94 18:34:34";
/*
* COMPONENT_NAME: (CMDSH) Bourne shell and related commands
*
* FUNCTIONS: ERR_RET, vtparse
*
* ORIGINS: 10, 26, 27
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1989, 1994
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
/* define to use faster MACROS instead of functions for performance */
#define _ILS_MACROS
#include <sys/types.h>
#include <ctype.h>
#include "vtparse.h"
#define ERR_RET() rv.v_type = V_STRING;\
rv.v_data.string = S_string;\
rv.v_len = cp - S_string;\
*rrv = rv;\
state = s_start;\
return -1;
/*
* vtparse.c
*
* Routine called after an escape character is read. This routine
* parses VT-100 sequences. This routine returns a structure of
* type "vcmd_t" which is described above. The element of the union
* "v_data" is a pointer (either int or char) to a *static* area of
* memory within this function, so if you want to save a value in the union,
* you must copy that value to another safe place.
*/
int vtparse(ch, rrv)
int ch; /* char input */
vcmd_t *rrv; /* return structure */
{
static short semicolon_seen,
close_paren, /* just too keep track */
cmdx_p; /* whether we got a ? or not */
static char S_string[64]; /* holds rejected characters */
static int S_args[16]; /* holds arguments to cmds */
static vcmd_t rv; /* return value */
static char *cp; /* tmp char star */
static int acc; /* number accumulator */
static enum {
s_start, /* 0 */
s_after_bracket, /* 1 */
s_after_pigpen, /* 2 */
s_indigit, /* 3 */
s_after_paren /* 4 */
} state = s_start; /* state variable */
cp = S_string;
/*
* Use a for loop to allow one case to throw out to another
* case with a continue statement.
*/
for(;;)
{ if(state != s_start) *cp++ = ch;
switch(state)
{ case s_start:
semicolon_seen = FALSE;
close_paren = FALSE;
cmdx_p = FALSE;
rv.v_data.args = S_args;
rv.v_data.args[0] = 0;
rv.v_data.args[1] = 0;
rv.v_data.args[2] = 0;
rv.v_data.args[3] = 0;
rv.v_len = 0;
acc = 0;
cp = S_string;
*cp++ = ch;
switch (ch)
{ case '[':
state = s_after_bracket;
break;
case '#':
state = s_after_pigpen;
break;
case '(':
state = s_after_paren;
break;
case ')':
state = s_after_paren;
close_paren = TRUE;
break;
default: /* check for SCMD1 */
if(strchr(SCMD1STR, ch)) {
rv.v_type = V_SCMD1;
rv.v_len = 1;
rv.v_data.args[0] = ch;
*rrv = rv;
state = s_start;
return(0); /* done processing */
}
ERR_RET(); /* else, reject the string */
}
return(1); /* continue processing */
case s_after_bracket:
if(ch == '?') { /* Possibly CMDX */
cmdx_p = TRUE; /* keep same state */
return 1;
}
if(ch == ';') { /* keep the same state */
semicolon_seen = TRUE;
return 1;
}
if(isdigit(ch)) {
acc = ch - '0'; /* account 1st digit */
state = s_indigit;
return 1;
}
if(ch >= 0x40) { /* good cmd character */
/* GOOD, we got a CMD */
rv.v_data.args[rv.v_len] = (int) ch;
rv.v_type = cmdx_p ? V_CMDX : V_CMD;
*rrv = rv;
state = s_start;
return 0; /* done processing */
}
ERR_RET();
case s_after_paren:
if(isalnum(ch)) {
rv.v_data.args[0] = ch;
rv.v_type = close_paren ? V_SCMD4 :V_SCMD3;
rv.v_len = 1;
*rrv = rv;
state = s_start;
return 0; /* done processing */
}
case s_after_pigpen:
if(isdigit(ch)) {
rv.v_data.args[0] = ch;
rv.v_type = V_SCMD2;
rv.v_len = 1;
*rrv = rv;
state = s_start;
return 0; /* done processing */
}
ERR_RET();
case s_indigit:
if(!isdigit(ch)) {
if (semicolon_seen && rv.v_len == 0)
rv.v_len++;
rv.v_data.args[rv.v_len++] = acc;
acc = 0;
state = s_after_bracket;
/* *throw* */ continue;
}
acc *= 10; /* keep the same state */
acc += ch - '0';
return 1; /* still processing */
}
}
}