Catdoc 是一套 GNU Public License Open Source,最近摸了一下,稍微改動了一點地方,主要原因是 catdoc 在找尋字碼表時,會採用原先在 compile time 所下的 define 關鍵字,這意味著程式若要搬移必須重制原先編譯時期所決定的相關目錄結構才行,例如一開始編譯時,就說字碼將安裝在 /usr/local/share/catdoc 下,那你把 binary 程式去另一台機器時,也必須把字碼一樣設置相同的路徑才行。
因此花了一點時間看了一下,還滿容易的,僅需把兩個變數(charset_path, map_path)的定義參數化,因為那個字碼路徑(CHARSETPATH)在各個程式之間算共享的資訊,在 C 語言中就是透過定義一份記憶體位置,其他用 extern 的方式來連結存取。改完後在多設個參數(-r /path/charsets)讓執行時可以初始化就好。
程式碼:
https://github.com/changyy/catdoc-portable
詳細流程:
diff --git a/catdoc-0.94.2/src/catdoc.c b/catdoc-0.94.2/src/catdoc.c
index d8270fd..c3729a4 100644
--- a/catdoc-0.94.2/src/catdoc.c
+++ b/catdoc-0.94.2/src/catdoc.c
@@ -35,6 +35,8 @@ int _argc;
 /* Processes options, reads charsets files and substitution */
 /* maps and passes all remaining args to processfile */
 /**************************************************************/
