rino 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|