| 6215 | } |
| 6216 | |
| 6217 | static void classify_layer(const char *pkg, int in, int out_deg, bool has_routes, |
| 6218 | bool has_entry_points, const char **layer, const char **reason) { |
| 6219 | static CBM_TLS char reason_buf[CBM_SZ_128]; |
| 6220 | if (has_entry_points && out_deg > 0 && in == 0) { |
| 6221 | *layer = "entry"; |
| 6222 | *reason = "has entry points, only outbound calls"; |
| 6223 | return; |
| 6224 | } |
| 6225 | if (has_routes) { |
| 6226 | *layer = "api"; |
| 6227 | *reason = "has HTTP route definitions"; |
| 6228 | return; |
| 6229 | } |
| 6230 | if (in > out_deg && in > ST_MIN_INDEGREE) { |
| 6231 | snprintf(reason_buf, sizeof(reason_buf), "high fan-in (%d in, %d out)", in, out_deg); |
| 6232 | *layer = "core"; |
| 6233 | *reason = reason_buf; |
| 6234 | return; |
| 6235 | } |
| 6236 | if (out_deg == 0 && in > 0) { |
| 6237 | *layer = "leaf"; |
| 6238 | *reason = "only inbound calls, no outbound"; |
| 6239 | return; |
| 6240 | } |
| 6241 | if (in == 0 && out_deg > 0) { |
| 6242 | *layer = "entry"; |
| 6243 | *reason = "only outbound calls"; |
| 6244 | return; |
| 6245 | } |
| 6246 | snprintf(reason_buf, sizeof(reason_buf), "fan-in=%d, fan-out=%d", in, out_deg); |
| 6247 | *layer = "internal"; |
| 6248 | *reason = reason_buf; |
| 6249 | (void)pkg; |
| 6250 | } |
| 6251 | |
| 6252 | /* Find or insert a package name, returning its index. Returns -1 if full. */ |
| 6253 | static int find_or_add_pkg(char **all_pkgs, int *npkgs, int max_pkgs, const char *pkg) { |