rino 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/README +44 -0
  2. data/Rakefile +123 -0
  3. data/ext/extconf.rb +26 -0
  4. data/ext/ruby_inchi_main.so +0 -0
  5. data/ext/src/aux2atom.h +2786 -0
  6. data/ext/src/comdef.h +148 -0
  7. data/ext/src/e_0dstereo.c +3014 -0
  8. data/ext/src/e_0dstereo.h +31 -0
  9. data/ext/src/e_comdef.h +57 -0
  10. data/ext/src/e_ctl_data.h +147 -0
  11. data/ext/src/e_ichi_io.c +498 -0
  12. data/ext/src/e_ichi_io.h +40 -0
  13. data/ext/src/e_ichi_parms.c +37 -0
  14. data/ext/src/e_ichi_parms.h +41 -0
  15. data/ext/src/e_ichicomp.h +50 -0
  16. data/ext/src/e_ichierr.h +40 -0
  17. data/ext/src/e_ichimain.c +593 -0
  18. data/ext/src/e_ichisize.h +43 -0
  19. data/ext/src/e_inchi_atom.c +75 -0
  20. data/ext/src/e_inchi_atom.h +33 -0
  21. data/ext/src/e_inpdef.h +41 -0
  22. data/ext/src/e_mode.h +706 -0
  23. data/ext/src/e_mol2atom.c +649 -0
  24. data/ext/src/e_readinch.c +58 -0
  25. data/ext/src/e_readmol.c +54 -0
  26. data/ext/src/e_readmol.h +180 -0
  27. data/ext/src/e_readstru.c +251 -0
  28. data/ext/src/e_readstru.h +33 -0
  29. data/ext/src/e_util.c +284 -0
  30. data/ext/src/e_util.h +61 -0
  31. data/ext/src/extr_ct.h +251 -0
  32. data/ext/src/ichi.h +206 -0
  33. data/ext/src/ichi_bns.c +7999 -0
  34. data/ext/src/ichi_bns.h +231 -0
  35. data/ext/src/ichican2.c +5000 -0
  36. data/ext/src/ichicano.c +2195 -0
  37. data/ext/src/ichicano.h +49 -0
  38. data/ext/src/ichicans.c +1625 -0
  39. data/ext/src/ichicant.h +379 -0
  40. data/ext/src/ichicomn.h +260 -0
  41. data/ext/src/ichicomp.h +50 -0
  42. data/ext/src/ichidrp.h +119 -0
  43. data/ext/src/ichierr.h +124 -0
  44. data/ext/src/ichiisot.c +101 -0
  45. data/ext/src/ichilnct.c +286 -0
  46. data/ext/src/ichimain.h +132 -0
  47. data/ext/src/ichimak2.c +1189 -0
  48. data/ext/src/ichimake.c +3812 -0
  49. data/ext/src/ichimake.h +205 -0
  50. data/ext/src/ichimap1.c +851 -0
  51. data/ext/src/ichimap2.c +2856 -0
  52. data/ext/src/ichimap4.c +1609 -0
  53. data/ext/src/ichinorm.c +741 -0
  54. data/ext/src/ichinorm.h +67 -0
  55. data/ext/src/ichiparm.c +45 -0
  56. data/ext/src/ichiparm.h +1441 -0
  57. data/ext/src/ichiprt1.c +3612 -0
  58. data/ext/src/ichiprt2.c +1511 -0
  59. data/ext/src/ichiprt3.c +3011 -0
  60. data/ext/src/ichiqueu.c +1003 -0
  61. data/ext/src/ichiring.c +326 -0
  62. data/ext/src/ichiring.h +49 -0
  63. data/ext/src/ichisize.h +35 -0
  64. data/ext/src/ichisort.c +539 -0
  65. data/ext/src/ichister.c +3538 -0
  66. data/ext/src/ichister.h +35 -0
  67. data/ext/src/ichitaut.c +3843 -0
  68. data/ext/src/ichitaut.h +387 -0
  69. data/ext/src/ichitime.h +74 -0
  70. data/ext/src/inchi_api.h +670 -0
  71. data/ext/src/inchi_dll.c +1480 -0
  72. data/ext/src/inchi_dll.h +34 -0
  73. data/ext/src/inchi_dll_main.c +23 -0
  74. data/ext/src/inchi_dll_main.h +31 -0
  75. data/ext/src/inpdef.h +328 -0
  76. data/ext/src/lreadmol.h +1246 -0
  77. data/ext/src/mode.h +706 -0
  78. data/ext/src/ruby_inchi_main.c +558 -0
  79. data/ext/src/runichi.c +4179 -0
  80. data/ext/src/strutil.c +3861 -0
  81. data/ext/src/strutil.h +182 -0
  82. data/ext/src/util.c +1130 -0
  83. data/ext/src/util.h +85 -0
  84. data/lib/clean_tempfile.rb +220 -0
  85. data/lib/rino.rb +111 -0
  86. data/test/test.rb +386 -0
  87. metadata +130 -0
