#include #include #include #include #include "config.h" #include "BHeap.h" #include "FHeap.h" #include "BinHeap.h" #include "PLList.h" #include "Huffman.h" void exception(int e, char *msg) { cerr << msg << endl; exit(-1); } PriorityList *newlist(int method) { switch (method) { case 0: return new BinHeap; break; case 1: return new BHeap; break; case 2: return new FHeap; break; case 3: return new PLList; break; default: cerr << _("Unknow priority list type: ") << method << endl; exit(-1); } } void Count(FILE * strm, PriorityList * P) { int tab[256], i, valid; char *t; if (!strm) { cerr << _("Error opening file (") << strerror(errno) << ")\n"; exit(-1); } for (i = 0; i < 256; i++) { tab[i] = 0; } while ((i = getc(strm)) != EOF) { tab[i]++; } for (i = 0; i < 256; i++) { if (tab[i]) { t = (char *) malloc(2); t[0] = i; t[1] = 0; HInsert(P, tab[i], t); } } } void ReadDic(FILE * strm, PriorityList * P) { char t[1024], *f, *word, *p; if (!strm) { cerr << _("Error opening file (") << strerror(errno) << ")\n"; exit(-1); } while(gets(t)) { if (!(f = strchr(t, ':'))) { cerr << _("Bad dictionnary structure. See doc/README.en (missing : separator)") << endl; exit (-1); } *(f++) = '\0'; word = t; while (*word == ' ') { word++; } p = word + strlen(word) - 1; while (*p == ' ') { *(p--) = '\0'; } if (!strlen(word)) { cerr << _("Bad dictionnary structure. See doc/README.en (missing word)") << endl; exit (-1); } while (*f == ' ') { f++; } p = f + strlen(f) - 1; while (*p == ' ') { *(p--) = '\0'; } if (!strlen(f)) { cerr << _("Bad dictionnary structure. See doc/README.en (missing frequency)") << endl; exit (-1); } } } void Usage(void) { cerr << _("Huffman [{-f|-i} file] {type}") << endl; cerr << _("Huffman -h") << endl; cerr << _("By Nicolas Noble (nicolas@nobis-crew.org).") << endl; cerr << _("This will encode the input file with the Huffman code") << endl; cerr << _("using the priority list defined by type.") << endl; cerr << _("Type is a number taken from this list:") << endl; cerr << _(" 0 : Binary Heap (default)") << endl; cerr << _(" 1 : Binomial Heap") << endl; cerr << _(" 2 : Fibbonacci Heap (bugged)") << endl; cerr << _(" 3 : Sorted chained list") << endl; cerr << _("-f file means that you specify a dictionnary file which is") << endl; cerr << _(" structured as described into the README file.") << endl; cerr << _("-i file means that you specify a file to encode. It will") << endl; cerr << _(" built a quiet dumb dictionnary.") << endl; cerr << _("By default, a dictionnary will be built from stdin.") << endl; cerr << _("-h prints this help and exit.") << endl; exit(0); } int main(int argc, char **argv) { PriorityList *P; HTree *H; FILE * f; int method = -1, readm = -1; char *filename = NULL; while (--argc) { argv++; if (*argv[0] == '-') { if (strlen(*argv) != 2) { cerr << _("Unknow option: ") << *argv << endl; Usage(); } switch (*argv[1]) { case 'h': Usage(); break; case 'i': if (readm != -1) { cerr << _("-i and -f options are exclusive") << endl; Usage(); } readm = 1; filename = *(++argv); break; case 'f': if (readm != -1) { cerr << _("-i and -f options are exclusive") << endl; Usage(); } readm = 2; filename = *(++argv); break; } } else { if ((strlen(*argv) != 1) || ((*argv[0] < '0' || *argv[0] > '3'))) { cerr << _("Unknow priority list type: ") << *argv << endl; Usage(); } if (method != -1) { cerr << _("Extra command: ") << *argv << endl; } method = *argv[0] - '0'; } } P = newlist(method); switch (readm) { case -1: Count(stdin, P); break; case 1: Count(fopen(filename, "r"), P); break; case 2: ReadDic(fopen(filename, "r"), P); break; default: cerr << _("Internal error.") << endl; exit(-1); } H = Coder(P); H->Trace(cout); return 0; }