⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grammar.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
            bytepool_destroy (by);    }}static int bytepool_reserve (bytepool *by, unsigned int n){    byte *_P;    if (n <= by->_Siz)        return 0;    /* byte pool can only grow and at least by doubling its size */    n = n >= by->_Siz * 2 ? n : by->_Siz * 2;    /* reallocate the memory and adjust pointers to the new memory location */    _P = (byte *) (mem_realloc (by->_F, sizeof (byte) * by->_Siz, sizeof (byte) * n));    if (_P != NULL)    {        by->_F = _P;        by->_Siz = n;        return 0;    }    return 1;}/*    string to string map typedef*/typedef struct map_str_{    byte *key;    byte *data;    struct map_str_ *next;} map_str;static void map_str_create (map_str **ma){    *ma = (map_str *) mem_alloc (sizeof (map_str));    if (*ma)    {        (**ma).key = NULL;        (**ma).data = NULL;        (**ma).next = NULL;    }}static void map_str_destroy (map_str **ma){    if (*ma)    {        map_str_destroy (&(**ma).next);        mem_free ((void **) &(**ma).key);        mem_free ((void **) &(**ma).data);        mem_free ((void **) ma);    }}GRAMMAR_IMPLEMENT_LIST_APPEND(map_str)/*    searches the map for specified key,    if the key is matched, *data is filled with data associated with the key,    returns 0 if the key is matched,    returns 1 otherwise*/static int map_str_find (map_str **ma, const byte *key, byte **data){    while (*ma)    {        if (str_equal ((**ma).key, key))        {            *data = str_duplicate ((**ma).data);            if (*data == NULL)                return 1;            return 0;        }        ma = &(**ma).next;    }    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);    return 1;}/*    string to rule map typedef*/typedef struct map_rule_{    byte *key;    rule *data;    struct map_rule_ *next;} map_rule;static void map_rule_create (map_rule **ma){    *ma = (map_rule *) mem_alloc (sizeof (map_rule));    if (*ma)    {        (**ma).key = NULL;        (**ma).data = NULL;        (**ma).next = NULL;    }}static void map_rule_destroy (map_rule **ma){    if (*ma)    {        map_rule_destroy (&(**ma).next);        mem_free ((void **) &(**ma).key);        mem_free ((void **) ma);    }}GRAMMAR_IMPLEMENT_LIST_APPEND(map_rule)/*    searches the map for specified key,    if the key is matched, *data is filled with data associated with the key,    returns 0 if the is matched,    returns 1 otherwise*/static int map_rule_find (map_rule **ma, const byte *key, rule **data){    while (*ma)    {        if (str_equal ((**ma).key, key))        {            *data = (**ma).data;            return 0;        }        ma = &(**ma).next;    }    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);    return 1;}/*    returns 1 if given character is a white space,    returns 0 otherwise*/static int is_space (byte c){    return c == ' ' || c == '\t' || c == '\n' || c == '\r';}/*    advances text pointer by 1 if character pointed by *text is a space,    returns 1 if a space has been eaten,    returns 0 otherwise*/static int eat_space (const byte **text){    if (is_space (**text))    {        (*text)++;        return 1;    }    return 0;}/*    returns 1 if text points to C-style comment start string,    returns 0 otherwise*/static int is_comment_start (const byte *text){    return text[0] == '/' && text[1] == '*';}/*    advances text pointer to first character after C-style comment block - if any,    returns 1 if C-style comment block has been encountered and eaten,    returns 0 otherwise*/static int eat_comment (const byte **text){    if (is_comment_start (*text))    {        /* *text points to comment block - skip two characters to enter comment body */        *text += 2;        /* skip any character except consecutive '*' and '/' */        while (!((*text)[0] == '*' && (*text)[1] == '/'))            (*text)++;        /* skip those two terminating characters */        *text += 2;        return 1;    }    return 0;}/*    advances text pointer to first character that is neither space nor C-style comment block*/static void eat_spaces (const byte **text){    while (eat_space (text) || eat_comment (text))        ;}/*    resizes string pointed by *ptr to successfully add character c to the end of the string,    returns 0 on success,    returns 1 otherwise*/static int string_grow (byte **ptr, unsigned int *len, byte c){    /* reallocate the string in 16-byte increments */    if ((*len & 0x0F) == 0x0F || *ptr == NULL)    {        byte *tmp = (byte *) mem_realloc (*ptr, ((*len + 1) & ~0x0F) * sizeof (byte),            ((*len + 1 + 0x10) & ~0x0F) * sizeof (byte));        if (tmp == NULL)            return 1;        *ptr = tmp;    }    if (c)    {        /* append given character */        (*ptr)[*len] = c;        (*len)++;    }    (*ptr)[*len] = '\0';    return 0;}/*    returns 1 if given character is a valid identifier character a-z, A-Z, 0-9 or _    returns 0 otherwise*/static int is_identifier (byte c){    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';}/*    copies characters from *text to *id until non-identifier character is encountered,    assumes that *id points to NULL object - caller is responsible for later freeing the string,    text pointer is advanced to point past the copied identifier,    returns 0 if identifier was successfully copied,    returns 1 otherwise*/static int get_identifier (const byte **text, byte **id){    const byte *t = *text;    byte *p = NULL;    unsigned int len = 0;    if (string_grow (&p, &len, '\0'))        return 1;    /* loop while next character in buffer is valid for identifiers */    while (is_identifier (*t))    {        if (string_grow (&p, &len, *t++))        {            mem_free ((void **) (void *) &p);            return 1;        }    }    *text = t;    *id = p;    return 0;}/*    converts sequence of DEC digits pointed by *text until non-DEC digit is encountered,    advances text pointer past the converted sequence,    returns the converted value*/static unsigned int dec_convert (const byte **text){    unsigned int value = 0;    while (**text >= '0' && **text <= '9')    {        value = value * 10 + **text - '0';        (*text)++;    }    return value;}/*    returns 1 if given character is HEX digit 0-9, A-F or a-f,    returns 0 otherwise*/static int is_hex (byte c){    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');}/*    returns value of passed character as if it was HEX digit*/static unsigned int hex2dec (byte c){    if (c >= '0' && c <= '9')        return c - '0';    if (c >= 'A' && c <= 'F')        return c - 'A' + 10;    return c - 'a' + 10;}/*    converts sequence of HEX digits pointed by *text until non-HEX digit is encountered,    advances text pointer past the converted sequence,    returns the converted value*/static unsigned int hex_convert (const byte **text){    unsigned int value = 0;    while (is_hex (**text))    {        value = value * 0x10 + hex2dec (**text);        (*text)++;    }    return value;}/*    returns 1 if given character is OCT digit 0-7,    returns 0 otherwise*/static int is_oct (byte c){    return c >= '0' && c <= '7';}/*    returns value of passed character as if it was OCT digit*/static int oct2dec (byte c){    return c - '0';}static byte get_escape_sequence (const byte **text){    int value = 0;    /* skip '\' character */    (*text)++;    switch (*(*text)++)    {    case '\'':        return '\'';    case '"':        return '\"';    case '?':        return '\?';    case '\\':        return '\\';    case 'a':        return '\a';    case 'b':        return '\b';    case 'f':        return '\f';    case 'n':        return '\n';    case 'r':        return '\r';    case 't':        return '\t';    case 'v':        return '\v';    case 'x':        return (byte) hex_convert (text);    }    (*text)--;    if (is_oct (**text))    {        value = oct2dec (*(*text)++);        if (is_oct (**text))        {            value = value * 010 + oct2dec (*(*text)++);            if (is_oct (**text))                value = value * 010 + oct2dec (*(*text)++);        }    }    return (byte) value;}/*    copies characters from *text to *str until " or ' character is encountered,    assumes that *str points to NULL object - caller is responsible for later freeing the string,    assumes that *text points to " or ' character that starts the string,    text pointer is advanced to point past the " or ' character,    returns 0 if string was successfully copied,    returns 1 otherwise*/static int get_string (const byte **text, byte **str){    const byte *t = *text;    byte *p = NULL;    unsigned int len = 0;    byte term_char;    if (string_grow (&p, &len, '\0'))        return 1;    /* read " or ' character that starts the string */    term_char = *t++;    /* while next character is not the terminating character */    while (*t && *t != term_char)    {        byte c;        if (*t == '\\')            c = get_escape_sequence (&t);        else            c = *t++;        if (string_grow (&p, &len, c))        {            mem_free ((void **) (void *) &p);            return 1;        }    }    /* skip " or ' character that ends the string */    t++;    *text = t;    *str = p;    return 0;}/*    gets emit code, the syntax is:    ".emtcode" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character>    assumes that *text already points to <symbol>,    returns 0 if emit code is successfully read,    returns 1 otherwise*/static int get_emtcode (const byte **text, map_byte **ma){    const byte *t = *text;    map_byte *m = NULL;    map_byte_create (&m);    if (m == NULL)        return 1;    if (get_identifier (&t, &m->key))    {        map_byte_destroy (&m);        return 1;    }    eat_spaces (&t);    if (*t == '\'')    {        byte *c;        if (get_string (&t, &c))        {            map_byte_destroy (&m);            return 1;        }        m->data = (byte) c[0];        mem_free ((void **) (void *) &c);    }    else if (t[0] == '0' && (t[1] == 'x' || t[1] == 'X'))    {        /* skip HEX "0x" or "0X" prefix */        t += 2;        m->data = (byte) hex_convert (&t);    }    else    {        m->data = (byte) dec_convert (&t);    }    eat_spaces (&t);    *text = t;    *ma = m;    return 0;}/*    gets regbyte declaration, the syntax is:    ".regbyte" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character>    assumes that *text already points to <symbol>,    returns 0 if regbyte is successfully read,    returns 1 otherwise

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -