BSD 3 development
[unix-history] / usr / src / cmd / compact / uncompact.c
CommitLineData
b60e6348
CMM
1/*
2 * Uncompact adaptive Huffman code input to output
3 *
4 * On - line algorithm
5 *
6 * Input file does not contain decoding tree
7 *
8 * Written by Colin L. Mc Master (UCB) February 14, 1979
9 */
10
11#include "compact.h"
12
13
14main (argc, argv)
15short argc;
16char *argv [ ];
17{
18 register short i;
19 register struct node *p;
20 register short j;
21 register int m;
22 union cio c, d;
23 char b;
24 longint ic, n;
25 char fname [LNAME], *cp;
26
27 dir [513] . next = NULL;
28 for (head = dir + (j = 513); j--; ) {
29 dirp = head--;
30 head -> next = dirp;
31 }
32 bottom = dirp -> pt = dict;
33 dict [0] . top [0] = dict [0] . top [1] = dirp;
34 dirq = dirp -> next;
35 in [EF] . flags = FBIT | SEEN;
36
37 for (i = 1; ; i++) {
38 ic = oc = 0;
39 (bottom -> top [1]) -> next = flist;
40 bottom -> top [1] = dirp;
41 flist = dirq;
42 if (i >= argc) {
43 uncfp = stdout;
44 cfp = stdin;
45 }
46 else {
47 m = -1;
48 cp = fname;
49 for (j = 0; j < (LNAME - 3) && (*cp = argv [i][j]); j++)
50 if (*cp++ == '/') m = j;
51 if (cp [-1] == 'C' && cp [-2] == '.') cp [-2] = 0;
52 else {
53 fprintf (stderr, "%s: File name must end with \".C\"\n", argv [i]);
54 if (i == argc - 1) break;
55 continue;
56 }
57 if (j >= (LNAME - 3) || (j - m) > 15) {
58 fprintf (stderr, "File name too long -- %s\n", argv [i]);
59 if (i == argc - 1) break;
60 continue;
61 }
62 if ((cfp = fopen (argv [i], "r")) == NULL) {
63 perror (argv [i]);
64 if (i == argc - 1) break;
65 continue;
66 }
67 if ((uncfp = fopen (fname, "w")) == NULL) {
68 perror (fname);
69 fclose (cfp);
70 if (i == argc - 1) break;
71 continue;
72 }
73 fstat (fileno (cfp), &status);
74 chmod (fname, status.st_mode & 07777);
75 }
76
77 if ((c . integ = getc (cfp)) != EOF) {
78 if ((d . integ = getc (cfp)) != EOF) {
79 c . chars . hib = d . integ & 0377;
80 c . integ &= 0177777;
81 if (c . integ != COMPACTED) goto notcompact;
82 if ((c . integ = getc (cfp)) != EOF) {
83 putc (c . chars . lob, uncfp);
84 ic = 3;
85
86 in [NC] . fp = in [EF] . fp = dict [0] . sp [0] . p = bottom = dict + 1;
87 bottom -> count [0] = bottom -> count [1] = dict [0] . count [1] = 1;
88 dirp -> next = dict [0] . top [1] = bottom -> top [0] = bottom -> top [1] = dirq = NEW;
89 dirq -> next = NULL;
90 dict [0] . fath . fp = NULL;
91 dirq -> pt = bottom -> fath . fp = in [c . integ] . fp = dict;
92 in [c . integ] . flags = (FBIT | SEEN);
93 in [NC] . flags = SEEN;
94 dict [0] . fath . flags = RLEAF;
95 bottom -> fath . flags = (LLEAF | RLEAF);
96 dict [0] . count [0] = 2;
97
98 dict [0] . sp [1] . ch = c . integ;
99 bottom -> sp [0] . ch = NC;
100 bottom -> sp [1] . ch = EF;
101
102 p = dict;
103 while ((c . integ = getc (cfp)) != EOF) {
104 ic++;
105 for (m = 0200; m; ) {
106 b = (m & c . integ ? 1 : 0);
107 m >>= 1;
108 if (p -> fath . flags & (b ? RLEAF : LLEAF)) {
109 d . integ = p -> sp [b] . ch;
110 if (d . integ == EF) break;
111 if (d . integ == NC) {
112 uptree (NC);
113 d . integ = 0;
114 for (j = 8; j--; m >>= 1) {
115 if (m == 0) {
116 c . integ = getc (cfp);
117 ic++;
118 m = 0200;
119 }
120 d . integ <<= 1;
121 if (m & c . integ) d . integ++;
122 }
123 insert (d . integ);
124 }
125 uptree (d . integ);
126 putc (d . chars . lob, uncfp);
127 oc++;
128 p = dict;
129 }
130 else p = p -> sp [b] . p;
131 }
132 }
133 }
134 }
135 else goto notcompact;
136 }
137 else {
138 notcompact : if (i < argc) {
139 fprintf (stderr, "%s: ", argv [i]);
140 unlink (fname);
141 }
142 if (c . integ == PACKED) fprintf (stderr, "File is packed. Use unpack.\n");
143 else fprintf (stderr, "Not a compacted file.\n");
144 if (i >= argc) break;
145 goto closeboth;
146 }
147
148 if (ferror (uncfp) || ferror (cfp))
149 if (i < argc) {
150 if (ferror (uncfp))
151 perror (fname);
152 else
153 perror (argv [i]);
154 fprintf (stderr, "Unable to uncompact %s\n", argv [i]);
155 unlink (fname);
156 goto closeboth;
157 }
158 if (i >= argc) break;
159 fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname);
160 unlink (argv [i]);
161 closeboth : fclose (cfp);
162 closein : fclose (uncfp);
163 if (i == argc - 1) break;
164 for (j = 256; j--; ) in [j] . flags = 0;
165 continue;
166 fail : fprintf (stderr, "Unsuccessful uncompact of standard input to standard output.\n");
167 break;
168 }
169}