~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shlwapi/wsprintf.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * wsprintf functions
  3  *
  4  * Copyright 1996 Alexandre Julliard
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  *
 20  * NOTE:
 21  * This code is duplicated in user32. If you change something here make sure
 22  * to change it in user32 too.
 23  */
 24 
 25 #include <stdarg.h>
 26 #include <string.h>
 27 #include <stdio.h>
 28 
 29 #include "windef.h"
 30 #include "winbase.h"
 31 #define NO_SHLWAPI_REG
 32 #include "shlwapi.h"
 33 
 34 #include "wine/debug.h"
 35 
 36 WINE_DEFAULT_DEBUG_CHANNEL(string);
 37 
 38 
 39 #define WPRINTF_LEFTALIGN   0x0001  /* Align output on the left ('-' prefix) */
 40 #define WPRINTF_PREFIX_HEX  0x0002  /* Prefix hex with 0x ('#' prefix) */
 41 #define WPRINTF_ZEROPAD     0x0004  /* Pad with zeros ('' prefix) */
 42 #define WPRINTF_LONG        0x0008  /* Long arg ('l' prefix) */
 43 #define WPRINTF_SHORT       0x0010  /* Short arg ('h' prefix) */
 44 #define WPRINTF_UPPER_HEX   0x0020  /* Upper-case hex ('X' specifier) */
 45 #define WPRINTF_WIDE        0x0040  /* Wide arg ('w' prefix) */
 46 
 47 typedef enum
 48 {
 49     WPR_UNKNOWN,
 50     WPR_CHAR,
 51     WPR_WCHAR,
 52     WPR_STRING,
 53     WPR_WSTRING,
 54     WPR_SIGNED,
 55     WPR_UNSIGNED,
 56     WPR_HEXA
 57 } WPRINTF_TYPE;
 58 
 59 typedef struct
 60 {
 61     UINT         flags;
 62     UINT         width;
 63     UINT         precision;
 64     WPRINTF_TYPE   type;
 65 } WPRINTF_FORMAT;
 66 
 67 typedef union {
 68     WCHAR   wchar_view;
 69     CHAR    char_view;
 70     LPCSTR  lpcstr_view;
 71     LPCWSTR lpcwstr_view;
 72     INT     int_view;
 73 } WPRINTF_DATA;
 74 
 75 static const CHAR null_stringA[] = "(null)";
 76 static const WCHAR null_stringW[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
 77 
 78 /***********************************************************************
 79  *           WPRINTF_ParseFormatA
 80  *
 81  * Parse a format specification. A format specification has the form:
 82  *
 83  * [-][#][0][width][.precision]type
 84  *
 85  * Return value is the length of the format specification in characters.
 86  */
 87 static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res )
 88 {
 89     LPCSTR p = format;
 90 
 91     res->flags = 0;
 92     res->width = 0;
 93     res->precision = 0;
 94     if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
 95     if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
 96     if (*p == '') { res->flags |= WPRINTF_ZEROPAD; p++; }
 97     while ((*p >= '') && (*p <= '9'))  /* width field */
 98     {
 99         res->width = res->width * 10 + *p - '';
100         p++;
101     }
102     if (*p == '.')  /* precision field */
103     {
104         p++;
105         while ((*p >= '') && (*p <= '9'))
106         {
107             res->precision = res->precision * 10 + *p - '';
108             p++;
109         }
110     }
111     if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
112     else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
113     else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
114     switch(*p)
115     {
116     case 'c':
117         res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
118         break;
119     case 'C':
120         res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
121         break;
122     case 'd':
123     case 'i':
124         res->type = WPR_SIGNED;
125         break;
126     case 's':
127         res->type = (res->flags & (WPRINTF_LONG |WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
128         break;
129     case 'S':
130         res->type = (res->flags & (WPRINTF_SHORT|WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
131         break;
132     case 'u':
133         res->type = WPR_UNSIGNED;
134         break;
135     case 'X':
136         res->flags |= WPRINTF_UPPER_HEX;
137         /* fall through */
138     case 'x':
139         res->type = WPR_HEXA;
140         break;
141     default: /* unknown format char */
142         res->type = WPR_UNKNOWN;
143         p--;  /* print format as normal char */
144         break;
145     }
146     return (INT)(p - format) + 1;
147 }
148 
149 
150 /***********************************************************************
151  *           WPRINTF_ParseFormatW
152  *
153  * Parse a format specification. A format specification has the form:
154  *
155  * [-][#][0][width][.precision]type
156  *
157  * Return value is the length of the format specification in characters.
158  */
159 static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res )
160 {
161     LPCWSTR p = format;
162 
163     res->flags = 0;
164     res->width = 0;
165     res->precision = 0;
166     if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
167     if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
168     if (*p == '') { res->flags |= WPRINTF_ZEROPAD; p++; }
169     while ((*p >= '') && (*p <= '9'))  /* width field */
170     {
171         res->width = res->width * 10 + *p - '';
172         p++;
173     }
174     if (*p == '.')  /* precision field */
175     {
176         p++;
177         while ((*p >= '') && (*p <= '9'))
178         {
179             res->precision = res->precision * 10 + *p - '';
180             p++;
181         }
182     }
183     if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
184     else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
185     else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
186     switch((CHAR)*p)
187     {
188     case 'c':
189         res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
190         break;
191     case 'C':
192         res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
193         break;
194     case 'd':
195     case 'i':
196         res->type = WPR_SIGNED;
197         break;
198     case 's':
199         res->type = ((res->flags & WPRINTF_SHORT) && !(res->flags & WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
200         break;
201     case 'S':
202         res->type = (res->flags & (WPRINTF_LONG|WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
203         break;
204     case 'u':
205         res->type = WPR_UNSIGNED;
206         break;
207     case 'X':
208         res->flags |= WPRINTF_UPPER_HEX;
209         /* fall through */
210     case 'x':
211         res->type = WPR_HEXA;
212         break;
213     default:
214         res->type = WPR_UNKNOWN;
215         p--;  /* print format as normal char */
216         break;
217     }
218     return (INT)(p - format) + 1;
219 }
220 
221 
222 /***********************************************************************
223  *           WPRINTF_GetLen
224  */
225 static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg,
226                               LPSTR number, UINT maxlen )
227 {
228     UINT len;
229 
230     if (format->flags & WPRINTF_LEFTALIGN) format->flags &= ~WPRINTF_ZEROPAD;
231     if (format->width > maxlen) format->width = maxlen;
232     switch(format->type)
233     {
234     case WPR_CHAR:
235     case WPR_WCHAR:
236         return (format->precision = 1);
237     case WPR_STRING:
238         if (!arg->lpcstr_view) arg->lpcstr_view = null_stringA;
239         for (len = 0; !format->precision || (len < format->precision); len++)
240             if (!*(arg->lpcstr_view + len)) break;
241         if (len > maxlen) len = maxlen;
242         return (format->precision = len);
243     case WPR_WSTRING:
244         if (!arg->lpcwstr_view) arg->lpcwstr_view = null_stringW;
245         for (len = 0; !format->precision || (len < format->precision); len++)
246             if (!*(arg->lpcwstr_view + len)) break;
247         if (len > maxlen) len = maxlen;
248         return (format->precision = len);
249     case WPR_SIGNED:
250         len = sprintf( number, "%d", arg->int_view );
251         break;
252     case WPR_UNSIGNED:
253         len = sprintf( number, "%u", (UINT)arg->int_view );
254         break;
255     case WPR_HEXA:
256         len = sprintf( number,
257                        (format->flags & WPRINTF_UPPER_HEX) ? "%X" : "%x",
258                        (UINT)arg->int_view);
259         break;
260     default:
261         return 0;
262     }
263     if (len > maxlen) len = maxlen;
264     if (format->precision < len) format->precision = len;
265     if (format->precision > maxlen) format->precision = maxlen;
266     if ((format->flags & WPRINTF_ZEROPAD) && (format->width > format->precision))
267         format->precision = format->width;
268     if (format->flags & WPRINTF_PREFIX_HEX) len += 2;
269     return len;
270 }
271 
272 
273 /***********************************************************************
274  *           wvnsprintfA   (SHLWAPI.@)
275  *
276  * Print formatted output to a string, up to a maximum number of chars.
277  *
278  * PARAMS
279  * buffer [O] Destination for output string
280  * maxlen [I] Maximum number of characters to write
281  * spec   [I] Format string
282  *
283  * RETURNS
284  *  Success: The number of characters written.
285  *  Failure: -1.
286  */
287 INT WINAPI wvnsprintfA( LPSTR buffer, INT maxlen, LPCSTR spec, __ms_va_list args )
288 {
289     WPRINTF_FORMAT format;
290     LPSTR p = buffer;
291     UINT i, len, sign;
292     CHAR number[20];
293     WPRINTF_DATA argData;
294 
295     TRACE("%p %u %s\n", buffer, maxlen, debugstr_a(spec));
296 
297     while (*spec && (maxlen > 1))
298     {
299         if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
300         spec++;
301         if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
302         spec += WPRINTF_ParseFormatA( spec, &format );
303 
304         switch(format.type)
305         {
306         case WPR_WCHAR:
307             argData.wchar_view = (WCHAR)va_arg( args, int );
308             break;
309         case WPR_CHAR:
310             argData.char_view = (CHAR)va_arg( args, int );
311             break;
312         case WPR_STRING:
313             argData.lpcstr_view = va_arg( args, LPCSTR );
314             break;
315         case WPR_WSTRING:
316             argData.lpcwstr_view = va_arg( args, LPCWSTR );
317             break;
318         case WPR_HEXA:
319         case WPR_SIGNED:
320         case WPR_UNSIGNED:
321             argData.int_view = va_arg( args, INT );
322             break;
323         default:
324             argData.wchar_view = 0;
325             break;
326         }
327 
328         len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
329         sign = 0;
330         if (!(format.flags & WPRINTF_LEFTALIGN))
331             for (i = format.precision; i < format.width; i++, maxlen--)
332                 *p++ = ' ';
333         switch(format.type)
334         {
335         case WPR_WCHAR:
336             *p++ = argData.wchar_view;
337             break;
338         case WPR_CHAR:
339             *p++ = argData.char_view;
340             break;
341         case WPR_STRING:
342             memcpy( p, argData.lpcstr_view, len );
343             p += len;
344             break;
345         case WPR_WSTRING:
346             {
347                 LPCWSTR ptr = argData.lpcwstr_view;
348                 for (i = 0; i < len; i++) *p++ = (CHAR)*ptr++;
349             }
350             break;
351         case WPR_HEXA:
352             if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
353             {
354                 *p++ = '';
355                 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
356                 maxlen -= 2;
357                 len -= 2;
358             }
359             /* fall through */
360         case WPR_SIGNED:
361             /* Transfer the sign now, just in case it will be zero-padded*/
362             if (number[0] == '-')
363             {
364                 *p++ = '-';
365                 sign = 1;
366             }
367             /* fall through */
368         case WPR_UNSIGNED:
369             for (i = len; i < format.precision; i++, maxlen--) *p++ = '';
370             memcpy( p, number + sign, len - sign  );
371             p += len - sign;
372             break;
373         case WPR_UNKNOWN:
374             continue;
375         }
376         if (format.flags & WPRINTF_LEFTALIGN)
377             for (i = format.precision; i < format.width; i++, maxlen--)
378                 *p++ = ' ';
379         maxlen -= len;
380     }
381     *p = 0;
382     TRACE("%s\n",debugstr_a(buffer));
383     return (maxlen > 1) ? (INT)(p - buffer) : -1;
384 }
385 
386 
387 /***********************************************************************
388  *           wvnsprintfW   (SHLWAPI.@)
389  *
390  * See wvnsprintfA.
391  */
392 INT WINAPI wvnsprintfW( LPWSTR buffer, INT maxlen, LPCWSTR spec, __ms_va_list args )
393 {
394     WPRINTF_FORMAT format;
395     LPWSTR p = buffer;
396     UINT i, len, sign;
397     CHAR number[20];
398     WPRINTF_DATA argData;
399 
400     TRACE("%p %u %s\n", buffer, maxlen, debugstr_w(spec));
401 
402     while (*spec && (maxlen > 1))
403     {
404         if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
405         spec++;
406         if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
407         spec += WPRINTF_ParseFormatW( spec, &format );
408 
409         switch(format.type)
410         {
411         case WPR_WCHAR:
412             argData.wchar_view = (WCHAR)va_arg( args, int );
413             break;
414         case WPR_CHAR:
415             argData.char_view = (CHAR)va_arg( args, int );
416             break;
417         case WPR_STRING:
418             argData.lpcstr_view = va_arg( args, LPCSTR );
419             break;
420         case WPR_WSTRING:
421             argData.lpcwstr_view = va_arg( args, LPCWSTR );
422             break;
423         case WPR_HEXA:
424         case WPR_SIGNED:
425         case WPR_UNSIGNED:
426             argData.int_view = va_arg( args, INT );
427             break;
428         default:
429             argData.wchar_view = 0;
430             break;
431         }
432 
433         len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
434         sign = 0;
435         if (!(format.flags & WPRINTF_LEFTALIGN))
436             for (i = format.precision; i < format.width; i++, maxlen--)
437                 *p++ = ' ';
438         switch(format.type)
439         {
440         case WPR_WCHAR:
441             *p++ = argData.wchar_view;
442             break;
443         case WPR_CHAR:
444             *p++ = argData.char_view;
445             break;
446         case WPR_STRING:
447             {
448                 LPCSTR ptr = argData.lpcstr_view;
449                 for (i = 0; i < len; i++) *p++ = (WCHAR)*ptr++;
450             }
451             break;
452         case WPR_WSTRING:
453             if (len) memcpy( p, argData.lpcwstr_view, len * sizeof(WCHAR) );
454             p += len;
455             break;
456         case WPR_HEXA:
457             if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
458             {
459                 *p++ = '';
460                 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
461                 maxlen -= 2;
462                 len -= 2;
463             }
464             /* fall through */
465         case WPR_SIGNED:
466             /* Transfer the sign now, just in case it will be zero-padded*/
467             if (number[0] == '-')
468             {
469                 *p++ = '-';
470                 sign = 1;
471             }
472             /* fall through */
473         case WPR_UNSIGNED:
474             for (i = len; i < format.precision; i++, maxlen--) *p++ = '';
475             for (i = sign; i < len; i++) *p++ = (WCHAR)number[i];
476             break;
477         case WPR_UNKNOWN:
478             continue;
479         }
480         if (format.flags & WPRINTF_LEFTALIGN)
481             for (i = format.precision; i < format.width; i++, maxlen--)
482                 *p++ = ' ';
483         maxlen -= len;
484     }
485     *p = 0;
486     TRACE("%s\n",debugstr_w(buffer));
487     return (maxlen > 1) ? (INT)(p - buffer) : -1;
488 }
489 
490 
491 /*************************************************************************
492  *           wnsprintfA   (SHLWAPI.@)
493  *
494  * Print formatted output to a string, up to a maximum number of chars.
495  *
496  * PARAMS
497  * lpOut      [O] Destination for output string
498  * cchLimitIn [I] Maximum number of characters to write
499  * lpFmt      [I] Format string
500  *
501  * RETURNS
502  *  Success: The number of characters written.
503  *  Failure: -1.
504  */
505 int WINAPIV wnsprintfA(LPSTR lpOut, int cchLimitIn, LPCSTR lpFmt, ...)
506 {
507     __ms_va_list valist;
508     INT res;
509 
510     __ms_va_start( valist, lpFmt );
511     res = wvnsprintfA( lpOut, cchLimitIn, lpFmt, valist );
512     __ms_va_end( valist );
513     return res;
514 }
515 
516 
517 /*************************************************************************
518  *           wnsprintfW   (SHLWAPI.@)
519  *
520  * See wnsprintfA.
521  */
522 int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt, ...)
523 {
524     __ms_va_list valist;
525     INT res;
526 
527     __ms_va_start( valist, lpFmt );
528     res = wvnsprintfW( lpOut, cchLimitIn, lpFmt, valist );
529     __ms_va_end( valist );
530     return res;
531 }
532 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.