summaryrefslogtreecommitdiff
path: root/src/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cc')
-rw-r--r--src/main.cc154
1 files changed, 148 insertions, 6 deletions
diff --git a/src/main.cc b/src/main.cc
index 520f6ec..9cc96d5 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,5 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
#include "config.h"
#include "BHeap.h"
#include "FHeap.h"
@@ -9,20 +11,41 @@
void exception(int e, char *msg)
{
- fprintf(stderr, "%s\n", msg);
+ cerr << msg << endl;
exit(-1);
}
-PriorityList *newlist(void)
+PriorityList *newlist(int method)
{
- return new BinHeap;
+ 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;
+ 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;
}
@@ -41,12 +64,131 @@ void Count(FILE * strm, PriorityList * P)
}
}
+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 = newlist();
+ PriorityList *P;
HTree *H;
+ FILE * f;
+ int method = -1, readm = -1;
+ char *filename = NULL;
- Count(stdin, P);
+ 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);