]> www.wagner.pp.ru Git - oss/fgis.git/blob - epu/intable.c
First checked in version
[oss/fgis.git] / epu / intable.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <unistd.h>
6 #include <getopt.h>
7 #include "epp.h"
8 #include "eppl_ut.h"
9 struct record {
10                unsigned short int outclass;
11                unsigned short int classes[32];
12               };
13 typedef struct record *rec;
14
15 void help(int exitcode)
16 { printf("Usage: intable [-%%] [-i] [-o file] [-f file] [-O value] [-u value] files\n");
17   exit(exitcode);
18 }
19
20 short int* table;
21
22 EPP *files[32];
23 char skip[32]={0,0,0,0,0,0,0,0,
24                0,0,0,0,0,0,0,0,
25                0,0,0,0,0,0,0,0,
26                0,0,0,0,0,0,0,0,};
27 int files_count,count,limit,delta;
28 int skip_count=0;   
29 char delimiter=',';
30
31 int offsite=-1;
32 int unmatched=-1;
33
34 int compare(struct record *r1, struct record *r2)
35 {int i; 
36  for (i=0;i<files_count;i++)
37  { if (r1->classes[i]>r2->classes[i]) return 1;
38    else
39    if (r1->classes[i]<r2->classes[i]) return -1;
40  }
41  return 0;
42
43 }
44 int search(struct record *key,int *index)
45 {int l=0,h=count-1,i,c;
46  while(l<=h)
47  { i=(l+h)>>1;
48    c=compare((struct record *)(table+(1+files_count)*i),key);
49    if (c<0) l=i+1;
50    else
51    { h=i-1;
52      if (!c) { *index=i;return 1;}
53    }
54   } 
55  *index=l;
56  return 0;
57 }
58 void insert(struct record *key,int index)
59 { int i;unsigned short int *l;
60   if (count==limit)
61   {  
62      table=realloc(table,(limit+=delta)*(1+files_count)*sizeof(short int));
63      if (!table)
64      { fprintf(stderr,"Couldn't realloc table. Table limit is %d\n",limit);
65        exit(1);
66      }
67    }
68
69  for(i=count;i>index;i--)
70   memcpy(table+(i)*(1+files_count),table+(i-1)*(1+files_count),
71   (1+files_count)*sizeof(short int)); 
72  l=(unsigned short int *)(table+index*(1+files_count));
73  memcpy(l,key,(files_count+1)*sizeof(short int));
74  count++;
75
76 void setvalue(int index,int value)
77 {
78  unsigned short int *l=(unsigned short int *)(table+index*(1+files_count));
79  *l=value;
80 }
81 int lineno=0;
82 int add_record(FILE *f)
83 { /* ÷ÏÚ×ÒÁÝÁÅÔ 0, ÅÓÌÉ ÔÁËÁÑ ËÏÍÂÉÎÁÃÉÑ ÕÖÅ ÅÓÔØ*/
84   struct record tmp;
85   char *endptr;
86   char line[256];
87   int i,v,j;
88   endptr=fgets(line,256,f);
89   if (!endptr) return 1;
90   lineno++;
91   for(i=0,j=0;i<files_count+skip_count;i++)
92   { v=strtol(endptr,&endptr,0);
93     while(*endptr==' '||*endptr=='\t') endptr++;
94     if (*endptr!=delimiter&&!(isdigit(*endptr)&&delimiter==' '))
95     { fprintf(stderr,"Invalid line %d in table. Error at char %d\n",
96       lineno,endptr-line);
97       exit(2);
98     }
99     if (*endptr==delimiter) 
100       endptr++; 
101     if (*endptr=='\n') 
102      { fprintf(stderr,"Not enough values in line %d:%d instead of%d\n",
103          lineno,i+1,files_count+1);
104        exit(2);
105      }
106     /* if ((v<files[i]->min||v>files[i]->max)&&v!=files[i]->offsite) */
107     if (v<0||v>65535) 
108      { fprintf(stderr,"Illegal value %d in column %d of line %d\n",
109         v,i+1,lineno);
110        exit(2);
111      } 
112     if (!skip[i])  
113     tmp.classes[j++]=v;
114   }
115   v=strtol(endptr,&endptr,0);
116   while (*endptr==' '||*endptr=='\t')endptr++;
117   if(*endptr!='\n')
118   { fprintf(stderr,"Extra data in line %d\n",lineno);
119     exit(2);
120   }
121     if (v<0||v>65535) 
122      { fprintf(stderr,"Illegal value %d in column %d of line %d\n",
123         v,files_count+1,lineno);
124        exit(2);
125      }   
126   tmp.outclass=v;
127   if (v>255) Create16bit=1;
128   if (search(&tmp,&i))
129   { setvalue(i,v); return 0;}
130   else
131   { insert(&tmp,i); return 1;}
132 }
133
134 int make_cell(int x,int y,int value)
135 { struct record tmp;
136   int i;EPP **epp;
137   for(i=0,epp=files;i<files_count;tmp.classes[i++]=epp_get(*(epp++),x,y));
138   if (search(&tmp,&i))
139    return *((unsigned short int *)(table+i*(1+files_count)));
140   else
141    return unmatched;
142 }
143
144 int getclass(const char *s)
145
146 {char *endptr;
147  int tmp=strtol(s,&endptr,0);
148  if (*endptr||tmp<0||tmp>65535) 
149   { fprintf(stderr,"Invalid class value %s\n",s);
150     exit(2);
151   }
152  return tmp;
153 }
154    
155 int main(int argc,char **argv)
156 { struct option long_options[]={
157 {"help",0,0,1},
158 {"version",0,0,2},
159 {"verbose",0,0,'%'},
160 {"delimiter",1,0,'d'},
161 {"input-file",1,0,'f'},
162 {"output-file",1,0,'o'},
163 {"offsite",1,0,'O'},
164 {"unmatched",1,0,'u'},
165 {"skip",1,0,3},
166 {"ignore-dupes",0,0,'i'},
167 {NULL,0,0,0}
168 };
169 char outname[1024]="intable.out.epp";
170 int index,c,i;
171 int ignore_dupes=0,verbose=0;
172 FILE *f=stdin;
173 EPP *new_file,**epp;
174 while ((c=getopt_long(argc,argv,"%iu:d:f:o:O:129456789",
175          long_options,&index))!=-1)
176 switch(c)
177 {case 2:show_version("intable","$Revision: 1.1 $");
178  case '%':verbose=1;break;
179  case 'd':delimiter=optarg[0];break;
180  case 'f':if (!(f=fopen(optarg,"r")))
181      { fprintf(stderr,"Cannot open file %s\n",optarg);
182        exit(2);
183      } break;
184   case 'o':strcpy(outname,default_ext(optarg,".epp"));break;
185   case 'O':offsite=getclass(optarg);
186       break;
187   case 'u':unmatched=getclass(optarg);break;
188   case 'i':ignore_dupes=1;break;
189   case '?':
190   case '1': case '2': case '3': case '4': case '5': case '6': case '7':
191   case '8': case '9':
192           skip_count++;
193           skip[c-'1']=1;
194           break;
195   case 3:{char *endptr;
196          i=strtol(optarg,&endptr,0);
197          if (*endptr||i<1||i>32) 
198          { fprintf(stderr,"Invalid column number %s\n",optarg); 
199            exit(2);
200          }
201          skip_count++;
202          skip[i]=1;
203          break;
204         }
205   case 1:
206   default:
207       help(c==1);
208
209   }
210  files_count=argc-optind;
211  table=malloc(65536*sizeof(short)*(files_count+1));
212  limit=65536;
213  delta=1024;
214  count=0;
215  epp=files;
216  for(i=0,index=optind;i<files_count;i++,index++,epp++)
217  {if (!(*epp=open_epp(default_ext(argv[index],".epp"))))
218   { fprintf(stderr,"Cannot open file %s\n",default_ext(argv[index],".epp"));
219     exit(2);
220   }
221   if(i&&!is_aligned(*files,*epp))
222   { fprintf(stderr,"File %s is incompatible with %s\n",
223      argv[optind],argv[index]);
224      exit(2);
225   }
226  }
227  while (!feof(f))
228  { if(!ignore_dupes && !add_record(f))
229    {fprintf(stderr,"Duplicated lines in table\n");
230      exit(2);
231    }
232  }
233  printf("%d lines read. %d values used\n",lineno,count);
234  if (offsite==-1) offsite=Create16bit?65535:255;
235  if (unmatched==-1) unmatched=offsite;
236  if (!(new_file=creat_epp_as(outname,*files)))
237  { fprintf(stderr,"Cannot create file %s\n",outname);
238    exit(2);
239  }
240  new_file->offsite=offsite;
241  install_progress_indicator(verbose?show_percent:check_int);
242  if ((i=clear_progress(for_each_cell(new_file,make_cell))))
243   unlink(outname);
244  if (!Create16bit||new_file->max>255)
245    close_epp(new_file);
246  else
247   {unlink(outname);
248    fast_convert_to_8bit(new_file,outname); 
249   }
250  
251 return abs(i);
252 }