~ubuntu-branches/ubuntu/hardy/openthesaurus/hardy

« back to all changes in this revision

Viewing changes to wordtree.c

  • Committer: Bazaar Package Importer
  • Author(s): Rene Engelhard
  • Date: 2005-02-16 22:04:11 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050216220411-lvs2pn0q9e19aj0m
Tags: 20041231-2
* add script to permutate the input lines, thescoder wants to
  have each meaning at least defined on an own line in the first
  part, many thanks to Maik Zumstrull for the script.
* postprocess the idx files to "fix" e.g. the Pi and "eulersche Zahl"
  synonyms by subsituting the (right) , with . since , is the delimiter
  in the index file format...

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  wordtree.c - Routines to manage word tree and synonimous list
 
3
 *
 
4
 *  Copyright (C) 2003 Giuseppe Modugno
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 */
 
20
 
 
21
 
 
22
#include <stdio.h>
 
23
#include <string.h>
 
24
#include <stdlib.h>
 
25
#include "wordtree.h"
 
26
 
 
27
 
 
28
/* Internal function prototypes. */
 
29
void write_bigend( FILE *f, unsigned int n );
 
30
void wordtree_output_idx( WTelem *tree, FILE *idx );
 
31
void wordtree_output_dat( WTelem *tree, FILE *dat );
 
32
 
 
33
 
 
34
 
 
35
WTelem *
 
36
wordtree_add( char *word, WTelem **tree )
 
37
{
 
38
  /* Add an element in the tree, maintaining alphabetic order of words.
 
39
   * Return the new allocated element in the tree.
 
40
   * If word exists, return the tree element present in tree without
 
41
   * allocating another element. */
 
42
  int cmp;
 
43
  
 
44
  if( *tree==NULL ) {
 
45
    /* Create a new element in the tree. */
 
46
    if( (*tree=(WTelem *)malloc(sizeof(WTelem)))==NULL )
 
47
      return(NULL);
 
48
    /* Copy string. */
 
49
    (*tree)->word = strdup( word );
 
50
    /* Set default status for the word. */
 
51
    (*tree)->synlist = NULL;
 
52
    (*tree)->num_syn = 0;
 
53
    (*tree)->left = NULL;
 
54
    (*tree)->right = NULL;
 
55
    (*tree)->isword = 0;
 
56
    return(*tree);
 
57
  }
 
58
  
 
59
  if( (cmp=strcmp(word,(*tree)->word))>0 )
 
60
    return wordtree_add(word,&(*tree)->right);
 
61
  else if( cmp<0 )
 
62
    return wordtree_add(word,&(*tree)->left);
 
63
  else
 
64
    return(*tree);              /* Word is present in the tree. */
 
65
}
 
66
 
 
67
 
 
68
 
 
69
SLelem *
 
70
synlist_add( WTelem *word, WTelem *syn )
 
71
{
 
72
  /* Add synonimous syn to the word word. */
 
73
  SLelem **list=&(word->synlist);
 
74
  SLelem *new;
 
75
  int cmp;
 
76
 
 
77
  /* Check if synonimous <syn> is the first of the list. */
 
78
  if( (*list==NULL) || (cmp=strcmp( syn->word, (*list)->syn->word ))<0 ) {
 
79
    /* Add synonimous <syn> as the first element of the list. */
 
80
    if( (new=(SLelem *)malloc(sizeof(SLelem)))==NULL )
 
81
      return(NULL);
 
82
    new->syn = syn;
 
83
    new->next = *list;
 
84
    word->num_syn++;
 
85
    return( *list=new );
 
86
  }
 
87
  if( !cmp ) {
 
88
    /* First element of synonimous list is equal to the new synonimous. */
 
89
    fprintf( stderr, "Warning: synonimous %s yet added to word %s\n", syn->word, word->word );
 
90
    return( *list );
 
91
  }
 
92
 
 
93
  /* Go down to the list up to the element alphabetically previous of new
 
94
   * synonimous <syn>. */
 
95
  while( ((*list)->next!=NULL) && (cmp=strcmp(syn->word,(*list)->next->syn->word))>0 )
 
96
    list = &((*list)->next);
 
97
  if( !cmp ) {
 
98
    /* Found the same synonimous in the list. */
 
99
    fprintf( stderr, "Warning: synonimous %s yet added to word %s\n", syn->word, word->word );
 
100
    return( (*list)->next );
 
101
  }
 
102
 
 
103
  /* Allocate new element list. */
 
104
  if( (new=(SLelem *)malloc(sizeof(SLelem)))==NULL )
 
105
    return(NULL);
 
106
  new->syn = syn;
 
107
  new->next = (*list)->next;
 
108
  word->num_syn++;
 
109
 
 
110
  /* Add new element to the list. */
 
111
  return( (*list)->next=new );
 
112
}
 
