Created
November 19, 2024 00:56
-
-
Save loicmolinari/4ca0107b5571bc9c5868cd5a85005e19 to your computer and use it in GitHub Desktop.
Extension parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Add extension flags to the bitfield that 'flags_out' points to. 'table' | |
| * stores extension names and flags to check for and 'extensions' is the list | |
| * usually returned by the EGL or GL implementation. New flags are stored using | |
| * a binary OR in order to keep flags set from a previous call. Caller must | |
| * ensure the bitfield is set to 0 at first call. | |
| */ | |
| void | |
| gl_extensions_add(const struct gl_extension_table *table, | |
| const char *extensions, | |
| uint64_t *flags_out) | |
| { | |
| struct { const char *str; size_t len, prev, next; } *list; | |
| size_t i = 0, n = 0; | |
| uint64_t flags = 0; | |
| char prev_char = ' '; | |
| /* Get number of supported extensions. */ | |
| while (extensions[i]) { | |
| if (prev_char == ' ' && extensions[i] != ' ') | |
| n++; | |
| prev_char = extensions[i++]; | |
| } | |
| if (n == 0) | |
| return; | |
| /* Allocate data structure storing each supported extension string with | |
| * their length. The 'prev' and 'next' members allow to skip extension | |
| * strings already matched using a linked list. There's an additional | |
| * entry to store the head of the list at index 0. */ | |
| list = xmalloc((n + 1) * sizeof *list); | |
| list[0].prev = list[0].len = i = 0; | |
| list[0].next = n = 1; | |
| list[0].str = NULL; | |
| prev_char = ' '; | |
| while (prev_char) { | |
| if (extensions[i] != ' ' && extensions[i] != '\0') { | |
| if (prev_char == ' ') | |
| list[n].str = &extensions[i]; | |
| } else if (prev_char != ' ') { | |
| list[n].len = &extensions[i] - list[n].str; | |
| list[n].prev = n - 1; | |
| list[n].next = n + 1; | |
| n++; | |
| } | |
| prev_char = extensions[i++]; | |
| } | |
| list[n - 1].next = 0; | |
| /* Match supported extensions not yet matched with table. */ | |
| for (; table->str && list[0].next; table++) { | |
| for (i = list[0].next; i; i = list[i].next) { | |
| if (table->len == list[i].len && | |
| !strncmp(table->str, list[i].str, table->len)) { | |
| list[list[i].prev].next = list[i].next; | |
| list[list[i].next].prev = list[i].prev; | |
| flags |= table->flag; | |
| break; | |
| } | |
| } | |
| } | |
| *flags_out |= flags; | |
| free(list); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment