Exemple #1
0
static str_t *extract_partial(struct msg_ac *msg)
{
	char *cursor;
	char *c = msg->buffer.addr;
	char *end = msg->buffer.addr + msg->buffer.sz;

	for (int line = 1; line < msg->line; line++) {
		while (1) {
			if (c == end)
				return 0;
			if (*c == '\n') {
				c++;
				break;
			}
			c++;
		}
	}

	cursor = c + (msg->col - 1);
	c += msg->col - 2;
	while (isident(*c))
		c--;
	c++;

	if (c == cursor)
		return 0;

	return str_from_cstr_len(c, cursor - c);
}
void php_function(const char *&txt, PopupList &pul, BString &className, bool sorted)
{
	BString label, function, params;
	txt = skip_whitespace(txt+8);

	const char *beg = txt;
	while (isident(*++txt)) ;
	function.SetTo(beg, txt-beg);

	txt = skip_whitespace(txt);
	if (*txt == '(') {
		const char* ptr = txt;
		txt = skip_block(txt+1, '(', ')');
		params.SetTo(ptr+1, txt-ptr-2);
		params.Prepend("  (");
		params.Append(")");
	}
	if (sorted)
	{
		label << SORT_PREFIX_PHP;
		if (className != "")
		{
			label << className << "::";
		}
	}
	else
	{
		if (className != "")
		{
			label << "• ";
		}
	}
	label << function << params;
	pul.insert(pul.end(), PopupMenu(label, function, beg));
} /* php_function */
static int
cpp_keyword(
LINE	*lp,
int	off)
{
	char	temp[NSTRING];
	register char *d = temp;
	register int  n;

	static	const	struct	{
		char	*name;
		int	code;
	} keyword_table[] = {
		{ "if",     CPP_IF },
		{ "ifdef",  CPP_IF },
		{ "ifndef", CPP_IF },
		{ "elif",   CPP_ELIF },
		{ "else",   CPP_ELSE },
		{ "endif",  CPP_ENDIF }
	};

	while (off < llength(lp)) {
		n = lgetc(lp,off++);
		if ((d - temp < sizeof(temp)-2) && isident(n))
			*d++ = (char)n;
		else
			break;
	}
	*d = EOS;

	for (n = 0; n < TABLESIZE(keyword_table); n++)
		if (!strcmp(temp, keyword_table[n].name))
			return keyword_table[n].code;
	return CPP_UNKNOWN;
}
Exemple #4
0
bool IsValidIdentifier(const char *Str)
	{
	if (!isidentf(Str[0]))
		return false;
	while (char c = *Str++)
		if (!isident(c))
			return false;
	return true;
	}
Exemple #5
0
TBOOLEAN
legal_identifier(char *p)
{
    if (!p || !(*p) || isdigit((unsigned char)*p))
	return FALSE;
    while (*p) {
	if (!isident(*p))
	    return FALSE;
	p++;
    }
    return TRUE;
}
Exemple #6
0
void
get_terminal_name(unsigned char name[MAX_TERM_LEN])
{
	unsigned char *term = getenv("TERM");
	int i;

	memset(name, 0, MAX_TERM_LEN);

	if (!term) return;

	for (i = 0; term[i] != 0 && i < MAX_TERM_LEN - 1; i++)
		name[i] = isident(term[i]) ? term[i] : '-';
}
Exemple #7
0
static int
bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
{
    int bufsize, x;
    char *endptr = NULL, *scalar = NULL, *buffer;
    time_t secs;
    struct tm *t;

    if (OPT_ISSET(ops,'s')) {
	scalar = OPT_ARG(ops, 's');
	if (!isident(scalar)) {
	    zwarnnam(nam, "not an identifier: %s", scalar);
	    return 1;
	}
    }
    if (OPT_ISSET(ops, 'r'))
	return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q'));

    errno = 0;
    secs = (time_t)strtoul(argv[1], &endptr, 10);
    if (errno != 0) {
	zwarnnam(nam, "%s: %e", argv[1], errno);
	return 1;
    } else if (*endptr != '\0') {
	zwarnnam(nam, "%s: invalid decimal number", argv[1]);
	return 1;
    }

    t = localtime(&secs);
    if (!t) {
	zwarnnam(nam, "%s: unable to convert to time", argv[1]);
	return 1;
    }
    bufsize = strlen(argv[0]) * 8;
    buffer = zalloc(bufsize);

    for (x=0; x < 4; x++) {
        if (ztrftime(buffer, bufsize, argv[0], t) >= 0)
	    break;
	buffer = zrealloc(buffer, bufsize *= 2);
    }

    if (scalar) {
	setsparam(scalar, metafy(buffer, -1, META_DUP));
    } else {
	printf("%s\n", buffer);
    }
    zfree(buffer, bufsize);

    return 0;
}
Exemple #8
0
static int
bin_syserror(char *nam, char **args, Options ops, UNUSED(int func))
{
    int num = 0;
    char *errvar = NULL, *msg, *pfx = "", *str;

    /* variable in which to write error message */
    if (OPT_ISSET(ops, 'e')) {
	errvar = OPT_ARG(ops, 'e');
	if (!isident(errvar)) {
	    zwarnnam(nam, "not an identifier: %s", errvar);
	    return 1;
	}
    }
    /* prefix for error message */
    if (OPT_ISSET(ops, 'p'))
	pfx = OPT_ARG(ops, 'p');

    if (!*args)
	num = errno;
    else {
	char *ptr = *args;
	while (*ptr && idigit(*ptr))
	    ptr++;
	if (!*ptr && ptr > *args)
	    num = atoi(*args);
	else {
	    const char **eptr;
	    for (eptr = sys_errnames; *eptr; eptr++) {
		if (!strcmp(*eptr, *args)) {
		    num = (eptr - sys_errnames) + 1;
		    break;
		}
	    }
	    if (!*eptr)
		return 2;
	}
    }

    msg = strerror(num);
    if (errvar) {
	str = (char *)zalloc(strlen(msg) + strlen(pfx) + 1);
	sprintf(str, "%s%s", pfx, msg);
	setsparam(errvar, str);
    } else {
	fprintf(stderr, "%s%s\n", pfx, msg);
    }

    return 0;
}
Exemple #9
0
int
rl_vi_eword (int count, int ignore)
{
  while (count-- && rl_point < rl_end - 1)
    {
      if (!whitespace (rl_line_buffer[rl_point]))
	rl_point++;

      while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
	rl_point++;

      if (rl_point < rl_end)
	{
	  if (isident (rl_line_buffer[rl_point]))
	    while (++rl_point < rl_end && isident (rl_line_buffer[rl_point]));
	  else
	    while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point])
		   && !whitespace (rl_line_buffer[rl_point]));
	}
      rl_point--;
    }
  return (0);
}
Exemple #10
0
/*  Read a C identifier beginning with "firstChar" and places it into "name".
 */
