static int version_from_since(struct parse_context *ctx, const char *since) { int version; if (since != NULL) { version = strtouint(since); if (version == -1) { fail(&ctx->loc, "invalid integer (%s)\n", since); } else if (version > ctx->interface->version) { fail(&ctx->loc, "since (%u) larger than version (%u)\n", version, ctx->interface->version); } } else { version = 1; } return version; }
void token_set_interval ( Token *token, const gchar *str, GError **err ) { guint interval; GError *lerr; lerr = NULL; interval = strtouint ( str, &lerr ); if ( lerr ){ g_propagate_error ( err, lerr ); return; } if ( interval == 0 ){ /* prevent 0 intervals */ g_set_error ( err, OTP_ERROR, OTP_ERROR_INVALID_TOKEN, "Interval must be greater than 1" ); return; } token->interval = interval; }
void token_set_pin_size ( Token *token, const gchar *str, GError **err ) { guint pin_size; GError *lerr; lerr = NULL; pin_size = strtouint ( str, &lerr ); if ( lerr ){ g_propagate_error ( err, lerr ); return; } if ( pin_size < MIN_PIN_SIZE || pin_size > MAX_PIN_SIZE ){ g_set_error ( err, OTP_ERROR, OTP_ERROR_INVALID_TOKEN, "Pin size must be between %d and %d", MIN_PIN_SIZE, MAX_PIN_SIZE ); return; } token->pin_size = pin_size; }
void token_set_digits ( Token *token, const gchar *str, GError **err ) { guint digits; GError *lerr; lerr = NULL; digits = strtouint ( str, &lerr ); if ( lerr ){ g_propagate_error ( err, lerr ); return; } if ( digits < MIN_DIGITS || digits > MAX_DIGITS ){ g_set_error ( err, OTP_ERROR, OTP_ERROR_INVALID_TOKEN, "Number of digits must be between %d and %d", MIN_DIGITS, MAX_DIGITS ); return; } token->digits = digits; }
static void start_element(void *data, const char *element_name, const char **atts) { struct parse_context *ctx = data; struct interface *interface; struct message *message; struct arg *arg; struct enumeration *enumeration; struct entry *entry; struct description *description = NULL; const char *name = NULL; const char *type = NULL; const char *interface_name = NULL; const char *value = NULL; const char *summary = NULL; const char *since = NULL; const char *allow_null = NULL; const char *enumeration_name = NULL; const char *bitfield = NULL; int i, version = 0; ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser); for (i = 0; atts[i]; i += 2) { if (strcmp(atts[i], "name") == 0) name = atts[i + 1]; if (strcmp(atts[i], "version") == 0) { version = strtouint(atts[i + 1]); if (version == -1) fail(&ctx->loc, "wrong version (%s)", atts[i + 1]); } if (strcmp(atts[i], "type") == 0) type = atts[i + 1]; if (strcmp(atts[i], "value") == 0) value = atts[i + 1]; if (strcmp(atts[i], "interface") == 0) interface_name = atts[i + 1]; if (strcmp(atts[i], "summary") == 0) summary = atts[i + 1]; if (strcmp(atts[i], "since") == 0) since = atts[i + 1]; if (strcmp(atts[i], "allow-null") == 0) allow_null = atts[i + 1]; if (strcmp(atts[i], "enum") == 0) enumeration_name = atts[i + 1]; if (strcmp(atts[i], "bitfield") == 0) bitfield = atts[i + 1]; } ctx->character_data_length = 0; if (strcmp(element_name, "protocol") == 0) { if (name == NULL) fail(&ctx->loc, "no protocol name given"); ctx->protocol->name = xstrdup(name); ctx->protocol->uppercase_name = uppercase_dup(name); } else if (strcmp(element_name, "copyright") == 0) { } else if (strcmp(element_name, "interface") == 0) { if (name == NULL) fail(&ctx->loc, "no interface name given"); if (version == 0) fail(&ctx->loc, "no interface version given"); interface = create_interface(ctx->loc, name, version); ctx->interface = interface; wl_list_insert(ctx->protocol->interface_list.prev, &interface->link); } else if (strcmp(element_name, "request") == 0 || strcmp(element_name, "event") == 0) { if (name == NULL) fail(&ctx->loc, "no request name given"); message = create_message(ctx->loc, name); if (strcmp(element_name, "request") == 0) wl_list_insert(ctx->interface->request_list.prev, &message->link); else wl_list_insert(ctx->interface->event_list.prev, &message->link); if (type != NULL && strcmp(type, "destructor") == 0) message->destructor = 1; version = version_from_since(ctx, since); if (version < ctx->interface->since) warn(&ctx->loc, "since version not increasing\n"); ctx->interface->since = version; message->since = version; if (strcmp(name, "destroy") == 0 && !message->destructor) fail(&ctx->loc, "destroy request should be destructor type"); ctx->message = message; } else if (strcmp(element_name, "arg") == 0) { if (name == NULL) fail(&ctx->loc, "no argument name given"); arg = create_arg(name); if (!set_arg_type(arg, type)) fail(&ctx->loc, "unknown type (%s)", type); switch (arg->type) { case NEW_ID: ctx->message->new_id_count++; /* fallthrough */ case OBJECT: if (interface_name) arg->interface_name = xstrdup(interface_name); break; default: if (interface_name != NULL) fail(&ctx->loc, "interface attribute not allowed for type %s", type); break; } if (allow_null) { if (strcmp(allow_null, "true") == 0) arg->nullable = 1; else if (strcmp(allow_null, "false") != 0) fail(&ctx->loc, "invalid value for allow-null attribute (%s)", allow_null); if (!is_nullable_type(arg)) fail(&ctx->loc, "allow-null is only valid for objects, strings, and arrays"); } if (enumeration_name == NULL || strcmp(enumeration_name, "") == 0) arg->enumeration_name = NULL; else arg->enumeration_name = xstrdup(enumeration_name); if (summary) arg->summary = xstrdup(summary); wl_list_insert(ctx->message->arg_list.prev, &arg->link); ctx->message->arg_count++; } else if (strcmp(element_name, "enum") == 0) { if (name == NULL) fail(&ctx->loc, "no enum name given"); enumeration = create_enumeration(name); if (bitfield == NULL || strcmp(bitfield, "false") == 0) enumeration->bitfield = false; else if (strcmp(bitfield, "true") == 0) enumeration->bitfield = true; else fail(&ctx->loc, "invalid value (%s) for bitfield attribute (only true/false are accepted)", bitfield); wl_list_insert(ctx->interface->enumeration_list.prev, &enumeration->link); ctx->enumeration = enumeration; } else if (strcmp(element_name, "entry") == 0) { if (name == NULL) fail(&ctx->loc, "no entry name given"); entry = create_entry(name, value); version = version_from_since(ctx, since); if (version < ctx->enumeration->since) warn(&ctx->loc, "since version not increasing\n"); ctx->enumeration->since = version; entry->since = version; if (summary) entry->summary = xstrdup(summary); else entry->summary = NULL; wl_list_insert(ctx->enumeration->entry_list.prev, &entry->link); } else if (strcmp(element_name, "description") == 0) { if (summary == NULL) fail(&ctx->loc, "description without summary"); description = xzalloc(sizeof *description); description->summary = xstrdup(summary); if (ctx->message) ctx->message->description = description; else if (ctx->enumeration) ctx->enumeration->description = description; else if (ctx->interface) ctx->interface->description = description; else ctx->protocol->description = description; ctx->description = description; } }