source: src/common/common.h @ d6a59ca

Last change on this file since d6a59ca was 5f4d9c3, checked in by Maciej Prill <mprill@…>, 13 years ago

Rewritten the build system, added lem UTF-8 version.

  • Property mode set to 100644
File size: 10.4 KB
Line 
1#ifndef __COMMON_H
2#define __COMMON_H
3
4#include <cstdio>
5#include <cctype>
6#include <cstring>
7#include <cstdlib>
8
9#include <cwchar>
10#include <cwctype>
11
12#include "../lib/const.h"
13
14#ifndef _CMDLINE_FILE
15#error _CMDLINE_FILE constant not defined!
16#else
17#include _CMDLINE_FILE
18#endif
19
20
21/**************************************************
22 * Stale dotyczace wejscia/wyjscia
23 */
24
25#define EMPTYFORM '*'
26#define INFIELD_SEP ':'
27#define MAXAUX 16
28#define FIELD_SEP " \t\n"
29#define FIELD_PREFIX_MAXLEN 32
30
31
32// katalogi z plikami konfiguracyjnymi
33// nowe
34// stare - do wyrzucenia
35// #define CONFIG_DIR ".utt/conf"
36
37// nazwa zmiennej okreslajaca sciezke do danych
38
39// #define UTT_DIR_VAR "UTT_DIR"
40
41// sciezka do plikow z danymi (np UTT_DIR/pliki) wzgledem $HOME!
42
43// #define UTT_DIR_DEFAULT ".utt/pl/"
44
45/**************************************************/
46
47
48extern FILE* inputf;
49extern FILE* outputf;
50extern FILE* failedf;
51
52extern char* input_filename;
53extern char* output_filename;
54extern char* failed_filename;
55extern bool one_line;
56extern bool one_field;
57
58extern char input_field_prefix[];
59extern char output_field_prefix[];
60
61extern bool copy_processed;
62extern bool append_output;
63extern bool append_failed;
64
65//sciezka do katalogu z danymi
66extern char utt_dir[];
67
68extern void process_common_options(gengetopt_args_info* args, char* argv0);
69extern void process_config_files(gengetopt_args_info* args, char* argv0);
70
71extern int expand_path(char* inpath, char* outpath);
72
73/**************************************************
74 * problems with casing                           */
75// sprawdzenie wielkosci liter
76// warto¶Ê zwracana:
77// 0 - wszystkie ma³e litery
78// 1 - pierwsza wielka, reszta male
79// 2 - wszystkie wielkie
80// 3 - inne
81inline int casing(char* s)
82{
83  int ret = isupper(*s) ? 1 : 0;
84  while(*++s != '\0')
85  {
86    if(isupper(*s))
87    {
88      if(ret==1) ret=2;
89      else if(ret==0) ret=3;
90    }
91    else
92    {
93      if(ret==2) ret=3;
94    }
95  }
96  return ret;
97}
98
99//
100inline void tolowers(char* s, char* d)
101{
102  *d=tolower(*s);
103  while(*s != '\0') * ++d = tolower(* ++s);
104}
105
106
107// przepisuje s do d
108// nadajac wielko¶Ê liter zgodnie z warto¶ci± casing
109// casing - warto¶Ê zwracana przez casing()
110// je¶li casing==3 przepisuje bez zmian (za ma³o informacji)
111inline void restorecasing(char *s, char *d, int casing)
112{
113  switch(casing)
114  {
115  case 0:
116  case 3:
117    *d=*s;
118    while(*s != '\0') * ++d = * ++s;
119    break;
120  case 1:
121    *d=toupper(*s);
122    while(*s != '\0') * ++d = * ++s;
123    break;
124  case 2:
125    *d=toupper(*s);
126    while(*s != '\0') * ++d = toupper(* ++s);
127    break;
128  }
129}
130
131/**************************************************/
132
133/*
134parameters:
135  -seg  - segment
136  -pref - field name or "1", "2", "3", "4" for the first four fields
137  +val  - field contents
138return value:
139  1 if specified field exists, 0 otherwise
140*/
141
142inline int getfield(char* seg, const char* pref, char* val)
143{
144
145  char* p=seg;
146  char* p0;
147
148  while(isspace(*p)) ++p;
149
150  // field "1"
151  p0=p; while(isdigit(*p)) ++p;
152  if(*pref=='1') if(p!=p0) { strncpy(val,p0,p-p0); val[p-p0]='\0'; return 1; } else return 0;
153 
154  while(isspace(*p)) ++p;
155
156  // field "2"
157  p0=p; while(isdigit(*p)) ++p;
158  if(*pref=='2') if(p!=p0) { strncpy(val,p0,p-p0); val[p-p0]='\0'; return 1; } else return 0;
159
160  while(isspace(*p)) ++p;
161
162  // field "3"
163  p0=p; while(isgraph(*p)) ++p; 
164  if(*pref=='3') if(p!=p0) { strncpy(val,p0,p-p0); val[p-p0]='\0'; return 1; } else return 0;
165
166  while(isspace(*p)) ++p;
167
168  // field "4"
169  p0=p; while(isgraph(*p)) ++p;
170  if(*pref=='4') if(p!=p0) { strncpy(val,p0,p-p0); val[p-p0]='\0'; return 1; } else return 0;
171
172  while(isspace(*p)) ++p;
173
174  // annotation fields
175  do p=strstr(p,pref); while(p!=NULL && *(p-1)!=' ' && *(p-1)!='\t');
176 
177  if(p==NULL) return 0;
178  else
179  {
180    p+=strlen(pref);
181    int len=strcspn(p,FIELD_SEP "\n\r\f\0");
182    strncpy(val,p,len);
183    val[len]='\0';
184    return 1;
185  }
186}
187
188inline int getfield(wchar_t* seg, const wchar_t* pref, wchar_t* val)
189{
190
191  wchar_t* p=seg;
192  wchar_t* p0;
193  while(iswspace(*p)) ++p;
194
195  // field "1"
196  p0=p; while(iswdigit(*p)) ++p;
197  if(*pref==L'1') 
198    if(p!=p0) 
199    { 
200      wcsncpy(val,p0,p-p0); 
201      val[p-p0]=L'\0'; 
202      return 1; 
203    } 
204    else 
205      return 0;
206  while(iswspace(*p)) ++p;
207 
208// field "2"
209  p0=p; while(iswdigit(*p)) ++p;
210  if(*pref==L'2') if(p!=p0) { wcsncpy(val,p0,p-p0); val[p-p0]=L'\0'; return 1; } else return 0;
211  while(iswspace(*p)) ++p;
212  // field "3"
213  p0=p; while(iswgraph(*p)) ++p; 
214  if(*pref==L'3') if(p!=p0) { wcsncpy(val,p0,p-p0); val[p-p0]=L'\0'; return 1; } else return 0;
215
216  while(iswspace(*p)) ++p;
217  p0=p; while(iswgraph(*p)) ++p;
218
219  if(*pref==L'4') if(p!=p0) { wcsncpy(val,p0,p-p0); val[p-p0]=L'\0'; return 1; } else return 0;
220  while(iswspace(*p)) ++p;
221
222  // annotation fields
223  do p=wcsstr(p,pref); while(p!=NULL && *(p-1)!=L' ' && *(p-1)!=L'\t');
224  if(p==NULL) return 0;
225  else
226  {
227    p+=wcslen(pref);
228    int len=wcscspn(p,FIELD_SEP L"\n\r\f\0");
229    wcsncpy(val,p,len);
230    val[len]=L'\0';
231    return 1;
232  }
233}
234
235/*
236parameters:
237        -name - field name, long or short
238        +prefix - field name with ':' appended if long name
239return value:
240        1 if correct field name, 0 otherwise
241examples:
242name    prefix  r.v.
243lem     lem:    1
244@       @       1
245::      'undef' 0
246a,b     'undef' 0
247*/
248inline
249int fieldprefix(char *name, char *prefix)
250{
251  if (ispunct(name[0]) && name[1]=='\0') // correct short name
252  {
253    strcpy(prefix, name); return 1;
254  }
255
256  int i=0;
257  while(name[i]!='\0' && isalnum(name[i])) ++i;
258 
259  if(name[i]=='\0' && i>0) // correct long name
260  {
261    sprintf(prefix,"%s:",name); return 1;
262  }
263
264  // incorrect
265  return 0;
266}
267
268inline
269bool process_seg(char* seg, gengetopt_args_info& args)
270{
271  char buf[256];
272  char pref[FIELD_PREFIX_MAXLEN];
273  bool ret = !args.process_given;
274  if(args.process_given)
275    {
276      getfield(seg,"3",buf);
277      for(int i=0; i<args.process_given; ++i)
278        if(strcmp(args.process_arg[i],buf)==0)
279          {
280            ret=true;
281            break;
282          }
283    }
284
285  if(ret==false) return false; 
286
287  for(int i=0; i<args.select_given; ++i)
288    {
289      fieldprefix(args.select_arg[i],pref); // !!! ŁATKA - ZOPTYMALIZOWAĆ !!!
290      if(! getfield(seg,pref,buf))
291        return false;
292    }
293  for(int i=0; i<args.ignore_given; ++i)
294    {
295      fieldprefix(args.ignore_arg[i],pref);  // !!! ŁATKA - ZOPTYMALIZOWAĆ !!!
296      if(getfield(seg,pref,buf))
297        return false;
298    }
299 
300  if(args.input_field_given & !getfield(seg,input_field_prefix,buf))
301    return false;
302
303  return true;
304}
305
306
307/*
308parameters:
309  -+seg - segment
310  -pref - prefix of the new field
311  -val  - contents of the new field
312return value:
313  1 - success, 0 - fail (limit on segment length exceeded)
314 */
315inline
316int addfield(char *seg, const char *pref, const char *val)
317     // zalozenie, ze seg konczy sie znakiem \n
318{
319  if(strlen(seg)+strlen(pref)+strlen(val) >= MAX_LINE) return 0; // bezpieczniej, ale wolniej
320
321  int seglen=strlen(seg);
322  sprintf(seg+(seglen-1)," %s%s\n",pref,val);
323  return 1;
324}
325
326/**************************************************/
327
328struct Seg
329{
330  int filepos, len;
331  char* tag;
332  char* form;
333  char* aux[MAXAUX];
334  int auxn;
335
336  bool parse(char* line);
337  char* getfield(char* fieldname);
338  void print(char* line);
339  bool addfield(char* s);
340  bool clearfields();
341};
342
343/**************************************************/
344
345/* definicja struktury wejscia/wyjscia
346 */
347struct Segment
348{
349  int filepos, len;
350  char* tag;
351  char* form;
352  char* aux[MAXAUX];
353  int auxn;
354
355  bool parse(char* line);
356  char* getfield(char* fieldname);
357  void print(char* line);
358  bool addfield(char* s);
359  bool clearfields();
360};
361
362/*
363 * Sprawdza czy nalezy przetwarzac dany segment.
364 */
365
366inline
367bool process_seg(Segment& s, gengetopt_args_info& args)
368{
369  bool ret = !args.process_given;
370
371  for(int i=0; i<args.process_given; ++i)
372    if(strcmp(args.process_arg[i],s.tag)==0)
373      {
374        ret=true;
375        break;
376      }
377
378  for(int i=0; i<args.select_given; ++i)
379    if(! s.getfield(args.select_arg[i]))
380      ret=false;
381
382  for(int i=0; i<args.ignore_given; ++i)
383    if(s.getfield(args.ignore_arg[i]))
384      ret=false;
385
386  return ret;
387}
388
389
390/*
391 * FUNKCJE OBSLUGUJACE WEJSCIE/WYJSCIE
392 */
393// napisy zostaj na miejscu (w line), tylko wskazniki sa ustawian
394// i zara dopisywane zera s dopisywane
395
396inline
397bool Segment::parse(char* line)
398{
399  auxn=0;
400  char* field;
401  if((field=strtok(line,FIELD_SEP))!=NULL)
402    filepos=atoi(field); // nie sprawdzana poprawnosc
403  else
404    return false;
405  if((field=strtok(NULL,FIELD_SEP))!=NULL)
406    len=atoi(field); // nie sprawdzana poprawnosc
407  else return false;
408  if((tag=strtok(NULL,FIELD_SEP))==NULL) return false;
409  if((form=strtok(NULL,FIELD_SEP))==NULL)
410    return true;
411  else
412    if(form[0] == EMPTYFORM && form[1] =='\0')
413      form=NULL;
414
415  while((aux[auxn]=strtok(NULL,FIELD_SEP))!=NULL) ++auxn;
416
417  return true;
418}
419
420
421inline char* Segment::getfield(char* f)
422{
423  int flen=strlen(f);
424  if(isalnum(*f))
425  {
426    for(int i=0; i<auxn; ++i)
427      if(strncmp(aux[i],f,flen)==0 && aux[i][flen]==INFIELD_SEP)
428        return aux[i]+flen+1;
429  } else
430  {
431    for(int i=0; i<auxn; ++i)
432    {
433      if(*f==*(aux[i]))
434        return aux[i]+1;
435    }
436  }
437  return NULL;
438}
439
440inline bool Segment::clearfields() {
441  for (int i=0; i<auxn; ++i) {
442    //    free(aux[i]);
443    aux[i] = NULL;
444  }
445  auxn=0;
446  return true;
447}
448
449inline // NIEEFEKTYWNE
450void Segment::print(char* line)
451{
452  sprintf(line,"%04d %02d %s", filepos, len, tag);
453  if(form)
454    {
455      strcat(line," ");
456      strcat(line,form);
457    }
458  else
459    if(auxn)
460      strcat(line," *");
461
462  for(int i=0; i<auxn; ++i)
463    {
464      strcat(line," ");
465      strcat(line,aux[i]);
466    }
467
468  strcat(line,"\n");
469}
470
471
472inline
473bool Segment::addfield(char* s)
474{
475  if(auxn<MAXAUX)
476    {
477      aux[auxn++]=s;
478      return true;
479    }
480  else
481    return false;
482}
483
484/**************************************************
485 * funkcje pomocne w operacjach na plikach        *
486 *  konfiguracyjnych                              *
487 **************************************************/
488
489// sprawdza istnienie pliku
490int file_accessible(const char* path);
491
492// sprawdza istnienie pliku konfiguracyjnego
493int config_file(const char* dir, const char* filename);
494
495/**************************************************/
496
497/* Pobiera wejscie
498 * parametry:
499 * - args - tablica stringow okresnajacych pola wejsciowe
500 * - args_len - rozmiar args
501 * - seg - segment
502 * wartosc - wskaznik do wejscia
503 */
504inline char*  getInput(char** args, int args_len, Segment seg) {
505  char* formp = NULL;
506  for (int i=0; i<args_len; ++i) {
507    if ('4' == args[i][0])
508      return seg.form;
509    if ((formp = seg.getfield(args[i])) != NULL) {
510      return formp;
511    }
512  }
513  return formp;
514}
515
516#endif
Note: See TracBrowser for help on using the repository browser.