void scan_file(char *filename) {
  FILE *fp = fopen(filename, "r");
  if (!fp) {
    printf("Can't open input file %s!\n", filename);
    exit(1);
  }

  int current_line = 0;
  int more_lines = true;
  while (more_lines) {
    int line_len = get_current_line_length(fp);
    {
      char *buf = malloc(line_len);
      char *starting_buf = buf;
      more_lines = read_line(fp, buf);
      current_line++;

      while (1) {
        Token *token = scan_string(&buf);
        if (!token) {
          break; 
        } 
        if (token->type == INVALID) {
          printf("Error: Unrecognized token '%s' in %s (row %i, col %i)\n", token->text, filename, current_line, (int)(buf - starting_buf)); 
          exit(1);
        }
        token_print(*token); 
        token_free(token);
      }
      free(buf - line_len);
    }
  }
}
示例#2
0
void TranslateLinksAndPrint(char* s) {
  static const char *href = "href='?in=";
  char *e, *tmp;
  while (1) {
    e = strstr(s, href);
    if (e == NULL) break;

    tmp = strndup(s, e - s);
    printf("%shref='#", tmp);
    free(tmp);
    e += strlen(href);

    s = strstr(e, "'>");
    if (s == NULL) return;  // should not happen

    tmp = strndup(e, s - e);
    // workaround bison bug
    if (tmp[strlen(tmp) - 1] == ';') {
      tmp[strlen(tmp) - 1] = 0;
    }
    scan_string(tmp);
    yyparse();
    free_scan_string();
    free(tmp);
  }
  printf("%s", s);
}
示例#3
0
/* Scan /proc/devices for a blockdevice (BLOCKDEV is 1) or a character
 * device (BLOCKDEV is 0) with a major number matching the major number of DEV.
 * When there is a match, store entry data in ENTRY and return 0. Return
 * non-zero otherwise. */
