rino 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +44 -0
- data/Rakefile +123 -0
- data/ext/extconf.rb +26 -0
- data/ext/ruby_inchi_main.so +0 -0
- data/ext/src/aux2atom.h +2786 -0
- data/ext/src/comdef.h +148 -0
- data/ext/src/e_0dstereo.c +3014 -0
- data/ext/src/e_0dstereo.h +31 -0
- data/ext/src/e_comdef.h +57 -0
- data/ext/src/e_ctl_data.h +147 -0
- data/ext/src/e_ichi_io.c +498 -0
- data/ext/src/e_ichi_io.h +40 -0
- data/ext/src/e_ichi_parms.c +37 -0
- data/ext/src/e_ichi_parms.h +41 -0
- data/ext/src/e_ichicomp.h +50 -0
- data/ext/src/e_ichierr.h +40 -0
- data/ext/src/e_ichimain.c +593 -0
- data/ext/src/e_ichisize.h +43 -0
- data/ext/src/e_inchi_atom.c +75 -0
- data/ext/src/e_inchi_atom.h +33 -0
- data/ext/src/e_inpdef.h +41 -0
- data/ext/src/e_mode.h +706 -0
- data/ext/src/e_mol2atom.c +649 -0
- data/ext/src/e_readinch.c +58 -0
- data/ext/src/e_readmol.c +54 -0
- data/ext/src/e_readmol.h +180 -0
- data/ext/src/e_readstru.c +251 -0
- data/ext/src/e_readstru.h +33 -0
- data/ext/src/e_util.c +284 -0
- data/ext/src/e_util.h +61 -0
- data/ext/src/extr_ct.h +251 -0
- data/ext/src/ichi.h +206 -0
- data/ext/src/ichi_bns.c +7999 -0
- data/ext/src/ichi_bns.h +231 -0
- data/ext/src/ichican2.c +5000 -0
- data/ext/src/ichicano.c +2195 -0
- data/ext/src/ichicano.h +49 -0
- data/ext/src/ichicans.c +1625 -0
- data/ext/src/ichicant.h +379 -0
- data/ext/src/ichicomn.h +260 -0
- data/ext/src/ichicomp.h +50 -0
- data/ext/src/ichidrp.h +119 -0
- data/ext/src/ichierr.h +124 -0
- data/ext/src/ichiisot.c +101 -0
- data/ext/src/ichilnct.c +286 -0
- data/ext/src/ichimain.h +132 -0
- data/ext/src/ichimak2.c +1189 -0
- data/ext/src/ichimake.c +3812 -0
- data/ext/src/ichimake.h +205 -0
- data/ext/src/ichimap1.c +851 -0
- data/ext/src/ichimap2.c +2856 -0
- data/ext/src/ichimap4.c +1609 -0
- data/ext/src/ichinorm.c +741 -0
- data/ext/src/ichinorm.h +67 -0
- data/ext/src/ichiparm.c +45 -0
- data/ext/src/ichiparm.h +1441 -0
- data/ext/src/ichiprt1.c +3612 -0
- data/ext/src/ichiprt2.c +1511 -0
- data/ext/src/ichiprt3.c +3011 -0
- data/ext/src/ichiqueu.c +1003 -0
- data/ext/src/ichiring.c +326 -0
- data/ext/src/ichiring.h +49 -0
- data/ext/src/ichisize.h +35 -0
- data/ext/src/ichisort.c +539 -0
- data/ext/src/ichister.c +3538 -0
- data/ext/src/ichister.h +35 -0
- data/ext/src/ichitaut.c +3843 -0
- data/ext/src/ichitaut.h +387 -0
- data/ext/src/ichitime.h +74 -0
- data/ext/src/inchi_api.h +670 -0
- data/ext/src/inchi_dll.c +1480 -0
- data/ext/src/inchi_dll.h +34 -0
- data/ext/src/inchi_dll_main.c +23 -0
- data/ext/src/inchi_dll_main.h +31 -0
- data/ext/src/inpdef.h +328 -0
- data/ext/src/lreadmol.h +1246 -0
- data/ext/src/mode.h +706 -0
- data/ext/src/ruby_inchi_main.c +558 -0
- data/ext/src/runichi.c +4179 -0
- data/ext/src/strutil.c +3861 -0
- data/ext/src/strutil.h +182 -0
- data/ext/src/util.c +1130 -0
- data/ext/src/util.h +85 -0
- data/lib/clean_tempfile.rb +220 -0
- data/lib/rino.rb +111 -0
- data/test/test.rb +386 -0
- metadata +130 -0
data/ext/src/util.c
ADDED
@@ -0,0 +1,1130 @@
|
|
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 <string.h>
|
12
|
+
#include <stdlib.h>
|
13
|
+
#include <ctype.h>
|
14
|
+
|
15
|
+
#include "mode.h"
|
16
|
+
|
17
|
+
#include "comdef.h"
|
18
|
+
#include "inpdef.h"
|
19
|
+
#include "util.h"
|
20
|
+
#include "extr_ct.h"
|
21
|
+
|
22
|
+
|
23
|
+
#include "ichicomp.h"
|
24
|
+
|
25
|
+
#define MIN_ATOM_CHARGE (-2)
|
26
|
+
#define MAX_ATOM_CHARGE 2
|
27
|
+
#define NEUTRAL_STATE (-MIN_ATOM_CHARGE)
|
28
|
+
#define NUM_ATOM_CHARGES (MAX_ATOM_CHARGE - MIN_ATOM_CHARGE + 1)
|
29
|
+
#define MAX_NUM_VALENCES 5 /* max. number + 1 to provide zero termination */
|
30
|
+
|
31
|
+
typedef struct tagElData {
|
32
|
+
const char *szElName;
|
33
|
+
int nAtMass; /* Avg. atomic mass from the Periodic Chart of the Elements (Fisher cat. no. 05-702-10) */
|
34
|
+
int nNormAtMass; /* Atomic mass of the most abundant isotope */
|
35
|
+
double dAtMass; /* exact mw of the most abundant isotope */
|
36
|
+
int nType; /* METAL or METAL2 */
|
37
|
+
int bDoNotAddH; /* InChI does not add imlicit H to atoms that have bDoNotAddH != 0 */
|
38
|
+
S_CHAR cValence[NUM_ATOM_CHARGES][MAX_NUM_VALENCES];
|
39
|
+
} ELDATA;
|
40
|
+
|
41
|
+
/* 2004=05-10: Added valences {1,3,5,7,} for As(2-) */
|
42
|
+
|
43
|
+
const ELDATA ElData[] = {
|
44
|
+
/* avg norm No -------- Valence(s) of an ion or neutral atom -------------*/
|
45
|
+
/* mw mass exact mw type H -2 -1 0 +1 +2 */
|
46
|
+
{ "H", 1, 1, 1.007825035, 0 , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
47
|
+
{ "D", 2, 2, 2.014101778, 0 , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
48
|
+
{ "T", 3, 3, 3.016049268, 0 , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
49
|
+
{ "He", 4, 4, 4.002600000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
50
|
+
{ "Li", 7, 7, 7.016000000, METAL , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
51
|
+
{ "Be", 9, 9, 9.012180000, METAL , 0, {{0,}, {0,}, {2,}, {1,}, {0,} }},
|
52
|
+
{ "B", 11, 11, 11.009300000, 0 , 0, {{3,}, {4,}, {3,}, {2,}, {1,} }},
|
53
|
+
{ "C", 12, 12, 12.000000000, 0 , 0, {{2,}, {3,}, {4,}, {3,}, {2,} }},
|
54
|
+
{ "N", 14, 14, 14.003074000, 0 , 0, {{1,}, {2,}, {3,5}, {4,}, {3,} }},
|
55
|
+
{ "O", 16, 16, 15.994914630, 0 , 0, {{0,}, {1,}, {2,}, {3,5,}, {4,} }},
|
56
|
+
{ "F", 19, 19, 18.998403220, 0 , 0, {{0,}, {0,}, {1,}, {2,}, {3,5} }},
|
57
|
+
{ "Ne", 20, 20, 19.992440000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
58
|
+
{ "Na", 23, 23, 22.989770000, METAL , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
59
|
+
{ "Mg", 24, 24, 23.985000000, METAL , 0, {{0,}, {0,}, {2,}, {1,}, {0,} }},
|
60
|
+
{ "Al", 27, 27, 26.981540000, METAL , 0, {{3,5,}, {4,}, {3,}, {2,}, {1,} }},
|
61
|
+
{ "Si", 28, 28, 27.976927100, 0 , 0, {{2,}, {3,5}, {4,}, {3,}, {2,} }},
|
62
|
+
{ "P", 31, 31, 30.973762000, 0 , 0, {{1,3,5,7,}, {2,4,6,}, {3,5,}, {4,}, {3,} }},
|
63
|
+
{ "S", 32, 32, 31.972070700, 0 , 0, {{0,}, {1,3,5,7,}, {2,4,6}, {3,5,}, {4,} }},
|
64
|
+
{ "Cl", 35, 35, 34.968852730, 0 , 0, {{0,}, {0,}, {1,3,5,7}, {2,4,6}, {3,5,} }},
|
65
|
+
{ "Ar", 40, 40, 39.962400000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
66
|
+
{ "K", 39, 39, 38.963700000, METAL , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
67
|
+
{ "Ca", 40, 40, 39.962600000, METAL , 0, {{0,}, {0,}, {2,}, {1,}, {0,} }},
|
68
|
+
{ "Sc", 45, 45, 44.955910000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
69
|
+
{ "Ti", 48, 48, 47.947950000, METAL , 1, {{0,}, {0,}, {3,4}, {0,}, {0,} }},
|
70
|
+
{ "V", 51, 51, 50.943960000, METAL , 1, {{0,}, {0,}, {2,3,4,5,}, {0,}, {0,} }},
|
71
|
+
{ "Cr", 52, 52, 51.940500000, METAL , 1, {{0,}, {0,}, {2,3,6,}, {0,}, {0,} }},
|
72
|
+
{ "Mn", 55, 55, 54.938050000, METAL2, 1, {{0,}, {0,}, {2,3,4,6,}, {0,}, {0,} }},
|
73
|
+
{ "Fe", 56, 56, 55.934900000, METAL2, 1, {{0,}, {0,}, {2,3,4,6,}, {0,}, {0,} }},
|
74
|
+
{ "Co", 59, 59, 58.933200000, METAL2, 1, {{0,}, {0,}, {2,3,}, {0,}, {0,} }},
|
75
|
+
{ "Ni", 59, 58, 57.935300000, METAL2, 1, {{0,}, {0,}, {2,3,}, {0,}, {0,} }},
|
76
|
+
{ "Cu", 64, 63, 62.929600000, METAL , 1, {{0,}, {0,}, {1,2,}, {0,}, {0,} }},
|
77
|
+
{ "Zn", 65, 64, 63.929147000, METAL , 1, {{0,}, {0,}, {2,}, {0,}, {0,} }},
|
78
|
+
{ "Ga", 70, 69, 68.925600000, METAL , 0, {{3,5,}, {4,}, {3,}, {0,}, {1,} }},
|
79
|
+
{ "Ge", 73, 74, 73.921177400, 0 , 0, {{2,4,6,}, {3,5,}, {4,}, {3,}, {0,} }},
|
80
|
+
{ "As", 75, 75, 74.921594200, 0 , 0, {{1,3,5,7,}, {2,4,6,}, {3,5,}, {4,}, {3,} }},
|
81
|
+
{ "Se", 79, 80, 79.916519600, 0 , 0, {{0,}, {1,3,5,7,}, {2,4,6,}, {3,5,}, {4,} }},
|
82
|
+
{ "Br", 80, 79, 78.918336100, 0 , 0, {{0,}, {0,}, {1,3,5,7,}, {2,4,6,}, {3,5,} }},
|
83
|
+
{ "Kr", 84, 84, 83.911500000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
84
|
+
{ "Rb", 85, 85, 84.911800000, METAL , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
85
|
+
{ "Sr", 88, 88, 87.905600000, METAL , 0, {{0,}, {0,}, {2,}, {1,}, {0,} }},
|
86
|
+
{ "Y", 89, 89, 88.905860000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
87
|
+
{ "Zr", 91, 90, 89.904700000, METAL , 1, {{0,}, {0,}, {4,}, {0,}, {0,} }},
|
88
|
+
{ "Nb", 93, 93, 92.906400000, METAL , 1, {{0,}, {0,}, {3,5,}, {0,}, {0,} }},
|
89
|
+
{ "Mo", 96, 98, 97.905400000, METAL , 1, {{0,}, {0,}, {3,4,5,6,}, {0,}, {0,} }},
|
90
|
+
{ "Tc", 98, 98, 97.907200000, METAL , 1, {{0,}, {0,}, {7,}, {0,}, {0,} }},
|
91
|
+
{ "Ru", 101, 102, 101.904300000, METAL , 1, {{0,}, {0,}, {2,3,4,6,}, {0,}, {0,} }},
|
92
|
+
{ "Rh", 103, 103, 102.905500000, METAL , 1, {{0,}, {0,}, {2,3,4,}, {0,}, {0,} }},
|
93
|
+
{ "Pd", 106, 106, 105.903500000, METAL , 1, {{0,}, {0,}, {2,4,}, {0,}, {0,} }},
|
94
|
+
{ "Ag", 108, 107, 106.905100000, METAL , 1, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
95
|
+
{ "Cd", 112, 114, 113.903400000, METAL , 1, {{0,}, {0,}, {2,}, {0,}, {0,} }},
|
96
|
+
{ "In", 115, 115, 114.903900000, METAL , 0, {{3,5,}, {2,4,}, {3,}, {0,}, {1,} }},
|
97
|
+
{ "Sn", 119, 120, 119.902200000, METAL2, 0, {{2,4,6,}, {3,5}, {2,4,}, {3,}, {0,} }},
|
98
|
+
{ "Sb", 122, 121, 120.903800000, METAL, 0, {{1,3,5,7,}, {2,4,6,}, {3,5,}, {2,4,}, {3,} }},
|
99
|
+
{ "Te", 128, 130, 129.906200000, 0 , 0, {{0,}, {1,3,5,7,}, {2,4,6,}, {3,5,}, {2,4,} }},
|
100
|
+
{ "I", 127, 127, 126.904500000, 0 , 0, {{0,}, {0,}, {1,3,5,7,}, {2,4,6}, {3,5,} }},
|
101
|
+
{ "Xe", 131, 132, 131.904100000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
102
|
+
{ "Cs", 133, 133, 132.905430000, METAL , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
103
|
+
{ "Ba", 137, 138, 137.905200000, METAL , 0, {{0,}, {0,}, {2,}, {1,}, {0,} }},
|
104
|
+
{ "La", 139, 139, 138.906360000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
105
|
+
{ "Ce", 140, 140, 139.905400000, METAL2, 1, {{0,}, {0,}, {3,4,}, {0,}, {0,} }},
|
106
|
+
{ "Pr", 141, 141, 140.907660000, METAL2, 1, {{0,}, {0,}, {3,4,}, {0,}, {0,} }},
|
107
|
+
{ "Nd", 144, 142, 141.907719000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
108
|
+
{ "Pm", 145, 145, 144.912800000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
109
|
+
{ "Sm", 150, 152, 151.919700000, METAL2, 1, {{0,}, {0,}, {2,3,}, {0,}, {0,} }},
|
110
|
+
{ "Eu", 152, 153, 152.921200000, METAL2, 1, {{0,}, {0,}, {2,3,}, {0,}, {0,} }},
|
111
|
+
{ "Gd", 157, 158, 157.924099000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
112
|
+
{ "Tb", 159, 159, 158.925350000, METAL2, 1, {{0,}, {0,}, {3,4,}, {0,}, {0,} }},
|
113
|
+
{ "Dy", 163, 164, 163.929200000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }}, /* mw rounding uncertain */
|
114
|
+
{ "Ho", 165, 165, 164.930300000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
115
|
+
{ "Er", 167, 166, 165.930300000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
116
|
+
{ "Tm", 169, 169, 168.934230000, METAL2, 1, {{0,}, {0,}, {2,3,}, {0,}, {0,} }},
|
117
|
+
{ "Yb", 173, 174, 173.938900000, METAL2, 1, {{0,}, {0,}, {2,3,}, {0,}, {0,} }},
|
118
|
+
{ "Lu", 175, 175, 174.940800000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
119
|
+
{ "Hf", 178, 180, 179.946600000, METAL , 1, {{0,}, {0,}, {4,}, {0,}, {0,} }},
|
120
|
+
{ "Ta", 181, 181, 180.948010000, METAL , 1, {{0,}, {0,}, {5,}, {0,}, {0,} }},
|
121
|
+
{ "W", 184, 184, 183.951000000, METAL2, 1, {{0,}, {0,}, {3,4,5,6,}, {0,}, {0,} }},
|
122
|
+
{ "Re", 186, 187, 186.955800000, METAL2, 1, {{0,}, {0,}, {2,4,6,7,}, {0,}, {0,} }},
|
123
|
+
{ "Os", 190, 192, 191.961500000, METAL2, 1, {{0,}, {0,}, {2,3,4,6,}, {0,}, {0,} }},
|
124
|
+
{ "Ir", 192, 193, 192.962900000, METAL2, 1, {{0,}, {0,}, {2,3,4,6,}, {0,}, {0,} }},
|
125
|
+
{ "Pt", 195, 195, 194.964800000, METAL2, 1, {{0,}, {0,}, {2,4,}, {0,}, {0,} }},
|
126
|
+
{ "Au", 197, 197, 196.966560000, METAL , 1, {{0,}, {0,}, {1,3,}, {0,}, {0,} }},
|
127
|
+
{ "Hg", 201, 202, 201.970617000, METAL2, 1, {{0,}, {0,}, {1,2,}, {0,}, {0,} }},
|
128
|
+
{ "Tl", 204, 205, 204.974400000, METAL2, 0, {{3,5,}, {2,4,}, {1,3,}, {0,}, {0,} }},
|
129
|
+
{ "Pb", 207, 208, 207.976627000, METAL2, 0, {{2,4,6,}, {3,5}, {2,4,}, {3,}, {0,} }},
|
130
|
+
{ "Bi", 209, 209, 208.980390000, METAL , 0, {{1,3,5,7,}, {2,4,6,}, {3,5,}, {2,4,}, {3,} }},
|
131
|
+
{ "Po", 209, 209, 208.982400000, METAL2, 0, {{0,}, {1,3,5,7,}, {2,4,6,}, {3,5,}, {2,4,} }},
|
132
|
+
{ "At", 210, 210, 209.987100000, 0 , 0, {{0,}, {0,}, {1,3,5,7,}, {2,4,6}, {3,5,} }},
|
133
|
+
{ "Rn", 222, 222, 222.017500000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
134
|
+
{ "Fr", 223, 223, 223.019700000, METAL , 0, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
135
|
+
{ "Ra", 226, 226, 226.025410000, METAL , 0, {{0,}, {0,}, {2,}, {1,}, {0,} }},
|
136
|
+
{ "Ac", 227, 227, 227.027750000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
137
|
+
{ "Th", 232, 232, 232.038050000, METAL2, 1, {{0,}, {0,}, {3,4,}, {0,}, {0,} }},
|
138
|
+
{ "Pa", 231, 231, 231.035880000, METAL2, 1, {{0,}, {0,}, {3,4,5,}, {0,}, {0,} }},
|
139
|
+
{ "U", 238, 238, 238.050790000, METAL2, 1, {{0,}, {0,}, {3,4,5,6,}, {0,}, {0,} }},
|
140
|
+
{ "Np", 237, 237, 237.048170000, METAL2, 1, {{0,}, {0,}, {3,4,5,6,}, {0,}, {0,} }},
|
141
|
+
{ "Pu", 244, 244, 244.064200000, METAL2, 1, {{0,}, {0,}, {3,4,5,6,}, {0,}, {0,} }},
|
142
|
+
{ "Am", 243, 243, 243.061370000, METAL2, 1, {{0,}, {0,}, {3,4,5,6,}, {0,}, {0,} }},
|
143
|
+
{ "Cm", 247, 247, 247.070300000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
144
|
+
{ "Bk", 247, 247, 247.070300000, METAL , 1, {{0,}, {0,}, {3,4,}, {0,}, {0,} }},
|
145
|
+
{ "Cf", 251, 251, 251.079600000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
146
|
+
{ "Es", 252, 252, 252.082800000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
147
|
+
{ "Fm", 257, 257, 257.095100000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
148
|
+
{ "Md", 258, 258, 258.098600000, METAL , 1, {{0,}, {0,}, {3,}, {0,}, {0,} }},
|
149
|
+
{ "No", 259, 259, 259.100900000, METAL , 1, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
150
|
+
{ "Lr", 260, 260, 260.105400000, METAL , 1, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
151
|
+
{ "Rf", 261, 261, 261.108700000, METAL , 1, {{0,}, {0,}, {1,}, {0,}, {0,} }},
|
152
|
+
{ "", 0, 0, 0.000000000, 0 , 0, {{0,}, {0,}, {0,}, {0,}, {0,} }},
|
153
|
+
|
154
|
+
};
|
155
|
+
/*
|
156
|
+
#ifdef __cplusplus
|
157
|
+
}
|
158
|
+
#endif
|
159
|
+
*/
|
160
|
+
|
161
|
+
int ERR_ELEM = 255;
|
162
|
+
int nElDataLen = sizeof(ElData)/sizeof(ElData[0])-1;
|
163
|
+
|
164
|
+
/***********************************************************************************/
|
165
|
+
int GetElementFormulaFromAtNum(int nAtNum, char *szElement )
|
166
|
+
{
|
167
|
+
nAtNum -= 1;
|
168
|
+
if ( 0 < nAtNum )
|
169
|
+
nAtNum += 2; /* bypass D, T */
|
170
|
+
if ( 0 <= nAtNum && nAtNum < nElDataLen ) {
|
171
|
+
strcpy( szElement, ElData[nAtNum].szElName );
|
172
|
+
return 0;
|
173
|
+
}
|
174
|
+
strcpy( szElement, "??" );
|
175
|
+
return -1;
|
176
|
+
}
|
177
|
+
/***********************************************************************************/
|
178
|
+
int get_el_number( const char* elname )
|
179
|
+
{
|
180
|
+
int i;
|
181
|
+
const char *p;
|
182
|
+
for ( i = 0; (p=ElData[i].szElName)[0] && strcmp( p, elname ); i++ )
|
183
|
+
;
|
184
|
+
return p[0]? i : ERR_ELEM;
|
185
|
+
}
|
186
|
+
/***********************************************************************************/
|
187
|
+
int get_periodic_table_number( const char* elname )
|
188
|
+
{
|
189
|
+
int num;
|
190
|
+
num = get_el_number( elname );
|
191
|
+
if ( num < ERR_ELEM )
|
192
|
+
num = inchi_max(1, num-1);
|
193
|
+
return num;
|
194
|
+
}
|
195
|
+
/***********************************************************************************/
|
196
|
+
int do_not_add_H( int nPeriodicNum )
|
197
|
+
{
|
198
|
+
return ElData[nPeriodicNum>1? nPeriodicNum+1:0].bDoNotAddH;
|
199
|
+
}
|
200
|
+
/***********************************************************************************/
|
201
|
+
int get_el_valence( int nPeriodicNum, int charge, int val_num )
|
202
|
+
{
|
203
|
+
if ( charge < MIN_ATOM_CHARGE || charge > MAX_ATOM_CHARGE || val_num >= MAX_NUM_VALENCES )
|
204
|
+
return 0;
|
205
|
+
return ElData[nPeriodicNum>1? nPeriodicNum+1:0].cValence[NEUTRAL_STATE+charge][val_num];
|
206
|
+
}
|
207
|
+
/***********************************************************************************
|
208
|
+
* output valence needed to unumbiguosly reconstruct bonds
|
209
|
+
***********************************************************************************/
|
210
|
+
int get_unusual_el_valence( int nPeriodicNum, int charge, int radical, int bonds_valence, int num_H, int num_bonds )
|
211
|
+
{
|
212
|
+
int i, num_found, chem_valence, rad_adj, known_chem_valence, exact_found;
|
213
|
+
if ( !num_bonds && !num_H )
|
214
|
+
return 0;
|
215
|
+
if ( charge < MIN_ATOM_CHARGE || charge > MAX_ATOM_CHARGE ) {
|
216
|
+
if ( bonds_valence == num_bonds )
|
217
|
+
return 0; /* all single bonds */
|
218
|
+
return bonds_valence;
|
219
|
+
}
|
220
|
+
if ( !get_el_valence( nPeriodicNum, charge, 0 ) && bonds_valence == num_bonds )
|
221
|
+
return 0;
|
222
|
+
|
223
|
+
chem_valence = bonds_valence + num_H;
|
224
|
+
rad_adj = 0;
|
225
|
+
num_found = 0;
|
226
|
+
exact_found = 0;
|
227
|
+
|
228
|
+
/* take into account radical */
|
229
|
+
if (radical==RADICAL_DOUBLET)
|
230
|
+
rad_adj = 1;
|
231
|
+
else
|
232
|
+
if (radical==RADICAL_TRIPLET )
|
233
|
+
rad_adj = 2;
|
234
|
+
|
235
|
+
for ( i = 0; i < MAX_NUM_VALENCES; i ++ ) {
|
236
|
+
if ( 0 < (known_chem_valence = get_el_valence( nPeriodicNum, charge, i )-rad_adj) &&
|
237
|
+
num_bonds <= known_chem_valence && known_chem_valence <= chem_valence ) {
|
238
|
+
num_found ++;
|
239
|
+
if ( known_chem_valence == chem_valence ) {
|
240
|
+
exact_found = 1;
|
241
|
+
break;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
}
|
245
|
+
return (exact_found && 1 == num_found)? 0 : chem_valence;
|
246
|
+
}
|
247
|
+
/***********************************************************************************
|
248
|
+
* output valence needed to unumbiguosly reconstruct number of H
|
249
|
+
***********************************************************************************/
|
250
|
+
int needed_unusual_el_valence( int nPeriodicNum, int charge, int radical, int bonds_valence, int num_H, int num_bonds )
|
251
|
+
{
|
252
|
+
int i, num_found, num_found_known, chem_valence, rad_adj, known_chem_valence, exact_found;
|
253
|
+
/*
|
254
|
+
if ( !num_bonds && !num_H )
|
255
|
+
return 0;
|
256
|
+
*/
|
257
|
+
chem_valence = bonds_valence + num_H;
|
258
|
+
if ( charge < MIN_ATOM_CHARGE || charge > MAX_ATOM_CHARGE ||
|
259
|
+
!get_el_valence( nPeriodicNum, charge, 0 ) ||
|
260
|
+
do_not_add_H( nPeriodicNum ) ) {
|
261
|
+
if ( !num_H )
|
262
|
+
return 0; /* no H */
|
263
|
+
return chem_valence; /* needs to add H-atoms */
|
264
|
+
}
|
265
|
+
|
266
|
+
/* take into account radical */
|
267
|
+
if (radical==RADICAL_DOUBLET)
|
268
|
+
rad_adj = 1;
|
269
|
+
else
|
270
|
+
if (radical==RADICAL_TRIPLET )
|
271
|
+
rad_adj = 2;
|
272
|
+
else
|
273
|
+
rad_adj = 0;
|
274
|
+
|
275
|
+
num_found_known = 0;
|
276
|
+
num_found = 0;
|
277
|
+
exact_found = 0;
|
278
|
+
|
279
|
+
for ( i = 0; i < MAX_NUM_VALENCES; i ++ ) {
|
280
|
+
if ( 0 < (known_chem_valence = get_el_valence( nPeriodicNum, charge, i )) &&
|
281
|
+
bonds_valence <= (known_chem_valence -= rad_adj) ) {
|
282
|
+
/* found known valence that fits without H */
|
283
|
+
num_found_known ++;
|
284
|
+
if ( known_chem_valence <= chem_valence ) {
|
285
|
+
/* known valence is large enough to accommodate (implicit) H */
|
286
|
+
num_found ++;
|
287
|
+
}
|
288
|
+
if ( known_chem_valence == chem_valence ) {
|
289
|
+
exact_found = 1;
|
290
|
+
break;
|
291
|
+
}
|
292
|
+
}
|
293
|
+
}
|
294
|
+
return (exact_found && 1 == num_found && 1 == num_found_known)? 0 : chem_valence? chem_valence : -1 /* needs zero */;
|
295
|
+
}
|
296
|
+
/***********************************************************************************
|
297
|
+
* output valence that does not fit any known valences
|
298
|
+
***********************************************************************************/
|
299
|
+
int detect_unusual_el_valence( int nPeriodicNum, int charge, int radical, int bonds_valence, int num_H, int num_bonds )
|
300
|
+
{
|
301
|
+
int i, chem_valence, rad_adj, known_chem_valence;
|
302
|
+
|
303
|
+
if ( !num_bonds && !num_H )
|
304
|
+
return 0;
|
305
|
+
|
306
|
+
if ( charge < MIN_ATOM_CHARGE || charge > MAX_ATOM_CHARGE ) {
|
307
|
+
if ( bonds_valence == num_bonds )
|
308
|
+
return 0; /* all single bonds */
|
309
|
+
return bonds_valence;
|
310
|
+
}
|
311
|
+
if ( !get_el_valence( nPeriodicNum, charge, 0 ) && bonds_valence == num_bonds )
|
312
|
+
return 0;
|
313
|
+
|
314
|
+
chem_valence = bonds_valence + num_H;
|
315
|
+
rad_adj = 0;
|
316
|
+
|
317
|
+
/* take into account radical */
|
318
|
+
if (radical==RADICAL_DOUBLET)
|
319
|
+
rad_adj = 1;
|
320
|
+
else
|
321
|
+
if (radical==RADICAL_TRIPLET || radical==RADICAL_SINGLET )
|
322
|
+
rad_adj = 2;
|
323
|
+
|
324
|
+
for ( i = 0; i < MAX_NUM_VALENCES; i ++ ) {
|
325
|
+
if ( 0 < (known_chem_valence = get_el_valence( nPeriodicNum, charge, i )-rad_adj) ) {
|
326
|
+
if ( known_chem_valence == chem_valence ) {
|
327
|
+
return 0;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
return chem_valence;
|
332
|
+
}
|
333
|
+
/***********************************************************************************/
|
334
|
+
int get_el_type( int nPeriodicNum )
|
335
|
+
{
|
336
|
+
return ElData[nPeriodicNum+1].nType;
|
337
|
+
}
|
338
|
+
/***********************************************************************************/
|
339
|
+
int is_el_a_metal( int nPeriodicNum )
|
340
|
+
{
|
341
|
+
return 0!=(ElData[nPeriodicNum+1].nType & IS_METAL);
|
342
|
+
}
|
343
|
+
/******************************************************************************************************/
|
344
|
+
/*#ifndef INCHI_LIBRARY*/
|
345
|
+
int extract_ChargeRadical( char *elname, int *pnRadical, int *pnCharge )
|
346
|
+
{
|
347
|
+
char *q, *r, *p;
|
348
|
+
int nCharge=0, nRad = 0, charge_len = 0, k, nVal, nSign, nLastSign=1, len;
|
349
|
+
|
350
|
+
p = elname;
|
351
|
+
|
352
|
+
/* extract radicals & charges */
|
353
|
+
while ( q = strpbrk( p, "+-^" ) ) {
|
354
|
+
switch ( *q ) {
|
355
|
+
case '+':
|
356
|
+
case '-':
|
357
|
+
for ( k = 0, nVal=0; (nSign = ('+' == q[k])) || (nSign = -('-' == q[k])); k++ ) {
|
358
|
+
nVal += (nLastSign = nSign);
|
359
|
+
charge_len ++;
|
360
|
+
}
|
361
|
+
if ( nSign = (int)strtol( q+k, &r, 10 ) ) { /* fixed 12-5-2001 */
|
362
|
+
nVal += nLastSign * (nSign-1);
|
363
|
+
}
|
364
|
+
charge_len = r - q;
|
365
|
+
nCharge += nVal;
|
366
|
+
break;
|
367
|
+
/* case '.': */ /* singlet '.' may be confused with '.' in formulas like CaO.H2O */
|
368
|
+
case '^':
|
369
|
+
nRad = 1; /* doublet here is 1. See below */
|
370
|
+
charge_len = 1;
|
371
|
+
for ( k = 1; q[0] == q[k]; k++ ) {
|
372
|
+
nRad ++;
|
373
|
+
charge_len ++;
|
374
|
+
}
|
375
|
+
break;
|
376
|
+
}
|
377
|
+
memmove( q, q+charge_len, strlen(q+charge_len)+1 );
|
378
|
+
}
|
379
|
+
len = strlen(p);
|
380
|
+
/* radical */
|
381
|
+
if ( (q = strrchr( p, ':' )) && !q[1]) {
|
382
|
+
nRad = RADICAL_SINGLET;
|
383
|
+
q[0] = '\0';
|
384
|
+
len --;
|
385
|
+
} else {
|
386
|
+
while( (q = strrchr( p, '.' )) && !q[1] ) {
|
387
|
+
nRad ++;
|
388
|
+
q[0] = '\0';
|
389
|
+
len --;
|
390
|
+
}
|
391
|
+
|
392
|
+
nRad = nRad == 1? RADICAL_DOUBLET :
|
393
|
+
nRad == 2? RADICAL_TRIPLET : 0;
|
394
|
+
}
|
395
|
+
*pnRadical = nRad;
|
396
|
+
*pnCharge = nCharge;
|
397
|
+
return ( nRad || nCharge );
|
398
|
+
|
399
|
+
}
|
400
|
+
/*#endif*/
|
401
|
+
/****************************************************************/
|
402
|
+
int extract_H_atoms( char *elname, S_CHAR num_iso_H[] )
|
403
|
+
{
|
404
|
+
int i, len, c, k, num_H, val;
|
405
|
+
char *q;
|
406
|
+
i = 0;
|
407
|
+
num_H = 0;
|
408
|
+
len = (int)strlen(elname);
|
409
|
+
c = UCINT elname[0];
|
410
|
+
while ( i < len ) {
|
411
|
+
switch ( c ) {
|
412
|
+
case 'H':
|
413
|
+
k = 0;
|
414
|
+
break;
|
415
|
+
case 'D':
|
416
|
+
k = 1;
|
417
|
+
break;
|
418
|
+
case 'T':
|
419
|
+
k = 2;
|
420
|
+
break;
|
421
|
+
default:
|
422
|
+
k = -1;
|
423
|
+
break;
|
424
|
+
}
|
425
|
+
q = elname+i+1; /* pointer to the next to elname[i] character */
|
426
|
+
c = UCINT q[0];
|
427
|
+
if ( k >= 0 && !islower( c ) ) {
|
428
|
+
/* found a hydrogen */
|
429
|
+
if ( isdigit( c ) ) {
|
430
|
+
val = (int)strtol( q, &q, 10 );
|
431
|
+
/* q = pointer to the next to number of hydrogen atom(s) character */
|
432
|
+
} else {
|
433
|
+
val = 1;
|
434
|
+
}
|
435
|
+
if ( k ) {
|
436
|
+
num_iso_H[k] += val;
|
437
|
+
} else {
|
438
|
+
num_H += val;
|
439
|
+
}
|
440
|
+
/* remove the hydrogen atom from the string */
|
441
|
+
len -= (q-elname)-i;
|
442
|
+
memmove( elname+i, q, len + 1 );
|
443
|
+
/* c = UCINT elname[i]; */
|
444
|
+
} else {
|
445
|
+
i ++;
|
446
|
+
}
|
447
|
+
c = UCINT elname[i]; /* moved here 11-04-2002 */
|
448
|
+
}
|
449
|
+
return num_H;
|
450
|
+
}
|
451
|
+
/***********************************************************************************/
|
452
|
+
int get_num_H (const char* elname, int inp_num_H, S_CHAR inp_num_iso_H[],
|
453
|
+
int charge, int radical, int chem_bonds_valence, int atom_input_valence,
|
454
|
+
int bAliased, int bDoNotAddH, int bHasMetalNeighbor )
|
455
|
+
{
|
456
|
+
int val, i, el_number, num_H = 0, num_iso_H;
|
457
|
+
static int el_number_N = 0, el_number_S, el_number_O, el_number_C;
|
458
|
+
if ( !el_number_N ) {
|
459
|
+
el_number_N = get_el_number( "N" );
|
460
|
+
el_number_S = get_el_number( "S" );
|
461
|
+
el_number_O = get_el_number( "O" );
|
462
|
+
el_number_C = get_el_number( "C" );
|
463
|
+
}
|
464
|
+
/* atom_input_valence (cValence) cannot be specified in case of */
|
465
|
+
/* aliased MOLFile atom with known inp_num_H or inp_num_iso_H[] */
|
466
|
+
if ( bAliased ) {
|
467
|
+
num_H = inp_num_H;
|
468
|
+
} else
|
469
|
+
if ( atom_input_valence && (atom_input_valence !=15 || chem_bonds_valence) ) {
|
470
|
+
num_H = inchi_max( 0, atom_input_valence - chem_bonds_valence );
|
471
|
+
} else
|
472
|
+
if ( atom_input_valence == 15 && !chem_bonds_valence ) {
|
473
|
+
num_H = 0;
|
474
|
+
} else
|
475
|
+
if ( MIN_ATOM_CHARGE <= charge &&
|
476
|
+
MAX_ATOM_CHARGE >= charge &&
|
477
|
+
ERR_ELEM != (el_number = get_el_number( elname ) ) &&
|
478
|
+
!ElData[el_number].bDoNotAddH && !bDoNotAddH ) {
|
479
|
+
/* add hydrogen atoms according to standard element valence */
|
480
|
+
if ( radical && radical != RADICAL_SINGLET ) {
|
481
|
+
if ( val = ElData[el_number].cValence[NEUTRAL_STATE+charge][0] ) {
|
482
|
+
val -= (radical==RADICAL_DOUBLET)? 1 :
|
483
|
+
(radical==RADICAL_SINGLET || radical==RADICAL_TRIPLET )? 2 : val;
|
484
|
+
/* if unknown radical then do not add H */
|
485
|
+
num_H = inchi_max( 0, val - chem_bonds_valence );
|
486
|
+
}
|
487
|
+
} else {
|
488
|
+
/* find the smallest valence that is greater than the sum of the chemical bond valences */
|
489
|
+
for ( i = 0;
|
490
|
+
(val=ElData[el_number].cValence[NEUTRAL_STATE+charge][i]) &&
|
491
|
+
val < chem_bonds_valence;
|
492
|
+
i++ )
|
493
|
+
;
|
494
|
+
/* special case: do not add H to N(IV), S(III), S+(II), S-(II) */ /* S ions added 2004-05-10 */
|
495
|
+
if ( el_number == el_number_N && !charge && !radical && val == 5 )
|
496
|
+
val = 3;
|
497
|
+
else
|
498
|
+
/*
|
499
|
+
if ( el_number == el_number_N && !charge && !radical && val == 3 &&
|
500
|
+
chem_bonds_valence == 2 && bHasMetalNeighbor )
|
501
|
+
val = 2;
|
502
|
+
else
|
503
|
+
*/
|
504
|
+
if ( el_number == el_number_S && !charge && !radical && val == 4 && chem_bonds_valence == 3 )
|
505
|
+
val = 3;
|
506
|
+
else
|
507
|
+
if ( bHasMetalNeighbor && el_number != el_number_C && val > 0 ) {
|
508
|
+
val --;
|
509
|
+
}
|
510
|
+
/*
|
511
|
+
if ( (el_number == el_number_S || el_number == el_number_O) &&
|
512
|
+
abs(charge)==1 && !radical && val == 3 && chem_bonds_valence == 2 && bHasMetalNeighbor )
|
513
|
+
val = 2;
|
514
|
+
else
|
515
|
+
*/
|
516
|
+
num_H = inchi_max( 0, val - chem_bonds_valence );
|
517
|
+
}
|
518
|
+
for ( i = 0, num_iso_H = 0; i < NUM_H_ISOTOPES; i ++ ) {
|
519
|
+
num_iso_H += inp_num_iso_H[i];
|
520
|
+
}
|
521
|
+
/* should not happen because atom here is not aliased */
|
522
|
+
if ( num_iso_H ) {
|
523
|
+
if ( num_H >= num_iso_H ) {
|
524
|
+
num_H -= num_iso_H;
|
525
|
+
} else {
|
526
|
+
num_H = inp_num_H; /* as requested in the alias */
|
527
|
+
/* num_H = (num_iso_H - num_H) % 2; */ /* keep unchanged parity of the total number of H atoms */
|
528
|
+
}
|
529
|
+
}
|
530
|
+
/* should not happen because atom here is not aliased */
|
531
|
+
if ( inp_num_H > num_H ) {
|
532
|
+
num_H = inp_num_H; /* as requested in the alias */
|
533
|
+
/* num_H = inp_num_H + (inp_num_H - num_H)%2; */ /* keep unchanged parity of the number of non-isotopic H atoms */
|
534
|
+
}
|
535
|
+
} else {
|
536
|
+
num_H = inp_num_H;
|
537
|
+
}
|
538
|
+
return num_H;
|
539
|
+
}
|
540
|
+
/***********************************************************************************/
|
541
|
+
int get_atw_from_elnum( int nAtNum )
|
542
|
+
{
|
543
|
+
nAtNum -= 1;
|
544
|
+
if ( 0 < nAtNum )
|
545
|
+
nAtNum += 2; /* bypass D, T */
|
546
|
+
if ( 0 <= nAtNum && nAtNum < nElDataLen ) {
|
547
|
+
return (int)ElData[nAtNum].nAtMass;
|
548
|
+
}
|
549
|
+
return 0;
|
550
|
+
}
|
551
|
+
/***********************************************************************************/
|
552
|
+
/*
|
553
|
+
int get_mw(char elname[])
|
554
|
+
{
|
555
|
+
int i;
|
556
|
+
|
557
|
+
for (i=0; i<NUMEL; i++)
|
558
|
+
if (strcmp(elname,elements[i])==0)
|
559
|
+
return(atomic_wt[i]);
|
560
|
+
return(0);
|
561
|
+
}
|
562
|
+
*/
|
563
|
+
/***********************************************************************************/
|
564
|
+
#ifndef INCHI_LIBRARY
|
565
|
+
/***********************************************************************************/
|
566
|
+
int get_atw(const char *elname)
|
567
|
+
{
|
568
|
+
int el_number, atw;
|
569
|
+
if ( ERR_ELEM != (el_number = get_el_number( elname )) ) {
|
570
|
+
atw = ElData[el_number].nAtMass;
|
571
|
+
} else {
|
572
|
+
atw = 0;
|
573
|
+
}
|
574
|
+
return atw;
|
575
|
+
}
|
576
|
+
/***********************************************************************************/
|
577
|
+
int normalize_name( char* name )
|
578
|
+
{
|
579
|
+
/* remove leading & trailing spaces; replace consecutive spaces with a single space */
|
580
|
+
/* Treat non-printable characters (Greeks) as spaces. 11-23-99 DCh. */
|
581
|
+
int i, len, n;
|
582
|
+
len = (int)strlen(name);
|
583
|
+
for ( i = 0, n = 0; i < len; i++ ) {
|
584
|
+
if ( isspace( UCINT name[i] ) /*|| !isprint( UCINT name[i] )*/ ) {
|
585
|
+
name[i] = ' '; /* exterminate tabs !!! */
|
586
|
+
n++;
|
587
|
+
} else {
|
588
|
+
if ( n > 0 ) {
|
589
|
+
memmove( (void*) &name[i-n], (void*) &name[i], len-i+1 );
|
590
|
+
i -= n;
|
591
|
+
len -= n;
|
592
|
+
}
|
593
|
+
n = -1;
|
594
|
+
}
|
595
|
+
}
|
596
|
+
if ( n == len ) /* empty line */
|
597
|
+
name[len=0] = '\0';
|
598
|
+
else
|
599
|
+
if ( ++n && n <= len ) {
|
600
|
+
len -= n;
|
601
|
+
name[len] = '\0';
|
602
|
+
}
|
603
|
+
return len;
|
604
|
+
}
|
605
|
+
#endif /* ifndef INCHI_LIBRARY */
|
606
|
+
/************************************************/
|
607
|
+
#ifndef inchi_malloc
|
608
|
+
void *inchi_malloc(size_t c)
|
609
|
+
{
|
610
|
+
return malloc(c);
|
611
|
+
}
|
612
|
+
#endif
|
613
|
+
#ifndef inchi_calloc
|
614
|
+
void *inchi_calloc(size_t c, size_t n)
|
615
|
+
{
|
616
|
+
return calloc(c,n);
|
617
|
+
}
|
618
|
+
#endif
|
619
|
+
#ifndef inchi_free
|
620
|
+
void inchi_free(void *p)
|
621
|
+
{
|
622
|
+
if(p) {
|
623
|
+
free(p); /*added check if zero*/
|
624
|
+
}
|
625
|
+
}
|
626
|
+
#endif
|
627
|
+
|
628
|
+
#ifndef INCHI_LIBRARY
|
629
|
+
/*******************************************************************/
|
630
|
+
char *fgetsTab( char *szLine, int len, FILE *f );
|
631
|
+
/*******************************************************************/
|
632
|
+
/* read up to len or tab or LF; if empty read next until finds non-empty line */
|
633
|
+
/* remove leading and trailing white spaces; keep zero termination */
|
634
|
+
/*******************************************************************/
|
635
|
+
char *fgetsTab( char *szLine, int len, FILE *f )
|
636
|
+
{
|
637
|
+
int length=0, c;
|
638
|
+
len --;
|
639
|
+
while ( length < len && EOF != (c = fgetc( f )) ) {
|
640
|
+
if ( c == '\t' )
|
641
|
+
c = '\n';
|
642
|
+
szLine[length++] = (char)c;
|
643
|
+
if ( c == '\n' )
|
644
|
+
break;
|
645
|
+
}
|
646
|
+
if ( !length && EOF == c ) {
|
647
|
+
return NULL;
|
648
|
+
}
|
649
|
+
szLine[length] = '\0';
|
650
|
+
return szLine;
|
651
|
+
}
|
652
|
+
/*******************************************************************/
|
653
|
+
/* read up to len or tab or LF; if empty read next until finds non-empty line */
|
654
|
+
/* remove leading and trailing white spaces; keep zero termination */
|
655
|
+
/*******************************************************************/
|
656
|
+
int my_fgetsTab( char *szLine, int len, FILE *f, int *bTooLongLine )
|
657
|
+
{
|
658
|
+
int length;
|
659
|
+
char *p;
|
660
|
+
do {
|
661
|
+
p = fgetsTab( szLine, len-1, f );
|
662
|
+
if ( !p ) {
|
663
|
+
*bTooLongLine = 0;
|
664
|
+
return -1; /* end of file or cannot read */
|
665
|
+
}
|
666
|
+
szLine[len-1] = '\0';
|
667
|
+
/*
|
668
|
+
*bTooLongLine = !strchr( szLine, '\n' );
|
669
|
+
*/
|
670
|
+
p = strchr( szLine, '\n' );
|
671
|
+
*bTooLongLine = ( !p && ((int)strlen(szLine)) == len-2 );
|
672
|
+
LtrimRtrim( szLine, &length );
|
673
|
+
} while ( !length );
|
674
|
+
return length;
|
675
|
+
}
|
676
|
+
/*******************************************************************/
|
677
|
+
int my_fgetsTab1( char *szLine, int len, FILE *f, int *bTooLongLine )
|
678
|
+
{
|
679
|
+
int length;
|
680
|
+
char *p;
|
681
|
+
/*do {*/
|
682
|
+
p = fgetsTab( szLine, len-1, f );
|
683
|
+
if ( !p ) {
|
684
|
+
*bTooLongLine = 0;
|
685
|
+
return -1; /* end of file or cannot read */
|
686
|
+
}
|
687
|
+
szLine[len-1] = '\0';
|
688
|
+
/*
|
689
|
+
*bTooLongLine = !strchr( szLine, '\n' );
|
690
|
+
*/
|
691
|
+
p = strchr( szLine, '\n' );
|
692
|
+
*bTooLongLine = ( !p && ((int)strlen(szLine)) == len-2 );
|
693
|
+
LtrimRtrim( szLine, &length );
|
694
|
+
/*} while ( !length );*/
|
695
|
+
return length;
|
696
|
+
}
|
697
|
+
#endif
|
698
|
+
|
699
|
+
#ifndef INCHI_LIBRARY
|
700
|
+
/*******************************************************************/
|
701
|
+
/* read up to len; if empty read next until found non-empty line */
|
702
|
+
/* remove leading and trailing white spaces; keep zero termination */
|
703
|
+
/*******************************************************************/
|
704
|
+
int my_fgets( char *szLine, int len, FILE *f, int *bTooLongLine )
|
705
|
+
{
|
706
|
+
int length;
|
707
|
+
char *p;
|
708
|
+
do {
|
709
|
+
p = fgets( szLine, len-1, f );
|
710
|
+
if ( !p ) {
|
711
|
+
*bTooLongLine = 0;
|
712
|
+
return -1; /* end of file or cannot read */
|
713
|
+
}
|
714
|
+
szLine[len-1] = '\0';
|
715
|
+
p = strchr( szLine, '\n' );
|
716
|
+
*bTooLongLine = ( !p && ((int)strlen(szLine)) == len-2 );
|
717
|
+
LtrimRtrim( szLine, &length );
|
718
|
+
} while ( !length );
|
719
|
+
return length;
|
720
|
+
}
|
721
|
+
/********************************************************************/
|
722
|
+
int my_fgetsUpToLfOrTab( char *szLine, int len, FILE *f )
|
723
|
+
{
|
724
|
+
int length;
|
725
|
+
char *p;
|
726
|
+
char szSkip[256];
|
727
|
+
int bTooLongLine = 0;
|
728
|
+
do {
|
729
|
+
p = fgetsTab( szLine, len-1, f );
|
730
|
+
if ( !p ) {
|
731
|
+
return -1; /* end of file or cannot read */
|
732
|
+
}
|
733
|
+
szLine[len-1] = '\0';
|
734
|
+
/*
|
735
|
+
bTooLongLine = !strchr( szLine, '\n' );
|
736
|
+
*/
|
737
|
+
bTooLongLine = ( !p && ((int)strlen(szLine)) == len-2 );
|
738
|
+
LtrimRtrim( szLine, &length );
|
739
|
+
} while ( !length );
|
740
|
+
if ( bTooLongLine ) {
|
741
|
+
while ( p = fgetsTab( szSkip, sizeof(szSkip)-1, f ) ) {
|
742
|
+
szSkip[sizeof(szSkip)-1] = '\0';
|
743
|
+
if ( strchr( szSkip, '\n' ) )
|
744
|
+
break;
|
745
|
+
}
|
746
|
+
}
|
747
|
+
return length;
|
748
|
+
}
|
749
|
+
/******************************************************************/
|
750
|
+
/* read not more than line_len bytes from an lf-terminated line */
|
751
|
+
/* if input line is too long quietly ignore the rest of the line */
|
752
|
+
char* fgets_up_to_lf( char* line, int line_len, FILE* inp )
|
753
|
+
{
|
754
|
+
char *p, *q;
|
755
|
+
memset( line, 0, line_len );
|
756
|
+
if ( NULL != (p = fgets( line, line_len, inp ) ) && NULL == strchr(p, '\n' ) ){
|
757
|
+
char temp[64]; /* bypass up to '\n' or up to end of file whichever comes first*/
|
758
|
+
while ( NULL != fgets( temp, sizeof(temp), inp ) && NULL == strchr(temp,'\n') )
|
759
|
+
;
|
760
|
+
}
|
761
|
+
if ( p && (q = strchr(line, '\r')) ) { /* fix CR CR LF line terminator. */
|
762
|
+
q[0] = '\n';
|
763
|
+
q[1] = '\0';
|
764
|
+
}
|
765
|
+
return p;
|
766
|
+
}
|
767
|
+
/*************************************************************************/
|
768
|
+
void remove_trailing_spaces( char* p )
|
769
|
+
{
|
770
|
+
int len;
|
771
|
+
for( len = (int)strlen( p ) - 1; len >= 0 && isspace( UCINT p[len] ); len-- )
|
772
|
+
;
|
773
|
+
p[++len] = '\0';
|
774
|
+
}
|
775
|
+
/*************************************************************************/
|
776
|
+
void remove_one_lf( char* p)
|
777
|
+
{
|
778
|
+
size_t len;
|
779
|
+
if ( p && 0 < (len = strlen(p)) && p[len-1] == '\n' ){
|
780
|
+
p[len-1] = '\0';
|
781
|
+
if ( len >= 2 && p[len-2] == '\r' )
|
782
|
+
p[len-2] = '\0';
|
783
|
+
}
|
784
|
+
}
|
785
|
+
#endif /* ifndef INCHI_LIBRARY */
|
786
|
+
/***************************************************************************/
|
787
|
+
/* Copies up to maxlen characters INCLUDING end null from source to target */
|
788
|
+
/* Fills out the rest of the target with null bytes */
|
789
|
+
int mystrncpy(char *target,const char *source,unsigned maxlen)
|
790
|
+
{ /* protected from non-zero-terminated source and overlapped target/source. 7-9-99 DCh. */
|
791
|
+
const char *p;
|
792
|
+
unsigned len;
|
793
|
+
|
794
|
+
if (target==NULL || maxlen == 0 || source == NULL)
|
795
|
+
return 0;
|
796
|
+
if ( p = (const char*)memchr(source, 0, maxlen) ) {
|
797
|
+
len = p-source; /* maxlen does not include the found zero termination */
|
798
|
+
} else {
|
799
|
+
len = maxlen-1; /* reduced length does not include one more byte for zero termination */
|
800
|
+
}
|
801
|
+
if ( len )
|
802
|
+
memmove( target, source, len );
|
803
|
+
/* target[len] = '\0'; */
|
804
|
+
memset( target+len, 0, maxlen-len); /* zero termination */
|
805
|
+
return 1;
|
806
|
+
}
|
807
|
+
/************************************************************************/
|
808
|
+
/* Remove leading and trailing white spaces */
|
809
|
+
char* LtrimRtrim( char *p, int* nLen )
|
810
|
+
{
|
811
|
+
int i, len=0;
|
812
|
+
if ( p && (len = strlen( p )) ) {
|
813
|
+
for ( i = 0; i < len && __isascii( p[i] ) && isspace( p[i] ); i++ )
|
814
|
+
;
|
815
|
+
if ( i )
|
816
|
+
(memmove)( p, p+i, (len -= i)+1 );
|
817
|
+
for ( ; 0 < len && __isascii( p[len-1] ) && isspace( p[len-1] ); len-- )
|
818
|
+
;
|
819
|
+
p[len] = '\0';
|
820
|
+
}
|
821
|
+
if ( nLen )
|
822
|
+
*nLen = len;
|
823
|
+
return p;
|
824
|
+
}
|
825
|
+
/*************************************************************************/
|
826
|
+
AT_NUMB *is_in_the_list( AT_NUMB *pathAtom, AT_NUMB nNextAtom, int nPathLen )
|
827
|
+
{
|
828
|
+
for ( ; nPathLen && *pathAtom != nNextAtom; nPathLen--, pathAtom++ )
|
829
|
+
;
|
830
|
+
return nPathLen? pathAtom : NULL;
|
831
|
+
}
|
832
|
+
/************************************************************************/
|
833
|
+
int num_of_H( inp_ATOM *at, int iat )
|
834
|
+
{
|
835
|
+
static int el_number_H;
|
836
|
+
int i, n, num_explicit_H = 0;
|
837
|
+
inp_ATOM *a = at + iat;
|
838
|
+
if ( !el_number_H )
|
839
|
+
el_number_H = get_periodic_table_number( "H" );
|
840
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
841
|
+
n = a->neighbor[i];
|
842
|
+
num_explicit_H += ( 1 == at[n].valence && el_number_H == at[n].el_number );
|
843
|
+
}
|
844
|
+
return num_explicit_H+NUMH(at,iat);
|
845
|
+
}
|
846
|
+
/************************************************************************/
|
847
|
+
int has_other_ion_neigh( inp_ATOM *at, int iat, int iat_ion_neigh, const char *el, int el_len )
|
848
|
+
{
|
849
|
+
int charge = at[iat_ion_neigh].charge;
|
850
|
+
int i, neigh;
|
851
|
+
for ( i = 0; i < at[iat].valence; i ++ ) {
|
852
|
+
neigh = at[iat].neighbor[i];
|
853
|
+
if ( neigh != iat_ion_neigh && at[neigh].charge == charge &&
|
854
|
+
NULL != memchr( el, at[neigh].el_number, el_len ) ) {
|
855
|
+
return 1;
|
856
|
+
}
|
857
|
+
}
|
858
|
+
return 0;
|
859
|
+
}
|
860
|
+
/************************************************************************/
|
861
|
+
/* BFS r=2 */
|
862
|
+
int has_other_ion_in_sphere_2(inp_ATOM *at, int iat, int iat_ion_neigh, const char *el, int el_len )
|
863
|
+
{
|
864
|
+
#define MAXQ 16
|
865
|
+
AT_NUMB q[MAXQ];
|
866
|
+
int lenq=0, lenq2, dist = 0, i = 0, iq, neigh, j, nRet=0;
|
867
|
+
q[lenq++] = iat;
|
868
|
+
at[iat].cFlags = 1;
|
869
|
+
|
870
|
+
iq = 0;
|
871
|
+
dist = 1;
|
872
|
+
/* use at->cFlags as an indicator */
|
873
|
+
while ( dist <= 2 ) {
|
874
|
+
for ( lenq2 = lenq; iq < lenq2; iq ++ ) {
|
875
|
+
i = q[iq];
|
876
|
+
for ( j = 0; j < at[i].valence; j ++ ) {
|
877
|
+
neigh = at[i].neighbor[j];
|
878
|
+
if ( !at[neigh].cFlags &&
|
879
|
+
at[neigh].valence <= 3 &&
|
880
|
+
NULL != memchr( el, at[neigh].el_number, el_len ) ) {
|
881
|
+
q[lenq ++] = neigh;
|
882
|
+
at[neigh].cFlags = 1;
|
883
|
+
if ( neigh != iat_ion_neigh &&
|
884
|
+
at[iat_ion_neigh].charge == at[neigh].charge ) {
|
885
|
+
nRet ++;
|
886
|
+
}
|
887
|
+
}
|
888
|
+
}
|
889
|
+
}
|
890
|
+
dist ++;
|
891
|
+
}
|
892
|
+
for ( iq = 0; iq < lenq; iq ++ ) {
|
893
|
+
i = q[iq];
|
894
|
+
at[i].cFlags = 0;
|
895
|
+
}
|
896
|
+
return nRet;
|
897
|
+
}
|
898
|
+
/************************************************************************/
|
899
|
+
int nNoMetalNumBonds( inp_ATOM *at, int at_no )
|
900
|
+
{
|
901
|
+
inp_ATOM *a = at + at_no;
|
902
|
+
int num_H = NUMH(a, 0);
|
903
|
+
int std_chem_bonds_valence = get_el_valence( a->el_number, a->charge, 0 );
|
904
|
+
int i;
|
905
|
+
if ( a->chem_bonds_valence + num_H > std_chem_bonds_valence ) {
|
906
|
+
int valence_to_metal = 0;
|
907
|
+
int num_bonds_to_metal = 0;
|
908
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
909
|
+
if ( is_el_a_metal( at[(int)a->neighbor[i]].el_number ) ) {
|
910
|
+
if ( (a->bond_type[i] & BOND_TYPE_MASK) >= BOND_TYPE_ALTERN ) {
|
911
|
+
return a->valence; /* fall back */
|
912
|
+
}
|
913
|
+
num_bonds_to_metal ++;
|
914
|
+
valence_to_metal += (a->bond_type[i] & BOND_TYPE_MASK);
|
915
|
+
}
|
916
|
+
}
|
917
|
+
if ( a->chem_bonds_valence + num_H - valence_to_metal == std_chem_bonds_valence ) {
|
918
|
+
/* removing bonds to metal produces standard valence */
|
919
|
+
return a->valence - num_bonds_to_metal;
|
920
|
+
}
|
921
|
+
}
|
922
|
+
#if( S_VI_O_PLUS_METAL_FIX_BOND == 1 )
|
923
|
+
else
|
924
|
+
if ( 1 == a->charge && 2 == get_endpoint_valence(a->el_number) &&
|
925
|
+
a->chem_bonds_valence + num_H == std_chem_bonds_valence ) {
|
926
|
+
int valence_to_metal = 0;
|
927
|
+
int num_bonds_to_metal = 0;
|
928
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
929
|
+
if ( is_el_a_metal( at[(int)a->neighbor[i]].el_number ) ) {
|
930
|
+
if ( (a->bond_type[i] & BOND_TYPE_MASK) >= BOND_TYPE_ALTERN ) {
|
931
|
+
return a->valence; /* fall back */
|
932
|
+
}
|
933
|
+
num_bonds_to_metal ++;
|
934
|
+
valence_to_metal += (a->bond_type[i] & BOND_TYPE_MASK);
|
935
|
+
}
|
936
|
+
}
|
937
|
+
if ( 1 == valence_to_metal ) {
|
938
|
+
/* removing bonds to metal produces standard valence */
|
939
|
+
return a->valence - num_bonds_to_metal;
|
940
|
+
}
|
941
|
+
}
|
942
|
+
#endif
|
943
|
+
|
944
|
+
return a->valence;
|
945
|
+
}
|
946
|
+
/************************************************************************/
|
947
|
+
int nNoMetalBondsValence( inp_ATOM *at, int at_no )
|
948
|
+
{
|
949
|
+
inp_ATOM *a = at + at_no;
|
950
|
+
int num_H = NUMH(a, 0);
|
951
|
+
int std_chem_bonds_valence = get_el_valence( a->el_number, a->charge, 0 );
|
952
|
+
int i;
|
953
|
+
if ( a->chem_bonds_valence + num_H > std_chem_bonds_valence ) {
|
954
|
+
int valence_to_metal = 0;
|
955
|
+
/*int num_bonds_to_metal = 0;*/
|
956
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
957
|
+
if ( is_el_a_metal( at[(int)a->neighbor[i]].el_number ) ) {
|
958
|
+
if ( (a->bond_type[i] & BOND_TYPE_MASK) >= BOND_TYPE_ALTERN ) {
|
959
|
+
return a->valence; /* fall back */
|
960
|
+
}
|
961
|
+
/*num_bonds_to_metal ++;*/
|
962
|
+
valence_to_metal += (a->bond_type[i] & BOND_TYPE_MASK);
|
963
|
+
}
|
964
|
+
}
|
965
|
+
if ( a->chem_bonds_valence + num_H - valence_to_metal == std_chem_bonds_valence ) {
|
966
|
+
/* removing bonds to metal produces standard valence */
|
967
|
+
return a->chem_bonds_valence - valence_to_metal;
|
968
|
+
}
|
969
|
+
}
|
970
|
+
#if( S_VI_O_PLUS_METAL_FIX_BOND == 1 )
|
971
|
+
else
|
972
|
+
if ( 1 == a->charge && 2 == get_endpoint_valence(a->el_number) &&
|
973
|
+
a->chem_bonds_valence + num_H == std_chem_bonds_valence ) {
|
974
|
+
int valence_to_metal = 0;
|
975
|
+
/*int num_bonds_to_metal = 0;*/
|
976
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
977
|
+
if ( is_el_a_metal( at[(int)a->neighbor[i]].el_number ) ) {
|
978
|
+
if ( (a->bond_type[i] & BOND_TYPE_MASK) >= BOND_TYPE_ALTERN ) {
|
979
|
+
return a->valence; /* fall back */
|
980
|
+
}
|
981
|
+
/*num_bonds_to_metal ++;*/
|
982
|
+
valence_to_metal += (a->bond_type[i] & BOND_TYPE_MASK);
|
983
|
+
}
|
984
|
+
}
|
985
|
+
if ( 1 == valence_to_metal ) {
|
986
|
+
/* removing bonds to metal produces standard valence */
|
987
|
+
return a->chem_bonds_valence - valence_to_metal;
|
988
|
+
}
|
989
|
+
}
|
990
|
+
#endif
|
991
|
+
return a->chem_bonds_valence;
|
992
|
+
}
|
993
|
+
/************************************************************************/
|
994
|
+
int nNoMetalNeighIndex( inp_ATOM *at, int at_no )
|
995
|
+
{
|
996
|
+
inp_ATOM *a = at + at_no;
|
997
|
+
int i;
|
998
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
999
|
+
if ( !is_el_a_metal( at[(int)a->neighbor[i]].el_number ) ) {
|
1000
|
+
return i;
|
1001
|
+
}
|
1002
|
+
}
|
1003
|
+
return -1;
|
1004
|
+
}
|
1005
|
+
/************************************************************************/
|
1006
|
+
int nNoMetalOtherNeighIndex( inp_ATOM *at, int at_no, int cur_neigh )
|
1007
|
+
{
|
1008
|
+
inp_ATOM *a = at + at_no;
|
1009
|
+
int i, neigh;
|
1010
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
1011
|
+
neigh = (int)a->neighbor[i];
|
1012
|
+
if ( neigh != cur_neigh && !is_el_a_metal( at[neigh].el_number ) ) {
|
1013
|
+
return i;
|
1014
|
+
}
|
1015
|
+
}
|
1016
|
+
return -1;
|
1017
|
+
}
|
1018
|
+
/************************************************************************/
|
1019
|
+
int nNoMetalOtherNeighIndex2( inp_ATOM *at, int at_no, int cur_neigh, int cur_neigh2 )
|
1020
|
+
{
|
1021
|
+
inp_ATOM *a = at + at_no;
|
1022
|
+
int i, neigh;
|
1023
|
+
for ( i = 0; i < a->valence; i ++ ) {
|
1024
|
+
neigh = (int)a->neighbor[i];
|
1025
|
+
if ( neigh != cur_neigh && neigh != cur_neigh2 && !is_el_a_metal( at[neigh].el_number ) ) {
|
1026
|
+
return i;
|
1027
|
+
}
|
1028
|
+
}
|
1029
|
+
return -1;
|
1030
|
+
}
|
1031
|
+
|
1032
|
+
|
1033
|
+
#ifndef INCHI_ANSI_ONLY
|
1034
|
+
/**************************************************************************/
|
1035
|
+
int MakeRemovedProtonsString( int nNumRemovedProtons, NUM_H *nNumExchgIsotopicH, NUM_H *nNumRemovedProtonsIsotopic,
|
1036
|
+
int bIsotopic, char *szRemovedProtons, int *num_removed_iso_H )
|
1037
|
+
{
|
1038
|
+
int i, j, len, num;
|
1039
|
+
len = 0;
|
1040
|
+
if ( nNumRemovedProtons ) {
|
1041
|
+
len = sprintf ( szRemovedProtons, "Proton balance: %c %d H+",
|
1042
|
+
nNumRemovedProtons>=0? '+':'-', abs(nNumRemovedProtons) );
|
1043
|
+
}
|
1044
|
+
if ( bIsotopic && (nNumRemovedProtonsIsotopic || nNumExchgIsotopicH) ) {
|
1045
|
+
for ( i = 0, j = 0; i < NUM_H_ISOTOPES; i ++ ) {
|
1046
|
+
num = (nNumExchgIsotopicH? nNumExchgIsotopicH[i]:0) +
|
1047
|
+
(nNumRemovedProtonsIsotopic? nNumRemovedProtonsIsotopic[i]:0);
|
1048
|
+
if ( num ) {
|
1049
|
+
len += sprintf( szRemovedProtons+len, "%s %d^%dH",
|
1050
|
+
j? ", ":" [ removed ", num, i+1);
|
1051
|
+
j ++;
|
1052
|
+
}
|
1053
|
+
}
|
1054
|
+
if ( j ) {
|
1055
|
+
len += sprintf( szRemovedProtons+len, " ]" );
|
1056
|
+
if ( num_removed_iso_H )
|
1057
|
+
*num_removed_iso_H = j;
|
1058
|
+
}
|
1059
|
+
}
|
1060
|
+
if ( !len ) {
|
1061
|
+
szRemovedProtons[0] = '\0';
|
1062
|
+
}
|
1063
|
+
return len;
|
1064
|
+
}
|
1065
|
+
#endif
|
1066
|
+
|
1067
|
+
#ifdef INCHI_ANSI_ONLY
|
1068
|
+
/*************************************************************************/
|
1069
|
+
/************* non-ANSI functions ****************/
|
1070
|
+
/*************************************************************************/
|
1071
|
+
#define __MYTOLOWER(c) ( ((c) >= 'A') && ((c) <= 'Z') ? ((c) - 'A' + 'a') : (c) )
|
1072
|
+
|
1073
|
+
#if ( !defined(_MSC_VER) || defined(__STDC__) && __STDC__ == 1 )
|
1074
|
+
/* support (VC++ Language extensions) = OFF && defined(INCHI_ANSI_ONLY) */
|
1075
|
+
int memicmp ( const void * p1, const void * p2, size_t length )
|
1076
|
+
{
|
1077
|
+
const U_CHAR *s1 = (const U_CHAR*)p1;
|
1078
|
+
const U_CHAR *s2 = (const U_CHAR*)p2;
|
1079
|
+
while ( length-- ) {
|
1080
|
+
if ( *s1 == *s2 ||
|
1081
|
+
__MYTOLOWER( (int)*s1 ) == __MYTOLOWER( (int)*s2 )) {
|
1082
|
+
s1 ++;
|
1083
|
+
s2 ++;
|
1084
|
+
} else {
|
1085
|
+
return __MYTOLOWER( (int)*s1 ) - __MYTOLOWER( (int)*s2 );
|
1086
|
+
}
|
1087
|
+
}
|
1088
|
+
return 0;
|
1089
|
+
}
|
1090
|
+
/*************************************************************************/
|
1091
|
+
int stricmp( const char *s1, const char *s2 )
|
1092
|
+
{
|
1093
|
+
while ( *s1 ) {
|
1094
|
+
if ( *s1 == *s2 ||
|
1095
|
+
__MYTOLOWER( (int)*s1 ) == __MYTOLOWER( (int)*s2 )) {
|
1096
|
+
s1 ++;
|
1097
|
+
s2 ++;
|
1098
|
+
} else {
|
1099
|
+
return __MYTOLOWER( (int)*s1 ) - __MYTOLOWER( (int)*s2 );
|
1100
|
+
}
|
1101
|
+
}
|
1102
|
+
if ( *s2 )
|
1103
|
+
return -1;
|
1104
|
+
return 0;
|
1105
|
+
}
|
1106
|
+
/*************************************************************************/
|
1107
|
+
char *_strnset( char *s, int val, size_t length )
|
1108
|
+
{
|
1109
|
+
char *ps = s;
|
1110
|
+
while (length-- && *ps)
|
1111
|
+
*ps++ = (char)val;
|
1112
|
+
return s;
|
1113
|
+
}
|
1114
|
+
/*************************************************************************/
|
1115
|
+
char *_strdup( const char *string )
|
1116
|
+
{
|
1117
|
+
char *p = NULL;
|
1118
|
+
if ( string ) {
|
1119
|
+
size_t length = strlen( string );
|
1120
|
+
p = (char *)inchi_malloc( length + 1 );
|
1121
|
+
if ( p ) {
|
1122
|
+
strcpy( p, string );
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
return p;
|
1126
|
+
}
|
1127
|
+
#endif
|
1128
|
+
#endif
|
1129
|
+
|
1130
|
+
|