static void parseIdentifier (vString *const string, const int firstChar)
{
	int c = firstChar;

	do
	{
		vStringPut (string, c);
		c = getcFromInputFile ();
	} while (isident (c));

	vStringTerminate (string);
	if (!isspace (c))
		ungetcToInputFile (c);  /* unget non-identifier character */
}
Exemple #11
0
int
rl_vi_fword (int count, int ignore)
{
  while (count-- && rl_point < (rl_end - 1))
    {
      /* Move to white space (really non-identifer). */
      if (isident (rl_line_buffer[rl_point]))
	{
	  while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
	    rl_point++;
	}
      else /* if (!whitespace (rl_line_buffer[rl_point])) */
	{
	  while (!isident (rl_line_buffer[rl_point]) &&
		 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
	    rl_point++;
	}

      /* Move past whitespace. */
      while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
	rl_point++;
    }
  return (0);
}
Exemple #12
0
static int get_token(char *token, int n)
{
    int c = fileGetc();
    int i = n;
    while (c != EOF && isident(c) && i < 1000) {
	token[i] = c;
	i++;
	c = fileGetc();
    }
    if (c == EOF)
	return 0;
    if (i != n) {
	token[i] = '\0';
	fileUngetc(c);
	return 1;
    } else {
	return 0;
    }
}
Exemple #13
0
static int
bin_syswrite(char *nam, char **args, Options ops, UNUSED(int func))
{
    int outfd = 1, len, count, totcount;
    char *countvar = NULL;

    /* -o: output file descriptor if not stdout */
    if (OPT_ISSET(ops, 'o')) {
	outfd = getposint(OPT_ARG(ops, 'o'), nam);
	if (outfd < 0)
	    return 1;
    }

    /* -c: variable in which to store count of bytes written */
    if (OPT_ISSET(ops, 'c')) {
	countvar = OPT_ARG(ops, 'c');
	if (!isident(countvar)) {
	    zwarnnam(nam, "not an identifier: %s", countvar);
	    return 1;
	}
    }

    totcount = 0;
    unmetafy(*args, &len);
    while (len) {
	while ((count = write(outfd, *args, len)) < 0) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
	    {
		if (countvar)
		    setiparam(countvar, totcount);
		return 2;
	    }
	}
	*args += count;
	totcount += count;
	len -= count;
    }
    if (countvar)
	setiparam(countvar, totcount);

    return 0;
}
void php_class(const char *&txt, PopupList &pul, BString &className, bool sorted)
{
	BString label;

	txt = skip_whitespace(txt+5);
	const char *beg = txt;
	while (isident(*++txt)) ;
	className.SetTo(beg, txt-beg);

	while (*++txt && *txt != '{') ;

//	txt = skip_whitespace(txt);
//	if (*txt == '(') {
//		const char* beg = txt;
//		txt = skip_block(txt+1, '(', ')');
//		params.SetTo(beg+1, txt-beg-2);
//		params.Prepend("  (");
//		params.Append(")");
//	}
	if (!sorted)
		pul.insert(pul.end(), PopupMenu(className, className, beg, true));
} /* php_class */
Exemple #15
0
int
rl_vi_bword (int count, int ignore)
{
  while (count-- && rl_point > 0)
    {
      int last_is_ident;

      /* If we are at the start of a word, move back to whitespace
	 so we will go back to the start of the previous word. */
      if (!whitespace (rl_line_buffer[rl_point]) &&
	  whitespace (rl_line_buffer[rl_point - 1]))
	rl_point--;

      /* If this character and the previous character are `opposite', move
	 back so we don't get messed up by the rl_point++ down there in
	 the while loop.  Without this code, words like `l;' screw up the
	 function. */
      last_is_ident = isident (rl_line_buffer[rl_point - 1]);
      if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
	  (!isident (rl_line_buffer[rl_point]) && last_is_ident))
	rl_point--;

      while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
	rl_point--;

      if (rl_point > 0)
	{
	  if (isident (rl_line_buffer[rl_point]))
	    while (--rl_point >= 0 && isident (rl_line_buffer[rl_point]));
	  else
	    while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) &&
		   !whitespace (rl_line_buffer[rl_point]));
	  rl_point++;
	}
    }
  return (0);
}
Exemple #16
0
void FindClass(TagFileInfo* fi,const char* str,PTagArray ta)
{
  FILE *g=fopen(fi->indexFile,"rb");
  if(!g)return;
  int sz;
  fread(&sz,4,1,g);
  fseek(g,4+sz*4*2,SEEK_SET);
  fread(&sz,4,1,g);
  Vector<int> offsets;
  offsets.Init(sz);
  if(sz)fread(&offsets[0],4,sz,g);
  fclose(g);
  FILE *f=fopen(fi->filename,"rb");
  if(!f)return;
  int len=strlen(str);
  int left=0;
  int right=offsets.Count()-1;
  int cmp;
  int pos;
  const char *cls;
  String base=fi->filename;
  int ri=base.RIndex("\\");
  if(ri!=-1)
  {
    base.Delete(ri+1);
  }

  while(left<=right)
  {
    pos=(right+left)/2;
    fseek(f,offsets[pos],SEEK_SET);
    fgets(strbuf,sizeof(strbuf),f);
    cls=strstr(strbuf,"\tclass:");
    if(!cls)
    {
      cls=strstr(strbuf,"\tstruct:");
      if(!cls)
      {
        cls="";
      }else
      {
        cls+=8;
      }
    }else
    {
      cls+=7;
    }
    cmp=strncmp(str,cls,len);
    if(!cmp && !isident(cls[len]))
    {
      break;
    }else if(cmp<=0)
    {
      right=pos-1;
    }else
    {
      left=pos+1;
    }
  }
  if(!cmp && !isident(cls[len]))
  {
    int endpos=pos;
    while(pos>0)
    {
      fseek(f,offsets[pos-1],SEEK_SET);
      fgets(strbuf,sizeof(strbuf),f);
      cls=strstr(strbuf,"\tclass:");
      if(!cls)
      {
        cls=strstr(strbuf,"\tstruct:");
        if(!cls)
        {
          cls="";
        }else
        {
          cls+=8;
        }
      }else
      {
        cls+=7;
      }
      if(!strncmp(str,cls,len) && !isident(cls[len]))
      {
        pos--;
      }else
      {
        break;
      }
    }
    while(endpos<offsets.Count()-1)
    {
      fseek(f,offsets[endpos+1],SEEK_SET);
      fgets(strbuf,sizeof(strbuf),f);
      cls=strstr(strbuf,"\tclass:");
      cls=strstr(strbuf,"\tclass:");
      if(!cls)
      {
        cls=strstr(strbuf,"\tstruct:");
        if(!cls)
        {
          cls="";
        }else
        {
          cls+=8;
        }
      }else
      {
        cls+=7;
      }
      if(!strncmp(str,cls,len) && !isident(cls[len]))
      {
        endpos++;
      }else
      {
        break;
      }
    }
    Vector<char*> lines;
    for(int i=pos;i<=endpos;i++)
    {
      fseek(f,offsets[i],SEEK_SET);
      fgets(strbuf,sizeof(strbuf),f);
      lines.Push(strdup(strbuf));
    }
    qsort(&lines[0],lines.Count(),4,StrCmp);
    for(int i=0;i<lines.Count();i++)
    {
      TagInfo *ti=ParseLine(lines[i],base);
      if(ti)ta->Push(ti);
      free(lines[i]);
    }
  }
  fclose(f);
}
Exemple #17
0
static void findHaskellTags (int is_literate)
{
    vString *name = vStringNew ();
    char token[1001], arg[1001];
    int c;
    int in_tex_lit_code = 0;
    c = get_next_char();

    while (c != EOF)
    {
	if (c == '\n') {
	    c = get_next_char();
	    continue;
	}

	if (isspace(c)) {
	    skip_rest_of_line();
	    c = get_next_char();
	    continue;
	}
        if (is_literate && !in_tex_lit_code) {
            if (c == '>') {
                c = fileGetc();
                if (c == ' ') {
                    c = get_next_char();
		    if (!isident(c)) {
			    skip_rest_of_line();
			    c = get_next_char();
			    continue;
		    }
                } else {
                    skip_rest_of_line();
                    c = get_next_char();
                    continue;
                }
            } else if (c == '\\') {
                int n = get_line(token);
                if (strncmp(token, "begin{code}", 11) == 0) {
                    in_tex_lit_code = 1;
                    c = get_next_char();
                    continue;
		} else {
		    if (n > 0 && token[n-1] != '\n')
			skip_rest_of_line();
		    else
			c = get_next_char();
		}
		continue;
            } else {
                skip_rest_of_line();
                c = get_next_char();
                continue;
            }   
        }
        if (is_literate && in_tex_lit_code && c == '\\') {
            if (strncmp(token, "end{code}", 9) == 0) {
                in_tex_lit_code = 0;
                c = get_next_char();
                continue;
            }
        }
	token[0] = c;
	token[1] = '\0';
	if (!isident(c)) {
		skip_rest_of_line();
		c = get_next_char();
		continue;
	}
	if (!get_token(token, 1)) {
		c = get_next_char();
		continue;
	}
	do {
	    if ((c = fileGetc()) == EOF)
		return;
	} while (c == ' ' || c == '\t');
	arg[0] = c;
	get_token(arg, 1);
	if (strcmp(token, "data") == 0 || strcmp(token, "newtype") == 0) {
	    add_tag(arg, K_TYPE, name);
	    c = inside_datatype(name);
	    continue;
	}
	if (strcmp(token, "type") == 0)
	    add_tag(arg, K_TYPE, name);
	else if (strcmp(token, "module") == 0)
	    add_tag(arg, K_MODULE, name);
	else if (strcmp(token, "instance") == 0 ||
		 strcmp(token, "foreign") == 0 ||
		 strcmp(token, "import") == 0)
	    ;
	else {
	    if (arg[0] != ':')
		add_tag(token, K_FUNCTION, name);
	}
	skip_rest_of_line();
	c = get_next_char();
    }
    vStringDelete(name);
}
Exemple #18
0
static int
bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
{
    int infd = 0, outfd = -1, bufsize = SYSREAD_BUFSIZE, count;
    char *outvar = NULL, *countvar = NULL, *inbuf;

    /* -i: input file descriptor if not stdin */
    if (OPT_ISSET(ops, 'i')) {
	infd = getposint(OPT_ARG(ops, 'i'), nam);
	if (infd < 0)
	    return 1;
    }

    /* -o: output file descriptor, else store in REPLY */
    if (OPT_ISSET(ops, 'o')) {
	if (*args) {
	    zwarnnam(nam, "no argument allowed with -o");
	    return 1;
	}
	outfd = getposint(OPT_ARG(ops, 'o'), nam);
	if (outfd < 0)
	    return 1;
    }

    /* -s: buffer size if not default SYSREAD_BUFSIZE */
    if (OPT_ISSET(ops, 's')) {
	bufsize = getposint(OPT_ARG(ops, 's'), nam);
	if (bufsize < 0)
	    return 1;
    }

    /* -c: name of variable to store count of transferred bytes */
    if (OPT_ISSET(ops, 'c')) {
	countvar = OPT_ARG(ops, 'c');
	if (!isident(countvar)) {
	    zwarnnam(nam, "not an identifier: %s", countvar);
	    return 1;
	}
    }

    if (*args) {
	/*
	 * Variable in which to store result if doing a plain read.
	 * Default variable if not specified is REPLY.
	 * If writing, only stuff we couldn't write is stored here,
	 * no default in that case (we just discard it if no variable).
	 */
	outvar = *args;
	if (!isident(outvar)) {
	    zwarnnam(nam, "not an identifier: %s", outvar);
	    return 1;
	}
    }

    inbuf = zhalloc(bufsize);

#if defined(HAVE_POLL) || defined(HAVE_SELECT)
    /* -t: timeout */
    if (OPT_ISSET(ops, 't'))
    {
# ifdef HAVE_POLL
	struct pollfd poll_fd;
	mnumber to_mn;
	int to_int, ret;

	poll_fd.fd = infd;
	poll_fd.events = POLLIN;

	to_mn = matheval(OPT_ARG(ops, 't'));
	if (errflag)
	    return 1;
	if (to_mn.type == MN_FLOAT)
	    to_int = (int) (1000 * to_mn.u.d);
	else
	    to_int = 1000 * (int)to_mn.u.l;

	while ((ret = poll(&poll_fd, 1, to_int)) < 0) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
		break;
	}
	if (ret <= 0) {
	    /* treat non-timeout error as error on read */
	    return ret ? 2 : 4;
	}
# else
	/* using select */
	struct timeval select_tv;
	fd_set fds;
	mnumber to_mn;
	int ret;

	FD_ZERO(&fds);
	FD_SET(infd, &fds);
	to_mn = matheval(OPT_ARG(ops, 't'));
	if (errflag)
	    return 1;

	if (to_mn.type == MN_FLOAT) {
	    select_tv.tv_sec = (int) to_mn.u.d;
	    select_tv.tv_usec =
		(int) ((to_mn.u.d - select_tv.tv_sec) * 1e6);
	} else {
	    select_tv.tv_sec = (int) to_mn.u.l;
	    select_tv.tv_usec = 0;
	}

	while ((ret = select(infd+1, (SELECT_ARG_2_T) &fds,
			     NULL, NULL,&select_tv)) < 1) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
		break;
	}
	if (ret <= 0) {
	    /* treat non-timeout error as error on read */
	    return ret ? 2 : 4;
	}
# endif
    }
#endif

    while ((count = read(infd, inbuf, bufsize)) < 0) {
	if (errno != EINTR || errflag || retflag || breaks || contflag)
	    break;
    }
    if (countvar)
	setiparam(countvar, count);
    if (count < 0)
	return 2;

    if (outfd >= 0) {
	if (!count)
	    return 5;
	while (count > 0) {
	    int ret;

	    ret = write(outfd, inbuf, count);
	    if (ret < 0) {
		if (errno == EINTR && !errflag &&
		    !retflag && !breaks && !contflag)
		    continue;
		if (outvar)
		    setsparam(outvar, metafy(inbuf, count, META_DUP));
		if (countvar)
		    setiparam(countvar, count);
		return 3;
	    }
	    inbuf += ret;
	    count -= ret;
	}
	return 0;
    }

    if (!outvar)
	    outvar = "REPLY";
    /* do this even if we read zero bytes */
    setsparam(outvar, metafy(inbuf, count, META_DUP));

    return count ? 0 : 5;
}
Exemple #19
0
static void pibdump (struct _file_ const * file, char const * schema, unsigned extent, flag_t flags) 

