/* Parses version string of the form <int>.<int> */ static bool parse_version(const char **string) { return parse_uint(string, &major_version) && parse_char(string, '.') && parse_uint(string, &minor_version); }
static mrb_bool parse_lineno(mrb_state *mrb, char **sp, listcmd_parser_state *st) { if (*sp == NULL || **sp == '\0') { return FALSE; } st->has_line_min = FALSE; st->has_line_max = FALSE; if (parse_uint(sp, &st->line_min)) { st->has_line_min = TRUE; } else { return FALSE; } if (skip_char(sp, ',')) { if (parse_uint(sp, &st->line_max)) { st->has_line_max = TRUE; } else { st->parse_error = TRUE; return FALSE; } } return TRUE; }
static int parse_wrap_args(const struct option *opt, const char *arg, int unset) { struct shortlog *log = opt->value; log->wrap_lines = !unset; if (unset) return 0; if (!arg) { log->wrap = DEFAULT_WRAPLEN; log->in1 = DEFAULT_INDENT1; log->in2 = DEFAULT_INDENT2; return 0; } log->wrap = parse_uint(&arg, ',', DEFAULT_WRAPLEN); log->in1 = parse_uint(&arg, ',', DEFAULT_INDENT1); log->in2 = parse_uint(&arg, '\0', DEFAULT_INDENT2); if (log->wrap < 0 || log->in1 < 0 || log->in2 < 0) return error(wrap_arg_usage); if (log->wrap && ((log->in1 && log->wrap <= log->in1) || (log->in2 && log->wrap <= log->in2))) return error(wrap_arg_usage); return 0; }
void perf_opt_parse(int argc, char **argv) { int c; opt_t *opt; isc_result_t result; unsigned int i; progname = isc_file_basename(argv[0]); perf_opt_add('h', perf_opt_boolean, NULL, "print this help", NULL, NULL); while ((c = getopt(argc, argv, optstr)) != -1) { for (i = 0; i < nopts; i++) { if (opts[i].c == c) break; } if (i == nopts) { perf_opt_usage(); exit(1); } if (c == 'h') { perf_opt_usage(); exit(0); } opt = &opts[i]; result = ISC_R_SUCCESS; switch (opt->type) { case perf_opt_string: *opt->u.stringp = optarg; break; case perf_opt_boolean: *opt->u.boolp = ISC_TRUE; break; case perf_opt_uint: *opt->u.uintp = parse_uint(opt->desc, optarg, 1, 0xFFFFFFFF); break; case perf_opt_timeval: *opt->u.uint64p = parse_timeval(opt->desc, optarg); break; case perf_opt_double: *opt->u.doublep = parse_double(opt->desc, optarg); break; case perf_opt_port: *opt->u.portp = parse_uint(opt->desc, optarg, 0, 0xFFFF); break; } } if (optind != argc) { fprintf(stderr, "unexpected argument %s\n", argv[optind]); perf_opt_usage(); exit(1); } }
static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv, int token, int trailer) { if (nv->name[0] == ':') { if (trailer || (stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) { return NGHTTP2_ERR_HTTP_HEADER; } } switch (token) { case NGHTTP2_TOKEN__STATUS: { if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) { return NGHTTP2_ERR_HTTP_HEADER; } if (nv->valuelen != 3) { return NGHTTP2_ERR_HTTP_HEADER; } stream->status_code = parse_uint(nv->value, nv->valuelen); if (stream->status_code == -1) { return NGHTTP2_ERR_HTTP_HEADER; } break; } case NGHTTP2_TOKEN_CONTENT_LENGTH: { if (stream->content_length != -1) { return NGHTTP2_ERR_HTTP_HEADER; } stream->content_length = parse_uint(nv->value, nv->valuelen); if (stream->content_length == -1) { return NGHTTP2_ERR_HTTP_HEADER; } break; } /* disallowed header fields */ case NGHTTP2_TOKEN_CONNECTION: case NGHTTP2_TOKEN_KEEP_ALIVE: case NGHTTP2_TOKEN_PROXY_CONNECTION: case NGHTTP2_TOKEN_TRANSFER_ENCODING: case NGHTTP2_TOKEN_UPGRADE: return NGHTTP2_ERR_HTTP_HEADER; case NGHTTP2_TOKEN_TE: if (!lstrieq("trailers", nv->value, nv->valuelen)) { return NGHTTP2_ERR_HTTP_HEADER; } break; default: if (nv->name[0] == ':') { return NGHTTP2_ERR_HTTP_HEADER; } } if (nv->name[0] != ':') { stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED; } return 0; }
app_action_t application_function_flash_receive(string_t *src, string_t *dst) { unsigned int chunk_offset, chunk_length; if(string_size(&flash_sector_buffer) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-receive: flash sector buffer too small: %d\n", string_size(&flash_sector_buffer)); return(app_action_error); } if(parse_uint(1, src, &chunk_offset, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-receive: chunk offset required\n"); return(app_action_error); } if(parse_uint(2, src, &chunk_length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-receive: chunk chunk_length required\n"); return(app_action_error); } if((chunk_length == 0) || ((chunk_offset % chunk_length) != 0)) { string_append(dst, "ERROR: flash-receive: chunk offset should be divisible by chunk size"); return(app_action_error); } if((chunk_length == 0) || ((SPI_FLASH_SEC_SIZE % chunk_length) != 0)) { string_append(dst, "ERROR: flash-receive: chunk length should be divisible by flash sector size"); return(app_action_error); } if((chunk_offset + chunk_length) > SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-receive: chunk_length(%u) + chunk_offset(%u) > sector size(%d)\n", chunk_length, chunk_offset, SPI_FLASH_SEC_SIZE); return(app_action_error); } if((flash_sector_buffer_use != fsb_free) && (flash_sector_buffer_use != fsb_config_cache) && (flash_sector_buffer_use != fsb_ota)) { string_format(dst, "ERROR: flash_send: sector buffer in use: %u\n", flash_sector_buffer_use); return(app_action_error); } flash_sector_buffer_use = fsb_ota; string_format(dst, "OK flash-receive: sending bytes: %u, from offset: %u, data: @", chunk_length, chunk_offset); string_splice(dst, -1, &flash_sector_buffer, chunk_offset, chunk_length); string_append(dst, "\n"); if((chunk_offset + chunk_length) >= SPI_FLASH_SEC_SIZE) flash_sector_buffer_use = fsb_free; return(app_action_normal); }
app_action_t application_function_flash_checksum(string_t *src, string_t *dst) { unsigned int address, current, length, done; SHA_CTX sha_context; unsigned char sha_result[SHA_DIGEST_LENGTH]; string_new(, sha_string, SHA_DIGEST_LENGTH * 2 + 2); if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-checksum: address required\n"); return(app_action_error); } if(parse_uint(2, src, &length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-checksum: length required\n"); return(app_action_error); } if((address % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR: flash_checksum: address should be divisible by flash sector size"); return(app_action_error); } if((length % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR: flash_checksum: length should be divisible by flash sector size"); return(app_action_error); } SHA1Init(&sha_context); for(current = address, done = 0; done < length; current += SPI_FLASH_SEC_SIZE, done += SPI_FLASH_SEC_SIZE) { spi_flash_read(current, string_buffer_nonconst(dst), SPI_FLASH_SEC_SIZE); SHA1Update(&sha_context, string_buffer(dst), SPI_FLASH_SEC_SIZE); } SHA1Final(sha_result, &sha_context); string_bin_to_hex(&sha_string, sha_result, SHA_DIGEST_LENGTH); string_clear(dst); string_format(dst, "OK flash-checksum: checksummed bytes: %u, from address: %u, checksum: ", done, address); string_append_string(dst, &sha_string); string_append(dst, "\n"); return(app_action_normal); }
int format_str_v(const StrFormatContext *ctxt, const char *format, va_list ap) { unsigned int written = 0; const char *pos = format; while(*pos != '\0') { FormatFlags flags; unsigned int minwidth = 0; int precision = -1; /* Negative means no precision */ char ch; const char *start = pos; while( (ch = *pos) != '\0' && ch != '%') pos++; if (pos != start) { CHECKCB(ctxt->write_str(ctxt->user_data, start, pos - start)); written += pos - start; } if (*pos == '\0') { va_end(ap); return written; } pos++; if (*pos == '\0') { va_end(ap); return written; } flags = parse_flags(&pos); /* parse width */ if (*pos >= '1' && *pos <= '9') { minwidth = parse_uint(&pos); } else if (*pos == '*') { int w = va_arg(ap,int); if (w < 0) { flags |= JUSTIFY_LEFT; minwidth = w; } else { minwidth = w; } pos ++; } /* parse precision */ if (*pos == '.') { pos++; if (*pos >= '0' && *pos <= '9') { precision = parse_uint(&pos); } else if (*pos == '*') { pos++; precision = va_arg(ap,int); }
static boolean parse_register_dcl_bracket( struct translate_ctx *ctx, struct parsed_dcl_bracket *bracket) { uint uindex; memset(bracket, 0, sizeof(struct parsed_dcl_bracket)); eat_opt_white( &ctx->cur ); if (!parse_uint( &ctx->cur, &uindex )) { /* it can be an empty bracket [] which means its range * is from 0 to some implied size */ if (ctx->cur[0] == ']' && ctx->implied_array_size != 0) { bracket->first = 0; bracket->last = ctx->implied_array_size - 1; goto cleanup; } report_error( ctx, "Expected literal unsigned integer" ); return FALSE; } bracket->first = uindex; eat_opt_white( &ctx->cur ); if (ctx->cur[0] == '.' && ctx->cur[1] == '.') { uint uindex; ctx->cur += 2; eat_opt_white( &ctx->cur ); if (!parse_uint( &ctx->cur, &uindex )) { report_error( ctx, "Expected literal integer" ); return FALSE; } bracket->last = (int) uindex; eat_opt_white( &ctx->cur ); } else { bracket->last = bracket->first; } cleanup: if (*ctx->cur != ']') { report_error( ctx, "Expected `]' or `..'" ); return FALSE; } ctx->cur++; return TRUE; }
static void gtp_boardsize( FILE * fp, int id, const char * new_size ){ if(new_size == NULL) { gtp_answer(fp, id, BOARD_SIZ_AS_STR); return; } u32 ns; if(!parse_uint(&ns, new_size)) { gtp_error(fp, id, "syntax error"); return; } if(ns != BOARD_SIZ) { gtp_error(fp, id, "unacceptable size"); fprintf(stderr, "board size cannot be changed on runtime; please edit t\ he master header file and recompile matilda\n"); char * s = alloc(); snprintf(s, MAX_PAGE_SIZ, "requested board size change to %ux%u", ns, ns); flog_info("gtp", s); release(s); }
static void set_ndots(const char *value) { isc_uint32_t n; isc_result_t result = parse_uint(&n, value, 128, "ndots"); if (result == ISC_R_SUCCESS) ndots = n; }
/* Parses expected server response to CFdDVK command: should be four newline * terminated numbers and a version string. */ static bool parse_archive_parameters(const char **string) { return parse_double(string, &sample_frequency) && parse_char(string, '\n') && parse_uint(string, &first_decimation) && parse_char(string, '\n') && parse_uint(string, &second_decimation) && parse_char(string, '\n') && parse_version(string) && parse_char(string, '\n') && parse_uint(string, &fa_entry_count) && parse_char(string, '\n') && parse_uint(string, &continuous_decimation) && parse_char(string, '\n'); }
static void set_timeout(const char *value) { isc_uint32_t n; isc_result_t result = parse_uint(&n, value, UINT_MAX, "timeout"); if (result == ISC_R_SUCCESS) timeout = n; }
static void set_tries(const char *value) { isc_uint32_t n; isc_result_t result = parse_uint(&n, value, INT_MAX, "tries"); if (result == ISC_R_SUCCESS) tries = n; }
/** * set an attribute on a room. */ static int room_attr_set(struct room *r, const char *name, const char *value) { int res; assert(r != NULL); assert(name != NULL); assert(value != NULL); if(!r) return 0; if(!strcasecmp("id", name)) res=parse_uint(name, value, &r->id); else if(!strcasecmp("name.short", name)) res=parse_str(name, value, &r->name.short_str); else if(!strcasecmp("name.long", name)) res=parse_str(name, value, &r->name.long_str); else if(!strcasecmp("desc.short", name)) res=parse_str(name, value, &r->desc.short_str); else if(!strcasecmp("desc.long", name)) res=parse_str(name, value, &r->desc.long_str); else if(!strcasecmp("creator", name)) res=parse_str(name, value, &r->creator); else if(!strcasecmp("owner", name)) res=parse_str(name, value, &r->owner); else res=parse_attr(name, value, &r->extra_values); if(res) r->dirty_fl=1; return res; }
/* Parses data format description in format * F | d[n] | D[n] * where n is a three bit data mask. */ static bool parse_data_format(const char **string, enum data_format *format) { if (read_char(string, 'F')) { *format = DATA_FA; return true; } else { if (read_char(string, 'd')) *format = DATA_D; else if (read_char(string, 'D')) *format = DATA_DD; else return FAIL_("Invalid data format"); if (**string == '\0') { data_mask = 15; // Read all fields by default return true; } else return parse_uint(string, &data_mask) && TEST_OK_(0 < data_mask && data_mask <= 15, "Invalid data mask"); } }
static bool parse_id( const char **string, unsigned int fa_entry_count, unsigned int *id) { return parse_uint(string, id) && TEST_OK_(*id < fa_entry_count, "id %u out of range", *id); }
/* parse default values from g_options[] into idmap_config */ static int config_defaults( struct idmap_config *config) { const struct config_option *option; const int count = ARRAYSIZE(g_options); char *dst; int i, status = NO_ERROR; for (i = 0; i < count; i++) { option = &g_options[i]; dst = (char*)config + option->offset; if (option->type == TYPE_INT) { if (!parse_uint(option->def, (UINT*)dst)) { status = ERROR_INVALID_PARAMETER; eprintf("failed to parse default value of %s=\"%s\": " "expected a number\n", option->key, option->def); break; } } else { if (FAILED(StringCchCopyA(dst, option->max_len, option->def))) { status = ERROR_BUFFER_OVERFLOW; eprintf("failed to parse default value of %s=\"%s\": " "buffer overflow > %u\n", option->key, option->def, option->max_len); break; } } } return status; }
static void socket_command_callback_data_received(lwip_if_socket_t *socket, unsigned int length) { static const char command_string[] = "flash-send "; unsigned int chunk_length; int chunk_offset; if((command_left_to_read == 0) && string_nmatch_cstr(&command_socket_receive_buffer, command_string, sizeof(command_string) - 1) && (parse_uint(2, &command_socket_receive_buffer, &chunk_length, 10, ' ') == parse_ok) && ((chunk_offset = string_sep(&command_socket_receive_buffer, 0, 3, ' ')) >= 0)) command_left_to_read = chunk_offset + chunk_length; if(command_left_to_read > 0) { if(length > command_left_to_read) command_left_to_read = 0; else command_left_to_read -= length; } if((command_left_to_read == 0) && (string_trim_nl(&command_socket_receive_buffer) || lwip_if_received_udp(socket))) dispatch_post_command(command_task_received_command); else lwip_if_receive_buffer_unlock(&command_socket); }
static errcode_t parse_time(struct field_set_info *info, char *arg) { struct tm ts; __u32 *ptr32; ptr32 = (__u32 *) info->ptr; if (strcmp(arg, "now") == 0) { *ptr32 = time(0); return 0; } memset(&ts, 0, sizeof(ts)); #ifdef HAVE_STRPTIME strptime(arg, "%Y%m%d%H%M%S", &ts); #else sscanf(arg, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon, &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec); ts.tm_year -= 1900; ts.tm_mon -= 1; if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 || ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 || ts.tm_min > 59 || ts.tm_sec > 61) ts.tm_mday = 0; #endif if (ts.tm_mday == 0) { /* Try it as an integer... */ return parse_uint(info, arg); } *ptr32 = mktime(&ts); return 0; }
static int local_port_parser(struct nv_pair *nv, int line, remote_conf_t *config) { if ((strcasecmp(nv->value, "any") == 0)) return 0; // The default is 0, which means any port return parse_uint (nv, line, &(config->local_port), 0, 65535); }
static const response* add(const char* l) { struct rule* r; if (*l != 'k' && *l != 'd' && *l != 'z' && *l != 'p' && *l != 'n') return 0; r = alloc_rule(); r->code = *l++; if ((l = parse_pattern(l, ':', &r->sender)) != 0 && *l == ':') if ((l = parse_pattern(l+1, ':', &r->recipient)) != 0 && *l == ':') if ((l = parse_str(l+1, ':', &r->response)) != 0 && *l == ':') if ((l = parse_uint(l+1, ':', &r->databytes)) != 0) if (*l == ':' && (l = parse_str(l+1, ':', &r->relayclient)) != 0 && *l == ':') parse_env(l+1, &r->environment); if (l == 0) return &resp_syntax; append_rule(r); /* Pre-load text files and pre-open CDB files */ if (!try_load(&r->sender)) return &resp_erropenref; if (!try_load(&r->recipient)) return &resp_erropenref; return 0; }
static int parse_meter_color_str(char *c_str, uint32_t *use_prev_meter_color, enum rte_mtr_color **dscp_table) { char *token; uint64_t previous_mtr_color = 0; int ret; /* First token: use previous meter color */ token = strtok_r(c_str, PARSE_DELIMITER, &c_str); if (token == NULL) return -1; ret = parse_uint(&previous_mtr_color, token); if (ret != 0) return -1; /* Check if previous meter color to be used */ if (previous_mtr_color) { *use_prev_meter_color = previous_mtr_color; return 0; } /* Parse dscp table entries */ ret = parse_dscp_table_entries(c_str, dscp_table); if (ret != 0) return -1; return 0; }
struct jtag_tap *jtag_tap_by_string(const char *s) { /* try by name first */ struct jtag_tap *t = jtag_all_taps(); while (t) { if (0 == strcmp(t->dotted_name, s)) return t; t = t->next_tap; } /* no tap found by name, so try to parse the name as a number */ unsigned n; if (parse_uint(s, &n) != ERROR_OK) return NULL; /* FIXME remove this numeric fallback code late June 2010, along * with all info in the User's Guide that TAPs have numeric IDs. * Also update "scan_chain" output to not display the numbers. */ t = jtag_tap_by_position(n); if (t) LOG_WARNING("Specify TAP '%s' by name, not number %u", t->dotted_name, n); return t; }
static void set_port(const char *value) { isc_uint32_t n; isc_result_t result = parse_uint(&n, value, 65535, "port"); if (result == ISC_R_SUCCESS) port = (isc_uint16_t) n; }
int main (int argc, char **argv) { argv0 = argv[0]; assert ((1ULL << (1ULL << max_inputs)) - 1ULL <= UINT_MAX); if (argc != 3) error ("Usage: circuitoptimizer truth_table_output max_gates"); superopt (argv[1], (int) parse_uint (argv[2], 10)); return 0; }
app_action_t application_function_flash_erase(string_t *src, string_t *dst) { unsigned int address, length; int sector_offset, sector_count, erased; uint32_t time_start, time_finish; if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-erase: offset required\n"); return(app_action_error); } if(parse_uint(2, src, &length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-erase: length required\n"); return(app_action_error); } sector_offset = address / SPI_FLASH_SEC_SIZE; sector_count = length / SPI_FLASH_SEC_SIZE; if((address % SPI_FLASH_SEC_SIZE) != 0) { sector_offset--; sector_count++; } if((length % SPI_FLASH_SEC_SIZE) != 0) sector_count++; time_start = system_get_time(); for(erased = 0; erased < sector_count; erased++) { system_soft_wdt_feed(); if(spi_flash_erase_sector(sector_offset + erased) != SPI_FLASH_RESULT_OK) break; } time_finish = system_get_time(); string_format(dst, "OK flash-erase: erased %d sectors from sector %d, in %lu milliseconds\n", erased - 1, sector_offset, (time_finish - time_start) / 1000); return(app_action_normal); }
static void superopt (const char *tt_output, int max_gates) { ninputs = (int) log2 (strlen (tt_output)); if (1u << ninputs != strlen (tt_output)) error ("truth_table_output must have a power-of-2 size"); if (max_inputs < ninputs) error ("Truth table too big. I can't represent so many inputs."); target_output = parse_uint (tt_output, 2); find_circuits (max_gates); }
/* parses a 4-touple of the form {x, y, z, w} * where x, y, z, w are numbers */ static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type, union tgsi_immediate_data *values) { unsigned i; int ret; eat_opt_white( &ctx->cur ); if (*ctx->cur != '{') { report_error( ctx, "Expected `{'" ); return FALSE; } ctx->cur++; for (i = 0; i < 4; i++) { eat_opt_white( &ctx->cur ); if (i > 0) { if (*ctx->cur != ',') { report_error( ctx, "Expected `,'" ); return FALSE; } ctx->cur++; eat_opt_white( &ctx->cur ); } switch (type) { case TGSI_IMM_FLOAT64: ret = parse_double(&ctx->cur, &values[i].Uint, &values[i+1].Uint); i++; break; case TGSI_IMM_FLOAT32: ret = parse_float(&ctx->cur, &values[i].Float); break; case TGSI_IMM_UINT32: ret = parse_uint(&ctx->cur, &values[i].Uint); break; case TGSI_IMM_INT32: ret = parse_int(&ctx->cur, &values[i].Int); break; default: assert(0); ret = FALSE; break; } if (!ret) { report_error( ctx, "Expected immediate constant" ); return FALSE; } } eat_opt_white( &ctx->cur ); if (*ctx->cur != '}') { report_error( ctx, "Expected `}'" ); return FALSE; } ctx->cur++; return TRUE; }
static int vz_veth_ioctl(int op_type, struct container *ct, struct ct_net *n, const char *pair0, const char *pair1) { struct vzctl_ve_hwaddr veth; int ret = -1; unsigned int veid = 0; if (ct) { ret = parse_uint(ct->name, &veid); if (ret) { pr_err("Unable to parse container's ID"); return -1; } } else { veid = 0; } veth.op = op_type; veth.veid = veid; veth.addrlen = ETH_ALEN; veth.addrlen_ve = ETH_ALEN; ret = gen_hwaddr(veth.dev_addr, ETH_ALEN); if (ret) { pr_err("Failed to gen_hwaddr: err=%d", ret); return -1; } if (n->addr) { sscanf(n->addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &veth.dev_addr_ve[0], &veth.dev_addr_ve[1], &veth.dev_addr_ve[2], &veth.dev_addr_ve[3], &veth.dev_addr_ve[4], &veth.dev_addr_ve[5]); } else { ret = gen_hwaddr(veth.dev_addr_ve, ETH_ALEN); if (ret) { pr_err("Failed to gen_hwaddr: err=%d", ret); return -1; } } memcpy(veth.dev_name, pair0, sizeof(veth.dev_name)); memcpy(veth.dev_name_ve, pair1, sizeof(veth.dev_name_ve)); ret = ioctl(get_vzctlfd(), VETHCTL_VE_HWADDR, &veth); if (ret) { if (errno == ENOTTY) { pr_err("veth feature is" " not supported by the kernel"); } else { pr_err("Unable to perform operation %d on veth device" " pair %s %s err=%d", op_type, pair0, pair1, errno); pr_perror("Error"); } return -1; } return 0; }