| 7508 | } |
| 7509 | |
| 7510 | static void classify_layer(const char *pkg, int in, int out_deg, bool has_routes, |
| 7511 | bool has_entry_points, const char **layer, const char **reason) { |
| 7512 | static CBM_TLS char reason_buf[CBM_SZ_128]; |
| 7513 | if (has_entry_points && out_deg > 0 && in == 0) { |
| 7514 | *layer = "entry"; |
| 7515 | *reason = "has entry points, only outbound calls"; |
| 7516 | return; |
| 7517 | } |
| 7518 | if (has_routes) { |
| 7519 | *layer = "api"; |
| 7520 | *reason = "has HTTP route definitions"; |
| 7521 | return; |
| 7522 | } |
| 7523 | if (in > out_deg && in > ST_MIN_INDEGREE) { |
| 7524 | snprintf(reason_buf, sizeof(reason_buf), "high fan-in (%d in, %d out)", in, out_deg); |
| 7525 | *layer = "core"; |
| 7526 | *reason = reason_buf; |
| 7527 | return; |
| 7528 | } |
| 7529 | if (out_deg == 0 && in > 0) { |
| 7530 | *layer = "leaf"; |
| 7531 | *reason = "only inbound calls, no outbound"; |
| 7532 | return; |
| 7533 | } |
| 7534 | if (in == 0 && out_deg > 0) { |
| 7535 | *layer = "entry"; |
| 7536 | *reason = "only outbound calls"; |
| 7537 | return; |
| 7538 | } |
| 7539 | snprintf(reason_buf, sizeof(reason_buf), "fan-in=%d, fan-out=%d", in, out_deg); |
| 7540 | *layer = "internal"; |
| 7541 | *reason = reason_buf; |
| 7542 | (void)pkg; |
| 7543 | } |
| 7544 | |
| 7545 | /* Find or insert a package name, returning its index. Returns -1 if full. */ |
| 7546 | static int find_or_add_pkg(char **all_pkgs, int *npkgs, int max_pkgs, const char *pkg) { |