/ lib / wind / test-normalize.c
test-normalize.c
  1  /*
  2   * Copyright (c) 2004 Kungliga Tekniska Högskolan
  3   * (Royal Institute of Technology, Stockholm, Sweden).
  4   * All rights reserved.
  5   *
  6   * Redistribution and use in source and binary forms, with or without
  7   * modification, are permitted provided that the following conditions
  8   * are met:
  9   *
 10   * 1. Redistributions of source code must retain the above copyright
 11   *    notice, this list of conditions and the following disclaimer.
 12   *
 13   * 2. Redistributions in binary form must reproduce the above copyright
 14   *    notice, this list of conditions and the following disclaimer in the
 15   *    documentation and/or other materials provided with the distribution.
 16   *
 17   * 3. Neither the name of the Institute nor the names of its contributors
 18   *    may be used to endorse or promote products derived from this software
 19   *    without specific prior written permission.
 20   *
 21   * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 24   * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 25   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 27   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 31   * SUCH DAMAGE.
 32   */
 33  
 34  #ifdef HAVE_CONFIG_H
 35  #include <config.h>
 36  #endif
 37  #include <stdio.h>
 38  #include <stdlib.h>
 39  #include <string.h>
 40  #include <err.h>
 41  
 42  #include <roken.h>
 43  
 44  #include "windlocl.h"
 45  #include "normalize_table.h"
 46  
 47  static size_t
 48  parse_vector(char *buf, uint32_t *v)
 49  {
 50      char *last;
 51      unsigned ret = 0;
 52      const char *n;
 53      unsigned u;
 54  
 55      for(n = strtok_r(buf, " ", &last);
 56  	n != NULL;
 57  	n = strtok_r(NULL, " ", &last)) {
 58  	if (ret >= MAX_LENGTH_CANON) {
 59  	    errx(1, "increase MAX_LENGTH_CANON");
 60  	}
 61  	if (sscanf(n, "%x", &u) != 1) {
 62  	    errx(1, "failed to parse hex: %s", n);
 63  	}
 64  	v[ret] = u;
 65  	++ret;
 66      }
 67      return ret;
 68  }
 69  
 70  static void
 71  dump_vector(const char * msg, uint32_t * v, size_t len)
 72  {
 73      size_t i;
 74  
 75      printf("%s: (%d) ", msg, (int)len);
 76      for (i=0; i < len; i++) {
 77  	printf("%s%x", (i > 0? " ":""), v[i]);
 78      }
 79      printf("\n");
 80  }
 81  
 82  static int
 83  test(char *buf, unsigned lineno)
 84  {
 85      char *last;
 86      char *c;
 87      uint32_t in[MAX_LENGTH_CANON];
 88      size_t in_len;
 89      uint32_t out[MAX_LENGTH_CANON];
 90      size_t out_len;
 91      uint32_t *tmp;
 92      size_t norm_len;
 93      int ret;
 94  
 95      c = strtok_r(buf, ";", &last);
 96      if (c == NULL)
 97  	return 0;
 98  
 99      in_len = parse_vector(c, in);
100      if (strtok_r(NULL, ";", &last) == NULL)
101  	return 0;
102      if (strtok_r(NULL, ";", &last) == NULL)
103  	return 0;
104      c = strtok_r(NULL, ";", &last);
105      if (c == NULL)
106  	return 0;
107      out_len = parse_vector(c, out);
108      if (strtok_r(NULL, ";", &last) == NULL)
109  	return 0;
110      c = last;
111  
112      norm_len = MAX_LENGTH_CANON;
113      tmp = malloc(norm_len * sizeof(uint32_t));
114      if (tmp == NULL && norm_len != 0)
115  	err(1, "malloc");
116      ret = _wind_stringprep_normalize(in, in_len, tmp, &norm_len);
117      if (ret) {
118  	printf("wind_stringprep_normalize %s failed\n", c);
119  	free(tmp);
120  	return 1;
121      }
122      if (out_len != norm_len) {
123  	printf("%u: wrong out len (%s)\n", lineno, c);
124  	dump_vector("Expected", out, out_len);
125  	dump_vector("Received", tmp, norm_len);
126  	free(tmp);
127  	return 1;
128      }
129      if (memcmp(out, tmp, out_len * sizeof(uint32_t)) != 0) {
130  	printf("%u: wrong out data (%s)\n", lineno, c);
131  	dump_vector("Expected", out, out_len);
132  	dump_vector("Received", tmp, norm_len);
133  	free(tmp);
134  	return 1;
135      }
136      free(tmp);
137      return 0;
138  }
139  
140  int
141  main(int argc, char **argv)
142  {
143      FILE *f;
144      char buf[1024];
145      char filename[256] = "NormalizationTest.txt";
146      unsigned failures = 0;
147      unsigned lineno = 0;
148  
149      if (argc > 2)
150  	errx(1, "usage: %s [file]", argv[0]);
151      else if (argc == 2)
152  	strlcpy(filename, argv[1], sizeof(filename));
153  
154      f = fopen(filename, "r");
155      if (f == NULL) {
156  	const char *srcdir = getenv("srcdir");
157  	if (srcdir != NULL) {
158  	    char longname[256];
159  	    snprintf(longname, sizeof(longname), "%s/%s", srcdir, filename);
160  	    f = fopen(longname, "r");
161  	}
162  	if (f == NULL)
163  	    err(1, "open %s", filename);
164      }
165      while (fgets(buf, sizeof(buf), f) != NULL) {
166  	lineno++;
167  	if (buf[0] == '#')
168  	    continue;
169  	if (buf[0] == '@') {
170  	    continue;
171  	}
172  	failures += test(buf, lineno);
173      }
174      fclose(f);
175      return failures != 0;
176  }