source: trunk/minix/commands/simple/tr.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.6 KB
Line 
1/* tr - translate characters Author: Michiel Huisjes */
2/* Usage: tr [-cds] [string1 [string2]]
3 * c: take complement of string1
4 * d: delete input characters coded string1
5 * s: squeeze multiple output characters of string2 into one character
6 */
7
8#define BUFFER_SIZE 1024
9#define ASCII 0377
10
11typedef char BOOL;
12#define TRUE 1
13#define FALSE 0
14
15#define NIL_PTR ((char *) 0)
16
17BOOL com_fl, del_fl, sq_fl;
18
19unsigned char output[BUFFER_SIZE], input[BUFFER_SIZE];
20unsigned char vector[ASCII + 1];
21BOOL invec[ASCII + 1], outvec[ASCII + 1];
22
23short in_index, out_index;
24
25#include <sys/types.h>
26#include <string.h>
27#include <stdlib.h>
28#include <unistd.h>
29
30_PROTOTYPE(int main, (int argc, char **argv));
31_PROTOTYPE(void convert, (void));
32_PROTOTYPE(void map, (unsigned char *string1, unsigned char *string2));
33_PROTOTYPE(void expand, (char *arg, unsigned char *buffer));
34_PROTOTYPE(void complement, (unsigned char *buffer));
35
36int main(argc, argv)
37int argc;
38char *argv[];
39{
40 register unsigned char *ptr;
41 int index = 1;
42 short i;
43
44 if (argc > 1 && argv[index][0] == '-') {
45 for (ptr = (unsigned char *) &argv[index][1]; *ptr; ptr++) {
46 switch (*ptr) {
47 case 'c': com_fl = TRUE; break;
48 case 'd': del_fl = TRUE; break;
49 case 's': sq_fl = TRUE; break;
50 default:
51 write(2,"Usage: tr [-cds] [string1 [string2]].\n", 38);
52 exit(1);
53 }
54 }
55 index++;
56 }
57 for (i = 0; i <= ASCII; i++) {
58 vector[i] = i;
59 invec[i] = outvec[i] = FALSE;
60 }
61
62 if (argv[index] != NIL_PTR) {
63 expand(argv[index++], input);
64 if (com_fl) complement(input);
65 if (argv[index] != NIL_PTR) expand(argv[index], output);
66 if (argv[index] != NIL_PTR) map(input, output);
67 for (ptr = input; *ptr; ptr++) invec[*ptr] = TRUE;
68 for (ptr = output; *ptr; ptr++) outvec[*ptr] = TRUE;
69 }
70 convert();
71 return(0);
72}
73
74void convert()
75{
76 short read_chars = 0;
77 short c, coded;
78 short last = -1;
79
80 for (;;) {
81 if (in_index == read_chars) {
82 if ((read_chars = read(0, (char *)input, BUFFER_SIZE)) <= 0) {
83 if (write(1, (char *)output, out_index) != out_index)
84 write(2, "Bad write\n", 10);
85 exit(0);
86 }
87 in_index = 0;
88 }
89 c = input[in_index++];
90 coded = vector[c];
91 if (del_fl && invec[c]) continue;
92 if (sq_fl && last == coded && outvec[coded]) continue;
93 output[out_index++] = last = coded;
94 if (out_index == BUFFER_SIZE) {
95 if (write(1, (char *)output, out_index) != out_index) {
96 write(2, "Bad write\n", 10);
97 exit(1);
98 }
99 out_index = 0;
100 }
101 }
102
103 /* NOTREACHED */
104}
105
106void map(string1, string2)
107register unsigned char *string1, *string2;
108{
109 unsigned char last;
110
111 while (*string1) {
112 if (*string2 == '\0')
113 vector[*string1] = last;
114 else
115 vector[*string1] = last = *string2++;
116 string1++;
117 }
118}
119
120void expand(arg, buffer)
121register char *arg;
122register unsigned char *buffer;
123{
124 int i, ac;
125
126 while (*arg) {
127 if (*arg == '\\') {
128 arg++;
129 i = ac = 0;
130 if (*arg >= '0' && *arg <= '7') {
131 do {
132 ac = (ac << 3) + *arg++ - '0';
133 i++;
134 } while (i < 4 && *arg >= '0' && *arg <= '7');
135 *buffer++ = ac;
136 } else if (*arg != '\0')
137 *buffer++ = *arg++;
138 } else if (*arg == '[') {
139 arg++;
140 i = *arg++;
141 if (*arg++ != '-') {
142 *buffer++ = '[';
143 arg -= 2;
144 continue;
145 }
146 ac = *arg++;
147 while (i <= ac) *buffer++ = i++;
148 arg++; /* Skip ']' */
149 } else
150 *buffer++ = *arg++;
151 }
152}
153
154void complement(buffer)
155unsigned char *buffer;
156{
157 register unsigned char *ptr;
158 register short i, index;
159 unsigned char conv[ASCII + 2];
160
161 index = 0;
162 for (i = 1; i <= ASCII; i++) {
163 for (ptr = buffer; *ptr; ptr++)
164 if (*ptr == i) break;
165 if (*ptr == '\0') conv[index++] = i & ASCII;
166 }
167 conv[index] = '\0';
168 strcpy((char *)buffer, (char *)conv);
169}
Note: See TracBrowser for help on using the repository browser.