{
	unsigned offset = 0;
	signed indent = 0;
	signed length = 0;
	unsigned lineno = 1;
	char symbol [0x0100];
	char string [0x0400];
	char * sp;
	signed c;
	output (indent++, "<%s xmlns:xsi='%s' xsi:noNamespaceSchemaLocation='%s'>", DATA_OBJECT, XML_NAMESPACE, schema);
	while ((c = getc (stdin)) != EOF) 
	{
		if ((c == '#') || (c == ';')) 
		{
			do 
			{
				c = getc (stdin);
			}
			while (nobreak (c));
		}
		if (isspace (c)) 
		{
			if (c == '\n') 
			{
				lineno++;
			}
			continue;
		}
		while (isdigit (c)) 
		{
			length *= 10;
			length += c - '0';
			c = getc (stdin);
		}
		while (isblank (c)) 
		{
			c = getc (stdin);
		}
		sp = symbol;
		if (isalpha (c) || (c == '_')) 
		{
			do 
			{
				*sp++ = (char)(c);
				c = getc (stdin);
			}
			while (isident (c));
		}
		*sp = (char)(0);
		while (isblank (c)) 
		{
			c = getc (stdin);
		}
		if (c == '[') 
		{

#if 0

			*sp++ = (char)(c);

#endif

			c = getc (stdin);
			while (isblank (c)) 
			{
				c = getc (stdin);
			}
			while (isdigit (c)) 
			{

#if 0

				*sp++ = (char)(c);

#endif

				c = getc (stdin);
			}
			while (isblank (c)) 
			{
				c = getc (stdin);
			}
			if (c != ']') 
			{
				error (1, EINVAL, "Have '%c' but need ']'", c);
			}

#if 0

			*sp++ = (char)(c);

#endif

			c = getc (stdin);
		}
		*sp = (char)(0);
		while (isblank (c)) 
		{
			c = getc (stdin);
		}
		sp = string;
		while (nobreak (c)) 
		{
			*sp++ = (char)(c);
			c = getc (stdin);
		}
		*sp = (char)(0);
		if (length > 0) 
		{

#if defined (WIN32)

			byte * buffer = (byte *)(emalloc (length));

#else

			byte buffer [length];

#endif

			if (read (file->file, buffer, length) == length) 
			{
				output (indent++, "<%s name='%s'>", DATA_MEMBER, symbol);

#if 0

				if (*string) 
				{
					output (indent++, "<text>");
					output (indent, "%s", string);
					output (indent--, "</text>");
				}

#endif

				output (indent++, "<%s>", DATA_OFFSET);
				output (indent, "%04X", offset);
				output (indent--, "</%s>", DATA_OFFSET);
				output (indent++, "<%s>", DATA_LENGTH);
				output (indent, "%d", length);
				output (indent--, "</%s>", DATA_LENGTH);
				output (indent++, "<%s>", DATA_MEMORY);
				for (c = 0; c < indent; c++) 
				{
					printf ("\t");
				}
				for (c = 0; c < length; c++) 
				{
					printf ("%02X", buffer [c]);
				}
				printf ("\n");
				output (indent--, "</%s>", DATA_MEMORY);
				output (indent--, "</%s>", DATA_MEMBER);
			}

#if defined (WIN32)

			free (buffer);

#endif

		}
		offset += length;
		length = 0;
	}
	output (indent--, "</%s>", DATA_OBJECT);
	if (_allclr (flags, PIB_SILENCE)) 
	{
		if (offset != extent) 
		{
			error (0, 0, "file %s is %d not %d bytes", file->name, extent, offset);
		}
	}
	return;
}
Exemple #20
0
const unsigned char*
do_action( const unsigned char* action, CIStream* args, COStream out) {
    const unsigned char* as;
    unsigned char ac;
    int argn = 0;

    as = action;
    if ( as != NULL )
        for ( ; ; ) {
            ac = *as++;
            switch (ac) {
            case PT_END:
                return as-1;
            case PT_SEPARATOR:
                return as;
            case PT_PUT_ARG: {
                CIStream arg = args[ (*as++) - 1 ];
                cis_rewind(arg);
                cos_copy_input_stream(out,arg);
                break;
            }
            case PT_ONE_OPT:
                cos_putch(out,arg_char);
                break;

            case PT_DOMAIN: {
                CIStream inbuf;
                Pattern save_rule = current_rule;
#if MAX_DOMAINS < 256
                int domain = *as++ - 1;
#else
                /* Get domain index as 14 bit little endian number */
                int domain = ((unsigned char)*as++)&0x7f;
                domain = ((((unsigned char)*as++)&0x7f)<<7) | domain;
#endif
                if ( as[0] == PT_VAR1 ||
                        ( as[0] == PT_OP &&
                          ( as[1] == OP_VAR || as[1] == OP_VAR_DFLT ) ) ) {
                    /* for safety, copy the variable's value in case it is
                       changed during translation.  */
                    COStream outbuf;
                    outbuf = make_buffer_output_stream();
                    as = do_action( as, args, outbuf );
                    inbuf = convert_output_to_input( outbuf );
                }
                else /* optimized operand access */
                    inbuf = function_operand( &as, args );
#ifdef TRACE
                if ( trace_switch ) {
                    int n;
                    fprintf( stderr, "%12ld,%2d ",
                             cis_line(input_stream), cis_column(input_stream));
                    for ( n = trace_indent ; n > 0 ; n-- )
                        fputc(' ',stderr);
                    if ( cis_is_file(inbuf) ) {
                        const char* inpath = cis_pathname(inbuf);
                        if ( inpath == NULL )
                            inpath = "-";
                        fprintf( stderr, "@%s{@read{%s}}\n",
                                 domains[domain]->name, inpath);
                    }
                    else
                        fprintf( stderr, "@%s{%.60s}\n",
                                 domains[domain]->name, cis_whole_string(inbuf));
                    ++trace_indent;
                }
#endif
                if ( !translate( inbuf, domains[domain], out, NULL ) &&
                        cis_is_file(inbuf) && exit_status < EXS_FAIL )
                    exit_status = EXS_FAIL;
#ifdef TRACE
                if ( trace_switch ) {
                    --trace_indent;
                }
#endif
                current_rule = save_rule;
                cis_close(inbuf);
                break;
            }

            case PT_VAR1: {
                char vname[2];
                vname[0] = *as++;
                vname[1] = '\0';
                put_var(out, vname, FALSE);
                break;
            }

            case PT_LINE:
                cos_freshline(out);
                break;

            case PT_MATCHED_TEXT:
                do_action( current_rule->pattern, args, out );
                break;

            case PT_SPECIAL_ARG:
#if MAX_DOMAINS >= 256 /* advance one more since  2 bytes for domain index */
            case PT_RECUR:
#endif
                as++;
            case PT_REGEXP:
#if MAX_DOMAINS < 256
            case PT_RECUR:
#endif
                as++;
            case PT_MATCH_ANY:
            case PT_MATCH_ONE: {
                /* these will be encountered only when replaying the template as $0 */
                CIStream arg = args[ argn++ ];
                cis_rewind(arg);
                cos_copy_input_stream(out,arg);
                break;
            }

            case PT_AUX:
                as++;
                break;

            case PT_OP: {
                CIStream inbuf = NULL;
                enum Operators ac;
                ac = (enum Operators)*as++;
                switch(ac) {
                case OP_UNDEFINE:
                case OP_DEFINE: {
                    inbuf = function_operand( &as, args );
                    read_patterns(inbuf, "", ac==OP_UNDEFINE);
                    break;
                }

                case OP_SUBST: {
                    int d;
                    CIStream arg;
                    Pattern save_rule = current_rule;
                    arg = function_operand( &as, args );
                    d = read_patterns(arg," temp ",FALSE);
                    inbuf = function_operand( &as, args );
                    translate ( inbuf, domains[d], out, NULL );
                    current_rule = save_rule;
                    delete_domain(d);
                    cis_close(arg);
                    break;
                }

                case OP_VAR: {
                    inbuf = function_operand( &as, args );
                    put_var(out, cis_whole_string(inbuf), FALSE );
                    break;
                }
                case OP_VAR_DFLT: {
                    inbuf = function_operand( &as, args ); /* variable name */
                    if ( put_var(out, cis_whole_string(inbuf), TRUE ) )
                        as = skip_action(as); /* skip default value */
                    else as = do_action( as, args, out ); /* output default */
                    break;
                }

                case OP_SET: {
                    CIStream name;
                    name = function_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    set_var( cis_whole_string(name),
                             cis_whole_string(inbuf), cis_length(inbuf) );
                    cis_close(name);
                    break;
                }

                case OP_BIND: {
                    CIStream name;
                    name = function_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    bind_var( cis_whole_string(name),
                              cis_whole_string(inbuf), cis_length(inbuf) );
                    cis_close(name);
                    break;
                }
                case OP_UNBIND: {
                    CIStream name;
                    name = function_operand( &as, args );
                    unbind_var( cis_whole_string(name) );
                    cis_close(name);
                    break;
                }

                case OP_APPEND: {
                    CIStream name;
                    name = function_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    append_var( cis_whole_string(name),
                                cis_whole_string(inbuf), cis_length(inbuf) );
                    cis_close(name);
                    break;
                }

                case OP_INCR:
                case OP_DECR: {
                    CIStream name;
                    name = function_operand( &as, args );
                    incr_var( cis_whole_string(name), ac==OP_DECR? -1 : 1 );
                    cis_close(name);
                    break;
                }

                case OP_GETENV:
                case OP_GETENV_DEFAULT: {
                    CIStream dbuf = NULL;
                    char* value;
                    inbuf = function_operand( &as, args );
                    if ( ac == OP_GETENV_DEFAULT )
                        dbuf = function_operand( &as, args );
                    value = getenv(cis_whole_string(inbuf));
                    if ( value == NULL )
                        cos_copy_input_stream(out, dbuf);
                    else cos_puts(out, value);
                    cis_close(dbuf);
                    break;
                }

                case OP_ERR: {
                    static COStream err_stream = NULL;
                    if ( err_stream == NULL )
                        err_stream = make_file_output_stream(stderr,"stderr");
                    as = do_action( as, args, err_stream );
                    break;
                }

                case OP_OUT: {
                    as = do_action( as, args, output_stream );
                    break;
                }

                case OP_PATH:
                case OP_FILE: {
                    const char* path = cis_pathname(input_stream);
                    if ( path != NULL ) {
                        if ( ac == OP_FILE )
                            path = pathname_name_and_type(path);
                        cos_puts(out, path);
                    }
                    break;
                }
                case OP_OUTFILE: {
                    const char* opath;
                    opath = cos_pathname(out);
                    if ( opath == NULL )
                        opath = cos_pathname(output_stream);
                    cos_puts(out, opath);
                    break;
                }

                case OP_LINE: {
                    put_number(out, cis_line(input_stream));
                    break;
                }
                case OP_COL: {
                    put_number(out, cis_column(input_stream));
                    break;
                }
                case OP_OUTCOL: {
                    put_number(out, cos_column(output_stream));
                    break;
                }
                case OP_HELP:
                    usage();
                    break;
                case OP_VERSION:
                    cos_puts(out, Version);
                    break;

                case OP_DATE:
                case OP_TIME: {
                    time_t now;
                    struct tm* ts;
                    char tbuf [12];
                    now = time(NULL);
                    ts = localtime(&now);
                    if ( ac == OP_TIME )
                        sprintf(tbuf, "%02d:%02d:%02d",
                                ts->tm_hour, ts->tm_min, ts->tm_sec);
                    else sprintf(tbuf, "%02d/%02d/%d",
                                     ts->tm_mon + 1, ts->tm_mday, 1900 + ts->tm_year);
                    cos_puts(out, tbuf);
                    break;
                }
                case OP_DATIME: {
                    time_t now;
                    now = time(NULL);
                    put_datime( out, &now );
                    break;
                }
                case OP_MODTIME: {
                    time_t mtime;
                    mtime = cis_mod_time(input_stream);
                    if ( mtime != 0 )
                        put_datime( out, &mtime );
                    break;
                }
                case OP_PROBE: {
                    inbuf = function_operand( &as, args );
                    cos_putch(out, probe_pathname(cis_whole_string(inbuf)));
                    break;
                }

                case OP_READ: {
                    const char* pathname;
                    CIStream in;
                    inbuf = function_operand( &as, args );
                    pathname = cis_whole_string(inbuf);
                    close_output(pathname);
                    in = open_input_file(pathname,binary);
                    cos_copy_input_stream(out, in);
                    cis_close(in);
                    break;
                }

                case OP_WRITE: {
                    COStream oldout;
                    const char* pathname;
                    oldout = output_stream;
                    inbuf = function_operand( &as, args );
                    pathname = cis_whole_string(inbuf);
                    output_stream = find_output_file(pathname,TRUE);
                    as = do_action( as, args, output_stream );
                    output_stream = oldout;
                    break;
                }

                case OP_CLOSE: {
                    inbuf = function_operand( &as, args );
                    close_output(cis_whole_string(inbuf));
                    break;
                }

                case OP_COMBINEPATH:
                case OP_MERGEPATH: {
                    CIStream dir;
                    CIStream name;
                    CIStream typ;
                    dir = function_operand( &as, args );
                    name = function_operand( &as, args );
                    typ = function_operand( &as, args );
                    merge_pathnames( out, ac==OP_COMBINEPATH, cis_whole_string(dir),
                                     cis_whole_string(name),
                                     cis_whole_string(typ) );
                    cis_close(dir);
                    cis_close(name);
                    cis_close(typ);
                    break;
                }
                case OP_RELPATH: {
                    CIStream dir;
                    dir = function_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    cos_puts( out, relative_pathname(cis_whole_string(dir),
                                                     cis_whole_string(inbuf)) );
                    cis_close(dir);
                    break;
                }
                case OP_EXP_WILD: {
                    inbuf = function_operand( &as, args );
                    expand_wildcard ( cis_whole_string(inbuf), out );
                    break;
                }

                case OP_ADD:
                case OP_SUB:
                case OP_MUL:
                case OP_DIV:
                case OP_MOD:
                case OP_AND:
                case OP_OR: {
                    long x,y,z;
                    x = numeric_operand( &as, args );
                    y = numeric_operand( &as, args );
                    switch(ac) {
                    case OP_ADD:
                        z = x + y;
                        break;
                    case OP_SUB:
                        z = x - y;
                        break;
                    case OP_MUL:
                        z = x * y;
                        break;
                    case OP_DIV:
                        z = x / y;
                        break;
                    case OP_MOD:
                        z = x % y;
                        break;
                    case OP_AND:
                        z = x & y;
                        break;
                    case OP_OR:
                        z = x | y;
                        break;
                    default: /* can't happen; just to avoid compiler warning */
                        assert(FALSE);
                        z = 0;
                        break;
                    }
                    put_number(out,z);
                    break;
                }
                case OP_NOT:
                    put_number(out, ~ numeric_operand( &as, args ) );
                    break;

                case OP_RADIX: {
                    int from, to;
                    unsigned long value;
                    char* string;
                    char* end;
                    const char* fmt;
                    char buf[24]; /* enough for 64 bits in octal */
                    from = (int)numeric_operand( &as, args );
                    to = (int)numeric_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    string = cis_whole_string(inbuf);
                    value = strtoul( string, &end, from );
                    if ( *end != '\0' )
                        input_error ( input_stream, EXS_NUM,
                                      "Invalid argument for radix %d conversion: \"%.99s\"\n",
                                      from, string);
                    if ( to == 8 )
                        fmt = "%lo";
                    else if ( to == 16 )
                        fmt = "%lX";
                    else {
                        if ( to != 10 )
                            input_error ( input_stream, EXS_NUM,
                                          "Unsupported radix: %d\n", to);
                        while ( isspace(string[0]) )
                            string++;
                        fmt = (string[0]=='-') ? "%ld" : "%lu";
                    }
                    sprintf(buf, fmt, value);
                    cos_puts(out, buf);
                    break;
                }

                case OP_STR_CMP:
                case OP_STRI_CMP: {	/* string comparison */
                    CIStream x = function_operand( &as, args );
                    CIStream y = function_operand( &as, args );
                    const char* xs = cis_whole_string(x);
                    const char* ys = cis_whole_string(y);
                    int cmp;
                    cmp = ac == OP_STRI_CMP ? stricmp(xs, ys) : strcmp(xs, ys);
                    cis_close(x);
                    cis_close(y);
                    as = do_cmp( cmp, as, args, out);
                    break;
                }
                case OP_NUM_CMP: {	/* numeric comparison */
                    long x = numeric_operand( &as, args );
                    long y = numeric_operand( &as, args );
                    int cmp;
                    if ( x < y )
                        cmp = -1;
                    else if ( x == y )
                        cmp = 0;
                    else cmp = 1;
                    as = do_cmp( cmp, as, args, out);
                    break;
                }

                case OP_LENGTH: {
                    inbuf = function_operand( &as, args );
                    put_number(out, cis_length(inbuf));
                    break;
                }

                case OP_TAB: {
                    int col;
                    col = (int)numeric_operand( &as, args );
                    cos_spaces(out, col - (int)cos_column(out));
                    break;
                }

                case OP_WRAP: {
                    unsigned length;
                    unsigned col;
                    inbuf = function_operand( &as, args );
                    length = cis_length(inbuf);
                    col = cos_column(out);
                    if ( ( ((int)(col + length)) > wrap_column &&
                            col > wrap_indent_length ) ||
                            ( col <= 1 && length > 0 ) ) {
                        cos_freshline(out);
                        cos_puts(out, wrap_indent);
                        skip_whitespace(inbuf);
                    }
                    cos_copy_input_stream(out, inbuf);
                    break;
                }

                case OP_SET_WRAP: {
                    wrap_column = (int)numeric_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    if ( wrap_indent != NULL )
                        free(wrap_indent);
                    wrap_indent_length = cis_length(inbuf);
                    wrap_indent = str_dup_len( cis_whole_string(inbuf),
                                               wrap_indent_length );
                    break;
                }

                case OP_RIGHT:
                case OP_LEFT:
                case OP_CENTER: { /* justify value in fixed-length field */
                    int field_length, string_length, left_pad, right_pad;
                    field_length = (int)numeric_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    string_length = cis_length(inbuf);
                    left_pad = field_length - string_length;
                    right_pad = 0;
                    if ( left_pad < 0 )
                        left_pad = 0;
                    if ( ac == OP_LEFT ) {
                        right_pad = left_pad;
                        left_pad = 0;
                    }
                    else if ( ac == OP_CENTER ) {
                        left_pad = left_pad / 2;
                        right_pad = field_length - string_length - left_pad;
                    }
                    cos_spaces(out, left_pad);
                    cos_copy_input_stream(out, inbuf);
                    cos_spaces(out, right_pad);
                    break;
                }

                case OP_FILL_RIGHT:
                case OP_FILL_LEFT:
                case OP_FILL_CENTER: { /* justify value in fixed-length field */
                    int field_length, string_length, left_pad, right_pad;
                    CIStream background;
                    int i;
                    background = function_operand( &as, args );
                    field_length = cis_length(background);
                    inbuf = function_operand( &as, args );
                    string_length = cis_length(inbuf);
                    left_pad = field_length - string_length;
                    right_pad = 0;
                    if ( left_pad < 0 )
                        left_pad = 0;
                    if ( ac == OP_FILL_LEFT ) {
                        right_pad = left_pad;
                        left_pad = 0;
                    }
                    else if ( ac == OP_FILL_CENTER ) {
                        left_pad = left_pad / 2;
                        right_pad = field_length - string_length - left_pad;
                    } else assert( ac == OP_FILL_RIGHT );
                    for ( i = left_pad ; i > 0 ; i-- )
                        cos_putch(out, cis_getch(background));
                    cos_copy_input_stream(out, inbuf);
                    if ( right_pad > 0 ) {
                        for ( i = string_length ; i > 0 ; i-- )
                            (void)cis_getch(background);
                        cos_copy_input_stream(out, background);
                    }
                    cis_close(background);
                    break;
                }

                case OP_SUBSTRING: {
                    int skip_length, result_length, string_length;
                    skip_length = (int)numeric_operand( &as, args );
                    result_length = (int)numeric_operand( &as, args );
                    inbuf = function_operand( &as, args );
                    string_length = cis_length(inbuf);
                    if ( skip_length <= string_length ) {
                        if ( skip_length < 0 )
                            skip_length = 0;
                        if ( (skip_length + result_length) > string_length )
                            result_length = string_length - skip_length;
                        cos_put_len(out, cis_whole_string(inbuf) + skip_length,
                                    result_length);
                    }
                    break;
                }

                case OP_DOWNCASE:
                case OP_UPCASE: {
                    int cc;
                    inbuf = function_operand( &as, args );
                    while ( (cc = cis_getch(inbuf)) != EOF )
                        cos_putch(out, ac==OP_DOWNCASE ? tolower(cc) : toupper(cc) );
                    break;
                }

                case OP_CHARINT:
                    inbuf = function_operand( &as, args );
                    put_number(out, cis_getch(inbuf));
                    break;
                case OP_INTCHAR:
                    cos_putch(out, (char)numeric_operand( &as, args ));
                    break;

                case OP_REVERSE: {
                    int len;
                    const char* start;
                    const char* ip;
                    inbuf = function_operand( &as, args );
                    len = cis_length(inbuf);
                    start = cis_whole_string(inbuf);
                    for ( ip = start+len-1 ; ip >= start ; ip-- )
                        cos_putch(out, *ip);
                    break;
                }

                case OP_SHELL: {
                    const char* command;
                    inbuf = function_operand( &as, args );
                    command = cis_whole_string(inbuf);
                    fflush(stdout);
                    if ( system( command ) < 0 ) {
                        input_error ( input_stream, EXS_SHELL,
                                      "Failed shell command \"%.20s...\":\n", command );
                        perror("system");
                    }
                    break;
                }

                case OP_EXIT:
                    translation_status = Translate_Exited;
                    break;

                case OP_FAIL:
                    translation_status = Translate_Failed;
                    break;

                case OP_END_OR_FAIL:
                    /* ideally this should be testing whether the input stream
                       has been advanced, but that is not so easy. */
                    translation_status =
                        ( cis_out_length(out) == 0 )? Translate_Failed : Translate_Exited;
                    break;

                case OP_EXIT_STATUS:
                    exit_status = (Exit_States)(int)numeric_operand( &as, args );
                    break;

                case OP_ABORT:
                    exit((int)(exit_status > EXS_FAIL ? exit_status : EXS_FAIL ));
                    break;

                case OP_GET_SWITCH:
                case OP_SET_SWITCH: {
                    const char* name;
                    int* valpt;
                    inbuf = function_operand( &as, args );
                    name = cis_whole_string(inbuf);
                    valpt = find_switch(name);
                    if ( valpt == NULL ) {
                        input_error(input_stream, EXS_UNDEF,
                                    "Undefined switch name \"%.99s\"\n", name );
                        if ( ac == OP_SET_SWITCH )
                            (void)numeric_operand( &as, args );
                    }
                    else {
                        if ( ac == OP_SET_SWITCH )
                            *valpt = (int)numeric_operand( &as, args );
                        else
                            put_number( out, *valpt );
                    }
                    break;
                }

                case OP_SET_PARM: {
                    const char* name;
                    CIStream val;
                    inbuf = function_operand( &as, args );
                    name = cis_whole_string(inbuf);
                    val = function_operand( &as, args );
                    if ( !set_parm( name, cis_whole_string(val) ) )
                        input_error(input_stream, EXS_UNDEF,
                                    "Undefined parameter name \"%.99s\"\n", name );
                    cis_close(val);
                    break;
                }

                case OP_SYNTAX: {
                    const char* type;
                    const char* charset;
                    CIStream val;
                    inbuf = function_operand( &as, args );
                    val = function_operand( &as, args );
                    charset = cis_whole_string(val);
                    for ( type = cis_whole_string(inbuf) ; *type != '\0' ; type++ ) {
                        const char* chars;
                        char c[2];
                        if ( type[1] == '\0' )
                            chars = charset;
                        else {
                            c[0] = *charset++;
                            c[1] = '\0';
                            chars = c;
                        }
                        if ( !set_syntax(type[0], chars) )
                            input_error(input_stream, EXS_UNDEF,
                                        "Undefined syntax type \"%.99s\"\n", type );
                    }
                    cis_close(val);
                    break;
                }

                case OP_DEFAULT_SYNTAX:
                    initialize_syntax();
                    break;

#ifndef MSDOS
                case OP_LOCALE: {
                    const char* lname;
                    inbuf = function_operand( &as, args );
                    lname = cis_whole_string(inbuf);
                    if ( setlocale(LC_ALL, lname) == NULL )
                        input_error(input_stream, EXS_UNDEF,
                                    "Undefined locale \"%.99s\"\n", lname );
                    break;
                }
#endif

                case OP_REPEAT: {
                    long n = numeric_operand( &as, args );
                    if ( n <= 0 )
                        as = skip_action(as);
                    else {
                        const unsigned char* start = as;
                        for ( ; n > 0 ; n-- )
                            as = do_action( start, args, out );
                    }
                    break;
                }

                case OP_QUOTE: {
                    inbuf = function_operand( &as, args );
                    quoted_copy( inbuf, out );
                    break;
                }
                default:
                    fprintf(stderr, "Undefined op in action: %d\n", (int)ac);
                    break;

                } /* end switch on ops */
                cis_close(inbuf);
                break;
                } /* end PT_OP */

            case PT_WORD_DELIM:
            case PT_ID_DELIM:
                /* Ignore if in expansion of "$0" */
                if ( current_rule == NULL || action != current_rule->pattern ) {
                    /* output a space if needed as a delimiter */
                    int prevch = cos_prevch(out);
                    if ( prevch != EOF )
                        if ( ac == PT_ID_DELIM ? isident(prevch) : isalnum(prevch) )
                            cos_putch(out,' ');
                }
                break;
#if 0   /* not needed now */
            case PT_ARG_DELIM:
                if ( cos_prevch(out) != Arg_Delim )
                    cos_putch(out,Arg_Delim);
                break;
#endif

            case PT_SPACE: {
                /* output a space if the last character is not white space */
                int prevch = cos_prevch(out);
                if ( !isspace(prevch) )
                    cos_putch(out,' ');
                break;
            }

            case PT_SKIP_WHITE_SPACE:
                break;

            case PT_QUOTE:		/* use next character literally */
                ac = *as++;
            /* and fall-through */
            default:
                cos_putch(out, ac);
            } /* end switch ac */
        } /* end for */
    /* can't ever get here, but return to avoid Gnu compiler warning. */
    return as;
}
Exemple #21
0
static int
bin_zsystem_flock(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
    int cloexec = 1, unlock = 0, readlock = 0;
    time_t timeout = 0;
    char *fdvar = NULL;
#ifdef HAVE_FCNTL_H
    struct flock lck;
    int flock_fd, flags;
#endif

    while (*args && **args == '-') {
	int opt;
	char *optptr = *args + 1, *optarg;
	args++;
	if (!*optptr || !strcmp(optptr, "-"))
	    break;
	while ((opt = *optptr)) {
	    switch (opt) {
	    case 'e':
		/* keep lock on "exec" */
		cloexec = 0;
		break;

	    case 'f':
		/* variable for fd */
		if (optptr[1]) {
		    fdvar = optptr + 1;
		    optptr += strlen(fdvar) - 1;
		} else if (*args) {
		    fdvar = *args++;
		}
		if (fdvar == NULL || !isident(fdvar)) {
		    zwarnnam(nam, "flock: option %c requires a variable name",
			     opt);
		    return 1;
		}
		break;

	    case 'r':
		/* read lock rather than read-write lock */
		readlock = 1;
		break;

	    case 't':
		/* timeout in seconds */
		if (optptr[1]) {
		    optarg = optptr + 1;
		    optptr += strlen(optarg) - 1;
		} else if (!*args) {
		    zwarnnam(nam, "flock: option %c requires a numeric timeout",
			     opt);
		    return 1;
		} else {
		    optarg = *args++;
		}
		timeout = (time_t)mathevali(optarg);
		break;

	    case 'u':
		/* unlock: argument is fd */
		unlock = 1;
		break;

	    default:
		zwarnnam(nam, "flock: unknown option: %c", *optptr);
		return 1;
	    }
	    optptr++;
	}
    }


    if (!args[0]) {
	zwarnnam(nam, "flock: not enough arguments");
	return 1;
    }
    if (args[1]) {
	zwarnnam(nam, "flock: too many arguments");
	return 1;
    }

#ifdef HAVE_FCNTL_H
    if (unlock) {
	flock_fd = (int)mathevali(args[0]);
	if (zcloselockfd(flock_fd) < 0) {
	    zwarnnam(nam, "flock: file descriptor %d not in use for locking",
		     flock_fd);
	    return 1;
	}
	return 0;
    }

    if (readlock)
	flags = O_RDONLY | O_NOCTTY;
    else
	flags = O_RDWR | O_NOCTTY;
    if ((flock_fd = open(unmeta(args[0]), flags)) < 0) {
	zwarnnam(nam, "failed to open %s for writing: %e", args[0], errno);
	return 1;
    }
    flock_fd = movefd(flock_fd);
    if (flock_fd == -1)
	return 1;
#ifdef FD_CLOEXEC
    if (cloexec)
    {
	long fdflags = fcntl(flock_fd, F_GETFD, 0);
	if (fdflags != (long)-1)
	    fcntl(flock_fd, F_SETFD, fdflags | FD_CLOEXEC);
    }
#endif
    addlockfd(flock_fd, cloexec);

    lck.l_type = readlock ? F_RDLCK : F_WRLCK;
    lck.l_whence = SEEK_SET;
    lck.l_start = 0;
    lck.l_len = 0;  /* lock the whole file */

    if (timeout > 0) {
	time_t end = time(NULL) + (time_t)timeout;
	while (fcntl(flock_fd, F_SETLK, &lck) < 0) {
	    if (errflag)
		return 1;
	    if (errno != EINTR && errno != EACCES && errno != EAGAIN) {
		zwarnnam(nam, "failed to lock file %s: %e", args[0], errno);
		return 1;
	    }
	    if (time(NULL) >= end)
		return 2;
	    sleep(1);
	}
    } else {
	while (fcntl(flock_fd, F_SETLKW, &lck) < 0) {
	    if (errflag)
		return 1;
	    if (errno == EINTR)
		continue;
	    zwarnnam(nam, "failed to lock file %s: %e", args[0], errno);
	    return 1;
	}
    }

    if (fdvar)
	setiparam(fdvar, flock_fd);

    return 0;
#else /* HAVE_FCNTL_H */
    zwarnnam(nam, "flock: not implemented on this system");
    return 255;
#endif /* HAVE_FCNTL_H */
}
Exemple #22
0
static void function (file const * file, off_t extent, flag_t flags)

