/* This is common code for mpi_timer.c and mpi_analyse.c.  Note that it
is NOT properly encapsulated and relies on the calling code to include
headers and so on. */



int matchstring (const char *arg1, const char *arg2) {

/* Case insensitive string compare. */

    int i;

    for (i = 0; i <= strlen(arg1); ++i)
        if (tolower(arg1[i]) != tolower(arg2[i])) return 0;
    return 1;
}



const char *matcharg (const char *arg, const void *table,
    int count, int size, const char *all) {

/* Match an argument, and return a pointer to a string consisting of
just the flag letters. */

    int i, j, k, n = strlen(arg);
    char *copy, flags[UCHAR_MAX+1];
    const argument_type *ptr;

    if (n == 0) return NULL;
    if ((copy = malloc(n+1)) == NULL)
        failure("Unable to copy argument");
    for (i = 0; i < n; ++i) copy[i] = tolower(arg[i]);
    copy[n] = '\0';
    if (strcmp(copy,"all") == 0) return all;

/* Try matching a word. */

    for (i = 0; i < count; ++i) {
        ptr = (const argument_type *)((const char *)table+size*i);
        if (strcmp(ptr->tag,copy) == 0) {
            copy[1] = '\0';
            return copy;
        }
    }

/* So it is not a word - try a sequence of letters. */

    for (i = 0; i < UCHAR_MAX+1; ++i) flags[i] = 0;
    for (j = 0; j < n; ++j) {
        k = (unsigned char)copy[j];
        for (i = 0; i < count; ++i) {
            ptr = (const argument_type *)((const char *)table+size*i);
            if (k == ptr->tag[0]) goto found;
        }
        return NULL;
found:  if (flags[k]) return NULL;
        flags[k] = 1;
    }
    return copy;
}



size_t readsize (const char *arg) {

/* Read a size with optional scale and convert to units of doubles.
Return the value or 0 for failure. */

    int k, m = 1, n;
    size_t z;

    if (sscanf(arg,"%d%n",&k,&n) != 1 || k < 1) return 0;
    if (tolower(arg[n]) == 'k') {
        m = 1024;
        ++n;
    } else if (tolower(arg[n]) == 'm') {
        m = 1048576;
        ++n;
    }
    if (arg[n] != '\0') return 0;
    z = k*(size_t)m;
    if (z != k*(double)m) return 0;
    return (z-1)/sizeof(double)+1;
}
