Ask for the keysize when generating a new card key.
[gnupg.git] / jnlib / stringhelp.c
blob3ff743a08f321a741f5649222649657929ada913
1 /* stringhelp.c - standard string helper functions
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005,
3 * 2006, 2007, 2008 Free Software Foundation, Inc.
5 * This file is part of JNLIB.
7 * JNLIB is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 3 of
10 * the License, or (at your option) any later version.
12 * JNLIB is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <ctype.h>
26 #ifdef HAVE_W32_SYSTEM
27 #include <windows.h>
28 #endif
30 #include "libjnlib-config.h"
31 #include "utf8conv.h"
32 #include "stringhelp.h"
35 #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
37 /* Sometimes we want to avoid mixing slashes and backslashes on W32
38 and prefer backslashes. There is usual no problem with mixing
39 them, however a very few W32 API calls can't grok plain slashes.
40 Printing filenames with mixed slashes also looks a bit strange.
41 This function has no effext on POSIX. */
42 static inline char *
43 change_slashes (char *name)
45 #ifdef HAVE_DRIVE_LETTERS
46 char *p;
48 if (strchr (name, '\\'))
50 for (p=name; *p; p++)
51 if (*p == '/')
52 *p = '\\';
54 #endif /*HAVE_DRIVE_LETTERS*/
55 return name;
60 * Look for the substring SUB in buffer and return a pointer to that
61 * substring in BUFFER or NULL if not found.
62 * Comparison is case-insensitive.
64 const char *
65 memistr (const void *buffer, size_t buflen, const char *sub)
67 const unsigned char *buf = buffer;
68 const unsigned char *t = (const unsigned char *)buffer;
69 const unsigned char *s = (const unsigned char *)sub;
70 size_t n = buflen;
72 for ( ; n ; t++, n-- )
74 if ( toupper (*t) == toupper (*s) )
76 for ( buf=t++, buflen = n--, s++;
77 n && toupper (*t) == toupper (*s); t++, s++, n-- )
79 if (!*s)
80 return (const char*)buf;
81 t = buf;
82 s = (const unsigned char *)sub ;
83 n = buflen;
86 return NULL;
89 const char *
90 ascii_memistr ( const void *buffer, size_t buflen, const char *sub )
92 const unsigned char *buf = buffer;
93 const unsigned char *t = (const unsigned char *)buf;
94 const unsigned char *s = (const unsigned char *)sub;
95 size_t n = buflen;
97 for ( ; n ; t++, n-- )
99 if (ascii_toupper (*t) == ascii_toupper (*s) )
101 for ( buf=t++, buflen = n--, s++;
102 n && ascii_toupper (*t) == ascii_toupper (*s); t++, s++, n-- )
104 if (!*s)
105 return (const char*)buf;
106 t = (const unsigned char *)buf;
107 s = (const unsigned char *)sub ;
108 n = buflen;
111 return NULL;
114 /* This function is similar to strncpy(). However it won't copy more
115 than N - 1 characters and makes sure that a '\0' is appended. With
116 N given as 0, nothing will happen. With DEST given as NULL, memory
117 will be allocated using jnlib_xmalloc (i.e. if it runs out of core
118 the function terminates). Returns DES or a pointer to the
119 allocated memory.
121 char *
122 mem2str( char *dest , const void *src , size_t n )
124 char *d;
125 const char *s;
127 if( n ) {
128 if( !dest )
129 dest = jnlib_xmalloc( n ) ;
130 d = dest;
131 s = src ;
132 for(n--; n && *s; n-- )
133 *d++ = *s++;
134 *d = '\0' ;
137 return dest ;
141 /****************
142 * remove leading and trailing white spaces
144 char *
145 trim_spaces( char *str )
147 char *string, *p, *mark;
149 string = str;
150 /* find first non space character */
151 for( p=string; *p && isspace( *(byte*)p ) ; p++ )
153 /* move characters */
154 for( (mark = NULL); (*string = *p); string++, p++ )
155 if( isspace( *(byte*)p ) ) {
156 if( !mark )
157 mark = string ;
159 else
160 mark = NULL ;
161 if( mark )
162 *mark = '\0' ; /* remove trailing spaces */
164 return str ;
167 /****************
168 * remove trailing white spaces
170 char *
171 trim_trailing_spaces( char *string )
173 char *p, *mark;
175 for( mark = NULL, p = string; *p; p++ ) {
176 if( isspace( *(byte*)p ) ) {
177 if( !mark )
178 mark = p;
180 else
181 mark = NULL;
183 if( mark )
184 *mark = '\0' ;
186 return string ;
190 unsigned
191 trim_trailing_chars( byte *line, unsigned len, const char *trimchars )
193 byte *p, *mark;
194 unsigned n;
196 for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
197 if( strchr(trimchars, *p ) ) {
198 if( !mark )
199 mark = p;
201 else
202 mark = NULL;
205 if( mark ) {
206 *mark = 0;
207 return mark - line;
209 return len;
212 /****************
213 * remove trailing white spaces and return the length of the buffer
215 unsigned
216 trim_trailing_ws( byte *line, unsigned len )
218 return trim_trailing_chars( line, len, " \t\r\n" );
221 size_t
222 length_sans_trailing_chars (const unsigned char *line, size_t len,
223 const char *trimchars )
225 const unsigned char *p, *mark;
226 size_t n;
228 for( mark=NULL, p=line, n=0; n < len; n++, p++ )
230 if (strchr (trimchars, *p ))
232 if( !mark )
233 mark = p;
235 else
236 mark = NULL;
239 if (mark)
240 return mark - line;
241 return len;
245 * Return the length of line ignoring trailing white-space.
247 size_t
248 length_sans_trailing_ws (const unsigned char *line, size_t len)
250 return length_sans_trailing_chars (line, len, " \t\r\n");
256 * Extract from a given path the filename component. This function
257 * terminates the process on memory shortage.
259 char *
260 make_basename(const char *filepath, const char *inputpath)
262 #ifdef __riscos__
263 return riscos_make_basename(filepath, inputpath);
264 #else
265 char *p;
267 (void)inputpath; /* Only required for riscos. */
269 if ( !(p=strrchr(filepath, '/')) )
270 #ifdef HAVE_DRIVE_LETTERS
271 if ( !(p=strrchr(filepath, '\\')) )
272 if ( !(p=strrchr(filepath, ':')) )
273 #endif
275 return jnlib_xstrdup(filepath);
278 return jnlib_xstrdup(p+1);
279 #endif
285 * Extract from a given filename the path prepended to it. If there
286 * isn't a path prepended to the filename, a dot is returned ('.').
287 * This function terminates the process on memory shortage.
289 char *
290 make_dirname(const char *filepath)
292 char *dirname;
293 int dirname_length;
294 char *p;
296 if ( !(p=strrchr(filepath, '/')) )
297 #ifdef HAVE_DRIVE_LETTERS
298 if ( !(p=strrchr(filepath, '\\')) )
299 if ( !(p=strrchr(filepath, ':')) )
300 #endif
302 return jnlib_xstrdup(".");
305 dirname_length = p-filepath;
306 dirname = jnlib_xmalloc(dirname_length+1);
307 strncpy(dirname, filepath, dirname_length);
308 dirname[dirname_length] = 0;
310 return dirname;
315 /* Implementation of make_filename and make_filename_try. We need to
316 use macros here to avoid the use of the sometimes problematic
317 va_copy function which is not available on all systems. */
318 #define MAKE_FILENAME_PART1 \
319 va_list arg_ptr; \
320 size_t n; \
321 const char *s; \
322 char *name, *home, *p; \
324 va_start (arg_ptr, first_part); \
325 n = strlen (first_part) + 1; \
326 while ( (s = va_arg (arg_ptr, const char *)) ) \
327 n += strlen(s) + 1; \
328 va_end(arg_ptr); \
330 home = NULL; \
331 if ( *first_part == '~' && first_part[1] == '/' \
332 && (home = getenv("HOME")) && *home ) \
333 n += strlen (home);
335 #define MAKE_FILENAME_PART2 \
336 p = (home \
337 ? stpcpy (stpcpy (name,home), first_part + 1)\
338 : stpcpy(name, first_part)); \
340 va_start (arg_ptr, first_part); \
341 while ( (s = va_arg(arg_ptr, const char *)) ) \
342 p = stpcpy (stpcpy (p,"/"), s); \
343 va_end(arg_ptr); \
344 return change_slashes (name);
347 /* Construct a filename from the NULL terminated list of parts. Tilde
348 expansion is done here. This function terminates the process on
349 memory shortage. */
350 char *
351 make_filename (const char *first_part, ... )
353 MAKE_FILENAME_PART1
354 name = jnlib_xmalloc (n);
355 MAKE_FILENAME_PART2
358 /* Construct a filename from the NULL terminated list of parts. Tilde
359 expansion is done here. This function may return NULL on error. */
360 char *
361 make_filename_try (const char *first_part, ... )
363 MAKE_FILENAME_PART1
364 name = jnlib_malloc (n);
365 if (!name)
366 return NULL;
367 MAKE_FILENAME_PART2
369 #undef MAKE_FILENAME_PART1
370 #undef MAKE_FILENAME_PART2
374 /* Compare whether the filenames are identical. This is a
375 special version of strcmp() taking the semantics of filenames in
376 account. Note that this function works only on the supplied names
377 without considereing any context like the current directory. See
378 also same_file_p(). */
380 compare_filenames (const char *a, const char *b)
382 #ifdef HAVE_DRIVE_LETTERS
383 for ( ; *a && *b; a++, b++ )
385 if (*a != *b
386 && (toupper (*(const unsigned char*)a)
387 != toupper (*(const unsigned char*)b) )
388 && !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
389 break;
391 if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
392 return 0;
393 else
394 return (toupper (*(const unsigned char*)a)
395 - toupper (*(const unsigned char*)b));
396 #else
397 return strcmp(a,b);
398 #endif
402 /* Convert 2 hex characters at S to a byte value. Return this value
403 or -1 if there is an error. */
405 hextobyte (const char *s)
407 int c;
409 if ( *s >= '0' && *s <= '9' )
410 c = 16 * (*s - '0');
411 else if ( *s >= 'A' && *s <= 'F' )
412 c = 16 * (10 + *s - 'A');
413 else if ( *s >= 'a' && *s <= 'f' )
414 c = 16 * (10 + *s - 'a');
415 else
416 return -1;
417 s++;
418 if ( *s >= '0' && *s <= '9' )
419 c += *s - '0';
420 else if ( *s >= 'A' && *s <= 'F' )
421 c += 10 + *s - 'A';
422 else if ( *s >= 'a' && *s <= 'f' )
423 c += 10 + *s - 'a';
424 else
425 return -1;
426 return c;
430 /* Print a BUFFER to stream FP while replacing all control characters
431 and the characters DELIM and DELIM2 with standard C escape
432 sequences. Returns the number of characters printed. */
433 size_t
434 print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
435 int delim, int delim2)
437 const unsigned char *p = buffer;
438 size_t count = 0;
440 for (; length; length--, p++, count++)
442 if (*p < 0x20
443 || *p == 0x7f
444 || *p == delim
445 || *p == delim2
446 || ((delim || delim2) && *p=='\\'))
448 putc ('\\', fp);
449 count++;
450 if (*p == '\n')
452 putc ('n', fp);
453 count++;
455 else if (*p == '\r')
457 putc ('r', fp);
458 count++;
460 else if (*p == '\f')
462 putc ('f', fp);
463 count++;
465 else if (*p == '\v')
467 putc ('v', fp);
468 count++;
470 else if (*p == '\b')
472 putc ('b', fp);
473 count++;
475 else if (!*p)
477 putc('0', fp);
478 count++;
480 else
482 fprintf (fp, "x%02x", *p);
483 count += 3;
486 else
488 putc (*p, fp);
489 count++;
493 return count;
496 /* Same as print_sanitized_buffer2 but with just one delimiter. */
497 size_t
498 print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
499 int delim)
501 return print_sanitized_buffer2 (fp, buffer, length, delim, 0);
505 size_t
506 print_sanitized_utf8_buffer (FILE *fp, const void *buffer,
507 size_t length, int delim)
509 const char *p = buffer;
510 size_t i;
512 /* We can handle plain ascii simpler, so check for it first. */
513 for (i=0; i < length; i++ )
515 if ( (p[i] & 0x80) )
516 break;
518 if (i < length)
520 char *buf = utf8_to_native (p, length, delim);
521 /*(utf8 conversion already does the control character quoting)*/
522 i = strlen (buf);
523 fputs (buf, fp);
524 jnlib_free (buf);
525 return i;
527 else
528 return print_sanitized_buffer (fp, p, length, delim);
532 size_t
533 print_sanitized_string2 (FILE *fp, const char *string, int delim, int delim2)
535 return string? print_sanitized_buffer2 (fp, string, strlen (string),
536 delim, delim2):0;
539 size_t
540 print_sanitized_string (FILE *fp, const char *string, int delim)
542 return string? print_sanitized_buffer (fp, string, strlen (string), delim):0;
545 size_t
546 print_sanitized_utf8_string (FILE *fp, const char *string, int delim)
548 return string? print_sanitized_utf8_buffer (fp,
549 string, strlen (string),
550 delim) : 0;
553 /* Create a string from the buffer P_ARG of length N which is suitable
554 for printing. Caller must release the created string using xfree.
555 This function terminates the process on memory shortage. */
556 char *
557 sanitize_buffer (const void *p_arg, size_t n, int delim)
559 const unsigned char *p = p_arg;
560 size_t save_n, buflen;
561 const unsigned char *save_p;
562 char *buffer, *d;
564 /* First count length. */
565 for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ )
567 if ( *p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\'))
569 if ( *p=='\n' || *p=='\r' || *p=='\f'
570 || *p=='\v' || *p=='\b' || !*p )
571 buflen += 2;
572 else
573 buflen += 5;
575 else
576 buflen++;
578 p = save_p;
579 n = save_n;
580 /* And now make the string */
581 d = buffer = jnlib_xmalloc( buflen );
582 for ( ; n; n--, p++ )
584 if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) {
585 *d++ = '\\';
586 if( *p == '\n' )
587 *d++ = 'n';
588 else if( *p == '\r' )
589 *d++ = 'r';
590 else if( *p == '\f' )
591 *d++ = 'f';
592 else if( *p == '\v' )
593 *d++ = 'v';
594 else if( *p == '\b' )
595 *d++ = 'b';
596 else if( !*p )
597 *d++ = '0';
598 else {
599 sprintf(d, "x%02x", *p );
600 d += 3;
603 else
604 *d++ = *p;
606 *d = 0;
607 return buffer;
611 /* Given a string containing an UTF-8 encoded text, return the number
612 of characters in this string. It differs from strlen in that it
613 only counts complete UTF-8 characters. Note, that this function
614 does not take combined characters into account. */
615 size_t
616 utf8_charcount (const char *s)
618 size_t n;
620 for (n=0; *s; s++)
621 if ( (*s&0xc0) != 0x80 ) /* Exclude continuation bytes: 10xxxxxx */
622 n++;
624 return n;
628 /****************************************************
629 ********** W32 specific functions ****************
630 ****************************************************/
632 #ifdef HAVE_W32_SYSTEM
633 const char *
634 w32_strerror (int ec)
636 static char strerr[256];
638 if (ec == -1)
639 ec = (int)GetLastError ();
640 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
641 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
642 strerr, DIM (strerr)-1, NULL);
643 return strerr;
645 #endif /*HAVE_W32_SYSTEM*/
648 /****************************************************
649 ******** Locale insensitive ctype functions ********
650 ****************************************************/
651 /* FIXME: replace them by a table lookup and macros */
653 ascii_isupper (int c)
655 return c >= 'A' && c <= 'Z';
659 ascii_islower (int c)
661 return c >= 'a' && c <= 'z';
664 int
665 ascii_toupper (int c)
667 if (c >= 'a' && c <= 'z')
668 c &= ~0x20;
669 return c;
672 int
673 ascii_tolower (int c)
675 if (c >= 'A' && c <= 'Z')
676 c |= 0x20;
677 return c;
682 ascii_strcasecmp( const char *a, const char *b )
684 if (a == b)
685 return 0;
687 for (; *a && *b; a++, b++) {
688 if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b))
689 break;
691 return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
694 int
695 ascii_strncasecmp (const char *a, const char *b, size_t n)
697 const unsigned char *p1 = (const unsigned char *)a;
698 const unsigned char *p2 = (const unsigned char *)b;
699 unsigned char c1, c2;
701 if (p1 == p2 || !n )
702 return 0;
706 c1 = ascii_tolower (*p1);
707 c2 = ascii_tolower (*p2);
709 if ( !--n || c1 == '\0')
710 break;
712 ++p1;
713 ++p2;
715 while (c1 == c2);
717 return c1 - c2;
722 ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n )
724 const char *a = a_arg;
725 const char *b = b_arg;
727 if (a == b)
728 return 0;
729 for ( ; n; n--, a++, b++ )
731 if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) )
732 return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
734 return 0;
738 ascii_strcmp( const char *a, const char *b )
740 if (a == b)
741 return 0;
743 for (; *a && *b; a++, b++) {
744 if (*a != *b )
745 break;
747 return *a == *b? 0 : (*(signed char *)a - *(signed char *)b);
751 void *
752 ascii_memcasemem (const void *haystack, size_t nhaystack,
753 const void *needle, size_t nneedle)
756 if (!nneedle)
757 return (void*)haystack; /* finding an empty needle is really easy */
758 if (nneedle <= nhaystack)
760 const char *a = haystack;
761 const char *b = a + nhaystack - nneedle;
763 for (; a <= b; a++)
765 if ( !ascii_memcasecmp (a, needle, nneedle) )
766 return (void *)a;
769 return NULL;
772 /*********************************************
773 ********** missing string functions *********
774 *********************************************/
776 #ifndef HAVE_STPCPY
777 char *
778 stpcpy(char *a,const char *b)
780 while( *b )
781 *a++ = *b++;
782 *a = 0;
784 return (char*)a;
786 #endif
788 #ifndef HAVE_STRSEP
789 /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
790 char *
791 strsep (char **stringp, const char *delim)
793 char *begin, *end;
795 begin = *stringp;
796 if (begin == NULL)
797 return NULL;
799 /* A frequent case is when the delimiter string contains only one
800 character. Here we don't need to call the expensive `strpbrk'
801 function and instead work using `strchr'. */
802 if (delim[0] == '\0' || delim[1] == '\0')
804 char ch = delim[0];
806 if (ch == '\0')
807 end = NULL;
808 else
810 if (*begin == ch)
811 end = begin;
812 else if (*begin == '\0')
813 end = NULL;
814 else
815 end = strchr (begin + 1, ch);
818 else
819 /* Find the end of the token. */
820 end = strpbrk (begin, delim);
822 if (end)
824 /* Terminate the token and set *STRINGP past NUL character. */
825 *end++ = '\0';
826 *stringp = end;
828 else
829 /* No more delimiters; this is the last token. */
830 *stringp = NULL;
832 return begin;
834 #endif /*HAVE_STRSEP*/
837 #ifndef HAVE_STRLWR
838 char *
839 strlwr(char *s)
841 char *p;
842 for(p=s; *p; p++ )
843 *p = tolower(*p);
844 return s;
846 #endif
849 #ifndef HAVE_STRCASECMP
851 strcasecmp( const char *a, const char *b )
853 for( ; *a && *b; a++, b++ ) {
854 if( *a != *b && toupper(*a) != toupper(*b) )
855 break;
857 return *(const byte*)a - *(const byte*)b;
859 #endif
862 /****************
863 * mingw32/cpd has a memicmp()
865 #ifndef HAVE_MEMICMP
867 memicmp( const char *a, const char *b, size_t n )
869 for( ; n; n--, a++, b++ )
870 if( *a != *b && toupper(*(const byte*)a) != toupper(*(const byte*)b) )
871 return *(const byte *)a - *(const byte*)b;
872 return 0;
874 #endif
877 #ifndef HAVE_MEMRCHR
878 void *
879 memrchr (const void *buffer, int c, size_t n)
881 const unsigned char *p = buffer;
883 for (p += n; n ; n--)
884 if (*--p == c)
885 return (void *)p;
886 return NULL;
888 #endif /*HAVE_MEMRCHR*/
891 /* Percent-escape the string STR by replacing colons with '%3a'. If
892 EXTRA is not NULL all characters in EXTRA are also escaped. */
893 static char *
894 do_percent_escape (const char *str, const char *extra, int die)
896 int i, j;
897 char *ptr;
899 if (!str)
900 return NULL;
902 for (i=j=0; str[i]; i++)
903 if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
904 j++;
905 if (die)
906 ptr = jnlib_xmalloc (i + 2 * j + 1);
907 else
909 ptr = jnlib_malloc (i + 2 * j + 1);
910 if (!ptr)
911 return NULL;
913 i = 0;
914 while (*str)
916 if (*str == ':')
918 ptr[i++] = '%';
919 ptr[i++] = '3';
920 ptr[i++] = 'a';
922 else if (*str == '%')
924 ptr[i++] = '%';
925 ptr[i++] = '2';
926 ptr[i++] = '5';
928 else if (extra && strchr (extra, *str))
930 ptr[i++] = '%';
931 ptr[i++] = tohex_lower ((*str>>4)&15);
932 ptr[i++] = tohex_lower (*str&15);
934 else
935 ptr[i++] = *str;
936 str++;
938 ptr[i] = '\0';
940 return ptr;
943 /* Percent-escape the string STR by replacing colons with '%3a'. If
944 EXTRA is not NULL all characters in EXTRA are also escaped. This
945 function terminates the process on memory shortage. */
946 char *
947 percent_escape (const char *str, const char *extra)
949 return do_percent_escape (str, extra, 1);
952 /* Same as percent_escape but return NULL instead of exiting on memory
953 error. */
954 char *
955 try_percent_escape (const char *str, const char *extra)
957 return do_percent_escape (str, extra, 0);