/** * @file FLICONV.c * @brief Sample program in C to convert files via the FLCICV interface * The program is compatible with the iconv utility on linux systems * @author limes datentechnik gmbh ******************************************************************************/ #include #include #include #include #include #include #define FICONV // enable "iconv" macros for "fliconv" functions #include"FLCICV.h" static void printHelp(void) { fprintf(stderr,"\n"); fprintf(stderr,"Usage: fliconv [OPTION...] [FILE...]\n"); fprintf(stderr,"Convert given files from one character set to another\n"); fprintf(stderr,"\n"); fprintf(stderr," Information:\n"); fprintf(stderr," -? Prints this help list\n"); fprintf(stderr," -h Prints this help list\n"); fprintf(stderr," -l List all supported character sets\n"); fprintf(stderr," -v Print program version\n"); fprintf(stderr," -a Print about information\n"); fprintf(stderr," -z Print license text\n"); fprintf(stderr," -p Print progress information\n"); fprintf(stderr,"\n"); fprintf(stderr," Input/Output file control:\n"); fprintf(stderr," FILE... Input file list [STDIN]\n"); fprintf(stderr," -o FILE Output file [STDOUT]\n"); fprintf(stderr,"\n"); fprintf(stderr," Input/Output format specification:\n"); fprintf(stderr," -f NAME Encoding string or CCSID of original text [UTF-8]\n"); fprintf(stderr," -t NAME Encoding string or CCSID for output [UTF-8]\n"); fprintf(stderr,"\n"); fprintf(stderr," Input encoding string enhancements:\n"); fprintf(stderr," //BOM Manage byte order change inside data (only if same bit width)\n"); fprintf(stderr," //ENL2LF Convert EBCDIC new line (0x85/0x15) to line feed (0x0A/0x25)\n"); fprintf(stderr,"\n"); fprintf(stderr," Output encoding string enhancements:\n"); fprintf(stderr," //BOM Write byte order mark\n"); fprintf(stderr," //ELF2NL Convert EBCDIC line feed (0x0A/0x25) to new line (0x85/0x15)\n"); fprintf(stderr," //TOUPPER Upper case mapping\n"); fprintf(stderr," //TOLOWER Lower case mapping\n"); fprintf(stderr," //TOSUPPER Special upper case mapping\n"); fprintf(stderr," //TOSLOWER Special lower case mapping\n"); fprintf(stderr," //TOFOLD Special case folding\n"); fprintf(stderr," //TOUSER Use case mapping defined in user table/module (^CP=cp_list)\n"); fprintf(stderr," //IGNORE Ignore invalid characters\n"); fprintf(stderr," //TRANSLIT['('[systab]')'] Transliterate invalid characters [ICONV]\n"); fprintf(stderr," //SUBSTITUTE['('[codepoint_list]')'] Substitute invalid characters [0x1A]\n"); #ifdef __HOST__ fprintf(stderr," //USRMOD'('module_name')' Use a predefined user table module (CCUTNPAS/CCUTSEPA/CCUTDELA/CCUTDLAX/...)\n"); #else fprintf(stderr," //USRMOD'('module_name')' Use a predefined user table module (ccutnpas/ccutsepa/ccutdela/ccutdlax/...)\n"); #endif fprintf(stderr," //USRTAB'('file_name')' Use a custom text file containing a user table (see FLCL manual for more information)\n"); fprintf(stderr," //REPORT['('[file_name]')'] Write a report file [STDERR]\n"); fprintf(stderr,"\n"); fprintf(stderr," Examples:\n"); fprintf(stderr," fliconv -l\n"); fprintf(stderr," fliconv -p -f UTF16LE//BOM -t 1141//ELF2NL//IGNORE//TRANSLIT//REPORT(report.txt) -o outdat.txt input1.txt input2.txt\n"); fprintf(stderr,"\n"); fprintf(stderr," Support:\n"); fprintf(stderr," Web : http://www.flam.de/\n"); fprintf(stderr," Mail: support@flam.de\n"); fprintf(stderr,"\n"); } /** * This test program implements the iconv utility with the FLUC character conversion module. * Use fliconv -? for the syntax, help and a sample */ int main(int argc, char * argv[]) { FILE* pfIn=stdin; FILE* pfOut=stdout; static char acIn[65536]; size_t i,uiOut,uiSiz,uiLen,uiRst,uiErr,uiCnt=0; char* h; char* a[256]; char* pcFrom="UTF-8"; char* pcTo="UTF-8"; char* pcOut=NULL; char* pcHlpIn; char* pcHlpOut; void* pvIcv; int k,isProgress=0; clock_t c=0; if (argc==2) { // parse HOST parameter string (comma separation) a[0]=argv[0]; a[1]=argv[1]; for (i=2,h=strchr(a[i-1],',');i<256 && h!=NULL;i++,h=strchr(a[i-1],',')) { h[0]=0x00; a[i]=h+1; } argc=i; argv=a; } for (i=1;i the last character is incomplete fprintf(stderr,"\nIncomplete multibyte character sequence at end of the data (Offset %"PRIi64")\n",iconv_position(pvIcv)+1); iconv_close(pvIcv); free(pcOut); exit(1); } pcHlpIn=acIn; uiLen+=uiRst; pcHlpOut=pcOut; uiOut=uiSiz; uiErr=iconv(pvIcv,&pcHlpIn,&uiLen,&pcHlpOut,&uiOut); uiOut=uiSiz-uiOut; if (uiErr>0) uiCnt+=uiErr; if ((uiErr==-1 && errno!=EINVAL) || (feof(pfIn) && uiRst)) { // conversion error fprintf(stderr,"\nCharacter conversion failed at byte offset %"PRIi64" (%d - %s)\n",iconv_position(pvIcv)+1,errno,fliconv_strerror(errno)); fprintf(stderr,"%s",iconv_error_trace()); fwrite(pcOut,1,uiOut,pfOut); iconv_close(pvIcv); free(pcOut); exit(1); } else { // write converted data uiErr=fwrite(pcOut,1,uiOut,pfOut); if (uiErr!=uiOut) { fprintf(stderr,"\nWrite data to file failed (%d - %s)\n",errno,strerror(errno)); iconv_close(pvIcv); free(pcOut); exit(2); } memcpy(acIn,pcHlpIn,uiLen); // save rest (incomplete multibyte sequence) at the beginning of the buffer uiRst=uiLen; } if (isProgress) { // progress bar if (clock()-c>CLOCKS_PER_SEC) { fprintf(stderr,"#"); c=clock(); } } } if (isProgress) fprintf(stderr,"\n"); if (ferror(pfIn)!=0 && ferror(pfIn)!=EOF) { // conversion loop and based on a read error fprintf(stderr,"\nRead data from file failed (%d - %s)\n",errno,strerror(errno)); iconv_close(pvIcv); free(pcOut); exit(3); } if (pfIn !=stdin) fclose(pfIn); i++; } if (isProgress) { // print statistic information fprintf(stderr,"\nStatistic:\n"); fprintf(stderr,"Files converted: %d\n",k); fprintf(stderr,"Total bytes converted: %"PRIi64"\n",iconv_position(pvIcv)); fprintf(stderr,"Non-reversible conversions: %"PRIi64"",(int64_t)uiCnt); if (uiCnt) fprintf(stderr," (use report file for more information)\n"); else fprintf(stderr,"\n"); fprintf(stderr,"\n"); } iconv_close(pvIcv); if (pfOut!=stdout) fclose(pfOut); free(pcOut); exit(0); } /******************************************************************************/