113
 
 
114
 
 
115
 
 
116
void
 
117
wordtree_output_idx( WTelem *tree, FILE *idx )
 
118
{
 
119
  /* Write output .idx files. */
 
120
  static unsigned int index=0;
 
121
  static unsigned int dat_offset=0;
 
122
  
 
123
  if( tree->left!=NULL )
 
124
    wordtree_output_idx( tree->left, idx );
 
125
  
 
126
  tree->index = index++;
 
127
  /* Write word and offset of dat file to idx file. */
 
128
  fprintf( idx, "%s,%u\n", tree->word, dat_offset );
 
129
  dat_offset += 2+(tree->num_syn<<1);
 
130
  
 
131
  if( !tree->isword )
 
132
    fprintf( stderr, "Warning: Word %s is only a synonimous\n", tree->word );
 
133
  if( !tree->num_syn )
 
134
    fprintf( stderr, "Warning: Word %s has no synonimous\n", tree->word );
 
135
 
 
136
  if( tree->right!=NULL )
 
137
    wordtree_output_idx( tree->right, idx );
 
138
  
 
139
}
 
140
 
 
141
 
 
142
 
 
143
void
 
144
wordtree_output_dat( WTelem *tree, FILE *dat )
 
145
{
 
146
  /* Write output .dat files. */
 
147
  SLelem *sle;
 
148
  static unsigned int dat_offset = 0;
 
149
  
 
150
  if( tree->left!=NULL )
 
151
    wordtree_output_dat( tree->left, dat );
 
152
  
 
153
  write_bigend( dat, tree->num_syn );
 
154
  dat_offset += 2;
 
155
  sle = tree->synlist;
 
156
  while( sle!=NULL ) {
 
157
    write_bigend( dat, sle->syn->index );
 
158
    dat_offset += 2;
 
159
    sle = sle->next;
 
160
  }
 
161
  
 
162
  if( tree->right!=NULL )
 
163
    wordtree_output_dat( tree->right, dat );
 
164
  
 
165
}
 
166
 
 
167
 
 
168
void
 
169
wordtree_output( WTelem *tree, FILE *idx, FILE *dat )
 
170
{
 
171
  /* Write output .idx and .dat files. */
 
172
  
 
173
  /* It's important to write .idx file first because
 
174
   * write_output_idx() enumerate words too and index
 
175
   * is used by write_output_dat() routine. */
 
176
  wordtree_output_idx( tree, idx );
 
177
  wordtree_output_dat( tree, dat );
 
178
}
 
179
 
 
180
 
 
181
void
 
182
write_bigend( FILE *f, unsigned int n )
 
183
{
 
184
  /* Write number n to file f as a 16-bit Big Endian format. */
 
185
  fprintf( f, "%c", (unsigned char)((n&0xFF00)>>8) );
 
186
  fprintf( f, "%c", (unsigned char)(n&0x00FF) );
 
187
}
 
188
 
 
189
 
 
190
 
 
191
void
 
192
wordtree_free( WTelem *tree )
 
193
{
 
194
  /* Free tree memory. */
 
195
  SLelem *sle, *stmp;
 
196
  
 
197
  if( tree->left!=NULL )
 
198
    wordtree_free( tree->left );
 
199
  
 
200
  if( tree->right!=NULL )
 
201
    wordtree_free( tree->right );
 
202
  
 
203
  /* Free synonimous list of that word. */
 
204
  sle = tree->synlist;
 
205
  while( sle!=NULL ) {
 
206
    stmp = sle->next;
 
207
    free(sle);
 
208
    sle = stmp;
 
209
  }
 
210
  
 
211
  /* Free tree element. */
 
212
  free(tree);
 
213
  
 
214
}