| 5911 | } |
| 5912 | |
| 5913 | static int arch_boundaries(cbm_store_t *s, const char *project, const char *path, |
| 5914 | cbm_cross_pkg_boundary_t **out_arr, int *out_count) { |
| 5915 | char norm[CBM_SZ_512]; |
| 5916 | char like[CBM_SZ_512]; |
| 5917 | bool scoped = arch_path_prepare(path, norm, sizeof(norm), like, sizeof(like)); |
| 5918 | char nsqlbuf[ST_SQL_BUF]; |
| 5919 | const char *nbase = |
| 5920 | "SELECT id, qualified_name, file_path FROM nodes WHERE project=?1 AND label IN " |
| 5921 | "(" CBM_SQL_CALLABLE_OR_TYPE_LABELS ")"; |
| 5922 | if (scoped) { |
| 5923 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s%s ORDER BY id", nbase, arch_path_scope_sql()); |
| 5924 | } else { |
| 5925 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s ORDER BY id", nbase); |
| 5926 | } |
| 5927 | sqlite3_stmt *nstmt = NULL; |
| 5928 | if (sqlite3_prepare_v2(s->db, nsqlbuf, CBM_NOT_FOUND, &nstmt, NULL) != SQLITE_OK) { |
| 5929 | store_set_error_sqlite(s, "arch_boundaries_nodes"); |
| 5930 | return CBM_STORE_ERR; |
| 5931 | } |
| 5932 | bind_text(nstmt, SKIP_ONE, project); |
| 5933 | if (scoped) { |
| 5934 | arch_bind_path_scope(nstmt, ST_COL_2, ST_COL_3, norm, like); |
| 5935 | } |
| 5936 | |
| 5937 | int ncap = CBM_SZ_256; |
| 5938 | int nn = 0; |
| 5939 | int64_t *nids = malloc(ncap * sizeof(int64_t)); |
| 5940 | char **npkgs = malloc(ncap * sizeof(char *)); |
| 5941 | |
| 5942 | int scan_rc24; |
| 5943 | while ((scan_rc24 = sqlite3_step(nstmt)) == SQLITE_ROW) { |
| 5944 | if (nn >= ncap) { |
| 5945 | ncap *= ST_GROWTH; |
| 5946 | nids = safe_realloc(nids, ncap * sizeof(int64_t)); |
| 5947 | npkgs = safe_realloc(npkgs, ncap * sizeof(char *)); |
| 5948 | } |
| 5949 | int64_t nid = sqlite3_column_int64(nstmt, 0); |
| 5950 | nids[nn] = nid; |
| 5951 | const char *qn = (const char *)sqlite3_column_text(nstmt, SKIP_ONE); |
| 5952 | npkgs[nn] = heap_strdup(cbm_qn_to_package(qn)); |
| 5953 | nn++; |
| 5954 | } |
| 5955 | if (scan_rc24 != SQLITE_DONE) { /* SCANCHK:24:nstmt */ |
| 5956 | store_set_error_sqlite(s, "row scan aborted"); |
| 5957 | sqlite3_finalize(nstmt); |
| 5958 | for (int bi = 0; bi < nn; bi++) { |
| 5959 | free(npkgs[bi]); |
| 5960 | } |
| 5961 | free(nids); |
| 5962 | free(npkgs); |
| 5963 | return CBM_STORE_ERR; |
| 5964 | } |
| 5965 | sqlite3_finalize(nstmt); |
| 5966 | |
| 5967 | /* Scan edges, count cross-package calls */ |
| 5968 | const char *esql = "SELECT source_id, target_id FROM edges WHERE project=?1 AND type='CALLS'"; |
| 5969 | sqlite3_stmt *estmt = NULL; |
| 5970 | if (sqlite3_prepare_v2(s->db, esql, CBM_NOT_FOUND, &estmt, NULL) != SQLITE_OK) { |
no test coverage detected