{
	unsigned object = 0;
	unsigned lineno = 0;
	unsigned offset = 0;
	unsigned length = 0;
	char memory [_ADDRSIZE +  1];
	char symbol [_NAMESIZE];
	char string [_LINESIZE];
	char * sp;
	signed c;
	while ((c = getc (stdin)) != EOF)
	{
		if ((c == '#') || (c == ';'))
		{
			do 
			{
				c = getc (stdin);
			}
			while (nobreak (c));
			lineno++;
			continue;
		}
		if (isspace (c))
		{
			if (c == '\n')
			{
				lineno++;
			}
			continue;
		}
		length = 0;
		while (isdigit (c))
		{
			length *= 10;
			length += c - '0';
			c = getc (stdin);
		}
		while (isblank (c))
		{
			c = getc (stdin);
		}
		sp = symbol;
		if (isalpha (c) || (c == '_'))
		{
			do 
			{
				* sp++ = (char) (c);
				c = getc (stdin);
			}
			while (isident (c));
		}
		while (isblank (c))
		{
			c = getc (stdin);
		}
		if (c == '[')
		{
			* sp++ = (char) (c);
			c = getc (stdin);
			while (isblank (c))
			{
				c = getc (stdin);
			}
			while (isdigit (c))
			{
				* sp++ = (char) (c);
				c = getc (stdin);
			}
			while (isblank (c))
			{
				c = getc (stdin);
			}
			* sp = (char) (0);
			if (c != ']')
			{
				error (1, EINVAL, "Have '%s' without ']' on line %d", symbol, lineno);
			}
			* sp++ = (char) (c);
			c = getc (stdin);
		}
		* sp = (char) (0);
		while (isblank (c))
		{
			c = getc (stdin);
		}
		sp = string;
		while (nobreak (c))
		{
			* sp++ = (char) (c);
			c = getc (stdin);
		}
		* sp = (char) (0);
		if (length)
		{
			byte buffer [length];
			if (read (file->file, buffer, length) == (signed) (length))
			{
				if (! object++)
				{
					for (c = 0; c < _ADDRSIZE +  65; c++)
					{
						putc ('-', stdout);
					}
					putc ('\n', stdout);
				}
				printf ("%s %u %s\n", hexoffset (memory, sizeof (memory), offset), length, symbol);
				hexview (buffer, offset, length, stdout);
				for (c = 0; c < _ADDRSIZE +  65; c++)
				{
					putc ('-', stdout);
				}
				putc ('\n', stdout);
			}
		}
		offset += length;
		lineno++;
	}
	if (_allclr (flags, ODD_SILENCE))
	{
		if (offset != (unsigned) (extent))
		{
			error (0, 0, "%s has %u bytes, not " OFF_T_SPEC " bytes.", file->name, offset, extent);
		}
	}
	return;
}
Exemple #23
0
/*
 * scanner() breaks expression[] into lexical units, storing them in token[].
 *   The total number of tokens found is returned as the function
 *   value.  Scanning will stop when '\0' is found in expression[], or
 *   when token[] is full.  extend_input_line() is called to extend
 *   expression array if needed.
 *
 *       Scanning is performed by following rules:
 *
 *      Current char    token should contain
 *     -------------    -----------------------
 *      1.  alpha,_     all following alpha-numerics
 *      2.  digit       0 or more following digits, 0 or 1 decimal point,
 *                              0 or more digits, 0 or 1 'e' or 'E',
 *                              0 or more digits.
 *      3.  ^,+,-,/     only current char
 *          %,~,(,)
 *          [,],;,:,
 *          ?,comma
 *          $           
 *      4.  &,|,=,*     current char; also next if next is same
 *      5.  !,<,>       current char; also next if next is =
 *      6.  ", '        all chars up until matching quote
 *      7.  #           this token cuts off scanning of the line (DFK).
 *      8.  `           (command substitution: all characters through the
 *                      matching backtic are replaced by the output of
 *                      the contained command, then scanning is restarted.)
 * EAM Jan 2010:	Bugfix. No rule covered an initial period. This caused
 *			string concatenation to fail for variables whose first
 *			character is 'E' or 'e'.  Now we add a 9th rule:
 *	9.  .		A period may be a token by itself (string concatenation)
 *			or the start of a decimal number continuing with a digit
 *
 *                      white space between tokens is ignored
 */
