sources/linetester/linetest.c (339 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "linetest.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wbitwise-op-parentheses" #pragma clang diagnostic ignored "-Wshift-op-parentheses" #pragma clang diagnostic ignored "-Wlogical-not-parentheses" #pragma clang diagnostic ignored "-Wlogical-op-parentheses" #pragma clang diagnostic ignored "-Wliteral-conversion" #pragma clang diagnostic ignored "-Wunused-but-set-variable" cql_string_literal(_literal_1_exp_dump, "exp"); cql_string_literal(_literal_2_act_dump, "act"); // // This file is auto-generated by linetest.sql, it is checked in just // in case CQL is broken by a change. The Last Known Good Verifier // can be used to verify the tests pass again, or report failures // while things are still otherwise broken. Rebuild with 'regen.sh' // // Generated from linetest.sql:39 /* CREATE PROC linetest_setup () BEGIN CREATE TABLE linedata( source TEXT NOT NULL, procname TEXT NOT NULL, line INTEGER NOT NULL, data TEXT NOT NULL, physical_line INTEGER NOT NULL ); CREATE TABLE procs( procname TEXT NOT NULL PRIMARY KEY ); CREATE INDEX __idx__test_lines ON linedata (source, procname); END; */ #define _PROC_ "linetest_setup" CQL_WARN_UNUSED cql_code linetest_setup(sqlite3 *_Nonnull _db_) { cql_code _rc_ = SQLITE_OK; _rc_ = cql_exec(_db_, "CREATE TABLE linedata( " "source TEXT NOT NULL, " "procname TEXT NOT NULL, " "line INTEGER NOT NULL, " "data TEXT NOT NULL, " "physical_line INTEGER NOT NULL " ")"); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = cql_exec(_db_, "CREATE TABLE procs( " "procname TEXT NOT NULL PRIMARY KEY " ")"); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = cql_exec(_db_, "CREATE INDEX __idx__test_lines ON linedata (source, procname)"); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = SQLITE_OK; cql_cleanup: return _rc_; } #undef _PROC_ // Generated from linetest.sql:46 /* CREATE PROC linetest_add (source_ TEXT NOT NULL, procname_ TEXT NOT NULL, line_ INTEGER NOT NULL, data_ TEXT NOT NULL, physical_line_ INTEGER NOT NULL) BEGIN INSERT INTO linedata(source, procname, line, data, physical_line) VALUES(source_, procname_, line_, data_, physical_line_); INSERT OR IGNORE INTO procs(procname) VALUES(procname_); END; */ #define _PROC_ "linetest_add" CQL_WARN_UNUSED cql_code linetest_add(sqlite3 *_Nonnull _db_, cql_string_ref _Nonnull source_, cql_string_ref _Nonnull procname_, cql_int32 line_, cql_string_ref _Nonnull data_, cql_int32 physical_line_) { cql_contract_argument_notnull((void *)source_, 1); cql_contract_argument_notnull((void *)procname_, 2); cql_contract_argument_notnull((void *)data_, 4); cql_code _rc_ = SQLITE_OK; sqlite3_stmt *_temp_stmt = NULL; _rc_ = cql_prepare(_db_, &_temp_stmt, "INSERT INTO linedata(source, procname, line, data, physical_line) VALUES(?, ?, ?, ?, ?)"); cql_multibind(&_rc_, _db_, &_temp_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, source_, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, procname_, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, line_, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, data_, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, physical_line_); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = sqlite3_step(_temp_stmt); if (_rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } cql_finalize_stmt(&_temp_stmt); _rc_ = cql_prepare(_db_, &_temp_stmt, "INSERT OR IGNORE INTO procs(procname) VALUES(?)"); cql_multibind(&_rc_, _db_, &_temp_stmt, 1, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, procname_); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = sqlite3_step(_temp_stmt); if (_rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } cql_finalize_stmt(&_temp_stmt); _rc_ = SQLITE_OK; cql_cleanup: cql_finalize_stmt(&_temp_stmt); return _rc_; } #undef _PROC_ // Generated from linetest.sql:55 /* CREATE PROC linetest_dump () BEGIN DECLARE C CURSOR FOR SELECT * FROM linedata; LOOP FETCH C BEGIN CALL printf("%s %s %4d %3d %s\n", C.source, C.procname, C.physical_line, C.line, C.data); END; END; */ #define _PROC_ "linetest_dump" typedef struct linetest_dump_C_row { cql_bool _has_row_; cql_uint16 _refs_count_; cql_uint16 _refs_offset_; cql_int32 line; cql_int32 physical_line; cql_string_ref _Nonnull source; cql_string_ref _Nonnull procname; cql_string_ref _Nonnull data; } linetest_dump_C_row; #define linetest_dump_C_refs_offset cql_offsetof(linetest_dump_C_row, source) // count = 3 CQL_WARN_UNUSED cql_code linetest_dump(sqlite3 *_Nonnull _db_) { cql_code _rc_ = SQLITE_OK; sqlite3_stmt *C_stmt = NULL; linetest_dump_C_row C = { ._refs_count_ = 3, ._refs_offset_ = linetest_dump_C_refs_offset }; _rc_ = cql_prepare(_db_, &C_stmt, "SELECT source, procname, line, data, physical_line " "FROM linedata"); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } for (;;) { _rc_ = sqlite3_step(C_stmt); C._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, C_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &C.source, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &C.procname, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &C.line, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &C.data, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &C.physical_line); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } if (!C._has_row_) break; cql_alloc_cstr(_cstr_1, C.source); cql_alloc_cstr(_cstr_2, C.procname); cql_alloc_cstr(_cstr_3, C.data); printf("%s %s %4d %3d %s\n", _cstr_1, _cstr_2, C.physical_line, C.line, _cstr_3); cql_free_cstr(_cstr_1, C.source); cql_free_cstr(_cstr_2, C.procname); cql_free_cstr(_cstr_3, C.data); } _rc_ = SQLITE_OK; cql_cleanup: cql_finalize_stmt(&C_stmt); cql_teardown_row(C); return _rc_; } #undef _PROC_ // Generated from linetest.sql:64 /* CREATE PROC dump_proc_records (source_ TEXT NOT NULL, procname_ TEXT NOT NULL) BEGIN DECLARE C CURSOR FOR SELECT * FROM linedata WHERE procname = procname_ AND source = source_; LOOP FETCH C BEGIN CALL printf("%5d %s\n", C.line, C.data); END; END; */ #define _PROC_ "dump_proc_records" typedef struct dump_proc_records_C_row { cql_bool _has_row_; cql_uint16 _refs_count_; cql_uint16 _refs_offset_; cql_int32 line; cql_int32 physical_line; cql_string_ref _Nonnull source; cql_string_ref _Nonnull procname; cql_string_ref _Nonnull data; } dump_proc_records_C_row; #define dump_proc_records_C_refs_offset cql_offsetof(dump_proc_records_C_row, source) // count = 3 CQL_WARN_UNUSED cql_code dump_proc_records(sqlite3 *_Nonnull _db_, cql_string_ref _Nonnull source_, cql_string_ref _Nonnull procname_) { cql_contract_argument_notnull((void *)source_, 1); cql_contract_argument_notnull((void *)procname_, 2); cql_code _rc_ = SQLITE_OK; sqlite3_stmt *C_stmt = NULL; dump_proc_records_C_row C = { ._refs_count_ = 3, ._refs_offset_ = dump_proc_records_C_refs_offset }; _rc_ = cql_prepare(_db_, &C_stmt, "SELECT source, procname, line, data, physical_line " "FROM linedata " "WHERE procname = ? AND source = ?"); cql_multibind(&_rc_, _db_, &C_stmt, 2, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, procname_, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, source_); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } for (;;) { _rc_ = sqlite3_step(C_stmt); C._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, C_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &C.source, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &C.procname, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &C.line, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &C.data, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &C.physical_line); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } if (!C._has_row_) break; cql_alloc_cstr(_cstr_4, C.data); printf("%5d %s\n", C.line, _cstr_4); cql_free_cstr(_cstr_4, C.data); } _rc_ = SQLITE_OK; cql_cleanup: cql_finalize_stmt(&C_stmt); cql_teardown_row(C); return _rc_; } #undef _PROC_ // Generated from linetest.sql:73 /* CREATE PROC dump (procname TEXT NOT NULL) BEGIN CALL printf("%s: difference encountered\n", procname); CALL printf("<<<< EXPECTED\n"); CALL dump_proc_records("exp", procname); CALL printf(">>>> ACTUAL\n"); CALL dump_proc_records("act", procname); END; */ #define _PROC_ "dump" CQL_WARN_UNUSED cql_code dump(sqlite3 *_Nonnull _db_, cql_string_ref _Nonnull procname) { cql_contract_argument_notnull((void *)procname, 1); cql_code _rc_ = SQLITE_OK; cql_alloc_cstr(_cstr_5, procname); printf("%s: difference encountered\n", _cstr_5); cql_free_cstr(_cstr_5, procname); printf("<<<< EXPECTED\n"); _rc_ = dump_proc_records(_db_, _literal_1_exp_dump, procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } printf(">>>> ACTUAL\n"); _rc_ = dump_proc_records(_db_, _literal_2_act_dump, procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = SQLITE_OK; cql_cleanup: return _rc_; } #undef _PROC_ // Generated from linetest.sql:134 /* CREATE PROC compare_lines (OUT procs INTEGER NOT NULL, OUT compares INTEGER NOT NULL, OUT errors INTEGER NOT NULL) BEGIN DECLARE p CURSOR FOR SELECT * FROM procs; LOOP FETCH p BEGIN SET procs := procs + 1; DECLARE actual CURSOR FOR SELECT * FROM linedata WHERE source = 'act' AND procname = p.procname; DECLARE expected CURSOR FOR SELECT * FROM linedata WHERE source = 'exp' AND procname = p.procname; FETCH actual; FETCH expected; WHILE actual AND expected BEGIN SET compares := compares + 1; IF actual.line <> expected.line OR actual.data <> expected.data THEN CALL dump(p.procname); CALL printf("\nFirst difference:\n"); CALL printf("expected: %5d %s\n", expected.line, expected.data); CALL printf(" actual: %5d %s\n", actual.line, actual.data); CALL printf("\nDifferences at:\n line %d in expected\n line %d in actual", expected.physical_line, actual.physical_line); CALL printf("\n"); SET errors := errors + 1; LEAVE; END IF; FETCH actual; FETCH expected; END; IF actual <> expected THEN IF NOT actual THEN CALL dump(p.procname); CALL printf("\nRan out of lines in actual:\n"); CALL printf("\nDifferences at:\n line %d in expected\n", expected.physical_line); CALL printf("\n"); SET errors := errors + 1; END IF; IF NOT expected THEN CALL dump(p.procname); CALL printf("\nRan out of lines in expected:\n"); CALL printf("\nDifferences at:\n line %d in actual\n", actual.physical_line); CALL printf("\n"); SET errors := errors + 1; END IF; END IF; END; END; */ #define _PROC_ "compare_lines" typedef struct compare_lines_p_row { cql_bool _has_row_; cql_uint16 _refs_count_; cql_uint16 _refs_offset_; cql_string_ref _Nonnull procname; } compare_lines_p_row; #define compare_lines_p_refs_offset cql_offsetof(compare_lines_p_row, procname) // count = 1 typedef struct compare_lines_actual_row { cql_bool _has_row_; cql_uint16 _refs_count_; cql_uint16 _refs_offset_; cql_int32 line; cql_int32 physical_line; cql_string_ref _Nonnull source; cql_string_ref _Nonnull procname; cql_string_ref _Nonnull data; } compare_lines_actual_row; #define compare_lines_actual_refs_offset cql_offsetof(compare_lines_actual_row, source) // count = 3 typedef struct compare_lines_expected_row { cql_bool _has_row_; cql_uint16 _refs_count_; cql_uint16 _refs_offset_; cql_int32 line; cql_int32 physical_line; cql_string_ref _Nonnull source; cql_string_ref _Nonnull procname; cql_string_ref _Nonnull data; } compare_lines_expected_row; #define compare_lines_expected_refs_offset cql_offsetof(compare_lines_expected_row, source) // count = 3 CQL_WARN_UNUSED cql_code compare_lines(sqlite3 *_Nonnull _db_, cql_int32 *_Nonnull procs, cql_int32 *_Nonnull compares, cql_int32 *_Nonnull errors) { cql_contract_argument_notnull((void *)procs, 1); cql_contract_argument_notnull((void *)compares, 2); cql_contract_argument_notnull((void *)errors, 3); cql_code _rc_ = SQLITE_OK; sqlite3_stmt *p_stmt = NULL; compare_lines_p_row p = { ._refs_count_ = 1, ._refs_offset_ = compare_lines_p_refs_offset }; sqlite3_stmt *actual_stmt = NULL; compare_lines_actual_row actual = { ._refs_count_ = 3, ._refs_offset_ = compare_lines_actual_refs_offset }; sqlite3_stmt *expected_stmt = NULL; compare_lines_expected_row expected = { ._refs_count_ = 3, ._refs_offset_ = compare_lines_expected_refs_offset }; *procs = 0; // set out arg to non-garbage *compares = 0; // set out arg to non-garbage *errors = 0; // set out arg to non-garbage _rc_ = cql_prepare(_db_, &p_stmt, "SELECT procname " "FROM procs"); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } for (;;) { _rc_ = sqlite3_step(p_stmt); p._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, p_stmt, 1, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &p.procname); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } if (!p._has_row_) break; *procs = (*procs) + 1; cql_finalize_stmt(&actual_stmt); _rc_ = cql_prepare(_db_, &actual_stmt, "SELECT source, procname, line, data, physical_line " "FROM linedata " "WHERE source = 'act' AND procname = ?"); cql_multibind(&_rc_, _db_, &actual_stmt, 1, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, p.procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } cql_finalize_stmt(&expected_stmt); _rc_ = cql_prepare(_db_, &expected_stmt, "SELECT source, procname, line, data, physical_line " "FROM linedata " "WHERE source = 'exp' AND procname = ?"); cql_multibind(&_rc_, _db_, &expected_stmt, 1, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, p.procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } _rc_ = sqlite3_step(actual_stmt); actual._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, actual_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &actual.source, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &actual.procname, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &actual.line, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &actual.data, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &actual.physical_line); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } _rc_ = sqlite3_step(expected_stmt); expected._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, expected_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &expected.source, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &expected.procname, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &expected.line, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &expected.data, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &expected.physical_line); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } for (;;) { if (!(actual._has_row_ && expected._has_row_)) break; *compares = (*compares) + 1; if (actual.line != expected.line || cql_string_compare(actual.data, expected.data) != 0) { _rc_ = dump(_db_, p.procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } printf("\nFirst difference:\n"); cql_alloc_cstr(_cstr_6, expected.data); printf("expected: %5d %s\n", expected.line, _cstr_6); cql_free_cstr(_cstr_6, expected.data); cql_alloc_cstr(_cstr_7, actual.data); printf(" actual: %5d %s\n", actual.line, _cstr_7); cql_free_cstr(_cstr_7, actual.data); printf("\nDifferences at:\n line %d in expected\n line %d in actual", expected.physical_line, actual.physical_line); printf("\n"); *errors = (*errors) + 1; break; } _rc_ = sqlite3_step(actual_stmt); actual._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, actual_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &actual.source, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &actual.procname, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &actual.line, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &actual.data, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &actual.physical_line); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } _rc_ = sqlite3_step(expected_stmt); expected._has_row_ = _rc_ == SQLITE_ROW; cql_multifetch(_rc_, expected_stmt, 5, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &expected.source, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &expected.procname, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &expected.line, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_STRING, &expected.data, CQL_DATA_TYPE_NOT_NULL | CQL_DATA_TYPE_INT32, &expected.physical_line); if (_rc_ != SQLITE_ROW && _rc_ != SQLITE_DONE) { cql_error_trace(); goto cql_cleanup; } } if (actual._has_row_ != expected._has_row_) { if (! actual._has_row_) { _rc_ = dump(_db_, p.procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } printf("\nRan out of lines in actual:\n"); printf("\nDifferences at:\n line %d in expected\n", expected.physical_line); printf("\n"); *errors = (*errors) + 1; } if (! expected._has_row_) { _rc_ = dump(_db_, p.procname); if (_rc_ != SQLITE_OK) { cql_error_trace(); goto cql_cleanup; } printf("\nRan out of lines in expected:\n"); printf("\nDifferences at:\n line %d in actual\n", actual.physical_line); printf("\n"); *errors = (*errors) + 1; } } } _rc_ = SQLITE_OK; cql_cleanup: cql_finalize_stmt(&p_stmt); cql_teardown_row(p); cql_finalize_stmt(&actual_stmt); cql_teardown_row(actual); cql_finalize_stmt(&expected_stmt); cql_teardown_row(expected); return _rc_; } #undef _PROC_ #pragma clang diagnostic pop