int
proc_dev_get_entry(dev_t device, int blockdev, struct proc_dev_entry* entry)
{
	struct file_buffer file;
	int rc;
	int scan_blockdev = 0;

	rc = get_file_buffer(&file, proc_dev_filename);
	if (rc)
		return rc;
	rc = -1;
	while (!eof(&file)) {
		if (scan_string(&file, "Block") == 0) {
			skip_line(&file);
			scan_blockdev = 1;
			continue;
		} else if (scan_dev_entry(&file, entry, scan_blockdev) == 0) {
			if ((major(entry->device) == major(device)) &&
			    blockdev == scan_blockdev) {
				rc = 0;
				break;
			}
			proc_dev_free_entry(entry);
		} else
			skip_line(&file);
	}
	free_file_buffer(&file);
	return rc;
}
示例#4
0
/******************************************************************
			scan()
See prlex.h for return values other than characters (i.e. > 256)
*******************************************************************/
int scan()
{
	ini_scan();
	getachar();
	if(Ch == EOF)
		return(EOF);
	switch(Ctype[Ch])
	{

	case DI:
		MY_ASSERT(isdigit(Ch)); /* double check */
	case SI:
		MY_ASSERT(isdigit(Ch) || Ch == '-' || Ch == '+');
		return(scan_number(Ch));

	case QU:
		MY_ASSERT(Ch == '"');
		scan_string();
		return(TOKEN_STRING);

	case BR:
		MY_ASSERT(Ch == ')' || Ch == '(');
		return(Ch);

#ifdef CLIPS_SYNTAX
	case QE:
		scan_identifier(?);
		return(TOKEN_VAR);
	case AL:
	case AU:
	case OT:
		scan_identifier(Ch);
		return(TOKEN_ATOM);
#else
	case AL:
		MY_ASSERT(islower(Ch));
		scan_identifier(Ch);
		return(TOKEN_ATOM);

	case US:
		MY_ASSERT(Ch == '_');

	case AU:
		scan_identifier(Ch);
		return(TOKEN_VAR);
#endif
	case CC:
		return(SCAN_ERR);
#ifdef  CHARACTER
	case AP:
		return(scan_character());
#endif
	default:
		return(Ch);
	}
}
示例#5
0
static PyObject *
Scan_str(Scan *self)
{        
    char scanstr[100];
    scan_string(self->scan, scanstr);
    
    char str[200];
    sprintf(str, "Scan: %s", scanstr);
    
    return  PyUnicode_FromString(str);
}
void Parser::scan_value(void) {
    int c = read_byte();
    switch (c) {
    case trace::TYPE_NULL:
    case trace::TYPE_FALSE:
    case trace::TYPE_TRUE:
        break;
    case trace::TYPE_SINT:
        scan_sint();
        break;
    case trace::TYPE_UINT:
        scan_uint();
        break;
    case trace::TYPE_FLOAT:
        scan_float();
        break;
    case trace::TYPE_DOUBLE:
        scan_double();
        break;
    case trace::TYPE_STRING:
        scan_string();
        break;
    case trace::TYPE_ENUM:
        scan_enum();
        break;
    case trace::TYPE_BITMASK:
        scan_bitmask();
        break;
    case trace::TYPE_ARRAY:
        scan_array();
        break;
    case trace::TYPE_STRUCT:
        scan_struct();
        break;
    case trace::TYPE_BLOB:
        scan_blob();
        break;
    case trace::TYPE_OPAQUE:
        scan_opaque();
        break;
    case trace::TYPE_REPR:
        scan_repr();
        break;
    case trace::TYPE_WSTRING:
        scan_wstring();
        break;
    default:
        std::cerr << "error: unknown type " << c << "\n";
        exit(1);
    case -1:
        break;
    }
}
示例#7
0
文件: empdb.c 项目: rohitsd1409/empdb
//input employee details from stdin
void get_emp_details(EMP_T **pp_to_e, int n)
{
	int i;

	assert(pp_to_e);
	
	for(i = 0; i < n; i++)
	{
		assert((*(pp_to_e + i)));
		assert((*(pp_to_e + i))->name);

		printf("\nEnter emp name: ");
		scan_string((*(pp_to_e + i))->name);
		printf("Enter emp id: ");
		scanf("%d",&(*(pp_to_e + i))->id);	
	}
}
示例#8
0
void Scanner::scan() {
	char token = file.get();
	while (token != EOF && error == -1) {
		switch (token) {
		case ',':
			scan_punctuation(token, Token::COMMA);
			break;
		case '.':
			scan_punctuation(token, Token::PERIOD);
			break;
		case '?':
			scan_punctuation(token, Token::Q_MARK);
			break;
		case '(':
			scan_punctuation(token, Token::LEFT_PAREN);
			break;
		case ')':
			scan_punctuation(token, Token::RIGHT_PAREN);
			break;
		case ':':
			scan_colon();
			break;
		case '#':
			scan_comment();
			break;
		case '\'':
			scan_string();
			break;
		case '\n':
			line++;
			break;
		default:
			scan_id(token);
			break;
		}
		token = file.get();
	}

	if (error == -1) {
		line++;
		add_token("", Token::END);
	}
}
示例#9
0
文件: scanst.c 项目: npe9/sprite
void
scan_sty()
{
	char		spec[STRING_MAX];
	int		tmp;

	MESSAGE("Scanning style file %s", sty_fn);
	while (scan_spec(spec)) {
		sty_tc++;
		put_dot = TRUE;

		/* output pre- and post-ambles */
		if (STREQ(spec, PREAMBLE)) {
			(void)scan_string(preamble);
			prelen = count_lfd(preamble);
		} else if (STREQ(spec, POSTAMBLE)) {
			(void)scan_string(postamble);
			postlen = count_lfd(postamble);
		} else if (STREQ(spec, GROUP_SKIP)) {
			(void)scan_string(group_skip);
			skiplen = count_lfd(group_skip);
		} else if (STREQ(spec, LETHEAD_PRE)) {
			(void)scan_string(lethead_pre);
			headprelen = count_lfd(lethead_pre);
		} else if (STREQ(spec, LETHEAD_SUF)) {
			(void)scan_string(lethead_suf);
			headsuflen = count_lfd(lethead_suf);
		} else if (STREQ(spec, LETHEAD_FLAG)) {
			SCAN_NO(&lethead_flag);
		} else if (STREQ(spec, SETPAGEOPEN)) {
			(void)scan_string(setpage_open);
			setpagelen = count_lfd(setpage_open);
		} else if (STREQ(spec, SETPAGECLOSE)) {
			(void)scan_string(setpage_close);
			setpagelen = count_lfd(setpage_close);
		/* output index item commands */
		} else if (STREQ(spec, ITEM_0)) {
			(void)scan_string(item_r[0]);
			ilen_r[0] = count_lfd(item_r[0]);
		} else if (STREQ(spec, ITEM_1)) {
			(void)scan_string(item_r[1]);
			ilen_r[1] = count_lfd(item_r[1]);
		} else if (STREQ(spec, ITEM_2)) {
			(void)scan_string(item_r[2]);
			ilen_r[2] = count_lfd(item_r[2]);
		} else if (STREQ(spec, ITEM_01)) {
			(void)scan_string(item_u[1]);
			ilen_u[1] = count_lfd(item_u[1]);
		} else if (STREQ(spec, ITEM_12)) {
			(void)scan_string(item_u[2]);
			ilen_u[2] = count_lfd(item_u[2]);
		} else if (STREQ(spec, ITEM_x1)) {
			(void)scan_string(item_x[1]);
			ilen_x[1] = count_lfd(item_x[1]);
		} else if (STREQ(spec, ITEM_x2)) {
			(void)scan_string(item_x[2]);
			ilen_x[2] = count_lfd(item_x[2]);
		/* output encapsulators */
		} else if (STREQ(spec, ENCAP_0))
			(void)scan_string(encap_p);
		else if (STREQ(spec, ENCAP_1))
			(void)scan_string(encap_i);
		else if (STREQ(spec, ENCAP_2))
			(void)scan_string(encap_s);
		/* output delimiters */
		else if (STREQ(spec, DELIM_0))
			(void)scan_string(delim_p[0]);
		else if (STREQ(spec, DELIM_1))
			(void)scan_string(delim_p[1]);
		else if (STREQ(spec, DELIM_2))
			(void)scan_string(delim_p[2]);
		else if (STREQ(spec, DELIM_N))
			(void)scan_string(delim_n);
		else if (STREQ(spec, DELIM_R))
			(void)scan_string(delim_r);
		/* output line width */
		else if (STREQ(spec, LINEMAX)) {
			SCAN_NO(&tmp);
			if (tmp > 0)
				linemax = tmp;
			else
				STY_ERROR2("%s must be positive (got %d)", LINE_MAX, tmp);
		/* output line indentation length*/
		} else if (STREQ(spec, INDENT_LENGTH)) {
			SCAN_NO(&tmp);
			if (tmp >= 0)
				indent_length = tmp;
			else
				STY_ERROR2("%s must be nonnegative (got %d)", INDENT_LENGTH, tmp);
		/* output line indentation*/
		} else if (STREQ(spec, INDENT_SPACE)) {
			(void)scan_string(indent_space);
		/* composite page delimiter */
		} else if (STREQ(spec, COMPOSITOR)) {
			(void)scan_string(page_comp);
		/* page precedence */
		} else if (STREQ(spec, PRECEDENCE)) {
			(void)scan_string(page_prec);
			(void)process_precedence();
		/* index input format */
		} else if (STREQ(spec, KEYWORD))
			(void)scan_string(idx_keyword);
		else if (STREQ(spec, AOPEN))
			(void)scan_char(&idx_aopen);
		else if (STREQ(spec, ACLOSE))
			(void)scan_char(&idx_aclose);
		else if (STREQ(spec, LEVEL))
			(void)scan_char(&idx_level);
		else if (STREQ(spec, ROPEN))
			(void)scan_char(&idx_ropen);
		else if (STREQ(spec, RCLOSE))
			(void)scan_char(&idx_rclose);
		else if (STREQ(spec, QUOTE))
			(void)scan_char(&idx_quote);
		else if (STREQ(spec, ACTUAL))
			(void)scan_char(&idx_actual);
		else if (STREQ(spec, ENCAP))
			(void)scan_char(&idx_encap);
		else if (STREQ(spec, ESCAPE))
			(void)scan_char(&idx_escape);
		else {
			(void)next_nonblank();
			STY_SKIPLINE;
			STY_ERROR("Unknown specifier %s.\n", spec);
			put_dot = FALSE;
		}
		if (put_dot) {
			STY_DOT;
		}
	}

	/* check if quote and escape are distinct */
	if (idx_quote == idx_escape) {
		STY_ERROR("Quote and escape symbols must be distinct (both `%c' now).\n", idx_quote);
		idx_quote = IDX_QUOTE;
		idx_escape = IDX_ESCAPE;
	}

	DONE(sty_tc - sty_ec, "attributes redefined", sty_ec, "ignored");
	CLOSE(sty_fp);
}
示例#10
0
int main() {
  int d,m,y;
  char query[1024];
  char *env;
  char *coord=NULL;
  char *search=NULL;
  char buf[1024];
  char *tmp;

  time_t t;
  struct tm *tt;

  time(&t);
  tt = localtime(&t);
  d = tt->tm_mday;
  m = tt->tm_mon+1;
  y = tt->tm_year+1900;

  env = getenv("QUERY_STRING");
  if (env) {
    char *s;
    s = strstr(env, "d="); if (s) sscanf(s, "d=%d", &d);
    s = strstr(env, "m="); if (s) sscanf(s, "m=%d", &m);
    s = strstr(env, "y="); if (s) sscanf(s, "y=%d", &y);
    s = strstr(env, "c="); 
    if (s) s+=2; else { // spatna kompatibilita so znackami
      s = strstr(env, "in=");
      if (s) s+=3;
    }
    if (s) {
      query[0]=0;
      sscanf(s, "%1000[^&]", query);
      coord=StringDecode(query);
    }
    s = strstr(env, "search="); 
    if (s) {
      query[0]=0;
      sscanf(s+7, "%1000[^&]", query);
      search = StringDecode(query);
    }
  }

  if (db_init()<0) return 1;

  printf("Content-Type: text/html; charset=UTF-8\n\n");

  printf("<html><head>\n"
      "<link rel=\"stylesheet\" href=\"breviar.css\">\n");

  Rst(&kontext);
  kontext_last_hb=kontext_last_he=-1;
  first.h=last.h=-1;

  if (coord) {
    printf("<title>%s</title>\n"
      "</head><body>\n"
      "<div class=\"nadpis\">%s</div>\n\n", coord, coord);
    kalendar = 0;
    scan_string(coord);
    yyparse();
    printf("<p>\n"
        "<form action=\"pismo.cgi\" method=\"get\">\n"
        "<input type=\"text\" name=\"c\">\n"
        "<input type=\"submit\" value=\"Zobraz\">\n"
        "</form>\n");
    {
      char *tmp = StringEncode(kontext.buf+1);
      printf(// "<p>\n"
          "<a href=\"pismo.cgi?c=%s\">Kontext</a>", tmp);
      free(tmp);
    }
    printf("&nbsp; &nbsp;");
    if (first.h!=-1) {
      char *b;
      int h;
      get_prev(first.k, first.h, &b, &h);
      if (b!=NULL) {
        snprintf(buf, sizeof(buf), "%s %d", b, h);
        tmp = StringEncode(buf);
        printf(// "<p>\n"
            "<a href=\"pismo.cgi?c=%s\">Dozadu (%s %d)</a>", tmp, b, h);
        free(tmp);
        free(b);
      }
    }
    printf("&nbsp; &nbsp;");
    if (last.h!=-1){
      char *b;
      int h;
      get_next(last.k, last.h, &b, &h);
      if (b!=NULL) {
        snprintf(buf, sizeof(buf), "%s %d", b, h);
        tmp = StringEncode(buf);
        printf(// "<p>\n"
            "<a href=\"pismo.cgi?c=%s\">Dopredu (%s %d)</a>", tmp, b, h);
        free(tmp);
        free(b);
      }
    }
    printf("<p>\n"
        "<form action=\"pismo.cgi\" method=\"get\">\n"
        "<input type=\"text\" name=\"search\">\n"
        "<input type=\"submit\" value=\"Hľadaj\">\n"
        "</form>\n");
  } else if (search) {
    char *b,*t;
    int h,v;

    printf("<title>Vyhľadávanie \"%s\"</title>\n"
        "</head><body>\n"
        "<div class=\"nadpis\">Vyhľadávanie \"%s\"</div>\n\n",
        search, search);

    fulltext_search(search);

    while (get_fulltext_result(&b, &h, &v, &t)) {
      int i,in,var;
      snprintf(buf, sizeof(buf), "%s%d", b,h);
      tmp = StringEncode(buf);
      printf("\n<p> <a href=\"pismo.cgi?c=%s\">%s%d", tmp, b, h);
      if (v!=-1) printf(",%d", v);
      printf("</a>: ");
      free(tmp);
      for (i=in=var=0; t[i]; i++) {
        if (t[i]=='<') {
          in = 1;
          if (!strncmp(t+i+1, "var>", 4)) var = 1;
          if (!strncmp(t+i+1, "/var>", 5)) var = 0;
        }
        if (!in && !var) printf("%c", t[i]);
        if (t[i]=='>') in = 0;
      }
    }

    printf("<p>\n"
        "<form action=\"pismo.cgi\" method=\"get\">\n"
        "<input type=\"text\" name=\"c\">\n"
        "<input type=\"submit\" value=\"Zobraz\">\n"
        "</form>\n");
    printf("<p>\n"
        "<form action=\"pismo.cgi\" method=\"get\">\n"
        "<input type=\"text\" name=\"search\">\n"
        "<input type=\"submit\" value=\"Hľadaj\">\n"
        "</form>\n");
    
    free_fulltext_search();
  } else {
    char *ct;
    if (!get_citania(y,m,d, &zalm, &ct)) return 3;

    kalendar = 1;

    //  printf("%s %s %s %s\n", row[0], row[1], row[2], row[3]);

    printf("<title>Čítania na %d.%d.%d</title>\n"
        "</head><body>\n"
        "<div class=\"nadpis\">Liturgické čítania na %d.%d.%d</div>\n\n",
        d,m,y,d,m,y);
    scan_string(ct);
    yyparse();

    /* toto asi nechceme
    {
      char *tmp = StringEncode(kontext.buf+1);
      printf("<p>\n"
          "<a href=\"pismo.cgi?c=%s\">Kontext</a>", tmp);
      free(tmp);
    }
    */

    free(zalm);
    free(ct);
  }
  printf("</body></html>\n");

  free_scan_string();

  db_close();
  return 0;
}
示例#11
0
文件: lexer.c 项目: timocramer/gbasm
int yylex(void) {
	int status;
	
#ifdef DEBUG
	printf("yylex is called\n"
		"  first_line:   %d\n"
		"  first_column: %d\n"
		"  last_line:    %d\n"
		"  last_column:  %d\n",
		yylloc.first_line,
		yylloc.first_column,
		yylloc.last_line,
		yylloc.last_column);
#endif
	
	skip_white_space:
	while(*src == ' ' || *src == '\t') {
		++yylloc.last_column;
		++src;
	}
	
	/* skip comments */
	if(*src == ';') {
		while(*src != '\n' && *src != 0) {
			++yylloc.last_column;
			++src;
		}
	}
	
	/* when a newline appears, update yylloc accordingly and start to skip
	whitespace again */
	if(*src == '\n') {
		++yylloc.last_line;
		yylloc.last_column = 1;
		++src;
		goto skip_white_space;
	}
	
	yylloc.first_line = yylloc.last_line;
	yylloc.first_column = yylloc.last_column;
	
	status = scan_multibyte_operator();
	if(status != 0)
		return status;
	
	status = scan_int();
	if(status != 0)
		return status;
	
	status = scan_string();
	if(status != 0)
		return status;
	
	status = scan_special_identifier();
	if(status != 0)
		return status;
	
	status = scan_identifier();
	if(status != 0)
		return status;
	
	/* Return a single char or, when end of string, 0 */
	++yylloc.last_column;
#ifdef DEBUG
	if(*src == 0)
		printf("yylex returns EOF\n");
	else
		printf("yylex returns '%c'\n", *src);
#endif
	return *src++;
}
示例#12
0
int scan(scan_info *info)
{
    int err = 0;
    int sym_code = SVO_NONE;
    const char **in = &(info->scanner);
    char tmp[SCAN_SIZE+1];

    while((**in != 0) && (isspace(**in))) (*in)++;

    if(isalpha(**in)){

        scan_ident(in,info->token,SCAN_SIZE);

        sym_code = token_to_id(info->token);
        if(sym_code == SVO_NONE) sym_code = SVO_IDENT;

    } else if(isdigit(**in)){

        scan_number(in,info->token,SCAN_SIZE);
        sym_code = SVO_NUMBER;
    } else{
        switch(**in){
        case '#':
            sym_code = SVO_END;
            break;
        case '>':
        case '<':
        case '=':
        case '!':

            scan_comp(in,info->token,SCAN_SIZE);
            break;

        case '"':

            err = scan_string(info,SCAN_SIZE);

            if(err != SHE_NO_ERROR){
                parse_vars_in_string(info->token,tmp,SCAN_SIZE);
                strncpy(info->token,tmp,SCAN_SIZE);
                info->token[SCAN_SIZE] = 0;
            }

            sym_code = SVO_DQ_STRING;
            break;
        case '\'':

            sym_code = SVO_SQ_STRING;
            err =scan_string(info,SCAN_SIZE);
            break;
        case 0:

            *(info->token) = 0;
            sym_code = SVO_END;
            break;
        default:
            info->token[0] = **in;
            info->token[1] = 0;
            (*in)++;
            break;

        }
        if(sym_code == SVO_NONE) sym_code = token_to_id(info->token);

    }

    info->sym_code = sym_code;

    return err;
}
示例#13
0
文件: lexer.c 项目: jdubeau123/luna
int
luna_scan(luna_lexer_t *self) {
  int c;
  token(ILLEGAL);

  // deferred outdents
  if (self->outdents) return outdent(self);

  // scan
  scan:
  switch (c = next) {
    case ' ':
    case '\t': goto scan;
    case '(': return token(LPAREN);
    case ')': return token(RPAREN);
    case '{': return token(LBRACE);
    case '}': return token(RBRACE);
    case '[': return token(LBRACK);
    case ']': return token(RBRACK);
    case ',': return token(COMMA);
    case '.': return token(OP_DOT);
    case '%': return token(OP_MOD);
    case '^': return token(OP_BIT_XOR);
    case '~': return token(OP_BIT_NOT);
    case '?': return token(QMARK);
    case ':': return token(COLON);
    case '@':
      self->tok.value.as_string = "self";
      return token(ID);
    case '+':
      switch (next) {
        case '+': return token(OP_INCR);
        case '=': return token(OP_PLUS_ASSIGN);
        default: return undo, token(OP_PLUS);
      }
    case '-':
      switch (next) {
        case '-': return token(OP_DECR);
        case '=': return token(OP_MINUS_ASSIGN);
        default: return undo, token(OP_MINUS);
      }
    case '*':
      switch (next) {
        case '=': return token(OP_MUL_ASSIGN);
        case '*': return token(OP_POW);
        default: return undo, token(OP_MUL);
      }
    case '/':
      return '=' == next
        ? token(OP_DIV_ASSIGN)
        : (undo, token(OP_DIV));
    case '!':
      return '=' == next
        ? token(OP_NEQ)
        : (undo, token(OP_NOT));
    case '=':
      return '=' == next
        ? token(OP_EQ)
        : (undo, token(OP_ASSIGN));
    case '&':
      switch (next) {
        case '&':
          return '=' == next
            ? token(OP_AND_ASSIGN)
            : (undo, token(OP_AND));
        default:
          return undo, token(OP_BIT_AND);
      }
    case '|':
      switch (next) {
        case '|':
          return '=' == next
            ? token(OP_OR_ASSIGN)
            : (undo, token(OP_OR));
        default:
          return undo, token(OP_BIT_OR);
      }
    case '<':
      switch (next) {
        case '=': return token(OP_LTE);
        case '<': return token(OP_BIT_SHL);
        default: return undo, token(OP_LT);
      }
    case '>':
      switch (next) {
        case '=': return token(OP_GTE);
        case '>': return token(OP_BIT_SHR);
        default: return undo, token(OP_GT);
      }
    case '#':
      while ((c = next) != '\n' && c) ; undo;
      goto scan;
    case '\n':
      return scan_newline(self);
    case '"':
    case '\'':
      return scan_string(self, c);
    case 0:
      if (self->indents) {
        --self->indents;
        return token(OUTDENT);
      }
      token(EOS);
      return 0;
    default:
      if (isalpha(c) || '_' == c) return scan_ident(self, c);
      if (isdigit(c) || '.' == c) return scan_number(self, c);
      error("illegal character");
      return 0;
  }
}
示例#14
0
bool tokz_get_token(Tokenizer *tokz, Token *tok)
{
    int c, c2, e;
    
    if (!(tokz->flags&TOKZ_READ_FROM_BUFFER))
    assert(tokz->file!=NULL);
    
    tok_free(tok);
    
    if(!TOK_IS_INVALID(&(tokz->ungettok))){
        *tok=tokz->ungettok;
        tokz->ungettok.type=TOK_INVALID;
        return TRUE;
    }

    while(1){
    
        e=0;
        
        do{
            c=GETCH();
        }while(c!='\n' && c!=EOF && isspace(c));
    
        tok->line=tokz->line;
    
        switch(c){
        case EOF:
            TOK_SET_OP(tok, OP_EOF);
            return TRUE;
            
        case '\n':
            INC_LINE();
            
            if(tokz->flags&TOKZ_IGNORE_NEXTLINE)
                continue;
            
            TOK_SET_OP(tok, OP_NEXTLINE);
            
            return TRUE;
            
        case '\\':
            do{
                c=GETCH();
                if(c==EOF){
                    TOK_SET_OP(tok, OP_EOF);
                    return FALSE;
                }
                if(!isspace(c) && e==0){
                    e=E_TOKZ_EOL_EXPECTED;
                    tokz_warn_error(tokz, tokz->line, e);
                    if(!(tokz->flags&TOKZ_ERROR_TOLERANT))
                        return FALSE;
                }
            }while(c!='\n');
            
            INC_LINE();
            continue;

        case '#':
            if(tokz->flags&TOKZ_READ_COMMENTS){
                e=scan_line_comment(tok, tokz);
                break;
            }else if((e=skip_line_comment(tokz))){
                break;
            }
            
            continue;
            
        case '/':
            c2=GETCH();
            
            if(c2=='='){
                TOK_SET_OP(tok, OP_AS_DIV);
                return TRUE;
            }
            
            if(c2!='*'){
                UNGETCH(c2);
                TOK_SET_OP(tok, OP_DIV);
                return TRUE;
            }
            
            if(tokz->flags&TOKZ_READ_COMMENTS){
                e=scan_c_comment(tok, tokz);
                break;
            }else if((e=skip_c_comment(tokz))){
                break;
            }
            
            continue;
            
        case '\"':
            e=scan_string(tok, tokz, TRUE);
            break;

        case '\'':
            e=scan_char(tok, tokz);
            break;

        default: 
            if(('0'<=c && c<='9') || c=='-' || c=='+'){
                e=scan_number(tok, tokz, c);
                break;
            }

             if(START_IDENT(c))
                e=scan_identifier(tok, tokz, c);
            else
                e=scan_op(tok, tokz, c);
        }
        
        if(!e)
            return TRUE;
        
        tokz_warn_error(tokz, tokz->line, e);
        return FALSE;
    }
}
StackFrame * Parser::parse_backtrace_frame(Mode mode) {
    size_t id = read_uint();

    StackFrameState *frame = lookup(frames, id);

    if (!frame) {
        frame = new StackFrameState;
        int c = read_byte();
        while (c != trace::BACKTRACE_END &&
               c != -1) {
            switch (c) {
            case trace::BACKTRACE_MODULE:
                frame->module = read_string();
                break;
            case trace::BACKTRACE_FUNCTION:
                frame->function = read_string();
                break;
            case trace::BACKTRACE_FILENAME:
                frame->filename = read_string();
                break;
            case trace::BACKTRACE_LINENUMBER:
                frame->linenumber = read_uint();
                break;
            case trace::BACKTRACE_OFFSET:
                frame->offset = read_uint();
                break;
            default:
                std::cerr << "error: unknown backtrace detail "
                          << c << "\n";
                exit(1);
            }
            c = read_byte();
        }

        frame->fileOffset = file->currentOffset();
        frames[id] = frame;
    } else if (file->currentOffset() < frame->fileOffset) {
        int c = read_byte();
        while (c != trace::BACKTRACE_END &&
               c != -1) {
            switch (c) {
            case trace::BACKTRACE_MODULE:
                scan_string();
                break;
            case trace::BACKTRACE_FUNCTION:
                scan_string();
                break;
            case trace::BACKTRACE_FILENAME:
                scan_string();
                break;
            case trace::BACKTRACE_LINENUMBER:
                scan_uint();
                break;
            case trace::BACKTRACE_OFFSET:
                scan_uint();
                break;
            default:
                std::cerr << "error: unknown backtrace detail "
                          << c << "\n";
                exit(1);
            }
            c = read_byte();
        }
    }

    return frame;
}
示例#16
0
struct skin_element* skin_parse(const char* document, 
                                skin_callback cb, void* cb_data)
{
    callback = cb;
    callback_data = cb_data;
#else
struct skin_element* skin_parse(const char* document)
{
#endif
    struct skin_element* root = NULL;
    struct skin_element* last = NULL;

    const char* cursor = document; /*Keeps track of location in the document*/
    
    skin_line = 1;
    skin_start = (char*)document;
    viewport_line = 0;

    skin_clear_errors();

    while(*cursor != '\0')
    {
        struct skin_element* tree = skin_parse_viewport(&cursor);
        if(!root)
        {
            root = tree;
            last = root;
        }
        else
        {
            last->next = skin_buffer_to_offset(tree);
            last = tree;
        }

        if(!last)
        {
            skin_free_tree(root); /* Clearing any memory already used */
            return NULL;
        }

        /* Making sure last is at the end */
        while(IS_VALID_OFFSET(last->next))
            last = skin_buffer_from_offset(last->next);

    }
    return root;

}

static struct skin_element* skin_parse_viewport(const char** document)
{
    struct skin_element* root = NULL;
    struct skin_element* last = NULL;
    struct skin_element* retval = NULL;

    retval = skin_alloc_element();
    if (!retval)
        return NULL;
    retval->type = VIEWPORT;
    retval->children_count = 1;
    retval->line = skin_line;
    viewport_line = skin_line;

    OFFSETTYPE(struct skin_element*)* children;

    const char* cursor = *document; /* Keeps track of location in the document */
    const char* bookmark; /* Used when we need to look ahead */

    int sublines = 0; /* Flag for parsing sublines */

    /* Parsing out the viewport tag if there is one */
    if(check_viewport(cursor))
    {
        if (!skin_parse_tag(retval, &cursor))
            return NULL;
        if(*cursor == '\n')
        {
            cursor++;
            skin_line++;
        }
    }
#ifdef ROCKBOX
    else if (callback)
    {
        if (callback(retval, callback_data) == CALLBACK_ERROR)
        {
            skin_error(GOT_CALLBACK_ERROR, cursor);
            return NULL;
        }
    }
#endif

    if (check_viewport(cursor))
    {
        retval->children_count = 0;
        *document = cursor;
        return retval;
    }
    retval->children_count = 1;
    children = skin_alloc_children(1);
    if (!children)
        return NULL;
    do
    {

        /* First, we check to see if this line will contain sublines */
        bookmark = cursor;
        sublines = 0;
        while(*cursor != '\n' && *cursor != '\0'
              && !(check_viewport(cursor) && cursor != *document))
        {
            if(*cursor == MULTILINESYM)
            {
                sublines = 1;
                break;
            }
            else if(*cursor == TAGSYM)
            {
                skip_tag(&cursor);
            }
            else if(*cursor == COMMENTSYM)
            {
                skip_comment(&cursor);
            }
            else
            {
                /* Advancing the cursor as normal */
                cursor++;
            }
        }
        cursor = bookmark;

        if(sublines)
        {
            struct skin_element* out = skin_parse_sublines(&cursor);
            if (!root)
            {
                root = out;
                last = root;
            }
            else
            {
                last->next = skin_buffer_to_offset(out);
                last = out;
            }
            if(!last)
                return NULL;
        }
        else
        {
#ifdef ROCKBOX
            /* strip all leading comments */
            while(*cursor == '#')
            {
                skip_comment(&cursor);
                skin_line++;
                
            }
            if (check_viewport(cursor))
                break;
#endif

            struct skin_element* out = skin_parse_line(&cursor);
            if (!root)
            {
                root = out;
                last = root;
            }
            else
            {
                last->next = skin_buffer_to_offset(out);
                last = out;
            }
            if(!last)
                return NULL;

        }
        /* Making sure last is at the end */
        while(IS_VALID_OFFSET(last->next))
            last = skin_buffer_from_offset(last->next);

        if(*cursor == '\n')
        {
            cursor++;
            skin_line++;
        }
#ifdef ROCKBOX
        /* strip all comments */
        while(*cursor == '#')
        {
            skip_comment(&cursor);
            skin_line++;
            
        }
        if (check_viewport(cursor))
            break;
#endif

    }
    while(*cursor != '\0' && !(check_viewport(cursor) && cursor != *document));

    *document = cursor;

    children[0] = skin_buffer_to_offset(root);
    retval->children = skin_buffer_to_offset(children);
    return retval;
}

/* Auxiliary Parsing Functions */

static struct skin_element* skin_parse_line(const char**document)
{
    return skin_parse_line_optional(document, 0);
}

/*
 * If conditional is set to true, then this will break upon encountering
 * SEPARATESYM.  This should only be used when parsing a line inside a
 * conditional, otherwise just use the wrapper function skin_parse_line()
 */
static struct skin_element* skin_parse_line_optional(const char** document,
                                                     int conditional)
{
    const char* cursor = *document;

    struct skin_element* root = NULL;
    struct skin_element* current = NULL;
    struct skin_element* retval = NULL;
    OFFSETTYPE(struct skin_element*)* children = NULL;

    /* A wrapper for the line */
    retval = skin_alloc_element();
    if (!retval)
        return NULL;
    retval->type = LINE;
    retval->line = skin_line;
    while (*cursor == '\t')
        cursor++;

    if(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM
       && !(conditional && (*cursor == ARGLISTSEPARATESYM
                            || *cursor == ARGLISTCLOSESYM
                            || *cursor == ENUMLISTSEPARATESYM
                            || *cursor == ENUMLISTCLOSESYM)))
    {
        retval->children_count = 1;
    }
    else
    {
        retval->children_count = 0;
    }

    if(retval->children_count > 0)
    {
        children = skin_alloc_children(1);
        if (!children)
            return NULL;
    }

#ifdef ROCKBOX
    if (callback)
    {
        switch (callback(retval, callback_data))
        {
            case CALLBACK_ERROR:
                skin_error(GOT_CALLBACK_ERROR, cursor);
                return NULL;
            default:
                break;
        }
    }
#endif

    while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM
          && !((*cursor == ARGLISTSEPARATESYM
                || *cursor == ARGLISTCLOSESYM
                || *cursor == ENUMLISTSEPARATESYM
                || *cursor == ENUMLISTCLOSESYM)
               && conditional)
          && !(check_viewport(cursor) && cursor != *document))
    {
        /* Allocating memory if necessary */
        if(root)
        {
            struct skin_element *next = skin_alloc_element();
            if (!next)
                return NULL;
            current->next = skin_buffer_to_offset(next);
            current = next;
        }
        else
        {
            current = skin_alloc_element();
            if (!current)
                return NULL;
            root = current;
        }

        /* Parsing the current element */
        if(*cursor == TAGSYM && cursor[1] == CONDITIONSYM)
        {
            if(!skin_parse_conditional(current, &cursor))
                return NULL;
        }
        else if(*cursor == TAGSYM && !find_escape_character(cursor[1]))
        {
            if(!skin_parse_tag(current, &cursor))
                return NULL;
        }
        else if(*cursor == COMMENTSYM)
        {
            if(!skin_parse_comment(current, &cursor))
                return NULL;
        }
        else
        {
            if(!skin_parse_text(current, &cursor, conditional))
                return NULL;
        }
    }

    /* Moving up the calling function's pointer */
    *document = cursor;
    
    if(root)
    {
        children[0] = skin_buffer_to_offset(root);
        retval->children = skin_buffer_to_offset(children);
    }
    return retval;
}

