diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/charconv/charconv.c |
Initial commit
Diffstat (limited to 'support/charconv/charconv.c')
-rw-r--r-- | support/charconv/charconv.c | 1052 |
1 files changed, 1052 insertions, 0 deletions
diff --git a/support/charconv/charconv.c b/support/charconv/charconv.c new file mode 100644 index 0000000000..11f0feda0a --- /dev/null +++ b/support/charconv/charconv.c @@ -0,0 +1,1052 @@ +/* charconv + * Filter for conversion of character tables + * Dr. Burkhard Kirste 1993/07/17 + * kirste@chemie.fu-berlin.de + * usage: charconv [-h|-v] [-d|-m|-u] [-f from_table] [-t to_table] + * [[-i] input_file [[-o] output_file]] + * requires: sys_def.h, getopt.c, charstab.h + * cc charconv.c getopt.c -o char_arr + */ +#define VERSION "1.00" +#define TEXQUOTE /* if defined, allow for ``F"u"se'' etc. */ +#include "sys_def.h" +#include <string.h> +#include <ctype.h> +#ifdef __ANSI +#include <stdlib.h> +#else +#ifdef sun +#include <stdlib.h> +#endif +#endif /* stdlib */ +#include "charstab.h" /* character tables */ + +#ifndef EOF +#define EOF -1 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef MAXPATHLEN +#define MAXPATHLEN 128 /* max. length of path names */ +#endif + +#define TABLELEN 256 /* size of conversion table */ +#define BUFLEN 1024 /* size of input buffer */ +#define MAXTOK 40 /* maximum size of token */ +#define OFFSET 1024 /* used in fgetit */ + + +/* prototypes */ +#ifdef __ANSI +#define PROTO(x) x +#else +#define PROTO(x) () +#endif + +int getopt PROTO((int argc, char **argv, char *opts)); +int do_table PROTO((char **from_table, char **to_table)); +int do_str PROTO((char **from_table, int to_type)); +int fgetit PROTO((int from_type, char **to_table, FILE *fp)); +int find_str PROTO((char *ptr, char **to_table)); + +#undef PROTO + +/* globals */ +static char sccsid[] = "@(#)charconv character conversion. 93/07/17 BKi"; +extern char *optarg; /* option arg. (getopt) */ +extern int optind, optopt; /* option index (getopt) */ +char buffer[BUFLEN]; /* input buffer */ +char conv_table[TABLELEN]; /* character conversion table */ +char *trans_ptr[TABLELEN]; /* string output */ + +int +do_table(from_table, to_table) + char **from_table, **to_table; + +/* + * Fill character conversion table + * 1993/07/11 BKi + * char **from_table: source character table + * char **to_table: aim character table + * global: conv_table[TABLELEN] + */ +{ + int i, j; + char *ptr; + + for (i = 0; i < TABLELEN; i++) + { + ptr = from_table[i]; + for (j = 0; j < TABLELEN; j++) + if (strcmp(ptr, to_table[j]) == 0) + break; + if (j >= TABLELEN) + j = i; + conv_table[i] = j; + } /* for i */ + return 0; +} /* do_table */ + +int +do_str(from_table, to_type) + char **from_table; + int to_type; + +/* + * Find corresponding string + * 1993/07/11 BKi + * char **from_table: source character table + * int to_type: type (column) in trans_string + * global: trans_string[TRANS_ROW][TRANS_COL] + * trans_ptr[TABLELEN] + */ +{ + int i, j; + char *ptr; + + for (i = 0; i < TABLELEN; i++) + { + ptr = from_table[i]; + for (j = 0; j < TRANS_ROW; j++) + if (strcmp(ptr, trans_string[j][0]) == 0) + { + trans_ptr[i] = trans_string[j][to_type]; + break; + } + if (j >= TRANS_ROW) + { + if (i == '\t') + trans_ptr[i] = "\t"; + else if (i == '\n') + trans_ptr[i] = "\n"; + else if (i == '\r') + trans_ptr[i] = "\r"; + else if (i < 32) + trans_ptr[i] = ""; + else + trans_ptr[i] = " "; + } + } /* for i */ + return 0; +} /* do_str */ + +int +find_str(ptr, to_table) + char *ptr; + char **to_table; + +/* + * Find character code corresponding to string + * 1993/07/11 BKi + * char *ptr: string + * char **to_table: character table + * return character code + */ +{ + int i; + + for (i = 0; i < TABLELEN; i++) + { + if (strcmp(ptr, to_table[i]) == 0) + return i; + } /* for i */ + /* if not found, use blank */ + return 0x20; +} /* find_str */ + +int +fgetit(from_type, to_table, fp) + int from_type; + char **to_table; + FILE *fp; + +/* + * Parse file fp, identify tokens, return character + * 1993/07/12 BKi + * int from_type: type of tokens (column) + * char **to_type: aim character table (or NULL) + * FILE *fp: input stream + * global: trans_string[TRANS_ROW][TRANS_COL] + * buffer[BUFLEN] + * return character_code || trans_string_row + OFFSET || EOF + */ +{ + int c; + int i; + static int len = 0; + static int special = 0; + + if (special < 2) + c = fgetc(fp); + if (c == EOF) + return c; + if (from_type == 0) + { + /* special coding */ + do + { + if (special == 0) + { + if (c != '\\') + return c; + else + { + ++special; + buffer[len++] = c; + buffer[len] = '\0'; + } + } else if (special == 1) + { + buffer[len++] = c; + buffer[len] = '\0'; + if (c == '\\' || len >= MAXTOK) + ++special; + } + if (special > 1) + { + c = buffer[0]; + for (i = 0; i < len; i++) + buffer[i] = buffer[i + 1]; + --len; + if (buffer[0] == '\\') + special = 1; + if (len == 0) + special = 0; + return c; + } + if (special == 1) + { + if (len > 2) + { + /* identify token */ + for (i = 0; i < TRANS_ROW; i++) + if (strcmp(buffer, trans_string[i][from_type]) == 0) + { + len = 0; + special = 0; + buffer[0] = '\0'; + if (to_table != NULL) + return find_str(trans_string[i][0], to_table); + else + return i + OFFSET; + } + } + c = fgetc(fp); + if (c == EOF) + return c; + } + } while (TRUE); + } else if (from_type == 1) + { + /* TeX */ + do + { + if (special == 2) + { + c = buffer[0]; + special = 0; + len = 0; + buffer[0] = '\0'; + } + if (special == 0) + { + if (c == '%') + { + do + { + c = fgetc(fp); + if (c == EOF) + return c; + } while (c != '\r' && c != '\n'); + return c; + } else if (c == '{' || c == '}' || c == '$') + { + c = fgetc(fp); + if (c == EOF) + return c; + continue; +#ifdef TEXQUOTE + } else if (c != '\\' && c != '\'' && c != '?' && c != '!' + && c != '`' && c != '"') +#else + } else if (c != '\\' && c != '\'' && c != '?' && c != '!' && c != '`') +#endif + return c; + else + { + special = 1; + buffer[len++] = c; + buffer[len] = '\0'; + } + } else if (special == 1) + { + if (len == 1 && buffer[0] != '\\') + { + /* check for '' ?` !` */ + buffer[len++] = c; + buffer[len] = '\0'; + if (strcmp(buffer, "``") == 0) + strcpy(buffer, "''"); +#ifdef TEXQUOTE + /* allow for ``F"u"se'' etc. */ + if (buffer[0] == '"') + { + switch (c) + { + case 'A': + strcpy(buffer, "\\\"A"); + len = 3; + break; + case 'O': + strcpy(buffer, "\\\"O"); + len = 3; + break; + case 'U': + strcpy(buffer, "\\\"U"); + len = 3; + break; + case 'a': + strcpy(buffer, "\\\"a"); + len = 3; + break; + case 'o': + strcpy(buffer, "\\\"o"); + len = 3; + break; + case 'u': + strcpy(buffer, "\\\"u"); + len = 3; + break; + case 's': + case '3': + case 'B': + strcpy(buffer, "\\ss{}"); + len = 5; + /* break; */ + } /* switch */ + } /* if quote */ +#endif + /* identify token */ + for (i = 0; i < TRANS_ROW; i++) + if (strcmp(buffer, trans_string[i][from_type]) == 0) + { + len = 0; + special = 0; + buffer[0] = '\0'; + if (to_table != NULL) + return find_str(trans_string[i][0], to_table); + else + return i + OFFSET; + } + /* otherwise nothing special */ + c = buffer[0]; + buffer[0] = buffer[1]; + buffer[1] = '\0'; + len = 1; + special = 2; + return c; + } + if (len >= MAXTOK) + { + len = 0; + special = 0; + buffer[0] = '\0'; + continue; + } else if (len == 1 && c == '3' && buffer[0] == '\\') + { + /* short for German sz */ + strcpy(buffer, "\\ss{}"); + len = 5; + } else if (len == 1 && c == '/' && buffer[0] == '\\') + { + /* italic extra space */ + len = 0; + special = 0; + buffer[0] = '\0'; + c = fgetc(fp); + if (c == EOF) + return c; + continue; + } else + { + buffer[len++] = c; + buffer[len] = '\0'; + } + } + if (special == 1) + { + if (len >= 2) + { + /* identify token */ + for (i = 0; i < TRANS_ROW; i++) + if (strncmp(buffer, trans_string[i][from_type], len) == 0 + || strncmp(buffer, &trans_string[i][from_type][1], len) == 0) + break; + if (i >= TRANS_ROW) + { + /* token not found */ + if (!isalpha(c)) + { + len = 0; + special = 0; + buffer[0] = '\0'; + if (c == ' ') + { + c = fgetc(fp); + if (c == EOF) + return c; + } + } else + { + /* get whole token */ + c = fgetc(fp); + if (c == EOF) + return c; + } + continue; + } + if (strcmp(buffer, trans_string[i][from_type]) == 0 + || trans_string[i][from_type][len + 1] == '$' + || trans_string[i][from_type][len] == '}' + || (trans_string[i][from_type][len] == '{' + && trans_string[i][from_type][len + 1] == '}')) + { + if (isalpha(c) && + (trans_string[i][from_type][len + 1] == '$' || + (trans_string[i][from_type][len] == '{' + && trans_string[i][from_type][len + 1] == '}'))) + { + c = fgetc(fp); + if (isalpha(c)) + continue; + else if (c != ' ') + { + special = 2; + buffer[0] = c; + buffer[1] = '\0'; + len = 1; + } + } + if (special != 2) + { + len = 0; + special = 0; + buffer[0] = '\0'; + } + if (to_table != NULL) + return find_str(trans_string[i][0], to_table); + else + return i + OFFSET; + } + } + c = fgetc(fp); + if (c == EOF) + return c; + } + } while (TRUE); + } else if (from_type == 2) + { + /* HTML */ + do + { + if (special == 0) + { + if (c != '&' && c != '<') + return c; + else + { + ++special; + buffer[len++] = c; + buffer[len] = '\0'; + } + } else if (special == 1) + { + buffer[len++] = c; + buffer[len] = '\0'; + if (c == '&' || len >= MAXTOK) + ++special; + } + if (special > 1) + { + c = buffer[0]; + for (i = 0; i < len; i++) + buffer[i] = buffer[i + 1]; + --len; + if (buffer[0] == '&' || buffer[0] == '<') + special = 1; + if (len == 0) + special = 0; + return c; + } + if (special == 1) + { + if (buffer[0] == '<' && (isalpha(buffer[1]) || buffer[1] == '/')) + { + /* skip HTML tag */ + do + { + c = fgetc(fp); + if (c == EOF) + return c; + if (c == '>') + { + special = 0; + len = 0; + buffer[0] = '\0'; + break; + } + } while (TRUE); + c = fgetc(fp); + if (c == EOF) + return c; + continue; + } + if (c == ';') + { + /* identify token */ + for (i = 0; i < TRANS_ROW; i++) + if (strcmp(buffer, trans_string[i][from_type]) == 0) + { + len = 0; + special = 0; + buffer[0] = '\0'; + if (to_table != NULL) + return find_str(trans_string[i][0], to_table); + else + return i + OFFSET; + } + if (strcmp(buffer, """) == 0) + c = '"'; + else + c = ' '; + len = 0; + special = 0; + buffer[0] = '\0'; + return c; + } + c = fgetc(fp); + if (c == EOF) + return c; + } + } while (TRUE); + } + return c; +} /* fgetit */ + +int +main(argc, argv) + int argc; + char **argv; +{ + static char opts[] = "hvdmuf:t:i:o:"; /* options (getopt) */ + static char allowed[] = " acdehlmrstz"; /* known table types */ + int optcheck = 0; /* check validitity of of options */ + int eol = 0; /* end-of-line option */ + int rtf_flag = 0; /* flag for RTF output (if 1) */ + int c; /* character */ + int lastc = ' '; + int i; + int in_type = 0, out_type = 0; /* 0: no conv., 1: char, 2: + * string */ + int from_type, to_type; /* source and aim type of conversion */ + char **from_table, **to_table; /* character conversion + * tables */ + char inname[MAXPATHLEN]; /* input file name */ + char outname[MAXPATHLEN]; /* output file name */ + FILE *fpin = NULL; /* input file */ + FILE *fpout = NULL; /* output file */ + + /* get options */ + inname[0] = outname[0] = '\0'; + from_type = to_type = ' '; + from_table = to_table = NULL; + do + { + if ((c = getopt(argc, argv, opts)) == EOF) + break; + switch (c) + { + case 'v': + fprintf(stderr, "%s %s\n", VERSION, sccsid); + case 'h': + case '?': + c = '?'; + optcheck = 1; + break; + case 'd': + eol = 1; + break; + case 'm': + eol = 2; + break; + case 'u': + eol = 3; + break; + case 'f': + from_type = (int) optarg[0] & 0xff; + break; + case 't': + to_type = (int) optarg[0] & 0xff; + break; + case 'i': + strncpy(inname, optarg, MAXPATHLEN); + inname[MAXPATHLEN - 1] = '\0'; + break; + case 'o': + strncpy(outname, optarg, MAXPATHLEN); + outname[MAXPATHLEN - 1] = '\0'; + /* break; */ + } /* options switch */ + if (c == '?') + break; + } while (TRUE); + if (optcheck == 0) + { + /* check validity of arguments */ + if (strchr(allowed, from_type) == NULL) + { + fprintf(stderr, "Unknown character table '%c' (-f)\n", + (char) from_type); + optcheck = 1; + } + if (strchr(allowed, to_type) == NULL) + { + fprintf(stderr, "Unknown character table '%c' (-t)\n", + (char) to_type); + optcheck = 1; + } + } + if (optcheck == 1) + { + fprintf(stderr, + "usage: charconv [-d|-m|-u] [-f from_table] [-t to_table]\n"); + fprintf(stderr, + " [[-i] input_file [-o] output_file]\n"); + fprintf(stderr, " -d - create MS DOS end-of-line (CRLF)\n"); + fprintf(stderr, " -m - create Macintosh end-of-line (CR)\n"); + fprintf(stderr, " -u - create Unix end-of-line (LF)\n"); + fprintf(stderr, " -f, -t - 'from'/'to' character table\n"); + fprintf(stderr, " where from_table/to_table is one of:\n"); + fprintf(stderr, " a - ASCII (7 bit) (*)\n"); + fprintf(stderr, " c - transcription (*)\n"); + fprintf(stderr, " d - DOS code page 437\n"); + fprintf(stderr, " e - EBCDIC (only for ASCII <-> EBCDIC!)\n"); + fprintf(stderr, " h - HTML (hypertext) (*)\n"); + fprintf(stderr, " l - ISO Latin 1 (Unix, ANSI, MS Windows)\n"); + fprintf(stderr, " m - Apple Macintosh\n"); + fprintf(stderr, " r - RTF (Rich Text Format) (output only!)\n"); + fprintf(stderr, " s - Symbol font\n"); + fprintf(stderr, " t - TeX (*)\n"); + fprintf(stderr, " z - Atari ST\n"); + fprintf(stderr, " (*) string code\n"); + return 1; + } + if (optind < argc) + { + strncpy(inname, argv[optind++], MAXPATHLEN); + inname[MAXPATHLEN - 1] = '\0'; + } + if (optind < argc) + { + strncpy(outname, argv[optind++], MAXPATHLEN); + outname[MAXPATHLEN - 1] = '\0'; + } + /* find conversion tables */ + switch (from_type) + { + case 'a': + in_type = 3; + from_table = NULL; + break; + case 'd': + in_type = 1; + from_table = pc_table; + break; + case 'e': + in_type = 4; + if (out_type == 0) + out_type = 3; + from_table = NULL; + break; + case 'l': + in_type = 1; + from_table = iso_table; + break; + case 'm': + in_type = 1; + from_table = mac_table; + break; + case 'z': + in_type = 1; + from_table = st_table; + break; + case 's': + in_type = 1; + from_table = sym_table; + break; + case 'c': + in_type = 2; + from_type = 0; + from_table = NULL; + break; + case 't': + in_type = 2; + from_type = 1; + from_table = NULL; + break; + case 'h': + in_type = 2; + from_type = 2; + from_table = NULL; + break; + default: + from_table = NULL; + } /* switch */ + switch (to_type) + { + case 'a': + out_type = 2; + to_type = 3; + to_table = NULL; + break; + case 'd': + out_type = 1; + to_table = pc_table; + break; + case 'e': + out_type = 4; + to_table = NULL; + break; + case 'r': + rtf_flag = 1; + case 'l': + out_type = 1; + to_table = iso_table; + break; + case 'm': + out_type = 1; + to_table = mac_table; + break; + case 'z': + out_type = 1; + to_table = st_table; + break; + case 's': + out_type = 1; + to_table = sym_table; + break; + case 'c': + out_type = 2; + to_type = 0; + to_table = NULL; + break; + case 't': + out_type = 2; + to_type = 1; + to_table = NULL; + break; + case 'h': + out_type = 2; + to_type = 2; + to_table = NULL; + break; + default: + to_table = NULL; + } /* switch */ + /* optionally, open files */ + if (strlen(inname)) + { + fpin = fopen(inname, "rb"); + if (fpin == NULL) + { + fprintf(stderr, "Error opening input file %s\n", inname); + exit(1); + } + } else + fpin = stdin; + if (strlen(outname)) + { + if (strlen(inname) && strcmp(inname, outname) == 0) + { + fprintf(stderr, "Error, 'output' must differ from 'input'\n"); + fpout = NULL; + } else + fpout = fopen(outname, "wb"); + if (fpout == NULL) + { + fprintf(stderr, "Error opening output file %s\n", outname); + exit(1); + } + } else + fpout = stdout; + /* prepare conversions */ + if (in_type == 1 && out_type == 0) + { + out_type = 1; +#ifdef __PC + to_type = 'd'; + to_table = pc_table; +#else +#ifdef __ATARI + to_type = 'r'; + to_table = st_table; +#else + to_type = 'l'; + to_table = iso_table; +#endif +#endif + } + if (in_type == 1 && out_type == 1) + { + if (from_table == to_table) + out_type = 0; + else + do_table(from_table, to_table); + } else if (in_type == 4) + { + /* EBCDIC to ASCII */ + in_type = 1; + out_type = 1; + for (i = 0; i < TABLELEN; i++) + conv_table[i] = ebc2asc[i]; + } else if (out_type == 4) + { + /* ASCII to EBCDIC */ + in_type = 1; + out_type = 1; + for (i = 0; i < TABLELEN; i++) + conv_table[i] = asc2ebc[i]; + } + if (out_type == 2 && in_type != 1 && in_type != 2) + { + in_type = 1; +#ifdef __PC + from_type = 'd'; + from_table = pc_table; +#else +#ifdef __ATARI + from_type = 'r'; + from_table = st_table; +#else + from_type = 'l'; + from_table = iso_table; +#endif +#endif + } + if (out_type == 2 && in_type == 1) + do_str(from_table, to_type); + if (in_type == 2) + { + buffer[0] = '\0'; + if (out_type == 0) + { + out_type = 1; +#ifdef __PC + to_type = 'd'; + to_table = pc_table; +#else +#ifdef __ATARI + to_type = 'r'; + to_table = st_table; +#else + to_type = 'l'; + to_table = iso_table; +#endif +#endif + } + } + if (rtf_flag == 1) + { + do + { + if (in_type < 2) + { + if ((c = fgetc(fpin)) == EOF) + break; + if (in_type == 1 && out_type == 1) + c = (int) conv_table[c] & 0xff; + else + c &= 0xff; + } else if (in_type == 2) + { + if ((c = fgetit(from_type, to_table, fpin)) == EOF) + break; + c &= 0xff; + } + if (c <= 0) + c = ' '; + if (c < 128) + { + if (fputc(c, fpout) == EOF) + break; + } else + { + if (fputs(rtf_table[c], fpout) == EOF) + break; + } + } while (TRUE); + } else if (in_type == 1 && out_type == 1) + { + do + { + if ((c = fgetc(fpin)) == EOF) + break; + if (eol == 0) + { + c = (int) conv_table[c] & 0xff; + if (fputc(c, fpout) == EOF) + break; + } else + { + if (from_type == 'e') + c = (int) conv_table[c] & 0xff; + if (c == '\n' && lastc == '\r') + { + /* CRLF */ + lastc = c; + continue; + } + lastc = c; + if (c == '\n' || c == '\r') + { + /* EOL */ + if (eol == 1) + { + /* DOS */ + c = '\r'; + if (to_type == 'e') + c = (int) conv_table[c] & 0xff; + if (fputc(c, fpout) == EOF) + break; + c = '\n'; + } else if (eol == 2) + c = '\r'; + else if (eol == 3) + c = '\n'; + } + if (from_type != 'e') + c = (int) conv_table[c] & 0xff; + if (fputc(c, fpout) == EOF) + break; + } + } while (TRUE); + } else if (in_type == 0 && out_type == 0) + { + do + { + if ((c = fgetc(fpin)) == EOF) + break; + if (eol == 0) + { + if (fputc(c, fpout) == EOF) + break; + } else + { + if (c == '\n' && lastc == '\r') + { + /* CRLF */ + lastc = c; + continue; + } + lastc = c; + if (c == '\n' || c == '\r') + { + /* EOL */ + if (eol == 1) + { + /* DOS */ + c = '\r'; + if (fputc(c, fpout) == EOF) + break; + c = '\n'; + } else if (eol == 2) + c = '\r'; + else if (eol == 3) + c = '\n'; + } + if (fputc(c, fpout) == EOF) + break; + } + } while (TRUE); + } else + do + { + if (in_type == 2) + { + if ((c = fgetit(from_type, to_table, fpin)) == EOF) + break; + } else if ((c = fgetc(fpin)) == EOF) + break; + if (eol == 0) + { + if (out_type == 2) + { + if (c >= OFFSET) + { + if (fputs(trans_string[c - OFFSET][to_type], fpout) == EOF) + break; + } else if (in_type == 2) + { + if (fputc(c, fpout) == EOF) + break; + } else + { + if (fputs(trans_ptr[c], fpout) == EOF) + break; + } + } else if (fputc(c, fpout) == EOF) + break; + } else + { + if (c == '\n' && lastc == '\r') + { + /* CRLF */ + lastc = c; + continue; + } + lastc = c; + if (c == '\n' || c == '\r') + { + /* EOL */ + if (eol == 1) + { + /* DOS */ + c = '\r'; + if (fputc(c, fpout) == EOF) + break; + c = '\n'; + } else if (eol == 2) + c = '\r'; + else if (eol == 3) + c = '\n'; + if (fputc(c, fpout) == EOF) + break; + } else if (out_type == 2) + { + if (c >= OFFSET) + { + if (fputs(trans_string[c - OFFSET][to_type], fpout) == EOF) + break; + } else if (in_type == 2) + { + if (fputc(c, fpout) == EOF) + break; + } else + { + if (fputs(trans_ptr[c], fpout) == EOF) + break; + } + } else if (fputc(c, fpout) == EOF) + break; + } + } while (TRUE); + if (fpout != stdout && fpout != NULL) + fclose(fpout); + if (fpin != stdin && fpin != NULL) + fclose(fpin); + return 0; +} /* main */ |