"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/scanner.c" between
wayland-1.17.0.tar.xz and wayland-1.18.0.tar.xz

About: Wayland is a computer display server protocol for a compositor to talk to its clients and a library for Linux implementing that protocol.

scanner.c  (wayland-1.17.0.tar.xz):scanner.c  (wayland-1.18.0.tar.xz)
skipping to change at line 28 skipping to change at line 28
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
#include "config.h"
#include "wayland-version.h" #include "wayland-version.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <getopt.h> #include <getopt.h>
skipping to change at line 254 skipping to change at line 253
XML_Parser parser; XML_Parser parser;
struct protocol *protocol; struct protocol *protocol;
struct interface *interface; struct interface *interface;
struct message *message; struct message *message;
struct enumeration *enumeration; struct enumeration *enumeration;
struct description *description; struct description *description;
char character_data[8192]; char character_data[8192];
unsigned int character_data_length; unsigned int character_data_length;
}; };
enum identifier_role {
STANDALONE_IDENT,
TRAILING_IDENT
};
static void * static void *
fail_on_null(void *p) fail_on_null(void *p)
{ {
if (p == NULL) { if (p == NULL) {
fprintf(stderr, "%s: out of memory\n", PROGRAM_NAME); fprintf(stderr, "%s: out of memory\n", PROGRAM_NAME);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
return p; return p;
} }
skipping to change at line 630 skipping to change at line 634
/* check range */ /* check range */
if (ret < 0 || ret > INT_MAX) { if (ret < 0 || ret > INT_MAX) {
return -1; return -1;
} }
errno = prev_errno; errno = prev_errno;
return (int)ret; return (int)ret;
} }
/* Check that the provided string will produce valid "C" identifiers.
*
* If the string will form the prefix of an identifier in the
* generated C code, then it must match [_a-zA-Z][_0-9a-zA-Z]*.
*
* If the string will form the suffix of an identifier, then
* it must match [_0-9a-zA-Z]+.
*
* Unicode characters or escape sequences are not permitted,
* since not all C compilers support them.
*
* If the above conditions are not met, then fail()
*/
static void
validate_identifier(struct location *loc,
const char *str,
enum identifier_role role)
{
const char *scan;
if (!*str) {
fail(loc, "element name is empty");
}
for (scan = str; *scan; scan++) {
char c = *scan;
/* we do not use the locale-dependent `isalpha` */
bool is_alpha = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
bool is_digit = c >= '0' && c <= '9';
bool leading_char = (scan == str) && role == STANDALONE_IDENT;
if (is_alpha || c == '_' || (!leading_char && is_digit))
continue;
if (role == TRAILING_IDENT)
fail(loc,
"'%s' is not a valid trailing identifier part", str)
;
else
fail(loc,
"'%s' is not a valid standalone identifier", str);
}
}
static int static int
version_from_since(struct parse_context *ctx, const char *since) version_from_since(struct parse_context *ctx, const char *since)
{ {
int version; int version;
if (since != NULL) { if (since != NULL) {
version = strtouint(since); version = strtouint(since);
if (version == -1) { if (version == -1) {
fail(&ctx->loc, "invalid integer (%s)\n", since); fail(&ctx->loc, "invalid integer (%s)\n", since);
} else if (version > ctx->interface->version) { } else if (version > ctx->interface->version) {
skipping to change at line 703 skipping to change at line 751
enumeration_name = atts[i + 1]; enumeration_name = atts[i + 1];
if (strcmp(atts[i], "bitfield") == 0) if (strcmp(atts[i], "bitfield") == 0)
bitfield = atts[i + 1]; bitfield = atts[i + 1];
} }
ctx->character_data_length = 0; ctx->character_data_length = 0;
if (strcmp(element_name, "protocol") == 0) { if (strcmp(element_name, "protocol") == 0) {
if (name == NULL) if (name == NULL)
fail(&ctx->loc, "no protocol name given"); fail(&ctx->loc, "no protocol name given");
validate_identifier(&ctx->loc, name, STANDALONE_IDENT);
ctx->protocol->name = xstrdup(name); ctx->protocol->name = xstrdup(name);
ctx->protocol->uppercase_name = uppercase_dup(name); ctx->protocol->uppercase_name = uppercase_dup(name);
} else if (strcmp(element_name, "copyright") == 0) { } else if (strcmp(element_name, "copyright") == 0) {
} else if (strcmp(element_name, "interface") == 0) { } else if (strcmp(element_name, "interface") == 0) {
if (name == NULL) if (name == NULL)
fail(&ctx->loc, "no interface name given"); fail(&ctx->loc, "no interface name given");
if (version == 0) if (version == 0)
fail(&ctx->loc, "no interface version given"); fail(&ctx->loc, "no interface version given");
validate_identifier(&ctx->loc, name, STANDALONE_IDENT);
interface = create_interface(ctx->loc, name, version); interface = create_interface(ctx->loc, name, version);
ctx->interface = interface; ctx->interface = interface;
wl_list_insert(ctx->protocol->interface_list.prev, wl_list_insert(ctx->protocol->interface_list.prev,
&interface->link); &interface->link);
} else if (strcmp(element_name, "request") == 0 || } else if (strcmp(element_name, "request") == 0 ||
strcmp(element_name, "event") == 0) { strcmp(element_name, "event") == 0) {
if (name == NULL) if (name == NULL)
fail(&ctx->loc, "no request name given"); fail(&ctx->loc, "no request name given");
validate_identifier(&ctx->loc, name, STANDALONE_IDENT);
message = create_message(ctx->loc, name); message = create_message(ctx->loc, name);
if (strcmp(element_name, "request") == 0) if (strcmp(element_name, "request") == 0)
wl_list_insert(ctx->interface->request_list.prev, wl_list_insert(ctx->interface->request_list.prev,
&message->link); &message->link);
else else
wl_list_insert(ctx->interface->event_list.prev, wl_list_insert(ctx->interface->event_list.prev,
&message->link); &message->link);
if (type != NULL && strcmp(type, "destructor") == 0) if (type != NULL && strcmp(type, "destructor") == 0)
skipping to change at line 750 skipping to change at line 801
message->since = version; message->since = version;
if (strcmp(name, "destroy") == 0 && !message->destructor) if (strcmp(name, "destroy") == 0 && !message->destructor)
fail(&ctx->loc, "destroy request should be destructor typ e"); fail(&ctx->loc, "destroy request should be destructor typ e");
ctx->message = message; ctx->message = message;
} else if (strcmp(element_name, "arg") == 0) { } else if (strcmp(element_name, "arg") == 0) {
if (name == NULL) if (name == NULL)
fail(&ctx->loc, "no argument name given"); fail(&ctx->loc, "no argument name given");
validate_identifier(&ctx->loc, name, STANDALONE_IDENT);
arg = create_arg(name); arg = create_arg(name);
if (!set_arg_type(arg, type)) if (!set_arg_type(arg, type))
fail(&ctx->loc, "unknown type (%s)", type); fail(&ctx->loc, "unknown type (%s)", type);
switch (arg->type) { switch (arg->type) {
case NEW_ID: case NEW_ID:
ctx->message->new_id_count++; ctx->message->new_id_count++;
/* fallthrough */ /* fallthrough */
case OBJECT: case OBJECT:
if (interface_name) if (interface_name) {
validate_identifier(&ctx->loc,
interface_name,
STANDALONE_IDENT);
arg->interface_name = xstrdup(interface_name); arg->interface_name = xstrdup(interface_name);
}
break; break;
default: default:
if (interface_name != NULL) if (interface_name != NULL)
fail(&ctx->loc, "interface attribute not allowed for type %s", type); fail(&ctx->loc, "interface attribute not allowed for type %s", type);
break; break;
} }
if (allow_null) { if (allow_null) {
if (strcmp(allow_null, "true") == 0) if (strcmp(allow_null, "true") == 0)
arg->nullable = 1; arg->nullable = 1;
skipping to change at line 795 skipping to change at line 851
if (summary) if (summary)
arg->summary = xstrdup(summary); arg->summary = xstrdup(summary);
wl_list_insert(ctx->message->arg_list.prev, &arg->link); wl_list_insert(ctx->message->arg_list.prev, &arg->link);
ctx->message->arg_count++; ctx->message->arg_count++;
} else if (strcmp(element_name, "enum") == 0) { } else if (strcmp(element_name, "enum") == 0) {
if (name == NULL) if (name == NULL)
fail(&ctx->loc, "no enum name given"); fail(&ctx->loc, "no enum name given");
validate_identifier(&ctx->loc, name, TRAILING_IDENT);
enumeration = create_enumeration(name); enumeration = create_enumeration(name);
if (bitfield == NULL || strcmp(bitfield, "false") == 0) if (bitfield == NULL || strcmp(bitfield, "false") == 0)
enumeration->bitfield = false; enumeration->bitfield = false;
else if (strcmp(bitfield, "true") == 0) else if (strcmp(bitfield, "true") == 0)
enumeration->bitfield = true; enumeration->bitfield = true;
else else
fail(&ctx->loc, fail(&ctx->loc,
"invalid value (%s) for bitfield attribute (only tru e/false are accepted)", "invalid value (%s) for bitfield attribute (only tru e/false are accepted)",
bitfield); bitfield);
wl_list_insert(ctx->interface->enumeration_list.prev, wl_list_insert(ctx->interface->enumeration_list.prev,
&enumeration->link); &enumeration->link);
ctx->enumeration = enumeration; ctx->enumeration = enumeration;
} else if (strcmp(element_name, "entry") == 0) { } else if (strcmp(element_name, "entry") == 0) {
if (name == NULL) if (name == NULL)
fail(&ctx->loc, "no entry name given"); fail(&ctx->loc, "no entry name given");
validate_identifier(&ctx->loc, name, TRAILING_IDENT);
entry = create_entry(name, value); entry = create_entry(name, value);
version = version_from_since(ctx, since); version = version_from_since(ctx, since);
if (version < ctx->enumeration->since) if (version < ctx->enumeration->since)
warn(&ctx->loc, "since version not increasing\n"); warn(&ctx->loc, "since version not increasing\n");
ctx->enumeration->since = version; ctx->enumeration->since = version;
entry->since = version; entry->since = version;
if (summary) if (summary)
entry->summary = xstrdup(summary); entry->summary = xstrdup(summary);
skipping to change at line 917 skipping to change at line 975
break; break;
default: default:
fail(&ctx->loc, fail(&ctx->loc,
"enumeration-style argument has wrong type") ; "enumeration-style argument has wrong type") ;
} }
} }
} }
} }
#ifndef HAVE_STRNDUP
char *
strndup(const char *s, size_t size)
{
char *r = malloc(size + 1);
strncpy(r, s, size);
r[size] = '\0';
return r;
}
#endif
static void static void
end_element(void *data, const XML_Char *name) end_element(void *data, const XML_Char *name)
{ {
struct parse_context *ctx = data; struct parse_context *ctx = data;
if (strcmp(name, "copyright") == 0) { if (strcmp(name, "copyright") == 0) {
ctx->protocol->copyright = ctx->protocol->copyright =
strndup(ctx->character_data, strndup(ctx->character_data,
ctx->character_data_length); ctx->character_data_length);
} else if (strcmp(name, "description") == 0) { } else if (strcmp(name, "description") == 0) {
skipping to change at line 1664 skipping to change at line 1733
break; break;
default: default:
printf("\tNULL,\n"); printf("\tNULL,\n");
break; break;
} }
} }
} }
} }
static void static void
emit_messages(struct wl_list *message_list, emit_messages(const char *name, struct wl_list *message_list,
struct interface *interface, const char *suffix) struct interface *interface, const char *suffix)
{ {
struct message *m; struct message *m;
struct arg *a; struct arg *a;
if (wl_list_empty(message_list)) if (wl_list_empty(message_list))
return; return;
printf("static const struct wl_message " printf("static const struct wl_message "
"%s_%s[] = {\n", "%s_%s[] = {\n",
skipping to change at line 1717 skipping to change at line 1786
printf("o"); printf("o");
break; break;
case ARRAY: case ARRAY:
printf("a"); printf("a");
break; break;
case FD: case FD:
printf("h"); printf("h");
break; break;
} }
} }
printf("\", types + %d },\n", m->type_index); printf("\", %s_types + %d },\n", name, m->type_index);
} }
printf("};\n\n"); printf("};\n\n");
} }
static void static void
emit_code(struct protocol *protocol, enum visibility vis) emit_code(struct protocol *protocol, enum visibility vis)
{ {
const char *symbol_visibility; const char *symbol_visibility;
struct interface *i, *next; struct interface *i, *next;
skipping to change at line 1773 skipping to change at line 1842
prev = NULL; prev = NULL;
wl_array_for_each(p, &types) { wl_array_for_each(p, &types) {
if (prev && strcmp(*p, prev) == 0) if (prev && strcmp(*p, prev) == 0)
continue; continue;
printf("extern const struct wl_interface %s_interface;\n", *p); printf("extern const struct wl_interface %s_interface;\n", *p);
prev = *p; prev = *p;
} }
wl_array_release(&types); wl_array_release(&types);
printf("\n"); printf("\n");
printf("static const struct wl_interface *types[] = {\n"); printf("static const struct wl_interface *%s_types[] = {\n", protocol->na me);
emit_null_run(protocol); emit_null_run(protocol);
wl_list_for_each(i, &protocol->interface_list, link) { wl_list_for_each(i, &protocol->interface_list, link) {
emit_types(protocol, &i->request_list); emit_types(protocol, &i->request_list);
emit_types(protocol, &i->event_list); emit_types(protocol, &i->event_list);
} }
printf("};\n\n"); printf("};\n\n");
wl_list_for_each_safe(i, next, &protocol->interface_list, link) { wl_list_for_each_safe(i, next, &protocol->interface_list, link) {
emit_messages(&i->request_list, i, "requests"); emit_messages(protocol->name, &i->request_list, i, "requests");
emit_messages(&i->event_list, i, "events"); emit_messages(protocol->name, &i->event_list, i, "events");
printf("%s const struct wl_interface " printf("%s const struct wl_interface "
"%s_interface = {\n" "%s_interface = {\n"
"\t\"%s\", %d,\n", "\t\"%s\", %d,\n",
symbol_visibility, i->name, i->name, i->version); symbol_visibility, i->name, i->name, i->version);
if (!wl_list_empty(&i->request_list)) if (!wl_list_empty(&i->request_list))
printf("\t%d, %s_requests,\n", printf("\t%d, %s_requests,\n",
wl_list_length(&i->request_list), i->name); wl_list_length(&i->request_list), i->name);
else else
skipping to change at line 1956 skipping to change at line 2025
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
XML_SetElementHandler(ctx.parser, start_element, end_element); XML_SetElementHandler(ctx.parser, start_element, end_element);
XML_SetCharacterDataHandler(ctx.parser, character_data); XML_SetCharacterDataHandler(ctx.parser, character_data);
do { do {
buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE); buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE);
len = fread(buf, 1, XML_BUFFER_SIZE, input); len = fread(buf, 1, XML_BUFFER_SIZE, input);
if (len < 0) { if (len < 0) {
fprintf(stderr, "fread: %m\n"); fprintf(stderr, "fread: %s\n", strerror(errno));
fclose(input); fclose(input);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (XML_ParseBuffer(ctx.parser, len, len == 0) == 0) { if (XML_ParseBuffer(ctx.parser, len, len == 0) == 0) {
fprintf(stderr, fprintf(stderr,
"Error parsing XML at line %ld col %ld: %s\n", "Error parsing XML at line %ld col %ld: %s\n",
XML_GetCurrentLineNumber(ctx.parser), XML_GetCurrentLineNumber(ctx.parser),
XML_GetCurrentColumnNumber(ctx.parser), XML_GetCurrentColumnNumber(ctx.parser),
XML_ErrorString(XML_GetErrorCode(ctx.parser))); XML_ErrorString(XML_GetErrorCode(ctx.parser)));
fclose(input); fclose(input);
 End of changes. 17 change blocks. 
8 lines changed or deleted 78 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)