static struct skin_element* skin_parse_sublines(const char** document)
{
    return skin_parse_sublines_optional(document, 0);
}

static struct skin_element* skin_parse_sublines_optional(const char** document,
                                                  int conditional)
{
    struct skin_element* retval;
    OFFSETTYPE(struct skin_element*)* children;
    const char* cursor = *document;
    int sublines = 1;
    int i;

    retval = skin_alloc_element();
    if (!retval)
        return NULL;
    retval->type = LINE_ALTERNATOR;
    retval->next = skin_buffer_to_offset(NULL);
    retval->line = skin_line;
    while (*cursor == '\t')
        cursor++;

    /* First we count the sublines */
    while(*cursor != '\0' && *cursor != '\n'
          && !((*cursor == ARGLISTSEPARATESYM
                || *cursor == ARGLISTCLOSESYM
                || *cursor == ENUMLISTSEPARATESYM
                || *cursor == ENUMLISTCLOSESYM)
               && conditional)
          && !(check_viewport(cursor) && cursor != *document))
    {
        if(*cursor == COMMENTSYM)
        {
            skip_comment(&cursor);
        }
        else if(*cursor == TAGSYM)
        {
            skip_tag(&cursor);
        }
        else if(*cursor == MULTILINESYM)
        {
            sublines++;
            cursor++;
        }
        else
        {
            cursor++;
        }
    }

    /* ...and then we parse them */
    retval->children_count = sublines;
    children = skin_alloc_children(sublines);
    if (!children)
        return NULL;

    cursor = *document;
    for(i = 0; i < sublines; i++)
    {
        children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional));
        if (children[i] < 0)
            return NULL;
        skip_whitespace(&cursor);

        if(*cursor != MULTILINESYM && i != sublines - 1)
        {
            skin_error(MULTILINE_EXPECTED, cursor);
            return NULL;
        }
        else if(i != sublines - 1)
        {
            cursor++;
        }
    }

