#include #include #include #include #include #include /* Compilation against libplaton library: gcc -pedantic -L ../../platon/ -I ../../ -o strconv strconv.c -lplaton */ #define BUFSIZE 512 #if 0 # define ARGV0 (strrchr(argv[0], '/') != NULL \ ? strrchr(argv[0], '/') + 1 : argv[0]) #endif struct charset_struct { char name[20]; char *charset; }; const struct charset_struct charsets[] = { {"ascii", charset_ascii }, {"plain", charset_ascii }, {"iso88592", charset_iso88592 }, {"iso8859-2", charset_iso88592 }, {"iso-8859-2", charset_iso88592 }, {"cp1250", charset_cp1250 }, {"cp-1250", charset_cp1250 }, {"windows1250", charset_cp1250 }, {"windows-1250", charset_cp1250 }, {"keybcs2", charset_keybcs2 }, {"universum", charset_universum }, {"koi8cz", charset_koi8cz }, {"pclatin1a", charset_pclatin1a }, {"pclatin2", charset_pclatin2 }, {"*", NULL } }; int main(int argc, char **argv) { FILE *f; char buf[BUFSIZE], *src_charset, *dest_charset; register int i, idx, count, errors; #ifndef ARGV0 char *ARGV0 = strrchr(argv[0], '/') != NULL ? strrchr(argv[0], '/') + 1 : argv[0]; #endif if (argc > 1 && ! strcmp(argv[1], "-l")) { char *tmp_charset = NULL; printf("List of available charsets and its aliases:\n"); for (i = 0; charsets[i].charset != NULL; i++) { if (charsets[i].charset != tmp_charset) { printf("\n "); tmp_charset = charsets[i].charset; } else { printf(", "); } printf("%s", charsets[i].name); } printf("\n\n"); return 0; } if (argc < 4) { fprintf(stderr, "Usage: %s [ -l ] ...\n", ARGV0); return 1; } /* Source charset initialization */ src_charset = NULL; while (strchr(argv[1], '_') != NULL) *(strchr(argv[1], '_')) = '-'; argv[1] = strtolower(argv[1]); argv[1] = str_trim(argv[1]); for (i = 0; charsets[i].charset != NULL; i++) { if (! strcmp(charsets[i].name, argv[1])) { src_charset = charsets[i].charset; break; } } if (src_charset == NULL) { fprintf(stderr, "%s: unknown source charset: %s\n", ARGV0, argv[1]); return 4; } /* Destination charset initialization */ dest_charset = NULL; while (strchr(argv[2], '_') != NULL) *(strchr(argv[2], '_')) = '-'; argv[2] = strtolower(argv[2]); argv[2] = str_trim(argv[2]); for (i = 0; charsets[i].charset != NULL; i++) { if (! strcmp(charsets[i].name, argv[2])) { dest_charset = charsets[i].charset; break; } } if (dest_charset == NULL) { fprintf(stderr, "%s: unknown destination charset: %s\n", ARGV0, argv[2]); return 4; } if (src_charset == dest_charset) { fprintf(stderr, "%s: source and destination charsets are the same\n", ARGV0); return 8; } /* * Main loop */ for (errors = 0, idx = 3; idx < argc; idx++) { if ((f = fopen(argv[idx], "r+")) == NULL) { fprintf(stderr, "%s: can't open file '%s'\n", ARGV0, argv[3]); errors++; continue; } i = -1; count = 0; do { count = fread(buf, sizeof(char), BUFSIZE - 1, f); buf[count] = '\0'; strconv(buf, src_charset, dest_charset); fseek(f, -count, SEEK_CUR); if (count != fwrite(buf, sizeof(char), count, f)) { fclose(f); fprintf(stderr, "%s: file '%s' write error\n", ARGV0, argv[idx]); i = -1; break; } i++; } while (count == BUFSIZE - 1); fclose(f); if (i < 0) { errors++; continue; } printf("%s: file '%s' with size %ld successfully converted\n", ARGV0, argv[idx], (long) (i * (BUFSIZE - 1)) + (long) count); } return errors ? 2 : 0; }