@@ -0,0 +1,539 @@
1
+ /*
2
+ * International Union of Pure and Applied Chemistry (IUPAC)
3
+ * International Chemical Identifier (InChI)
4
+ * Version 1
5
+ * Software version 1.00
6
+ * April 13, 2005
7
+ * Developed at NIST
8
+ */
9
+
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #include <string.h>
13
+
14
+ #include "mode.h"
15
+
16
+ #include "comdef.h"
17
+ #include "extr_ct.h"
18
+ #include "ichitaut.h"
19
+ #include "ichicant.h"
20
+ #include "ichicomn.h"
21
+
22
+ #include "ichicomp.h"
23
+
24
+ #define RET_MAX 32767
25
+
26
+ /**********************************************************************************/
27
+ void swap ( char *a, char *b, size_t width )
28
+ {
29
+ char tmp;
30
+ if ( a != b )
31
+ while ( width-- ) {
32
+ tmp = *a;
33
+ *a++ = *b;
34
+ *b++ = tmp;
35
+ }
36
+ }
37
+ /**********************************************************************************/
38
+ /* Sort by insertions */
39
+ int insertions_sort( void *base, size_t num, size_t width, int ( *compare )(const void *e1, const void *e2 ) )
40
+ {
41
+ char *i, *j, *pk;
42
+ int num_trans = 0;
43
+ size_t k;
44
+ for( k=1, pk = (char*)base; k < num; k++, pk += width ) {
45
+ for( i = pk, j = pk + width; j > (char*)base && (*compare)(i,j) > 0; j=i, i -= width ) {
46
+ swap( i, j, width );
47
+ num_trans ++;
48
+ }
49
+ }
50
+ return num_trans;
51
+ }
52
+ /**********************************************************************************/
53
+ /* Sort by insertions */
54
+ int insertions_sort_AT_NUMBERS( AT_NUMB *base, int num, int ( *compare )(const void *e1, const void *e2 ) )
55
+ {
56
+ AT_NUMB *i, *j, *pk, tmp;
57
+ int k, num_trans = 0;
58
+ for( k=1, pk = base; k < num; k++, pk ++ ) {
59
+ for( j = (i = pk) + 1, tmp = *j; j > base && (*compare)(i,&tmp) > 0; j=i, i -- ) {
60
+ *j = *i;
61
+ num_trans ++;
62
+ }
63
+ *j = tmp;
64
+ }
65
+ return num_trans;
66
+ }
67
+ /**********************************************************************************/
68
+ /* Sort neighbors according to ranks in ascending order */
69
+ void insertions_sort_NeighList_AT_NUMBERS( NEIGH_LIST base, AT_RANK *nRank )
70
+ {
71
+ AT_NUMB *i, *j, *pk, tmp;
72
+ AT_RANK rj; /* optimization */
73
+ int k, num = (int)*base++;
74
+ for( k=1, pk = base; k < num; k++, pk ++ ) {
75
+ for( j = (i = pk) + 1, rj=nRank[(int)*j]; j > base && nRank[(int)*i] > rj; j=i, i -- ) {
76
+ tmp = *i;
77
+ *i = *j;
78
+ *j = tmp;
79
+ }
80
+ }
81
+ }
82
+ /**********************************************************************************/
83
+ /* Sort neighbors according to ranks in ascending order */
84
+ int insertions_sort_AT_RANK( AT_RANK *base, int num )
85
+ {
86
+ AT_RANK *i, *j, *pk, tmp;
87
+ int k, num_trans = 0;
88
+ for( k=1, pk = base; k < num; k++, pk ++ ) {
89
+ for( j = (i = pk) + 1, tmp = *j; j > base && *i > tmp; j=i, i -- ) {
90
+ *j = *i;
91
+ num_trans ++;
92
+ }
93
+ *j = tmp;
94
+ }
95
+ return num_trans;
96
+ }
97
+ /**********************************************************************************/
98
+ /* Sort neighbors according to ranks in ascending order */
99
+ int insertions_sort_NeighList_AT_NUMBERS3( NEIGH_LIST base, AT_RANK *nRank )
100
+ {
101
+ AT_NUMB *i, *j, *pk, tmp;
102
+ AT_RANK rj;
103
+ int k, n, num = (int)*base++;
104
+ for( k=1, pk = base, n=0; k < num; k++, pk ++ ) {
105
+ for( j = (i = pk) + 1, rj=nRank[(int)(tmp=*j)]; j > base && nRank[(int)*i] > rj; j=i, i -- ) {
106
+ *j = *i;
107
+ n ++;
108
+ }
109
+ *j = tmp;
110
+ }
111
+ return n;
112
+ }
113
+
114
+ /**********************************************************************************/
115
+ /* Sort neighbors according to symm. ranks (primary key) and canon. ranks (secondary key), in descending order */
116
+ void insertions_sort_NeighListBySymmAndCanonRank( NEIGH_LIST base, const AT_RANK *nSymmRank, const AT_RANK *nCanonRank )
117
+ {
118
+ AT_NUMB *i, *j, *pk, tmp;
119
+ int diff;
120
+ int k, num = (int)*base++;
121
+ for( k=1, pk = base; k < num; k++, pk ++ ) {
122
+ for( j = (i = pk) + 1; j > base && /* always j > i */
123
+ ( 0 > (diff = (int)nSymmRank[(int)*i] - (int)nSymmRank[(int)*j]) ||
124
+ !diff && nCanonRank[(int)*i] < nCanonRank[(int)*j]); j=i, i -- ) {
125
+ tmp = *i;
126
+ *i = *j;
127
+ *j = tmp;
128
+ }
129
+ }
130
+ }
131
+
132
+ /*********************************************************************************************
133
+ *
134
+ * Comparison functions
135
+ *
136
+ *********************************************************************************************/
137
+ int CompNeighborsAT_NUMBER( const void* a1, const void* a2)
138
+ {
139
+ #ifdef CT_NEIGH_INCREASE
140
+ return (int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a1]] -
141
+ (int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a2]];
142
+ #else
143
+ return (int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a2]] -
144
+ (int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a1]];
145
+ #endif
146
+ }
147
+
148
+ /**********************************************************************************/
149
+ int comp_AT_RANK( const void* a1, const void* a2)
150
+ {
151
+ return (int)*(const AT_RANK*)a1 - (int)*(const AT_RANK*)a2;
152
+ }
153
+
154
+ /**********************************************************************************/
155
+ /* Compare for sorting Ranks only */
156
+ int CompRank(const void* a1, const void* a2 )
157
+ {
158
+ int ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a1] -
159
+ (int)pn_RankForSort[(int)*(const AT_RANK*)a2];
160
+ return ret;
161
+ }
162
+ /**********************************************************************************/
163
+ int CompRanksOrd( const void* a1, const void* a2 )
164
+ {
165
+ int ret;
166
+ ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a1] -
167
+ (int)pn_RankForSort[(int)*(const AT_RANK*)a2];
168
+ if ( !ret )
169
+ ret = (int)*(const AT_RANK*)a1 - (int)*(const AT_RANK*)a2;
170
+ return ret;
171
+ }
172
+ /**********************************************************************************/
173
+ int CompAtomInvariants2Only( const void* a1, const void* a2 )
174
+ {
175
+ const ATOM_INVARIANT2 *pAI1 = pAtomInvariant2ForSort + (int)*(const AT_RANK*)a1;
176
+ const ATOM_INVARIANT2 *pAI2 = pAtomInvariant2ForSort + (int)*(const AT_RANK*)a2;
177
+ int i;
178
+ for ( i = 0; i < AT_INV_BREAK1; i ++ ) {
179
+ if ( pAI1->val[i] == pAI2->val[i] )
180
+ continue;
181
+ return (int)pAI1->val[i] - (int)pAI2->val[i];
182
+ }
183
+ if ( pAI1->iso_sort_key != pAI2->iso_sort_key ) {
184
+ return ( pAI1->iso_sort_key > pAI2->iso_sort_key )? 1 : -1;
185
+ }
186
+ for ( ; i < AT_INV_LENGTH; i ++ ) {
187
+ if ( pAI1->val[i] != pAI2->val[i] )
188
+ continue;
189
+ return (int)pAI1->val[i] - (int)pAI2->val[i];
190
+ }
191
+ if ( pAI1->iso_aux_key != pAI2->iso_aux_key ) {
192
+ return ( pAI1->iso_aux_key > pAI2->iso_aux_key )? 1 : -1;
193
+ }
194
+ return 0;
195
+ }
196
+ /**********************************************************************************/
197
+ int CompAtomInvariants2( const void* a1, const void* a2 )
198
+ {
199
+ /* Warning: the following line may be compiler implementation dependent */
200
+ int ret = CompAtomInvariants2Only( a1, a2 );
201
+ if ( !ret )
202
+ ret = (int)*(const AT_RANK*)a1 - (int)*(const AT_RANK*)a2;
203
+ return ret;
204
+ }
205
+ /**********************************************************************************/
206
+ /* Compare two elements lexic�graphically */
207
+ int CompChemElemLex( const void *a1, const void *a2 )
208
+ {
209
+ return memcmp( a1, a2, 2);
210
+ }
211
+ /**********************************************************************************/
212
+ /* lexicographic compare */
213
+ int CompareNeighListLex( NEIGH_LIST pp1, NEIGH_LIST pp2, const AT_RANK *nRank)
214
+ {
215
+ int len1 = (int)*pp1++;
216
+ int len2 = (int)*pp2++;
217
+ int len = inchi_min( len1, len2 );
218
+ int diff = 0;
219
+ while ( len -- > 0 && !( diff = (int)nRank[*pp1++] - (int)nRank[*pp2++] ) )
220
+ ;
221
+ return diff? diff : (len1 - len2);
222
+
223
+ }
224
+ /**********************************************************************************/
225
+ /* lexicographic compare */
226
+ int CompareNeighListLexUpToMaxRank( NEIGH_LIST pp1, NEIGH_LIST pp2, const AT_RANK *nRank, AT_RANK nMaxAtNeighRank )
227
+ {
228
+ int len1 = (int)*pp1++;
229
+ int len2 = (int)*pp2++;
230
+ int diff = 0;
231
+ int len;
232
+ while( 0 < len1 && nRank[pp1[len1-1]] > nMaxAtNeighRank ) {
233
+ len1 --;
234
+ }
235
+ while( 0 < len2 && nRank[pp2[len2-1]] > nMaxAtNeighRank ) {
236
+ len2 --;
237
+ }
238
+ len = inchi_min( len1, len2 );
239
+ while ( len -- > 0 && !( diff = (int)nRank[*pp1++] - (int)nRank[*pp2++] ) )
240
+ ;
241
+ return diff? diff : (len1 - len2);
242
+
243
+ }
244
+ /**********************************************************************************/
245
+ int compare_NeighLists( const NEIGH_LIST *op1, const NEIGH_LIST *op2 )
246
+ {
247
+ return CompareNeighListLex( *op1, *op2, pn_RankForSort);
248
+ }
249
+ /**********************************************************************************/
250
+ int CompNeighListRanks( const void* a1, const void* a2 )
251
+ {
252
+ int ret;
253
+ ret = (int)pn_RankForSort[*((const AT_RANK*)a1)] -
254
+ (int)pn_RankForSort[*((const AT_RANK*)a2)];
255
+ if ( !ret )
256
+ ret = compare_NeighLists( pNeighList_RankForSort + *((const AT_RANK*)a1),
257
+ pNeighList_RankForSort + *((const AT_RANK*)a2) );
258
+ return ret;
259
+ }
260
+ /**********************************************************************************/
261
+ int CompNeighLists( const void* a1, const void* a2 )
262
+ {
263
+ int ret;
264
+ ret = compare_NeighLists( pNeighList_RankForSort + *((const AT_RANK*)a1),
265
+ pNeighList_RankForSort + *((const AT_RANK*)a2) );
266
+ return ret;
267
+ }
268
+ /**********************************************************************************/
269
+ int CompNeighListsUpToMaxRank( const void* a1, const void* a2 )
270
+ {
271
+ int ret;
272
+ ret = CompareNeighListLexUpToMaxRank( pNeighList_RankForSort[*((const AT_RANK*)a1)],
273
+ pNeighList_RankForSort[*((const AT_RANK*)a2)],
274
+ pn_RankForSort, nMaxAtNeighRankForSort );
275
+ return ret;
276
+ }
277
+ /**********************************************************************************/
278
+ int CompNeighListRanksOrd( const void* a1, const void* a2 )
279
+ {
280
+ int ret = CompNeighListRanks( a1, a2 );
281
+ if ( !ret )
282
+ ret = (int)*((const AT_RANK*)a1) - (int)*((const AT_RANK*)a2); /* keep original order if identical */
283
+ return ret;
284
+ }
285
+ /**********************************************************************************/
286
+ int CompRanksInvOrd( const void* a1, const void* a2 )
287
+ {
288
+ return (int)*(const AT_RANK*)a2 - (int)*(const AT_RANK*)a1;
289
+ }
290
+ /**********************************************************************************/
291
+ int CompNeighborsRanksCountEql( const void* a1, const void* a2 )
292
+ {
293
+ #ifdef CT_NEIGH_INCREASE
294
+ int ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a1] -
295
+ (int)pn_RankForSort[(int)*(const AT_RANK*)a2];
296
+ #else
297
+ int ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a2] -
298
+ (int)pn_RankForSort[(int)*(const AT_RANK*)a1];
299
+ #endif
300
+ nNumCompNeighborsRanksCountEql += !ret;
301
+ return ret;
302
+ }
303
+ /****************************************************************************************
304
+ *
305
+ * In this neighbor list the (vertex number) = (canonical number) - 1
306
+ * Since LinearCT is sorted so that parents are in ascending order
307
+ * and all neighbors of a parent are smaller than the parent and are
308
+ * in ascending order, the neighbors in the NEIGH_LIST are automatically
309
+ * sorted in ascending order
310
+ */
311
+ NEIGH_LIST *CreateNeighListFromLinearCT( AT_NUMB *LinearCT, int nLenCT, int num_atoms )
312
+ {
313
+ /* atom numbers in LinearCT are canonical numbers
314
+ * order: parent[i] > neigh[i][0] < neigh[i][1]...<neigh[i][n] < parent[i+1] > neigh[i+1][0] < ...
315
+ * parent[i] < parent[i+1]
316
+ */
317
+ int i, j;
318
+ S_CHAR *valence = NULL;
319
+ NEIGH_LIST *pp = NULL;
320
+ AT_NUMB *pAtList = NULL;
321
+ AT_RANK n_vertex, n_neigh;
322
+ int err = 1, num_bonds;
323
+ int length, start;
324
+ if ( (int)LinearCT[0] > num_atoms ) {
325
+ goto exit_function;
326
+ }
327
+ if ( !(valence = (S_CHAR*)inchi_calloc( num_atoms+1, sizeof(valence[0]) ) ) ) {
328
+ goto exit_function;
329
+ }
330
+ for ( i = 1, num_bonds = 0, n_vertex = LinearCT[0]; i < nLenCT; i ++ ) {
331
+ if ( (n_neigh = LinearCT[i]) < n_vertex ) {
332
+ valence[n_neigh] ++;
333
+ valence[n_vertex] ++;
334
+ num_bonds += 2;
335
+ } else
336
+ if ( (int)(n_vertex = n_neigh) > num_atoms ) {
337
+ goto exit_function;
338
+ }
339
+ }
340
+ if ( (int)n_vertex != num_atoms ) {
341
+ goto exit_function;
342
+ }
343
+ length = num_bonds + num_atoms + 1;
344
+ if ( pp = (NEIGH_LIST *) inchi_calloc((num_atoms+1), sizeof(NEIGH_LIST)) ) {
345
+ if ( pAtList = (AT_NUMB *) inchi_malloc( length*sizeof(*pAtList) ) ) {
346
+ /* create empty connection table */
347
+ for ( i = 1, length = 0; i <= num_atoms; i ++ ) {
348
+ start = length;
349
+ length += (valence[i]+1);
350
+ pp[i-1] = pAtList + start;
351
+ pp[i-1][0] = 0;
352
+ }
353
+ /* fill out the CT */
354
+ for ( i = 1, n_vertex = LinearCT[0]-1; i < nLenCT; i ++ ) {
355
+ if ( (n_neigh = LinearCT[i]-1) < n_vertex ) {
356
+ /* vertex - neighbor connection */
357
+ j = (int)(++pp[(int)n_vertex][0]);
358
+ pp[(int)n_vertex][j] = n_neigh;
359
+ /* neighbor - vertex connection */
360
+ j = (int)(++pp[(int)n_neigh][0]);
361
+ pp[(int)n_neigh][j] = n_vertex;
362
+
363
+ } else
364
+ if ( (int)(n_vertex = n_neigh) >= num_atoms ) {
365
+ goto exit_function;
366
+ }
367
+ }
368
+ err = 0;
369
+ }
370
+ }
371
+ exit_function:
372
+ if ( valence ) {
373
+ inchi_free( valence );
374
+ }
375
+ if ( err ) {
376
+ if ( pAtList )
377
+ inchi_free( pAtList );
378
+ if ( pp ) {
379
+ inchi_free( pp );
380
+ pp = NULL;
381
+ }
382
+ }
383
+ return pp;
384
+ }
385
+
386
+ /***********************************************************************************
387
+ * NEIGH_LIST pp[] is an array of pointers to the lists of neighboring atoms numbers
388
+ * The first number in each list is a number of neighbors.
389
+ * In case of bDoubleBondSquare != 0 neighbors connected by the double bond appear 2 times
390
+ * The first element pp[0] is a pointer to be deallocated to free all the lists.
391
+ */
392
+ NEIGH_LIST *CreateNeighList( int num_atoms, int num_at_tg, sp_ATOM* at,
393
+ int bDoubleBondSquare, T_GROUP_INFO *t_group_info )
394
+ {
395
+ /* +1 to add NULL termination */
396
+ NEIGH_LIST *pp = (NEIGH_LIST *) inchi_calloc((num_at_tg+1), sizeof(NEIGH_LIST));
397
+ T_GROUP *t_group = NULL;
398
+ AT_NUMB *nEndpointAtomNumber = NULL;
399
+ int num_t_groups = 0;
400
+ int nFirstEndpointAtNoPos;
401
+
402
+ AT_NUMB *pAtList = NULL;
403
+ int length, start, val, i, j;
404
+ if ( pp ) {
405
+ if ( num_at_tg > num_atoms ) {
406
+ t_group = t_group_info->t_group;
407
+ num_t_groups = t_group_info->num_t_groups;
408
+ nEndpointAtomNumber = t_group_info->nEndpointAtomNumber;
409
+ }
410
+
411
+ if ( !bDoubleBondSquare ) {
412
+ for ( i = 0, length = 0; i < num_atoms; i ++ ) {
413
+ length += (int)at[i].valence + (num_t_groups && at[i].endpoint);
414
+ }
415
+ length += num_atoms;
416
+ for ( i = 0; i < num_t_groups; i ++ ) {
417
+ length += (int)t_group[i].nNumEndpoints;
418
+ }
419
+ length += num_t_groups;
420
+
421
+ } else {
422
+ for ( i = 0, length = 0; i < num_atoms; i ++ ) {
423
+ val = (int)at[i].valence;
424
+ for ( j = 0; j < val; j ++ ) {
425
+ length += 1 + (bDoubleBondSquare && BOND_DOUBLE == at[i].bond_type[j]);
426
+ }
427
+ length += (num_t_groups && at[i].endpoint);
428
+ }
429
+ length += num_atoms;
430
+ for ( i = 0; i < num_t_groups; i ++ ) {
431
+ length += (int)t_group[i].nNumEndpoints;
432
+ }
433
+ length += num_t_groups;
434
+ }
435
+ length ++; /* +1 to save number of neighbors */
436
+ if ( pAtList = (AT_NUMB *) inchi_malloc( length*sizeof(*pAtList) ) ) {
437
+ if ( !bDoubleBondSquare ) {
438
+ for ( i = 0, length = 0; i < num_atoms; i ++ ) {
439
+ val = at[i].valence;
440
+ start = length ++;
441
+ for ( j = 0; j < val; j ++ ) {
442
+ pAtList[length ++] = at[i].neighbor[j];
443
+ }
444
+ /* add endpoint */
445
+ if (num_t_groups && at[i].endpoint) {
446
+ pAtList[length ++] = num_atoms + (int)at[i].endpoint - 1;
447
+ }
448
+ pAtList[start] = length - start - 1; /* number of neighbors before the list of neighbors */
449
+ pp[i] = pAtList + start; /* pointer to the <num.neigh.><list of neigh> */
450
+ }
451
+
452
+ } else {
453
+ for ( i = 0, length = 0; i < num_atoms; i ++ ) {
454
+ val = at[i].valence;
455
+ start = length ++;
456
+ for ( j = 0; j < val; j ++ ) {
457
+ pAtList[length ++] = at[i].neighbor[j];
458
+ if ( bDoubleBondSquare && BOND_DOUBLE == at[i].bond_type[j] ) {
459
+ pAtList[length ++] = at[i].neighbor[j]; /* a list of neighbor orig. numbers */
460
+ }
461
+ }
462
+ /* add endpoint */
463
+ if (num_t_groups && at[i].endpoint) {
464
+ pAtList[length ++] = num_atoms + (int)at[i].endpoint - 1;
465
+ }
466
+ pAtList[start] = length - start - 1; /* number of neighbors before the list of neighbors */
467
+ pp[i] = pAtList + start; /* pointer to the <num.neigh.><list of neigh> */
468
+ }
469
+ }
470
+
471
+ /* add t-groups */
472
+ for ( i = 0; i < num_t_groups; i ++ ) {
473
+ val = (int)t_group[i].nNumEndpoints;
474
+ start = length ++;
475
+ nFirstEndpointAtNoPos = (int)t_group[i].nFirstEndpointAtNoPos;
476
+ for ( j = 0; j < val; j ++ ) {
477
+ pAtList[length ++] = nEndpointAtomNumber[nFirstEndpointAtNoPos+j];
478
+ }
479
+ pAtList[start] = length - start - 1; /* number of neighbors before the list of neighbors */
480
+ pp[num_atoms+i] = pAtList + start; /* pointer to the <num.neigh.><list of neigh> */
481
+ }
482
+ } else {
483
+ inchi_free ( pp );
484
+ return NULL;
485
+ }
486
+ }
487
+ return pp;
488
+ }
489
+ /**********************************************************************************/
490
+ void FreeNeighList( NEIGH_LIST *pp )
491
+ {
492
+ if ( pp ) {
493
+ if ( pp[0] ) {
494
+ inchi_free( pp[0] );
495
+ }
496
+ inchi_free( pp );
497
+ }
498
+ }
499
+
500
+ /**********************************************************************************/
501
+ int BreakAllTies( int num_atoms, int num_max, AT_RANK **pRankStack,
502
+ NEIGH_LIST *NeighList, AT_RANK *nTempRank, CANON_STAT *pCS)
503
+ {
504
+ int i, nRet = -1, nNumRanks=1 /* value does not matter*/;
505
+
506
+ AT_RANK *nPrevRank = *pRankStack ++;
507
+ AT_RANK *nPrevAtomNumber = *pRankStack ++;
508
+
509
+ AT_RANK *nNewRank = NULL;
510
+ AT_RANK *nNewAtomNumber = NULL;
511
+
512
+ if ( !pRankStack[0] ) {
513
+ pRankStack[0] = (AT_RANK *)inchi_malloc(num_max*sizeof(*nNewRank));
514
+ }
515
+ if ( !pRankStack[1] ) {
516
+ pRankStack[1] = (AT_RANK *)inchi_malloc(num_max*sizeof(*nNewAtomNumber));
517
+ }
518
+ if ( !pRankStack[0] || !pRankStack[1] )
519
+ return CT_OUT_OF_RAM; /* <BRKPT> */
520
+ nNewRank = pRankStack[0];
521
+ nNewAtomNumber = pRankStack[1];
522
+
523
+ if ( nNewRank && nNewAtomNumber ) {
524
+ memcpy( nNewAtomNumber, nPrevAtomNumber, num_atoms*sizeof(nNewAtomNumber[0]));
525
+ memcpy( nNewRank, nPrevRank, num_atoms*sizeof(nNewRank[0]));
526
+
527
+ for ( i = 1, nRet=0; i < num_atoms; i ++ ) { /* 12-12-2001: replaced Prev... with New... */
528
+ if ( nNewRank[(int)nNewAtomNumber[i-1]] == nNewRank[(int)nNewAtomNumber[i]] ) {
529
+ nNewRank[nNewAtomNumber[i-1]] = (AT_RANK)i;
530
+ nNumRanks = DifferentiateRanks2( num_atoms, NeighList,
531
+ nNumRanks, nNewRank, nTempRank,
532
+ nNewAtomNumber, &pCS->lNumNeighListIter, 1 );
533
+ pCS->lNumBreakTies ++;
534
+ nRet ++;
535
+ }
536
+ }
537
+ }
538
+ return nRet;
539
+ }