summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/main.cc154
-rw-r--r--src/test.cc21
3 files changed, 162 insertions, 15 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 173e832..c8a43f6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,4 +12,4 @@ Huffman_SOURCES = main.cc
LDADD = ../lib/libPriorityLists.la
testTas_LDADD = $(LDADD)
-Huffman_LDADD = $(LDADD)
+Huffman_LDADD = $(LDADD) ../lib/libHuffman.la
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);
diff --git a/src/test.cc b/src/test.cc
index e9a15c1..48d7762 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -20,7 +20,7 @@ void exception(int e, char *msg)
PriorityList *newlist(void)
{
- return new FHeap;
+ return new BHeap;
}
void DoCombTest(int number)
@@ -59,7 +59,7 @@ void FullTest(void)
{
PriorityList *T;
Datas_t Datas;
- Cell C1, C2;
+ Cell C1, C2, C3;
Key_t K;
int i;
@@ -76,7 +76,7 @@ void FullTest(void)
DoCombTest(10);
DoCombTest(70);
DoCombTest(1000);
- DoCombTest(10000);
+// DoCombTest(10000);
#ifdef BT
DoCombTest(100000);
#ifdef VBT
@@ -88,7 +88,8 @@ void FullTest(void)
T = newlist();
for (i = 0; i < 30; i++) {
fprintf(stderr, "%i ", N[i]);
- T->Insert(N[i], NULL);
+ C1 = T->Insert(N[i], NULL);
+ if (N[i] == 30) C3 = C1;
}
fprintf(stderr, "59 54 -10\n");
@@ -101,18 +102,22 @@ void FullTest(void)
cerr << _("Ok.\nExtract_Min + List browsing...\n");
cerr << T->Extract_Min(Datas) << endl;
T->Dump(cerr);
- cerr << _("Ok.\nLower_Key(-12) over 59...\n");
- T->Lower_Key(C1, -12);
+ cerr << _("Ok.\nLower_Key(0) over 59...\n");
+ T->Lower_Key(C1, 0);
cerr << _("Ok.\nList browsing...\n");
T->Dump(cerr);
cerr << _("Ok.\nDelete over 54...\n");
T->Delete(Datas, C2);
cerr << _("Ok.\nList browsing...\n");
T->Dump(cerr);
- cerr << "Ok.\nExtract_Min...\n";
+ cerr << _("Ok.\nLower_Key(-12) over 30...\n");
+ T->Lower_Key(C3, -12);
+ cerr << _("Ok.\nList browsing...\n");
+ T->Dump(cerr);
+ cerr << _("Ok.\nExtract_Min...\n");
cerr << T->Extract_Min(Datas) << endl;
cerr << _("Ok.\nExtracting datas...\n");
- for (i = 1; i <= 30; i++) {
+ for (i = 0; i <= 29; i++) {
cerr << _("Minimum #") << i << " = " << (K = (T->Extract_Min(Datas)))
<< endl;
if (K != i)