diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 955a1ed..e30bb9d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,3 +103,4 @@ install( include(symbols.cmake) +add_subdirectory(tools) diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 0000000..7ad3ff5 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,23 @@ +set( + UCHARDET_SOURCES + uchardet.cpp +) + +add_executable( + uchardet + ${UCHARDET_SOURCES} +) + +target_link_libraries( + uchardet + ${UCHARDET_TARGET} +) + +install( + TARGETS + uchardet + RUNTIME + DESTINATION + ${DIR_BIN} +) + diff --git a/src/tools/uchardet.cpp b/src/tools/uchardet.cpp new file mode 100644 index 0000000..285248c --- /dev/null +++ b/src/tools/uchardet.cpp @@ -0,0 +1,158 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Universal charset detector code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * BYVoid + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "../uchardet.h" +#include +#include +#include +#include +#include + +#ifndef VERSION +#define VERSION "Unknown" +#endif +#define BUFFER_SIZE 32768 + +void detect(FILE * fp) +{ + uchardet_t handle = uchardet_new(); + + size_t size = BUFFER_SIZE; + char * buffer_in = (char *) malloc(size * sizeof(char)); + + while (fgets(buffer_in, size, fp) != NULL) + { + size_t freesize = size; + + char * buffer_in_p = buffer_in; + size_t line_length = strlen(buffer_in_p); + while (line_length + 1 == freesize && buffer_in_p[line_length - 2] != '\n') + { + buffer_in_p += size - 1; + freesize = size + 1; + size += size; + size_t offset = buffer_in_p - buffer_in; + buffer_in = (char *) realloc(buffer_in, size * sizeof(char)); + buffer_in_p = buffer_in + offset; + + if (fgets(buffer_in_p, freesize, fp) == NULL) + break; + + line_length = strlen(buffer_in_p); + } + + int retval = uchardet_handle_data(handle, buffer_in, strlen(buffer_in)); + + if (retval != 0) + { + fprintf(stderr, "Handle data error.\n"); + exit(0); + } + } + uchardet_data_end(handle); + + printf("%s\n", uchardet_get_charset(handle)); + + uchardet_delete(handle); + free(buffer_in); +} + +void show_version() +{ + printf("\n"); + printf("uchardet Command Line Tool\n"); + printf("Version %s\n", VERSION); + printf("\n"); + printf("Author: %s\n", "BYVoid"); + printf("Bug Report: %s\n", "http://code.google.com/p/uchardet/issues/entry"); + printf("\n"); +} + +void show_usage() +{ + show_version(); + printf("Usage:\n"); + printf(" uchardet [Options] [File]\n"); + printf("\n"); + printf("Options:\n"); + printf(" -v, --version Print version and build information.\n"); + printf(" -h, --help Print this help.\n"); + printf("\n"); +} + +int main(int argc, char ** argv) +{ + static struct option longopts[] = + { + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 'h' }, + { 0, 0, 0, 0 }, + }; + + static int oc; + while((oc = getopt_long(argc, argv, "vh", longopts, NULL)) != -1) + { + switch (oc) + { + case 'v': + show_version(); + return 0; + case 'h': + show_usage(); + return 0; + case '?': + printf("Please use %s --help.\n", argv[0]); + return 1; + } + } + + FILE * f = stdin; + if (argc == 2) + { + f = fopen(argv[1], "r"); + if (f == NULL) + { + fprintf(stderr, "Cannot open file.\n"); + return 1; + } + } + + detect(f); + + fclose(f); + + return 0; +}