int
scanner(char **expressionp, size_t *expressionlenp)
{
    int current;	/* index of current char in expression[] */
    char *expression = *expressionp;
    int quote;
    char brace;

    curly_brace_count = 0;

    for (current = t_num = 0; expression[current] != NUL; current++) {
	if (t_num + 1 >= token_table_size) {
	    /* leave space for dummy end token */
	    extend_token_table();
	}
	if (isspace((unsigned char) expression[current]))
	    continue;		/* skip the whitespace */
	token[t_num].start_index = current;
	token[t_num].length = 1;
	token[t_num].is_token = TRUE;	/* to start with... */

	if (expression[current] == '`') {
	    substitute(expressionp, expressionlenp, current);
	    expression = *expressionp;	/* expression might have moved */
	    current--;
	    continue;
	}
	/* allow _ to be the first character of an identifier */
	/* allow 8bit characters in identifiers */
	if (isalpha((unsigned char)expression[current])
	    || (expression[current] == '_')
	    || ALLOWED_8BITVAR(expression[current])) {
		while (isident(expression[current + 1]))
		    APPEND_TOKEN;

	} else if (isdigit((unsigned char) expression[current])) {
	    token[t_num].is_token = FALSE;
	    token[t_num].length = get_num(&expression[current]);
	    current += (token[t_num].length - 1);

	} else if (expression[current] == '.') {
	    /* Rule 9 */
	    if (isdigit((unsigned char)expression[current+1])) {
		token[t_num].is_token = FALSE;
		token[t_num].length = get_num(&expression[current]);
		current += (token[t_num].length - 1);
	    } /* do nothing if the . is a token by itself */

	} else if (expression[current] == LBRACE) {
	    int partial;
	    token[t_num].is_token = FALSE;
	    token[t_num].l_val.type = CMPLX;
	    partial = sscanf(&expression[++current], "%lf , %lf %c",
			&token[t_num].l_val.v.cmplx_val.real,
			&token[t_num].l_val.v.cmplx_val.imag,
			&brace);

	    if (partial <= 0) {
		curly_brace_count++;
		token[t_num++].is_token = TRUE;
		current--;
		continue;
	    }

	    if (partial != 3 || brace != RBRACE)
		int_error(t_num, "invalid complex constant");

	    token[t_num].length += 2;
	    while (expression[++current] != RBRACE) {
		token[t_num].length++;
		if (expression[current] == NUL)		/* { for vi % */
		    int_error(t_num, "no matching '}'");
	    }
	} else if (expression[current] == '\'' ||
		   expression[current] == '\"') {
	    token[t_num].length++;
	    quote = expression[current];
	    while (expression[++current] != quote) {
		if (!expression[current]) {
		    expression[current] = quote;
		    expression[current + 1] = NUL;
		    break;
		} else if (quote == '\"'
                           && expression[current] == '\\'
			   && expression[current + 1]) {
		    current++;
		    token[t_num].length += 2;
		} else if (quote == '\"' && expression[current] == '`') {
		    substitute(expressionp, expressionlenp, current);
		    expression = *expressionp;	/* it might have moved */
		    current--;
                } else if (quote == '\'' 
                           && expression[current+1] == '\''
                           && expression[current+2] == '\'') {
                    /* look ahead: two subsequent single quotes 
                     * -> take them in
                     */
                    current += 2;
                    token[t_num].length += 3;
		} else
		    token[t_num].length++;
	    }
	} else
	    switch (expression[current]) {
	    case '#':
#ifdef OLD_STYLE_CALL_ARGS
		/* FIXME: This ugly exception handles the old-style syntatic  */
		/* entity $# (number of arguments in "call" statement), which */
		/* otherwise would be treated as introducing a comment.       */
		if ((t_num == 0) ||
		    (gp_input_line[token[t_num-1].start_index] != '$'))
#endif
			goto endline;	/* ignore the rest of the line */
	    case '^':
	    case '+':
	    case '-':
	    case '/':
	    case '%':
	    case '~':
	    case '(':
	    case ')':
	    case '[':
	    case ']':
	    case ';':
	    case ':':
	    case '?':
	    case ',':
	    case '$':
		break;
	    case '}':		/* complex constants will not end up here */
		curly_brace_count--;
		break;
	    case '&':
	    case '|':
	    case '=':
	    case '*':
		if (expression[current] == expression[current + 1])
		    APPEND_TOKEN;
		break;
	    case '!':
	    case '>':
		if (expression[current + 1] == '=')
		    APPEND_TOKEN;
		if (expression[current + 1] == '>')
		    APPEND_TOKEN;
		break;
	    case '<':
		if (expression[current + 1] == '=')
		    APPEND_TOKEN;
		if (expression[current + 1] == '<')
		    APPEND_TOKEN;
		break;
	    default:
		int_error(t_num, "invalid character %c",expression[current]);
	    }
	++t_num;		/* next token if not white space */
    }

  endline:			/* comments jump here to ignore line */

/* Now kludge an extra token which points to '\0' at end of expression[].
   This is useful so printerror() looks nice even if we've fallen off the
   line. */

    token[t_num].start_index = current;
    token[t_num].length = 0;
    /* print 3+4  then print 3+  is accepted without
     * this, since string is ignored if it is not
     * a token
     */
    token[t_num].is_token = TRUE;
    return (t_num);
}
Exemple #24
0
static std::string selectorFromMethodDeclaration(std::string decl) {
    // Trim whitespace
    decl = trim(decl);
    
    if (decl.size() == 0)
        return std::string();
    
    // Determine if this method is class or instance
    bool isClassMethod = false;
    if (decl[0] == '+')
        isClassMethod = true;
    else if (decl[0] != '-')
        return std::string(); // Not a method decl
    
    // Find colon
    std::string sel;
    if (isClassMethod)
        sel.push_back('+');
    else
        sel.push_back('-');
    
    IgnoringStage ignoringStage = IgnoringStage_Start;
    
    bool isStart = true;
    long bracketCount = 0;
    long variableLength = 0;
    for (long i = 0, len = decl.size(); i < len; i++) {
        char c = decl[i];
        char next_c = i + 1 < len ? decl[i + 1] : '\0';
        
        if (c == '/' && next_c == '/') {
            // Oops it's a comment
            for (; i < len; i++) {
                char c1 = decl[i];
                char next_c1 = i + 1 < len ? decl[i + 1] : '\0';
                if (c1 == '\n' || (c1 == '\r' && next_c1 != '\n'))
                    break;
            }
            continue;
        }
        
        if (c == '/' && next_c == '*') {
            i += 2; // Don't allow /*/
            
            // Oops it's a comment
            for (; i < len; i++) {
                char c1 = decl[i];
                char next_c1 = i + 1 < len ? decl[i + 1] : '\0';
                if (c1 == '*' && next_c1 == '/')
                    break;
            }
            i++;
            continue;
        }
        
        if (ignoringStage == IgnoringStage_Start) {
//            printf("@start\n");
            
            if (isspace(c))
                continue;
            
            if (c == '-' || c == '+')
                continue;
            
            if (c == '(') {
                bracketCount++;
                ignoringStage = IgnoringStage_Brackets; // printf("->brackets\n");
                continue;
            }
            
            if (isident(c)) {
                ignoringStage = IgnoringStage_NotIgnoring; // printf("->selector\n");
                isStart = false;
                i--;
                continue;
            }
            
            return std::string(); // Not a method
        }
        if (ignoringStage == IgnoringStage_NotIgnoring) {
//            printf("@selector\n");
            
            variableLength = 0;
            
            if (isspace(c))
                continue;
            if (isident(c)) {
                sel.push_back(c);
                continue;
            }
            if (c == ':') {
                sel.push_back(c);
                ignoringStage = IgnoringStage_Colon; // printf("->colon\n");
                continue;
            }
            
            return std::string(); // Not a method
        }
        else if (ignoringStage == IgnoringStage_Colon) {
            // printf("@colon\n");
            
            if (isspace(c))
                continue;
            if (c == '(') {
                bracketCount++;
                ignoringStage = IgnoringStage_Brackets; // printf("->brackets\n");
                continue;
            }
            if (isident(c)) {
                ignoringStage = IgnoringStage_Variable; // printf("->variable\n");
                i--; // Redo this loop as a variable
                continue;
            }
            
            return std::string(); // Not a method
        }
        else if (ignoringStage == IgnoringStage_Brackets) {
//            printf("@brackets\n");
            
            if (c == '(') {
                bracketCount++;
                continue;
            }
            if (c == ')') {
                bracketCount--;
                if (bracketCount == 0) {
                    if (isStart) {
                        ignoringStage = IgnoringStage_NotIgnoring; // printf("->selector\n");
                        isStart = false;
                    }
                    else {
                        ignoringStage = IgnoringStage_Variable; // printf("->variable\n");
                    }
                }
                continue;
            }
            
            continue;
        }
        else if (ignoringStage == IgnoringStage_Variable) {
//            printf("@variable\n");
            
            if (isident(c)) {
                variableLength++;
                continue;
            }
            else {
                if (variableLength == 0)
                    return std::string(); // Not a method. Needs an argument
            }
            
            if (isspace(c)) {
                ignoringStage = IgnoringStage_NotIgnoring; // printf("->selector\n");
                continue;
            }
            
            if (c == ':') {
                sel.push_back(c);
                ignoringStage = IgnoringStage_Colon; // printf("->colon\n");
                continue;
            }
            
            return std::string(); // Not a method. Needs an argument
        }
    }
    return sel;
}
Exemple #25
0
/*
 - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 */