#ifdef ROCKBOX
    if (callback)
    {
        if (callback(retval, callback_data) == CALLBACK_ERROR)
        {
            skin_error(GOT_CALLBACK_ERROR, *document);
            return NULL;
        }
    }
#endif
    *document = cursor;
    retval->children = skin_buffer_to_offset(children);

    return retval;
}

static int skin_parse_tag(struct skin_element* element, const char** document)
{
    const char* cursor = *document + 1;
    const char* bookmark;
    char *open_square_bracket = NULL;

    char tag_name[MAX_TAG_LENGTH];
    char* tag_args;
    const struct tag_info *tag;
    struct skin_tag_parameter* params = NULL;

    int num_args = 1;
    int i;
    int qmark = 0; /* Flag for the all-or-none option */

    int optional = 0;

    /* Checking the tag name */
    for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++)
        tag_name[i] = cursor[i];

    /* First we check the two characters after the '%', then a single char */
    tag = NULL;
    i = MAX_TAG_LENGTH;
    while (!tag && i > 1)
    {
        tag_name[i-1] = '\0';
        tag = find_tag(tag_name);
        i--;
    }

    if(!tag)
    {
        skin_error(ILLEGAL_TAG, cursor);
        return 0;
    }
    cursor += i;

    /* Copying basic tag info */
    if(element->type != CONDITIONAL && element->type != VIEWPORT)
        element->type = TAG;
    element->tag = tag;
    tag_args = tag->params;
    element->line = skin_line;

    /* Checking for the * flag */
    if(tag_args[0] == '?')
    {
        qmark = 1;
        tag_args++;
    }

    /* If this tag has no arguments, we can bail out now */
    if(strlen(tag_args) == 0
       || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM)
       || (qmark && *cursor != ARGLISTOPENSYM))
    {
        
#ifdef ROCKBOX
        if (callback)
        {
            if (callback(element, callback_data) == CALLBACK_ERROR)
            {
                skin_error(GOT_CALLBACK_ERROR, cursor);
                return 0;
            }
        }
#endif
        *document = cursor;
        return 1;
    }

    /* Checking the number of arguments and allocating args */
    if(*cursor != ARGLISTOPENSYM && tag_args[0] != '|')
    {
        skin_error(ARGLIST_EXPECTED, cursor);
        return 0;
    }
    else
    {
        cursor++;
    }

    bookmark = cursor;
    while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM)
    {
        /* Skipping over escaped characters */
        if(*cursor == TAGSYM && *(cursor+1) != ARGLISTSEPARATESYM)
        {
            skip_tag(&cursor);
        }
        else if(*cursor == COMMENTSYM)
        {
            skip_comment(&cursor);
        }
        else if(*cursor == ARGLISTSEPARATESYM)
        {
            num_args++;
            cursor++;
        }
        else
        {
            cursor++;
        }
    }

    cursor = bookmark; /* Restoring the cursor */
    element->params_count = num_args;
    params = skin_alloc_params(num_args);
    if (!params)
        return 0;

    /* Now we have to actually parse each argument */
    for(i = 0; i < num_args; i++)
    {
        char type_code;
        /* Making sure we haven't run out of arguments */
        if(*tag_args == '\0')
        {
            skin_error(TOO_MANY_ARGS, cursor);
            return 0;
        }

        /* Checking for the optional bar */
        if(*tag_args == '|')
        {
            optional = 1;
            tag_args++;
        }

        /* Scanning the arguments */
        skip_whitespace(&cursor);

        /* Checking for comments */
        if(*cursor == COMMENTSYM)
            skip_comment(&cursor);

        if (*tag_args == '[')
        {
            /* we need to guess which type of param it is. 
             * guess using this priority:
             * default > decimal/integer > single tag/code > string
             */
            int j=0;
            bool canbedefault = false, last_char_is_percent = false;
            bool haspercent = false, number = true, hasdecimal = false;
            char temp_params[8];
            open_square_bracket = tag_args;
            tag_args++;
            while (*tag_args != ']')
            {
                if (*tag_args >= 'a' && *tag_args <= 'z')
                    canbedefault = true;
                temp_params[j++] = tolower(*tag_args++);
            }
            temp_params[j] = '\0';
            j = 0;
            while (cursor[j] && cursor[j] != ',' && cursor[j] != ')')
            {
                haspercent = haspercent || (cursor[j] == '%');
                hasdecimal = hasdecimal || (cursor[j] == '.');
                number = number && (isdigit(cursor[j]) || 
                                    (cursor[j] == '.') ||
                                    (cursor[j] == '-') ||
                                    (cursor[j] == '%'));
                j++;
            }
            last_char_is_percent = cursor[j-1] == '%';
            type_code = '?';
            if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1]))
            {
                type_code = 'i';
            }
            else if (number && hasdecimal && strchr(temp_params, 'd'))
            {
                type_code = 'd';
            }
            else if (number && last_char_is_percent && strchr(temp_params, 'p'))
            {
                type_code = 'p';
            }
            else if (number && 
                     (strchr(temp_params, 'i') || strchr(temp_params, 'd')))
            {
                type_code = strchr(temp_params, 'i') ? 'i' : 'd';
            }
            else if (haspercent && 
                    (strchr(temp_params, 't') || strchr(temp_params, 'c')))
            {
                type_code = strchr(temp_params, 't') ? 't' : 'c';
            }
            else if (strchr(temp_params, 's'))
            {
                type_code = 's';
            }
            if (type_code == '?')
            {
                skin_error(INSUFFICIENT_ARGS, cursor);
                return 0;
            }   
        }
        else
            type_code = *tag_args;
        /* Storing the type code */
        params[i].type_code = type_code;

        /* Checking a nullable argument for null. */
        if(*cursor == DEFAULTSYM && !isdigit(cursor[1]))
        {
            if(islower(type_code))
            {
                params[i].type = DEFAULT;
                cursor++;
            }
            else
            {
                skin_error(DEFAULT_NOT_ALLOWED, cursor);
                return 0;
            }
        }
        else if(tolower(type_code) == 'i')
        {
            /* Scanning an int argument */
            if(!isdigit(*cursor) && *cursor != '-')
            {
                skin_error(INT_EXPECTED, cursor);
                return 0;
            }

            params[i].type = INTEGER;
            params[i].data.number = scan_int(&cursor);
        }
        else if(tolower(type_code) == 'd' || tolower(type_code) == 'p')
        {
            int val = 0;
            bool have_point = false;
            bool have_tenth = false;
            while ( isdigit(*cursor) || *cursor == '.' )
            {
                if (*cursor != '.')
                {
                    val *= 10;
                    val += *cursor - '0';
                    if (have_point)
                    {
                        have_tenth = true;
                        cursor++;
                        break;
                    }
                }
                else
                    have_point = true;
                cursor++;
            }
            if (have_tenth == false)
                val *= 10;
            if (tolower(type_code) == 'd')
                params[i].type = DECIMAL;
            else
            {
                params[i].type = PERCENT;
                cursor++; /* skip trailing % sign */
            }
            params[i].data.number = val;
        }
        else if(tolower(type_code) == 's' || tolower(type_code) == 'f')
        {
            /* Scanning a string argument */
            params[i].type = STRING;
            params[i].data.text = skin_buffer_to_offset(scan_string(&cursor));

        }
        else if(tolower(type_code) == 'c')
        {
            /* Recursively parsing a code argument */
            params[i].type = CODE;
            params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
            if(params[i].data.code < 0)
                return 0;
        }
        else if (tolower(type_code) == 't')
        {
            struct skin_element* child = skin_alloc_element();
            child->type = TAG;
            if (!skin_parse_tag(child, &cursor))
                return 0;
            child->next = skin_buffer_to_offset(NULL);
            params[i].type = CODE;
            params[i].data.code = skin_buffer_to_offset(child);
        }
            

        skip_whitespace(&cursor);

        if(*cursor != ARGLISTSEPARATESYM && i < num_args - 1)
        {
            skin_error(SEPARATOR_EXPECTED, cursor);
            return 0;
        }
        else if(*cursor != ARGLISTCLOSESYM && i == num_args - 1)
        {
            skin_error(CLOSE_EXPECTED, cursor);
            return 0;
        }
        else
        {
            cursor++;
        }

        if (*(tag_args + 1) == '*')
        {
            if (i+1 == num_args)
                tag_args += 2;
            else if (open_square_bracket  && *tag_args == ']')
            {
                tag_args = open_square_bracket;
                open_square_bracket = NULL;
            }
        }
        else
            tag_args++;

        /* Checking for the optional bar */
        if(*tag_args == '|')
        {
            optional = 1;
            tag_args++;
        }
    }
    element->params = skin_buffer_to_offset(params);

    /* Checking for a premature end */
    if(*tag_args != '\0' && !optional)
    {
        skin_error(INSUFFICIENT_ARGS, cursor);
        return 0;
    }
