示例#1
0
文件: csslex.c 项目: erkyrath/mincss
/* Parse a string. (Assume the leading quote has already been accepted.)
   Return the number of characters parsed. If the incoming text is not
   a valid string, push it back and return 0. 
   (But if we run into an unescaped newline, report an error and return
   the string so far, no pushback.)
*/
static int parse_string(mincss_context *context, int32_t delim)
{
    int count = 0;

    while (1) {
        int32_t ch = next_char(context);
        if (ch == -1) {
            mincss_note_error(context, "Unterminated string");
            return count;
        }
        count++;

        if (ch == delim)
            return count;

        if (ch == '\\') {
            int len = parse_universal_newline(context);
            if (len) {
                /* Backslashed newline: drop it. */
                erase_char(context, len+1);
                count -= 1;
                continue;
            }
            int32_t val = '?';
            len = parse_escaped_hex(context, &val);
            if (len) {
                /* Backslashed hex: drop the hex string... */
                erase_char(context, len);
                /* Replace the backslash itself with the named character. */
                context->token[context->tokenlen-1] = val;
                continue;
            }
            /* Any other character: take the next char literally
               (substitute it for the backslash). */
            ch = next_char(context);
            if (ch == -1) {
                mincss_note_error(context, "Unterminated string (ends with backslash)");
                return count;
            }
            erase_char(context, 1);
            context->token[context->tokenlen-1] = ch;
            continue;
        }

        /* If a string runs into an unescaped newline, we report an error
           and pretend the string ended. */
        if (ch == '\n' || ch == '\r' || ch == '\f') {
            mincss_note_error(context, "Unterminated string");
            return count;
        }
    }
}
示例#2
0
/**
 * Handle input on the line editor.
 *
 * @param editor        Line editor state.
 * @param key           Key that was pressed.
 */
