Compare the names of two file_struct entities, similar to how strcmp() * would do if it were operating on the joined strings. * * Some differences beginning with protocol_version 29: (1) directory names * are compared with an assumed trailing slash so that they compare in a * way that would cause them to sort immediately prior to any content they * may have; (2) a directory of any name compa
| 3250 | * may be NULL (for a removed item), in which case it is considered to be |
| 3251 | * after any existing item. */ |
| 3252 | int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2) |
| 3253 | { |
| 3254 | int dif; |
| 3255 | const uchar *c1, *c2; |
| 3256 | enum fnc_state state1, state2; |
| 3257 | enum fnc_type type1, type2; |
| 3258 | enum fnc_type t_path = protocol_version >= 29 ? t_PATH : t_ITEM; |
| 3259 | |
| 3260 | if (!f1 || !F_IS_ACTIVE(f1)) { |
| 3261 | if (!f2 || !F_IS_ACTIVE(f2)) |
| 3262 | return 0; |
| 3263 | return -1; |
| 3264 | } |
| 3265 | if (!f2 || !F_IS_ACTIVE(f2)) |
| 3266 | return 1; |
| 3267 | |
| 3268 | c1 = (uchar*)f1->dirname; |
| 3269 | c2 = (uchar*)f2->dirname; |
| 3270 | if (c1 == c2) |
| 3271 | c1 = c2 = NULL; |
| 3272 | if (!c1) { |
| 3273 | type1 = S_ISDIR(f1->mode) ? t_path : t_ITEM; |
| 3274 | c1 = (const uchar*)f1->basename; |
| 3275 | if (type1 == t_PATH && *c1 == '.' && !c1[1]) { |
| 3276 | type1 = t_ITEM; |
| 3277 | state1 = s_TRAILING; |
| 3278 | c1 = (uchar*)""; |
| 3279 | } else |
| 3280 | state1 = s_BASE; |
| 3281 | } else { |
| 3282 | type1 = t_path; |
| 3283 | state1 = s_DIR; |
| 3284 | } |
| 3285 | if (!c2) { |
| 3286 | type2 = S_ISDIR(f2->mode) ? t_path : t_ITEM; |
| 3287 | c2 = (const uchar*)f2->basename; |
| 3288 | if (type2 == t_PATH && *c2 == '.' && !c2[1]) { |
| 3289 | type2 = t_ITEM; |
| 3290 | state2 = s_TRAILING; |
| 3291 | c2 = (uchar*)""; |
| 3292 | } else |
| 3293 | state2 = s_BASE; |
| 3294 | } else { |
| 3295 | type2 = t_path; |
| 3296 | state2 = s_DIR; |
| 3297 | } |
| 3298 | |
| 3299 | if (type1 != type2) |
| 3300 | return type1 == t_PATH ? 1 : -1; |
| 3301 | |
| 3302 | do { |
| 3303 | if (!*c1) { |
| 3304 | switch (state1) { |
| 3305 | case s_DIR: |
| 3306 | state1 = s_SLASH; |
| 3307 | c1 = (uchar*)"/"; |
| 3308 | break; |
| 3309 | case s_SLASH: |
no outgoing calls
no test coverage detected