| 6325 | } |
| 6326 | |
| 6327 | static void classify_layer(const char *pkg, int in, int out_deg, bool has_routes, |
| 6328 | bool has_entry_points, const char **layer, const char **reason) { |
| 6329 | static CBM_TLS char reason_buf[CBM_SZ_128]; |
| 6330 | if (has_entry_points && out_deg > 0 && in == 0) { |
| 6331 | *layer = "entry"; |
| 6332 | *reason = "has entry points, only outbound calls"; |
| 6333 | return; |
| 6334 | } |
| 6335 | if (has_routes) { |
| 6336 | *layer = "api"; |
| 6337 | *reason = "has HTTP route definitions"; |
| 6338 | return; |
| 6339 | } |
| 6340 | if (in > out_deg && in > ST_MIN_INDEGREE) { |
| 6341 | snprintf(reason_buf, sizeof(reason_buf), "high fan-in (%d in, %d out)", in, out_deg); |
| 6342 | *layer = "core"; |
| 6343 | *reason = reason_buf; |
| 6344 | return; |
| 6345 | } |
| 6346 | if (out_deg == 0 && in > 0) { |
| 6347 | *layer = "leaf"; |
| 6348 | *reason = "only inbound calls, no outbound"; |
| 6349 | return; |
| 6350 | } |
| 6351 | if (in == 0 && out_deg > 0) { |
| 6352 | *layer = "entry"; |
| 6353 | *reason = "only outbound calls"; |
| 6354 | return; |
| 6355 | } |
| 6356 | snprintf(reason_buf, sizeof(reason_buf), "fan-in=%d, fan-out=%d", in, out_deg); |
| 6357 | *layer = "internal"; |
| 6358 | *reason = reason_buf; |
| 6359 | (void)pkg; |
| 6360 | } |
| 6361 | |
| 6362 | /* Find or insert a package name, returning its index. Returns -1 if full. */ |
| 6363 | static int find_or_add_pkg(char **all_pkgs, int *npkgs, int max_pkgs, const char *pkg) { |