File: infoind.c

package info (click to toggle)
lie 2.2.2%2Bdfsg-1
  • links: PTS
  • area: main
  • in suites: lenny, squeeze
  • size: 952 kB
  • ctags: 1,710
  • sloc: ansic: 12,761; yacc: 395; makefile: 148; sh: 4
file content (137 lines) | stat: -rw-r--r-- 4,901 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* This program produces an index file where the indexes
   point to the text belonging to the keywords. This program
   have to be executed after each update of the file INFOFILE
*/

#include "lie.h"

#define BUFSIZE 2048

#define INDEXFIL "INFO.ind"
#define INFOFIL "INFO"

#define KEYCHAR  '@'
#define NEWLINE  '\n'
#define OPEN '('
#define CLOSE ')'

objtype type_code(char* name)
{ if (!strncmp(name, "int",3)) return (INTEGER);
  if (!strncmp(name, "vec",3)) return (VECTOR);
  if (!strncmp(name, "mat",3)) return (MATRIX);
  if (!strncmp(name, "grp",3)) return (GROUP);
  if (!strncmp(name, "vid",3)) return (VOID);
  if (!strncmp(name, "tex",3)) return (TEKST);
  if (!strncmp(name, "bin",3)) return (BIGINT);
  if (!strncmp(name, "pol",3)) return (POLY);
  return (ERROR);
}

static void make_key(char* start,char* key)
{ if (strlen(start) >= KEYWORDLEN)
  { strncpy(key,start,KEYWORDLEN-1); key[KEYWORDLEN-1] = '\0';
    printf("Key \"%s\" truncated\n to \"%s\".\n",start,key);
  }
  else strcpy(key,start);
}

/* scan any parents specified after CLOSE in heading of function */
static void add_parents(char* start,info_index_tp* inf)
{ int i=0; char* pt=strchr(start,KEYCHAR); char key[KEYWORDLEN];
  if (start[0]=='\0') /* NEWLINE directly after CLOSE */
    { inf->directory=false; inf->parents.n=0; return; }
  if (pt==start) /* KEYCHAR directly after CLOSE */
    { inf->directory=true;  inf->parents.n=0; return; }
  while (i<N_PARENTS && pt!=NULL)
  { *pt='\0'; /* replace KEYCHAR by '\0' */
    make_key(start,key); strcpy(inf->parents.p[i++],key);
    pt=strchr(start=pt+1,KEYCHAR);
  }
  if (strlen(start)>0)
    /* last name not followed by KEYCHAR: the key is not a dir */
  { if (i<N_PARENTS)
    { make_key(start,key); strcpy(inf->parents.p[i],key);
      inf->directory=false; ++i;
    }
    else
    { printf("Maximum number of parents (=%d) exceeded.\n",i); exit(1); }
  }
  else inf->directory=true;
  inf->parents.n=i;
}

int main(void)
{ char indexfil[LABELLENGTH];
  char infofil[LABELLENGTH];
  char buf[BUFSIZE+1];
  char key[KEYWORDLEN];
  long number_chars_read;
  int i,count=0;
  FILE *indexpt,*infopt;
  info_index_tp info; /* current info record */

  strcpy(indexfil,INDEXFIL);
  indexpt=fopen(indexfil,writemode);
  if (indexpt==NULL)
    { printf("File %s cannot be written.\n",indexfil); exit(1); }
  for (i=0; i<MAX_INFO_FILES; ++i) /* traverse INFO files */
  { char* bufpt=buf,* bufpt_newline=buf,* bufpt_open=buf,* bufpt_close=buf;
    long file_adress=0; /* offset of start of current buffer in file */
    sprintf(infofil,"%s.%d",INFOFIL,i);
    if ((infopt=fopen(infofil,readmode))==0)
      if (i==0) { printf("File %s cannot be read.\n",infofil); exit(1); }
      else continue; /* skip non-existent INFO files after INFO.0 */
    printf("Indexing file '%s'.\n",infofil);
/* repeatedly read in a buffer: */
    while (  !feof(infopt)
	  && fseek(infopt,file_adress,0)==0 /* read on after prev item */
	  && (number_chars_read=fread(buf,sizeof(*buf),BUFSIZE,infopt))!=0
	  )
    { long location_start= -1, location_end= -1; /* offsets into buffer */
      buf[number_chars_read]='\0';
      while (  (bufpt=strchr(bufpt,KEYCHAR))!=0
	    && bufpt_newline!=NULL && bufpt_close!=NULL && bufpt_open!=NULL )
      { location_end=bufpt-buf; /* offset of next key into buffer */
	if (location_start>=0) /* skip the first time around */
	{ strcpy(info.keyword,key);
	  info.start=file_adress+location_start;
	  info.size =location_end-location_start;
	  info.seq=i; count++;
	  fwrite(&info,sizeof(info_index_tp),1,indexpt); /* write record */
	}
/* Scan for new key. Pattern: ... ( ... ) ... \n */
	if (  (bufpt_open=strchr(bufpt,OPEN))==NULL
	   || (bufpt_close=strchr(bufpt_open,CLOSE))==NULL
	   || (bufpt_newline=strchr(bufpt,NEWLINE))==NULL
	   ) continue; /* no complete header line present in buffer */
	*bufpt_open='\0'; make_key(bufpt+1,key); *bufpt_open=OPEN;
	bufpt=bufpt_open;
	if (bufpt[1]==CLOSE) { info.narg=0; bufpt++; } /* @f() */
	else /* scan types */ 
	{ int k=0;
	  while (k<6 && (*bufpt!=CLOSE))
	  { info.t[k++]=type_code(++bufpt); bufpt=(bufpt+3); }
	    /* each type has EXACTLY 3 characters, separator is not read */
	  info.narg=k;
	}
	if (*bufpt != CLOSE)
	{ printf("Too many arguments (=%d) found for %s\n"
		,info.narg,key);
	  exit(1);
	}
	bufpt=bufpt_newline+1;
	location_start=bufpt-buf; /* advance to next line */
	do --bufpt_newline; while (isspace(*bufpt_newline)); /* erases CR */ 
	*++bufpt_newline='\0';
	add_parents(bufpt_close+1,&info);
      } /* end of key scanning loop */
      file_adress=file_adress + location_end;
      bufpt_newline=bufpt=bufpt_close=bufpt_open=buf;
      if (number_chars_read<BUFSIZE) break;
    } /* end of buffer reading loop */
    fclose(infopt);
  } /* end of loop over info files */
  printf("End of indexing. Final key '%s'.\nWrote %d info entries.\n"
	,key,count);
  return 0;
}