]> git.gir.st - base65536.git/blob - main.c
fix -Werror=misleading-indentation
[base65536.git] / main.c
1 /* base65536 en- and decoder with usage similar to GNU's base64.
2 (C) 2016 Tobias Girstmair, http://isticktoit.net/
3 Released under the GNU GPL v3. See LICENSE for details. */
4
5 #define _XOPEN_SOURCE
6 #include <errno.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include "base65536.h"
12
13 #define VERSION "0.2"
14
15 #define DEFAULT_WRAP 72
16
17 #define COPYRIGHT "(C) 2016 Tobias Girstmair, GPLv3"
18 #define HELP_TEXT \
19 "Usage: %s [OPTION]... [FILE]\n"\
20 "Options: -d (decode), -i (ignore-garbage), -w COLS (wrap, default %d) "\
21 "-v (version) -h (help)\n"
22
23 struct ops {
24 FILE* f;
25 int d; /*decode*/
26 int i; /*ignore-garbage*/
27 int w; /*wrap*/
28 };
29
30 void do_encode (FILE* in, FILE* out, int wrap_column);
31 void do_decode (FILE* in, FILE* out, int ignore_garbage);
32
33 int main (int argc, char** argv) {
34 struct ops op = {stdin, 0, 0, DEFAULT_WRAP};
35 int opt;
36
37 opterr=0; /* suppress default error messages */
38 while ( (opt = getopt(argc, argv, "diw:vh")) != -1) {
39 switch (opt) {
40 case 'd': op.d = 1; break;
41 case 'i': op.i = 1; break;
42 case 'w': op.w = atoi (optarg); break;
43 case 'v':
44 fprintf (stderr, "base65536 %s\n%s\n", VERSION, COPYRIGHT);
45 return 0;
46 case 'h':
47 fprintf (stderr, HELP_TEXT, argv[0], DEFAULT_WRAP);
48 return 0;
49 default:
50 fprintf (stderr, "unknown option '-%c'.\n", optopt);
51 return 1;
52 }
53 }
54 if (argc-optind > 1) {
55 fprintf (stderr, "%s: extra operand '%s'. \n", argv[0], argv[argc-1]);
56 return 1;
57 } else if (optind < argc) {
58 if (strcmp (argv [optind], "-") != 0) {
59 op.f = fopen (argv[optind], "rb");
60 if (op.f == NULL) {
61 fprintf (stderr, "%s: %s: %s\n", argv[0], argv[optind], strerror(errno));
62 return 1;
63 }
64 }
65 }
66
67 if (op.d) {
68 do_decode (op.f, stdout, op.i);
69 } else {
70 do_encode (op.f, stdout, op.w);
71 }
72
73 if (op.f != stdin) fclose (op.f);
74
75 return 0;
76 }
77
78
79 void do_encode (FILE* in, FILE* out, int wrap_column) {
80 int in_char[2];
81 char out_utf8[5];
82 int unicode_cp;
83 long cnt = 0;
84
85 while (1) {
86 if ((in_char[0] = getc(in)) == EOF) break;
87 in_char[1] = getc(in);
88
89 unicode_cp = base65536_encode_char (in_char);
90 codepoint_to_utf8 (unicode_cp, out_utf8);
91 fprintf (out, "%s%s", wrap_column&&!(cnt%wrap_column)&&cnt?"\n":"", out_utf8);
92 cnt++;
93 if (in_char[1] == EOF) break;
94 }
95 printf ("\n");
96 }
97
98 void do_decode (FILE* in, FILE* out, int ignore_garbage) {
99 int out_char[2];
100 char in_utf8[5];
101 int unicode_cp;
102 int chars_written;
103
104 while (1) {
105 for (int i = 0; i < 5; i++) {
106 int c = getc (in);
107 if (c == EOF) {
108 return;
109 } else if (i != 0 && c < 0x80) { /* start of new asciichar */
110 ungetc (c, in);
111 in_utf8[i] = '\0';
112 break;
113 } else if (i != 0 && c >= 0xc0) { /* start of new utf8char */
114 ungetc (c, in);
115 in_utf8[i] = '\0';
116 break;
117 }
118 in_utf8[i] = c;
119 }
120 unicode_cp = utf8_to_codepoint (in_utf8);
121 /* ignore ascii-chars, because base65k won't map to those (but
122 whitespace may be added by the encoder / medium) */
123 if (unicode_cp < 0x80) continue;
124
125 chars_written = base65536_decode_char (unicode_cp, out_char);
126 if (chars_written > 0) {
127 fputc (out_char[0], out);
128 if (chars_written ==2) fputc (out_char[1], out);
129 } else {
130 if (!ignore_garbage) {
131 fprintf (stderr, "Unrecognized glyph %s\n", in_utf8);
132 return;
133 }
134 }
135 }
136 }
Imprint / Impressum