Beispiel #1
0
Text* Parser::parse_text(){
	if(it==end){
		return NULL;
	}

	SaneString::iterator start=it;
	char c,q;

	if(maybe_char(QUOTE1)){
		q=QUOTE1;
	}
	else if(maybe_char(QUOTE2)){
		q=QUOTE2;
	}
	else if(maybe_char(QUOTE3)){
		q=QUOTE3;
	}
	//Try unquoted
	else{
		do{
			c=parse_escape(*it,UNQUOTED_EOF);
		}while(!(
			//Ordered by expected frequency
			isspace(c) or c==OPEN_TAG or c==CLOSE_TAG or c==NAMED_ATTR or
			c==QUOTE1 or c==QUOTE2 or c==OPEN_SECTION or c==CLOSE_SECTION or
			c==QUOTE3
		) and ++it!=end);

		if(it==start){
			return NULL;
		}

		return new Text(text.substr(start-text.begin(),it-start));
	}

	//Must be quoted
	do{
		c=parse_escape(*it,QUOTED_EOF);
	}while(c!=q and ++it!=end);

	if(!maybe_char(q)){
		throw ParseError(QUOTED_EOF,line,col);
	}

	return new Text(
		((SaneString)text.substr(start-text.begin(),it-start)).escape(q)
	);
}
Beispiel #2
0
/** текст выводимый на консоль
**/
int
parse_print(char *text,char **endptr,Tag *toptag) {
	char *s,*p;
	Tag *tag;
	TRACE("");
	tag=NULL;
	if (text[0]!='#'||text[1]!='?'||text[2]!='>') return 1;
	s=text;
	if (toptag) tag=mark(PRINT,text,text,toptag);
	mark_len(NULL,3,s,&s,tag);	// открывающая группа #?>
	while(*s) {
		p=s;
		mark_cspn(CHARS,"<$[\\",s,&s,tag);		// фрагмент до кавычки ' или esc
		if (s[0]=='\\') parse_escape(s,&s,tag);	// esc
		if (s[0]=='$') parse_variable(s,&s,tag);// подстановка переменных
		if (s[0]=='[') parse_command(s,&s,tag); // полстановка команд
		if (s[0]=='<') {
			if (s[1]=='?' && s[2]=='#') {
				mark_len(NULL,3,s,&s,tag);	// закрывающая группа <?#
				break;
			} else {
				mark_len(NULL,1,s,&s,tag);
			}
		}
		if (p==s) break;
	}
	if (endptr) (*endptr)=s;
	return 0;
}
Beispiel #3
0
/** строка с подстановками
*/
int
parse_subst(char *text,char **endptr,Tag *toptag) {
	char *p;
	char *s;
	Tag *tag;
	tag=NULL;
	if (text[0]!='\"') return 1;
	s=text;
	if (toptag) tag=mark(STRING,text,s,toptag);
	mark_len(NULL,1,s,&s,tag);	// открывающая кавычка
	while(*s) {
		p=s;
		s+=strcspn(s,"\\$[{\"");
		if (p!=s) mark(CHARS,p,s,tag);
		switch (*s) {
			case '\\' : parse_escape(s,&s,tag);break;
			case '$'  : parse_variable(s,&s,tag);break;
			case '['  : parse_command(s,&s,tag);break;
		}
		if (s[0]=='\"') {
			mark_len(NULL,1,s,&s,tag);	// закрывающая кавычка
			break;
		}
		if (p==s) break;
	}
	if (endptr) (*endptr)=s;
	return 0;
}
Beispiel #4
0
struct token *get_string_constant(SCTX_ struct token *token, struct expression *expr)
{
	struct string *string = token->string;
	struct token *next = token->next, *done = NULL;
	int stringtype = token_type(token);
	int is_wide = stringtype == TOKEN_WIDE_STRING;
	static char buffer[MAX_STRING];
	int len = 0;
	int bits;

	while (!done) {
		switch (token_type(next)) {
		case TOKEN_WIDE_STRING:
			is_wide = 1;
		case TOKEN_STRING:
			next = next->next;
			break;
		default:
			done = next;
		}
	}
	bits = is_wide ? 32 : sctxp bits_in_char;
	while (token != done) {
		unsigned v;
		const char *p = token->string->data;
		const char *end = p + token->string->length - 1;
		while (p < end) {
			p = parse_escape(sctx_ p, &v, end, bits, token->pos);
			if (len < MAX_STRING)
				buffer[len] = v;
			len++;
		}
		token = token->next;
	}
	if (len > MAX_STRING) {
		warning(sctx_ token->pos, "trying to concatenate %d-character string (%d bytes max)", len, MAX_STRING);
		len = MAX_STRING;
	}

	if (len >= string->length)	/* can't cannibalize */
		string = __alloc_string(sctx_ len+1);
	string->length = len+1;
	string->used = string->length;
	memcpy(string->data, buffer, len);
	string->data[len] = '\0';
	expr->string = string;
	expr->wide = is_wide;
	return token;
}
Beispiel #5
0
/* If the text starting at P going up to (but not including) END
   starts with a character constant, set *TOK to point to that
   character constant, and return 1.  Otherwise, return zero.
   Signal an error if it contains a malformed or incomplete character
   constant.  */
static int
get_character_constant (struct macro_buffer *tok, char *p, char *end)
{
  /* ISO/IEC 9899:1999 (E)  Section 6.4.4.4  paragraph 1 
     But of course, what really matters is that we handle it the same
     way GDB's C/C++ lexer does.  So we call parse_escape in utils.c
     to handle escape sequences.  */
  if ((p + 1 <= end && *p == '\'')
      || (p + 2 <= end && p[0] == 'L' && p[1] == '\''))
    {
      char *tok_start = p;
      char *body_start;

      if (*p == '\'')
        p++;
      else if (*p == 'L')
        p += 2;
      else
        gdb_assert (0);

      body_start = p;
      for (;;)
        {
          if (p >= end)
            error ("Unmatched single quote.");
          else if (*p == '\'')
            {
              if (p == body_start)
                error ("A character constant must contain at least one "
                       "character.");
              p++;
              break;
            }
          else if (*p == '\\')
            {
              p++;
              parse_escape (&p);
            }
          else
            p++;
        }

      set_token (tok, tok_start, p);
      return 1;
    }
  else
    return 0;
}
Beispiel #6
0
/* If the text starting at P going up to (but not including) END
   starts with a string literal, set *TOK to point to that string
   literal, and return 1.  Otherwise, return zero.  Signal an error if
   it contains a malformed or incomplete string literal.  */