#ifdef ROCKBOX
    if (callback)
    {
        if (callback(element, callback_data) == CALLBACK_ERROR)
        {
            skin_error(GOT_CALLBACK_ERROR, *document);
            return 0;
        }
    }
#endif
    *document = cursor;

    return 1;
}

/*
 * If the conditional flag is set true, then parsing text will stop at an
 * ARGLISTSEPARATESYM.  Only set that flag when parsing within a conditional
 */
static int skin_parse_text(struct skin_element* element, const char** document,
                           int conditional)
{
    const char* cursor = *document;
    int length = 0;
    int dest;
    char *text = NULL;

    /* First figure out how much text we're copying */
    while(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM
          && *cursor != COMMENTSYM
          && !((*cursor == ARGLISTSEPARATESYM
                || *cursor == ARGLISTCLOSESYM
                || *cursor == ENUMLISTSEPARATESYM
                || *cursor == ENUMLISTCLOSESYM)
               && conditional))
    {
        /* Dealing with possibility of escaped characters */
        if(*cursor == TAGSYM)
        {
            if(find_escape_character(cursor[1]))
                cursor++;
            else
                break;
        }

        length++;
        cursor++;
    }

    cursor = *document;

    /* Copying the text into the element struct */
    element->type = TEXT;
    element->line = skin_line;
    element->next = skin_buffer_to_offset(NULL);
    text = skin_alloc_string(length);
    element->data = skin_buffer_to_offset(text);
    if (element->data < 0)
        return 0;
    
    for(dest = 0; dest < length; dest++)
    {
        /* Advancing cursor if we've encountered an escaped character */
        if(*cursor == TAGSYM)
            cursor++;

        text[dest] = *cursor;
        cursor++;
    }
    text[length] = '\0';
    
#ifdef ROCKBOX
    if (callback)
    {
        if (callback(element, callback_data) == CALLBACK_ERROR)
        {
            skin_error(GOT_CALLBACK_ERROR, *document);
            return 0;
        }
    }
#endif

    *document = cursor;

    return 1;
}