void line_editor_input(line_editor_t *editor, uint16_t key) {
  switch (key) {
  case CONSOLE_KEY_LEFT:
    if (editor->offset) {
      console_putc(editor->console, '\b');
      editor->offset--;
    }

    break;
  case CONSOLE_KEY_RIGHT:
    if (editor->offset != editor->len) {
      console_putc(editor->console, editor->buf[editor->offset]);
      editor->offset++;
    }

    break;
  case CONSOLE_KEY_HOME:
    while (editor->offset) {
      console_putc(editor->console, '\b');
      editor->offset--;
    }

    break;
  case CONSOLE_KEY_END:
    while (editor->offset < editor->len) {
      console_putc(editor->console, editor->buf[editor->offset]);
      editor->offset++;
    }

    break;
  case '\b':
    erase_char(editor, false);
    break;
  case 0x7f:
    erase_char(editor, true);
    break;
  case '\n':
    /* The shell code sends \n to place it at the end of the buffer. */
    editor->offset = editor->len;
    insert_char(editor, key);
    break;
  default:
    if (isprint(key))
      insert_char(editor, key);

    break;
  }
}
示例#3
0
// See if a chunk matches a component
bool human_parse::match_component(std::string part, std::set < std::string > set_ref){
  
  // Clean up - erase periods and lowercase
  part = erase_char(part, ".");
  unsigned int input_size = part.size();
  for(unsigned int i = 0; i < input_size; i++){
    part[i] = tolower(part[i]);
  }
  
  // If the resulting string is in the set, it's a match!
  if(set_ref.find(part) != set_ref.end()){
    return true;
  }
  
  // Otherwise, it's not.
  return false;
}
示例#4
0
t_inst		*create_inst(char *s, int where, t_inst *head, int c)
{
	t_inst *maillon;

	maillon = (t_inst *)malloc(sizeof(t_inst));
	maillon->is_label = 0;
	maillon->where = -1;
	maillon->s = ft_strdup(erase_char(s));
	maillon->opcode = 0;
	if (!head)
	{
		maillon->value = find_opcode(s);
		maillon->size = 1;
		if (maillon->value == -1)
			bad_instruction(c);
		maillon->opcode = is_op(maillon->value);
	}
	else
		find_value(s, maillon, head, c);
	maillon->where = where;
	maillon->next = NULL;
	return (maillon);
}
示例#5
0
文件: csslex.c 项目: erkyrath/mincss
/* Grab the next token. Returns the tokentype. The token's text is available
   at context->token, length context->tokenlen.
*/
tokentype mincss_next_token(mincss_context *context)
{
    /* Discard all text in the buffer from the previous token. But if
       any characters were pushed back, keep those. */
    if (context->tokenlen) {
        int extra = context->tokenmark - context->tokenlen;
        if (extra > 0) {
            memmove(context->token, context->token+context->tokenlen, extra*sizeof(int32_t));
        }
        context->tokenlen = 0;
        context->tokenmark = extra;
    }

    context->tokendiv = 0;

    int32_t ch = next_char(context);
    if (ch == -1) {
        return tok_EOF;
    }

    /* Simple one-character tokens. */
    switch (ch) {
    case '(':
        return tok_LParen;
    case ')':
        return tok_RParen;
    case '[':
        return tok_LBracket;
    case ']':
        return tok_RBracket;
    case '{':
        return tok_LBrace;
    case '}':
        return tok_RBrace;
    case ':':
        return tok_Colon;
    case ';':
        return tok_Semicolon;

    /* Some cases that are more than one character, but still easy to take care of. */

    case '~': {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch == '=')
            return tok_Includes;
        putback_char(context, 1);
        return tok_Delim;
    }

    case '|': {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch == '=')
            return tok_DashMatch;
        putback_char(context, 1);
        return tok_Delim;
    }

    case '@': {
        int len = parse_ident(context, 0);
        if (len == 0) 
            return tok_Delim;
        return tok_AtKeyword;
    }

    case '#': {
        int len = parse_ident(context, 1);
        if (len == 1) 
            return tok_Delim;
        return tok_Hash;
    }

    /* Not proud of this next one. */
    case '<': {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch == '!') {
            ch = next_char(context);
            if (ch == -1) {
                putback_char(context, 1);
                return tok_Delim;
            }
            if (ch == '-') {
                ch = next_char(context);
                if (ch == -1) {
                    putback_char(context, 2);
                    return tok_Delim;
                }
                if (ch == '-') {
                    return tok_CDO;
                }
                putback_char(context, 3);
                return tok_Delim;
            }
            putback_char(context, 2);
            return tok_Delim;
        }
        putback_char(context, 1);
        return tok_Delim;
    }
    }

    if (IS_WHITESPACE(ch)) {
        while (1) {
            ch = next_char(context);
            if (ch == -1) 
                return tok_Space;
            if (!IS_WHITESPACE(ch)) {
                putback_char(context, 1);
                return tok_Space;
            }
            continue;
        }
    }

    if (ch == '"' || ch == '\'') {
        /* Strings begin with a single or double quote. */
        parse_string(context, ch);
        return tok_String;
    }

    if (IS_NUMBER_START(ch)) {
        /* Digits could begin a number, percentage, or dimension, depending
           on what's after them. */
        putback_char(context, 1);
        int numlen = parse_number(context);
        if (numlen == 0) {
            ch = next_char(context);
            return tok_Delim;
        }
        ch = next_char(context);
        if (ch == -1)
            return tok_Number;
        if (ch == '%')
            return tok_Percentage;
        if (ch == '-' || IS_IDENT_START(ch)) {
            /* ### doesn't check for backslash escapes */
            putback_char(context, 1);
            int numlen = context->tokenlen;
            int len = parse_ident(context, 0);
            if (len > 0) {
                context->tokendiv = numlen;
                return tok_Dimension;
            }
            else {
                return tok_Number;
            }
        }
        putback_char(context, 1);
        return tok_Number;
    }

    if (ch == '-' || IS_IDENT_START(ch)) {
        /* Ordinary identifiers. Note that minus signs always indicate
           identifiers, not numbers. (At least in CSS 2.1.) (Except
           that it might be a CDC --> token.) */

        ch = next_char(context);
        if (ch == -1) {
            /* Do nothing */
        }
        else if (ch == '-') {
            ch = next_char(context);
            if (ch == -1) {
                putback_char(context, 1);
            }
            else if (ch == '>') {
                return tok_CDC;
            }
            else {
                putback_char(context, 2);
            }
        }
        else {
            putback_char(context, 1);
        }

        putback_char(context, 1);
        int len = parse_ident(context, 0);
        if (len == 0) {
            ch = next_char(context);
            return tok_Delim;
        }
        if (len == 3 && match_accepted_chars(context, "url")) {
            int sublen = parse_uri_body(context);
            if (sublen > 0)
                return tok_URI;
        }
        /* If the following character is a left-paren, this is a function. */
        ch = next_char(context);
        if (ch == -1) 
            return tok_Ident;
        if (ch == '(')
            return tok_Function;
        putback_char(context, 1);
        return tok_Ident;
    }

    if (ch == '/') {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch != '*') {
            putback_char(context, 1);
            return tok_Delim;
        }
        int gotstar = 0;
        while (1) {
            ch = next_char(context);
            if (ch == -1) {
                mincss_note_error(context, "Unterminated comment");
                return tok_Comment;
            }
            if (ch == '/' && gotstar)
                return tok_Comment;
            gotstar = (ch == '*');
        }
    }

    if (ch == '\\') {
        /* A backslash which forms a hex escape is the start of an
           identifier. (Even if it's not a normal identifier-start
           character.) A backslashed nonwhite character starts an
           identifer as itself. A backslash before whitespace is
           a delimiter. */
        int len = parse_universal_newline(context);
        if (len) {
            /* Backslashed newline: put back the newline, accept the
               backslash. */
            putback_char(context, len);
            return tok_Delim;
        }
        int32_t val = '?';
        len = parse_escaped_hex(context, &val);
        if (len) {
            /* Backslashed hex: drop the hex string... */
            erase_char(context, len);
            /* Replace the backslash itself with the named character. */
            context->token[context->tokenlen-1] = val;
            /* Parse the rest of the identifier. */
            parse_ident(context, 1);
            /* If the following character is a left-paren, this is a function. */
            ch = next_char(context);
            if (ch == -1) 
                return tok_Ident;
            if (ch == '(')
                return tok_Function;
            putback_char(context, 1);
            return tok_Ident;
        }
        ch = next_char(context);
        if (ch == -1) {
            /* If there is no next character, take the backslash as a
               delimiter. */
            return tok_Delim;
        }
        /* Any other character: take the next char literally
           (substitute it for the backslash). */
        erase_char(context, 1);
        context->token[context->tokenlen-1] = ch;
        /* Parse the rest of the identifier. */
        parse_ident(context, 1);
        /* If the following character is a left-paren, this is a function. */
        ch = next_char(context);
        if (ch == -1) 
            return tok_Ident;
        if (ch == '(')
            return tok_Function;
        putback_char(context, 1);
        return tok_Ident;
    }

    /* Anything not captured above is a one-character Delim token. */
    return tok_Delim;
}
示例#6
0
文件: csslex.c 项目: erkyrath/mincss
/* Parse a URI. (Assume the leading "url" has already been accepted.)
   Return the number of characters parsed. If the incoming text is not
   a valid URI, push it back and return 0. 
*/
static int parse_uri_body(mincss_context *context)
{
    int count = 0;

    int32_t ch = next_char(context);
    if (ch == -1)
        return 0;
    count++;

    if (ch != '(') {
        putback_char(context, 1);
        return 0;
    }

    while (1) {
        ch = next_char(context);
        if (ch == -1) {
            putback_char(context, count);
            return 0;
        }
        count++;
        if (IS_WHITESPACE(ch))
            continue;
        break;
    }

    if (ch < ' ' || ch == '(' || ch == ')' || (ch > '~' && ch < 0xA0 && ch != '\\')) {
        /* Invalid characters for a URL body. */
        putback_char(context, count);
        return 0;
    }

    if (ch == '"' || ch == '\'') {
        /* The quoted case. */
        int len = parse_string(context, ch);
        if (!len) {
            putback_char(context, count);
            return 0;
        }
        count += len;
    }
    else {
        /* The unquoted case. We put back the initial char in case it was a backslash. */
        putback_char(context, 1);
        count -= 1;
        while (1) {
            ch = next_char(context);
            if (ch == -1) {
                putback_char(context, count);
                return 0;
            }
            count++;
            if (ch == '\\') {
                int len = parse_universal_newline(context);
                if (len) {
                    /* Backslashed newline: drop it. */
                    erase_char(context, len+1);
                    count -= 1;
                    continue;
                }
                int32_t val = '?';
                len = parse_escaped_hex(context, &val);
                if (len) {
                    /* Backslashed hex: drop the hex string... */
                    erase_char(context, len);
                    /* Replace the backslash itself with the named character. */
                    context->token[context->tokenlen-1] = val;
                    continue;
                }
                /* Any other character: take the next char literally
                   (substitute it for the backslash). */
                ch = next_char(context);
                if (ch == -1) {
                    mincss_note_error(context, "Unterminated URI (ends with backslash)");
                    return count;
                }
                erase_char(context, 1);
                context->token[context->tokenlen-1] = ch;
                continue;
            }
            if (ch < ' ' || ch == '"' || ch == '\'' || ch == '(' || ch == ')' || ch == '\\' || (ch > '~' && ch < 0xA0)) {
                putback_char(context, 1);
                count -= 1;
                break;
            }
            continue;
        }

    }

    /* Chew up trailing whitespace and the close-paren. */
    while (1) {
        ch = next_char(context);
        if (ch == -1) {
            putback_char(context, count);
            return 0;
        }
        count++;
        if (IS_WHITESPACE(ch))
            continue;
        if (ch == ')')
            break;
        putback_char(context, count);
        return 0;
    }
    
    return count;    
}
示例#7
0
文件: csslex.c 项目: erkyrath/mincss
/* Parse an identifier.
   Return the number of characters parsed. If the incoming text is not
   an identifier, push it back and return 0.
   If gotstart is false, the initial character must be read. If true,
   it's already accepted.
   (This is also used to parse #hash tokens. In that case, gotstart is
   true, but the initial character is the hash.)
*/
static int parse_ident(mincss_context *context, int gotstart)
{
    int count = 0;
    int32_t ch = 0;

    if (!gotstart) {
        ch = next_char(context);
        if (ch == -1)
            return 0;
        count++;

        /* We can start with a minus, but only if the following character
           is a legit ident-start character *or* an escape. */
        if (ch == '-') {
            ch = next_char(context);
            if (ch == -1) {
                putback_char(context, count);
                return 0;
            }
            count++;
        }
        
        if (ch == '\\') {
            int len = parse_universal_newline(context);
            if (len) {
                /* Backslashed newline: put back both, exit. */
                putback_char(context, 1+len);
                return count-(1+len);
            }
            int32_t val = '?';
            len = parse_escaped_hex(context, &val);
            if (len) {
                /* Backslashed hex: drop the hex string... */
                erase_char(context, len);
                /* Replace the backslash itself with the named character. */
                context->token[context->tokenlen-1] = val;
            }
            else {
                ch = next_char(context);
                if (ch == -1) {
                    /* If there is no next character, put the backslash back
                       and exit. */
                    putback_char(context, 1);
                    return count-1;
                }
                /* Any other character: take the next char literally
                   (substitute it for the backslash). */
                erase_char(context, 1);
                context->token[context->tokenlen-1] = ch;
            }
        }
        else {
            /* Note that Unicode characters from 0xA0 on can *all* be used in
               identifiers. IS_IDENT_START includes these. */
            if (!IS_IDENT_START(ch)) {
                putback_char(context, count);
                return 0;
            }
        }
    }
    else {
        count = 1;
    }

    while (1) {
        ch = next_char(context);
        if (ch == -1) 
            return count;
        count++;

        if (ch == '\\') {
            int len = parse_universal_newline(context);
            if (len) {
                /* Backslashed newline: put back both, exit. */
                putback_char(context, 1+len);
                return count-(1+len);
            }
            int32_t val = '?';
            len = parse_escaped_hex(context, &val);
            if (len) {
                /* Backslashed hex: drop the hex string... */
                erase_char(context, len);
                /* Replace the backslash itself with the named character. */
                context->token[context->tokenlen-1] = val;
                continue;
            }
            ch = next_char(context);
            if (ch == -1) {
                /* If there is no next character, put the backslash back
                   and exit. */
                putback_char(context, 1);
                return count-1;
            }
            /* Any other character: take the next char literally
               (substitute it for the backslash). */
            erase_char(context, 1);
            context->token[context->tokenlen-1] = ch;
            continue;
        }

        if (!(IS_IDENT_START(ch) || (ch == '-') || (ch >= '0' && ch <= '9'))) {
            putback_char(context, 1);
            return count-1;
        }
        continue;
    }
}
示例#8
0
int main( int argc, char *argv[] )
{
    std::stringstream in;
    std::stringstream out;
    std::string filename;
    std::string header;

    char *gateway_var = getenv( "GATEWAY_INTERFACE" );
    if( gateway_var == nullptr ) {
        // Expect a single filename for now.
        if( argc == 2 ) {
            filename = argv[1];
        } else if( argc != 1 ) {
            std::cout << "Supply a filename to style or no arguments." << std::endl;
            exit( EXIT_FAILURE );
        }

        if( filename.empty() ) {
            in << std::cin.rdbuf();
        } else {
            std::ifstream fin( filename, std::ios::binary );
            if( !fin.good() ) {
                std::cout << "Failed to open " << filename << std::endl;
                exit( EXIT_FAILURE );
            }
            in << fin.rdbuf();
            fin.close();
        }
    } else {
        std::map<std::string, std::string> params;
        initializePost( params );
        std::string data = params[ "data" ];
        if( data.empty() ) {
            exit( -255 );
        }
        in.str( data );
        header = "Content-type: application/json\n\n";
    }

    if( in.str().size() == 0 ) {
        std::cout << "Error, input empty." << std::endl;
        exit( EXIT_FAILURE );
    }
    JsonOut jsout( out, true );
    JsonIn jsin( in );

    format( jsin, jsout );

    out << std::endl;

    if( filename.empty() ) {
        std::cout << header;
        std::cout << out.str();
    } else {
        std::string in_str = in.str();
#ifdef MSYS2
        erase_char( in_str, '\r' );
#endif
        if( in_str == out.str() ) {
            std::cout << "Unformatted " << filename << std::endl;
            exit( EXIT_SUCCESS );
        } else {
            std::ofstream fout( filename, std::ios::binary | std::ios::trunc );
            fout << out.str();
            fout.close();
            std::cout << "Formatted " << filename << std::endl;
            exit( EXIT_FAILURE );
        }
    }
}