| 284 | } |
| 285 | |
| 286 | static bool |
| 287 | binary_operator (bool l_is_l, enum binop bop) |
| 288 | { |
| 289 | int op; |
| 290 | |
| 291 | if (l_is_l) |
| 292 | advance (false); |
| 293 | op = pos + 1; |
| 294 | |
| 295 | /* Is the right integer expression of the form '-l string'? */ |
| 296 | bool r_is_l = op < argc - 2 && streq (argv[op + 1], "-l"); |
| 297 | if (r_is_l) |
| 298 | advance (false); |
| 299 | |
| 300 | pos += 3; |
| 301 | |
| 302 | switch (bop) |
| 303 | { |
| 304 | case EQ_BINOP: case GE_BINOP: case GT_BINOP: |
| 305 | case LE_BINOP: case LT_BINOP: case NE_BINOP: |
| 306 | { |
| 307 | char lbuf[INT_BUFSIZE_BOUND (uintmax_t)]; |
| 308 | char rbuf[INT_BUFSIZE_BOUND (uintmax_t)]; |
| 309 | char const *l = (l_is_l |
| 310 | ? umaxtostr (strlen (argv[op - 1]), lbuf) |
| 311 | : find_int (argv[op - 1])); |
| 312 | char const *r = (r_is_l |
| 313 | ? umaxtostr (strlen (argv[op + 2]), rbuf) |
| 314 | : find_int (argv[op + 1])); |
| 315 | int cmp = strintcmp (l, r); |
| 316 | switch (+bop) |
| 317 | { |
| 318 | case EQ_BINOP: return cmp == 0; |
| 319 | case GE_BINOP: return cmp >= 0; |
| 320 | case GT_BINOP: return cmp > 0; |
| 321 | case LE_BINOP: return cmp <= 0; |
| 322 | case LT_BINOP: return cmp < 0; |
| 323 | case NE_BINOP: return cmp != 0; |
| 324 | } |
| 325 | unreachable (); |
| 326 | } |
| 327 | |
| 328 | case NT_BINOP: case OT_BINOP: |
| 329 | { |
| 330 | if (l_is_l | r_is_l) |
| 331 | test_syntax_error (_("%s does not accept -l"), |
| 332 | argv[op]); |
| 333 | int cmp = timespec_cmp (get_mtime (argv[op - 1]), |
| 334 | get_mtime (argv[op + 1])); |
| 335 | return bop == OT_BINOP ? cmp < 0 : cmp > 0; |
| 336 | } |
| 337 | |
| 338 | case EF_BINOP: |
| 339 | if (l_is_l | r_is_l) |
| 340 | test_syntax_error (_("-ef does not accept -l")); |
| 341 | else |
| 342 | { |
| 343 | struct stat st[2]; |