diff --git a/parser.c b/parser.c index 7e93175..f7ab041 100644 --- a/parser.c +++ b/parser.c @@ -50,7 +50,7 @@ enum token_id { struct token { enum token_id id; char *str; - unsigned num; + unsigned long long num; struct qmi_struct *qmi_struct; }; @@ -169,6 +169,7 @@ static struct token yylex() { struct symbol *sym; struct token token = {}; + unsigned long long num; char buf[128]; char *p = buf; int base; @@ -227,8 +228,14 @@ static struct token yylex() else base = 10; + errno = 0; + num = strtoull(buf, NULL, base); + if (errno) + yyerror("number %s out of range", buf); + + token.num = num; token.id = TOK_NUM; - token.num = strtol(buf, NULL, base); + return token; } else if (!ch) { token.id = TOK_EOF; diff --git a/qmic.c b/qmic.c index f542f82..05c86c4 100644 --- a/qmic.c +++ b/qmic.c @@ -28,7 +28,7 @@ void qmi_const_header(FILE *fp) return; list_for_each_entry(qc, &qmi_consts, node) - fprintf(fp, "#define %s %d\n", qc->name, qc->value); + fprintf(fp, "#define %s %llu\n", qc->name, qc->value); fprintf(fp, "\n"); } diff --git a/qmic.h b/qmic.h index 670adeb..b898d04 100644 --- a/qmic.h +++ b/qmic.h @@ -28,7 +28,7 @@ extern const char *qmi_package; struct qmi_const { const char *name; - unsigned value; + unsigned long long value; struct list_head node; }; diff --git a/tests/num_large.qmi b/tests/num_large.qmi new file mode 100644 index 0000000..96ef038 --- /dev/null +++ b/tests/num_large.qmi @@ -0,0 +1,23 @@ +package test; + +# As a 32 bit signed number, this would be negative +const TEST_NUMBER = 0x87654321; +# This value requires more than 32 bits to represent +const TEST_NUMBER = 0x123456789; + +struct qmi_result { + u16 result; + u16 error; +}; + +request test_request { + required u8 test_number = 0x12; +} = 0x80000000; + +response test_response { + required qmi_result r = 2; +} = 020000000000; + +indication test_indication { + optional u64 value = 0x99; +} = 0x7; diff --git a/tests/num_too_big.qmi b/tests/num_too_big.qmi new file mode 100644 index 0000000..10fe70a --- /dev/null +++ b/tests/num_too_big.qmi @@ -0,0 +1,22 @@ +package test; + +# This value requires more than 32 bits to represent +const TEST_NUMBER = 0x123456789; + +struct qmi_result { + u16 result; + u16 error; +}; + +request test_request { + required u8 test_number = 0x12; +} = 0x100000000; + +response test_response { + required qmi_result r = 2; +} = 040000000000; + +indication test_indication { + # This value requires more than 64 bits to represent + optional u64 value = 0x12345678987654321; +} = 0x7;