libutf

UTF-8 library
git clone git://git.suckless.org/libutf
Log | Files | Refs | README | LICENSE

utftest.c (2549B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <stdarg.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #include "utf.h"
      7 
      8 #define ARGBEGIN \
      9 	{ \
     10 		Rune _argr; \
     11 		\
     12 		if(!argv0) \
     13 			argv0 = argv[0]; \
     14 		for(argc--, argv++; *argv && (*argv)[0] == '-' && (*argv)[1] != '\0'; argc--, argv++) { \
     15 			if((*argv)[1] == '-' && (*argv)[2] == '\0') { /* -- signifies end of flags */ \
     16 				argc--; argv++; \
     17 				break; \
     18 			} \
     19 			(*argv)++; \
     20 			while(**argv != '\0' && (*argv += chartorune(&_argr, *argv))) \
     21 				switch(_argr)
     22 
     23 #define ARGEND \
     24 		} \
     25 	}
     26 
     27 #define ARGC()  _argr
     28 
     29 static void eprintf(const char *, ...);
     30 static void usage(void);
     31 
     32 static const char *argv0;
     33 
     34 int
     35 main(int argc, char *argv[])
     36 {
     37 	int aflag = 0, dflag = 0, lflag = 0, sflag = 0, tflag = 0, uflag = 0, vflag = 0;
     38 	char buf[BUFSIZ], rbuf[UTFmax];
     39 	int len, len2;
     40 	size_t i, j, n;
     41 	Rune r;
     42 
     43 	ARGBEGIN {
     44 	case 'a': aflag = 1; break;
     45 	case 'd': dflag = 1; break;
     46 	case 'l': lflag = 1; break;
     47 	case 's': sflag = 1; break;
     48 	case 't': tflag = 1; break;
     49 	case 'u': uflag = 1; break;
     50 	case 'v': vflag = 1; break;
     51 	default:
     52 		r = ARGC();
     53 		rbuf[runetochar(rbuf, &r)] = '\0';
     54 		eprintf("unknown flag -%s\n", rbuf);
     55 		usage();
     56 	} ARGEND;
     57 
     58 	if(argc != 0)
     59 		usage();
     60 
     61 	for(i = 0; (n = fread(&buf[i], 1, sizeof buf - i, stdin)); i = n-i) {
     62 		for(n += i, i = 0; (len = charntorune(&r, &buf[i], n-i)); i += len) {
     63 			if(r == Runeerror) {
     64 				fprintf(stderr, "%s: error converting char to rune:", argv0);
     65 				for(j = i; j < i+len; j++)
     66 					fprintf(stderr, " %02X", (unsigned char)buf[j]);
     67 				fputc('\n', stderr);
     68 			}
     69 			if(((aflag && isalpharune(r)) || (dflag && isdigitrune(r))
     70 			 || (lflag && islowerrune(r)) || (sflag && isspacerune(r))
     71 			 || (tflag && istitlerune(r)) || (uflag && isupperrune(r))
     72 			 || (!aflag && !dflag && !lflag && !sflag && !tflag && !uflag)) == vflag)
     73 				continue;
     74 
     75 			if((len2 = runetochar(rbuf, &r))) {
     76 				if(!fwrite(rbuf, len2, 1, stdout))
     77 					eprintf("write error:");
     78 			}
     79 			else
     80 				fprintf(stderr, "%s: error converting rune to char: U+%02X\n", argv0, r);
     81 		}
     82 		if(i < n)
     83 			memcpy(buf, &buf[i], n-i);
     84 	}
     85 	if(ferror(stdin))
     86 		eprintf("read error:");
     87 
     88 	return EXIT_SUCCESS;
     89 }
     90 
     91 void
     92 eprintf(const char *fmt, ...)
     93 {
     94 	va_list ap;
     95 
     96 	fprintf(stderr, "%s: ", argv0);
     97 
     98 	va_start(ap, fmt);
     99 	vfprintf(stderr, fmt, ap);
    100 	va_end(ap);
    101 
    102 	if(fmt[0] && fmt[strlen(fmt)-1] == ':') {
    103 		fputc(' ', stderr);
    104 		perror(NULL);
    105 	}
    106 	exit(EXIT_FAILURE);
    107 }
    108 
    109 void
    110 usage(void)
    111 {
    112 	fprintf(stderr, "usage: %s [-adlstuv]\n", argv0);
    113 	exit(EXIT_FAILURE);
    114 }