sources/linetester/linetest_main.c (106 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 <inttypes.h> #include "cqlrt.h" #include "linetest.h" // super cheesy error handling #define E(x) \ if (SQLITE_OK != (x)) { \ fprintf(stderr, "error encountered at: %s (%s:%d)\n", #x, __FILE__, __LINE__); \ fprintf(stderr, "args: %s, %s\n", expected_name, actual_name); \ fprintf(stderr, "sqlite3_errmsg: %s\n", sqlite3_errmsg(db)); \ exit(1); \ } const char *prefix1 = "#define _PROC_ \""; const char *prefix2 = "#undef _PROC_"; const char *prefix3 = "#line "; const char *prefix4 = "# "; int32_t tests = 0; int32_t errors = 0; int32_t attempts = 0; sqlite3 *db = NULL; const char *expected_name; const char *actual_name; void read_file(FILE *input, const char *source) { cql_string_ref name = cql_string_ref_new(source); cql_string_ref proc = NULL; char buffer[40960]; // good enough for test purposes bool base_at_next_line = false; int32_t line = 0; int32_t line_base = 0; int32_t physical_line = 0; while (fgets(buffer, sizeof(buffer), input)) { physical_line++; char *p = strchr(buffer, '\n'); *p = 0; const char *p1 = strstr(buffer, prefix1); if (p1 == buffer) { cql_string_release(proc); proc = cql_string_ref_new(buffer + strlen(prefix1)); base_at_next_line = true; line = 0; size_t plen = strlen(proc->ptr); ((char*)proc->ptr)[plen-1] = 0; } const char *p2 = strstr(buffer, prefix2); if (p2 == buffer) { cql_string_release(proc); proc = NULL; line = 0; line_base = 0; } const char *line_start = NULL; const char *p3 = strstr(buffer, prefix3); if (p3 != NULL) { line_start = p3 + strlen(prefix3); } const char *p4 = strstr(buffer, prefix4); if (p4 != NULL) { line_start = p4 + strlen(prefix4); } if (line_start != NULL) { line = atoi(line_start); if (base_at_next_line) { line_base = line - 1; base_at_next_line = false; } line -= line_base; continue; } cql_string_ref ref = cql_string_ref_new(buffer); if (!proc) continue; E(linetest_add(db, name, proc, line, ref, physical_line)); cql_string_release(ref); } } int main(int argc, char **argv) { if (argc != 3) { printf("usage cql-linetest expected actual\n"); printf("cql-linetest is a test tool. It processes the input files\n"); printf("normalizing the lines to the start of each procedure\n"); printf("and verifies that the line numbers are as expected\n"); exit(0); } expected_name = argv[1]; actual_name = argv[2]; FILE *expected = fopen(expected_name, "r"); if (!expected) { fprintf(stderr, "unable to open file '%s'\n", expected_name); } FILE *actual = fopen(actual_name, "r"); if (!actual) { fprintf(stderr, "unable to open file '%s'\n", actual_name); } E(sqlite3_open(":memory:", &db)); E(linetest_setup(db)); read_file(expected, "exp"); read_file(actual, "act"); fclose(actual); fclose(expected); int32_t procs, compares, errors; E(compare_lines(db, &procs, &compares, &errors)); printf("\n"); if (errors) { printf("EXPECTED INPUT FILE: %s\n", expected_name); printf(" ACTUAL INPUT FILE: %s\n", actual_name); } printf("Verification results: %d procedures matched %d patterns of which %d were errors.\n", procs, compares, errors); exit(errors); }