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