static int skin_parse_conditional(struct skin_element* element, const char** document)
{
    const char* cursor = *document + 1; /* Starting past the "%" */
    const char* bookmark;
    int children = 1;
    int i;
    
#ifdef ROCKBOX
    bool feature_available = true;
    const char *false_branch = NULL;
    const char *conditional_end = NULL;
#endif
    OFFSETTYPE(struct skin_element*)* children_array = NULL;

    /* Some conditional tags allow for target feature checking,
     * so to handle that call the callback as usual with type == TAG
     * then call it a second time with type == CONDITIONAL and check the return
     * value */
    element->type = TAG;
    element->line = skin_line;

    /* Parsing the tag first */
    if(!skin_parse_tag(element, &cursor))
        return 0;

    element->type = CONDITIONAL;
#ifdef ROCKBOX
    if (callback)
    {
        switch (callback(element, callback_data))
        {
            case FEATURE_NOT_AVAILABLE:
                feature_available = false;
                break;
            case CALLBACK_ERROR:
                return 0;
            default:
                break;
        }
    }
#endif
    
    /* Counting the children */
    if(*(cursor++) != ENUMLISTOPENSYM)
    {
        skin_error(ARGLIST_EXPECTED, cursor);
        return 0;
    }
    bookmark = cursor;
    while(*cursor != ENUMLISTCLOSESYM && *cursor != '\0')
    {
        if(*cursor == COMMENTSYM)
        {
            skip_comment(&cursor);
        }
        else if(*cursor == TAGSYM)
        {
            skip_tag(&cursor);
        }
        else if(*cursor == ENUMLISTSEPARATESYM)
        {
            children++;
            cursor++;
            if (*cursor == '\n')
                cursor++;
#ifdef ROCKBOX
            if (false_branch == NULL && !feature_available)
            {
                false_branch = cursor;
                children--;
            }
#endif
        }
        else
        {
            cursor++;
        }
    }
#ifdef ROCKBOX
    if (*cursor == ENUMLISTCLOSESYM && 
        false_branch == NULL && !feature_available)
    {
        false_branch = cursor+1;
        children--;
    }
    if (element->tag->flags&FEATURE_TAG)
    {
        if (feature_available && children > 1)
            children--;
    }
    conditional_end = cursor;
    /* if we are skipping the true branch fix that up */
    cursor = false_branch ? false_branch : bookmark;
#else
    cursor = bookmark;
#endif
    /* Parsing the children */
    
    /* Feature tags could end up having 0 children which breaks
     * the render in dangerous ways. Minor hack, but insert an empty
     * child.  (e.g %?xx<foo> when xx isnt available ) */
    
    if (children == 0)
    {
        const char* emptyline= "";
        children = 1;
        children_array = skin_alloc_children(children);
        if (!children_array)
            return 0;
        element->children_count = children;
        children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline));
    }
    else
    {    
        children_array = skin_alloc_children(children);
        if (!children_array)
            return 0;
        element->children_count = children;

        for(i = 0; i < children; i++)
        {
            if (*cursor == '\n')
            {
                skin_line++;
                cursor++;
            }
            children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
            if (children_array[i] < 0)
                return 0;
            skip_whitespace(&cursor);
#ifdef ROCKBOX
            if ((element->tag->flags&FEATURE_TAG) && feature_available)
                cursor = conditional_end;
#endif

            if(i < children - 1 && *cursor != ENUMLISTSEPARATESYM)
            {
                skin_error(SEPARATOR_EXPECTED, cursor);
                return 0;
            }
            else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM)
            {
                skin_error(CLOSE_EXPECTED, cursor);
                return 0;
            }
            else
            {
                cursor++;
            }
        }
    }
    *document = cursor;
    element->children = skin_buffer_to_offset(children_array);

    return 1;
}

static int skin_parse_comment(struct skin_element* element, const char** document)
{
    const char* cursor = *document;
#ifndef ROCKBOX
    char* text = NULL;
#endif
    int length;
    /*
     * Finding the index of the ending newline or null-terminator
     * The length of the string of interest doesn't include the leading #, the
     * length we need to reserve is the same as the index of the last character
     */
    for(length = 0; cursor[length] != '\n' && cursor[length] != '\0'; length++);

    element->type = COMMENT;
    element->line = skin_line;
#ifdef ROCKBOX 
    element->data = INVALID_OFFSET;
#else    
    element->data = text = skin_alloc_string(length);
    if (!element->data)
        return 0;
    /* We copy from one char past cursor to leave out the # */
    memcpy((void*)text, (void*)(cursor + 1),
           sizeof(char) * (length-1));
    text[length - 1] = '\0';
#endif
    if(cursor[length] == '\n')
        skin_line++;

    *document += (length); /* Move cursor up past # and all text */
    if(**document == '\n')
        (*document)++;

    return 1;
}

static struct skin_element* skin_parse_code_as_arg(const char** document)
{
    int sublines = 0;
    const char* cursor = *document;

    /* Checking for sublines */
    while(*cursor != '\n' && *cursor != '\0'
          && *cursor != ENUMLISTSEPARATESYM && *cursor != ARGLISTSEPARATESYM
          && *cursor != ENUMLISTCLOSESYM && *cursor != ARGLISTCLOSESYM)
    {
        if(*cursor == MULTILINESYM)
        {
            sublines = 1;
            break;
        }
        else if(*cursor == TAGSYM)
        {
            skip_tag(&cursor);
        }
        else
        {
            /* Advancing the cursor as normal */
            cursor++;
        }
    }