static int
get_string_literal (struct macro_buffer *tok, char *p, char *end)
{
  if ((p + 1 <= end
       && *p == '\"')
      || (p + 2 <= end
          && p[0] == 'L'
          && p[1] == '\"'))
    {
      char *tok_start = p;

      if (*p == '\"')
        p++;
      else if (*p == 'L')
        p += 2;
      else
        gdb_assert (0);

      for (;;)
        {
          if (p >= end)
            error ("Unterminated string in expression.");
          else if (*p == '\"')
            {
              p++;
              break;
            }
          else if (*p == '\n')
            error ("Newline characters may not appear in string "
                   "constants.");
          else if (*p == '\\')
            {
              p++;
              parse_escape (&p);
            }
          else
            p++;
        }

      set_token (tok, tok_start, p);
      return 1;
    }
  else
    return 0;
}
Beispiel #7
0
Text* Parser::parse_doc_text(){
	if(it==end){
		return NULL;
	}

	SaneString::iterator start=it;
	char c;

	do{
		c=parse_escape(*it,NULL);
	}while(c!=OPEN_TAG and ++it!=end);

	if(start==it){
		return NULL;
	}

	return new Text(text.substr(start-text.begin(),it-start));
}
Beispiel #8
0
void iterator::parse_string( void )
{
	if ( _c != '\"' )
		return;
	
	skip_utf();

	while( _c != '\"' )
	{
		if ( _c == '\\' )
			parse_escape();
		next_utf();
		if ( ! _utf )
			return;
	}
	skip_utf();
	_type = TOK_STRING;
}
Beispiel #9
0
void iterator::parse_char( void )
{
	if ( _c != '\'' )
		return;
	
	skip_utf();

	while( _c != '\'' )
	{
		if ( _c == '\\' )
			parse_escape();
		next_utf();
		if ( ! _utf )
			return;
	}
	skip_utf();
	_type = TOK_CHARACTER;
}
Beispiel #10
0
Text* Parser::parse_section_text(){
	if(it==end){
		return NULL;
	}

	SaneString::iterator start=it;
	char c;

	do{
		c=parse_escape(*it,SECTION_EOF);
	}while(!(c==OPEN_TAG or c==CLOSE_SECTION) and ++it!=end);

	if(start==it){
		return NULL;
	}

	return new Text(text.substr(start-text.begin(),it-start));
}
Beispiel #11
0
static int parse_fstab_line(char *line, struct fs_info **ret_fs)
{
	char    *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;
	struct fs_info *fs;

	*ret_fs = 0;
	strip_line(line);
	if ((cp = strchr(line, '#')))
		*cp = 0;        /* Ignore everything after the comment char */
	cp = line;

	device = parse_word(&cp);
	mntpnt = parse_word(&cp);
	type = parse_word(&cp);
	opts = parse_word(&cp);
	freq = parse_word(&cp);
	passno = parse_word(&cp);

	if (!device)
		return 0;       /* Allow blank lines */

	if (!mntpnt || !type)
		return -1;

	parse_escape(device);
	parse_escape(mntpnt);
	parse_escape(type);
	parse_escape(opts);
	parse_escape(freq);
	parse_escape(passno);

	dev = blkid_get_devname(cache, device, NULL);
	if (dev)
		device = dev;

	if (strchr(type, ','))
		type = 0;

	fs = create_fs_device(device, mntpnt, type ? type : "auto", opts,
			      freq ? atoi(freq) : -1,
			      passno ? atoi(passno) : -1);
	if (dev)
		free(dev);

	if (!fs)
		return -1;
	*ret_fs = fs;
	return 0;
}
static int parse_fstab_line(char *line, struct fs_info *fs)
{
    char	*dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;

    if ((cp = strchr(line, '#')))
        *cp = 0;	/* Ignore everything after the comment char */
    cp = line;

    device = parse_word(&cp);
    mntpnt = parse_word(&cp);
    type = parse_word(&cp);
    opts = parse_word(&cp);
    freq = parse_word(&cp);
    passno = parse_word(&cp);

    if (!device)
        return -1;	/* Allow blank lines */

    if (!mntpnt || !type)
        return -1;

    parse_escape(device);
    parse_escape(mntpnt);
    parse_escape(type);
    parse_escape(opts);
    parse_escape(freq);
    parse_escape(passno);

    dev = blkid_get_devname(cache, device, NULL);
    if (dev)
        device = dev;

    if (strchr(type, ','))
        type = 0;

    fs->device = string_copy(device);
    fs->mountpt = string_copy(mntpnt);
    fs->type = string_copy(type);
    fs->opts = string_copy(opts ? opts : "");
    fs->freq = freq ? atoi(freq) : -1;
    fs->passno = passno ? atoi(passno) : -1;
    fs->flags = 0;
    fs->next = NULL;

    if (dev)
        free(dev);

    return 0;
}
Beispiel #13
0
/** строка без подстановок
*/
int
parse_string(char *text,char **endptr,Tag *toptag) {
	char *s,*p;
	Tag *tag;
	TRACE("");
	tag=NULL;
	if (text[0]!='\'') return 1;
	s=text;
	if (toptag) tag=mark(STRING,text,text,toptag);
	mark_len(NULL,1,s,&s,tag);	// открывающая кавычка
	while(*s) {
		p=s;
		mark_cspn(CHARS,"\'\\",s,&s,tag);		// фрагмент до кавычки ' или esc
		if (s[0]=='\\') parse_escape(s,&s,tag);	// esc
		if (s[0]=='\'') {
			mark_len(NULL,1,s,&s,tag);	// закрывающая кавычка
			break;
		}
		if (p==s) break;
	}
	if (endptr) (*endptr)=s;
	return 0;
}
Beispiel #14
0
void get_char_constant(SCTX_ struct token *token, unsigned long long *val)
{
	const char *p = token->embedded, *end;
	unsigned v;
	int type = token_type(token);
	switch (type) {
	case TOKEN_CHAR:
	case TOKEN_WIDE_CHAR:
		p = token->string->data;
		end = p + token->string->length;
		break;
	case TOKEN_CHAR_EMBEDDED_0 ... TOKEN_CHAR_EMBEDDED_3:
		end = p + type - TOKEN_CHAR;
		break;
	default:
		end = p + type - TOKEN_WIDE_CHAR;
	}
	p = parse_escape(sctx_ p, &v, end,
			type < TOKEN_WIDE_CHAR ? sctxp bits_in_char : 32, token->pos);
	if (p != end)
		warning(sctx_ token->pos,
			"multi-character character constant");
	*val = v;
}
Beispiel #15
0
Regexp *
make_regexp(char *s, size_t len, int ignorecase, int dfa)
{
	Regexp *rp;
	const char *rerr;
	char *src = s;
	char *temp;
	char *end = s + len;
	register char *dest;
	register int c, c2;

	/* Handle escaped characters first. */

	/*
	 * Build a copy of the string (in dest) with the
	 * escaped characters translated, and generate the regex
	 * from that.  
	 */
	emalloc(dest, char *, len + 2, "make_regexp");
	temp = dest;

	while (src < end) {
		if (*src == '\\') {
			c = *++src;
			switch (c) {
			case 'a':
			case 'b':
			case 'f':
			case 'n':
			case 'r':
			case 't':
			case 'v':
			case 'x':
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
				c2 = parse_escape(&src);
				if (c2 < 0)
					cant_happen();
				/*
				 * Unix awk treats octal (and hex?) chars
				 * literally in re's, so escape regexp
				 * metacharacters.
				 */
				if (do_traditional && ! do_posix && (ISDIGIT(c) || c == 'x')
				    && strchr("()|*+?.^$\\[]", c2) != NULL)
					*dest++ = '\\';
				*dest++ = (char) c2;
				break;
			case '8':
			case '9':	/* a\9b not valid */
				*dest++ = c;
				src++;
				break;
			case 'y':	/* normally \b */
				/* gnu regex op */
				if (! do_traditional) {
					*dest++ = '\\';
					*dest++ = 'b';
					src++;
					break;
				}
				/* else, fall through */
			default:
				*dest++ = '\\';
				*dest++ = (char) c;
				src++;
				break;
			} /* switch */
		} else
			*dest++ = *src++;	/* not '\\' */
	} /* for */

	*dest = '\0' ;	/* Only necessary if we print dest ? */
	emalloc(rp, Regexp *, sizeof(*rp), "make_regexp");
	memset((char *) rp, 0, sizeof(*rp));
	rp->pat.allocated = 0;	/* regex will allocate the buffer */
	emalloc(rp->pat.fastmap, char *, 256, "make_regexp");

	if (ignorecase)
		rp->pat.translate = casetable;
	else
		rp->pat.translate = NULL;
	len = dest - temp;
	if ((rerr = re_compile_pattern(temp, len, &(rp->pat))) != NULL)
		fatal("%s: /%s/", gettext(rerr), temp);

	/* gack. this must be done *after* re_compile_pattern */
	rp->pat.newline_anchor = FALSE; /* don't get \n in middle of string */
	if (dfa && ! ignorecase) {
		dfacomp(temp, len, &(rp->dfareg), TRUE);
		rp->dfa = TRUE;
	} else
		rp->dfa = FALSE;

	free(temp);
	return rp;
}
Beispiel #16
0
/*		    rebuild it with those removed or expanded, respectively */
void
vms_arg_fixup( int *pargc, char ***pargv )
{
    char *f_in, *f_out, *f_err,
	*out_mode, *rms_opt1, *rms_opt2;
    char **argv = *pargv;
    int i, argc = *pargc;
    int err_to_out_redirect = 0, out_to_err_redirect = 0;

#ifndef NO_CHECK_SHELL
    if (shell$is_shell())
	return;		    /* don't do anything if we're running DECshell */
#endif
#ifndef NO_DCL_CMD
    for (i = 1; i < argc ; i++)     /* check for dash or other non-VMS args */
	if (strchr("->\\|", *argv[i]))	break;	    /* found => (i < argc) */
    if (i >= argc && (v_argc = vms_gawk()) > 0) {   /* vms_gawk => dcl_parse */
	/* if we successfully parsed the command, replace original argv[] */
	argc = v_argc,	argv = v_argv;
	v_argz = v_argc = 0,  v_argv = NULL;
    }
#endif
    v_add_arg(v_argc = 0, basename(argv[0]));	/* store arg #0 (image name) */

    f_in = f_out = f_err = NULL;	/* stdio setup (no filenames yet) */
    out_mode = "w";			/* default access for stdout */
    rms_opt1 = rms_opt2 = "ctx=stm";	/* ("context = stream") == no-opt */

    for (i = 1; i < argc; i++) {
	char *p, *fn;
	int  is_arg;

	is_arg = 0;		/* current arg does not begin with dash */
	p = argv[i];		/* current arg */
	switch (*p) {
	  case '<':		/* stdin */
	      /*[should try to determine whether this is really a directory
		 spec using <>; for now, force user to quote them with '\<']*/
		if ( f_in ) {
		    fatal("multiple specification of '<' for stdin");
		} else if (*++p == '<') {   /* '<<' is not supported */
		    fatal("'<<' not available for stdin");
		} else {
		    p = skipblanks(p);
		    fn = (*p ? p : argv[++i]);	/* use next arg if necessary */
		    if (i >= argc || *fn == '-')
			fatal("invalid i/o redirection, null filespec after '<'");
		    else
			f_in = fn;	    /* save filename for stdin */
		}
		break;
	  case '>':   {		/* stdout or stderr */
	      /*[vms-specific kludge '>$' added to force stdout to be created
		 as record-oriented text file instead of in stream-lf format]*/
		int is_out = 1;		    /* assume stdout */
		if (*++p == '>')	/* '>>' => append */
		    out_mode = "a",  p++;
		else if (*p == '&')	/* '>&' => stderr */
		    is_out = 0,  p++;
		else if (*p == '$')	/* '>$' => kludge for record format */
		    rms_opt1 = "rfm=var",  rms_opt2 = "rat=cr",  p++;
		else			/* '>'	=> create */
		    ;	    /* use default values initialized prior to loop */
		p = skipblanks(p);
		fn = (*p ? p : argv[++i]);	/* use next arg if necessary */
		if (i >= argc || *fn == '-') {
		    fatal("invalid i/o redirection, null filespec after '>'");
		} else if (is_out) {
		    if (out_to_err_redirect)
			fatal("conflicting specifications for stdout");
		    else if (f_out)
			fatal("multiple specification of '>' for stdout");
		    else
			f_out = fn;	    /* save filename for stdout */
		} else {
		    if (err_to_out_redirect)
			fatal("conflicting specifications for stderr");
		    else if (f_err)
			fatal("multiple specification of '>&' for stderr");
		    else
			f_err = fn;	    /* save filename for stderr */
		}
	    }	break;
	  case '2':		/* check for ``2>&1'' special case'' */
		if (strcmp(p, "2>&1") != 0)
		    goto ordinary_arg;
		else if (f_err || out_to_err_redirect)
		    fatal("conflicting specifications for stderr");
		else {
		    err_to_out_redirect = 1;
		    f_err = "SYS$OUTPUT:";
		}  break;
	  case '1':		/* check for ``1>&2'' special case'' */
		if (strcmp(p, "1>&2") != 0)
		    goto ordinary_arg;
		else if (f_out || err_to_out_redirect)
		    fatal("conflicting specifications for stdout");
		else {
		    out_to_err_redirect = 1;
		    f_out = "SYS$ERROR:";
		}  break;
	  case '|':		/* pipe */
	      /* command pipelines are not supported */
		fatal("command pipes not available ('|' encountered)");
		break;
	  case '&':		/* background */
	      /*[we could probably spawn or fork ourself--maybe someday]*/
		if (*(p+1) == '\0' && i == argc - 1) {
		    fatal("background tasks not available ('&' encountered)");
		    break;
		} else		/* fall through */
		    ;	/*NOBREAK*/
	  case '-':		/* argument */
		is_arg = 1;		/*(=> skip wildcard check)*/
	  default:		/* other (filespec assumed) */
ordinary_arg:
	      /* process escape sequences or expand wildcards */
		v_add_arg(++v_argc, p);		/* include this arg */
		p = strchr(p, '\\');		/* look for backslash */
		if (p != NULL) {    /* does it have escape sequence(s)? */
#if 0	/* disable escape parsing; it's now done elsewhere within gawk */
		    register int c;
		    char *q = v_argv[v_argc] + (p - argv[i]);
		    do {
			c = *p++;
			if (c == '\\')
			    c = parse_escape(&p);
			*q++ = (c >= 0 ? (char)c : '\\');
		    } while (*p != '\0');
		    *q = '\0';
#endif	/*0*/
		} else if (!is_arg && strchr(v_argv[v_argc], '=') == NULL) {
		    vms_expand_wildcards(v_argv[v_argc]);
		}
		break;
	} /* end switch */
    } /* loop */

    /*
     * Now process any/all I/O options encountered above.
     */

    /* must do stderr first, or vaxcrtl init might not see it */
    /*[ catch 22:  we'll also redirect errors encountered doing <in or >out ]*/
    if (f_err) {	/* define logical name but don't open file */
	int len = strlen(f_err);
	if (strncasecmp(f_err, "SYS$OUTPUT", len) == 0
	 && (f_err[len] == ':' || f_err[len] == '\0'))
	    err_to_out_redirect = 1;
	else
	    (void) vms_define("SYS$ERROR", f_err);
    }
    /* do stdin before stdout, so we bomb we won't create empty output file */
    if (f_in) {		/* [re]open file and define logical name */
	stdin = freopen(f_in, "r", stdin, "mbf=2");
	if (stdin != NULL)
	    (void) vms_define("SYS$INPUT", f_in);
	else
	    fatal("<%s (%s)", f_in, strerror(errno));
    }
    if (f_out) {	/* disallow file sharing to reduce overhead */
	stdout = freopen(f_out, out_mode, stdout,
			 rms_opt1, rms_opt2, "shr=nil", "mbf=2");   /*VAXCRTL*/
	if (stdout != NULL) {
#ifdef crtl_bug  /* eof sometimes doesn't get set properly for stm_lf file */
# define BIGBUF 8*BUFSIZ	/* maximum record size: 4096 instead of 512 */
	    setvbuf(stdout, malloc(BIGBUF), _IOFBF, BIGBUF);
#endif
	    (void) vms_define("SYS$OUTPUT", f_out);
	} else
	    fatal(">%s%s (%s)", (*out_mode == 'a' ? ">" : ""),
		  f_out, strerror(errno));
    }
    if (err_to_out_redirect) {	/* special case for ``2>&1'' construct */
	(void) fclose(stderr);
	(void) dup2(1, 2);	/* make file 2 (stderr) share file 1 (stdout) */
	stderr = stdout;
	(void) vms_define("SYS$ERROR", "SYS$OUTPUT:");
    } else if (out_to_err_redirect) {	/* ``1>&2'' */
	(void) fclose(stdout);
	(void) dup2(2, 1);	/* make file 1 (stdout) share file 2 (stderr) */
	stdout = stderr;
	(void) vms_define("SYS$OUTPUT", "SYS$ERROR:");
    }

#ifndef NO_DCL_CMD
    /* if we replaced argv[] with our own, we can release it now */
    if (argv != *pargv)
	free((void *)argv),  argv = NULL;
#endif
    *pargc = ++v_argc;		/* increment to account for argv[0] */
    *pargv = v_argv;
    return;
}
Beispiel #17
0
Datei: re.c Projekt: WndSks/msys
Regexp *
make_regexp(const char *s, size_t len, int ignorecase, int dfa)
{
	Regexp *rp;
	const char *rerr;
	const char *src = s;
	char *temp;
	const char *end = s + len;
	register char *dest;
	register int c, c2;
	static short first = TRUE;
	static short no_dfa = FALSE;
	int has_anchor = FALSE;

	/* The number of bytes in the current multibyte character.
	   It is 0, when the current character is a singlebyte character.  */
	size_t is_multibyte = 0;
#ifdef MBS_SUPPORT
	mbstate_t mbs;

	if (gawk_mb_cur_max > 1)
		memset(&mbs, 0, sizeof(mbstate_t)); /* Initialize.  */
#endif

	if (first) {
		first = FALSE;
		no_dfa = (getenv("GAWK_NO_DFA") != NULL);	/* for debugging and testing */
	}

	/* Handle escaped characters first. */

	/*
	 * Build a copy of the string (in dest) with the
	 * escaped characters translated, and generate the regex
	 * from that.  
	 */
	emalloc(dest, char *, len + 2, "make_regexp");
	temp = dest;

	while (src < end) {
#ifdef MBS_SUPPORT
		if (gawk_mb_cur_max > 1 && ! is_multibyte) {
			/* The previous byte is a singlebyte character, or last byte
			   of a multibyte character.  We check the next character.  */
			is_multibyte = mbrlen(src, end - src, &mbs);
			if ((is_multibyte == 1) || (is_multibyte == (size_t) -1)
				|| (is_multibyte == (size_t) -2 || (is_multibyte == 0))) {
				/* We treat it as a singlebyte character.  */
				is_multibyte = 0;
			}
		}
#endif

		/* We skip multibyte character, since it must not be a special
		   character.  */
		if ((gawk_mb_cur_max == 1 || ! is_multibyte) &&
		    (*src == '\\')) {
			c = *++src;
			switch (c) {
			case 'a':
			case 'b':
			case 'f':
			case 'n':
			case 'r':
			case 't':
			case 'v':
			case 'x':
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
				c2 = parse_escape(&src);
				if (c2 < 0)
					cant_happen();
				/*
				 * Unix awk treats octal (and hex?) chars
				 * literally in re's, so escape regexp
				 * metacharacters.
				 */
				if (do_traditional && ! do_posix && (ISDIGIT(c) || c == 'x')
				    && strchr("()|*+?.^$\\[]", c2) != NULL)
					*dest++ = '\\';
				*dest++ = (char) c2;
				break;
			case '8':
			case '9':	/* a\9b not valid */
				*dest++ = c;
				src++;
				break;
			case 'y':	/* normally \b */
				/* gnu regex op */
				if (! do_traditional) {
					*dest++ = '\\';
					*dest++ = 'b';
					src++;
					break;
				}
				/* else, fall through */
			default:
				*dest++ = '\\';
				*dest++ = (char) c;
				src++;
				break;
			} /* switch */
		} else {
			c = *src;
			if (c == '^' || c == '$')
				has_anchor = TRUE;
			*dest++ = *src++;	/* not '\\' */
		}
		if (gawk_mb_cur_max > 1 && is_multibyte)
			is_multibyte--;
	} /* while */

	*dest = '\0' ;	/* Only necessary if we print dest ? */
	emalloc(rp, Regexp *, sizeof(*rp), "make_regexp");
	memset((char *) rp, 0, sizeof(*rp));
	rp->pat.allocated = 0;	/* regex will allocate the buffer */
	emalloc(rp->pat.fastmap, char *, 256, "make_regexp");

	/*
	 * Lo these many years ago, had I known what a P.I.T.A. IGNORECASE
	 * was going to turn out to be, I wouldn't have bothered with it.
	 *
	 * In the case where we have a multibyte character set, we have no
	 * choice but to use RE_ICASE, since the casetable is for single-byte
	 * character sets only.
	 *
	 * On the other hand, if we do have a single-byte character set,
	 * using the casetable should give  a performance improvement, since
	 * it's computed only once, not each time a regex is compiled.  We
	 * also think it's probably better for portability.  See the
	 * discussion by the definition of casetable[] in eval.c.
	 */

	if (ignorecase) {
		if (gawk_mb_cur_max > 1) {
			syn |= RE_ICASE;
			rp->pat.translate = NULL;
		} else {
			syn &= ~RE_ICASE;
			rp->pat.translate = (char *) casetable;
		}
	} else {
		rp->pat.translate = NULL;
		syn &= ~RE_ICASE;
	}

	dfasyntax(syn | (ignorecase ? RE_ICASE : 0), ignorecase ? TRUE : FALSE, '\n');
	re_set_syntax(syn);

	len = dest - temp;
	if ((rerr = re_compile_pattern(temp, len, &(rp->pat))) != NULL)
		fatal("%s: /%s/", rerr, temp);	/* rerr already gettextized inside regex routines */

	/* gack. this must be done *after* re_compile_pattern */
	rp->pat.newline_anchor = FALSE; /* don't get \n in middle of string */
	if (dfa && ! no_dfa) {
		dfacomp(temp, len, &(rp->dfareg), TRUE);
		rp->dfa = TRUE;
	} else
		rp->dfa = FALSE;
	rp->has_anchor = has_anchor;

	free(temp);
	return rp;
}
Beispiel #18
0
static void
mi_parse_argv (char *args, struct mi_parse *parse)
{
  char *chp = args;
  int argc = 0;
  char **argv = xmalloc ((argc + 1) * sizeof (char *));
  argv[argc] = NULL;
  while (1)
    {
      char *arg;
      /* skip leading white space */
      while (isspace (*chp))
	chp++;
      /* Three possibilities: EOF, quoted string, or other text. */
      switch (*chp)
	{
	case '\0':
	  parse->argv = argv;
	  parse->argc = argc;
	  return;
	case '"':
	  {
	    /* A quoted string. */
	    int len;
	    char *start = chp + 1;
	    /* Determine the buffer size. */
	    chp = start;
	    len = 0;
	    while (*chp != '\0' && *chp != '"')
	      {
		if (*chp == '\\')
		  {
		    chp++;
		    if (parse_escape (&chp) <= 0)
		      {
			/* Do not allow split lines or "\000" */
			freeargv (argv);
			return;
		      }
		  }
		else
		  chp++;
		len++;
	      }
	    /* Insist on a closing quote. */
	    if (*chp != '"')
	      {
		freeargv (argv);
		return;
	      }
	    /* Insist on trailing white space. */
	    if (chp[1] != '\0' && !isspace (chp[1]))
	      {
		freeargv (argv);
		return;
	      }
	    /* create the buffer. */
	    arg = xmalloc ((len + 1) * sizeof (char));
	    /* And copy the characters in. */
	    chp = start;
	    len = 0;
	    while (*chp != '\0' && *chp != '"')
	      {
		if (*chp == '\\')
		  {
		    chp++;
		    arg[len] = parse_escape (&chp);
		  }
		else
		  arg[len] = *chp++;
		len++;
	      }
	    arg[len] = '\0';
	    chp++;		/* that closing quote. */
	    break;
	  }
	default:
	  {
	    /* An unquoted string.  Accumulate all non blank
	       characters into a buffer. */
	    int len;
	    char *start = chp;
	    while (*chp != '\0' && !isspace (*chp))
	      {
		chp++;
	      }
	    len = chp - start;
	    arg = xmalloc ((len + 1) * sizeof (char));
	    strncpy (arg, start, len);
	    arg[len] = '\0';
	    break;
	  }
	}
      /* Append arg to argv. */
      argv = xrealloc (argv, (argc + 2) * sizeof (char *));
      argv[argc++] = arg;
      argv[argc] = NULL;
    }
}
Beispiel #19
0
void
do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
{
  /* A flag to indicate the option is changed or not.  */
  int option_changed = 0;

  gdb_assert (c->type == set_cmd);

  switch (c->var_type)
    {
    case var_string:
      {
	char *newobj;
	const char *p;
	char *q;
	int ch;

	if (arg == NULL)
	  arg = "";
	newobj = (char *) xmalloc (strlen (arg) + 2);
	p = arg;
	q = newobj;
	while ((ch = *p++) != '\000')
	  {
	    if (ch == '\\')
	      {
		/* \ at end of argument is used after spaces
		   so they won't be lost.  */
		/* This is obsolete now that we no longer strip
		   trailing whitespace and actually, the backslash
		   didn't get here in my test, readline or
		   something did something funky with a backslash
		   right before a newline.  */
		if (*p == 0)
		  break;
		ch = parse_escape (get_current_arch (), &p);
		if (ch == 0)
		  break;	/* C loses */
		else if (ch > 0)
		  *q++ = ch;
	      }
	    else
	      *q++ = ch;
	  }
#if 0
	if (*(p - 1) != '\\')
	  *q++ = ' ';
#endif
	*q++ = '\0';
	newobj = (char *) xrealloc (newobj, q - newobj);

	if (*(char **) c->var == NULL
	    || strcmp (*(char **) c->var, newobj) != 0)
	  {
	    xfree (*(char **) c->var);
	    *(char **) c->var = newobj;

	    option_changed = 1;
	  }
	else
	  xfree (newobj);
      }
      break;
    case var_string_noescape:
      if (arg == NULL)
	arg = "";

      if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
	{
	  xfree (*(char **) c->var);
	  *(char **) c->var = xstrdup (arg);

	  option_changed = 1;
	}
      break;
    case var_filename:
      if (arg == NULL)
	error_no_arg (_("filename to set it to."));
      /* FALLTHROUGH */
    case var_optional_filename:
      {
	char *val = NULL;

	if (arg != NULL)
	  {
	    /* Clear trailing whitespace of filename.  */
	    const char *ptr = arg + strlen (arg) - 1;
	    char *copy;

	    while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
	      ptr--;
	    copy = xstrndup (arg, ptr + 1 - arg);

	    val = tilde_expand (copy);
	    xfree (copy);
	  }
	else
	  val = xstrdup ("");

	if (*(char **) c->var == NULL
	    || strcmp (*(char **) c->var, val) != 0)
	  {
	    xfree (*(char **) c->var);
	    *(char **) c->var = val;

	    option_changed = 1;
	  }
	else
	  xfree (val);
      }
      break;
    case var_boolean:
      {
	int val = parse_cli_boolean_value (arg);

	if (val < 0)
	  error (_("\"on\" or \"off\" expected."));
	if (val != *(int *) c->var)
	  {
	    *(int *) c->var = val;

	    option_changed = 1;
	  }
      }
      break;
    case var_auto_boolean:
      {
	enum auto_boolean val = parse_auto_binary_operation (arg);

	if (*(enum auto_boolean *) c->var != val)
	  {
	    *(enum auto_boolean *) c->var = val;

	    option_changed = 1;
	  }
      }
      break;
    case var_uinteger:
    case var_zuinteger:
      {
	LONGEST val;

	if (arg == NULL)
	  {
	    if (c->var_type == var_uinteger)
	      error_no_arg (_("integer to set it to, or \"unlimited\"."));
	    else
	      error_no_arg (_("integer to set it to."));
	  }

	if (c->var_type == var_uinteger && is_unlimited_literal (arg))
	  val = 0;
	else
	  val = parse_and_eval_long (arg);

	if (c->var_type == var_uinteger && val == 0)
	  val = UINT_MAX;
	else if (val < 0
		 /* For var_uinteger, don't let the user set the value
		    to UINT_MAX directly, as that exposes an
		    implementation detail to the user interface.  */
		 || (c->var_type == var_uinteger && val >= UINT_MAX)
		 || (c->var_type == var_zuinteger && val > UINT_MAX))
	  error (_("integer %s out of range"), plongest (val));

	if (*(unsigned int *) c->var != val)
	  {
	    *(unsigned int *) c->var = val;

	    option_changed = 1;
	  }
      }
      break;
    case var_integer:
    case var_zinteger:
      {
	LONGEST val;

	if (arg == NULL)
	  {
	    if (c->var_type == var_integer)
	      error_no_arg (_("integer to set it to, or \"unlimited\"."));
	    else
	      error_no_arg (_("integer to set it to."));
	  }

	if (c->var_type == var_integer && is_unlimited_literal (arg))
	  val = 0;
	else
	  val = parse_and_eval_long (arg);

	if (val == 0 && c->var_type == var_integer)
	  val = INT_MAX;
	else if (val < INT_MIN
		 /* For var_integer, don't let the user set the value
		    to INT_MAX directly, as that exposes an
		    implementation detail to the user interface.  */
		 || (c->var_type == var_integer && val >= INT_MAX)
		 || (c->var_type == var_zinteger && val > INT_MAX))
	  error (_("integer %s out of range"), plongest (val));

	if (*(int *) c->var != val)
	  {
	    *(int *) c->var = val;

	    option_changed = 1;
	  }
	break;
      }
    case var_enum:
      {
	int i;
	int len;
	int nmatches;
	const char *match = NULL;
	char *p;

	/* If no argument was supplied, print an informative error
	   message.  */
	if (arg == NULL)
	  {
	    char *msg;
	    int msg_len = 0;

	    for (i = 0; c->enums[i]; i++)
	      msg_len += strlen (c->enums[i]) + 2;

	    msg = xmalloc (msg_len);
	    *msg = '\0';
	    make_cleanup (xfree, msg);

	    for (i = 0; c->enums[i]; i++)
	      {
		if (i != 0)
		  strcat (msg, ", ");
		strcat (msg, c->enums[i]);
	      }
	    error (_("Requires an argument. Valid arguments are %s."), 
		   msg);
	  }

	p = strchr (arg, ' ');

	if (p)
	  len = p - arg;
	else
	  len = strlen (arg);

	nmatches = 0;
	for (i = 0; c->enums[i]; i++)
	  if (strncmp (arg, c->enums[i], len) == 0)
	    {
	      if (c->enums[i][len] == '\0')
		{
		  match = c->enums[i];
		  nmatches = 1;
		  break; /* Exact match.  */
		}
	      else
		{
		  match = c->enums[i];
		  nmatches++;
		}
	    }

	if (nmatches <= 0)
	  error (_("Undefined item: \"%s\"."), arg);

	if (nmatches > 1)
	  error (_("Ambiguous item \"%s\"."), arg);

	if (*(const char **) c->var != match)
	  {
	    *(const char **) c->var = match;

	    option_changed = 1;
	  }
      }
      break;
    case var_zuinteger_unlimited:
      {
	LONGEST val;

	if (arg == NULL)
	  error_no_arg (_("integer to set it to, or \"unlimited\"."));

	if (is_unlimited_literal (arg))
	  val = -1;
	else
	  val = parse_and_eval_long (arg);

	if (val > INT_MAX)
	  error (_("integer %s out of range"), plongest (val));
	else if (val < -1)
	  error (_("only -1 is allowed to set as unlimited"));

	if (*(int *) c->var != val)
	  {
	    *(int *) c->var = val;
	    option_changed = 1;
	  }
      }
      break;
    default:
      error (_("gdb internal error: bad var_type in do_setshow_command"));
    }
  c->func (c, NULL, from_tty);

  if (notify_command_param_changed_p (option_changed, c))
    {
      char *name, *cp;
      struct cmd_list_element **cmds;
      struct cmd_list_element *p;
      int i;
      int length = 0;

      /* Compute the whole multi-word command options.  If user types command
	 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
	 command option change notification, because it is confusing.  We can
	 trace back through field 'prefix' to compute the whole options,
	 and pass "foo bar baz" to notification.  */

      for (i = 0, p = c; p != NULL; i++)
	{
	  length += strlen (p->name);
	  length++;

	  p = p->prefix;
	}
      cp = name = (char *) xmalloc (length);
      cmds = XNEWVEC (struct cmd_list_element *, i);

      /* Track back through filed 'prefix' and cache them in CMDS.  */
      for (i = 0, p = c; p != NULL; i++)
	{
	  cmds[i] = p;
	  p = p->prefix;
	}

      /* Don't trigger any observer notification if prefixlist is not
	 setlist.  */
      i--;
      if (cmds[i]->prefixlist != &setlist)
	{
	  xfree (cmds);
	  xfree (name);

	  return;
	}
      /* Traverse them in the reversed order, and copy their names into
	 NAME.  */
      for (i--; i >= 0; i--)
	{
	  memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
	  cp += strlen (cmds[i]->name);

	  if (i != 0)
	    {
	      cp[0] = ' ';
	      cp++;
	    }
	}
      cp[0] = 0;

      xfree (cmds);

      switch (c->var_type)
	{
	case var_string:
	case var_string_noescape:
	case var_filename:
	case var_optional_filename:
	case var_enum:
	  observer_notify_command_param_changed (name, *(char **) c->var);
	  break;
	case var_boolean:
	  {
	    char *opt = *(int *) c->var ? "on" : "off";

	    observer_notify_command_param_changed (name, opt);
	  }
	  break;
	case var_auto_boolean:
	  {
	    const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];

	    observer_notify_command_param_changed (name, s);
	  }
	  break;
	case var_uinteger:
	case var_zuinteger:
	  {
	    char s[64];

	    xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
	    observer_notify_command_param_changed (name, s);
	  }
	  break;
	case var_integer:
	case var_zinteger:
	case var_zuinteger_unlimited:
	  {
	    char s[64];

	    xsnprintf (s, sizeof s, "%d", *(int *) c->var);
	    observer_notify_command_param_changed (name, s);
	  }
	  break;
	}
      xfree (name);
    }
}
/* Parse a C escape sequence. STRING_PTR points to a variable
 * containing a pointer to the string to parse. That pointer
 * is updated past the characters we use. The value of the
 * escape sequence is returned.
 *
 * A negative value means the sequence \ newline was seen,
 * which is supposed to be equivalent to nothing at all.
 *
 * If \ is followed by a null character, we return a negative
 * value and leave the string pointer pointing at the null character.
 *
 * If \ is followed by 000, we return 0 and leave the string pointer
 * after the zeros. A value of 0 does not mean end of string. */
