#include /* size_t */ #include "libpsargs.h" /* Test string containing { c, '\0' } without iteration. * Theoretically saves a little bit of time compared to strcmp(3). */ #define SCMPFLAT(a, b) (*(a) != '\0' && *((a)+1) == '\0' && *(a) == (b)) int check_arg(char **args){ enum { UNINITIALIZED = 0, NORMAL = 1, INLPAREN = 2 } s; int terms; for(s = UNINITIALIZED, terms = 0; *args != NULL; ++args) switch(s){ case UNINITIALIZED: case NORMAL: if(SCMPFLAT(*args, l)) s = INLPAREN; else return 0; /* syntax error */ break; default: /* >= INLPAREN */ /* decrement s if on an rparen, increment if on lparen * increment terms if on an rparen */ if(args[0][1] == '\0'){ s += (args[0][0] == L_PAREN) - (args[0][0] == R_PAREN); terms += (args[0][0] == R_PAREN && s == NORMAL); } break; } /* make sure nothing's open */ return terms * (s == NORMAL); } char ** corresponding_arg(char **arg){ size_t p; for(p = 1; p > 0;){ ++arg; /* branching here potentially saves a comparison. * this seems like the most optimal way to do this, * maybe it isn't, i don't care too much */ if(SCMPFLAT(*arg, L_PAREN)) ++p; else if(SCMPFLAT(*arg, R_PAREN)) --p; } return arg; } #undef SCMPFLAT