static int			/* 0 failure, 1 success */
regmatch(char *prog)
{
	register char *scan;	/* Current node. */
	char *next;		/* Next node. */
	extern char *strchr();

	scan = prog;
#ifdef DEBUG
	if (scan != NULL && regnarrate) {
		fprintf(stderr, "%s(\n", regprop(scan));
	}
#endif
	while (scan != NULL) {
#ifdef DEBUG
		if (regnarrate) {
			fprintf(stderr, "%s...\n", regprop(scan));
		}
#endif
		next = regnext(scan);

		switch (OP(scan)) {
		case BOL:
			if (reginput != regbol) {
				return(0);
			}
			break;
		case EOL:
			if (regpeek(0) != '\0' && regpeek(0) != '\n') {
				return(0);
			}
			break;
		case BEGWORD:
			/* Match if current char isident
			 * and previous char BOL or !ident */
			if ((regpeek(0) == 0 || !isident(regpeek(0))) ||
			    (reginput != regbol && isident(regpeek(-1)))) {
				return(0);
			}
			break;
		case ENDWORD:
			/* Match if previous char isident
			 * and current char EOL or !ident */
			if ((regpeek(0) != 0 && isident(regpeek(0))) ||
			    reginput == regbol ||
			    !isident(regpeek(-1))) {
 				return(0);
			}
 			break;
		case WHITESP:
			/* match single whitespace */
			if (regpeek(0) != 0 && !isspace(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case NWHITESP:
			/* don't match eol, or space or tab */
			if (regpeek(0) == 0 || isspace(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case ALNUM: /* includes _ */
			if (regpeek(0) == 0 || !isident(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case NALNUM:
			if (regpeek(0) == 0 || isident(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case DIGIT:
			if (regpeek(0) == 0 || !isdigit(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case NDIGIT:
			if (regpeek(0) == 0 || isdigit(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case PRINT:
			if (regpeek(0) == 0 ||
			    !(isprint(regpeek(0)) || isspace(regpeek(0)))) {
				return(0);
			}
			reginput++;
			break;
		case NPRINT:
			if (regpeek(0) == 0 || isprint(regpeek(0)) || isspace(regpeek(0))) {
				return(0);
			}
			reginput++;
			break;
		case ANY:
			if (regpeek(0) == '\0' || regpeek(0) == '\n') {
				return(0);
			}
			regseek(1);
			break;
		case EXACTLY: {
				register int len;
				register char *opnd;

				opnd = OPERAND(scan);
				/* Inline the first character, for speed. */
				if (*opnd != regpeek(0)) {
					return(0);
				}
				len = strlen(opnd);
				if (len > 1 &&
				    strncmp(opnd, reginput, len) != 0) {
					return(0);
				}
				regseek(len);
			}
			break;
		case ANYOF:
			if (strchr(OPERAND(scan), regpeek(0)) == NULL) {
				return(0);
			}
			regseek(1);
			break;
		case ANYBUT:
			if (strchr(OPERAND(scan), regpeek(0)) != NULL) {
				return(0);
			}
			regseek(1);
			break;
		case NOTHING:
			break;
		case BACK:
			break;
		case OPEN+1:
		case OPEN+2:
		case OPEN+3:
		case OPEN+4:
		case OPEN+5:
		case OPEN+6:
		case OPEN+7:
		case OPEN+8:
		case OPEN+9: {
				register int no;
				register char *save;

				no = OP(scan) - OPEN;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set startp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regstartp[no] == NULL) {
						regstartp[no] = save;
					}
					return(1);
				} else {
					return(0);
				}
			}
			break;
		case CLOSE+1:
		case CLOSE+2:
		case CLOSE+3:
		case CLOSE+4:
		case CLOSE+5:
		case CLOSE+6:
		case CLOSE+7:
		case CLOSE+8:
		case CLOSE+9: {
				register int no;
				register char *save;

				no = OP(scan) - CLOSE;
				save = reginput;

				if (regmatch(next)) {
					/*
					 * Don't set endp if some later
					 * invocation of the same parentheses
					 * already has.
					 */
					if (regendp[no] == NULL) {
						regendp[no] = save;
					}
					return(1);
				} else {
					return(0);
				}
			}
			break;
		case BRANCH: {
				register char *save;

				if (OP(next) != BRANCH) {	/* No choice. */
					next = OPERAND(scan);	/* Avoid recursion. */
				} else {
					do {
						save = reginput;
						if (regmatch(OPERAND(scan))) {
							return(1);
						}
						reginput = save;
						scan = regnext(scan);
					} while (scan != NULL && OP(scan) == BRANCH);
					return(0);
					/* NOTREACHED */
				}
			}
			break;
		case STAR:
		case PLUS: {
				register char nextch;
				register int no;
				register char *save;
				register int min;

				/*
				 * Lookahead to avoid useless match attempts
				 * when we know what character comes next.
				 */
				nextch = '\0';
				if (OP(next) == EXACTLY) {
					nextch = *OPERAND(next);
				}
				min = (OP(scan) == STAR) ? 0 : 1;
				save = reginput;
				no = regrepeat(OPERAND(scan));
				while (no >= min) {
					/* If it could work, try it. */
					if (nextch == '\0' || regpeek(0) == nextch) {
						if (regmatch(next)) {
							return(1);
						}
					}
					/* Couldn't or didn't -- back up. */
					no--;
					reginput = save + no;
				}
				return(0);
			}
			break;
		case MINMAX: {
				register char	*save;
				unsigned char	min;
				unsigned char	max;
				register int	no;

				next = OPERAND(scan);
				min = OP(next);
				next = OPERAND(next);
				max = OP(next);
				next = OPERAND(next);
				save = reginput;
				for (no = 0 ; no < min ; no++) {
					if (!regmatch(next)) {
						reginput = save;
						return(0);
					}
				}
				for ( ; no < max ; no++) {
					if (!regmatch(next)) {
						break;
					}
				}
				return(1);
			}
			break;
		case END:
			return(1);	/* Success! */
			break;
		default:
			SREerror("memory corruption");
			return(0);
			break;
		}

		scan = next;
	}

	/*
	 * We get here only if there's trouble -- normally "case END" is
	 * the terminating point.
	 */
	SREerror("corrupted pointers");
	return(0);
}
Exemple #26
0
/*
 - regrepeat - repeatedly match something simple, report how many
 */
static int
regrepeat(char *p)
{
	register int count = 0;
	register char *scan;
	register char *opnd;
	extern char *strchr();

	scan = reginput;
	opnd = OPERAND(p);
	switch (OP(p)) {
	case ANY:
		/* make sure '.' doesn't match a \n character */
		while (*scan != 0 && *scan != '\n') {
			count++;
			scan++;
		}
		break;
	case EXACTLY:
		while (*opnd == *scan) {
			count++;
			scan++;
		}
		break;
	case ANYOF:
		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
			count++;
			scan++;
		}
		break;
	case ANYBUT:
		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
			count++;
			scan++;
		}
		break;
	case WHITESP :
		while (*scan != 0 && isspace(*scan)) {
			count++;
			scan++;
		}
		break;
	case NWHITESP :
		while (*scan != 0 && !isspace(*scan)) {
			count++;
			scan++;
		}
		break;
	case DIGIT :
		while (*scan != 0 && isdigit(*scan)) {
			count++;
			scan++;
		}
		break;
	case NDIGIT :
		while (*scan != 0 && !isdigit(*scan)) {
			count++;
			scan++;
		}
		break;
	case ALNUM :
		while (*scan != 0 && isident(*scan)) {
			count++;
			scan++;
		}
		break;
	case NALNUM :
		while (*scan != 0 && !isident(*scan)) {
			count++;
			scan++;
		}
		break;
	case PRINT :
		while (*scan != 0 && (isprint(*scan) || isspace(*scan))) {
			count++;
			scan++;
		}
		break;
	case NPRINT :
		while (*scan != 0 && !(isprint(*scan) || isspace(*scan))) {
			count++;
			scan++;
		}
		break;
	default:		/* Oh dear.  Called inappropriately. */
		SREerror("internal foulup");
		count = 0;	/* Best compromise. */
		break;
	}
	reginput = scan;

	return(count);
}
Exemple #27
0
static int
bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
#ifdef HAVE_SELECT
    int i, fd, fdsetind = 0, fdmax = 0, fdcount;
    fd_set fdset[3];
    const char fdchar[3] = "rwe";
    struct timeval tv, *tvptr = NULL;
    char *outarray = "reply", **outdata, **outptr;
    char *outhash = NULL;
    LinkList fdlist;

    for (i = 0; i < 3; i++)
	FD_ZERO(fdset+i);

    for (; *args; args++) {
	char *argptr = *args, *endptr;
	zlong tempnum;
	if (*argptr == '-') {
	    for (argptr++; *argptr; argptr++) {
		switch (*argptr) {
		    /*
		     * Array name for reply, if not $reply.
		     * This gets set to e.g. `-r 0 -w 1' if 0 is ready
		     * for reading and 1 is ready for writing.
		     */
		case 'a':
		case 'A':
		    i = *argptr;
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (idigit(*argptr) || !isident(argptr)) {
			zwarnnam(nam, "invalid array name: %s", argptr);
			return 1;
		    }
		    if (i == 'a')
			outarray = argptr;
		    else
			outhash = argptr;
		    /* set argptr to next to last char because of increment */
		    while (argptr[1])
			argptr++;
		    break;

		    /* Following numbers indicate fd's for reading */
		case 'r':
		    fdsetind = 0;
		    break;

		    /* Following numbers indicate fd's for writing */
		case 'w':
		    fdsetind = 1;
		    break;

		    /* Following numbers indicate fd's for errors */
		case 'e':
		    fdsetind = 2;
		    break;

		    /*
		     * Get a timeout value in hundredths of a second
		     * (same units as KEYTIMEOUT).  0 means just poll.
		     * If not given, blocks indefinitely.
		     */
		case 't':
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (!idigit(*argptr)) {
			zwarnnam(nam, "number expected after -t");
			return 1;
		    }
		    tempnum = zstrtol(argptr, &endptr, 10);
		    if (*endptr) {
			zwarnnam(nam, "garbage after -t argument: %s",
				 endptr);
			return 1;
		    }
		    /* timevalue now active */
		    tvptr = &tv;
		    tv.tv_sec = (long)(tempnum / 100);
		    tv.tv_usec = (long)(tempnum % 100) * 10000L;

		    /* remember argptr is incremented at end of loop */
		    argptr = endptr - 1;
		    break;

		    /* Digits following option without arguments are fd's. */
		default:
		    if (handle_digits(nam, argptr, fdset+fdsetind,
				      &fdmax))
			return 1;
		}
	    }
	} else if (handle_digits(nam, argptr, fdset+fdsetind, &fdmax))
	    return 1;
    }

    errno = 0;
    do {
	i = select(fdmax, (SELECT_ARG_2_T)fdset, (SELECT_ARG_2_T)(fdset+1),
		   (SELECT_ARG_2_T)(fdset+2), tvptr);
    } while (i < 0 && errno == EINTR && !errflag);

    if (i <= 0) {
	if (i < 0)
	    zwarnnam(nam, "error on select: %e", errno);
	/* else no fd's set.  Presumably a timeout. */
	return 1;
    }

    /*
     * Make a linked list of all file descriptors which are ready.
     * These go into an array preceded by -r, -w or -e for read, write,
     * error as appropriate.  Typically there will only be one set
     * so this looks rather like overkill.
     */
    fdlist = znewlinklist();
    for (i = 0; i < 3; i++) {
	int doneit = 0;
	for (fd = 0; fd < fdmax; fd++) {
	    if (FD_ISSET(fd, fdset+i)) {
		char buf[BDIGBUFSIZE];
		if (outhash) {
		    /*
		     * Key/value pairs; keys are fd's (as strings),
		     * value is a (possibly improper) subset of "rwe".
		     */
		    LinkNode nptr;
		    int found = 0;

		    convbase(buf, fd, 10);
		    for (nptr = firstnode(fdlist); nptr; 
			 nptr = nextnode(nextnode(nptr))) {
			if (!strcmp((char *)getdata(nptr), buf)) {
			    /* Already there, add new character. */
			    void **dataptr = getaddrdata(nextnode(nptr));
			    char *data = (char *)*dataptr, *ptr;
			    found = 1;
			    if (!strchr(data, fdchar[i])) {
				strcpy(buf, data);
				for (ptr = buf; *ptr; ptr++)
				    ;
				*ptr++ = fdchar[i];
				*ptr = '\0';
				zsfree(data);
				*dataptr = ztrdup(buf);
			    }
			    break;
			}
		    }
		    if (!found) {
			/* Add new key/value pair. */
			zaddlinknode(fdlist, ztrdup(buf));
			buf[0] = fdchar[i];
			buf[1] = '\0';
			zaddlinknode(fdlist, ztrdup(buf));
		    }
		} else {
		    /* List of fd's preceded by -r, -w, -e. */
		    if (!doneit) {
			buf[0] = '-';
			buf[1] = fdchar[i];
			buf[2] = 0;
			zaddlinknode(fdlist, ztrdup(buf));
			doneit = 1;
		    }
		    convbase(buf, fd, 10);
		    zaddlinknode(fdlist, ztrdup(buf));
		}
	    }
	}
    }

    /* convert list to array */
    fdcount = countlinknodes(fdlist);
    outptr = outdata = (char **)zalloc((fdcount+1)*sizeof(char *));
    while (nonempty(fdlist))
	*outptr++ = getlinknode(fdlist);
    *outptr = NULL;
    /* and store in array parameter */
    if (outhash)
	sethparam(outhash, outdata);
    else
	setaparam(outarray, outdata);
    freelinklist(fdlist, NULL);

    return 0;
#else
    /* TODO: use poll */
    zerrnam(nam, "your system does not implement the select system call.");
    return 2;
#endif
}
Exemple #28
0
int main() {
	int fd=open("test.js",O_RDONLY);

	char buf[1024];
	int n=read(fd,buf,1024);
	int c,i,state='X',q,esc, last='X',pstate=0;
	for(;;) {
		for(i=0;i<n;i++) {
			c=buf[i];
			putchar(c);
			switch(state) {
			case 'X':
			state_X:
				state='X'; 
				if(c=='/') { state='/'; }
				else if(ispunctuation(c)) { parse(c); if(c==')') { last='E'; } else { last='P'; } }
				else if(isspace(c)) { state='W'; }
				else if(c=='\''||c=='"') { state='S'; q=c; esc=0; last='S'; }
				else if(isdigit(c)) { state='N'; last='N'; ident=b_ident; *ident++=c; }
				else if(isident(c)) { state='I'; last='I'; ident=b_ident; *ident++=c; }
				else { goto abort; }
				break;
			case 'W':
				if(isspace(c)) { /* nothing */ }
				else { goto state_X; }
				break;
			case 'I':
				if(isident(c)) { *ident++=c; }
				else { parse('I'); goto state_X; }
				break;
			case 'S':
				if(esc) { esc=0; }
				else if(c==q) { parse('S'); state='X'; }
				else if(c=='\\') { esc=1; }
				else { /* nothing */ }
				break;
			case 'N':
				if(isdigit(c) || c=='.') { *ident++=c; }
				else { parse('N'); goto state_X; }
				break;
			case '/':
				printf("\x1b[01;31m%c\x1b[00m" "\x1b[01;33m%.*s\x1b[00m",last,(int)(ident-b_ident),b_ident);
				if(c=='*') { state='C'; esc=0; }
				else if(c=='/') { state='c'; }
				else if(last!='N'&&last!='I'&&last!='E') { esc=0; state='R'; goto state_R; }
				else if(last=='I'&&strncmp(b_ident,"return",6)==0) { esc=0; state='R'; goto state_R; }
				else { parse('/'); goto state_X; }
				break;
			case 'R':
			state_R:
				if(esc) { esc=0; }
				else if(c=='\\') { esc=1; }
				else if(c=='/') { parse('R'); state='X'; }
				else { /* nothing */ }
				break;
			case 'C':
				if(esc) { if(c=='/') { state='X'; } else { esc=0; } }
				else if(c=='*') { esc=1; }
				else { /* nothing */ }
				break;
			case 'c':
				if(c=='\n'||c=='\r') { state='X'; }
				else { /* nothing */ }
				break;
			default:
				abort();
			}

			if(pstate!=state) { printf("\x1b[01;32m%c\x1b[00m",state); }
			pstate=state;
		}
		n=read(fd,buf,1024);
		if(n==0) break;
	}

	return 0;

	abort:
		printf("\n Abort: char '%c' state '%c'\n",c,state);
	return 1;
}
Exemple #29
0
static enum parse_error
parse_set_common(struct option *opt_tree, struct conf_parsing_state *state,
		 struct string *mirror, int is_system_conf, int want_domain)
{
	const unsigned char *domain_orig = NULL;
	size_t domain_len = 0;
	unsigned char *domain_copy = NULL;
	const unsigned char *optname_orig;
	size_t optname_len;
	unsigned char *optname_copy;

	skip_white(&state->pos);
	if (!*state->pos.look) return show_parse_error(state, ERROR_PARSE);

	if (want_domain) {
		domain_orig = state->pos.look;
		while (isident(*state->pos.look) || *state->pos.look == '*'
		       || *state->pos.look == '.' || *state->pos.look == '+')
			state->pos.look++;
		domain_len = state->pos.look - domain_orig;

		skip_white(&state->pos);
	}

	/* Option name */
	optname_orig = state->pos.look;
	while (is_option_name_char(*state->pos.look)
	       || *state->pos.look == '.')
		state->pos.look++;
	optname_len = state->pos.look - optname_orig;

	skip_white(&state->pos);

	/* Equal sign */
	if (*state->pos.look != '=')
		return show_parse_error(state, ERROR_PARSE);
	state->pos.look++; /* '=' */
	skip_white(&state->pos);
	if (!*state->pos.look)
		return show_parse_error(state, ERROR_VALUE);

	optname_copy = memacpy(optname_orig, optname_len);
	if (!optname_copy) return show_parse_error(state, ERROR_NOMEM);
	if (want_domain) {
		domain_copy = memacpy(domain_orig, domain_len);
		if (!domain_copy) {
			mem_free(optname_copy);
			return show_parse_error(state, ERROR_NOMEM);
		}
	}

	/* Option value */
	{
		struct option *opt;
		unsigned char *val;
		const struct conf_parsing_pos pos_before_value = state->pos;

		if (want_domain && *domain_copy) {
			struct option *domain_tree;

			domain_tree = get_domain_tree(domain_copy);
			if (!domain_tree) {
				mem_free(domain_copy);
				mem_free(optname_copy);
				skip_option_value(&state->pos);
				return show_parse_error(state, ERROR_NOMEM);
			}

			if (mirror) {
				opt = get_opt_rec_real(domain_tree,
						       optname_copy);
			} else {
				opt = get_opt_rec(opt_tree, optname_copy);
				if (opt) {
					opt = get_option_shadow(opt, opt_tree,
								domain_tree);
					if (!opt) {
						mem_free(domain_copy);
						mem_free(optname_copy);
						skip_option_value(&state->pos);
						return show_parse_error(state,
									ERROR_NOMEM);
					}
				}
			}
		} else {
			opt = mirror
				? get_opt_rec_real(opt_tree, optname_copy)
				: get_opt_rec(opt_tree, optname_copy);
		}
		if (want_domain)
			mem_free(domain_copy);
		domain_copy = NULL;
		mem_free(optname_copy);
		optname_copy = NULL;

		if (!opt || (opt->flags & OPT_HIDDEN)) {
			show_parse_error(state, ERROR_OPTION);
			skip_option_value(&state->pos);
			return ERROR_OPTION;
			/* TODO: Distinguish between two scenarios:
			 * - A newer version of ELinks has saved an
			 *   option that this version does not recognize.
			 *   The option must be preserved.  (This works.)
			 * - The user has added an option, saved
			 *   elinks.conf, restarted ELinks, deleted the
			 *   option, and is now saving elinks.conf again.
			 *   The option should be rewritten to "unset".
			 *   (This does not work yet.)
			 * In both cases, ELinks has no struct option
			 * for that name.  Possible fixes:
			 * - If the tree has OPT_AUTOCREATE, then
			 *   assume the user had created that option,
			 *   and rewrite it to "unset".  Otherwise,
			 *   keep it.
			 * - When the user deletes an option, just mark
			 *   it with OPT_DELETED, and keep it in memory
			 *   as long as OPT_TOUCHED is set.  */
		}

		if (!option_types[opt->type].read) {
			show_parse_error(state, ERROR_VALUE);
			skip_option_value(&state->pos);
			return ERROR_VALUE;
		}

		val = option_types[opt->type].read(opt, &state->pos.look,
						   &state->pos.line);
		if (!val) {
			/* The reader function failed.  Jump back to
			 * the beginning of the value and skip it with
			 * the generic code.  For the error message,
			 * use the line number at the beginning of the
			 * value, because the ending position is not
			 * interesting if there is an unclosed quote.  */
			state->pos = pos_before_value;
			show_parse_error(state, ERROR_VALUE);
			skip_option_value(&state->pos);
			return ERROR_VALUE;
		}

		if (!mirror) {
			/* loading a configuration file */
			if (!option_types[opt->type].set
			    || !option_types[opt->type].set(opt, val)) {
				mem_free(val);
				return show_parse_error(state, ERROR_VALUE);
			}
		} else if (is_system_conf) {
			/* scanning a file that will not be rewritten */
			struct option *flagsite = indirect_option(opt);

			if (!(flagsite->flags & OPT_DELETED)
			    && option_types[opt->type].equals
			    && option_types[opt->type].equals(opt, val))
				flagsite->flags &= ~OPT_MUST_SAVE;
			else
				flagsite->flags |= OPT_MUST_SAVE;
		} else {
			/* rewriting a configuration file */
			struct option *flagsite = indirect_option(opt);

			if (flagsite->flags & OPT_DELETED) {
				/* Replace the "set" command with an
				 * "unset" command.  */
				add_to_string(mirror, "unset ");
				add_bytes_to_string(mirror, optname_orig,
						    optname_len);
				state->mirrored = state->pos.look;
			} else if (option_types[opt->type].write) {
				add_bytes_to_string(mirror, state->mirrored,
						    pos_before_value.look
						    - state->mirrored);
				option_types[opt->type].write(opt, mirror);
				state->mirrored = state->pos.look;
			}
			/* Remember that the option need not be
			 * written to the end of the file.  */
			flagsite->flags &= ~OPT_MUST_SAVE;
		}
		mem_free(val);
	}

	return ERROR_NONE;
}
Exemple #30
0
void
vcc_Lexer(struct tokenlist *tl, struct source *sp)
{
	const char *p, *q;
	unsigned u;

	tl->src = sp;
	for (p = sp->b; p < sp->e; ) {

		/* Skip any whitespace */
		if (isspace(*p)) {
			p++;
			continue;
		}

		/* Skip '#.*\n' comments */
		if (*p == '#') {
			while (p < sp->e && *p != '\n')
				p++;
			continue;
		}

		/* Skip C-style comments */
		if (*p == '/' && p[1] == '*') {
			for (q = p + 2; q < sp->e; q++) {
				if (*q == '/' && q[1] == '*') {
					vsb_printf(tl->sb,
					    "/* ... */ comment contains /*\n");
					vcc_AddToken(tl, EOI, p, p + 2);
					vcc_ErrWhere(tl, tl->t);
					vcc_AddToken(tl, EOI, q, q + 2);
					vcc_ErrWhere(tl, tl->t);
					return;
				}
				if (*q == '*' && q[1] == '/') {
					p = q + 2;
					break;
				}
			}
			if (q < sp->e)
				continue;
			vcc_AddToken(tl, EOI, p, p + 2);
			vsb_printf(tl->sb,
			    "Unterminated /* ... */ comment, starting at\n");
			vcc_ErrWhere(tl, tl->t);
			return;
		}

		/* Skip C++-style comments */
		if (*p == '/' && p[1] == '/') {
			while (p < sp->e && *p != '\n')
				p++;
			continue;
		}

		/* Recognize inline C-code */
		if (*p == 'C' && p[1] == '{') {
			for (q = p + 2; q < sp->e; q++) {
				if (*q == '}' && q[1] == 'C') {
					vcc_AddToken(tl, CSRC, p, q + 2);
					break;
				}
			}
			if (q < sp->e) {
				p = q + 2;
				continue;
			}
			vcc_AddToken(tl, EOI, p, p + 2);
			vsb_printf(tl->sb,
			    "Unterminated inline C source, starting at\n");
			vcc_ErrWhere(tl, tl->t);
			return;
		}

		/* Recognize long-strings */
		if (*p == '{' && p[1] == '"') {
			for (q = p + 2; q < sp->e; q++) {
				if (*q == '"' && q[1] == '}') {
					vcc_AddToken(tl, CSTR, p, q + 2);
					break;
				}
			}
			if (q < sp->e) {
				p = q + 2;
				u = tl->t->e - tl->t->b;
				u -= 4;		/* {" ... "} */
				tl->t->dec = TlAlloc(tl, u + 1 );
				AN(tl->t->dec);
				memcpy(tl->t->dec, tl->t->b + 2, u);
				tl->t->dec[u] = '\0';
				continue;
			}
			vcc_AddToken(tl, EOI, p, p + 2);
			vsb_printf(tl->sb,
			    "Unterminated long-string, starting at\n");
			vcc_ErrWhere(tl, tl->t);
			return;
		}

		/* Match for the fixed tokens (see token.tcl) */
		u = vcl_fixed_token(p, &q);
		if (u != 0) {
			vcc_AddToken(tl, u, p, q);
			p = q;
			continue;
		}

		/* Match strings, with \\ and \" escapes */
		if (*p == '"') {
			for (q = p + 1; q < sp->e; q++) {
				if (*q == '"') {
					q++;
					break;
				}
				if (*q == '\r' || *q == '\n') {
					vcc_AddToken(tl, EOI, p, q);
					vsb_printf(tl->sb,
					    "Unterminated string at\n");
					vcc_ErrWhere(tl, tl->t);
					return;
				}
			}
			vcc_AddToken(tl, CSTR, p, q);
			if (vcc_decstr(tl))
				return;
			p = q;
			continue;
		}

		/* Match Identifiers */
		if (isident1(*p)) {
			for (q = p; q < sp->e; q++)
				if (!isident(*q))
					break;
			if (isvar(*q)) {
				for (; q < sp->e; q++)
					if (!isvar(*q))
						break;
				vcc_AddToken(tl, VAR, p, q);
			} else {
				vcc_AddToken(tl, ID, p, q);
			}
			p = q;
			continue;
		}

		/* Match numbers { [0-9]+ } */
		if (isdigit(*p)) {
			for (q = p; q < sp->e; q++)
				if (!isdigit(*q))
					break;
			vcc_AddToken(tl, CNUM, p, q);
			p = q;
			continue;
		}
		vcc_AddToken(tl, EOI, p, p + 1);
		vsb_printf(tl->sb, "Syntax error at\n");
		vcc_ErrWhere(tl, tl->t);
		return;
	}
}