int parse_escape(char **string_ptr)
{
  register int c = *(*string_ptr)++;
  switch (c) {
    case 'a':
      return '\a';
    case 'b':
      return '\b';
    case 'e':
      return 033;
    case 'f':
      return '\f';
    case 'n':
      return '\n';
    case 'r':
      return '\r';
    case 't':
      return '\t';
    case 'v':
      return '\v';
    case '\n':
      return -2;
    case 0:
      (*string_ptr)--;
      return 0;
    case '^':
      c = *(*string_ptr)++;
      if (c == '\\') {
          c = parse_escape(string_ptr);
      }
      if (c == '?') {
          return 0177;
      }
      return ((c & 0200) | (c & 037));

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      {
          register int i = (c - '0');
          register int count = 0;
          while (++count < 3) {
              if ((c = *(*string_ptr)++) >= '0' && c <= '7') {
                  i *= 8;
                  i += (c - '0');
              } else {
                  (*string_ptr)--;
                  break;
              }
          }
          return i;
      }
    default:
      return c;
  }
}
void
do_setshow_command(char *arg, int from_tty, struct cmd_list_element *c)
{
  if (c->type == set_cmd)
    {
      switch (c->var_type)
	{
	case var_string:
	  {
	    char *newstr;
	    char *p;
	    char *q;
	    int ch;

	    if (arg == NULL)
	      arg = "";
	    newstr = (char *)xmalloc(strlen(arg) + 2);
	    p = arg;
	    q = newstr;
	    while ((ch = *p++) != '\000')
	      {
		if (ch == '\\')
		  {
		    /* \ at end of argument is used after spaces
		       so they won't be lost.  */
		    /* This is obsolete now that we no longer strip
		       trailing whitespace and actually, the backslash
		       didn't get here in my test, readline or
		       something did something funky with a backslash
		       right before a newline.  */
		    if (*p == 0)
		      break;
		    ch = parse_escape(&p);
		    if (ch == 0)
		      break;	/* C loses */
		    else if (ch > 0)
		      *q++ = ch;
		  }
		else
		  *q++ = ch;
	      }
#if 0
	    if (*(p - 1) != '\\')
	      *q++ = ' ';
#endif /* 0 */
	    *q++ = '\0';
	    newstr = (char *)xrealloc(newstr, (q - newstr));
	    if (*(char **)c->var != NULL)
	      xfree(*(char **)c->var);
	    *(char **)c->var = newstr;
	  }
	  break;
	case var_string_noescape:
	  if (arg == NULL)
	    arg = "";
	  if (*(char **)c->var != NULL)
	    xfree(*(char **)c->var);
	  *(char **)c->var = savestring(arg, strlen(arg));
	  break;
	case var_optional_filename:
	  if (arg == NULL)
	    arg = "";
	  if (*(char **)c->var != NULL)
	    xfree(*(char **)c->var);
	  *(char **)c->var = savestring(arg, strlen(arg));
	  break;
	case var_filename:
	  if (arg == NULL)
	    error_no_arg(_("filename to set it to."));
	  if (*(char **)c->var != NULL)
	    xfree (*(char **)c->var);
	  *(char **)c->var = tilde_expand(arg);
	  break;
	case var_boolean:
	  *(int *)c->var = parse_binary_operation(arg);
	  break;
	case var_auto_boolean:
	  *(enum auto_boolean *)c->var = parse_auto_binary_operation(arg);
	  break;
	case var_uinteger:
	  if (arg == NULL)
	    error_no_arg(_("integer to set it to."));
	  *(unsigned int *)c->var = (unsigned int)parse_and_eval_long(arg);
	  if (*(unsigned int *)c->var == 0)
	    *(unsigned int *)c->var = UINT_MAX;
	  break;
	case var_integer:
	  {
	    unsigned int val;
	    if (arg == NULL)
	      error_no_arg(_("integer to set it to."));
	    val = (unsigned int)parse_and_eval_long(arg);
	    if (val == 0)
	      *(int *)c->var = INT_MAX;
	    else if (val >= INT_MAX)
	      error(_("integer %u out of range"), val);
	    else
	      *(int *)c->var = val;
	    break;
	  }
	case var_zinteger:
	  if (arg == NULL)
	    error_no_arg(_("integer to set it to."));
	  *(int *)c->var = (int)parse_and_eval_long(arg);
	  break;
	case var_enum:
	  {
	    int i;
	    int len;
	    int nmatches = 0;
	    const char *match = NULL;
	    char *p;

	    /* APPLE LOCAL: Give the valid options for all error
	       messages for enum type commands. */

	    /* If an argument was supplied, parse it. */
	    if (arg != NULL)
	      {
		p = strchr(arg, ' ');

		if (p)
		  len = (p - arg);
		else
		  len = strlen(arg);

		nmatches = 0;
		for (i = 0; c->enums[i]; i++)
		  if (strncmp(arg, c->enums[i], len) == 0)
		    {
		      if (c->enums[i][len] == '\0')
			{
			  match = c->enums[i];
			  nmatches = 1;
			  break; /* exact match. */
			}
		      else
			{
			  match = c->enums[i];
			  nmatches++;
			}
		    }
	      }

	    if (nmatches == 1)
	      *(const char **)c->var = match;
	    else
	      {
                /* If there was an error, print an informative
                   error message.  */
                struct ui_file *tmp_error_stream = mem_fileopen();
                make_cleanup_ui_file_delete (tmp_error_stream);

                if (arg == NULL)
                  fprintf_unfiltered(tmp_error_stream, "Requires an argument.");
                else if (nmatches <= 0)
                  fprintf_unfiltered(tmp_error_stream, "Undefined item: \"%s\".", arg);
		else if (nmatches > 1)
                  fprintf_unfiltered(tmp_error_stream, "Ambiguous item \"%s\".", arg);

                fprintf_unfiltered(tmp_error_stream, " Valid arguments are ");
                for (i = 0; c->enums[i]; i++)
                  {
                    if (i != 0)
                      fprintf_unfiltered(tmp_error_stream, ", ");
                    fputs_unfiltered(c->enums[i], tmp_error_stream);
                  }
                fprintf_unfiltered(tmp_error_stream, ".");
                error_stream(tmp_error_stream);
	      }

	    /* END APPLE LOCAL */
	  }
	  break;
	default:
	  error(_("gdb internal error: bad var_type in do_setshow_command"));
	}
    }
  else if (c->type == show_cmd)
    {
      struct cleanup *old_chain;
      struct ui_stream *stb;

      stb = ui_out_stream_new(uiout);
      old_chain = make_cleanup_ui_out_stream_delete(stb);

      /* Possibly call the pre hook: */
      if (c->pre_show_hook)
	(c->pre_show_hook)(c);

      switch (c->var_type)
	{
	case var_string:
	  {
	    if (*(unsigned char **)c->var)
	      fputstr_filtered(*(char **)c->var, '"', stb->stream);
	  }
	  break;
	case var_string_noescape:
	case var_optional_filename:
	case var_filename:
	case var_enum:
	  if (*(char **)c->var)
	    fputs_filtered(*(char **)c->var, stb->stream);
	  break;
	case var_boolean:
	  fputs_filtered(*(int *)c->var ? "on" : "off", stb->stream);
	  break;
	case var_auto_boolean:
	  switch (*(enum auto_boolean*)c->var)
	    {
	    case AUTO_BOOLEAN_TRUE:
	      fputs_filtered("on", stb->stream);
	      break;
	    case AUTO_BOOLEAN_FALSE:
	      fputs_filtered("off", stb->stream);
	      break;
	    case AUTO_BOOLEAN_AUTO:
	      fputs_filtered("auto", stb->stream);
	      break;
	    default:
	      internal_error(__FILE__, __LINE__,
			     _("do_setshow_command: invalid var_auto_boolean"));
	      break;
	    }
	  break;
	case var_uinteger:
	  if (*(unsigned int *)c->var == UINT_MAX)
	    {
	      fputs_filtered("unlimited", stb->stream);
	      break;
	    }
	  /* else fall through */
	case var_zinteger:
	  fprintf_filtered(stb->stream, "%u", *(unsigned int *)c->var);
	  break;
	case var_integer:
	  if (*(int *)c->var == INT_MAX)
	    {
	      fputs_filtered("unlimited", stb->stream);
	    }
	  else
	    fprintf_filtered(stb->stream, "%d", *(int *)c->var);
	  break;

	default:
	  error(_("gdb internal error: bad var_type in do_setshow_command"));
	}


      /* FIXME: cagney/2005-02-10: Need to split this in half: code to
	 convert the value into a string (esentially the above); and
	 code to print the value out.  For the latter there should be
	 MI and CLI specific versions.  */

      if (ui_out_is_mi_like_p(uiout))
	ui_out_field_stream(uiout, "value", stb);
      else
	{
	  long length;
	  char *value = ui_file_xstrdup(stb->stream, &length);
	  make_cleanup(xfree, value);
	  if (c->show_value_func != NULL)
	    c->show_value_func(gdb_stdout, from_tty, c, value);
	  else
	    deprecated_show_value_hack(gdb_stdout, from_tty, c, value);
	}
      do_cleanups(old_chain);
    }
  else
    error(_("gdb internal error: bad cmd_type in do_setshow_command"));
  c->func(c, NULL, from_tty);
  if ((c->type == set_cmd) && deprecated_set_hook)
    deprecated_set_hook(c);
}
Beispiel #22
0
/**
 * Print a char in a certain console.
 * 
 * @param con  The console to which the char is printed.
 * @param ch   The char to print.
 *****************************************************************************/
