| 5810 | } |
| 5811 | |
| 5812 | static int arch_boundaries(cbm_store_t *s, const char *project, const char *path, |
| 5813 | cbm_cross_pkg_boundary_t **out_arr, int *out_count) { |
| 5814 | char norm[CBM_SZ_512]; |
| 5815 | char like[CBM_SZ_512]; |
| 5816 | bool scoped = arch_path_prepare(path, norm, sizeof(norm), like, sizeof(like)); |
| 5817 | char nsqlbuf[ST_SQL_BUF]; |
| 5818 | const char *nbase = |
| 5819 | "SELECT id, qualified_name, file_path FROM nodes WHERE project=?1 AND label IN " |
| 5820 | "(" CBM_SQL_CALLABLE_OR_TYPE_LABELS ")"; |
| 5821 | if (scoped) { |
| 5822 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s%s ORDER BY id", nbase, arch_path_scope_sql()); |
| 5823 | } else { |
| 5824 | snprintf(nsqlbuf, sizeof(nsqlbuf), "%s ORDER BY id", nbase); |
| 5825 | } |
| 5826 | sqlite3_stmt *nstmt = NULL; |
| 5827 | if (sqlite3_prepare_v2(s->db, nsqlbuf, CBM_NOT_FOUND, &nstmt, NULL) != SQLITE_OK) { |
| 5828 | store_set_error_sqlite(s, "arch_boundaries_nodes"); |
| 5829 | return CBM_STORE_ERR; |
| 5830 | } |
| 5831 | bind_text(nstmt, SKIP_ONE, project); |
| 5832 | if (scoped) { |
| 5833 | arch_bind_path_scope(nstmt, ST_COL_2, ST_COL_3, norm, like); |
| 5834 | } |
| 5835 | |
| 5836 | int ncap = CBM_SZ_256; |
| 5837 | int nn = 0; |
| 5838 | int64_t *nids = malloc(ncap * sizeof(int64_t)); |
| 5839 | char **npkgs = malloc(ncap * sizeof(char *)); |
| 5840 | |
| 5841 | int scan_rc24; |
| 5842 | while ((scan_rc24 = sqlite3_step(nstmt)) == SQLITE_ROW) { |
| 5843 | if (nn >= ncap) { |
| 5844 | ncap *= ST_GROWTH; |
| 5845 | nids = safe_realloc(nids, ncap * sizeof(int64_t)); |
| 5846 | npkgs = safe_realloc(npkgs, ncap * sizeof(char *)); |
| 5847 | } |
| 5848 | int64_t nid = sqlite3_column_int64(nstmt, 0); |
| 5849 | nids[nn] = nid; |
| 5850 | const char *qn = (const char *)sqlite3_column_text(nstmt, SKIP_ONE); |
| 5851 | npkgs[nn] = heap_strdup(cbm_qn_to_package(qn)); |
| 5852 | nn++; |
| 5853 | } |
| 5854 | if (scan_rc24 != SQLITE_DONE) { /* SCANCHK:24:nstmt */ |
| 5855 | store_set_error_sqlite(s, "row scan aborted"); |
| 5856 | sqlite3_finalize(nstmt); |
| 5857 | for (int bi = 0; bi < nn; bi++) { |
| 5858 | free(npkgs[bi]); |
| 5859 | } |
| 5860 | free(nids); |
| 5861 | free(npkgs); |
| 5862 | return CBM_STORE_ERR; |
| 5863 | } |
| 5864 | sqlite3_finalize(nstmt); |
| 5865 | |
| 5866 | /* Scan edges, count cross-package calls */ |
| 5867 | const char *esql = "SELECT source_id, target_id FROM edges WHERE project=?1 AND type='CALLS'"; |
| 5868 | sqlite3_stmt *estmt = NULL; |
| 5869 | if (sqlite3_prepare_v2(s->db, esql, CBM_NOT_FOUND, &estmt, NULL) != SQLITE_OK) { |
no test coverage detected