    if(sublines)
        return skin_parse_sublines_optional(document, 1);
    else
        return skin_parse_line_optional(document, 1);
}
// returns a token on the heap, or a null pointer
Token *scan_string(char **buf) {
  char *starting_buf = *buf;
  static int in_multiline_comment = false;
  char c = read_character(buf);

  if (in_multiline_comment) {
    if (c == '*') {
      if (read_character(buf) == '/') {
        in_multiline_comment = false;
        return token_new(COMMENT, "/* ... */", 9); 
      } 
      unread_character(buf);
    }
    if (c != '\0') {
      return scan_string(buf); 
    }
  }

  switch(c) {
    case ':':
      if (read_character(buf) == '=') {
        return token_new(ASSIGN, ":=", 2);
      } 
      unread_character(buf);
    case '+':
      return token_new(PLUS, "+", 1);
    case '-':
      return token_new(MINUS, "-", 1);
    case '*':
      return token_new(TIMES, "*", 1);
    case '/':
      c = read_character(buf);
      if (c == '/') {
        int len = 2;
        while ((c = read_character(buf)) && c != '\n' && c != EOF) {
          len++; 
        }
        unread_character(buf);
        return token_new(COMMENT, *buf - len, len);
      } else if (c == '*' && !in_multiline_comment) {
        in_multiline_comment = true;
        return scan_string(buf);
      }
      unread_character(buf); 
      return token_new(DIV, "/", 1);
    case '(':
      return token_new(LPAREN, "(", 1);
    case ')':
      return token_new(RPAREN, ")", 1);
    case ' ':
    case '\t':
    case '\n':
      return scan_string(buf);
    case '\0':
    case EOF:
      return NULL;
  }
  // try and parse an identifer or keyword
  if (isalpha(c)) {
    // check if keyword 
    char *keywords[] = {"read", "write"};
    int keywords_len = 2;
    for (int i = 0; i < keywords_len; i++) {
      if (strncmp(*buf - 1, keywords[i], strlen(keywords[i])) == 0) {
        *buf += strlen(keywords[i]) - 1; 
        return token_new(KEYWORD, keywords[i], strlen(keywords[i]));
      }
    }

    // parse as identifer
    int len = 1;
    while ((c = read_character(buf)) && isalnum(c)) {
      len++; 
    }
    // unread the character that broke the while loop
    unread_character(buf);
    return token_new(IDENTIFIER, *buf - len, len);
  }

  if (isdigit(c) || c == '.') {
    // parse as digit
    int len = 1;
    int dot_found = (c == '.');
    while ((c = read_character(buf))) {
      if (c == '.') {
        if (dot_found) {
          break;
        } 
        dot_found = true;
      } else if (!isdigit(c)) {
        break;
      } 
      len++;
    }  
    // unread the character that broke the while loop
    unread_character(buf);
    return token_new(NUMBER, *buf - len, len);
  }

  char debug_str[2] = {c, '\0'};
  return token_new(INVALID, debug_str, 1);
}
示例#18
0
int
main (int argc, char *argv[])
{
  const unsigned char *p, *eof;
  int i;
  const char *error_string;
  struct stat sb;

  Marpa_Config marpa_configuration;

  Marpa_Grammar g;
  Marpa_Recognizer r;
  /* Longest rule is 4 symbols */
  Marpa_Symbol_ID rhs[4];

  int fd = open (argv[1], O_RDONLY);
  //initialize a stat for getting the filesize
  if (fstat (fd, &sb) == -1)
    {
      perror ("fstat");
      return 1;
    }
  //do the actual mmap, and keep pointer to the first element
  p = (unsigned char *) mmap (0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
  //something went wrong
  if (p == MAP_FAILED)
    {
      perror ("mmap");
      return 1;
    }

  marpa_c_init (&marpa_configuration);
  g = marpa_g_new (&marpa_configuration);
  if (!g)
    {
      Marpa_Error_Code errcode =
        marpa_c_error (&marpa_configuration, &error_string);
      printf ("marpa_g_new returned %d: %s", errcode, error_string);
      exit (1);
    }

  ((S_begin_array = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_begin_object = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_end_array = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_end_object = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_name_separator = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_value_separator = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_member = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_value = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g);
  ((S_false = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g);
  ((S_null = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g);
  ((S_true = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g);
  ((S_object = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_array = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g);
  ((S_number = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_string = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_object_contents = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);
  ((S_array_contents = marpa_g_symbol_new (g)) >= 0)
    || fail ("marpa_g_symbol_new", g);

  rhs[0] = S_false;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);
  rhs[0] = S_null;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);
  rhs[0] = S_true;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);
  rhs[0] = S_object;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);
  rhs[0] = S_array;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);
  rhs[0] = S_number;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);
  rhs[0] = S_string;
  (marpa_g_rule_new (g, S_value, rhs, 1) >= 0)
    || fail ("marpa_g_rule_new", g);

  rhs[0] = S_begin_array;
  rhs[1] = S_array_contents;
  rhs[2] = S_end_array;
  (marpa_g_rule_new (g, S_array, rhs, 3) >= 0)
    || fail ("marpa_g_rule_new", g);

  rhs[0] = S_begin_object;
  rhs[1] = S_object_contents;
  rhs[2] = S_end_object;
  (marpa_g_rule_new (g, S_object, rhs, 3) >= 0)
    || fail ("marpa_g_rule_new", g);

  (marpa_g_sequence_new
   (g, S_array_contents, S_value, S_value_separator, 0,
    MARPA_PROPER_SEPARATION) >= 0) || fail ("marpa_g_sequence_new", g);
  (marpa_g_sequence_new
   (g, S_object_contents, S_member, S_value_separator, 0,
    MARPA_PROPER_SEPARATION) >= 0) || fail ("marpa_g_sequence_new", g);

  rhs[0] = S_string;
  rhs[1] = S_name_separator;
  rhs[2] = S_value;
  (marpa_g_rule_new (g, S_member, rhs, 3) >= 0)
    || fail ("marpa_g_rule_new", g);

  if (0)
    {
      (marpa_g_symbol_is_terminal_set (g, S_value_separator, 1) >= 0) ||
        fail ("marpa_g_symbol_is_terminal", g);
    }

  (marpa_g_start_symbol_set (g, S_value) >= 0)
    || fail ("marpa_g_start_symbol_set", g);
  if (marpa_g_precompute (g) < 0)
    {
      marpa_g_error (g, &error_string);
      puts (error_string);
      exit (1);
    }
  r = marpa_r_new (g);
  if (!r)
    {
      marpa_g_error (g, &error_string);
      puts (error_string);
      exit (1);
    }
  if (!marpa_r_start_input (r))
    {
      marpa_g_error (g, &error_string);
      puts (error_string);
      exit (1);
    }

  i = 0;
  eof = p + sb.st_size;
  while (p + i < eof)
    {
      Marpa_Symbol_ID token;
      const int start_of_token = i;

      switch (p[i])
        {
        case '-':
        case '+':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          i = scan_number (p + i, eof) - p;
          token = S_number;
          break;
        case '"':
          i = scan_string (p + i, eof) - p;
          token = S_string;
          break;
        case '[':
          token = S_begin_array;
          i++;
          break;
        case ']':
          token = S_end_array;
          i++;
          break;
        case '{':
          token = S_begin_object;
          i++;
          break;
        case '}':
          token = S_end_object;
          i++;
          break;
        case ',':
          token = S_value_separator;
          i++;
          break;
        case ':':
          token = S_name_separator;
          i++;
          break;
        case 'n':
          i = scan_constant ("null", (p + i), eof) - p;
          token = S_null;
          break;
        case ' ':
        case 0x09:
        case 0x0A:
        case 0x0D:
          i++;
          goto NEXT_TOKEN;
        default:
          marpa_g_error (g, &error_string);
          printf ("lexer failed at char %d: '%c'", i, p[i]);
          exit (1);
        }
      /* Token value of zero is not allowed, so we add one */
      if (0)
        fprintf (stderr, "reading token %ld, %s\n",
                 (long) token, symbol_name (token));
      int status = marpa_r_alternative (r, token, start_of_token + 1, 1);
      if (status != MARPA_ERR_NONE)
        {
          Marpa_Symbol_ID expected[20];
          int count_of_expected = marpa_r_terminals_expected (r, expected);
          int i;
          for (i = 0; i < count_of_expected; i++)
            {
              fprintf (stderr, "expecting symbol %ld, %s\n",
                       (long) i, symbol_name (expected[i]));
            }
          marpa_g_error (g, &error_string);
          fprintf (stderr,
                   "marpa_alternative(%p,%ld,%s,%ld,1) returned %d: %s", r,
                   (long) token, symbol_name (token),
                   (long) (start_of_token + 1), status, error_string);
          exit (1);
        }
      status = marpa_r_earleme_complete (r);
      if (status < 0)
        {
          marpa_g_error (g, &error_string);
          printf ("marpa_earleme_complete returned %d: %s", status,
                  error_string);
          exit (1);
        }
    NEXT_TOKEN:;
    }

  {
    Marpa_Bocage bocage;
    Marpa_Order order;
    Marpa_Tree tree;
    bocage = marpa_b_new (r, -1);
    if (!bocage)
      {
        int errcode = marpa_g_error (g, &error_string);
        printf ("marpa_bocage_new returned %d: %s", errcode, error_string);
        exit (1);
      }
    order = marpa_o_new (bocage);
    if (!order)
      {
        int errcode = marpa_g_error (g, &error_string);
        printf ("marpa_order_new returned %d: %s", errcode, error_string);
        exit (1);
      }
    tree = marpa_t_new (order);
    if (!tree)
      {
        Marpa_Error_Code errcode = marpa_g_error (g, &error_string);
        printf ("marpa_t_new returned %d: %s", errcode, error_string);
        exit (1);
      }
    {
      Marpa_Value value = NULL;
      int column = 0;
      int tree_status;
      tree_status = marpa_t_next (tree);
      if (tree_status <= -1)
        {
          Marpa_Error_Code errcode = marpa_g_error (g, &error_string);
          printf ("marpa_t_next returned %d: %s", errcode, error_string);
          exit (1);
        }

      value = marpa_v_new (tree);
      if (!value)
        {
          Marpa_Error_Code errcode = marpa_g_error (g, &error_string);
          printf ("marpa_v_new returned %d: %s", errcode, error_string);
          exit (1);
        }
      while (1)
        {
          Marpa_Step_Type step_type = marpa_v_step (value);
          Marpa_Symbol_ID token;
          if (step_type < 0)
            {
              Marpa_Error_Code errcode = marpa_g_error (g, &error_string);
              printf ("marpa_v_event returned %d: %s", errcode, error_string);
              exit (1);
            }
          if (step_type == MARPA_STEP_INACTIVE)
            {
              if (0)
                printf ("No more events\n");
              break;
            }
          if (step_type != MARPA_STEP_TOKEN)
            continue;
          token = marpa_v_token (value);
          if (1)
            {
              if (column > 60)
                {
                  putchar ('\n');
                  column = 0;
                }
              if (token == S_begin_array)
                {
                  putchar ('[');
                  column++;
                  continue;
                }
              if (token == S_end_array)
                {
                  putchar (']');
                  column++;
                  continue;
                }
              if (token == S_begin_object)
                {
                  putchar ('{');
                  column++;
                  continue;
                }
              if (token == S_end_object)
                {
                  putchar ('}');
                  column++;
                  continue;
                }
              if (token == S_name_separator)
                {
                  putchar (':');
                  column++;
                  continue;
                }
              if (token == S_value_separator)
                {
                  putchar (',');
                  column++;
                  continue;
                }
              if (token == S_null)
                {
                  fputs ("undef", stdout);
                  column += 5;
                  continue;
                }
              if (token == S_true)
                {
                  putchar ('1');
                  column++;
                  continue;
                }
              if (token == S_false)
                {
                  putchar ('0');
                  column++;
                  continue;
                }
              if (token == S_number)
                {
                  /* We added one to avoid zero
                   * Now we must subtract it
                   */
                  int i;
                  const int start_of_number = marpa_v_token_value (value) - 1;
                  const int end_of_number =
                    scan_number (p + start_of_number, eof) - p;
                  column += 2 + (end_of_number - start_of_number);

                  /* We output numbers as Perl strings */
                  putchar ('"');
                  for (i = start_of_number; i < end_of_number; i++)
                    {
                      putchar (p[i]);
                    }
                  putchar ('"');
                  continue;
                }
              if (token == S_string)
                {
                  /* We added one to avoid zero
                   * Now we must subtract it, but we also
                   * add one for the initial double quote
                   */
                  int i;
                  const int start_of_string = marpa_v_token_value (value);
                  /* Subtract one for the final double quote */
                  const int end_of_string =
                    (scan_string (p + start_of_string, eof) - p) - 1;

                  /* We add back the inital and final double quotes,
                   * and increment the column accordingly.
                   */
                  column += 2;
                  putchar ('"');
                  i = start_of_string;
                  while (i < end_of_string)
                    {
                      const unsigned char ch0 = p[i++];
                      if (ch0 == '\\')
                        {
                          const unsigned char ch1 = p[i++];
                          switch (ch1)
                            {
                            case '\\':
                            case '/':
                            case '"':
                            case 'b':
                            case 'f':
                            case 'n':
                            case 'r':
                            case 't':
                              /* explicit non-hex JSON escapes are the same
                               * as the Perl escapes */
                              column += 2;
                              putchar ('\\');
                              putchar (ch1);
                              continue;
                            case 'u':
                              {
                                int digit;
                                putchar ('x');
                                putchar ('{');
                                for (digit = 0; digit < 4; digit++)
                                  {
                                    const unsigned char hex_ch = p[i + digit];
                                    if ((hex_ch >= 'a' && hex_ch <= 'f')
                                        || (hex_ch >= 'A' && hex_ch <= 'F')
                                        || (hex_ch >= '0' && hex_ch <= '9'))
                                      {
                                        printf
                                          ("illegal char in JSON hex number at location %d (0x%x): '%c' ",
                                           i, hex_ch, hex_ch);
                                        exit (1);
                                      }
                                    putchar (hex_ch);
                                  }
                                putchar ('}');
                                column += 7;
                                i += 4;
                              }
                              continue;
                            default:
                              printf
                                ("illegal escaped char in JSON input (0x%x):'%c' ",
                                 i, p[i]);
                              exit (1);
                            }
                        }

                      /* An unescaped JSON char, one that does not need Perl escaping */
                      if (ch0 == '_' || (ch0 >= '0' && ch0 <= '9')
                          || (ch0 >= 'a' && ch0 <= 'z') || (ch0 >= 'A'
                                                            && ch0 <= 'Z'))
                        {
                          putchar (ch0);
                          column++;
                          continue;
                        }
                      /* An unescaped JSON char,
                       * but one which quotemeta would escape for Perl */
                      putchar ('\\');
                      putchar (ch0);
                      column += 2;
                      continue;
                    }
                  putchar ('"');
                  continue;
                }
              fprintf (stderr, "Unknown symbol %s at %d",
                       symbol_name (token), marpa_v_token_value (value) - 1);
              exit (1);
            }
        }
      if (column > 60)
        {
          putchar ('\n');
          column = 0;
        }
    }
  }

  return 0;
}
示例#19
0
文件: recipy.c 项目: cmatei/GCX
void fscan_recipy(FILE *fp, struct vs_recipy *vs)
{
	char lb[RECIPY_TEXT + RECSYM_SIZE + 1];
	int ret;
	char *r, *val;

	if (fp == NULL)
		return;

	init_vs_recipy(vs);

	while ((r = fgets(lb, RECIPY_TEXT+16, fp)) != NULL) {
		ret = sym_lookup (lb, res_syms, &val);
		if (ret == -2) // commment, skip
			continue;
		if (ret == -1) {
			info_printf("fscan recipy: bad line: %s\n", lb);
			continue;
		}
		switch (ret) {
		case 1:
			scan_string(vs->objname, val, RECIPY_TEXT);
			break;
		case 2:
			scan_string(vs->chart, val, RECIPY_TEXT);
			break;
		case 3:
			scan_string(vs->frame, val, RECIPY_TEXT);
			break;
		case 4:
			scan_double(&(vs->p.r1), val);
			break;
		case 5:
			scan_double(&(vs->p.r2), val);
			break;
		case 6:
			scan_double(&(vs->p.r3), val);
			break;
		case 7:
			scan_int(&(vs->p.quads), val);
			break;
		case 8:
			scan_int(&(vs->p.sky_method), val);
			break;
		case 9:
			scan_double(&(vs->p.sigmas), val);
			break;
		case 10:
			scan_int(&(vs->p.max_iter), val);
			break;
		case 11:
			scan_int(&(vs->usewcs), val);
			break;
		case 12:
			scan_ra(&(vs->ra), val);
			break;
		case 13:
			scan_dec(&(vs->dec), val);
			break;
		case 14:
			ret = radd_std_star(vs, val);
			break;
		case 15:
			ret = radd_pgm_star(vs, val);
			break;
		case 16:
			scan_double(&(vs->p.sat_limit), val);
			break;
		case 17:
			scan_string(vs->repstar, val, RECIPY_TEXT);
			break;
		case 18:
			scan_string(vs->repinfo, val, RECIPY_TEXT);
			break;
		case 19:
			scan_double(&(vs->scint_factor), val);
			break;
		case 20:
			scan_double(&(vs->aperture), val);
			break;
		case 21:
			scan_double(&(vs->airmass), val);
			break;
		};
	}
}
示例#20
0
int
stream_vscanf (stream_t *stream,
	const char *fmt,		/* Format string for the scanf */
	va_list argp)			/* Arguments to scanf */
#endif
{
	unsigned char ch, size;
	unsigned base;
	unsigned short len;
	int nmatch, ic;
	void *ptr;
	const char *pattern = 0;

	nmatch = 0;
	for (;;) switch (ch = FETCH_BYTE (fmt++)) {
	case '\0':
		return nmatch;
	case '%':
		ch = FETCH_BYTE (fmt++);
		if (ch == '%')
			goto def;
		if (ch != '*')
			ptr = va_arg (argp, void*);
		else {
			ptr = 0;
			ch = FETCH_BYTE (fmt++);
		}
		len = 0;
		size = REGULAR;
		while (ch >= '0' && ch <= '9') {
			len = len*10 + ch - '0';
			ch = FETCH_BYTE (fmt++);
		}
		if (len == 0)
			len = 30000;

		if (ch == 'l') {
			ch = FETCH_BYTE (fmt++);
			size = LONG;
		} else if (ch == 'h') {
			size = SHORT;
			ch = FETCH_BYTE (fmt++);
		} else if (ch == '[') {
			pattern = fmt;
			ch = FETCH_BYTE (fmt);
			if (ch == '^')
				ch = FETCH_BYTE (++fmt);
			while (ch != 0 && ch != ']')
				ch = FETCH_BYTE (++fmt);
			if (ch != 0)
				++fmt;
			ch = '[';
		}

		if (ch >= 'A' && ch <= 'Z') {
			ch = ch + 'a' - 'A';
			size = LONG;
		}

		switch (ch) {
		case 0:
			return -1;
		case 'c':
			if (len == 30000)
				len = 1;
			goto string;
		case 's':
		case '[':
string:			if (scan_string (stream, (char*) ptr, ch, len,
			    pattern) && ptr)
				++nmatch;
			break;
		case 'o':
			base = 8 | snoUnsigned;
			goto number;
		case 'x':
			base = 16 | snoUnsigned;
			goto number;
		case 'd':
			base = 10;
            goto number;
        case 'u':
            base = 10 | snoUnsigned;
number:			if (scan_number (stream, ptr, base, len, size) && ptr)
				++nmatch;
			break;
		}

		if (feof (stream))
			return nmatch ? nmatch : -1;
		break;

	case ' ':
	case '\n':
	case '\t':
		/* Skip spaces. */
		for (;;) {
			ic = peekchar (stream);
			if (ic < 0)
				break;
			if (! ISSPACE ((unsigned char) ic))
				break;
			getchar (stream);
		}
		break;

	default:
def:		ic = peekchar (stream);
		if (ic < 0)
			return -1;
		if ((unsigned char) ic != ch)
			return nmatch;
		getchar (stream);
	}