PUBLIC void out_char(TTY* tty, char ch)
{
	CONSOLE * con = tty->tty_dev;
	u8* pch = (u8*)(V_MEM_BASE + con->cursor * 2);

	assert(con->cursor - con->orig < con->con_size);

	/*
	 * calculate the coordinate of cursor in current console (not in
	 * current screen)
	 */
	int cursor_x = (con->cursor - con->orig) % SCR_WIDTH;
	int cursor_y = (con->cursor - con->orig) / SCR_WIDTH;

	if (con->c_esc_state > 0) {	/* check for escape sequences */
		parse_escape(con, ch);
		return;
	}
  
	switch(ch) {
	case 000:
		return;
	case 007:		/* beep */
		//beep();
		break;
	case '\b':		/* backspace */
		if (con->cursor > con->orig) {
			con->cursor--;
			*(pch - 2) = ' ';
			*(pch - 1) = DEFAULT_CHAR_COLOR;
		}
		break;
	case '\n':		/* line feed */
		if ((con->con_tty->tty_termios.c_oflag & (OPOST|ONLCR))
						== (OPOST|ONLCR)) {
			con->cursor = con->orig + SCR_WIDTH * cursor_y;
		}
	case 013:		/* CTRL-K */
	case 014:		/* CTRL-L */
		con->cursor = con->cursor + SCR_WIDTH;
		break;
	case '\r':		/* carriage return */
		con->cursor = con->orig + SCR_WIDTH * cursor_y;
		break;
	case '\t':		/* tab */
		con->cursor = con->orig + SCR_WIDTH * cursor_y + ((cursor_x + TAB_SIZE) & ~TAB_MASK);
		break;
	case 033:		/* ESC - start of an escape sequence */
		con->c_esc_state = 1;
		return;
	default:
		*pch++ = ch;
		*pch++ = DEFAULT_CHAR_COLOR;
		con->cursor++;
		break;
	}

	if (con->cursor - con->orig >= con->con_size) {
		cursor_x = (con->cursor - con->orig) % SCR_WIDTH;
		cursor_y = (con->cursor - con->orig) / SCR_WIDTH;
		int cp_orig = con->orig + (cursor_y + 1) * SCR_WIDTH - SCR_SIZE;
		w_copy(con->orig, cp_orig, SCR_SIZE - SCR_WIDTH);
		con->crtc_start = con->orig;
		con->cursor = con->orig + (SCR_SIZE - SCR_WIDTH) + cursor_x;
		clear_screen(con->cursor, SCR_WIDTH);
		if (!con->is_full)
			con->is_full = 1;
	}

	assert(con->cursor - con->orig < con->con_size);

	while (con->cursor >= con->crtc_start + SCR_SIZE ||
	       con->cursor < con->crtc_start) {
		scroll_screen(con, SCR_UP);

		clear_screen(con->cursor, SCR_WIDTH);
	}

	flush(con);
}