[Spice-devel] [usbredir v2 strtok_r Test Program] a test program for win_strtok_r

Uri Lublin uril at redhat.com
Thu May 24 07:40:27 PDT 2012


This is not to be committed.
Just a test program for previous patch.
---

/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
   Copyright (C) 2012 Red Hat, Inc.

   Red Hat Authors:
   Uri Lublin <uril at redhat.com>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* implementation copied from the patch */
/*
 *  strtok_r like implementation for windows (mingw).
 *
 *  Only the first character of delim is used as a delimiter
 */
char *win_strtok_r(char *str, const char *delim, char **state)
{
    const char d = delim[0];
    char *p;
    int found = 0;

    /* sanity checks */
    if ((delim == NULL) || (state == NULL))
       return NULL;
   
    if (str == NULL) {
       str = *state;
    }

    if (str == NULL) {
       return NULL;
    }

    for (p=str; *p ; p++) {
       if (*p == d) {
           found = 1;
           *p++ = '\0';
           while (*p && *p==d) /* skip all delimiters */ 
               p++;
           break;
       }
    }

    *state = found ? p : NULL;

    /* do not return empty strings */
    if (!*str)
        return NULL;

    return str;
}




const char *safe(const char *s)
{
    if (s)
        return s;
    return "NULL";
}

/* 
 * tokenizing a string 'str' with delimiters 'delim' and 'delim2' once
 * by win_strtok_r and once by strtok_r, and compares the result.
 * str   must not be NULL
 * delim must contain at least a single character.
 * delim2 may be NULL
 * returns 0 on success, -1 on failure
 */
int test_1_case(const char *str, const char *delim, const char *delim2)
{
    char *str1 = strdup(str); /* call with win_strtok_r */
    char *str2 = strdup(str); /* call with strtok_r */
    char *state1, *state2;
    char *tok11, *tok12;
    char *tok21, *tok22;
    int res = -1;


    if (!str1 || !str2 || !delim) {
        printf("bad params\n");
        return -1;
    }

    if (strcmp(str1, str2) != 0) {
        printf("str1=%s and str2=%s differ\n", str1, str2);
    }

    printf("\ntestcase '%s', delim=%s, delim2=%s\n", str1, delim, safe(delim2));

    tok11 = win_strtok_r(str1, delim, &state1);
    tok12 = strtok_r(str2, delim, &state2);
    while (tok11 && tok12) {
        if (strcmp(tok11, tok12) != 0) {
            printf("-- tok11=%s, tok12=%s\n", tok11, tok12);
            goto fail;
        }
        if (delim2) {
            tok21 = win_strtok_r(tok11, delim2, &state1);
            tok22 = strtok_r(tok12, delim2, &state2);
            while (tok21 && tok22) {
                if (strcmp(tok21, tok22) != 0) {
                    printf("== tok21=%s, tok22=%s\n", tok21, tok22);
                    goto fail;                
                }
                tok21 = win_strtok_r(NULL, delim2, &state1);
                tok22 = strtok_r(NULL, delim2, &state2);
            }
            if (tok21 || tok22) {
                printf("++ tok21=%s, tok22=%s\n", safe(tok21), safe(tok22));
                goto fail;
            }
        }
        tok11 = win_strtok_r(NULL, delim, &state1);
        tok12 = strtok_r(NULL, delim, &state2);
    }

    if (tok11 || tok12) {
        printf("** tok11=%s tok12=%s\n", safe(tok11), safe(tok12));
        goto fail;
    }

    res = 0;
 fail:
    free(str1);
    free(str2);
    return res;
}


/* ts[] must end with a NULL entry */
int test_many_cases(const char *ts[], const char *d1, const char *d2)
{
    const char **pstr;
    int r=0;

    for (pstr=ts; *pstr; pstr++) {
        if (test_1_case(*pstr, d1, d2)) {
            printf("failed for testcase %s\n", *pstr);
            r++;
        }
    }
    return r;
}

int main()
{
    int r;
    const char *a[] = {
	"hello:uri:how::::are you",
	"here we are : in the center of town :: look : : every body here",
	"abcdefg",
	"",
	":::",
        ":",
	NULL
    };

    const char *b[] = {
	"hello:uri+how:are::::you++++Hey there:lookatme",
	"h+++u+++q:"
	"",
	"h",
	"h:",
	"h:+p",
	"h+:p",
	"h:+",
	"h+:",
	"++::++h++::+q:v",
	NULL
    };

    const char *c[] = {
        "hello",
        NULL
    };

    r = 0;
    r += test_many_cases(a, ":", NULL);
    r += test_many_cases(b, ":", "+");
    r += test_many_cases(c, "", NULL);

    if (r == 0) {
        printf("success\n");
    } else {
        printf("failed in %d tests\n", r);
    }
    return r;
}

-- 
1.7.1



More information about the Spice-devel mailing list