Initial commit
[kk_librfid.git] / firmware / scripts / .svn / text-base / usbstring.c.svn-base
blob5724b40065944d95d51ccaccb8e72de4dcdacc48
1 /* AT91SAM7 USB string descriptor builder 
2  * (C) 2006 by Harald Welte <laforge@gnumonks.org>
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 2 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, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
19 /* Based on existing utf8_to_utf16le() function,
20  * Copyright (C) 2003 David Brownell
21  *
22  * This program is free software; you can redistribute it and/or modify
23  * it under the terms of the GNU Lesser General Public License as published
24  * by the Free Software Foundation; either version 2.1 of the License, or
25  * (at your option) any later version.
26  */
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
34 static int utf8_to_utf16le(const char *s, u_int16_t *cp, unsigned len)
36         int     count = 0;
37         u_int8_t        c;
38         u_int16_t       uchar;
40         /* this insists on correct encodings, though not minimal ones.
41          * BUT it currently rejects legit 4-byte UTF-8 code points,
42          * which need surrogate pairs.  (Unicode 3.1 can use them.)
43          */
44         while (len != 0 && (c = (u_int8_t) *s++) != 0) {
45                 if (c & 0x80) {
46                         // 2-byte sequence:
47                         // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
48                         if ((c & 0xe0) == 0xc0) {
49                                 uchar = (c & 0x1f) << 6;
51                                 c = (u_int8_t) *s++;
52                                 if ((c & 0xc0) != 0xc0)
53                                         goto fail;
54                                 c &= 0x3f;
55                                 uchar |= c;
57                         // 3-byte sequence (most CJKV characters):
58                         // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
59                         } else if ((c & 0xf0) == 0xe0) {
60                                 uchar = (c & 0x0f) << 12;
62                                 c = (u_int8_t) *s++;
63                                 if ((c & 0xc0) != 0xc0)
64                                         goto fail;
65                                 c &= 0x3f;
66                                 uchar |= c << 6;
68                                 c = (u_int8_t) *s++;
69                                 if ((c & 0xc0) != 0xc0)
70                                         goto fail;
71                                 c &= 0x3f;
72                                 uchar |= c;
74                                 /* no bogus surrogates */
75                                 if (0xd800 <= uchar && uchar <= 0xdfff)
76                                         goto fail;
78                         // 4-byte sequence (surrogate pairs, currently rare):
79                         // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
80                         //     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
81                         // (uuuuu = wwww + 1)
82                         // FIXME accept the surrogate code points (only)
84                         } else
85                                 goto fail;
86                 } else
87                         uchar = c;
89                 *cp++ = uchar;
90                 count++;
91                 len--;
92         }
93         return count;
94 fail:
95         return -1;
98 #define COLUMNS         6
99 static int print_array16(u_int16_t *buf, int len)
101         int i;
102         for (i = 0; i < len; i++) {
103                 int mod = i % COLUMNS;
104                 char *suffix;
105                 char *prefix;
107                 switch (mod) {
108                 case 0:
109                         if (i == 0)
110                                 prefix = "\t";
111                         else
112                                 prefix= "\t\t\t";
113                         suffix = ", ";
114                         break;
115                 case COLUMNS-1:
116                         prefix = "";
117                         suffix = ",\n";
118                         break;
119                 default:
120                         prefix = "";
121                         suffix = ", ";
122                         break;
123                 }
124                         
125                 printf("%s0x%04x%s", prefix, buf[i], suffix);
126         }
129 static void print_structhdr(int i, int size)
131         printf( "static const struct {\n"
132                 "\tstruct usb_descriptor_header hdr;\n"
133                 "\tu_int16_t wData[];\n"
134                 "} __attribute__((packed)) string%d = {\n"
135                 "\t.hdr = {\n"
136                 "\t\t.bLength = sizeof(struct usb_descriptor_header) + %u * sizeof(u_int16_t),\n"
137                 "\t\t.bDescriptorType = USB_DT_STRING,\n"
138                 "\t},\n"
139                 "\t.wData = {", i, size);
141 static void print_structftr(void)
143         printf("},\n};\n\n");
146 int main(int argc, char **argv)
148         char asciibuf[512+1];
149         u_int16_t utf16buf[1024+1];
150         int len;
151         int j, i = 1;
153         printf("#ifndef _USB_STRINGS_H\n#define _USB_STRINGS_H\n\n");
154         printf("/* THIS FILE IS AUTOGENERATED, DO NOT MODIFY MANUALLY */\n\n");
155         printf("#include <usb_ch9.h>\n");
156         printf("#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n\n");
158         print_structhdr(0, 1);
159         printf("0x0409 /* English */ ");
160         print_structftr();
161 #if 0   
162         printf("static const struct usb_string_descriptor string0 = {\n"
163                "\t.bLength = sizeof(string0) + 1 * sizeof(u_int16_t),\n"
164                "\t.bDescriptorType = USB_DT_STRING,\n"
165                "\t.wData[0] = 0x0409, /* English */\n"
166                "};\n\n");
167 #endif
169         while (scanf("%512[^\n]\n", asciibuf) != EOF) {
170                 len = strlen(asciibuf);
171                 printf("/* String %u \"%s\" */\n", i, asciibuf);
173                 /* FIXME: check return value */
174                 utf8_to_utf16le(asciibuf, utf16buf, len);
176                 print_structhdr(i, len);
177 #if 0
178                 printf("static const struct usb_string_descriptor string%d = {\n"
179                        "\t.bLength = sizeof(string%d) + %d * sizeof(u_int16_t),\n"
180                        "\t.bDescriptorType = USB_DT_STRING,\n"
181                        "\t.wData = {", i, i, len);
182 #endif
184                 print_array16(utf16buf, len);
186                 print_structftr();
187 #if 0
188                 printf("},\n};\n\n");
189 #endif
191                 i++;
192         }
194         printf("static const struct usb_descriptor_header *usb_strings[] = {\n");
195         for (j = 0; j < i; j++) 
196                 printf("\t(struct usb_descriptor_header *) &string%d,\n", j);
197         printf("};\n\n");
198         printf("#endif /* _USB_STRINGS_H */\n");
200         exit(0);