+char *charset_path = NULL;
+char *map_path = NULL;
 int main(int argc, char **argv) {
 FILE *f;
 int c,i;
@@ -56,8 +58,15 @@ int main(int argc, char **argv) {
 #ifdef HAVE_LANGINFO
 get_locale_charset();
 #endif 
- while ((c=getopt(argc,argv,"Vls:d:f:taubxv8wm:"))!=-1) {
+ charset_path = strdup(CHARSETPATH);
+ map_path = charset_path;
+ while ((c=getopt(argc,argv,"Vls:d:f:taubxv8wm:r:"))!=-1) {
 switch (c) {
+ case 'r':
+ free(charset_path);
+ charset_path = strdup(optarg);
+ map_path = charset_path;
+ break;
 case 's':
 check_charset(&source_csname,optarg);
 forced_charset = 1;
@@ -181,12 +190,13 @@ int main(int argc, char **argv) {
 fclose(f);
 }
 }
+ free(charset_path);
 return c;
 }
 /************************************************************************/
 /* Displays help message */
 /************************************************************************/
 void help (void) {
- printf("Usage:\n catdoc [-vu8btawxlV] [-m number] [-s charset] "
+ printf("Usage:\n catdoc [-vu8btawxlV] [-r /path/charsets] [-m number] [-s charset] "
 "[-d charset] [ -f format] files\n");
 }
diff --git a/catdoc-0.94.2/src/catppt.c b/catdoc-0.94.2/src/catppt.c
index 50fc04c..f74307a 100644
--- a/catdoc-0.94.2/src/catppt.c
+++ b/catdoc-0.94.2/src/catppt.c
@@ -34,7 +34,7 @@
 * 
 */
 void help (void) {
- printf("Usage:\n ppt2text [-lV] [-b string] [-s charset] [-d charset] files\n");
+ printf("Usage:\n ppt2text [-lV] [-r /path/charsets] [-b string] [-s charset] [-d charset] files\n");
 }
 
 
@@ -48,6 +48,8 @@ char *input_buffer, *output_buffer;
 * 
 * @return 
 */
+char *charset_path = NULL;
+char *map_path = NULL;
 int main(int argc, char *argv[]) {
 FILE *input;
 FILE *new_file, *ole_file;
@@ -68,10 +70,17 @@ int main(int argc, char *argv[]) {
 get_locale_charset();
 #endif
 
+ charset_path = strdup(CHARSETPATH);
+ map_path = charset_path;
 check_charset(&dest_csname,dest_csname); 
 
- while ((c=getopt(argc,argv,"Vls:d:p:"))!=-1) {
+ while ((c=getopt(argc,argv,"Vls:d:p:r:"))!=-1) {
 switch(c) {
+ case 'r':
+ free(charset_path);
+ charset_path = strdup(optarg);
+ map_path = charset_path;
+ break;
 case 'l':
 list_charsets(); exit(0);
 case 's':
@@ -153,5 +162,6 @@ int main(int argc, char *argv[]) {
 fprintf(stderr, "%s is not OLE file or Error\n", filename);
 }
 }
+ free(charset_path);
 return 0;
 }
diff --git a/catdoc-0.94.2/src/charsets.c b/catdoc-0.94.2/src/charsets.c
index b52a1eb..9c0b699 100644
--- a/catdoc-0.94.2/src/charsets.c
+++ b/catdoc-0.94.2/src/charsets.c
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 #include "catdoc.h"
 
-char *charset_path=CHARSETPATH;
+//char *charset_path=CHARSETPATH;
 char *source_csname=SOURCE_CHARSET, *dest_csname=TARGET_CHARSET;
 short int * source_charset;
 int unknown_as_hex=0;
diff --git a/catdoc-0.94.2/src/substmap.c b/catdoc-0.94.2/src/substmap.c
index f29d629..a609a4c 100644
--- a/catdoc-0.94.2/src/substmap.c
+++ b/catdoc-0.94.2/src/substmap.c
@@ -13,7 +13,7 @@
 #include <stdlib.h>
 #include "catdoc.h"
 SUBSTMAP spec_chars, replacements;
-char *map_path=CHARSETPATH;
+//char *map_path=CHARSETPATH;
 void map_insert(SUBSTMAP map, int uc, const char *s) ;
 int longest_sequence=6;/* six is longest character sequence which can be
 generated by catdoc internally*/
diff --git a/catdoc-0.94.2/src/xls2csv.c b/catdoc-0.94.2/src/xls2csv.c
index 243e801..34184d1 100644
--- a/catdoc-0.94.2/src/xls2csv.c
+++ b/catdoc-0.94.2/src/xls2csv.c
@@ -31,13 +31,15 @@ extern char *sheet_separator;
 /* Displays help message */
 /************************************************************************/
 void help (void) {
- printf("Usage:\n xls2csv [-xlV] [-g number] [-f date-format] [-b string] [-s charset] [-d charset] [-c char] [ -q number] files\n");
+ printf("Usage:\n xls2csv [-xlV] [-r /path/charsets] [-g number] [-f date-format] [-b string] [-s charset] [-d charset] [-c char] [ -q number] files\n");
 }
 /* Defines unicode chars which should be
 replaced by strings before UNICODE->target chatset
 mappigs are applied i.e. TeX special chars like %
 */
 char *input_buffer, *output_buffer;
+char *charset_path = NULL;
+char *map_path = NULL;
 int main(int argc, char *argv[])
 {
 FILE *input;
@@ -58,11 +60,17 @@ int main(int argc, char *argv[])
 #ifdef HAVE_LANGINFO
 get_locale_charset();
 #endif
- 
+ charset_path = strdup(CHARSETPATH);
+ map_path = charset_path;
 check_charset(&dest_csname,dest_csname); 
- 
- while ((c=getopt(argc,argv,"Vlf:s:d:xq:c:b:g:p:"))!=-1) {
+
+ while ((c=getopt(argc,argv,"Vlf:s:d:xq:c:b:g:p:r:"))!=-1) {
 switch(c) {
+ case 'r':
+ free(charset_path);
+ charset_path = strdup(optarg);
+ map_path = charset_path;
+ break;
 case 'l':
 list_charsets(); exit(0);
 case 'x': 
@@ -176,5 +184,6 @@ int main(int argc, char *argv[])
 fprintf(stderr, "%s is not OLE file or Error\n", filename);
 }
 }
+ free(charset_path);
 return 0;
 }