/*************************************************************************** * Copyright (C) 2011 by SEMIKO * * mail@semico.ru * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include /* Коды выхода BSD from @(#)sysexits.h 8.1 (Berkeley) 6/2/93 */ /* Copyright (c) 1987, 1993 */ /* The Regents of the University of California. All rights reserved. */ #define EX_USAGE 64 /* command line usage error */ #define EX_DATAERR 65 /* data format error */ #define EX_NOINPUT 66 /* cannot open input */ #define EX_NOUSER 67 /* addressee unknown */ #define EX_NOHOST 68 /* host name unknown */ #define EX_UNAVAILABLE 69 /* service unavailable */ #define EX_SOFTWARE 70 /* internal software error */ #define EX_OSERR 71 /* system error (e.g., can't fork) */ #define EX_OSFILE 72 /* critical OS file missing */ #define EX_CANTCREAT 73 /* can't create (user) output file */ #define EX_IOERR 74 /* input/output error */ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ #define EX_PROTOCOL 76 /* remote error in protocol */ #define EX_NOPERM 77 /* permission denied */ #define EX_CONFIG 78 /* configuration error */ char version[]="Version 0.12"; /* v0.1 - 02.03.11 v0.11 - 15.03.11 - добавлен вывод в HTM-файл v0.12 - 30.03.11 - исправлена ошибка в окончаниях строк для win32 */ int dos=0; /* 0-GNU/Linux 1-DOS 2-Win32 */ char fname[5][256]; /* 0-MKN без расширения 1-MKN исходный 2-TXT 3-HTM */ int fname_vsego; /* всего файлов в строке аргументов */ FILE *fp1, *fp2, *fp3; /* потоки 1-MKN 2-TXT 3-HTM */ char mes0[8]; /* ВК ПС для DOS или ВК для Linux */ char str[1024]; char str1[1024]; char str2[1024]; char strerr[256]; /* сообщение об ошибке */ int temp[32]; char ctemp[32]; int kluch_e; /* вывод сообщений 0-нет, 1 -есть*/ int kluch_zap; /* запятая = 1, точка =0 */ int kluch_nzap; /* точка или запятая = 1 - нет, 0 - есть */ struct mkn { int n; /* число записей в строке */ int g; /* записывать номер группы */ int d; /* номер записи даты */ int fd; /* формат записи даты */ int t; /* номер записи времени */ int ft; /* формат записи времени */ long grn; /* начальная группа */ long grk; /* конечная группа */ long grt; /* текущая группа */ int zapt; /* текущая запись */ } mkn; int read_mkn(void); int data2str1(int); int time2str1(int); int d2str1(void); int str2file(int); /*==================================*/ int read_mkn(void) { /* считывание очередных 8 байтов из MKN и преобразование в строку в temp[] */ int i,j; int re=0; for (i=0; i<8; i++) { /* перенос данных в temp[] */ j=fgetc(fp1); if (j==EOF) {re=1; goto end;} if (j<0) j+=256; if (j<0) j=-j; j%=256; temp[i]=j; if (temp[i]==0xFF) temp[i]=0; /* очистить неинициализированные участки блокнота */ } end: return(re); } int d2str1(void) { int i,j,k; int re=0; int ich,icl,znak, porjadok; char mantissa[24]; char zap; if (kluch_zap==0) zap='.'; else zap=','; str1[0]=0; if (temp[0]==0x80) znak=1; else znak=0; k=(int)temp[7]; /* порядок */ if (k<0) k+=256; if (k<0) k=-k; if ((k>=0)&&(k<100)) porjadok=k; if ((k>=157)&&(k<=255)) porjadok=k-256; /* отрицательный порядок */ j=0; for (i=1; i<7; i++) { /* разбор мантиссы */ k=(int)temp[i]; if (k<0) k+=256; if (k<0) k=0; ich=k/16; /* ст тетрада BCD формата */ icl=k%16; /* мл тетрада BCD формата */ if ((ich>=0)&&(ich<=9)) mantissa[j]=(char)(ich+48); else mantissa[j]='0'; if (j<16) j++; if ((j==1)&&((porjadok>7)||(porjadok<=0))) {mantissa[j]=zap; j++;} if ((j==porjadok+1)&&(porjadok>0)&&(porjadok<=7)) {mantissa[j]=zap; j++;} if ((icl>=0)&&(icl<=9)) mantissa[j]=(char)(icl+48); else mantissa[j]='0'; if (j<16) j++; if ((j==porjadok+1)&&(porjadok>0)&&(porjadok<=7)) {mantissa[j]=zap; j++;} mantissa[j]=0; } /* удаление нулей с хвоста и запятой если есть */ j=0; for (i=13; i>0; i--) { if (j==0) { if (((mantissa[i]=='0')||(mantissa[i]==0))&& (mantissa[i-1]!=zap)) mantissa[i]=0; else { if ((mantissa[i-1]==zap)&&(kluch_nzap!=0)) mantissa[i-1]=0; j=1; } } } if (mantissa[0]==0) { if (kluch_nzap!=0) strcpy(mantissa,"0"); else { if (kluch_zap!=0) strcpy(mantissa, "0,0"); else strcpy(mantissa, "0.0"); } } str1[0]=0; if (znak==1) strcat(str1,"-"); strcat(str1,mantissa); if ((porjadok<0)||(porjadok>7)) {strcat(str1,"E"); sprintf(ctemp,"%d",porjadok); strcat(str1,ctemp); } end: return(re); } /*================================*/ int data2str1(int fd) { /* Разбор даты из temp */ int re=0; int znak; int por; if (temp[0]==0x80) znak=1; else znak=0; str1[0]=0; if (temp[1]==0) { /* Ноль */ switch(fd) { case 1: strcpy(str1,"0"); break; case 2: strcpy(str1,"00.00"); break; case 3: strcpy(str1,"00.00.00"); break; case 4: strcpy(str1,"00.00.0000"); break; default: strcpy(str1,"0"); } goto end; } por=temp[7]; switch (fd) { case 1: /* DD */ if (por==0) {str1[0]=48+temp[1]/16; str1[1]=0; goto end;} /* D */ if (por==1) {str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]=0; goto end;} /* DD */ if (por==2) {str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]=48+temp[2]/16; str1[3]=0; goto end;} /*DDD = 2 года 8 мес */ if (por==3) {str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]=48+temp[2]/16; /* DDDD = 27 лет */ str1[3]=48+temp[2]%16; str1[4]=0; goto end;} break; case 2: /* DD.MM */ if (por==2) { str1[0]='0'; str1[1]=48+temp[1]/16; str1[2]='.'; str1[3]=48+temp[1]%16; str1[4]=48+temp[2]/16; str1[5]=0; goto end; } if (por==3) { str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]='.'; str1[3]=48+temp[2]/16; str1[4]=48+temp[2]%16; str1[5]=0; goto end; } break; case 3: /* DD.MM.YY */ if (por==4) { str1[0]='0'; str1[1]=48+temp[1]/16; str1[2]='.'; str1[3]=48+temp[1]%16; str1[4]=48+temp[2]/16; str1[5]='.'; str1[6]=48+temp[2]%16; str1[7]=48+temp[3]/16; str1[8]=0; goto end; } if (por==5) { str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]='.'; str1[3]=48+temp[2]/16; str1[4]=48+temp[2]%16; str1[5]='.'; str1[6]=48+temp[3]/16; str1[7]=48+temp[3]%16; str1[8]=0; goto end; } break; case 4: /* DD.MM.YYYY */ if (por==6) { str1[0]='0'; str1[1]=48+temp[1]/16; str1[2]='.'; str1[3]=48+temp[1]%16; str1[4]=48+temp[2]/16; str1[5]='.'; str1[6]=48+temp[2]%16; str1[7]=48+temp[3]/16; str1[8]=48+temp[3]%16; str1[9]=48+temp[4]/16; str1[10]=0; goto end; } if (por==7) { str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]='.'; str1[3]=48+temp[2]/16; str1[4]=48+temp[2]%16; str1[5]='.'; str1[6]=48+temp[3]/16; str1[7]=48+temp[3]%16; str1[8]=48+temp[4]/16; str1[9]=48+temp[4]%16; str1[10]=0; goto end; } break; } d2str1(); /* не удалось разобрать дату - перенести число */ end: return(re); } int time2str1(int ft) { /* Разбор времени из temp */ int re=0; int znak; int por; if (temp[0]==0x80) znak=1; else znak=0; str1[0]=0; if (temp[1]==0) { if (ft==1) strcpy(str1,"00:00:00"); else strcpy(str1,"0"); goto end; } por=temp[7]; switch (ft) { case 1: /* HH.MMSS */ if (por==0) { str1[0]='0'; str1[1]=48+temp[1]/16; str1[2]=':'; str1[3]=48+temp[1]%16; str1[4]=48+temp[2]/16; str1[5]=':'; str1[6]=48+temp[2]%16; str1[7]=48+temp[3]/16; str1[8]=0; goto end; } if (por==1) { str1[0]=48+temp[1]/16; str1[1]=48+temp[1]%16; str1[2]=':'; str1[3]=48+temp[2]/16; str1[4]=48+temp[2]%16; str1[5]=':'; str1[6]=48+temp[3]/16; str1[7]=48+temp[3]%16; str1[8]=0; goto end; } break; case 2: /* HH.HHHH - доли часа */ d2str1(); goto end; } d2str1(); end: return(re); } /*================ str2file ==============*/ int str2file(int p) { /* запись str в fp2 (TXT p==2) или str2 в fp3 (HTM p==3) */ int i,j; int re=0; if ((p<2)||(p>3)) {re=EX_SOFTWARE; goto end;} if (p==2) { for (i=0; i2) j=2; strncpy(fname[j+1],argv[i],248); if (j<2) fname_vsego++; } else { c=argv[i][1]; if (c=='-') c=argv[i][2]; /* для --help и т.п.*/ k=1; if ((c=='h')||(c=='H')||(c=='?')) { /* help */ printf("mkn2txt - converter MKN to TXT & HTM files %s",mes0); printf("mkn2txt MKNfile [key] %s",mes0); /* v0.11 */ printf("mkn2txt [-h|-v|-w] %s",mes0); printf("\t-h,-H,-?\tthis help; %s",mes0); printf("\t-v,-V\tversion; %s",mes0); printf("\t-w,-W\twarranty and copyright; %s",mes0); printf("\t-e,-E\techo on (-e0 - echo off, default); %s%s",mes0,mes0); printf("\t-p\tuse '.' (default ','); %s",mes0); printf("\t-i\tinteger if possible; %s%s",mes0,mes0); printf("\t-nN\tN - column, 1-32, default 4;%s", mes0); printf("\t-n+\t4 column and number of group;%s%s", mes0,mes0); printf("\t-d[m[y[y]]]N\tN - number of data column;%s", mes0); printf("\t-dN\tdata format DD;%s", mes0); printf("\t-dmN\tdata format DD.MM;%s", mes0); printf("\t-dmyN\tdata format DD.MM.YY;%s", mes0); printf("\t-dmyyN\tdata format DD.MM.YYYY;%s%s", mes0,mes0); printf("\t-t[h]N\tN - number of time column;%s", mes0); printf("\t-tN\ttime format HH:MM:SS (from R9055 = HH.MMSS);%s", mes0); printf("\t-thN\ttime format HH,hhhh;%s", mes0); printf(mes0); goto end; } if ((c=='v')||(c=='V')) { /* version */ printf(version); if (dos==0) printf(" (GNU/Linux)"); if (dos==1) printf(" (DOS)"); if (dos==2) printf(" (Win32)"); printf(mes0); goto end; } if ((c=='w')||(c=='W')) { /* copyleft & warranty */ printf("Copyright (C) 2011 by NPP SEMIKO (Russia, Novosibirsk) %s%s",mes0,mes0); printf("This program is free software; you can redistribute it and/or modify %s",mes0); printf("it under the terms of the GNU General Public License as published by %s",mes0); printf("the Free Software Foundation; either version 2 of the License, or %s",mes0); printf("(at your option) any later version. %s%s",mes0,mes0); printf("This program is distributed in the hope that it will be useful, %s",mes0); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of %s",mes0); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the %s",mes0); printf("GNU General Public License for more details. %s%s",mes0,mes0); printf("You should have received a copy of the GNU General Public License %s",mes0); printf("along with this program; if not, write to the Free Software %s",mes0); printf("Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"); printf(mes0); goto end; } if ((c=='n')||(c=='N')) { /* group */ if (argv[i][2]=='+') { mkn.n=4; mkn.g=1; /* записывать номер группы */ } else {mkn.n=atoi(argv[i]+2); if (mkn.n<1) mkn.n=1; if (mkn.n>32) mkn.n=32; mkn.g=0; /* не записывать номер группы*/ } k=0; } if ((c=='d')||(c=='D')) { /* group */ if ((argv[i][2]=='m')||(argv[i][2]=='m')) { if ((argv[i][2]=='y')||(argv[i][2]=='Y')) { if ((argv[i][3]=='y')||(argv[i][3]=='Y')) { mkn.d=atoi(argv[i]+5); /* DDMMYYYY */ mkn.fd=4; } else { mkn.d=atoi(argv[i]+4); /* DDMMYY */ mkn.fd=3; } } else { mkn.d=atoi(argv[i]+3); /* DDMM */ mkn.fd=2; } } else { mkn.d=atoi(argv[i]+2); /* DD */ mkn.fd=1; } if (mkn.d<0) mkn.d=0; if (mkn.d>32) mkn.d=32; k=0; } if ((c=='t')||(c=='T')) { /* group */ if ((argv[i][2]=='h')||(argv[i][2]=='H')) { mkn.t=atoi(argv[i]+3); /* HH.HHHH - час и доли часа*/ mkn.ft=2; } else { mkn.t=atoi(argv[i]+2); /*HH.MMSS - час, минуты секунды*/ mkn.ft=1; } if (mkn.t<0) mkn.t=0; if (mkn.t>32) mkn.t=32; k=0; } if ((c=='e')||(c=='E')) { /* echo */ kluch_e=1; if (argv[i][2]=='0') kluch_e=0; /* -e0 */ k=0; } if ((c=='p')||(c=='P')) { /* точка, иначе запятая */ kluch_zap=0; k=0; } if ((c=='i')||(c=='I')) { /* выводить целое без запятой или точки, если возможно */ kluch_nzap=1; k=0; } if (k!=0) {printf("mkn2txt -h for help %s",mes0); goto end;} } } nach: if (fname_vsego<=0) {re=EX_USAGE; goto end;} /* нет файла */ fp1=fopen(fname[1],"rb"); /* открыть MKN как двоичный для чтения */ if (fp1==NULL) {re=EX_NOINPUT; if (kluch_e!=0) printf("MKN not found %s",mes0); goto end;} /* файл MKN не открыт */ /* найти имя файла без расширения */ j=0; k=strlen(fname[1]); for (i=k; i>0; i--) { if (fname[1][i]=='.') {j=i; goto m1;} /* убрать текущее расширение у имени файла */ } m1: strncpy(fname[0],fname[1],248); if ((j>0)&&(j=mkn.grk) { if (kluch_e!=0) printf("MKN format error %s",mes0); re=EX_DATAERR; goto end2; } mkn.grt=mkn.grn; mkn.zapt=0; /* записать заголовок файла */ strcpy(str2,"\r\n"); strcat(str2,"
\r\n\r\n"); j=str2file(3); cicl: for (i=1; i<=mkn.n; i++) { if (i==1) {str[0]=0; /* новая строка */ str2[0]=0; if (mkn.g!=0) { sprintf(str1,"%d\t",mkn.grt); /* номер группы*/ strcat(str,str1); } strcpy(str2,"\r\n\r\n\r\n"); j=str2file(2); if (j!=0) {re=j; goto end2;} j=str2file(3); if (j!=0) {re=j; goto end2;} str[0]=0; str2[0]=0; goto cicl; end3: if (str[0]!=0) {strcat(str,"\r\n"); /*Запись последней строки TXT */ j=str2file(2); if (j!=0) {re=j; goto end2;} strcat(str2,"\r\n"); /*Запись последней строки HTM */ j=str2file(3); if (j!=0) {re=j; goto end2;} } strcpy(str2,"
"); } else {strcat(str,"\t"); /* разделить поля */ strcat(str2,""); } j=read_mkn(); if (j!=0) {if (kluch_e!=0) printf("MKN format error %s",mes0); re=EX_DATAERR; goto end2; } if (i==mkn.d) data2str1(mkn.fd); else { if (i==mkn.t) time2str1(mkn.ft); else d2str1(); } strcat(str,str1); strcat(str2,str1); str1[0]=0; mkn.zapt++; if (mkn.zapt>=4) { mkn.zapt=0; mkn.grt++; if (mkn.grt>mkn.grk) goto end3; /* последняя группа исчерпана */ } } strcat(str,"\r\n"); strcat(str2,"
\r\n\r\n"); j=str2file(3); if (j!=0) {re=j; goto end2;} end2: fclose(fp3); end4: fclose(fp2); end1: fclose(fp1); end: return (re); }