1/* Test of u16_prev() function. 2 Copyright (C) 2010 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17/* Written by Bruno Haible <bruno@clisp.org>, 2010. */ 18 19#include <config.h> 20 21#include "unistr.h" 22 23#include "macros.h" 24 25static int 26check (const uint16_t *input, size_t input_length, ucs4_t *puc) 27{ 28 ucs4_t uc; 29 30 /* Test recognition when at the beginning of the string. */ 31 if (u16_prev (&uc, input + input_length, input) != input) 32 return 1; 33 34 /* Test recognition when preceded by a 1-unit character. */ 35 { 36 uint16_t buf[100]; 37 uint16_t *ptr; 38 size_t i; 39 ucs4_t uc1; 40 41 ptr = buf; 42 *ptr++ = 0x2102; 43 for (i = 0; i < input_length; i++) 44 ptr[i] = input[i]; 45 46 if (u16_prev (&uc1, ptr + input_length, buf) != ptr) 47 return 2; 48 if (uc1 != uc) 49 return 3; 50 } 51 52 /* Test recognition when preceded by a 2-unit character. */ 53 { 54 uint16_t buf[100]; 55 uint16_t *ptr; 56 size_t i; 57 ucs4_t uc1; 58 59 ptr = buf; 60 *ptr++ = 0xD835; 61 *ptr++ = 0xDD1E; 62 for (i = 0; i < input_length; i++) 63 ptr[i] = input[i]; 64 65 if (u16_prev (&uc1, ptr + input_length, buf) != ptr) 66 return 4; 67 if (uc1 != uc) 68 return 5; 69 } 70 71 *puc = uc; 72 return 0; 73} 74 75static int 76check_invalid (const uint16_t *input, size_t input_length) 77{ 78 ucs4_t uc; 79 80 /* Test recognition when at the beginning of the string. */ 81 uc = 0xBADFACE; 82 if (u16_prev (&uc, input + input_length, input) != NULL) 83 return 1; 84 if (uc != 0xBADFACE) 85 return 2; 86 87#if CONFIG_UNICODE_SAFETY 88 /* Test recognition when preceded by a 1-unit character. */ 89 { 90 uint16_t buf[100]; 91 uint16_t *ptr; 92 size_t i; 93 94 ptr = buf; 95 *ptr++ = 0x2102; 96 for (i = 0; i < input_length; i++) 97 ptr[i] = input[i]; 98 99 uc = 0xBADFACE; 100 if (u16_prev (&uc, ptr + input_length, buf) != NULL) 101 return 3; 102 if (uc != 0xBADFACE) 103 return 4; 104 } 105 106 /* Test recognition when preceded by a 2-unit character. */ 107 { 108 uint16_t buf[100]; 109 uint16_t *ptr; 110 size_t i; 111 112 ptr = buf; 113 *ptr++ = 0xD835; 114 *ptr++ = 0xDD1E; 115 for (i = 0; i < input_length; i++) 116 ptr[i] = input[i]; 117 118 uc = 0xBADFACE; 119 if (u16_prev (&uc, ptr + input_length, buf) != NULL) 120 return 5; 121 if (uc != 0xBADFACE) 122 return 6; 123 } 124#endif 125 126 return 0; 127} 128 129int 130main () 131{ 132 ucs4_t uc; 133 134 /* Test ISO 646 unit input. */ 135 { 136 ucs4_t c; 137 uint16_t buf[1]; 138 139 for (c = 0; c < 0x80; c++) 140 { 141 buf[0] = c; 142 uc = 0xBADFACE; 143 ASSERT (check (buf, 1, &uc) == 0); 144 ASSERT (uc == c); 145 } 146 } 147 148 /* Test BMP unit input. */ 149 { 150 static const uint16_t input[] = { 0x20AC }; 151 uc = 0xBADFACE; 152 ASSERT (check (input, SIZEOF (input), &uc) == 0); 153 ASSERT (uc == 0x20AC); 154 } 155 156 /* Test 2-units character input. */ 157 { 158 static const uint16_t input[] = { 0xD835, 0xDD1F }; 159 uc = 0xBADFACE; 160 ASSERT (check (input, SIZEOF (input), &uc) == 0); 161 ASSERT (uc == 0x1D51F); 162 } 163 164 /* Test incomplete/invalid 1-unit input. */ 165 { 166 static const uint16_t input[] = { 0xD835 }; 167 ASSERT (check_invalid (input, SIZEOF (input)) == 0); 168 } 169 { 170 static const uint16_t input[] = { 0xDD1F }; 171 ASSERT (check_invalid (input, SIZEOF (input)) == 0); 172 } 173 174 return 0; 175} 176