Subversion Repositories wimsdev

Rev

Rev 6789 | Rev 14249 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.    Modified to run w/o p2c libraries
  3.    2007 Ernst-Georg Schmid
  4.    Modified to run as shared library
  5.    2007 Ernst-Georg Schmid
  6.    pgchem@tuschehund.de
  7.    
  8.    compile with gcc without optimizations (except -march= -mcpu=) or it gets SLOWER!
  9.    
  10.    THIS VERSION HAS extended_molstat SWITCHED ON BY DEFAULT!
  11.    
  12.    This file is part of the xchem::tigress project.
  13.  
  14.    --- DUAL LICENSING ---
  15.    
  16.    If checkmol.c aka. pgchem::barsoi is compiled as a library, it is released under the terms of the
  17.    lesser GNU General Public License. For the executable, the original GPL
  18.    licensing applies!
  19.    
  20.    This program is free software; you can redistribute it and/or modify
  21.    it under the terms of the lesser GNU General Public License as published by
  22.    the Free Software Foundation version 2.1 of the License.
  23.  
  24.    This program is distributed in the hope that it will be useful,
  25.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.    lesser GNU General Public License for more details.
  28.    
  29.    --- DUAL LICENSING ---
  30.  
  31.    ORIGINAL HEADER:
  32.    
  33. checkmol/matchmol
  34. Norbert Haider, University of Vienna, 2003-2007
  35. norbert.haider@univie.ac.at
  36.  
  37. This software is published under the terms of the GNU General Public
  38. License (GPL, see below). For a detailed description of this license,
  39. see http://www.gnu.org/copyleft/gpl.html
  40.  
  41. If invoked as "checkmol", this program reads 2D and 3D molecular structure
  42. files in various formats (Tripos Alchemy "mol", Tripos SYBYL "mol2", MDL "mol")
  43. and describes the molecule either by its functional groups or by a set of
  44. descriptors useful for database pre-screening (number of rings, sp2-hybridized
  45. carbons, aromatic bonds, etc.; see definition of molstat_rec).
  46.  
  47. If invoked as "matchmol", the program reads two individual 2D or 3D molecular
  48. structure files in various formats (see above) and checks if the first molecule
  49. (the "needle") is a substructure of the second one (the "haystack").
  50. "Haystack" can also be a MDL SD-file (containing multiple MOL files);
  51. if invoked with "-" as file argument, both "needle" and "haystack" are
  52. read as an SD-file from standard input, assuming the first entry in
  53. the SDF to be the "needle"; output: entry number + ":F" (false) or ":T" (true)
  54.  
  55.  
  56. Compile with fpc (Free Pascal, see http://www.freepascal.org), using
  57. the -Sd or -S2 option (Delphi mode; IMPORTANT!)
  58.  
  59. example for compilation (with optimization) and installation:
  60.  
  61. fpc checkmol.pas -S2 -Xs -OG -Or -O2u -Op1
  62.  
  63. as "root", do the following:
  64.  
  65. cp checkmol /usr/local/bin
  66. cd /usr/local/bin
  67. ln checkmol matchmol
  68.  
  69.  
  70. Version history
  71.  
  72. v0.1   extends "chkmol" utility (N. Haider, 2002), adds matching functionality;
  73.  
  74. v0.1a  minor bugfixes:
  75.        stop ring search when max_rings is reached (function is_ringpath);
  76.        fixed upper/lowercase of element symbol in MDL molfile output;
  77.        added debug output for checkmol (-D option)
  78.  
  79. v0.2   added functionality to switch ring search from SAR (set of all rings) to
  80.        SSR (set of small rings; see below) if number of rings exceeds max_rings
  81.        (1024), e.g. with Buckminster-fullerenes (thanks to E.-G. Schmid for a hint);
  82.        added -r command-line option to force ring search into SSR mode;
  83.        as SSR, we regard the set of all rings with max. 10 ring members, and in
  84.        which no ring is completely contained in another one
  85.  
  86. v0.2a  fixed a bug in function is_ringpath which could cause SAR ring search to
  87.        overlook a few rings (e.g., the six 8-membered rings in cubane)
  88.  
  89. v0.2b  fixed unequal treatment of needle and haystack structures with respect
  90.        to aromaticity check (trusting input file vs. full check)
  91.  
  92. v0.2c  modified the changes of v0.2b so that they affect only "matchmol" mode;
  93.        added quick_match function
  94.  
  95. v0.2d  refined function bondtypes_OK so that it does not accept C=O fragments
  96.        (and C=S, C=Se, C=Te) as equivalent to aromatic C-O (C-S, C-Se, C-Te);
  97.        fixed function find_ndl_ref_atom to use only heavy atoms as "needle"
  98.        reference atoms for atom-to-atom match; update function quick_match to
  99.        handle queries with only one heavy atom (thanks to A. Barozza for a hint)
  100.  
  101. v0.2e  modified procedure get_molstat: adds 1 formal double bond for each aromatic
  102.        ring to the "fingerprint" in order to allow an isolated double bond in the
  103.        needle to be matched as a fragment of an aromatic ring
  104.        ATTENTION: "fingerprints" (molecular statistics) generated with a previous
  105.        version of checkmol(-x and -X option) must be updated for structure/
  106.        substructure database searching with matchmaol.
  107.  
  108. v0.2f  modified procedures chk_ccx, chk_xccx, write_fg_text, write_fg_text_de,
  109.        write_fg_code in order to report halogen derivatives other than alkyl halides,
  110.        aryl halides and acyl halides (e.g., vinyl halides) and C=C compounds other
  111.        than "true" alkenes, enols, enediols, enamines, etc. (e.g. vinyl halides);
  112.        added "strict mode" (option -s) for matching: this uses a more thorough
  113.        comparison of atom types and bond types (new functions atomtypes_OK_strict,
  114.        bondtypes_OK_strict, several minor modifications in other subroutines).
  115.  
  116. v0.2g  changed procedure readinputfile (+ minor changes in main routine) in
  117.        order to read very large SD input files without "not enough memory" error
  118.        (the previous version attempted to read the entire SD file into a buffer,
  119.        the new version reads only one molecule at once);
  120.        fixed a minor bug in read_mol2file which led to undefined bond types;
  121.        added definition of "debug" option as a compiler flag.
  122.  
  123. v0.2h  fixed a small bug which caused program hangs with (e.g.) some metal
  124.        complexes: this was solved just by increasing the number of possible
  125.        neighbor atoms from 8 to 16 (now defined in the constant max_neighbors).
  126.  
  127. v0.2i  introduced some more plausibility checking (number of directly connected
  128.        atoms), result stored in variable mol_OK (set in count_neighbors);
  129.        completely rewrote function matrix_OK which now can handle up to
  130.        max_neighbors substituents per atom (previous versions were limited to
  131.        4 substituents; larger numbers are required e.g. for ferrocenes and
  132.        similar compounds).
  133.  
  134. v0.2j  new function raw_hetbond_count: ignores bond order (in contrast to function
  135.        hetbond_count), this is better suitable for molecular statistics.
  136.        ATTENTION: previously generated "fingerprints" in databases must be updated!
  137.        improved recognition of non-conformant SD files (with missing "M  END" line)
  138.  
  139. v0.2k  changed quick_match routine to compare atom types only by element in
  140.        order to avoid (rare) cases of non-matching identical input files;
  141.        slightly changed error message for non-existant input files
  142.  
  143. v0.3   changed function update_Htotal in order to distinguish between 3-valent
  144.        and 5-valent phosphorus (thanks to H. Feldman for this suggestion);
  145.        added a table (array ringprop) to store ring sizes and aromaticity for
  146.        faster lookup; changed aromaticity detection (chk_arom) to be fully
  147.        independent of Kekule structures in condensed ring systems; changed add_ring
  148.        to store new rings in ascending order (with respect to ring size): this
  149.        will cause the aromaticity detection to start with smaller rings;
  150.        added additional calls to chk_arom when in SSR ring search mode (to ensure
  151.        that all aromatic rings are found); speeded up function is_newring;
  152.        added option "-M": this restores the behavior of previous versions,
  153.        i.e. metal atoms will be accepted as ring members (which costs a lot
  154.        of performance for coordinate compounds like ferrocenes but gives
  155.        only little useful information); when used in databases: use the _same_
  156.        mode ("-M" or not) _both_ for checkmol (creation of fingerprints) and matchmol;
  157.        fixed ugly linebreaks in show_usage;
  158.  
  159. v0.3a  fixed a bug in read_charges (which was introduced in the v0.3 code cleanup)
  160.  
  161. v0.3b  fixed recognition of ketenes, CO2, CS2, CSO, phosphines, boronic esters
  162.  
  163. v0.3c  fixed recognition of hydrazines, hydroxylamines, thiocarboxylic acids,
  164.        orthocarboxylic acids; slightly changed textual output for a few functional
  165.        groups
  166.  
  167. v0.3d  added bond topology feature ("any", "ring", "chain", as defined by MDL specs,
  168.        plus "always_any", "excess-ringcount", "exact-ringcount") to bond properties
  169.        and implemented its use for substructure searches, either as specified in the
  170.        query MDL molfile or by using "strict" mode; added ring_count property to
  171.        "bonds" section of Checkmol-tweaked molfiles (using an unused field in the MDL
  172.        molfile specs);
  173.        added option for E/Z isomer search, either globally (-g option) or per
  174.        double bond: bstereo_xyz property, encoded either by a leading "0" in the
  175.        bond block of a checkmol-tweaked molfile or by using the "stereo care" flag
  176.        as defined in the MDL file specs (both atoms of a double bond must carry
  177.        this flag)
  178.  
  179. v0.3e  fixed wrong position of "stereo care" flag expected in input molfile;
  180.  
  181. v0.3f  added option for enantiospecific search (R/S isomer search); this can be
  182.        turned on either globally (-G option or using the "chiral" flag in the
  183.        "counts line" of the query MDL molfile) or per atom (using - or abusing -
  184.        the "stereo care" flag); enantiomers are compared using the 3D coordinates
  185.        of the substituents at a chiral center, so we do not have to rely on the
  186.        presence of correct "up" and "down" bond types in the candidate structures;
  187.        nevertheless, "pseudo-3D" structures (i.e. flat 2D structures with "up"
  188.        and "down" bond notation) can be also used, even in mixed mode both as
  189.        query structure and candidate structure; added support for "up" and "down"
  190.        bond notation in MDL molfile output (if -m option is used and these bond
  191.        types were present in the input file); refined function find_ndl_ref_atom;
  192.        fixed Alchemy atom type misinterpretation (upper/lower case mismatch);
  193.  
  194. v0.3g  minor fixes: recognition of sp2 nitrogen in N=N structures (function
  195.        update_atypes); extended E/Z geometry check to C=N and N=N bonds; accelerated
  196.        exact search by initial comparison of C,O,N counts; added meaningful error
  197.        message for input structures with 0 (zero) atoms;
  198.  
  199. v0.3h  added a match matrix clean-up step to function is_matching in order to
  200.        remove "impossible" multiple matches prior to chirality check; added
  201.        function ndl_maybe_chiral as a plausibility check; added support for other
  202.        atoms than carbon as chiral centers; changed function is_cis from a
  203.        distance-based cis/trans check into a torsion-based check;
  204.  
  205. v0.3i  minor fixes in functions max_neighbors and chk_ammon;
  206.        revert ringsearch_mode to its original value for each new molecule
  207.        (main routine)
  208.  
  209. v0.3j  various improvements in checkmol: added alkenyl (vinyl) and alkynyl
  210.        residues as possible substituents for amides, esters, ethers, etc.;
  211.        extended recognition of orthocarboxylic acid derivatives; refined
  212.        recognition of oxohetarenes and iminohetareenes, ureas, nitroso
  213.        compounds; fixed reading of "old-style" charges from MDL files;
  214.        refined aromaticity check; fixed a bug in procedure chk_arom and
  215.        renamed function is_exocyclic_methylene_C into
  216.        find_exocyclic_methylene_C; added assignment of pointers to "nil"
  217.        after calling "freemem" in procedure zap_molecule and zap_needle;
  218.        matchmol: refined selection of needle reference atom; added "strict
  219.        chirality check" mode (if -x -s and -G options are used): returns
  220.        "false" if a chiral or pseudochiral atom is matched against its
  221.        counterpart with undefined or "flat" geometry; added an alternative
  222.        selection mechanism for the needle reference atom, based on the
  223.        Morgan algorithm;
  224.  
  225. v0.3k  improved matching of nitro compounds (ionic vs. non-ionic
  226.        representation); some finetuning in recognition of N-oxides,
  227.        hydroxylamines, etc.; modified get_molstat in order to ignore
  228.        charges in nitro groups, N-oxides, sulfoxides, azides, etc. in
  229.        ionic representation; added function normalize_ionic_bonds;
  230.        fixed a bug in is_alkenyl; fixed a bug (introduced in v0.3j) in
  231.        the treatment of "old-style" MDL charges;
  232.  
  233. v0.3l  minor adjustments in quick_match (for unknown atom types,
  234.        opposite charges); some performance improvements, e.g. in function
  235.        path_pos, reduced extensive calls to is_heavyatom and is_metal
  236.        by extending atom_rec with boolean fields 'heavy' and 'metal'
  237.        (thanks to E.-G.Schmid); added molstat field n_rBz (number of
  238.        benzene rings; deactivated by default); added -l command-line
  239.        option to checkmol (lists all molstat codes with a short
  240.        explanation); added graceful handling of NoStruct (i.e.,
  241.        zero-atom) molecules
  242.  
  243. v0.3m  minor bug fixes (chk_imine), let normalize_ionic_bonds return "true"
  244.        if some bond-order change was made; fixed incorrect implementation
  245.        of the Morgan algorithm (thanks to H.Feldman), fixed is_matching in
  246.        order to prevent wrong matches of larger rings on smaller ones; count
  247.        halogens also as type "X" in molstat (as before v0.3l); added some more
  248.        molstat descriptors for most elements (deactivated by default; for
  249.        activation, uncomment the definition of "extended_molstat", see below);
  250.        added support for the generation of binary fingerprints with output
  251.        either as boolean values (-f option) or as decimal values (-F option),
  252.        fingerprint patterns are supplied by the user (in SDF format, max. 62
  253.        structures per file); added a version check ("tweaklevel",
  254.        ringsearch_mode, opt_metalrings) for "tweaked" MDL molfiles
  255.  
  256. v0.3n  increased max_vringsize in SSR mode from 10 to 12 (now defined in
  257.        ssr_vringsize); optionally changed ring statistics to ignore envelope
  258.        rings (which completely contain another ring, "reduced SAR") in order to
  259.        make molstat in SAR and SSR mode more compatible) - disabled by default;
  260.        introduced a new molstat descriptor: n_br2p (number of bonds which
  261.        belong to two or more rings); changed n_b1 counter to ignore bonds to
  262.        explicit hydrogens; added procedure fix_ssr_ringcounts
  263.        (see comment in the code); added bond property mdl_stereo for preservation
  264.        of original value; slightly changed "get_molstat" and "update_atypes" in
  265.        order to consolidate atom type for various N atoms; remember "chiral" flag
  266.        status in molfile output (-m); modified chk_arom in order to accept rings
  267.        as aromatic if all bonds are of type 'A'; several minor bug fixes
  268.  
  269. v0.3o  minor changes in update_atypes (nitrogen); changed the matching
  270.        algorithm in order to take care of disconnected molecular graphs
  271.        (e.g., salts); refined matching of atoms with formal charges
  272.  
  273.  
  274. Credits:
  275.  
  276. Rami Jbara (rami_jbara@hotmail.com) designed the 8-character functional
  277. group codes.
  278.  
  279. I am also very grateful to Ernst-Georg Schmid (Bayer Business Services,
  280. Leverkusen/Germany) and to Howard Feldman (The Blueprint Initiative,
  281. Toronto/Canada) for numerous bug reports and suggestions for improvements.
  282.  
  283.  
  284.  
  285. ===============================================================================
  286. DISCLAIMER
  287. This program is free software; you can redistribute it and/or
  288. modify it under the terms of the GNU General Public License
  289. as published by the Free Software Foundation; either version 2
  290. of the License, or (at your option) any later version.
  291.  
  292. This program is distributed in the hope that it will be useful,
  293. but WITHOUT ANY WARRANTY; without even the implied warranty of
  294. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  295. GNU General Public License for more details.
  296.  
  297. You should have received a copy of the GNU General Public License
  298. along with this program; if not, write to the Free Software Foundation,
  299. Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  300. ===============================================================================
  301. */
  302.  
  303. /* $DEFINE debug                    uncomment if desired */
  304. /* $DEFINE extended_molstat         uncomment if desired */
  305. /* $DEFINE reduced_SAR              uncomment if desired */
  306.  
  307. /* uses
  308.   SYSUTILS, MATH; */
  309.  
  310. #include <stdlib.h>
  311. #include <stdio.h>
  312. #include <math.h>
  313. #include <string.h>
  314. #include <ctype.h>
  315. #include <sys/types.h>
  316. #include <sys/stat.h>
  317. #include "safemem.h"
  318. #ifdef MAKE_SHARED_LIBRARY
  319. #include "barsoi.h"
  320. #endif
  321.  
  322. #ifdef MAKE_SHARED_LIBRARY
  323. #define version         "0.3p C (pgchem::barsoi)"
  324. #else
  325. #define version         "0.3p C"
  326. #endif
  327.  
  328. #undef REDUCED_SAR
  329.  
  330. /* How many recursions before aborting is_ringpath and reverting to SSR */
  331. #define max_ringpath_recursion_depth   500000
  332.  
  333. /* How many recursions before aborting is_match and reverting to non-exhaustive match */
  334. #define max_match_recursion_depth   500000
  335.  
  336. #define tweaklevel      2
  337.     /* v0.3m; accept tweaks in MDL molfiles only if same level */
  338. #define max_atoms       1024
  339. #define max_bonds       1024
  340. #define slack           8192
  341. #define max_ringsize    128
  342. #define max_rings       1024
  343. #define max_fg          256
  344. #define max_neighbors   16      /* new in v0.2h */
  345.  
  346. #define TAB             '\t'
  347.  
  348. #define max_matchpath_length  256
  349. #define pmCheckMol      1001
  350. #define pmMatchMol      1002
  351.  
  352. #define rs_sar          2001    /* ring search mode: SAR = set of all rings */
  353. #define rs_ssr          2002
  354.     /*                   SSR = set of small rings */
  355.  
  356. #define btopo_any       0       /* bond topology, new in v0.3d */
  357. #define btopo_ring      1
  358. #define btopo_chain     2
  359. #define btopo_always_any  3     /* even in "strict mode" */
  360. #define btopo_excess_rc  4
  361. /* bond in candidate must be included in _more_ rings than
  362.                         the matching bond in the query ==> specific search for
  363.                         annulated systems */
  364. #define btopo_exact_rc  5
  365.     /* bond in query and candidate must have same ring count */
  366.  
  367. #define bstereo_any     0
  368.     /* new in v0.3d, any E/Z isomer matches (for double bonds) */
  369. #define bstereo_xyz     1
  370.     /* E/Z match is checked by using XYZ coordinates of the atoms */
  371. #define bstereo_up      11      /* new in v0.3f, flags for single bonds */
  372. #define bstereo_down    16
  373. #define bstereo_either    14    /* 0.3x */
  374. #define bstereo_double_either    13     /* 0.3x */
  375.  
  376. #define fpf_boolean     3001
  377.     /* v0.3m; format for fingerprint output (n:T, n:F) */
  378. #define fpf_decimal     3002
  379.     /* v0.3m; format for fingerprint output as decimal value of bitstring */
  380. #define fp_blocksize    62
  381.     /* v0.3m; 1 bit may be used for sign (e.g. by PHP), 1 bit for "exact hit" */
  382. #define ssr_vringsize   12      /* v0.3n; max. ring size in SSR mode */
  383.  
  384. /* Definitions for functional groups: */
  385. #define fg_cation       1
  386. #define fg_anion        2
  387. #define fg_carbonyl     3
  388. #define fg_aldehyde     4
  389. #define fg_ketone       5
  390. #define fg_thiocarbonyl  6
  391. #define fg_thioaldehyde  7
  392. #define fg_thioketone   8
  393. #define fg_imine        9
  394. #define fg_hydrazone    10
  395. #define fg_semicarbazone  11
  396. #define fg_thiosemicarbazone  12
  397. #define fg_oxime        13
  398. #define fg_oxime_ether  14
  399. #define fg_ketene       15
  400. #define fg_ketene_acetal_deriv  16
  401. #define fg_carbonyl_hydrate  17
  402. #define fg_hemiacetal   18
  403. #define fg_acetal       19
  404. #define fg_hemiaminal   20
  405. #define fg_aminal       21
  406. #define fg_thiohemiaminal  22
  407. #define fg_thioacetal   23
  408. #define fg_enamine      24
  409. #define fg_enol         25
  410. #define fg_enolether    26
  411. #define fg_hydroxy      27
  412. #define fg_alcohol      28
  413. #define fg_prim_alcohol  29
  414. #define fg_sec_alcohol  30
  415. #define fg_tert_alcohol  31
  416. #define fg_1_2_diol     32
  417. #define fg_1_2_aminoalcohol  33
  418. #define fg_phenol       34
  419. #define fg_1_2_diphenol  35
  420. #define fg_enediol      36
  421. #define fg_ether        37
  422. #define fg_dialkylether  38
  423. #define fg_alkylarylether  39
  424. #define fg_diarylether  40
  425. #define fg_thioether    41
  426. #define fg_disulfide    42
  427. #define fg_peroxide     43
  428. #define fg_hydroperoxide  44
  429. #define fg_hydrazine    45
  430. #define fg_hydroxylamine  46
  431. #define fg_amine        47
  432. #define fg_prim_amine   48
  433. #define fg_prim_aliph_amine  49
  434. #define fg_prim_arom_amine  50
  435. #define fg_sec_amine    51
  436. #define fg_sec_aliph_amine  52
  437. #define fg_sec_mixed_amine  53
  438. #define fg_sec_arom_amine  54
  439. #define fg_tert_amine   55
  440. #define fg_tert_aliph_amine  56
  441. #define fg_tert_mixed_amine  57
  442. #define fg_tert_arom_amine  58
  443. #define fg_quart_ammonium  59
  444. #define fg_n_oxide      60
  445. #define fg_halogen_deriv  61
  446. #define fg_alkyl_halide  62
  447. #define fg_alkyl_fluoride  63
  448. #define fg_alkyl_chloride  64
  449. #define fg_alkyl_bromide  65
  450. #define fg_alkyl_iodide  66
  451. #define fg_aryl_halide  67
  452. #define fg_aryl_fluoride  68
  453. #define fg_aryl_chloride  69
  454. #define fg_aryl_bromide  70
  455. #define fg_aryl_iodide  71
  456. #define fg_organometallic  72
  457. #define fg_organolithium  73
  458. #define fg_organomagnesium  74
  459. #define fg_carboxylic_acid_deriv  75
  460. #define fg_carboxylic_acid  76
  461. #define fg_carboxylic_acid_salt  77
  462. #define fg_carboxylic_acid_ester  78
  463. #define fg_lactone      79
  464. #define fg_carboxylic_acid_amide  80
  465. #define fg_carboxylic_acid_prim_amide  81
  466. #define fg_carboxylic_acid_sec_amide  82
  467. #define fg_carboxylic_acid_tert_amide  83
  468. #define fg_lactam       84
  469. #define fg_carboxylic_acid_hydrazide  85
  470. #define fg_carboxylic_acid_azide  86
  471. #define fg_hydroxamic_acid  87
  472. #define fg_carboxylic_acid_amidine  88
  473. #define fg_carboxylic_acid_amidrazone  89
  474. #define fg_nitrile      90
  475. #define fg_acyl_halide  91
  476. #define fg_acyl_fluoride  92
  477. #define fg_acyl_chloride  93
  478. #define fg_acyl_bromide  94
  479. #define fg_acyl_iodide  95
  480. #define fg_acyl_cyanide  96
  481. #define fg_imido_ester  97
  482. #define fg_imidoyl_halide  98
  483. #define fg_thiocarboxylic_acid_deriv  99
  484. #define fg_thiocarboxylic_acid  100
  485. #define fg_thiocarboxylic_acid_ester  101
  486. #define fg_thiolactone  102
  487. #define fg_thiocarboxylic_acid_amide  103
  488. #define fg_thiolactam   104
  489. #define fg_imido_thioester  105
  490. #define fg_oxohetarene  106
  491. #define fg_thioxohetarene  107
  492. #define fg_iminohetarene  108
  493. #define fg_orthocarboxylic_acid_deriv  109
  494. #define fg_carboxylic_acid_orthoester  110
  495. #define fg_carboxylic_acid_amide_acetal  111
  496. #define fg_carboxylic_acid_anhydride  112
  497. #define fg_carboxylic_acid_imide  113
  498. #define fg_carboxylic_acid_unsubst_imide  114
  499. #define fg_carboxylic_acid_subst_imide  115
  500. #define fg_co2_deriv    116
  501. #define fg_carbonic_acid_deriv  117
  502. #define fg_carbonic_acid_monoester  118
  503. #define fg_carbonic_acid_diester  119
  504. #define fg_carbonic_acid_ester_halide  120
  505. #define fg_thiocarbonic_acid_deriv  121
  506. #define fg_thiocarbonic_acid_monoester  122
  507. #define fg_thiocarbonic_acid_diester  123
  508. #define fg_thiocarbonic_acid_ester_halide  124
  509. #define fg_carbamic_acid_deriv  125
  510. #define fg_carbamic_acid  126
  511. #define fg_carbamic_acid_ester  127
  512. #define fg_carbamic_acid_halide  128
  513. #define fg_thiocarbamic_acid_deriv  129
  514. #define fg_thiocarbamic_acid  130
  515. #define fg_thiocarbamic_acid_ester  131
  516. #define fg_thiocarbamic_acid_halide  132
  517. #define fg_urea         133
  518. #define fg_isourea      134
  519. #define fg_thiourea     135
  520. #define fg_isothiourea  136
  521. #define fg_guanidine    137
  522. #define fg_semicarbazide  138
  523. #define fg_thiosemicarbazide  139
  524. #define fg_azide        140
  525. #define fg_azo_compound  141
  526. #define fg_diazonium_salt  142
  527. #define fg_isonitrile   143
  528. #define fg_cyanate      144
  529. #define fg_isocyanate   145
  530. #define fg_thiocyanate  146
  531. #define fg_isothiocyanate  147
  532. #define fg_carbodiimide  148
  533. #define fg_nitroso_compound  149
  534. #define fg_nitro_compound  150
  535. #define fg_nitrite      151
  536. #define fg_nitrate      152
  537. #define fg_sulfuric_acid_deriv  153
  538. #define fg_sulfuric_acid  154
  539. #define fg_sulfuric_acid_monoester  155
  540. #define fg_sulfuric_acid_diester  156
  541. #define fg_sulfuric_acid_amide_ester  157
  542. #define fg_sulfuric_acid_amide  158
  543. #define fg_sulfuric_acid_diamide  159
  544. #define fg_sulfuryl_halide  160
  545. #define fg_sulfonic_acid_deriv  161
  546. #define fg_sulfonic_acid  162
  547. #define fg_sulfonic_acid_ester  163
  548. #define fg_sulfonamide  164
  549. #define fg_sulfonyl_halide  165
  550. #define fg_sulfone      166
  551. #define fg_sulfoxide    167
  552. #define fg_sulfinic_acid_deriv  168
  553. #define fg_sulfinic_acid  169
  554. #define fg_sulfinic_acid_ester  170
  555. #define fg_sulfinic_acid_halide  171
  556. #define fg_sulfinic_acid_amide  172
  557. #define fg_sulfenic_acid_deriv  173
  558. #define fg_sulfenic_acid  174
  559. #define fg_sulfenic_acid_ester  175
  560. #define fg_sulfenic_acid_halide  176
  561. #define fg_sulfenic_acid_amide  177
  562. #define fg_thiol        178
  563. #define fg_alkylthiol   179
  564. #define fg_arylthiol    180
  565. #define fg_phosphoric_acid_deriv  181
  566. #define fg_phosphoric_acid  182
  567. #define fg_phosphoric_acid_ester  183
  568. #define fg_phosphoric_acid_halide  184
  569. #define fg_phosphoric_acid_amide  185
  570. #define fg_thiophosphoric_acid_deriv  186
  571. #define fg_thiophosphoric_acid  187
  572. #define fg_thiophosphoric_acid_ester  188
  573. #define fg_thiophosphoric_acid_halide  189
  574. #define fg_thiophosphoric_acid_amide  190
  575. #define fg_phosphonic_acid_deriv  191
  576. #define fg_phosphonic_acid  192
  577. #define fg_phosphonic_acid_ester  193
  578. #define fg_phosphine    194
  579. #define fg_phosphinoxide  195
  580. #define fg_boronic_acid_deriv  196
  581. #define fg_boronic_acid  197
  582. #define fg_boronic_acid_ester  198
  583. #define fg_alkene       199
  584. #define fg_alkyne       200
  585. #define fg_aromatic     201
  586. #define fg_heterocycle  202
  587. #define fg_alpha_aminoacid  203
  588. #define fg_alpha_hydroxyacid  204
  589.  
  590. typedef enum
  591. { false = 0, true } boolean;
  592.  
  593.  
  594. typedef char str2[3];
  595.  
  596. typedef char str3[4];
  597.  
  598. typedef char str4[5];
  599.  
  600. typedef char str5[6];
  601.  
  602. typedef char str8[9];
  603.  
  604. typedef struct atom_rec
  605. {
  606.   str2 element;
  607.   str3 atype;
  608.   float x, y, z;
  609.   int formal_charge;
  610.   float real_charge;
  611.   int Hexp;                     /* explicit H count */
  612.   int Htot;                     /* total H count */
  613.   int neighbor_count, ring_count;
  614.   boolean arom, stereo_care;    /* new in v0.3d */
  615.   boolean q_arom;               // v0.3p potentially aromatic in a query structure
  616.   boolean heavy;                /* new in v0.3l */
  617.   boolean metal;                /* new in v0.3l */
  618.   int nvalences;                /* new in v0.3m */
  619.   boolean tag;                  /* new in v0.3o */
  620.   int nucleon_number;           /* 0.3.x */
  621.   int radical_type;             /* 0.3.x */
  622. } atom_rec;
  623.  
  624. typedef struct bond_rec
  625. {
  626.   int a1, a2;
  627.   char btype;
  628.   int ring_count;
  629.   boolean arom;
  630.   boolean q_arom;               // v0.3p potentially aromatic in a query structure
  631.   int topo;                     /* new in v0.3d, see MDL file description */
  632.   int stereo;                   /* new in v0.3d */
  633.   int mdl_stereo;               /* new in v0.3n */
  634. } bond_rec;
  635.  
  636. typedef int ringpath_type[max_ringsize];
  637. typedef int matchpath_type[max_matchpath_length];
  638.  
  639. typedef atom_rec atomlist[max_atoms];
  640. typedef bond_rec bondlist[max_bonds];
  641. typedef ringpath_type ringlist[max_rings];
  642. typedef int neighbor_rec[max_neighbors];        /* new in v0.2h */
  643. typedef boolean fglist[max_fg];
  644.  
  645. typedef char molbuftype[max_atoms + max_bonds + slack][256];
  646.  
  647. typedef boolean matchmatrix[max_neighbors][max_neighbors];
  648.     /* new in v0.2i */
  649.  
  650. typedef struct molstat_rec
  651. {
  652.   int n_QA, n_QB, n_chg;        /* number of query atoms, query bonds, charges */
  653.   int n_C1, n_C2, n_C;
  654.   /* number of sp, sp2 hybridized, and total no. of carbons */
  655.   int n_CHB1p, n_CHB2p, n_CHB3p, n_CHB4;
  656.   /* number of C atoms with at least 1, 2, 3 hetero bonds */
  657.   int n_O2, n_O3;               /* number of sp2 and sp3 oxygens */
  658.   int n_N1, n_N2, n_N3;         /* number of sp, sp2, and sp3 nitrogens */
  659.   int n_S, n_SeTe;
  660.   /* number of sulfur atoms and selenium or tellurium atoms */
  661.   int n_F, n_Cl, n_Br, n_I;
  662.   /* number of fluorine, chlorine, bromine, iodine atoms */
  663.   int n_P, n_B;                 /* number of phosphorus and boron atoms */
  664.   int n_Met, n_X;
  665.   /* number of metal and "other" atoms (not listed elsewhere); v0.3l */
  666.   int n_b1, n_b2, n_b3, n_bar;
  667.   /* number single, double, triple, and aromatic bonds */
  668.   int n_C1O, n_C2O, n_CN, n_XY;
  669.   /* number of C-O single bonds, C=O double bonds, CN bonds (any type), hetero/hetero bonds */
  670.   int n_r3, n_r4, n_r5, n_r6, n_r7, n_r8;
  671.   /* number of 3-, 4-, 5-, 6-, 7-, and 8-membered rings */
  672.   int n_r9, n_r10, n_r11, n_r12, n_r13p;
  673.   /* number of 9-, 10-, 11-, 12-, and 13plus-membered rings */
  674.   int n_rN, n_rN1, n_rN2, n_rN3p;
  675.   /* number of rings containing N (any number), 1 N, 2 N, and 3 N or more */
  676.   int n_rO, n_rO1, n_rO2p;
  677.   /* number of rings containing O (any number), 1 O, and 2 O or more */
  678.   int n_rS, n_rX, n_rAr, n_rBz;
  679.   /* number of rings containing S (any number), any heteroatom (any number),  */
  680.   /* number of aromatic rings, number of benzene rings */
  681.   int n_br2p;                   /* number of bonds belonging to more than one ring (v0.3n) */
  682. /* p2c: checkmol.pas, line 590:
  683.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  684.   /*$IFDEF extended_molstat */
  685.   int n_psg01, n_psg02, n_psg13, n_psg14;
  686.   /* number of atoms belonging to elements of group 1, 2, etc.  */
  687.   int n_psg15, n_psg16, n_psg17, n_psg18;
  688.   /* number of atoms belonging to elements of group 15, 16, etc.  */
  689.   int n_pstm, n_psla;
  690.   /* number of transition metals, lanthanides/actinides */
  691.   int n_iso, n_rad;
  692.   /* number of isotopes, radicals */
  693.   /*$ENDIF */
  694. } molstat_rec;
  695.  
  696. typedef struct ringprop_rec
  697. {
  698.   /* new in v0.3 */
  699.   int size;
  700.   boolean arom, envelope;
  701. } ringprop_rec;
  702.  
  703. typedef ringprop_rec ringprop_type[max_rings];
  704.  
  705. typedef struct p_3d
  706. {
  707.   /* new in v0.3d */
  708.   double x, y, z;
  709. } p_3d;
  710.  
  711. typedef int chirpath_type[4];   /* new in v0.3f */
  712.  
  713. #ifdef MAKE_SHARED_LIBRARY
  714. static boolean yet_initialized = false;
  715. #endif
  716.  
  717. typedef struct connval_rec
  718. {
  719.   /* new in v0.3j */
  720.   int def;                      /* better as longint for large molecules? */
  721.   int tmp;
  722. } connval_rec;
  723.  
  724. typedef connval_rec connval_type[max_atoms];    /* new in v0.3j  */
  725.  
  726.  
  727. static int progmode;
  728. static char progname[256];
  729.  
  730. #ifndef MAKE_SHARED_LIBRARY
  731. static int i;                   /* general purpose index */
  732. #endif
  733.  
  734. static int li;
  735. static boolean opt_none, opt_verbose, opt_text, opt_text_de, opt_code,
  736.   opt_bin, opt_bitstring, opt_stdin, opt_exact, opt_debug,
  737.   opt_molout, opt_molstat, opt_molstat_X, opt_xmdlout, opt_strict;
  738.     /* new in v0.2f */
  739. static boolean opt_metalrings;  /* new in v0.3 */
  740. static boolean opt_geom;        /* new in v0.3d */
  741. static boolean opt_chiral;      /* new in v0.3f */
  742. static boolean opt_iso;         /* new in v0.3x */
  743. static boolean opt_chg;         /* new in v0.3x */
  744. static boolean opt_rad;         /* new in v0.3x */
  745. static int opt_rs;              /* new in v0.3i */
  746.  
  747. #ifdef MAKE_SHARED_LIBRARY
  748. static int opt_rs_dll = RPA_DEFAULT;
  749. #endif
  750.  
  751. static boolean opt_fp;          /* new in v0.3m */
  752. static int fpformat;            /* new in v0.3m */
  753. static char filetype[256];
  754. /*molfile : text; */
  755. static char molfilename[256];
  756. static char ndl_molfilename[256];
  757. static char molname[256];
  758. static char ndl_molname[256];
  759. static char tmp_molname[256];   /* v0.3m */
  760. static char molcomment[256];
  761. static int n_atoms, n_bonds, n_rings;
  762.     /* the number of rings we determined ourselves */
  763. static int n_countablerings;
  764.     /* v0.3n; number of rings which are not envelope rings */
  765. static int n_cmrings;
  766.     /* the number of rings we read from a (CheckMol-tweaked) MDL molfile */
  767. //static int n_charges;         /* number of charges */
  768. static int n_heavyatoms, n_heavybonds, ndl_n_atoms, ndl_n_bonds, ndl_n_rings,
  769.   ndl_n_heavyatoms, ndl_n_heavybonds;
  770. /*cm_mdlmolfile  : boolean; */
  771. static boolean found_arominfo, found_querymol, ndl_querymol;
  772. static int tmp_n_atoms;         /* v0.3m */
  773. static int tmp_n_bonds;         /* v0.3m */
  774. static int tmp_n_rings;         /* v0.3m */
  775. static int tmp_n_heavyatoms;    /* v0.3m */
  776. static int tmp_n_heavybonds;    /* v0.3m */
  777.  
  778. static atom_rec *atom;
  779. static bond_rec *bond;
  780. static ringpath_type *ring;
  781. static ringprop_rec *ringprop;  /* new in v0.3 */
  782.  
  783. static atom_rec *ndl_atom;
  784. static bond_rec *ndl_bond;
  785. static ringpath_type *ndl_ring;
  786. static ringprop_rec *ndl_ringprop;      /* new in v0.3 */
  787. static int ndl_ref_atom;        /* since v0.3j as a global variable */
  788. static atom_rec *tmp_atom;      /* v0.3m */
  789. static bond_rec *tmp_bond;      /* v0.3m */
  790. static ringpath_type *tmp_ring; /* v0.3m */
  791. static ringprop_rec *tmp_ringprop;      /* v0.3m */
  792.  
  793. static boolean matchresult, matchsummary;       /* v0.3o */
  794. static matchpath_type ndl_matchpath, hst_matchpath;
  795.  
  796. static fglist fg;
  797. static str4 atomtype;
  798. static str3 newatomtype;
  799.  
  800. static char (*molbuf)[256];
  801. static int molbufindex;
  802.  
  803. static boolean mol_in_queue;
  804. static int mol_count;
  805.  
  806. static molstat_rec molstat, ndl_molstat, tmp_molstat;   /* v0.3m */
  807.  
  808. static int ringsearch_mode, max_vringsize;      /* for SSR ring search */
  809.  
  810. static FILE *rfile;
  811. static boolean rfile_is_open, mol_OK;   /* new in v0.2i */
  812.  
  813. static int n_ar;                /* new in v0.3 */
  814. static int prev_n_ar;           /* new in v0.3 */
  815. static boolean ez_search;       /* new in v0.3d */
  816. static boolean rs_search;       /* new in v0.3f */
  817. static boolean ez_flag;         /* new in v0.3f */
  818. static boolean chir_flag;       /* new in v0.3f */
  819. static boolean rs_strict;       /* new in v0.3j */
  820.  
  821. static int n_Ctot, n_Otot, n_Ntot;      /* new in v0.3g */
  822. static int ndl_n_Ctot, ndl_n_Otot, ndl_n_Ntot;  /* new in v0.3g */
  823. static int tmp_n_Ctot, tmp_n_Otot, tmp_n_Ntot;  /* new in v0.3m */
  824. static boolean ether_generic;   /* v0.3j */
  825. static boolean amine_generic;   /* v0.3j   */
  826. static boolean hydroxy_generic; /* v0.3j */
  827. static connval_rec *cv;         /* new in v0.3j */
  828. static long long fpdecimal;     /* v0.3m */
  829. static long long fpincrement;
  830. static int fpindex;
  831. static boolean fp_exacthit, fp_exactblock;
  832. static int tmfcode;
  833.     /* v0.3m; version number for tweaked MDL molfiles (tweaklevel) */
  834. static boolean tmfmismatch;
  835.     /* v0.3m; rely on tweaked MDL molfiles only if same level */
  836. static boolean auto_ssr;
  837.     /* v0.3n; indicates that SAR -> SSR fallback has happened */
  838. static int recursion_depth;
  839.     /* ====================emulated pascal functions============================ */
  840.  
  841. static boolean
  842. file_exists (const char *fileName)
  843. {
  844.   struct stat filestat;
  845.  
  846.   return stat (fileName, &filestat) == 0 ? true : false;
  847. }
  848.  
  849. static void
  850. lblank (int cols, char *nstr)
  851. {
  852.   /* inserts leading blanks up to a given number of total characters */
  853.   char STR1[256];
  854.  
  855.   if (strlen (nstr) >= cols)
  856.     return;
  857.   while (strlen (nstr) < cols)
  858.     sprintf (nstr, " %s", strcpy (STR1, nstr));
  859. }
  860.  
  861. static inline double
  862. radtodeg (double rads)
  863. {
  864.   return (180.0 / M_PI) * rads;
  865. }
  866.  
  867. static void
  868. strdelete (char *s, int pos, int len)
  869. {
  870.   int slen;
  871.  
  872.   if (--pos < 0)
  873.     return;
  874.   slen = strlen (s) - pos;
  875.   if (slen <= 0)
  876.     return;
  877.   s += pos;
  878.   if (slen <= len)
  879.     {
  880.       *s = 0;
  881.       return;
  882.     }
  883.   while ((*s = s[len]))
  884.     s++;
  885. }
  886.  
  887. static int
  888. strpos2 (char *s, char *pat, int pos)
  889. {
  890.   char *cp, ch;
  891.   int slen;
  892.  
  893.   if (--pos < 0)
  894.     return 0;
  895.   slen = strlen (s) - pos;
  896.   cp = s + pos;
  897.   if (!(ch = *pat++))
  898.     return 0;
  899.   pos = strlen (pat);
  900.   slen -= pos;
  901.   while (--slen >= 0)
  902.     {
  903.       if (*cp++ == ch && !strncmp (cp, pat, pos))
  904.         return cp - s;
  905.     }
  906.   return 0;
  907. }
  908.  
  909. static char *
  910. strsub (char *ret, char *s, int pos, int len)
  911. {
  912.   char *s2;
  913.  
  914.   if (--pos < 0 || len <= 0)
  915.     {
  916.       *ret = 0;
  917.       return ret;
  918.     }
  919.   while (pos > 0)
  920.     {
  921.       if (!*s++)
  922.         {
  923.           *ret = 0;
  924.           return ret;
  925.         }
  926.       pos--;
  927.     }
  928.   s2 = ret;
  929.   while (--len >= 0)
  930.     {
  931.       if (!(*s2++ = *s++))
  932.         return ret;
  933.     }
  934.   *s2 = 0;
  935.   return ret;
  936. }
  937.  
  938.  
  939. /*============================= auxiliary functions & procedures */
  940.  
  941. inline static void
  942. all_lowercase (char *astring)
  943. {
  944.   int i;
  945.   int l = strlen (astring);
  946.  
  947.   for (i = 0; i < l; i++)
  948.     {
  949.       astring[i] = tolower (astring[i]);
  950.     }
  951. }
  952.  
  953. static void
  954. init_globals ()
  955. {
  956.   /*int i;*/
  957.  
  958.   opt_verbose = false;
  959.   opt_debug = false;
  960.   opt_exact = false;
  961.   opt_stdin = false;
  962.   opt_text = false;
  963.   opt_code = false;
  964.   opt_bin = false;
  965.   opt_bitstring = false;
  966.   opt_molout = false;
  967.   opt_molstat = false;
  968.   opt_molstat_X = false;
  969.   opt_xmdlout = false;
  970.   opt_strict = false;           /* new in v0.2f */
  971.   opt_metalrings = false;       /* new in v0.3 */
  972.   opt_geom = false;             /* new in v0.3d */
  973.   opt_chiral = false;           /* new in v0.3f */
  974.   opt_fp = false;               /* new in v0.3m */
  975.   opt_iso = false;              /* new in v0.3x */
  976.   opt_chg = false;              /* new in v0.3x */
  977.   opt_rad = false;              /* new in v0.3x */
  978.   /*cm_mdlmolfile   := false; */
  979.   found_arominfo = false;
  980.   found_querymol = false;
  981.   ndl_querymol = false;
  982.   opt_rs = rs_sar;              /* v0.3i */
  983.   /*ringsearch_mode := rs_sar; */
  984.   rfile_is_open = false;        /* new in v0.2g */
  985.   ez_search = false;            /* new in v0.3d */
  986.   rs_search = false;            /* new in v0.3f */
  987.   ez_flag = false;              /* new in v0.3f */
  988.   chir_flag = false;            /* new in v0.3f */
  989.   rs_strict = false;            /* new in v0.3j */
  990.   n_Ctot = 0;
  991.   n_Otot = 0;
  992.   n_Ntot = 0;                   /* new in v0.3g */
  993.   ndl_n_Ctot = 0;
  994.   ndl_n_Otot = 0;
  995.   ndl_n_Ntot = 0;               /* new in v0.3g */
  996.   //for (i = 0; i < max_fg; i++)
  997.   //  fg[i] = false;
  998.   memset (fg, 0, sizeof (fglist));
  999.   /*try */
  1000.   molbuf = safe_malloc (sizeof (molbuftype));
  1001.   /*except
  1002.      on e:Eoutofmemory do
  1003.      begin
  1004.      writeln('Not enough memory');
  1005.      halt(4);
  1006.      end;
  1007.      end; */
  1008.   ether_generic = false;        /* v0.3j */
  1009.   amine_generic = false;        /* v0.3j */
  1010.   hydroxy_generic = false;      /* v0.3j */
  1011.   fpformat = fpf_decimal;       /* v0.3m */
  1012.   fpindex = 0;                  /* v0.3m */
  1013.   fp_exacthit = false;          /* v0.3m */
  1014.   fp_exactblock = false;        /* v0.3m */
  1015.   tmfcode = 0;                  /* v0.3m */
  1016.   tmfmismatch = false;          /* v0.3m */
  1017.   auto_ssr = false;             /* v0.3n */
  1018.   recursion_depth = 0;
  1019. }
  1020.  
  1021.  
  1022. static inline void
  1023. init_molstat (mstat)
  1024.      molstat_rec *mstat;
  1025. {
  1026.   /*
  1027.      with mstat do
  1028.      begin
  1029.      n_QA := 0; n_QB := 0; n_chg := 0;
  1030.      n_C1 := 0; n_C2 := 0; n_C  := 0;
  1031.      n_CHB1p := 0; n_CHB2p := 0; n_CHB3p := 0; n_CHB4 := 0;
  1032.      n_O2 := 0; n_O3  := 0;
  1033.      n_N1 := 0; n_N2 := 0; n_N3 := 0;
  1034.      n_S := 0; n_SeTe := 0;
  1035.      n_F := 0; n_Cl := 0; n_Br := 0; n_I := 0;
  1036.      n_P := 0; n_B := 0;
  1037.      n_Met := 0; n_X := 0;
  1038.      n_b1 := 0; n_b2 := 0; n_b3 := 0; n_bar := 0;
  1039.      n_C1O := 0; n_C2O := 0; n_CN := 0; n_XY := 0;
  1040.      n_r3 := 0; n_r4 := 0; n_r5 := 0; n_r6 := 0; n_r7 := 0;
  1041.      n_r8 := 0; n_r9 := 0; n_r10 := 0; n_r11 := 0; n_r12 := 0; n_r13p := 0;
  1042.      n_rN := 0; n_rN1 := 0; n_rN2 := 0; n_rN3p := 0;
  1043.      n_rO := 0; n_rO1 := 0; n_rO2p := 0;
  1044.      n_rS := 0; n_rX := 0;
  1045.      n_rAr := 0; n_rBz := 0; n_br2p := 0;
  1046.      end;
  1047.    */
  1048.   memset (mstat, 0, sizeof (molstat_rec));      /* v0.3k */
  1049. }
  1050.  
  1051.  
  1052. #if 0
  1053. static void
  1054. debugoutput (dstr)
  1055.      char *dstr;
  1056. {
  1057.   if (opt_debug)
  1058.     printf ("%s\n", dstr);
  1059. }
  1060. #endif
  1061.  
  1062. static void
  1063. left_trim (trimstr)
  1064.      char *trimstr;
  1065. {
  1066.   while (*trimstr != '\0' && (trimstr[0] == ' ' || trimstr[0] == TAB))
  1067.     strdelete (trimstr, 1, 1);
  1068. }
  1069.  
  1070.  
  1071. static int
  1072. left_int (trimstr)
  1073.      char *trimstr;
  1074. {
  1075.   char numstr[256];
  1076.   char auxstr[256];
  1077.   int auxint = 0;
  1078.   char STR1[256];
  1079.  
  1080.   strcpy (numstr, "-+0123456789");
  1081.   *auxstr = '\0';
  1082.   while (*trimstr != '\0' && (trimstr[0] == ' ' || trimstr[0] == TAB))
  1083.     strdelete (trimstr, 1, 1);
  1084.   while ((*trimstr != '\0') &&
  1085.          (strpos2 (numstr, (sprintf (STR1, "%c", trimstr[0]), STR1), 1) > 0))
  1086.     {
  1087.       sprintf (auxstr + strlen (auxstr), "%c", trimstr[0]);
  1088.       strdelete (trimstr, 1, 1);
  1089.     }
  1090.   return auxint;
  1091. }
  1092.  
  1093. static int
  1094. path_pos (int id, int *a_path)
  1095. {
  1096.   int i = 0;
  1097.  
  1098.   for (i = 0; i < max_ringsize; i++)
  1099.     {
  1100.       if (*(a_path++) == id)
  1101.         {
  1102.           return ++i;
  1103.         }
  1104.     }
  1105.   return 0;
  1106. }
  1107.  
  1108. static int
  1109. path_length (int *a_path)
  1110. {
  1111.   if ((a_path[max_ringsize - 1] != 0) && (path_pos (0, a_path) == 0))
  1112.     return max_ringsize;
  1113.   else
  1114.     return (path_pos (0, a_path) - 1);
  1115. }
  1116.  
  1117. static int
  1118. get_bond (int ba1, int ba2)
  1119. {
  1120.   int i;
  1121.   int b_id = 0;
  1122.   int FORLIM;
  1123.  
  1124.   if (n_bonds <= 0)
  1125.     return b_id;
  1126.   FORLIM = n_bonds;
  1127.   for (i = 1; i <= FORLIM; i++)
  1128.     {
  1129.       if ((bond[i - 1].a1 == ba1 && bond[i - 1].a2 == ba2) ||
  1130.           (bond[i - 1].a1 == ba2 && bond[i - 1].a2 == ba1))
  1131.         b_id = i;
  1132.     }
  1133.   return b_id;
  1134. }
  1135.  
  1136. static void
  1137. clear_atom_tags ()
  1138. {
  1139.   int i, FORLIM;
  1140.  
  1141.   if (n_atoms > 0)
  1142.     {
  1143.       FORLIM = n_atoms;
  1144.       for (i = 0; i < FORLIM; i++)
  1145.         atom[i].tag = false;
  1146.     }
  1147. }
  1148.  
  1149. #if 0
  1150. static void
  1151. set_atom_tags ()
  1152. {
  1153.   int i, FORLIM;
  1154.  
  1155.   if (n_atoms > 0)
  1156.     {
  1157.       FORLIM = n_atoms;
  1158.       for (i = 0; i < FORLIM; i++)
  1159.         atom[i].tag = true;
  1160.     }
  1161. }
  1162. #endif
  1163. static void
  1164. order_ringpath (int *r_path)
  1165. {
  1166.   /* order should be: array starts with atom of lowest number, followed by neighbor atom with lower number */
  1167.   int i, pl, a_ref, a_left, a_right, a_tmp;
  1168.  
  1169.   pl = path_length (r_path);
  1170.   if (pl < 3)
  1171.     return;
  1172.   a_ref = n_atoms;
  1173.   /* start with highest possible value for an atom number */
  1174.   for (i = 0; i < pl; i++)
  1175.     {
  1176.       if (r_path[i] < a_ref)    /* find the minimum value ==> reference atom */
  1177.         a_ref = r_path[i];
  1178.     }
  1179.   if (a_ref < 1)                /* just to be sure */
  1180.     return;
  1181.   if (path_pos (a_ref, r_path) < pl)
  1182.     a_right = r_path[path_pos (a_ref, r_path)];
  1183.   else
  1184.     a_right = r_path[0];
  1185.   if (path_pos (a_ref, r_path) > 1)
  1186.     a_left = r_path[path_pos (a_ref, r_path) - 2];
  1187.   else
  1188.     a_left = r_path[pl - 1];
  1189.   if (a_right == a_left)        /* should never happen */
  1190.     return;
  1191.   if (a_right < a_left)
  1192.     {
  1193.       /* correct ring numbering direction, only shift of the reference atom to the left end required */
  1194.       while (path_pos (a_ref, r_path) > 1)
  1195.         {
  1196.           a_tmp = r_path[0];
  1197.           for (i = 1; i < pl; i++)
  1198.             r_path[i - 1] = r_path[i];
  1199.           r_path[pl - 1] = a_tmp;
  1200.         }
  1201.       return;
  1202.     }
  1203.   while (path_pos (a_ref, r_path) < pl)
  1204.     {
  1205.       /* step one: create "mirrored" ring path with reference atom at right end */
  1206.       a_tmp = r_path[pl - 1];
  1207.       for (i = pl; i >= 2; i--)
  1208.         r_path[i - 1] = r_path[i - 2];
  1209.       r_path[0] = a_tmp;
  1210.     }
  1211.   for (i = 1; i <= pl / 2; i++)
  1212.     {                           /* one more mirroring */
  1213.       a_tmp = r_path[i - 1];
  1214.       r_path[i - 1] = r_path[pl - i];
  1215.       r_path[pl - i] = a_tmp;
  1216.       /* wrong ring numbering direction, two steps required */
  1217.     }
  1218. }
  1219.  
  1220. static void
  1221. clear_ndl_atom_tags ()
  1222. {
  1223.   int i;
  1224.  
  1225.   if (ndl_n_atoms > 0)
  1226.     {
  1227.  
  1228.       for (i = 0; i < ndl_n_atoms; i++)
  1229.         ndl_atom[i].tag = false;
  1230.     }
  1231. }
  1232.  
  1233.  
  1234. static void
  1235. set_ndl_atom_tags ()
  1236. {
  1237.   int i;
  1238.  
  1239.   if (ndl_n_atoms > 0)
  1240.     {
  1241.  
  1242.       for (i = 0; i < ndl_n_atoms; i++)
  1243.         ndl_atom[i].tag = true;
  1244.     }
  1245. }
  1246.  
  1247.  
  1248. static int
  1249. count_tagged_ndl_heavyatoms ()
  1250. {
  1251.   int i;
  1252.   int n = 0;
  1253.  
  1254.   if (ndl_n_atoms < 1)
  1255.     return n;
  1256.  
  1257.   for (i = 0; i < ndl_n_atoms; i++)
  1258.     {
  1259.       if (ndl_atom[i].heavy && ndl_atom[i].tag)
  1260.         n++;
  1261.     }
  1262.   return n;
  1263. }
  1264.  
  1265.  
  1266.  
  1267. /*============================= geometry functions ========================== */
  1268.  
  1269. static double
  1270. dist3d (p1, p2)
  1271.      p_3d p1, p2;
  1272. {
  1273.   double res, TEMP, TEMP1, TEMP2;
  1274.  
  1275.   TEMP = p1.x - p2.x;
  1276.   TEMP1 = p1.y - p2.y;
  1277.   TEMP2 = p1.z - p2.z;
  1278.   res = sqrt (TEMP * TEMP + TEMP1 * TEMP1 + TEMP2 * TEMP2);
  1279.   return res;
  1280. }
  1281.  
  1282.  
  1283. /*
  1284. function is_cis(p1,p2,p3,p4:p_3d):boolean;  (* new in v0.3d
  1285. var                         (* just a simple, distance-based estimation
  1286.   total_dist  : double;     (* instead of calculating the dihedral angle
  1287.   direct_dist : double;
  1288.   res         : boolean;
  1289. begin
  1290.   res := false;
  1291.   total_dist  := dist3d(p1,p2) + dist3d(p2,p3) + dist3d(p3,p4);
  1292.   direct_dist := dist3d(p1,p4);
  1293.   if (direct_dist < 0.78 * total_dist) then res := true;  (* cutoff value of 0.78 was
  1294.   is_cis := res;                                          (* experimentally determined
  1295. end;
  1296. */
  1297. /* function is_cis was replaced by a new one in v0.3h */
  1298.  
  1299.  
  1300. static p_3d
  1301. subtract_3d (p1, p2)
  1302.      p_3d p1, p2;
  1303. {
  1304.   p_3d p;
  1305.  
  1306.   p.x = p1.x - p2.x;
  1307.   p.y = p1.y - p2.y;
  1308.   p.z = p1.z - p2.z;
  1309.   return p;
  1310. }
  1311.  
  1312.  
  1313. static p_3d
  1314. add_3d (p1, p2)
  1315.      p_3d p1, p2;
  1316. {
  1317.   p_3d p;
  1318.  
  1319.   p.x = p1.x + p2.x;
  1320.   p.y = p1.y + p2.y;
  1321.   p.z = p1.z + p2.z;
  1322.   return p;
  1323. }
  1324.  
  1325. #if 0
  1326. static void
  1327. vec2origin (p1, p2)
  1328.      p_3d *p1, *p2;
  1329. {
  1330.   p_3d p;
  1331.  
  1332.   p = subtract_3d (*p2, *p1);
  1333.   *p2 = p;
  1334.   p1->x = 0.0;
  1335.   p1->y = 0.0;
  1336.   p1->z = 0.0;
  1337. }
  1338. #endif
  1339.  
  1340. static double
  1341. scalar_prod (p1, p2, p3)
  1342.      p_3d p1, p2, p3;
  1343. {
  1344.   p_3d p;
  1345.   double res;
  1346.  
  1347.   p = subtract_3d (p2, p1);
  1348.   p2 = p;
  1349.   p = subtract_3d (p3, p1);
  1350.   p3 = p;
  1351.   p1.x = 0.0;
  1352.   p1.y = 0.0;
  1353.   p1.z = 0.0;
  1354.   res = p2.x * p3.x + p2.y * p3.y + p2.z * p3.z;
  1355.   return res;
  1356. }
  1357.  
  1358.  
  1359. static p_3d
  1360. cross_prod (p1, p2, p3)
  1361.      p_3d p1, p2, p3;
  1362. {
  1363.   p_3d p, orig_p1;
  1364.  
  1365.   orig_p1 = p1;
  1366.   p = subtract_3d (p2, p1);
  1367.   p2 = p;
  1368.   p = subtract_3d (p3, p1);
  1369.   p3 = p;
  1370.   p.x = p2.y * p3.z - p2.z * p3.y;
  1371.   p.y = p2.z * p3.x - p2.x * p3.z;
  1372.   p.z = p2.x * p3.y - p2.y * p3.x;
  1373.   return (add_3d (orig_p1, p));
  1374. }
  1375.  
  1376.  
  1377. static double
  1378. angle_3d (p1, p2, p3)
  1379.      p_3d p1, p2, p3;
  1380. {
  1381.   p_3d lp1, lp2, lp3, p;
  1382.   double res = 0.0;
  1383.   double magn_1, magn_2, cos_phi;
  1384.  
  1385.   lp1 = p1;
  1386.   lp2 = p2;
  1387.   lp3 = p3;
  1388.   p = subtract_3d (lp2, lp1);
  1389.   lp2 = p;
  1390.   p = subtract_3d (lp3, lp1);
  1391.   lp3 = p;
  1392.   lp1.x = 0.0;
  1393.   lp1.y = 0.0;
  1394.   lp1.z = 0.0;
  1395.   magn_1 = dist3d (lp1, lp2);
  1396.   magn_2 = dist3d (lp1, lp3);
  1397.   if (magn_1 * magn_2 == 0)     /* emergency exit */
  1398.     return M_PI;
  1399.   cos_phi = scalar_prod (lp1, lp2, lp3) / (magn_1 * magn_2);
  1400.   if (cos_phi < -1)
  1401.     cos_phi = -1.0;
  1402.   if (cos_phi > 1)
  1403.     cos_phi = 1.0;
  1404.   res = acos (cos_phi);
  1405.   return res;
  1406. }
  1407.  
  1408.  
  1409. static double
  1410. torsion (p1, p2, p3, p4)
  1411.      p_3d p1, p2, p3, p4;
  1412. {
  1413.   p_3d lp1, lp2, lp3, lp4, d1, c1, c2;
  1414.   double res;
  1415.   p_3d c1xc2, c2xc1;
  1416.   double dist1, dist2, sign;
  1417.  
  1418.   /* copy everything into local variables */
  1419.   lp1 = p1;
  1420.   lp2 = p2;
  1421.   lp3 = p3;
  1422.   lp4 = p4;
  1423.   /* get the vector between the two central atoms */
  1424.   d1 = subtract_3d (p3, p2);
  1425.   /* shift the first atom parallel to be attached to p3 instead of p2 */
  1426.   lp1 = add_3d (p1, d1);
  1427.   /* now get the cross product vectors */
  1428.   c1 = cross_prod (lp3, lp2, lp1);
  1429.   c2 = cross_prod (lp3, lp2, lp4);
  1430.   res = angle_3d (p3, c1, c2);
  1431.   /*now check if it is clockwise or anticlockwise: */
  1432.   /*first, make the cross products of the two cross products c1 and c2 (both ways) */
  1433.   c1xc2 = cross_prod (lp3, c1, c2);
  1434.   c2xc1 = cross_prod (lp3, c2, c1);
  1435.   /*next, get the distances from these points to our refernce point lp2 */
  1436.   dist1 = dist3d (lp2, c1xc2);
  1437.   dist2 = dist3d (lp2, c2xc1);
  1438.   if (dist1 <= dist2)
  1439.     sign = 1.0;
  1440.   else
  1441.     sign = -1.0;
  1442.   return (sign * res);
  1443. }
  1444.  
  1445.  
  1446. static double
  1447. ctorsion (p1, p2, p3, p4)
  1448.      p_3d p1, p2, p3, p4;
  1449. {
  1450.   /* calculates "pseudo-torsion" defined by atoms 3 and 4, being both */
  1451.   /* attached to atom 2, with respect to axis of atoms 1 and 2 */
  1452.   p_3d lp1, lp2, lp3, lp4;
  1453.   /*d1 : p_3d; */
  1454.   p_3d c1, c2;
  1455.   double res;
  1456.   p_3d c1xc2, c2xc1;
  1457.   double dist1, dist2, sign;
  1458.  
  1459.   /* copy everything into local variables */
  1460.   lp1 = p1;
  1461.   lp2 = p2;
  1462.   lp3 = p3;
  1463.   lp4 = p4;
  1464.   /* get the cross product vectors */
  1465.   c1 = cross_prod (lp2, lp1, lp3);
  1466.   c2 = cross_prod (lp2, lp1, lp4);
  1467.   res = angle_3d (p2, c1, c2);
  1468.   /*now check if it is clockwise or anticlockwise: */
  1469.   /*first, make the cross products of the two cross products c1 and c2 (both ways) */
  1470.   c1xc2 = cross_prod (lp2, c1, c2);
  1471.   c2xc1 = cross_prod (lp2, c2, c1);
  1472.   /*next, get the distances from these points to our refernce point lp1 */
  1473.   dist1 = dist3d (lp1, c1xc2);
  1474.   dist2 = dist3d (lp1, c2xc1);
  1475.   if (dist1 <= dist2)
  1476.     sign = 1.0;
  1477.   else
  1478.     sign = -1.0;
  1479.   return (sign * res);
  1480. }
  1481.  
  1482.  
  1483. static boolean
  1484. is_cis (p1, p2, p3, p4)
  1485.      p_3d p1, p2, p3, p4;
  1486. {
  1487.   /* new in v0.3h, uses the dihedral angle */
  1488.   double phi;
  1489.   boolean res = false;
  1490.  
  1491.   phi = torsion (p1, p2, p3, p4);
  1492.   if (fabs (phi) < M_PI / 2)
  1493.     res = true;
  1494.   return res;
  1495. }
  1496.  
  1497.  
  1498. /*====================== end of geometry functions ========================== */
  1499.  
  1500. static void
  1501. show_usage ()
  1502. {
  1503.   if (progmode == pmMatchMol)
  1504.     {
  1505.       printf
  1506.         ("matchmol version %s  N. Haider, University of Vienna, 2003-2007\n",
  1507.          version);
  1508.       printf ("Usage: matchmol [options] <needle> <haystack>\n");
  1509.       printf
  1510.         (" where <needle> and <haystack> are the two molecules to compare\n");
  1511.       printf
  1512.         (" (supported formats: MDL *.mol or *.sdf, Alchemy *.mol, Sybyl *.mol2)\n");
  1513.       printf (" options can be:\n");
  1514.       printf ("    -v  verbose output\n");
  1515.       printf ("    -x  exact match\n");
  1516.       printf
  1517.         ("    -s  strict comparison of atom and bond types (including ring check)\n");
  1518.       /* new in v0.2f, v0.3d */
  1519.       printf ("    -r  force SSR (set of small rings) ring search mode\n");
  1520.       printf
  1521.         ("    -m  write matching molecule as MDL molfile to standard output\n");
  1522.       printf
  1523.         ("        (default output: record number + \":T\" for hit  or \":F\" for miss\n");
  1524.       printf ("    -M  accept metal atoms as ring members\n");
  1525.       printf ("    -g  check geometry of double bonds (E/Z)\n");
  1526.       printf ("    -G  check geometry of chiral centers (R/S)\n");
  1527.       printf ("    -a  check charges strict\n");        /* 0.3x */
  1528.       printf ("    -i  check isotopes strict\n");       /* 0.3x */
  1529.       printf ("    -d  check radicals strict\n");       /* 0.3x */
  1530.       printf
  1531.         ("    -f  fingerprint mode (1 haystack, multiple needles) with boolean output\n");
  1532.       printf
  1533.         ("    -F  fingerprint mode (1 haystack, multiple needles) with decimal output\n");
  1534.       return;
  1535.     }
  1536.   printf ("checkmol version %s  N. Haider, University of Vienna, 2003-2007\n",
  1537.           version);
  1538.   printf ("Usage: checkmol [options] <filename>\n");
  1539.   printf (" where options can be:\n");
  1540.   printf
  1541.     ("    -l  print a list of fingerprint codes + explanation and exit\n");
  1542.   printf ("    -v  verbose output\n");
  1543.   printf ("    -r  force SSR (set of small rings) ring search mode\n");
  1544.   printf ("    -M  accept metal atoms as ring members\n");
  1545.   printf ("  and one of the following:\n");
  1546.   printf
  1547.     ("    -e  english text (common name of functional group; default)\n");
  1548.   printf ("    -d  german text (common name of functional group)\n");
  1549.   printf ("    -c  code (acronym-like code for functional group)\n");
  1550.   printf
  1551.     ("    -b  binary (a bitstring representing absence or presence of each group)\n");
  1552.   printf
  1553.     ("    -s  the ASCII representation of the above bitstring, i.e. 0s and 1s)\n");
  1554.   printf
  1555.     ("    -x  print molecular statistics (number of various atom types, bond types,\n");
  1556.   printf ("        ring sizes, etc.\n");
  1557.   printf
  1558.     ("    -X  same as above, listing all records (even if 0) as comma-separated list\n");
  1559.   printf ("    -a  count charges in fingerprint\n");    /* 0.3x */
  1560.   printf
  1561.     ("    -m  write MDL molfile (with special encoding for aromatic atoms/bonds)\n");
  1562.   printf (" options can be combined like -vc\n");
  1563.   printf (" <filename> specifies any file in the formats supported\n");
  1564.   printf
  1565.     (" (MDL *.mol, Alchemy *.mol, Sybyl *.mol2), the filename \"-\" (without quotes)\n");
  1566.   printf (" specifies standard input\n");
  1567.   /* the "debug" option (-D) remains undocumented */
  1568. }
  1569.  
  1570.  
  1571. static void
  1572. list_molstat_codes ()
  1573. {
  1574.   printf ("n_atoms:     number of heavy atoms\n");
  1575.   printf ("n_bonds:     number of bonds between non-H atoms\n");
  1576.   printf ("n_rings:     number of rings\n");
  1577.   printf ("n_QA:        number of query atoms\n");
  1578.   printf ("n_QB:        number of query bonds\n");
  1579.   printf ("n_chg:       number of charges\n");
  1580.   printf ("n_C1:        number of sp-hybridized carbon atoms\n");
  1581.   printf ("n_C2:        number of sp2-hybridized carbon atoms\n");
  1582.   printf ("n_C:         total number of carbon atoms\n");
  1583.   printf
  1584.     ("n_CHB1p:     number of carbon atoms with at least 1 bond to a hetero atom\n");
  1585.   printf
  1586.     ("n_CHB2p:     number of carbon atoms with at least 2 bonds to a hetero atom\n");
  1587.   printf
  1588.     ("n_CHB3p:     number of carbon atoms with at least 3 bonds to a hetero atom\n");
  1589.   printf
  1590.     ("n_CHB4:      number of carbon atoms with 4 bonds to a hetero atom\n");
  1591.   printf ("n_O2:        number of sp2-hybridized oxygen atoms\n");
  1592.   printf ("n_O3:        number of sp3-hybridized oxygen atoms\n");
  1593.   printf ("n_N1:        number of sp-hybridized nitrogen atoms\n");
  1594.   printf ("n_N2:        number of sp2-hybridized nitrogen atoms\n");
  1595.   printf ("n_N3:        number of sp3-hybridized nitrogen atoms\n");
  1596.   printf ("n_S:         number of sulfur atoms\n");
  1597.   printf ("n_SeTe:      total number of selenium and tellurium atoms\n");
  1598.   printf ("n_F:         number of fluorine atoms\n");
  1599.   printf ("n_Cl:        number of chlorine atoms\n");
  1600.   printf ("n_Br:        number of bromine atoms\n");
  1601.   printf ("n_I:         number of iodine atoms\n");
  1602.   printf ("n_P:         number of phosphorus atoms\n");
  1603.   printf ("n_B:         number of boron atoms\n");
  1604.   printf ("n_Met:       total number of metal atoms\n");
  1605.   printf
  1606.     ("n_X:         total number of \"other\" atoms (not listed above) and halogens\n");
  1607.   printf ("n_b1:        number of single bonds\n");
  1608.   printf ("n_b2:        number of double bonds\n");
  1609.   printf ("n_b3:        number of triple bonds\n");
  1610.   printf ("n_bar:       number of aromatic bonds\n");
  1611.   printf ("n_C1O:       number of C-O single bonds\n");
  1612.   printf ("n_C2O:       number of C=O double bonds\n");
  1613.   printf ("n_CN:        number of C/N bonds (any type)\n");
  1614.   printf ("n_XY:        number of heteroatom/heteroatom bonds (any type)\n");
  1615.   printf ("n_r3:        number of 3-membered rings\n");
  1616.   printf ("n_r4:        number of 4-membered rings\n");
  1617.   printf ("n_r5:        number of 5-membered rings\n");
  1618.   printf ("n_r6:        number of 6-membered rings\n");
  1619.   printf ("n_r7:        number of 7-membered rings\n");
  1620.   printf ("n_r8:        number of 8-membered rings\n");
  1621.   printf ("n_r9:        number of 9-membered rings\n");
  1622.   printf ("n_r10:       number of 10-membered rings\n");
  1623.   printf ("n_r11:       number of 11-membered rings\n");
  1624.   printf ("n_r12:       number of 12-membered rings\n");
  1625.   printf ("n_r13p:      number of 13-membered or larger rings\n");
  1626.   printf ("n_rN:        number of rings containing nitrogen (any number)\n");
  1627.   printf ("n_rN1:       number of rings containing 1 nitrogen atom\n");
  1628.   printf ("n_rN2:       number of rings containing 2 nitrogen atoms\n");
  1629.   printf
  1630.     ("n_rN3p:      number of rings containing 3 or more nitrogen atoms\n");
  1631.   printf ("n_rO:        number of rings containing oxygen (any number)\n");
  1632.   printf ("n_rO1:       number of rings containing 1 oxygen atom\n");
  1633.   printf ("n_rO2p:      number of rings containing 2 or more oxygen atoms\n");
  1634.   printf ("n_rS:        number of rings containing sulfur (any number)\n");
  1635.   printf ("n_rX:        number of heterocycles (any type)\n");
  1636.   printf ("n_rar:       number of aromatic rings (any type)\n");
  1637. /* p2c: checkmol.pas, line 1207:
  1638.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  1639.   /*$IFDEF extended_molstat */
  1640.   printf ("n_rbz:       number of benzene rings\n");
  1641.   printf ("n_br2p:      number of bonds belonging to two or more rings\n");
  1642.   printf
  1643.     ("n_psg01:     number of atoms belonging to group 1 of the periodic system\n");
  1644.   printf
  1645.     ("n_psg02:     number of atoms belonging to group 2 of the periodic system\n");
  1646.   printf
  1647.     ("n_psg13:     number of atoms belonging to group 13 of the periodic system\n");
  1648.   printf
  1649.     ("n_psg14:     number of atoms belonging to group 14 of the periodic system\n");
  1650.   printf
  1651.     ("n_psg15:     number of atoms belonging to group 15 of the periodic system\n");
  1652.   printf
  1653.     ("n_psg16:     number of atoms belonging to group 16 of the periodic system\n");
  1654.   printf
  1655.     ("n_psg17:     number of atoms belonging to group 17 of the periodic system\n");
  1656.   printf
  1657.     ("n_psg18:     number of atoms belonging to group 18 of the periodic system\n");
  1658.   printf
  1659.     ("n_pstm:      number of atoms belonging to the transition metals\n");
  1660.   printf
  1661.     ("n_psla:      number of atoms belonging to the lanthanides or actinides\n");
  1662.   printf ("n_iso:      number of isotopes\n");
  1663.   printf ("n_rad:      number of radicals\n");
  1664.   /*$ENDIF */
  1665. }
  1666.  
  1667.  
  1668. #if 0
  1669. static void parse_args()
  1670. {
  1671.   int p;
  1672.   char parstr[256];
  1673.   char tmpstr[256];
  1674.   int l;
  1675.  
  1676.   *tmpstr = '\0';
  1677.   opt_none = true;
  1678.   if (progmode == pmCheckMol) {
  1679.     for (p = 1; p < P_argc; p++) {
  1680.       strcpy(parstr, P_argv[p]);
  1681.       if (!strcmp(parstr, "-l")) {   /* new in v0.3l */
  1682.         list_molstat_codes();
  1683.         _Escape(0);
  1684.       }
  1685.       if (p < P_argc - 1) {
  1686.         if (strpos2(parstr, "-", 1) == 1 && p < P_argc - 1) {
  1687.           strcpy(tmpstr, P_argv[p]);
  1688.           left_trim(tmpstr);
  1689.           l = 0;
  1690.           if (strpos2(tmpstr, "v", 1) > 0)
  1691.             l++;
  1692.           if (strpos2(tmpstr, "D", 1) > 0)
  1693.             l++;
  1694.           if (strpos2(tmpstr, "r", 1) > 0)
  1695.             l++;
  1696.           if (strpos2(tmpstr, "M", 1) > 0)   /* new in v0.3 */
  1697.             l++;
  1698.           if (strlen(tmpstr) > l + 2) {
  1699.             show_usage();
  1700.             _Escape(1);
  1701.           }
  1702.           opt_none = false;
  1703.           if (strpos2(tmpstr, "M", 1) > 0)
  1704.             opt_metalrings = true;
  1705.           if (strpos2(tmpstr, "v", 1) > 0)
  1706.             opt_verbose = true;
  1707. /* p2c: checkmol.pas, line 1261:
  1708.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  1709.           /*$IFDEF debug
  1710.           if (strpos2(tmpstr, "D", 1) > 0)
  1711.             opt_debug = true;
  1712.           $ENDIF*/
  1713.           if (strpos2(tmpstr, "e", 1) > 0)
  1714.             opt_text = true;
  1715.           else {
  1716.             if (strpos2(tmpstr, "d", 1) > 0)
  1717.               opt_text_de = true;
  1718.             else {
  1719.               if (strpos2(tmpstr, "c", 1) > 0)
  1720.                 opt_code = true;
  1721.               else {
  1722.                 if (strpos2(tmpstr, "b", 1) > 0)
  1723.                   opt_bin = true;
  1724.                 else {
  1725.                   if (strpos2(tmpstr, "s", 1) > 0)
  1726.                     opt_bitstring = true;
  1727.                 }
  1728.               }
  1729.             }
  1730.             if (strpos2(tmpstr, "x", 1) > 0)
  1731.               opt_molstat = true;
  1732.             if (strpos2(tmpstr, "r", 1) > 0)
  1733.               opt_rs = rs_ssr;
  1734.             if (strpos2(tmpstr, "X", 1) > 0) {
  1735.               opt_molstat = true;
  1736.               opt_molstat_X = true;
  1737.             }
  1738.             if (strpos2(tmpstr, "m", 1) > 0) {
  1739.               opt_text = false;
  1740.               opt_text_de = false;
  1741.               opt_bin = false;
  1742.               opt_bitstring = false;
  1743.               opt_code = false;
  1744.               opt_molstat = false;
  1745.               opt_xmdlout = true;
  1746.             }
  1747.           }
  1748.           strcpy(molfilename, tmpstr);
  1749.         }
  1750.       } else {
  1751.         if (strpos2(parstr, "-", 1) == 1) {
  1752.           if (strlen(parstr) > 1) {
  1753.             show_usage();
  1754.             _Escape(1);
  1755.           }
  1756.           opt_stdin = true;
  1757.         } else {
  1758.           opt_stdin = false;
  1759.           strcpy(molfilename, parstr);
  1760.         }
  1761.       }
  1762.     }
  1763.     if (opt_text == false && opt_text_de == false && opt_code == false &&
  1764.         opt_bin == false && opt_bitstring == false && opt_molstat == false &&
  1765.         opt_molstat_X == false && opt_xmdlout == false)
  1766.       opt_none = true;
  1767.   }
  1768.   if (progmode == pmMatchMol) {
  1769.     *ndl_molfilename = '\0';
  1770.     *molfilename = '\0';
  1771.     for (p = 1; p < P_argc; p++) {
  1772.       strcpy(parstr, P_argv[p]);
  1773.       if (p == 1) {
  1774.         if (strpos2(parstr, "-", 1) == 1) {
  1775.           if (strpos2(parstr, "v", 1) > 1)
  1776.             opt_verbose = true;
  1777. /* p2c: checkmol.pas, line 1329:
  1778.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  1779.           /*$IFDEF debug
  1780.              if (strpos2(parstr, "D", 1) > 1)
  1781.              opt_debug = true;
  1782.              $ENDIF*/
  1783.              if (strpos2(parstr, "x", 1) > 1)
  1784.              opt_exact = true;
  1785.              if (strpos2(parstr, "s", 1) > 1)   /* new in v0.2f */
  1786.              opt_strict = true;
  1787.              if (strpos2(parstr, "m", 1) > 1)
  1788.              opt_molout = true;
  1789.              if (strpos2(parstr, "r", 1) > 1)
  1790.              opt_rs = rs_ssr;
  1791.              if (strpos2(parstr, "M", 1) > 0)   /* new in v0.3 */
  1792.              opt_metalrings = true;
  1793.              if (strpos2(parstr, "g", 1) > 0)   /* new in v0.3d */
  1794.              opt_geom = true;
  1795.              if (strpos2(parstr, "G", 1) > 0)   /* new in v0.3f */
  1796.              opt_chiral = true;
  1797.              if (strpos2(parstr, "f", 1) > 0) {   /* new in v0.3m */
  1798.              opt_fp = true;
  1799.              fpformat = fpf_boolean;
  1800.              }
  1801.              if (strpos2(parstr, "F", 1) > 0) {   /* new in v0.3m */
  1802.              opt_fp = true;
  1803.              fpformat = fpf_decimal;
  1804.              }
  1805.              if (strpos2(parstr, "h", 1) > 1) {
  1806.              show_usage();
  1807.              _Escape(0);
  1808.              }
  1809.              } else
  1810.              strcpy(ndl_molfilename, parstr);
  1811.              }
  1812.              if (p == P_argc - 2) {
  1813.              if (strpos2(parstr, "-", 1) != 1)
  1814.              strcpy(ndl_molfilename, parstr);
  1815.              }
  1816.              if (p == P_argc - 1) {
  1817.              if (strcmp(parstr, "-"))
  1818.              strcpy(molfilename, parstr);
  1819.              else
  1820.              opt_stdin = true;
  1821.              }
  1822.              }
  1823.              if (opt_geom)   /* v0.3d */
  1824.              ez_search = true;
  1825.              if (opt_chiral)   /* v0.3f */
  1826.              rs_search = true;
  1827.              if (opt_chiral && opt_strict && (opt_exact || opt_fp))
  1828.              /* new in v0.3j, v0.3m */
  1829.              rs_strict = true;
  1830.              if (opt_fp) {   /* v0.3m */
  1831.              opt_molout = false;
  1832.              opt_exact = false;
  1833.              }
  1834.              }  /* progmode = pmMatchMol */
  1835.              ringsearch_mode = opt_rs;   /* v0.3i */
  1836.              }
  1837. #endif
  1838.  
  1839. static void
  1840. parse_args (int argc, char *argv[])
  1841. {
  1842.   short p;
  1843.   char parstr[256];
  1844.   char tmpstr[256];
  1845.   short l;
  1846.  
  1847.   *tmpstr = '\0';
  1848.   opt_none = true;
  1849.   *molfilename = '\0';
  1850.   *ndl_molfilename = '\0';
  1851.   if (progmode == pmCheckMol)
  1852.     {
  1853.       for (p = 1; p <= argc - 1; p++)
  1854.         {
  1855.           strcpy (parstr, argv[p]);
  1856.           if (!strcmp (parstr, "-l"))
  1857.             {                   /* new in v0.3l */
  1858.               list_molstat_codes ();
  1859.               exit (0);
  1860.             }
  1861.           if (p < argc - 1)
  1862.             {
  1863.               if (strpos2 (parstr, "-", 1) == 1 && p < argc - 1)
  1864.                 {
  1865.                   strcpy (tmpstr, argv[p]);
  1866.                   left_trim (tmpstr);
  1867.                   l = 0;
  1868.                   if (strpos2 (tmpstr, "v", 1) > 0)
  1869.                     l++;
  1870.                   if (strpos2 (tmpstr, "D", 1) > 0)
  1871.                     l++;
  1872.                   if (strpos2 (tmpstr, "r", 1) > 0)
  1873.                     l++;
  1874.                   /*if (strpos2 (tmpstr, "a", 1) > 0)   // 0.3x
  1875.                      l++; */
  1876.                   if (strpos2 (tmpstr, "M", 1) > 0)     /* new in v0.3 */
  1877.                     l++;
  1878.                   if (strlen (tmpstr) > l + 2)
  1879.                     {
  1880.                       show_usage ();
  1881.                       exit (1);
  1882.                     }
  1883.                   opt_none = false;
  1884.                   if (strpos2 (tmpstr, "M", 1) > 0)
  1885.                     opt_metalrings = true;
  1886.                   if (strpos2 (tmpstr, "v", 1) > 0)
  1887.                     opt_verbose = true;
  1888.                   /*{$IFDEF debug
  1889.                      if pos('D',tmpstr)>0 then opt_debug       := true;
  1890.                      {$ENDIF */
  1891.                   if (strpos2 (tmpstr, "e", 1) > 0)
  1892.                     opt_text = true;
  1893.                   else
  1894.                     {
  1895.                       if (strpos2 (tmpstr, "d", 1) > 0)
  1896.                         opt_text_de = true;
  1897.                       else
  1898.                         {
  1899.                           if (strpos2 (tmpstr, "c", 1) > 0)
  1900.                             opt_code = true;
  1901.                           else
  1902.                             {
  1903.                               if (strpos2 (tmpstr, "b", 1) > 0)
  1904.                                 opt_bin = true;
  1905.                               else
  1906.                                 {
  1907.                                   if (strpos2 (tmpstr, "s", 1) > 0)
  1908.                                     opt_bitstring = true;
  1909.                                 }
  1910.                             }
  1911.                         }
  1912.                       if (strpos2 (tmpstr, "x", 1) > 0)
  1913.                         opt_molstat = true;
  1914.                       if (strpos2 (tmpstr, "r", 1) > 0)
  1915.                         opt_rs = rs_ssr;
  1916.                       /* if (strpos2 (tmpstr, "a", 1) > 0)
  1917.                          opt_chg = true; */ /* 0.3x  */
  1918.                       if (strpos2 (tmpstr, "X", 1) > 0)
  1919.                         {
  1920.                           opt_molstat = true;
  1921.                           opt_molstat_X = true;
  1922.                         }
  1923.                       if (strpos2 (tmpstr, "m", 1) > 0)
  1924.                         {
  1925.                           opt_text = false;
  1926.                           opt_text_de = false;
  1927.                           opt_bin = false;
  1928.                           opt_bitstring = false;
  1929.                           opt_code = false;
  1930.                           opt_molstat = false;
  1931.                           opt_xmdlout = true;
  1932.                         }
  1933.                     }
  1934.                   strcpy (molfilename, tmpstr);
  1935.                 }
  1936.             }
  1937.           else
  1938.             {
  1939.               if (strpos2 (parstr, "-", 1) == 1)
  1940.                 {
  1941.                   if (strlen (parstr) > 1)
  1942.                     {
  1943.                       show_usage ();
  1944.                       exit (1);
  1945.                     }
  1946.                   opt_stdin = true;
  1947.                 }
  1948.               else
  1949.                 {
  1950.                   opt_stdin = false;
  1951.                   strcpy (molfilename, parstr);
  1952.                 }
  1953.             }
  1954.         }
  1955.       if (opt_text == false && opt_text_de == false && opt_code == false &&
  1956.           opt_bin == false && opt_bitstring == false && opt_molstat == false
  1957.           && opt_molstat_X == false && opt_xmdlout == false
  1958.           && opt_chg == false)
  1959.         opt_none = true;        /* 0.3x */
  1960.     }
  1961.   if (progmode == pmMatchMol)
  1962.     {
  1963.  
  1964.       for (p = 1; p <= argc - 1; p++)
  1965.         {
  1966.           strcpy (parstr, argv[p]);
  1967.           if (p == 1)
  1968.             {
  1969.               if (strpos2 (parstr, "-", 1) == 1)
  1970.                 {
  1971.                   if (strpos2 (parstr, "v", 1) > 1)
  1972.                     opt_verbose = true;
  1973.                   /*{$IFDEF debug
  1974.                      if pos('D',parstr)>1 then opt_debug       := true;
  1975.                      {$ENDIF */
  1976.                   if (strpos2 (parstr, "x", 1) > 1)
  1977.                     opt_exact = true;
  1978.                   if (strpos2 (parstr, "s", 1) > 1)     /* new in v0.2f */
  1979.                     opt_strict = true;
  1980.                   if (strpos2 (parstr, "m", 1) > 1)
  1981.                     opt_molout = true;
  1982.                   if (strpos2 (parstr, "r", 1) > 1)
  1983.                     opt_rs = rs_ssr;
  1984.                   if (strpos2 (parstr, "a", 1) > 0)
  1985.                     opt_chg = true;     /* 0.3x */
  1986.                   if (strpos2 (parstr, "i", 1) > 0)
  1987.                     opt_iso = true;     /* 0.3x */
  1988.                   if (strpos2 (parstr, "d", 1) > 0)
  1989.                     opt_rad = true;     /* 0.3x */
  1990.                   if (strpos2 (parstr, "M", 1) > 0)     /* new in v0.3 */
  1991.                     opt_metalrings = true;
  1992.                   if (strpos2 (parstr, "g", 1) > 0)     /* new in v0.3d */
  1993.                     opt_geom = true;
  1994.                   if (strpos2 (parstr, "G", 1) > 0)     /* new in v0.3f */
  1995.                     opt_chiral = true;
  1996.                   if (strpos2 (parstr, "f", 1) > 0)
  1997.                     {           /* new in v0.3m */
  1998.                       opt_fp = true;
  1999.                       fpformat = fpf_boolean;
  2000.                     }
  2001.                   if (strpos2 (parstr, "F", 1) > 0)
  2002.                     {           /* new in v0.3m */
  2003.                       opt_fp = true;
  2004.                       fpformat = fpf_decimal;
  2005.                     }
  2006.                   if (strpos2 (parstr, "h", 1) > 1)
  2007.                     {
  2008.                       show_usage ();
  2009.                       exit (0);
  2010.                     }
  2011.                 }
  2012.               else
  2013.                 strcpy (ndl_molfilename, parstr);
  2014.             }
  2015.           if (p == argc - 2)
  2016.             {
  2017.               if (strpos2 (parstr, "-", 1) != 1)
  2018.                 strcpy (ndl_molfilename, parstr);
  2019.             }
  2020.           if (p == argc - 1)
  2021.             {
  2022.               if (strcmp (parstr, "-"))
  2023.                 strcpy (molfilename, parstr);
  2024.               else
  2025.                 opt_stdin = true;
  2026.             }
  2027.         }
  2028.       if (opt_geom)             /* v0.3d */
  2029.         ez_search = true;
  2030.       if (opt_chiral)           /* v0.3f */
  2031.         rs_search = true;
  2032.       if (opt_chiral && opt_strict && (opt_exact || opt_fp))
  2033.         /* new in v0.3j, v0.3m  */
  2034.         rs_strict = true;
  2035.       if (opt_fp)
  2036.         {                       /* v0.3m */
  2037.           opt_molout = false;
  2038.           opt_exact = false;
  2039.         }
  2040.     }                           /* progmode = pmMatchMol */
  2041.   ringsearch_mode = opt_rs;     /* v0.3i */
  2042. }
  2043.  
  2044. /*============== input-related functions & procedures ===================== */
  2045.  
  2046. static char *
  2047. get_filetype (Result, f)
  2048.      char *Result;
  2049.      char *f;
  2050. {
  2051.   char rline[256];
  2052.   char auxstr[256];
  2053.   int i;
  2054.   boolean mdl1 = false;
  2055.   int ri;
  2056.   int sepcount = 0;
  2057.   char STR1[256], STR6[256], STR7[256];
  2058.  
  2059.   strcpy (auxstr, "unknown");
  2060.   i = li;
  2061.   ri = li - 1;
  2062.   while (ri < molbufindex && sepcount < 1)
  2063.     {
  2064.       ri++;
  2065.       strcpy (rline, molbuf[ri - 1]);
  2066.       if (strpos2 (rline, "$$$$", 1) > 0)
  2067.         sepcount++;
  2068.       if ((i == li) && (strcmp (strsub (STR1, rline, 7, 5), "ATOMS") == 0) &&
  2069.           (strcmp (strsub (STR6, rline, 20, 5), "BONDS") == 0) &&
  2070.           (strcmp (strsub (STR7, rline, 33, 7), "CHARGES") == 0))
  2071.         strcpy (auxstr, "alchemy");
  2072.       if ((i == li + 3) && (strcmp (strsub (STR1, rline, 35, 5), "V2000") ==
  2073.                             0))
  2074.         /* and (copy(rline,31,3)='999') */
  2075.         mdl1 = true;
  2076.       if ((i == li + 1) && (strcmp (strsub (STR1, rline, 3, 6), "-ISIS-") ==
  2077.                             0))
  2078.         mdl1 = true;
  2079.       if ((i == li + 1) && (strcmp (strsub (STR1, rline, 3, 8), "WLViewer") ==
  2080.                             0))
  2081.         mdl1 = true;
  2082.       if ((i == li + 1) && (strcmp (strsub (STR1, rline, 3, 8), "CheckMol") ==
  2083.                             0))
  2084.         mdl1 = true;
  2085.       if ((i == li + 1) && (strcmp (strsub (STR1, rline, 3, 8), "CATALYST") ==
  2086.                             0))
  2087.         {
  2088.           mdl1 = true;
  2089.           strcpy (auxstr, "mdl");
  2090.         }
  2091.       if (strpos2 (rline, "M  END", 1) == 1 || mdl1)
  2092.         strcpy (auxstr, "mdl");
  2093.       if (strpos2 (rline, "@<TRIPOS>MOLECULE", 1) > 0)
  2094.         strcpy (auxstr, "sybyl");
  2095.       i++;
  2096.     }
  2097.   /* new in v0.2j: try to identify non-conformant SD-files */
  2098.   if (!strcmp (auxstr, "unknown") && sepcount > 0)
  2099.     strcpy (auxstr, "mdl");
  2100.   return strcpy (Result, auxstr);
  2101. }
  2102.  
  2103.  
  2104. static void
  2105. zap_molecule ()
  2106. {
  2107.   /* try */
  2108.   if (atom != NULL)
  2109.     {
  2110.       free (atom);
  2111.       atom = NULL;              /* added in v0.3j */
  2112.     }
  2113.   if (bond != NULL)
  2114.     {
  2115.       free (bond);
  2116.       bond = NULL;              /* added in v0.3j */
  2117.     }
  2118.   if (ring != NULL)
  2119.     {
  2120.       free (ring);
  2121.       ring = NULL;              /* added in v0.3j */
  2122.     }
  2123.   if (ringprop != NULL)
  2124.     {
  2125.       free (ringprop);
  2126.       ringprop = NULL;          /* added in v0.3j */
  2127.     }
  2128.   /* except
  2129.      on e:Einvalidpointer do begin end;
  2130.      end; */
  2131.   n_atoms = 0;
  2132.   n_bonds = 0;
  2133.   n_rings = 0;
  2134. }
  2135.  
  2136.  
  2137. static void
  2138. zap_needle ()
  2139. {
  2140.   /* try */
  2141.   if (ndl_atom != NULL)
  2142.     {
  2143.       free (ndl_atom);
  2144.       ndl_atom = NULL;          /* added in v0.3j */
  2145.     }
  2146.   if (ndl_bond != NULL)
  2147.     {
  2148.       free (ndl_bond);
  2149.       ndl_bond = NULL;          /* added in v0.3j */
  2150.     }
  2151.   if (ndl_ring != NULL)
  2152.     {
  2153.       free (ndl_ring);
  2154.       ndl_ring = NULL;          /* added in v0.3j */
  2155.     }
  2156.   if (ndl_ringprop != NULL)
  2157.     {
  2158.       free (ndl_ringprop);      /* fixed in v0.3g */
  2159.       ndl_ringprop = NULL;      /* added in v0.3j */
  2160.     }
  2161.   /* except
  2162.      on e:Einvalidpointer do begin end;
  2163.      end; */
  2164.   ndl_n_atoms = 0;
  2165.   ndl_n_bonds = 0;
  2166.   ndl_n_rings = 0;
  2167. }
  2168.  
  2169. #if 0
  2170. static void
  2171. zap_tmp ()
  2172. {
  2173.   /* try */
  2174.   if (tmp_atom != NULL)
  2175.     {
  2176.       free (tmp_atom);
  2177.       tmp_atom = NULL;          /* added in v0.3j */
  2178.     }
  2179.   if (tmp_bond != NULL)
  2180.     {
  2181.       free (tmp_bond);
  2182.       tmp_bond = NULL;          /* added in v0.3j */
  2183.     }
  2184.   if (tmp_ring != NULL)
  2185.     {
  2186.       free (tmp_ring);
  2187.       tmp_ring = NULL;          /* added in v0.3j */
  2188.     }
  2189.   if (tmp_ringprop != NULL)
  2190.     {
  2191.       free (tmp_ringprop);      /* fixed in v0.3g */
  2192.       tmp_ringprop = NULL;      /* added in v0.3j */
  2193.     }
  2194.   /* except
  2195.      on e:Einvalidpointer do begin end;
  2196.      end; */
  2197.   tmp_n_atoms = 0;
  2198.   tmp_n_bonds = 0;
  2199.   tmp_n_rings = 0;
  2200. }
  2201. #endif
  2202.  
  2203. static boolean
  2204. is_heavyatom (id)
  2205.      int id;
  2206. {
  2207.   str2 el;
  2208.  
  2209.   strcpy (el, atom[id - 1].element);
  2210.  
  2211.   if (!strcmp (el, "DU") || !strcmp (el, "LP"))
  2212.     return false;
  2213.   /*if (progmode == pmCheckMol && !strcmp (el, "H ")
  2214.      && atom[id - 1].nucleon_number < 2)
  2215.      return false;               0.3x  */
  2216.   if (!strcmp (el, "H "))       /* 0.3 p */
  2217.     {
  2218.       if (progmode == pmMatchMol && !opt_iso)
  2219.         {
  2220.           return false;
  2221.         }
  2222.       else
  2223.         {
  2224.           if (atom[id - 1].nucleon_number < 2)
  2225.             return false;
  2226.         }
  2227.     }
  2228.   return true;
  2229. }
  2230.  
  2231.  
  2232. static boolean
  2233. ndl_alkene_C (ba)
  2234.      int ba;
  2235. {
  2236.   /* new in v0.3f */
  2237.   boolean res = false;
  2238.   int i, ba2, FORLIM;
  2239.  
  2240.   if (ndl_n_atoms <= 0 || ndl_n_bonds <= 0)
  2241.     return false;
  2242.   FORLIM = ndl_n_bonds;
  2243.   for (i = 0; i < FORLIM; i++)
  2244.     {
  2245.       if (ndl_bond[i].a1 == ba || ndl_bond[i].a2 == ba)
  2246.         {
  2247.           if (ndl_bond[i].a1 == ba)
  2248.             ba2 = ndl_bond[i].a2;
  2249.           else
  2250.             ba2 = ndl_bond[i].a1;
  2251.           if (!strcmp (ndl_atom[ba - 1].atype, "C2 ") &&
  2252.               !strcmp (ndl_atom[ba2 - 1].atype, "C2 ")
  2253.               && ndl_bond[i].btype == 'D' && ndl_bond[i].arom == false)
  2254.             res = true;
  2255.         }
  2256.     }
  2257.   return res;
  2258. }
  2259.  
  2260.  
  2261. static boolean
  2262. is_metal (id)
  2263.      int id;
  2264. {
  2265.   boolean r = false;
  2266.   str2 el;
  2267.  
  2268.   strcpy (el, atom[id - 1].element);
  2269.   if (!strcmp (el, "LI") || !strcmp (el, "NA") || !strcmp (el, "K ") ||
  2270.       !strcmp (el, "RB") || !strcmp (el, "CS") || !strcmp (el, "BE") ||
  2271.       !strcmp (el, "MG") || !strcmp (el, "CA") || !strcmp (el, "SR") ||
  2272.       !strcmp (el, "BA") || !strcmp (el, "TI") || !strcmp (el, "ZR") ||
  2273.       !strcmp (el, "CR") || !strcmp (el, "MO") || !strcmp (el, "MN") ||
  2274.       !strcmp (el, "FE") || !strcmp (el, "CO") || !strcmp (el, "NI") ||
  2275.       !strcmp (el, "PD") || !strcmp (el, "PT") || !strcmp (el, "SN") ||
  2276.       !strcmp (el, "CU") || !strcmp (el, "AG") || !strcmp (el, "AU") ||
  2277.       !strcmp (el, "ZN") || !strcmp (el, "CD") || !strcmp (el, "HG") ||
  2278.       !strcmp (el, "AL") || !strcmp (el, "SN") || !strcmp (el, "PB") ||
  2279.       !strcmp (el, "SB") || !strcmp (el, "BI"))
  2280. /* p2c: checkmol.pas, line 1577:
  2281.  * Note: Line breaker spent 0.0 seconds, 5000 tries on line 1686 [251] */
  2282.     /* etc. etc. */
  2283.     r = true;
  2284.   return r;
  2285. }
  2286.  
  2287.  
  2288. static int
  2289. get_nvalences (a_el)
  2290.      char *a_el;
  2291. {
  2292.   /* changed name and position in v0.3m */
  2293.   /* preliminary version; should be extended to element/atomtype */
  2294.   int res = 1;
  2295.  
  2296.   if (!strcmp (a_el, "H "))
  2297.     res = 1;
  2298.   /*if (!strcmp (a_el, "D "))   // v0.3n
  2299.      res = 1; */
  2300.   if (!strcmp (a_el, "C "))
  2301.     res = 4;
  2302.   if (!strcmp (a_el, "N "))
  2303.     res = 3;
  2304.   if (!strcmp (a_el, "O "))
  2305.     res = 2;
  2306.   if (!strcmp (a_el, "S "))
  2307.     res = 2;
  2308.   if (!strcmp (a_el, "SE"))
  2309.     res = 2;
  2310.   if (!strcmp (a_el, "TE"))
  2311.     res = 2;
  2312.   if (!strcmp (a_el, "P "))
  2313.     res = 3;
  2314.   if (!strcmp (a_el, "F "))
  2315.     res = 1;
  2316.   if (!strcmp (a_el, "CL"))
  2317.     res = 1;
  2318.   if (!strcmp (a_el, "BR"))
  2319.     res = 1;
  2320.   if (!strcmp (a_el, "I "))
  2321.     res = 1;
  2322.   if (!strcmp (a_el, "AT"))
  2323.     res = 1;
  2324.   if (!strcmp (a_el, "B "))
  2325.     res = 3;
  2326.   if (!strcmp (a_el, "LI"))
  2327.     res = 1;
  2328.   if (!strcmp (a_el, "NA"))
  2329.     res = 1;
  2330.   if (!strcmp (a_el, "K "))
  2331.     res = 1;
  2332.   if (!strcmp (a_el, "CA"))
  2333.     res = 2;
  2334.   if (!strcmp (a_el, "SR"))
  2335.     res = 2;
  2336.   if (!strcmp (a_el, "MG"))
  2337.     res = 2;
  2338.   if (!strcmp (a_el, "FE"))
  2339.     res = 3;
  2340.   if (!strcmp (a_el, "MN"))
  2341.     res = 2;
  2342.   if (!strcmp (a_el, "HG"))
  2343.     res = 2;
  2344.   if (!strcmp (a_el, "SI"))
  2345.     res = 4;
  2346.   if (!strcmp (a_el, "SN"))
  2347.     res = 4;
  2348.   if (!strcmp (a_el, "ZN"))
  2349.     res = 2;
  2350.   if (!strcmp (a_el, "CU"))
  2351.     res = 2;
  2352.   if (!strcmp (a_el, "A "))
  2353.     res = 4;
  2354.   if (!strcmp (a_el, "Q "))
  2355.     res = 4;
  2356.   return res;
  2357. }
  2358.  
  2359.  
  2360. static char *
  2361. convert_type (Result, oldtype)
  2362.      char *Result;
  2363.      char *oldtype;
  2364. {
  2365.   int i;
  2366.   str3 newtype;
  2367.  
  2368.   sprintf (newtype, "%.3s", oldtype);
  2369.   for (i = 0; i <= 2; i++)
  2370.     newtype[i] = toupper (newtype[i]);
  2371.   if (newtype[0] == '~')
  2372.     strcpy (newtype, "VAL");
  2373.   if (newtype[0] == '*')
  2374.     strcpy (newtype, "STR");
  2375.   return strcpy (Result, newtype);
  2376. }
  2377.  
  2378.  
  2379. static char *
  2380. convert_sybtype (Result, oldtype)
  2381.      char *Result;
  2382.      char *oldtype;
  2383. {
  2384.   str3 newtype;
  2385.  
  2386.   /*  NewType := Copy(OldType,1,3); */
  2387.   /*  For i := 1 To 3 Do NewType[i] := UpCase(NewType[i]); */
  2388.   /*  If NewType[1] = '~' Then NewType := 'VAL'; */
  2389.   /*  If NewType[1] = '*' Then NewType := 'STR'; */
  2390.   strcpy (newtype, "DU ");
  2391.   if (!strcmp (oldtype, "H    "))
  2392.     strcpy (newtype, "H  ");
  2393.   if (!strcmp (oldtype, "C.ar "))
  2394.     strcpy (newtype, "CAR");
  2395.   if (!strcmp (oldtype, "C.2  "))
  2396.     strcpy (newtype, "C2 ");
  2397.   if (!strcmp (oldtype, "C.3  "))
  2398.     strcpy (newtype, "C3 ");
  2399.   if (!strcmp (oldtype, "C.1  "))
  2400.     strcpy (newtype, "C1 ");
  2401.   if (!strcmp (oldtype, "O.2  "))
  2402.     strcpy (newtype, "O2 ");
  2403.   if (!strcmp (oldtype, "O.3  "))
  2404.     strcpy (newtype, "O3 ");
  2405.   if (!strcmp (oldtype, "O.co2"))
  2406.     strcpy (newtype, "O2 ");
  2407.   if (!strcmp (oldtype, "O.spc"))
  2408.     strcpy (newtype, "O3 ");
  2409.   if (!strcmp (oldtype, "O.t3p"))
  2410.     strcpy (newtype, "O3 ");
  2411.   if (!strcmp (oldtype, "N.1  "))
  2412.     strcpy (newtype, "N1 ");
  2413.   if (!strcmp (oldtype, "N.2  "))
  2414.     strcpy (newtype, "N2 ");
  2415.   if (!strcmp (oldtype, "N.3  "))
  2416.     strcpy (newtype, "N3 ");
  2417.   if (!strcmp (oldtype, "N.pl3"))
  2418.     strcpy (newtype, "NPL");
  2419.   if (!strcmp (oldtype, "N.4  "))
  2420.     strcpy (newtype, "N3+");
  2421.   if (!strcmp (oldtype, "N.am "))
  2422.     strcpy (newtype, "NAM");
  2423.   if (!strcmp (oldtype, "N.ar "))
  2424.     strcpy (newtype, "NAR");
  2425.   if (!strcmp (oldtype, "F    "))
  2426.     strcpy (newtype, "F  ");
  2427.   if (!strcmp (oldtype, "Cl   "))
  2428.     strcpy (newtype, "CL ");
  2429.   if (!strcmp (oldtype, "Br   "))
  2430.     strcpy (newtype, "BR ");
  2431.   if (!strcmp (oldtype, "I    "))
  2432.     strcpy (newtype, "I  ");
  2433.   if (!strcmp (oldtype, "Al   "))
  2434.     strcpy (newtype, "AL ");
  2435.   if (!strcmp (oldtype, "ANY  "))
  2436.     strcpy (newtype, "A  ");
  2437.   if (!strcmp (oldtype, "Ca   "))
  2438.     strcpy (newtype, "CA ");
  2439.   if (!strcmp (oldtype, "Du   "))
  2440.     strcpy (newtype, "DU ");
  2441.   if (!strcmp (oldtype, "Du.C "))
  2442.     strcpy (newtype, "DU ");
  2443.   if (!strcmp (oldtype, "H.spc"))
  2444.     strcpy (newtype, "H  ");
  2445.   if (!strcmp (oldtype, "H.t3p"))
  2446.     strcpy (newtype, "H  ");
  2447.   if (!strcmp (oldtype, "HAL  "))
  2448.     strcpy (newtype, "Cl ");
  2449.   if (!strcmp (oldtype, "HET  "))
  2450.     strcpy (newtype, "Q  ");
  2451.   if (!strcmp (oldtype, "HEV  "))
  2452.     strcpy (newtype, "DU ");
  2453.   if (!strcmp (oldtype, "K    "))
  2454.     strcpy (newtype, "K  ");
  2455.   if (!strcmp (oldtype, "Li   "))
  2456.     strcpy (newtype, "LI ");
  2457.   if (!strcmp (oldtype, "LP   "))
  2458.     strcpy (newtype, "LP ");
  2459.   if (!strcmp (oldtype, "Na   "))
  2460.     strcpy (newtype, "NA ");
  2461.   if (!strcmp (oldtype, "P.3  "))
  2462.     strcpy (newtype, "P3 ");
  2463.   if (!strcmp (oldtype, "S.2  "))
  2464.     strcpy (newtype, "S2 ");
  2465.   if (!strcmp (oldtype, "S.3  "))
  2466.     strcpy (newtype, "S3 ");
  2467.   if (!strcmp (oldtype, "S.o  "))
  2468.     strcpy (newtype, "SO ");
  2469.   if (!strcmp (oldtype, "S.o2 "))
  2470.     strcpy (newtype, "SO2");
  2471.   if (!strcmp (oldtype, "Si   "))
  2472.     strcpy (newtype, "SI ");
  2473.   if (!strcmp (oldtype, "P.4  "))
  2474.     strcpy (newtype, "P4 ");
  2475.   return strcpy (Result, newtype);
  2476. }
  2477.  
  2478.  
  2479. static char *
  2480. convert_MDLtype (Result, oldtype)
  2481.      char *Result, *oldtype;
  2482. {
  2483.   str3 newtype;
  2484.  
  2485.   /*  NewType := Copy(OldType,1,3); */
  2486.   /*  For i := 1 To 3 Do NewType[i] := UpCase(NewType[i]); */
  2487.   /*  If NewType[1] = '~' Then NewType := 'VAL'; */
  2488.   /*  If NewType[1] = '*' Then NewType := 'STR'; */
  2489.   strcpy (newtype, "DU ");
  2490.   if (!strcmp (oldtype, "H  "))
  2491.     strcpy (newtype, "H  ");
  2492.   if (!strcmp (oldtype, "C  "))
  2493.     strcpy (newtype, "C3 ");
  2494.   if (!strcmp (oldtype, "O  "))
  2495.     strcpy (newtype, "O2 ");
  2496.   if (!strcmp (oldtype, "N  "))
  2497.     strcpy (newtype, "N3 ");
  2498.   if (!strcmp (oldtype, "F  "))
  2499.     strcpy (newtype, "F  ");
  2500.   if (!strcmp (oldtype, "Cl "))
  2501.     strcpy (newtype, "CL ");
  2502.   if (!strcmp (oldtype, "Br "))
  2503.     strcpy (newtype, "BR ");
  2504.   if (!strcmp (oldtype, "I  "))
  2505.     strcpy (newtype, "I  ");
  2506.   if (!strcmp (oldtype, "Al "))
  2507.     strcpy (newtype, "AL ");
  2508.   if (!strcmp (oldtype, "ANY"))
  2509.     strcpy (newtype, "A  ");
  2510.   if (!strcmp (oldtype, "Ca "))
  2511.     strcpy (newtype, "CA ");
  2512.   if (!strcmp (oldtype, "Du "))
  2513.     strcpy (newtype, "DU ");
  2514.   if (!strcmp (oldtype, "K  "))
  2515.     strcpy (newtype, "K  ");
  2516.   if (!strcmp (oldtype, "Li "))
  2517.     strcpy (newtype, "LI ");
  2518.   if (!strcmp (oldtype, "LP "))
  2519.     strcpy (newtype, "LP ");
  2520.   if (!strcmp (oldtype, "Na "))
  2521.     strcpy (newtype, "NA ");
  2522.   if (!strcmp (oldtype, "P  "))
  2523.     strcpy (newtype, "P3 ");
  2524.   if (!strcmp (oldtype, "S  "))
  2525.     strcpy (newtype, "S3 ");
  2526.   if (!strcmp (oldtype, "Si "))
  2527.     strcpy (newtype, "SI ");
  2528.   if (!strcmp (oldtype, "P  "))
  2529.     strcpy (newtype, "P4 ");
  2530.   if (!strcmp (oldtype, "A  "))
  2531.     strcpy (newtype, "A  ");
  2532.   if (!strcmp (oldtype, "Q  "))
  2533.     strcpy (newtype, "Q  ");
  2534.   return strcpy (Result, newtype);
  2535. }
  2536.  
  2537.  
  2538. static char *
  2539. get_element (Result, oldtype)
  2540.      char *Result;
  2541.      char *oldtype;
  2542. {
  2543.   char elemstr[256];
  2544.  
  2545.   if (!strcmp (oldtype, "H   "))
  2546.     strcpy (elemstr, "H ");
  2547.   /* if (!strcmp (oldtype, "D   "))  // v0.3n
  2548.      strcpy (elemstr, "D "); */
  2549.   if (!strcmp (oldtype, "CAR "))
  2550.     strcpy (elemstr, "C ");
  2551.   if (!strcmp (oldtype, "C2  "))
  2552.     strcpy (elemstr, "C ");
  2553.   if (!strcmp (oldtype, "C3  "))
  2554.     strcpy (elemstr, "C ");
  2555.   if (!strcmp (oldtype, "C1  "))
  2556.     strcpy (elemstr, "C ");
  2557.   if (!strcmp (oldtype, "O2  "))
  2558.     strcpy (elemstr, "O ");
  2559.   if (!strcmp (oldtype, "O3  "))
  2560.     strcpy (elemstr, "O ");
  2561.   if (!strcmp (oldtype, "O2  "))
  2562.     strcpy (elemstr, "O ");
  2563.   if (!strcmp (oldtype, "O3  "))
  2564.     strcpy (elemstr, "O ");
  2565.   if (!strcmp (oldtype, "O3  "))
  2566.     strcpy (elemstr, "O ");
  2567.   if (!strcmp (oldtype, "N1  "))
  2568.     strcpy (elemstr, "N ");
  2569.   if (!strcmp (oldtype, "N2  "))
  2570.     strcpy (elemstr, "N ");
  2571.   if (!strcmp (oldtype, "N3  "))
  2572.     strcpy (elemstr, "N ");
  2573.   if (!strcmp (oldtype, "NPL "))
  2574.     strcpy (elemstr, "N ");
  2575.   if (!strcmp (oldtype, "N3+ "))
  2576.     strcpy (elemstr, "N ");
  2577.   if (!strcmp (oldtype, "NAM "))
  2578.     strcpy (elemstr, "N ");
  2579.   if (!strcmp (oldtype, "NAR "))
  2580.     strcpy (elemstr, "N ");
  2581.   if (!strcmp (oldtype, "F   "))
  2582.     strcpy (elemstr, "F ");
  2583.   if (!strcmp (oldtype, "CL  "))
  2584.     strcpy (elemstr, "CL");
  2585.   if (!strcmp (oldtype, "BR  "))
  2586.     strcpy (elemstr, "BR");
  2587.   if (!strcmp (oldtype, "I   "))
  2588.     strcpy (elemstr, "I ");
  2589.   if (!strcmp (oldtype, "AT  "))
  2590.     strcpy (elemstr, "AT");
  2591.   if (!strcmp (oldtype, "AL  "))
  2592.     strcpy (elemstr, "AL");
  2593.   if (!strcmp (oldtype, "DU  "))
  2594.     strcpy (elemstr, "DU");
  2595.   if (!strcmp (oldtype, "CA  "))
  2596.     strcpy (elemstr, "CA");
  2597.   if (!strcmp (oldtype, "DU  "))
  2598.     strcpy (elemstr, "DU");
  2599.   if (!strcmp (oldtype, "Cl  "))
  2600.     strcpy (elemstr, "CL");
  2601.   if (!strcmp (oldtype, "K   "))
  2602.     strcpy (elemstr, "K ");
  2603.   if (!strcmp (oldtype, "LI  "))
  2604.     strcpy (elemstr, "LI");
  2605.   if (!strcmp (oldtype, "LP  "))
  2606.     strcpy (elemstr, "LP");
  2607.   if (!strcmp (oldtype, "NA  "))
  2608.     strcpy (elemstr, "NA");
  2609.   if (!strcmp (oldtype, "P3  "))
  2610.     strcpy (elemstr, "P ");
  2611.   if (!strcmp (oldtype, "S2  "))
  2612.     strcpy (elemstr, "S ");
  2613.   if (!strcmp (oldtype, "S3  "))
  2614.     strcpy (elemstr, "S ");
  2615.   if (!strcmp (oldtype, "SO  "))
  2616.     strcpy (elemstr, "S ");
  2617.   if (!strcmp (oldtype, "SO2 "))
  2618.     strcpy (elemstr, "S ");
  2619.   if (!strcmp (oldtype, "SI  "))
  2620.     strcpy (elemstr, "SI");
  2621.   if (!strcmp (oldtype, "P4  "))
  2622.     strcpy (elemstr, "P ");
  2623.   if (!strcmp (oldtype, "A   "))
  2624.     strcpy (elemstr, "A ");
  2625.   if (!strcmp (oldtype, "Q   "))
  2626.     strcpy (elemstr, "Q ");
  2627.   return strcpy (Result, elemstr);
  2628. }
  2629.  
  2630.  
  2631. static char *
  2632. get_sybelement (Result, oldtype)
  2633.      char *Result;
  2634.      char *oldtype;
  2635. {
  2636.   int i;
  2637.   str2 elemstr;
  2638.  
  2639.   if (strpos2 (oldtype, ".", 1) < 2)
  2640.     sprintf (elemstr, "%.2s", oldtype);
  2641.   else
  2642.     {
  2643.       sprintf (elemstr, "%.*s", strpos2 (oldtype, ".", 1) - 1, oldtype);
  2644.       if (strlen (elemstr) < 2)
  2645.         strcat (elemstr, " ");
  2646.     }
  2647.   for (i = 0; i <= 1; i++)
  2648.     elemstr[i] = toupper (elemstr[i]);
  2649.   return strcpy (Result, elemstr);
  2650. }
  2651.  
  2652.  
  2653. static char *
  2654. get_MDLelement (Result, oldtype)
  2655.      char *Result;
  2656.      char *oldtype;
  2657. {
  2658.   int i;
  2659.   str2 elemstr;
  2660.  
  2661.   sprintf (elemstr, "%.2s", oldtype);
  2662.   for (i = 0; i <= 1; i++)
  2663.     elemstr[i] = toupper (elemstr[i]);
  2664.   if (elemstr[0] == '~')
  2665.     strcpy (elemstr, "??");
  2666.   if (elemstr[0] == '*')
  2667.     strcpy (elemstr, "??");
  2668.   return strcpy (Result, elemstr);
  2669. }
  2670.  
  2671. static void
  2672. read_molfile (mfilename)
  2673.      char *mfilename;
  2674. {
  2675.   /* reads ALCHEMY mol files */
  2676.   int n;
  2677.   char rline[256], tmpstr[256];
  2678.   char xstr[256], ystr[256], zstr[256], chgstr[256];
  2679.   float xval, yval, zval, chgval;
  2680.   char a1str[256], a2str[256], elemstr[256];
  2681.   int a1val, a2val, ri;
  2682.   char STR1[256];
  2683.   int FORLIM;
  2684.   atom_rec *WITH;
  2685.   bond_rec *WITH1;
  2686.  
  2687.   if (n_atoms > 0)
  2688.     zap_molecule ();
  2689.   ri = li;
  2690.   strcpy (rline, molbuf[ri - 1]);
  2691.   sprintf (tmpstr, "%.5s", rline);
  2692.   (void)sscanf (tmpstr, "%d", &n_atoms);
  2693.   strsub (tmpstr, rline, 14, 5);
  2694.   (void)sscanf (tmpstr, "%d", &n_bonds);
  2695.   strsub (molname, rline, 42, (int) (strlen (rline) - 42L));
  2696.   /* try */
  2697.   atom = safe_calloc (n_atoms, sizeof (atom_rec));
  2698.   bond = safe_calloc (n_bonds, sizeof (bond_rec));
  2699.   ring = safe_calloc (1, sizeof (ringlist));
  2700.   ringprop = safe_calloc (1, sizeof (ringprop_type));
  2701.   /* except
  2702.      on e:Eoutofmemory do
  2703.      begin
  2704.      writeln('Not enough memory');
  2705.      halt(4);
  2706.      end;
  2707.      end; */
  2708.   n_heavyatoms = 0;
  2709.   n_heavybonds = 0;
  2710.   n_Ctot = 0;                   /* v0.3g */
  2711.   n_Otot = 0;                   /* v0.3g */
  2712.   n_Ntot = 0;                   /* v0.3g */
  2713.   FORLIM = n_atoms;
  2714.   for (n = 1; n <= FORLIM; n++)
  2715.     {
  2716.       ri++;
  2717.       strcpy (rline, molbuf[ri - 1]);
  2718.       strsub (atomtype, rline, 7, 4);
  2719.       sprintf (STR1, "%c", toupper (*atomtype));
  2720.       strcpy (atomtype, STR1);  /* fixed in v0.3f */
  2721.       get_element (elemstr, atomtype);
  2722.       if (!strcmp (elemstr, "C "))
  2723.         n_Ctot++;
  2724.       if (!strcmp (elemstr, "O "))
  2725.         n_Otot++;
  2726.       if (!strcmp (elemstr, "N "))
  2727.         n_Ntot++;
  2728.       convert_type (newatomtype, atomtype);
  2729.       strsub (xstr, rline, 14, 7);
  2730.       strsub (ystr, rline, 23, 7);
  2731.       strsub (zstr, rline, 32, 7);
  2732.       strsub (chgstr, rline, 43, 7);
  2733.       (void)sscanf (xstr, "%g", &xval);
  2734.       (void)sscanf (ystr, "%g", &yval);
  2735.       (void)sscanf (zstr, "%g", &zval);
  2736.       (void)sscanf (chgstr, "%g", &chgval);
  2737.       WITH = &atom[n - 1];
  2738.       strcpy (WITH->element, elemstr);
  2739.       strcpy (WITH->atype, newatomtype);
  2740.       WITH->x = xval;
  2741.       WITH->y = yval;
  2742.       WITH->z = zval;
  2743.       WITH->real_charge = chgval;
  2744.       if (is_heavyatom (n))
  2745.         {
  2746.           n_heavyatoms++;
  2747.           WITH->heavy = true;
  2748.           if (is_metal (n))
  2749.             WITH->metal = true;
  2750.         }
  2751.       WITH->nvalences = get_nvalences (WITH->element);  /* v0.3m   */
  2752.     }
  2753.   /*
  2754.      with atom^[n] do
  2755.      begin
  2756.      x := 0; y := 0; z := 0;  (* v0.3g
  2757.      formal_charge  := 0;
  2758.      real_charge    := 0;
  2759.      Hexp           := 0;
  2760.      Htot           := 0;
  2761.      neighbor_count := 0;
  2762.      ring_count     := 0;
  2763.      arom           := false;
  2764.      stereo_care    := false;
  2765.      heavy          := false;
  2766.      metal          := false;
  2767.      tag            := false;
  2768.      end;
  2769.    */
  2770.   FORLIM = n_bonds;
  2771.   for (n = 0; n < FORLIM; n++)
  2772.     {
  2773.       ri++;
  2774.       strcpy (rline, molbuf[ri - 1]);
  2775.       strsub (a1str, rline, 9, 3);
  2776.       strsub (a2str, rline, 15, 3);
  2777.       (void)sscanf(a1str, "%d", &a1val);
  2778.       (void)sscanf(a2str, "%d", &a2val);
  2779.       WITH1 = &bond[n];
  2780.       WITH1->a1 = a1val;
  2781.       WITH1->a2 = a2val;
  2782.       WITH1->btype = rline[19];
  2783.       WITH1->ring_count = 0;
  2784.       WITH1->arom = false;
  2785.       WITH1->topo = btopo_any;
  2786.       WITH1->stereo = bstereo_any;
  2787.       WITH1->mdl_stereo = 0;    /* v0.3n */
  2788.       if (atom[a1val - 1].heavy && atom[a2val - 1].heavy)
  2789.         n_heavybonds++;
  2790.     }
  2791.   memset (ring, 0, sizeof (ringlist));
  2792.   for (n = 0; n < max_rings; n++)
  2793.     {                           /* new in v0.3 */
  2794.       ringprop[n].size = 0;
  2795.       ringprop[n].arom = false;
  2796.       ringprop[n].envelope = false;
  2797.     }
  2798.   li = ri + 1;
  2799. }
  2800.  
  2801.  
  2802. static void
  2803. read_mol2file (mfilename)
  2804.      char *mfilename;
  2805. {
  2806.   /* reads SYBYL mol2 files */
  2807.   int n, code;
  2808.   char sybatomtype[6];
  2809.   char tmpstr[256], rline[256];
  2810.   char xstr[256], ystr[256], zstr[256], chgstr[256];
  2811.   float xval, yval, zval, chgval;
  2812.   char a1str[256], a2str[256], elemstr[256];
  2813.   int a1val, a2val, ri, FORLIM;
  2814.   atom_rec *WITH;
  2815.   bond_rec *WITH1;
  2816.  
  2817.   if (n_atoms > 0)
  2818.     zap_molecule ();
  2819.   *rline = '\0';
  2820.   ri = li - 1;
  2821.   while ((ri < molbufindex) && (strpos2 (rline, "@<TRIPOS>MOLECULE", 1) == 0))
  2822.     {
  2823.       ri++;
  2824.       strcpy (rline, molbuf[ri - 1]);
  2825.     }
  2826.   if (ri < molbufindex)
  2827.     {
  2828.       ri++;
  2829.       strcpy (molname, molbuf[ri - 1]);
  2830.     }
  2831.   if (ri < molbufindex)
  2832.     {
  2833.       ri++;
  2834.       strcpy (rline, molbuf[ri - 1]);
  2835.     }
  2836.   sprintf (tmpstr, "%.5s", rline);
  2837.   (void)sscanf (tmpstr, "%d", &n_atoms);
  2838. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  2839.   strsub (tmpstr, rline, 7, 5);
  2840.   (void)sscanf (tmpstr, "%d", &n_bonds);
  2841.   /* try */
  2842. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  2843.   atom = safe_calloc (n_atoms, sizeof (atom_rec));
  2844.   bond = safe_calloc (n_bonds, sizeof (bond_rec));
  2845.   ring = safe_calloc (1, sizeof (ringlist));
  2846.   ringprop = safe_calloc (1, sizeof (ringprop_type));
  2847.   /* except
  2848.      on e:Eoutofmemory do
  2849.      begin
  2850.      writeln('Not enough memory');
  2851.      halt(4);
  2852.      end;
  2853.      end; */
  2854.   n_heavyatoms = 0;
  2855.   n_heavybonds = 0;
  2856.   n_Ctot = 0;                   /* v0.3g */
  2857.   n_Otot = 0;                   /* v0.3g */
  2858.   n_Ntot = 0;                   /* v0.3g */
  2859.   while ((ri < molbufindex) && (strpos2 (rline, "@<TRIPOS>ATOM", 1) == 0))
  2860.     {
  2861.       ri++;
  2862.       strcpy (rline, molbuf[ri - 1]);
  2863.     }
  2864.   FORLIM = n_atoms;
  2865.   for (n = 1; n <= FORLIM; n++)
  2866.     {
  2867.       /*
  2868.          with atom^[n] do
  2869.          begin
  2870.          x := 0; y := 0; z := 0;  (* v0.3g
  2871.          formal_charge  := 0;
  2872.          real_charge    := 0;
  2873.          Hexp           := 0;
  2874.          Htot           := 0;
  2875.          neighbor_count := 0;
  2876.          ring_count     := 0;
  2877.          arom           := false;
  2878.          stereo_care    := false;
  2879.          heavy          := false;
  2880.          metal          := false;
  2881.          tag            := false;
  2882.          end;
  2883.        */
  2884.       if (ri < molbufindex)
  2885.         {
  2886.           ri++;
  2887.           strcpy (rline, molbuf[ri - 1]);
  2888.         }
  2889.       strsub (sybatomtype, rline, 48, 5);
  2890.       get_sybelement (elemstr, sybatomtype);
  2891.       if (!strcmp (elemstr, "C "))
  2892.         n_Ctot++;
  2893.       if (!strcmp (elemstr, "O "))
  2894.         n_Otot++;
  2895.       if (!strcmp (elemstr, "N "))
  2896.         n_Ntot++;
  2897.       convert_sybtype (newatomtype, sybatomtype);
  2898.       strsub (xstr, rline, 18, 9);
  2899.       strsub (ystr, rline, 28, 9);
  2900.       strsub (zstr, rline, 38, 9);
  2901.       strsub (chgstr, rline, 70, 9);
  2902.       (void)sscanf (xstr, "%g", &xval);
  2903.       (void)sscanf (ystr, "%g", &yval);
  2904.       (void)sscanf (zstr, "%g", &zval);
  2905.       (void)sscanf (chgstr, "%g", &chgval);
  2906.       WITH = &atom[n - 1];
  2907.       strcpy (WITH->element, elemstr);
  2908.       strcpy (WITH->atype, newatomtype);
  2909.       WITH->x = xval;
  2910.       WITH->y = yval;
  2911.       WITH->z = zval;
  2912.       WITH->real_charge = chgval;
  2913.       if (is_heavyatom (n))
  2914.         {
  2915.           n_heavyatoms++;
  2916.           WITH->heavy = true;
  2917.           if (is_metal (n))
  2918.             WITH->metal = true;
  2919.         }
  2920.       WITH->nvalences = get_nvalences (WITH->element);  /* v0.3m   */
  2921.     }
  2922.   while ((ri < molbufindex) && (strpos2 (rline, "@<TRIPOS>BOND", 1) == 0))
  2923.     {
  2924.       ri++;
  2925.       strcpy (rline, molbuf[ri - 1]);
  2926.     }
  2927.   FORLIM = n_bonds;
  2928.   for (n = 0; n < FORLIM; n++)
  2929.     {
  2930.       if (ri < molbufindex)
  2931.         {
  2932.           ri++;
  2933.           strcpy (rline, molbuf[ri - 1]);
  2934.         }
  2935.       strsub (a1str, rline, 9, 3);
  2936.       strsub (a2str, rline, 14, 3);
  2937.       code = (sscanf (a1str, "%d", &a1val) == 0);
  2938.       if (code != 0)
  2939.         printf ("%s\007\n", rline);
  2940.       code = (sscanf (a2str, "%d", &a2val) == 0);
  2941.       if (code != 0)
  2942.         printf ("%s\007\n", rline);
  2943.       WITH1 = &bond[n];
  2944.       WITH1->a1 = a1val;
  2945.       WITH1->a2 = a2val;
  2946.       if (rline[17] == '1')
  2947.         WITH1->btype = 'S';
  2948.       if (rline[17] == '2')
  2949.         WITH1->btype = 'D';
  2950.       if (rline[17] == '3')
  2951.         WITH1->btype = 'T';
  2952.       if (rline[17] == 'a')
  2953.         WITH1->btype = 'A';
  2954.       WITH1->ring_count = 0;
  2955.       WITH1->arom = false;
  2956.       WITH1->topo = btopo_any;
  2957.       WITH1->stereo = bstereo_any;
  2958.       WITH1->mdl_stereo = 0;    /* v0.3n */
  2959.       if (atom[a1val - 1].heavy && atom[a2val - 1].heavy)
  2960.         n_heavybonds++;
  2961.     }
  2962.   memset (ring, 0, sizeof (ringlist));
  2963.   for (n = 0; n < max_rings; n++)
  2964.     {                           /* new in v0.3 */
  2965.       ringprop[n].size = 0;
  2966.       ringprop[n].arom = false;
  2967.       ringprop[n].envelope = false;
  2968.     }
  2969.   li = ri + 1;
  2970. }
  2971.  
  2972.  
  2973. static void
  2974. read_charges (chgstring_)
  2975.      char *chgstring_;
  2976. {
  2977.   char chgstring[256];
  2978.   int a_id, a_chg;
  2979.   /* int n_chrg;*/
  2980.  
  2981.   /* typical example: a molecule with 2 cations + 1 anion */
  2982.   /* M  CHG  3   8   1  10   1  11  -1 */
  2983.   strcpy (chgstring, chgstring_);
  2984.   if (strpos2 (chgstring, "M  CHG", 1) <= 0)
  2985.     return;
  2986.   strdelete (chgstring, 1, 6);
  2987.   left_trim (chgstring);
  2988.  /* n_chrg = left_int (chgstring);*/
  2989.   /* this assignment must be kept also in non-debug mode! */
  2990. /* p2c: checkmol.pas, line 2077:
  2991.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  2992.   /*$IFDEF debug */
  2993.   /*if (n_chrg == 0)
  2994.      debugoutput ("strange... M  CHG present, but no charges found"); */
  2995.   /*$ENDIF */
  2996.   while (*chgstring != '\0')
  2997.     {
  2998.       a_id = left_int (chgstring);
  2999.       a_chg = left_int (chgstring);
  3000.       if (a_id != 0 && a_chg != 0)
  3001.         atom[a_id - 1].formal_charge = a_chg;
  3002.       //printf ("CHG %i %i\n", a_id, a_chg);
  3003.     }
  3004. }
  3005.  
  3006. static void
  3007. read_isotopes (char *isotopestring_)
  3008. {
  3009.   char isotopestring[256];
  3010.   int a_id, a_nucleon_number;
  3011.   /* int n_isotopes;*/
  3012.  
  3013.   /* typical example: a molecule with 2 cations + 1 anion */
  3014.   /* M  CHG  3   8   1  10   1  11  -1 */
  3015.   strcpy (isotopestring, isotopestring_);
  3016.   if (strpos2 (isotopestring, "M  ISO", 1) <= 0)
  3017.     return;
  3018.   strdelete (isotopestring, 1, 6);
  3019.   left_trim (isotopestring);
  3020.   /*n_isotopes = left_int (isotopestring);*/
  3021.   /* this assignment must be kept also in non-debug mode! */
  3022. /* p2c: checkmol.pas, line 2077:
  3023.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  3024.   /*$IFDEF debug */
  3025.   /*if (n_chrg == 0)
  3026.      debugoutput ("strange... M  CHG present, but no charges found"); */
  3027.   /*$ENDIF */
  3028.   while (*isotopestring != '\0')
  3029.     {
  3030.       a_id = left_int (isotopestring);
  3031.       a_nucleon_number = left_int (isotopestring);
  3032.       if (a_id != 0 && a_nucleon_number != 0)
  3033.         {
  3034.           atom[a_id - 1].nucleon_number = a_nucleon_number;
  3035.           if (!strcmp (atom[a_id - 1].element, "H "))
  3036.             {
  3037.               atom[a_id - 1].heavy = true;
  3038.               n_heavyatoms++;
  3039.               strcpy (atom[a_id - 1].atype, "DU ");
  3040.             }
  3041.         }
  3042.       //printf ("ISO %i %i\n", a_id, a_nucleon_number);
  3043.     }
  3044. }
  3045.  
  3046. static void
  3047. read_radicals (radstring_)
  3048.      char *radstring_;
  3049. {
  3050.   char radstring[256];
  3051.   int a_id, a_rad;
  3052.  
  3053.   /* typical example: a molecule with 2 cations + 1 anion */
  3054.   /* M  CHG  3   8   1  10   1  11  -1 */
  3055.   strcpy (radstring, radstring_);
  3056.   if (strpos2 (radstring, "M  RAD", 1) <= 0)
  3057.     return;
  3058.   strdelete (radstring, 1, 6);
  3059.   left_trim (radstring);
  3060.   (void)left_int (radstring);
  3061.   /* this assignment must be kept also in non-debug mode! */
  3062. /* p2c: checkmol.pas, line 2077:
  3063.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  3064.   /*$IFDEF debug */
  3065.   /*if (n_chrg == 0)
  3066.      debugoutput ("strange... M  CHG present, but no charges found"); */
  3067.   /*$ENDIF */
  3068.   while (*radstring != '\0')
  3069.     {
  3070.       a_id = left_int (radstring);
  3071.       a_rad = left_int (radstring);
  3072.       if (a_id != 0 && a_rad != 0)
  3073.         atom[a_id - 1].radical_type = a_rad;
  3074.       //printf ("RAD %i %i\n", a_id, a_rad);
  3075.     }
  3076. }
  3077.  
  3078.  
  3079. static void
  3080. read_MDLmolfile (char *mfilename)
  3081. {
  3082.   /* reads MDL mol files */
  3083.   int n, v, tmp_n_atoms, tmp_n_bonds, code;     /* v0.3l */
  3084.   char rline[256], tmpstr[256];
  3085.   char xstr[256], ystr[256], zstr[256], chgstr[256];
  3086.   float xval, yval, zval, chgval;
  3087.   char a1str[256], a2str[256], elemstr[256];
  3088.   int a1val, a2val, ri, rc, bt, bs;
  3089.   int sepcount = 0;
  3090.   int i;                        /* v0.3j */
  3091.   boolean clearcharges = true;  /* v0.3j */
  3092.   char STR1[256];
  3093. /*  int FORLIM;*/
  3094.   atom_rec *WITH;
  3095.   bond_rec *WITH1;
  3096.  
  3097.   /* v0.3j */
  3098.   if (n_atoms > 0)
  3099.     zap_molecule ();
  3100.   /*cm_mdlmolfile := false; */
  3101.   *rline = '\0';
  3102.   ri = li;
  3103.   strcpy (molname, molbuf[ri - 1]);     /* line 1 */
  3104.   if (ri < molbufindex)         /* line 2 */
  3105.     ri++;
  3106.   strcpy (rline, molbuf[ri - 1]);
  3107.   if (strpos2 (rline, "CheckMol", 1) == 3)
  3108.     {
  3109.       /*cm_mdlmolfile := true; */
  3110.       found_arominfo = true;
  3111.       tmfcode = 1;              /* v0.3m (begin) */
  3112.       code = 0;
  3113.       if ((strlen (rline) >= 39) && (strpos2 (rline, "TMF", 1) == 35))
  3114.         {                       /* v0.3m; encoding of tweaklevel */
  3115.           strsub (tmpstr, rline, 38, 2);
  3116.           code = (sscanf (tmpstr, "%d", &tmfcode) == 0);
  3117.         }
  3118.       if (code != 0 || tmfcode != tweaklevel)
  3119.         tmfmismatch = true;
  3120.       else
  3121.         tmfmismatch = false;
  3122.       if ((strpos2 (rline, ":r0", 1) >= 40 && ringsearch_mode != rs_sar) |
  3123.           (strpos2 (rline, ":r1", 1) >= 40 && ringsearch_mode != rs_ssr))
  3124.         tmfmismatch = true;
  3125.       if ((strpos2 (rline, ":m0", 1) >= 40 && opt_metalrings == true) |
  3126.           (strpos2 (rline, ":m1", 1) >= 40 && opt_metalrings == false))
  3127.         tmfmismatch = true;
  3128. /* p2c: checkmol.pas, line 2128:
  3129.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  3130.       /*$IFDEF debug */
  3131.       //if (tmfmismatch)
  3132.       //printf ("\"tweaked\" molfile: version mismatch!\n");
  3133.       // else
  3134.       //printf ("\"tweaked\" molfile: version OK");
  3135.     }
  3136.   /*$ENDIF */
  3137.   /* v0.3m (end) */
  3138.   if (ri < molbufindex)         /* line 3 */
  3139.     ri++;
  3140.   strcpy (rline, molbuf[ri - 1]);
  3141.   strcpy (molcomment, rline);
  3142.   if (ri < molbufindex)         /* line 4 */
  3143.     ri++;
  3144.   strcpy (rline, molbuf[ri - 1]);
  3145.   sprintf (tmpstr, "%.3s", rline);
  3146.   (void)sscanf (tmpstr, "%d", &n_atoms);
  3147.   strsub (tmpstr, rline, 4, 3);
  3148.   (void)sscanf (tmpstr, "%d", &n_bonds);
  3149.   strsub (tmpstr, rline, 10, 3);
  3150.   /* if it is a CheckMol-tweaked molfile, this is the number of rings */
  3151.   n_cmrings = 0;
  3152.   code = (sscanf (tmpstr, "%d", &n_cmrings) == 0);
  3153.   if (code != 0)
  3154.     n_cmrings = 0;
  3155.   /* do some range checking for n_atoms, n_bonds; new in v0.3l */
  3156.   tmp_n_atoms = n_atoms;
  3157.   if (n_atoms > max_atoms)
  3158.     n_atoms = max_atoms;
  3159.   if (n_atoms < 0)
  3160.     n_atoms = 0;
  3161.   tmp_n_bonds = n_bonds;
  3162.   if (n_bonds > max_bonds)
  3163.     n_bonds = max_bonds;
  3164.   if (n_bonds < 0)
  3165.     n_bonds = 0;
  3166.   if (n_atoms == 0
  3167. #ifndef MAKE_SHARED_LIBRARY
  3168.       && opt_verbose
  3169. #endif
  3170.     )
  3171.     {                           /* v0.3l */
  3172.       printf ("WARNING: Possible NoStruct read!\n");
  3173.       printf ("NoStructs are proprietary, obsolete and dangerous.\n");
  3174.     }
  3175.   /* try */
  3176.   atom = safe_calloc (n_atoms, sizeof (atom_rec));
  3177.   bond = safe_calloc (n_bonds, sizeof (bond_rec));
  3178.   /* this would be only one safe_calloc() in C;  v0.3l */
  3179.   ring = safe_calloc (1, sizeof (ringlist));
  3180.   ringprop = safe_calloc (1, sizeof (ringprop_type));
  3181.   /* except
  3182.      on e:Eoutofmemory do
  3183.      begin
  3184.      writeln('Not enough memory');
  3185.      (* close(molfile);
  3186.      halt(4);
  3187.      exit;
  3188.      end;
  3189.      end; */
  3190.   /* check for the chirality flag */
  3191.   if (strlen (rline) > 14 && rline[14] == '1')  /* new in v0.3f */
  3192.     chir_flag = true;
  3193.   n_heavyatoms = 0;
  3194.   n_heavybonds = 0;
  3195.   n_Ctot = 0;                   /* v0.3g */
  3196.   n_Otot = 0;                   /* v0.3g */
  3197.   n_Ntot = 0;                   /* v0.3g */
  3198.   if (n_atoms > 0)
  3199.     {                           /* v0.3l */
  3200.       for (n = 1; n <= tmp_n_atoms; n++)
  3201.         {
  3202.           if (n <= max_atoms)
  3203.             v = n;
  3204.           else
  3205.             v = max_atoms;
  3206.           /* just for safety; v0.3l */
  3207.           /*
  3208.              with atom^[v] do
  3209.              begin
  3210.              x := 0; y := 0; z := 0;  (* v0.3g
  3211.              formal_charge  := 0;
  3212.              real_charge    := 0;
  3213.              Hexp           := 0;
  3214.              Htot           := 0;
  3215.              neighbor_count := 0;
  3216.              ring_count     := 0;
  3217.              arom           := false;
  3218.              stereo_care    := false;
  3219.              metal          := false;
  3220.              heavy          := false;
  3221.              tag            := false;
  3222.              end;
  3223.            */
  3224.           /* replaced by fillchar() after getmem() (see above); v0.3l */
  3225.           ri++;
  3226.           strcpy (rline, molbuf[ri - 1]);
  3227.           strsub (atomtype, rline, 32, 3);
  3228.           get_MDLelement (elemstr, atomtype);
  3229.           if (!strcmp (elemstr, "C "))
  3230.             n_Ctot++;
  3231.           if (!strcmp (elemstr, "O "))
  3232.             n_Otot++;
  3233.           if (!strcmp (elemstr, "N "))
  3234.             n_Ntot++;
  3235.  
  3236.           convert_MDLtype (newatomtype, atomtype);
  3237.           strsub (xstr, rline, 1, 10);  /* fixed in v0.3k (was: 2,9 etc.) */
  3238.           strsub (ystr, rline, 11, 10);
  3239.           strsub (zstr, rline, 21, 10);
  3240.           /*chgstr := '0'; */
  3241.           strsub (chgstr, rline, 37, 3);        /* new in v0.3j */
  3242.           (void)sscanf (chgstr, "%f", &chgval);
  3243.           if (chgval != 0)
  3244.             {
  3245.               if (chgval >= 1 && chgval <= 7)
  3246.                 chgval = 4.0 - chgval;
  3247.               else
  3248.                 {
  3249.                   chgval = 0.0;
  3250.                 }
  3251.             }                   /* end (v0.3j) */
  3252.           (void)sscanf (xstr, "%f", &xval);
  3253.           (void)sscanf (ystr, "%f", &yval);
  3254.           (void)sscanf (zstr, "%f", &zval);
  3255.           /* v0.3k: removed superfluous val(chgstr,chgval,code) */
  3256.           WITH = &atom[v - 1];
  3257.           strcpy (WITH->element, elemstr);
  3258.           if (!strcmp (elemstr, "A ") || !strcmp (elemstr, "Q ") ||
  3259.               !strcmp (elemstr, "X "))
  3260.             /* 'X ' added in v0.3n */
  3261.             found_querymol = true;
  3262.  
  3263.           strcpy (WITH->atype, newatomtype);
  3264.  
  3265.  
  3266.           if (!strcmp (elemstr, "D "))
  3267.             {
  3268.               strcpy (WITH->element, "H ");
  3269.               WITH->nucleon_number = 2;
  3270.             }                   /* 0.3x */
  3271.           if (!strcmp (elemstr, "T "))
  3272.             {
  3273.               strcpy (WITH->element, "H ");
  3274.               WITH->nucleon_number = 3;
  3275.             }                   /* 0.3x */
  3276.  
  3277.  
  3278.  
  3279.           WITH->x = xval;
  3280.           WITH->y = yval;
  3281.           WITH->z = zval;
  3282.           WITH->formal_charge = (long) floor (chgval + 0.5);
  3283.           WITH->real_charge = 0.0;      /* v0.3j */
  3284.           /* read aromaticity flag from CheckMol-tweaked MDL molfile */
  3285.           if (strlen (rline) > 37 && rline[37] == '0')
  3286.             {
  3287.               WITH->arom = true;
  3288.               found_arominfo = true;
  3289.             }
  3290.           /* new in v0.3d: read stereo care flag */
  3291.           if (strlen (rline) > 47 && rline[47] == '1')
  3292.             WITH->stereo_care = true;
  3293.           if (is_heavyatom (n))
  3294.             {
  3295.               n_heavyatoms++;
  3296.               WITH->heavy = true;
  3297.               if (is_metal (n))
  3298.                 WITH->metal = true;
  3299.             }
  3300.           WITH->nvalences = get_nvalences (WITH->element);
  3301.           /* v0.3m                 */
  3302.         }
  3303.     }                           /* if (n_atoms > 0)... */
  3304.   if (n_bonds > 0)
  3305.     {                           /* v0.3l */
  3306.       for (n = 1; n <= tmp_n_bonds; n++)
  3307.         {
  3308.           if (n <= max_bonds)
  3309.             v = n;
  3310.           else
  3311.             v = max_bonds;
  3312.           /* just for safety; v0.3l */
  3313.           ri++;
  3314.           strcpy (rline, molbuf[ri - 1]);
  3315.           sprintf (a1str, "%.3s", rline);
  3316.           strsub (a2str, rline, 4, 3);
  3317.           code = (sscanf (a1str, "%d", &a1val) == 0);
  3318.           if (code != 0)        /* v0.3l */
  3319.             a1val = 1;
  3320.           code = (sscanf (a2str, "%d", &a2val) == 0);
  3321.           if (code != 0)        /* v0.3l */
  3322.             a2val = 1;
  3323.           WITH1 = &bond[v - 1];
  3324.           WITH1->a1 = a1val;
  3325.           WITH1->a2 = a2val;
  3326.           if (rline[8] == '1')  /* single */
  3327.             WITH1->btype = 'S';
  3328.           if (rline[8] == '2')  /* double */
  3329.             WITH1->btype = 'D';
  3330.           if (rline[8] == '3')  /* triple */
  3331.             WITH1->btype = 'T';
  3332.           if (rline[8] == '4')  /* aromatic */
  3333.             WITH1->btype = 'A';
  3334.           if (rline[8] == '5')  /* single or double */
  3335.             WITH1->btype = 'l';
  3336.           if (rline[8] == '6')  /* single or aromatic */
  3337.             WITH1->btype = 's';
  3338.           if (rline[8] == '7')  /* double or aromatic */
  3339.             WITH1->btype = 'd';
  3340.           if (rline[8] == '8')  /* any */
  3341.             WITH1->btype = 'a';
  3342.           sprintf (STR1, "%c", WITH1->btype);
  3343.           if (strpos2 ("lsda", STR1, 1) > 0)
  3344.             found_querymol = true;
  3345.           WITH1->arom = false;
  3346.           WITH1->q_arom = false;        /* 0.3p */
  3347.           /* read aromaticity flag from CheckMol-tweaked MDL molfile */
  3348.           if (WITH1->btype == 'A' || rline[7] == '0')
  3349.             {
  3350.               WITH1->arom = true;
  3351.               if (rline[7] == '0')
  3352.                 found_arominfo = true;
  3353.             }
  3354.           strsub (tmpstr, rline, 13, 3);
  3355.           /* new in v0.3d: read ring_count from tweaked molfile */
  3356.           code = (sscanf (tmpstr, "%d", &rc) == 0);
  3357.           if (code != 0 || rc < 0 || progmode == pmCheckMol || tmfmismatch)
  3358.             WITH1->ring_count = 0;
  3359.           else
  3360.             WITH1->ring_count = rc;
  3361.           /* v0.3n: added tmfmismatch check */
  3362.           strsub (tmpstr, rline, 16, 3);        /* new in v0.3d: read bond topology; */
  3363.           code = (sscanf (tmpstr, "%d", &bt) == 0);
  3364.           /* extended features are encoded by leading zero */
  3365.           if (code != 0 || (unsigned long) bt > 2)
  3366.             WITH1->topo = btopo_any;
  3367.           else
  3368.             {
  3369.               if (tmpstr[1] == '0')
  3370.                 WITH1->topo = bt + 3;
  3371.               else
  3372.                 WITH1->topo = bt;
  3373.             }
  3374.           /* v0.3n changed >5 into >2 */
  3375.           /* new in v0.3d: add stereo property from MDL "stereo care" flag in atom block */
  3376.           WITH1->stereo = bstereo_any;
  3377.           if (WITH1->btype == 'D')
  3378.             {
  3379.               if (atom[WITH1->a1 - 1].stereo_care
  3380.                   && atom[WITH1->a2 - 1].stereo_care)
  3381.                 {               /* this is the MDL-conformant encoding, */
  3382.                   WITH1->stereo = bstereo_xyz;  /* for an alternative see below */
  3383.                   ez_flag = true;       /* v0.3f */
  3384.                 }
  3385.               else
  3386.                 {               /* this extended feature is encoded by a leading zero */
  3387.                   strsub (tmpstr, rline, 10, 3);
  3388.                   /* new in v0.3d: read bond stereo specification; */
  3389.                   code = (sscanf (tmpstr, "%d", &bs) == 0);
  3390.                   WITH1->mdl_stereo = bs;       /* v0.3n */
  3391.                   if (code != 0 || bs <= 0 || bs > 2)
  3392.                     WITH1->stereo = bstereo_any;
  3393.                   else
  3394.                     WITH1->stereo = bstereo_xyz;
  3395.                   if (tmpstr[1] == '0')
  3396.                     WITH1->stereo = bstereo_xyz;
  3397.                 }
  3398.             }
  3399.           /*if stereo <> bstereo_any then ez_search := true; */
  3400.           if (WITH1->stereo != bstereo_any)     /* changed in v0.3f */
  3401.             ez_flag = true;
  3402.           if (WITH1->btype == 'S' && strlen (rline) > 11 && rline[11] == '1')
  3403.             WITH1->stereo = bstereo_up;
  3404.           if (WITH1->btype == 'S' && strlen (rline) > 11 && rline[11] == '6')
  3405.             WITH1->stereo = bstereo_down;
  3406.           if (WITH1->btype == 'S' && strlen (rline) > 11 && rline[11] == '4')
  3407.             WITH1->stereo = bstereo_either;     /* 0.3x */
  3408.           if (WITH1->btype == 'D' && strlen (rline) > 11 && rline[11] == '3')
  3409.             WITH1->stereo = bstereo_double_either;      /* 0.3x */
  3410.           strsub (tmpstr, rline, 10, 3);
  3411.           /* new in v0.3n: save original bond stereo specification; */
  3412.           (void)sscanf (tmpstr, "%d", &bs);
  3413.           /* v0.3n */
  3414. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  3415.           WITH1->mdl_stereo = bs;       /* v0.3n */
  3416.           if (atom[a1val - 1].heavy && atom[a2val - 1].heavy)
  3417.             n_heavybonds++;
  3418.         }
  3419.     }                           /* if (n_bonds > 0)... */
  3420.   while (ri < molbufindex && sepcount < 1)
  3421.     {
  3422.       ri++;
  3423.       strcpy (rline, molbuf[ri - 1]);
  3424.       if (strpos2 (rline, "M  CHG", 1) > 0)
  3425.         {                       /* new in v0.3j */
  3426.           if (clearcharges)
  3427.             {                   /* "M  CHG" supersedes all "old-style" charge values */
  3428.  
  3429.               for (i = 0; i < n_atoms; i++)
  3430.                 atom[i].formal_charge = 0;
  3431.             }
  3432.           read_charges (rline);
  3433.           clearcharges = false;
  3434.           /* subsequent "M  CHG" lines must not clear previous values */
  3435.         }
  3436.  
  3437.       if (strpos2 (rline, "M  ISO", 1) > 0)
  3438.         read_isotopes (rline);  /* 0.3x */
  3439.  
  3440.       if (strpos2 (rline, "M  RAD", 1) > 0)
  3441.         read_radicals (rline);  /* 0.3x */
  3442.  
  3443.       if (strpos2 (rline, "$$$$", 1) > 0)
  3444.         {
  3445.           sepcount++;
  3446.           if (molbufindex > ri + 2)     /* we assume this is an SDF file */
  3447.             mol_in_queue = true;
  3448.         }
  3449.     }
  3450.   memset (ring, 0, sizeof (ringlist));
  3451.   for (n = 0; n < max_rings; n++)
  3452.     {                           /* new in v0.3 */
  3453.       ringprop[n].size = 0;
  3454.       ringprop[n].arom = false;
  3455.       ringprop[n].envelope = false;
  3456.     }
  3457.   li = ri + 1;
  3458. }
  3459.  
  3460.  
  3461.  
  3462. static void
  3463. write_MDLmolfile ()
  3464. {
  3465.   int i;
  3466.   char tmpstr[256];
  3467.   char wline[256];
  3468.   int a_chg;
  3469.   int a_iso;
  3470.   int a_rad;
  3471.   char tmflabel[256];           /* v0.3m */
  3472.   char STR1[256];
  3473.   /*char STR7[256];*/
  3474.   int FORLIM;
  3475.  
  3476.   sprintf (tmflabel, "%d", (int) tweaklevel);   /* v0.3m */
  3477.   while (strlen (tmflabel) < 2) /* v0.3m */
  3478.     sprintf (tmflabel, "0%s", strcpy (STR1, tmflabel));
  3479.   sprintf (tmflabel, "TMF%s", strcpy (STR1, tmflabel)); /* v0.3m */
  3480.   if (strlen (molname) > 80)
  3481.     sprintf (molname, "%.80s", strcpy (STR1, molname));
  3482.   puts (molname);
  3483.   printf ("  CheckMol                        %s", tmflabel);    /* v0.3m */
  3484.   if (ringsearch_mode == rs_sar)        /* v0.3m */
  3485.     printf (":r0");
  3486.   if (ringsearch_mode == rs_ssr)        /* v0.3m */
  3487.     printf (":r1");
  3488.   if (opt_metalrings)
  3489.     printf (":m1");
  3490.   else
  3491.     printf (":m0");
  3492.   /* v0.3m */
  3493.   printf ("\n%s\n", molcomment);
  3494.   *wline = '\0';
  3495.   *tmpstr = '\0';
  3496.   sprintf (tmpstr, "%d", n_atoms);
  3497.   lblank (3L, tmpstr);
  3498.   strcat (wline, tmpstr);
  3499.   *tmpstr = '\0';               /* first 3 digits: number of atoms */
  3500.   sprintf (tmpstr, "%d", n_bonds);
  3501.   lblank (3L, tmpstr);
  3502.   strcat (wline, tmpstr);
  3503.   *tmpstr = '\0';               /* next 3 digits: number of bonds */
  3504.   strcpy (tmpstr, "  0");
  3505.   strcat (wline, tmpstr);
  3506.   *tmpstr = '\0';               /* next 3 digits: number of atom lists (not used by us) */
  3507. /* p2c: checkmol.pas, line 2388:
  3508.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  3509. #ifdef REDUCED_SAR
  3510.   sprintf (tmpstr, "%d", n_countablerings);
  3511.   /* v0.3n; changed n_rings into n_countablerings */
  3512. #else
  3513.   sprintf (tmpstr, "%d", n_rings);
  3514. #endif
  3515.   lblank (3L, tmpstr);
  3516.   strcat (wline, tmpstr);
  3517.   *tmpstr = '\0';
  3518.   /* officially "obsolete", we use it for the number of rings */
  3519.   strcat (wline, "  ");         /* v0.3n: obey chiral flag */
  3520.   if (chir_flag)
  3521.     strcat (wline, "1");
  3522.   else
  3523.     strcat (wline, "0");
  3524.   /* v0.3n */
  3525.   strcat (wline, "               999 V2000");
  3526.   /* v0.3n (adjust string length) */
  3527.   puts (wline);
  3528.   FORLIM = n_atoms;
  3529.   for (i = 0; i < FORLIM; i++)
  3530.     {
  3531.       *wline = '\0';
  3532.       sprintf (tmpstr, "%1.4f", atom[i].x);
  3533.       lblank (10L, tmpstr);
  3534.       strcat (wline, tmpstr);
  3535.       sprintf (tmpstr, "%1.4f", atom[i].y);
  3536.       lblank (10L, tmpstr);
  3537.       strcat (wline, tmpstr);
  3538.       sprintf (tmpstr, "%1.4f", atom[i].z);
  3539.       lblank (10L, tmpstr);
  3540.       strcat (wline, tmpstr);
  3541.       strcpy (tmpstr, atom[i].element);
  3542.       /* tmpstr := lowercase(tmpstr); REPLACE!!! */
  3543.       //tmpstr[0] = toupper (tmpstr[0]);
  3544.       all_lowercase (tmpstr);
  3545.       tmpstr[0] = toupper (tmpstr[0]);
  3546.       /*wline := wline + ' '+atom^[i].element+' '; */
  3547.       sprintf (wline + strlen (wline), " %s ", tmpstr);
  3548.       strcat (wline, " 0");     /* mass difference (isotopes) */
  3549.       /* now we code aromaticity into the old-style charge column (charges are now in the M  CHG line) */
  3550.       if (atom[i].arom)
  3551.         strcpy (tmpstr, " 00");
  3552.       else
  3553.         strcpy (tmpstr, "  0");
  3554.       strcat (wline, tmpstr);
  3555.       strcat (wline, "  0  0  0  0  0  0  0  0  0  0");
  3556.       puts (wline);
  3557.     }
  3558.   FORLIM = n_bonds;
  3559.   for (i = 0; i < FORLIM; i++)
  3560.     {
  3561.       *wline = '\0';
  3562.       sprintf (tmpstr, "%d", bond[i].a1);
  3563.       lblank (3L, tmpstr);
  3564.       strcat (wline, tmpstr);
  3565.       sprintf (tmpstr, "%d", bond[i].a2);
  3566.       lblank (3L, tmpstr);
  3567.       strcat (wline, tmpstr);
  3568.       if (bond[i].btype == 'S')
  3569.         strcpy (tmpstr, "  1");
  3570.       if (bond[i].btype == 'D')
  3571.         strcpy (tmpstr, "  2");
  3572.       if (bond[i].btype == 'T')
  3573.         strcpy (tmpstr, "  3");
  3574.       if (bond[i].btype == 'A')
  3575.         strcpy (tmpstr, "  4");
  3576.       if (bond[i].btype == 'l')
  3577.         strcpy (tmpstr, "  5");
  3578.       if (bond[i].btype == 's')
  3579.         strcpy (tmpstr, "  6");
  3580.       if (bond[i].btype == 'd')
  3581.         strcpy (tmpstr, "  7");
  3582.       if (bond[i].btype == 'a')
  3583.         strcpy (tmpstr, "  8");
  3584.       /* now encode our own aromaticity information */
  3585.       if (bond[i].arom)
  3586.         tmpstr[1] = '0';
  3587.       strcat (wline, tmpstr);   /* next, encode bond stereo property (v0.3f) */
  3588.       /*if (bond^[i].stereo = bstereo_up) then wline := wline + '  1' else */
  3589.       /*  if (bond^[i].stereo = bstereo_down) then wline := wline + '  6' else */
  3590.       /*    wline := wline + '  0'; */
  3591.       /* restore original value from MDL molfile (v0.3n) */
  3592.       /* wline := wline + '  ' + inttostr(bond^[i].mdl_stereo);    REPLACE!!! */
  3593.       *tmpstr = '\0';
  3594.       sprintf (tmpstr, "%i", bond[i].mdl_stereo);
  3595.       strcat (wline, "  ");
  3596.       strcat (wline, tmpstr);
  3597.       *tmpstr = '\0';
  3598.       /* now encode the ring_count of this bond (using a field which officially is "not used") */
  3599.       /* tmpstr := inttostr(bond^[i].ring_count); REPLACE!!! */
  3600.       sprintf (tmpstr, "%i", bond[i].ring_count);
  3601.       while (strlen (tmpstr) < 3)
  3602.         sprintf (tmpstr, " %s", strcpy (STR1, tmpstr));
  3603.       sprintf (wline + strlen (wline), "%s  0  0", tmpstr);
  3604.       puts (wline);
  3605.     }
  3606.   FORLIM = n_atoms;
  3607.   for (i = 1; i <= FORLIM; i++)
  3608.     {
  3609.       a_chg = atom[i - 1].formal_charge;
  3610.       if (a_chg != 0)
  3611.         {
  3612.           strcpy (wline, "M  CHG  1 ");
  3613.           sprintf (tmpstr, "%d", i);
  3614.           lblank (3L, tmpstr);
  3615.           sprintf (wline + strlen (wline), "%s ", tmpstr);
  3616.           sprintf (tmpstr, "%d", a_chg);
  3617.           lblank (3L, tmpstr);
  3618.           strcat (wline, tmpstr);
  3619.           puts (wline);
  3620.         }
  3621.     }
  3622.   for (i = 1; i <= FORLIM; i++) /* 0.3x */
  3623.     {
  3624.       a_iso = atom[i - 1].nucleon_number;
  3625.       if (a_iso != 0)
  3626.         {
  3627.           strcpy (wline, "M  ISO  1 ");
  3628.           sprintf (tmpstr, "%d", i);
  3629.           lblank (3L, tmpstr);
  3630.           sprintf (wline + strlen (wline), "%s ", tmpstr);
  3631.           sprintf (tmpstr, "%d", a_iso);
  3632.           lblank (3L, tmpstr);
  3633.           strcat (wline, tmpstr);
  3634.           puts (wline);
  3635.         }
  3636.     }
  3637.   for (i = 1; i <= FORLIM; i++) /* 0.3x */
  3638.     {
  3639.       a_rad = atom[i - 1].radical_type;
  3640.       if (a_rad != 0)
  3641.         {
  3642.           strcpy (wline, "M  RAD  1 ");
  3643.           sprintf (tmpstr, "%d", i);
  3644.           lblank (3L, tmpstr);
  3645.           sprintf (wline + strlen (wline), "%s ", tmpstr);
  3646.           sprintf (tmpstr, "%d", a_rad);
  3647.           lblank (3L, tmpstr);
  3648.           strcat (wline, tmpstr);
  3649.           puts (wline);
  3650.         }
  3651.     }
  3652.   printf ("M  END\n");
  3653. }
  3654.  
  3655.  
  3656. /*============= chemical processing functions && procedures ============ */
  3657.  
  3658. static boolean
  3659. is_electroneg (a_el)
  3660.      char *a_el;
  3661. {
  3662.   /* new in v0.3j */
  3663.   boolean res = false;
  3664.  
  3665.   if (!strcmp (a_el, "N "))
  3666.     res = true;
  3667.   if (!strcmp (a_el, "P "))
  3668.     res = true;
  3669.   if (!strcmp (a_el, "O "))
  3670.     res = true;
  3671.   if (!strcmp (a_el, "S "))
  3672.     res = true;
  3673.   if (!strcmp (a_el, "SE"))
  3674.     res = true;
  3675.   if (!strcmp (a_el, "TE"))
  3676.     res = true;
  3677.   if (!strcmp (a_el, "F "))
  3678.     res = true;
  3679.   if (!strcmp (a_el, "CL"))
  3680.     res = true;
  3681.   if (!strcmp (a_el, "BR"))
  3682.     res = true;
  3683.   if (!strcmp (a_el, "I "))
  3684.     res = true;
  3685.   if (!strcmp (a_el, "AT"))
  3686.     res = true;
  3687.   return res;
  3688. }
  3689.  
  3690.  
  3691. static void
  3692. count_neighbors ()
  3693. {
  3694.   /* counts heavy-atom neighbors and explicit hydrogens */
  3695.   int i, FORLIM;
  3696.  
  3697.   if (n_atoms < 1 || n_bonds < 1)
  3698.     return;
  3699.   FORLIM = n_bonds;
  3700.   for (i = 0; i < FORLIM; i++)
  3701.     {
  3702.       if (atom[bond[i].a1 - 1].heavy)
  3703.         atom[bond[i].a2 - 1].neighbor_count++;
  3704.       if (atom[bond[i].a2 - 1].heavy)
  3705.         atom[bond[i].a1 - 1].neighbor_count++;
  3706.       if (!strcmp (atom[bond[i].a1 - 1].element, "H "))
  3707.         atom[bond[i].a2 - 1].Hexp++;
  3708.       if (!strcmp (atom[bond[i].a2 - 1].element, "H "))
  3709.         atom[bond[i].a1 - 1].Hexp++;
  3710.       /* plausibility check (new in v02.i) */
  3711.       if (atom[bond[i].a1 - 1].neighbor_count > max_neighbors ||
  3712.           atom[bond[i].a2 - 1].neighbor_count > max_neighbors)
  3713.         {
  3714.           mol_OK = false;
  3715.           /*writeln('invalid molecule!'); */
  3716.         }
  3717.     }
  3718. }
  3719.  
  3720.  
  3721. static void
  3722. get_neighbors (Result, id)
  3723.      int *Result;
  3724.      int id;
  3725. {
  3726.   int i;
  3727.   //neighbor_rec nb_tmp;
  3728.   int nb_count = 0;
  3729.   //int FORLIM = n_bonds;
  3730.  
  3731.   //memset (Result, 0, sizeof (neighbor_rec));
  3732.  
  3733.   for (i = 0; i < n_bonds; i++)
  3734.     {
  3735.       if (bond[i].a1 == id && atom[bond[i].a2 - 1].heavy
  3736.           && nb_count < max_neighbors)
  3737.         {
  3738.           Result[nb_count++] = bond[i].a2;
  3739.         }
  3740.       if (bond[i].a2 == id && atom[bond[i].a1 - 1].heavy
  3741.           && nb_count < max_neighbors)
  3742.         {
  3743.           Result[nb_count++] = bond[i].a1;
  3744.         }
  3745.     }
  3746.   //return memcpy (Result, nb_tmp, sizeof (neighbor_rec));
  3747. }
  3748.  
  3749.  
  3750. static void
  3751. get_ndl_neighbors (int *Result, int id)
  3752. {
  3753.   int i;
  3754.   //neighbor_rec nb_tmp;
  3755.   int nb_count = 0;
  3756.   /* v0.3i: use max_neighbors instead of a fixed value of 8 */
  3757.   //int FORLIM = ndl_n_bonds;
  3758.  
  3759.   //memset (nb_tmp, 0, sizeof (neighbor_rec));
  3760.  
  3761.   for (i = 0; i < ndl_n_bonds; i++)
  3762.     {
  3763.       if (ndl_bond[i].a1 == id && nb_count < max_neighbors &&
  3764.           ndl_atom[ndl_bond[i].a2 - 1].heavy)
  3765.         {
  3766.           nb_count++;
  3767.           Result[nb_count - 1] = ndl_bond[i].a2;
  3768.         }
  3769.       if (ndl_bond[i].a2 == id && nb_count < max_neighbors &&
  3770.           ndl_atom[ndl_bond[i].a1 - 1].heavy)
  3771.         {
  3772.           nb_count++;
  3773.           Result[nb_count - 1] = ndl_bond[i].a1;
  3774.         }
  3775.     }
  3776.   //return memcpy (Result, nb_tmp, sizeof (neighbor_rec));
  3777. }
  3778.  
  3779.  
  3780. static int *
  3781. get_nextneighbors (int *Result, int id, int prev_id)
  3782. {
  3783.   int i;
  3784.   neighbor_rec nb_tmp;
  3785.   int nb_count = 0;
  3786.   int FORLIM;
  3787.  
  3788.   /* gets all neighbors except prev_id (usually the atom where we came from */
  3789.   memset (nb_tmp, 0, sizeof (neighbor_rec));
  3790.   FORLIM = n_bonds;
  3791.   for (i = 0; i < FORLIM; i++)
  3792.     {
  3793.       if (bond[i].a1 == id && bond[i].a2 != prev_id &&
  3794.           nb_count < max_neighbors && atom[bond[i].a2 - 1].heavy)
  3795.         {
  3796.           nb_count++;
  3797.           nb_tmp[nb_count - 1] = bond[i].a2;
  3798.         }
  3799.       if (bond[i].a2 == id && bond[i].a1 != prev_id &&
  3800.           nb_count < max_neighbors && atom[bond[i].a1 - 1].heavy)
  3801.         {
  3802.           nb_count++;
  3803.           nb_tmp[nb_count - 1] = bond[i].a1;
  3804.         }
  3805.     }
  3806.   return memcpy (Result, nb_tmp, sizeof (neighbor_rec));
  3807. }
  3808.  
  3809.  
  3810. static int *
  3811. get_ndl_nextneighbors (int *Result, int id, int prev_id)
  3812. {
  3813.   int i;
  3814.   neighbor_rec nb_tmp;
  3815.   int nb_count = 0;
  3816.   int FORLIM;
  3817.  
  3818.   /* gets all neighbors except prev_id (usually the atom where we came from */
  3819.   memset (nb_tmp, 0, sizeof (neighbor_rec));
  3820.   FORLIM = ndl_n_bonds;
  3821.   for (i = 0; i < FORLIM; i++)
  3822.     {
  3823.       if (ndl_bond[i].a1 == id && ndl_bond[i].a2 != prev_id &&
  3824.           nb_count < max_neighbors && ndl_atom[ndl_bond[i].a2 - 1].heavy)
  3825.         {
  3826.           nb_count++;
  3827.           nb_tmp[nb_count - 1] = ndl_bond[i].a2;
  3828.         }
  3829.       if (ndl_bond[i].a2 == id && ndl_bond[i].a1 != prev_id &&
  3830.           nb_count < max_neighbors && ndl_atom[ndl_bond[i].a1 - 1].heavy)
  3831.         {
  3832.           nb_count++;
  3833.           nb_tmp[nb_count - 1] = ndl_bond[i].a1;
  3834.         }
  3835.     }
  3836.   return memcpy (Result, nb_tmp, sizeof (neighbor_rec));
  3837. }
  3838.  
  3839. #if 0
  3840. static int path_pos (id, a_path) int id;
  3841.      int *a_path;
  3842.      {
  3843.      /* new version in v0.3l */
  3844.      int i;
  3845.      int pp = 0;
  3846.  
  3847.      for (i = 1; i <= max_ringsize; i++)
  3848.      {
  3849.      if (a_path[i - 1] == id)
  3850.      {
  3851.      pp = i;
  3852.      /* p2c: checkmol.pas, line 2620:
  3853.      * Warning: Expected a '(', found a semicolon [227]  */
  3854.      /* p2c: checkmol.pas, line 2620:
  3855.      * Warning: Expected an expression, found a semicolon [227] */
  3856.      fflush (0);
  3857.      P_ioresult = 0;
  3858.      }
  3859.      }
  3860.      return pp;
  3861.      }
  3862. #endif
  3863.  
  3864. static int
  3865. matchpath_pos (int id, int *a_path)
  3866. {
  3867.   int i;
  3868.   int pp = 0;
  3869.  
  3870.   for (i = max_matchpath_length; i >= 1; i--)
  3871.     {
  3872.       if (a_path[i - 1] == id)
  3873.         pp = i;
  3874.     }
  3875.   return pp;
  3876. }
  3877.  
  3878.  
  3879. static int
  3880. matchpath_length (int *a_path)
  3881. {
  3882.   if (a_path[max_matchpath_length - 1] != 0)
  3883.     return max_matchpath_length;
  3884.   else
  3885.     return (matchpath_pos (0L, a_path) - 1);
  3886. }
  3887.  
  3888. static int
  3889. get_ndl_bond (int ba1, int ba2)
  3890. {
  3891.   int i;
  3892.   int b_id = 0;
  3893.   int FORLIM;
  3894.  
  3895.   if (ndl_n_bonds <= 0)
  3896.     return b_id;
  3897.   FORLIM = ndl_n_bonds;
  3898.   for (i = 1; i <= FORLIM; i++)
  3899.     {
  3900.       if ((ndl_bond[i - 1].a1 == ba1 && ndl_bond[i - 1].a2 == ba2) ||
  3901.           (ndl_bond[i - 1].a1 == ba2 && ndl_bond[i - 1].a2 == ba1))
  3902.         b_id = i;
  3903.     }
  3904.   return b_id;
  3905. }
  3906.  
  3907. static int
  3908. ringcompare (int *rp1, int *rp2)
  3909. {
  3910.   int i, j;
  3911.   int rc = 0;
  3912.   int rs1, rs2;
  3913.   int n_common = 0;
  3914.   int max_cra;
  3915.  
  3916.   rs1 = path_length (rp1);
  3917.   rs2 = path_length (rp2);
  3918.   if (rs1 < rs2)
  3919.     max_cra = rs1;
  3920.   else
  3921.     max_cra = rs2;
  3922.   for (i = 0; i < rs1; i++)
  3923.     {
  3924.       for (j = 0; j < rs2; j++)
  3925.         {
  3926.           if (rp1[i] == rp2[j])
  3927.             n_common++;
  3928.         }
  3929.     }
  3930.   if (rs1 == rs2 && n_common == max_cra)
  3931.     {
  3932.       rc = 0;
  3933.       return rc;
  3934.     }
  3935.   if (n_common == 0)
  3936.     rc += 8;
  3937.   if (n_common < max_cra)
  3938.     {
  3939.       rc += 4;
  3940.       return rc;
  3941.     }
  3942.   if (rs1 < rs2)
  3943.     rc++;
  3944.   else
  3945.     rc += 2;
  3946.   return rc;
  3947. }
  3948.  
  3949.  
  3950. static boolean
  3951. rc_identical (int rc_int)
  3952. {
  3953.   if (rc_int == 0)
  3954.     return true;
  3955.   else
  3956.     return false;
  3957. }
  3958.  
  3959.  
  3960. static boolean
  3961. rc_1in2 (int rc_int)
  3962. {
  3963.   if (rc_int & 1)
  3964.     return true;
  3965.   else
  3966.     return false;
  3967. }
  3968.  
  3969.  
  3970. static boolean
  3971. rc_2in1 (int rc_int)
  3972. {
  3973.   rc_int /= 2;
  3974.   if (rc_int & 1)
  3975.     return true;
  3976.   else
  3977.     return false;
  3978. }
  3979.  
  3980.  
  3981. #if 0
  3982. static boolean
  3983. rc_different (int rc_int)
  3984. {
  3985.   rc_int /= 4;
  3986.   if (rc_int & 1)
  3987.     return true;
  3988.   else
  3989.     return false;
  3990. }
  3991. #endif
  3992. #if 0
  3993. static boolean
  3994. rc_independent (int rc_int)
  3995. {
  3996.   rc_int /= 8;
  3997.   if (rc_int & 1)
  3998.     return true;
  3999.   else
  4000.     return false;
  4001. }
  4002. #endif
  4003.  
  4004. static boolean
  4005. is_newring (int *n_path)
  4006. {
  4007.   int i, j;
  4008.   boolean nr = true;
  4009.   boolean same_ring;
  4010.   ringpath_type tmp_path;
  4011.   int rc_result;
  4012.   boolean found_ring;
  4013.   int pl;                       /* new in v0.3 */
  4014.   int FORLIM;
  4015.  
  4016.   pl = path_length (n_path);    /* new in v0.3 */
  4017.   if (n_rings <= 0)
  4018.     return true;
  4019.   switch (ringsearch_mode)
  4020.     {
  4021.  
  4022.     case rs_sar:
  4023.       found_ring = false;
  4024.       i = 0;
  4025.       while (i < n_rings && !found_ring)
  4026.         {
  4027.           i++;
  4028.           if (pl != ringprop[i - 1].size)       /* compare only rings of same size */
  4029.             continue;
  4030.           same_ring = true;
  4031.           for (j = 0; j < max_ringsize; j++)
  4032.             {
  4033.               if (ring[i - 1][j] != n_path[j])
  4034.                 same_ring = false;
  4035.             }
  4036.           if (same_ring)
  4037.             {
  4038.               nr = false;
  4039.               found_ring = true;
  4040.             }
  4041.         }
  4042.       break;
  4043.  
  4044.     case rs_ssr:
  4045.       FORLIM = n_rings;
  4046.       for (i = 0; i < FORLIM; i++)
  4047.         {
  4048.           for (j = 0; j < max_ringsize; j++)
  4049.             tmp_path[j] = ring[i][j];
  4050.           rc_result = ringcompare (n_path, tmp_path);
  4051.           if (rc_identical (rc_result))
  4052.             nr = false;
  4053.           if (rc_1in2 (rc_result))
  4054.             {
  4055.               /* exchange existing ring by smaller one */
  4056.               for (j = 0; j < max_ringsize; j++)
  4057.                 ring[i][j] = n_path[j];
  4058.               /* update ring property record (new in v0.3) */
  4059.               ringprop[i].size = pl;
  4060.               nr = false;
  4061. /* p2c: checkmol.pas, line 2841:
  4062.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4063.               /*$IFDEF debug */
  4064.               /* debugoutput('replacing ring '+inttostr(i)+' by smaller one (ringsize: '+inttostr(path_length(n_path))+')'); */
  4065.               /*$ENDIF */
  4066.             }
  4067.           if (rc_2in1 (rc_result))
  4068.             {
  4069.               /* new ring contains existing one, but is larger ==> discard */
  4070.               nr = false;
  4071.             }
  4072.         }
  4073.       break;
  4074.     }
  4075.   return nr;
  4076. }
  4077.  
  4078.  
  4079. static void
  4080. add_ring (int *n_path)
  4081. {
  4082.   /* new in v0.3: store rings in an ordered way (with ascending ring size) */
  4083.   int i;
  4084.   int j = 0;
  4085.   int k, s, pl;
  4086. /* p2c: checkmol.pas, line 2862:
  4087.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4088.   /*$IFDEF debug */
  4089.   /*char dstr[256];*/
  4090.   int FORLIM;
  4091.  
  4092.   /*$ENDIF */
  4093.   pl = path_length (n_path);
  4094.  
  4095.   if (pl < 1)
  4096.     return;
  4097.  
  4098.   if (n_rings >= max_rings)
  4099.     {
  4100.  
  4101. /* p2c: checkmol.pas, line 2906:
  4102.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4103.       /*$IFDEF debug
  4104.          debugoutput ("max_rings exceeded!");
  4105.          $ENDIF */
  4106.       return;
  4107.     }
  4108.   n_rings++;
  4109.  
  4110. /* p2c: checkmol.pas, line 2871:
  4111.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4112.   /*$IFDEF debug */
  4113.   /* dstr := '';
  4114.      for j := 1 to pl do dstr := dstr + inttostr((n_path[j])) + ' ';
  4115.      debugoutput('adding ring '+inttostr(n_rings)+':  '+dstr); */
  4116.   /*$ENDIF */
  4117.   if (n_rings > 1)
  4118.     {
  4119.       FORLIM = n_rings;
  4120.       for (i = 1; i < FORLIM; i++)
  4121.         {
  4122.           s = ringprop[i - 1].size;
  4123.           if (pl >= s)
  4124.             j = i;
  4125.         }
  4126.     }
  4127.   j++;                          /* the next position is ours */
  4128.   if (j < n_rings)
  4129.     {                           /* push up the remaining rings by one position */
  4130.       for (k = n_rings; k > j; k--)
  4131.         {
  4132.           ringprop[k - 1].size = ringprop[k - 2].size;
  4133.           /*ringprop^[k].arom := ringprop^[(k-1)].arom; */
  4134.           for (i = 0; i < max_ringsize; i++)
  4135.             ring[k - 1][i] = ring[k - 2][i];
  4136.         }
  4137.     }
  4138.   ringprop[j - 1].size = pl;
  4139.   for (i = 0; i < max_ringsize; i++)
  4140.     {
  4141.       ring[j - 1][i] = n_path[i];
  4142.       /*inc(atom^[(n_path[i])].ring_count); */
  4143.     }
  4144. }
  4145.  
  4146.  
  4147. #if 0
  4148.  static boolean is_ringpath (s_path) int *s_path;
  4149.      {
  4150.      boolean Result;
  4151.      int i, j;
  4152.      neighbor_rec nb;
  4153.      boolean rp = false;
  4154.      boolean new_atom;
  4155.      int a_last, pl;
  4156.      ringpath_type l_path;
  4157.      int FORLIM;
  4158.  
  4159.      /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  4160.      memset (nb, 0, sizeof (neighbor_rec));
  4161.      memset (l_path, 0, sizeof (ringpath_type));
  4162.      pl = path_length (s_path);
  4163.      if (pl < 1)
  4164.      {
  4165.      /* p2c: checkmol.pas, line 2928:
  4166.      * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4167.      /*$IFDEF debug
  4168.      debugoutput ("Oops! Got zero-length s_path!");
  4169.      $ENDIF */
  4170.      return Result;
  4171.      }
  4172.      for (i = 0; i < pl; i++)
  4173.      l_path[i] = s_path[i];
  4174.      /* check if the last atom is a metal and stop if opt_metalrings is not set (v0.3) */
  4175.      if (opt_metalrings == false)
  4176.      {
  4177.      if (atom[l_path[pl - 1] - 1].metal)
  4178.      {
  4179.      /* p2c: checkmol.pas, line 2942:
  4180.      * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4181.      /*$IFDEF debug
  4182.      debugoutput ("skipping metal in ring search");
  4183.      $ENDIF */
  4184.      return false;
  4185.      }
  4186.      }
  4187.      /* check if ring is already closed */
  4188.      if (pl > 2 && l_path[pl - 1] == l_path[0])
  4189.      {
  4190.      l_path[pl - 1] = 0;        /* remove last entry (redundant!) */
  4191.      order_ringpath (l_path);
  4192.      if (is_newring (l_path))
  4193.      {
  4194.      if (n_rings >= max_rings)
  4195.      {
  4196.      /* p2c: checkmol.pas, line 2958:
  4197.      * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4198.      /*$IFDEF debug
  4199.      debugoutput ("maximum number of rings exceeded!");
  4200.      $ENDIF */
  4201.      return false;
  4202.      }
  4203.      add_ring (l_path);
  4204.      }
  4205.      /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  4206.      return true;
  4207.      }
  4208.      /* any other case: ring is not (yet) closed */
  4209.      a_last = l_path[pl - 1];
  4210.      get_neighbors (nb, a_last);
  4211.      if (atom[a_last - 1].neighbor_count <= 1)
  4212.      return false;
  4213.      if (n_rings >= max_rings)
  4214.      /* added in v0.2: check if max_rings is reached **/
  4215.      {                          /* if ring is not closed, continue searching */
  4216.      return false;
  4217.      }
  4218.      FORLIM = atom[a_last - 1].neighbor_count;
  4219.      for (i = 0; i < FORLIM; i++)
  4220.      {
  4221.      new_atom = true;
  4222.      for (j = 1; j < pl; j++)
  4223.      {
  4224.      if (nb[i] == l_path[j])
  4225.      {                    /* v0.3k */
  4226.      new_atom = false;
  4227.      /* p2c: checkmol.pas, line 2982:
  4228.      * Warning: Expected a '(', found a semicolon [227] */
  4229.      /* p2c: checkmol.pas, line 2982:
  4230.      * Warning: Expected an expression, found a semicolon [227] */
  4231.      fflush (0);
  4232.      P_ioresult = 0;      /* v0.3k */
  4233.      }
  4234.      }
  4235.      /* added in v0.1a: check if max_rings not yet reached */
  4236.      /* added in v0.2:  limit ring size to max_vringsize instead of max_ringsize */
  4237.      if (new_atom && pl < max_vringsize && n_rings < max_rings)
  4238.      {
  4239.      l_path[pl] = nb[i];
  4240.      if (pl < max_ringsize - 1)   /* just to be sure */
  4241.      l_path[pl + 1] = 0;
  4242.      if (is_ringpath (l_path))
  4243.      rp = true;
  4244.      }
  4245.      }
  4246.      return rp;
  4247.      }
  4248. #endif
  4249.  
  4250. static boolean
  4251. is_ringpath (int *s_path)
  4252. {
  4253.   int i, j;
  4254.   neighbor_rec nb;
  4255.   boolean rp = false;
  4256.   boolean new_atom;
  4257.   int a_last, pl;
  4258.   ringpath_type l_path;
  4259.   int FORLIM, pl_prev, pl_next, max_ringsize_dec;
  4260.  
  4261. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  4262.   memset ((void *) nb, 0, sizeof (neighbor_rec));
  4263.   memset ((void *) l_path, 0, sizeof (ringpath_type));
  4264.   pl = path_length (s_path);
  4265.   if (pl < 1)
  4266.     {
  4267. /* p2c: checkmol.pas, line 2524:
  4268.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4269.  
  4270.       return false;
  4271.     }
  4272.  
  4273.   pl_prev = pl - 1;
  4274.   //memcpy (l_path, s_path, sizeof (ringpath_type));
  4275.   memcpy (l_path, s_path, pl * sizeof (int));
  4276.  
  4277.   /* check if the last atom is a metal and stop if opt_metalrings is not set (v0.3) */
  4278.   if (opt_metalrings == false)
  4279.     {
  4280.       if (atom[l_path[pl_prev] - 1].metal)
  4281.         {
  4282. /* p2c: checkmol.pas, line 2538:
  4283.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4284.           return false;
  4285.         }
  4286.     }
  4287.   /* check if ring is already closed */
  4288.   if (pl > 2 && l_path[pl_prev] == l_path[0])
  4289.     {
  4290.       l_path[pl_prev] = 0;      /* remove last entry (redundant!) */
  4291.       order_ringpath (l_path);
  4292.       if (is_newring (l_path))
  4293.         {
  4294.           if (n_rings >= max_rings)
  4295.             {
  4296. /* p2c: checkmol.pas, line 2554:
  4297.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  4298.  
  4299.               return false;
  4300.             }
  4301.           add_ring (l_path);
  4302.         }
  4303. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  4304.       return true;
  4305.     }
  4306.   /* any other case: ring is not (yet) closed */
  4307.   a_last = l_path[pl_prev];
  4308.   get_neighbors (nb, a_last);
  4309.   if (atom[a_last - 1].neighbor_count <= 1)
  4310.     return false;
  4311.   if (n_rings >= max_rings)
  4312.     /* added in v0.2: check if max_rings is reached */
  4313.     {                           /* if ring is not closed, continue searching */
  4314.       return false;
  4315.     }
  4316.   FORLIM = atom[a_last - 1].neighbor_count;
  4317.   pl_next = pl + 1;
  4318.   max_ringsize_dec = max_ringsize - 1;
  4319.   for (i = 0; i < FORLIM; i++)
  4320.     {
  4321.       new_atom = true;
  4322.       for (j = 1; j < pl; j++)
  4323.         {
  4324.           if (nb[i] == l_path[j])
  4325.             {
  4326.               new_atom = false;
  4327.               break;
  4328.             }
  4329.         }
  4330.       /* added in v0.1a: check if max_rings not yet reached */
  4331.       /* added in v0.2:  limit ring size to max_vringsize instead of max_ringsize */
  4332.       if (new_atom && pl < max_vringsize && n_rings < max_rings)
  4333.         {
  4334.           l_path[pl] = nb[i];
  4335.           if (pl < max_ringsize_dec)    /* just to be sure */
  4336.             l_path[pl_next] = 0;
  4337.  
  4338.           if (max_ringpath_recursion_depth != 0
  4339.               && ++recursion_depth > max_ringpath_recursion_depth)
  4340.             {
  4341. #ifndef MAKE_SHARED_LIBRARY
  4342.               if (opt_verbose)
  4343. #endif
  4344.                 printf
  4345.                   ("Warning: max. number of ringpath recursions (%i) reached\n",
  4346.                    max_ringpath_recursion_depth);
  4347.               n_rings = max_rings;
  4348.               return false;
  4349.             }
  4350.  
  4351.           /*printf("%i\n",recursion_depth);
  4352.           fflush(stdout);*/
  4353.  
  4354.           if (is_ringpath (l_path))
  4355.             rp = true;
  4356.           /*return true;*/
  4357.         }
  4358.     }
  4359.   return rp;
  4360. }
  4361.  
  4362. static boolean
  4363. is_ringbond (int b_id)
  4364. {
  4365.   int i, ra1, ra2;
  4366.   neighbor_rec nb;
  4367.   ringpath_type search_path;
  4368.   boolean rb = false;
  4369.   int FORLIM;
  4370.  
  4371.   recursion_depth = 0;
  4372.  
  4373.   ra1 = bond[b_id - 1].a1;
  4374.   ra2 = bond[b_id - 1].a2;
  4375.   memset (nb, 0, sizeof (neighbor_rec));
  4376.   memset (search_path, 0, sizeof (ringpath_type));
  4377.   get_neighbors (nb, ra2);
  4378.   if (atom[ra2 - 1].neighbor_count <= 1 || atom[ra1 - 1].neighbor_count <= 1)
  4379.     return false;
  4380.   search_path[0] = ra1;
  4381.   search_path[1] = ra2;
  4382.   FORLIM = atom[ra2 - 1].neighbor_count;
  4383.   for (i = 0; i < FORLIM; i++)
  4384.     {
  4385.       if (nb[i] != ra1 && atom[nb[i] - 1].heavy)
  4386.         {
  4387.           search_path[2] = nb[i];
  4388.           if (is_ringpath (search_path))
  4389.             rb = true;
  4390.           //return true;
  4391.         }
  4392.     }
  4393.   return rb;
  4394. }
  4395.  
  4396.  
  4397. static void
  4398. chk_ringbonds ()
  4399. {
  4400.   int i, a1rc, a2rc;
  4401.  
  4402.   if (n_bonds < 1)
  4403.     return;
  4404.  
  4405.   for (i = 0; i < n_bonds; i++)
  4406.     {
  4407.       a1rc = atom[bond[i].a1 - 1].ring_count;
  4408.       a2rc = atom[bond[i].a2 - 1].ring_count;
  4409.       if (n_rings == 0 || (a1rc < n_rings && a2rc < n_rings))
  4410.         {
  4411.           is_ringbond (i + 1);
  4412.           /*inc(bond^[i].ring_count); */
  4413.         }
  4414.     }
  4415. }
  4416.  
  4417.  
  4418. /* v0.3d: moved procedure update_ringcount a bit down */
  4419.  
  4420.  
  4421. static int
  4422. raw_hetbond_count (int a)
  4423. {
  4424.   /* new in v0.2j, ignores bond order */
  4425.   int i;
  4426.   neighbor_rec nb;
  4427.   str2 nb_el;
  4428.   int hbc = 0;
  4429.   int FORLIM;
  4430.  
  4431.   if (a <= 0 || a > n_atoms)
  4432.     return hbc;
  4433.   memset (nb, 0, sizeof (neighbor_rec));
  4434.   get_neighbors (nb, a);
  4435.   if (atom[a - 1].neighbor_count <= 0)
  4436.     return hbc;
  4437.   FORLIM = atom[a - 1].neighbor_count;
  4438.   for (i = 0; i < FORLIM; i++)
  4439.     {
  4440.       strcpy (nb_el, atom[nb[i] - 1].element);
  4441.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "A ") && strcmp (nb_el, "H ")  /* &&  strcmp (nb_el, "D ") */
  4442.           && strcmp (nb_el, "LP") && strcmp (nb_el, "DU"))
  4443.         /* added 'D ' in v0.3n */
  4444.         hbc++;
  4445.     }
  4446.   return hbc;
  4447. }
  4448.  
  4449.  
  4450. static int
  4451. hetbond_count (int a)
  4452. {
  4453.   int i;
  4454.   neighbor_rec nb;
  4455.   str2 nb_el;
  4456.   float hbc = 0.0;
  4457.   int FORLIM;
  4458.  
  4459.   if (a <= 0 || a > n_atoms)
  4460.     return ((int) floor (hbc + 0.5));
  4461.   memset (nb, 0, sizeof (neighbor_rec));
  4462.   get_neighbors (nb, a);
  4463.   if (atom[a - 1].neighbor_count <= 0)
  4464.     return ((int) floor (hbc + 0.5));
  4465.   FORLIM = atom[a - 1].neighbor_count;
  4466.   for (i = 0; i < FORLIM; i++)
  4467.     {
  4468.       strcpy (nb_el, atom[nb[i] - 1].element);
  4469.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "A ") && strcmp (nb_el, "H ")  /*&& strcmp (nb_el, "D ") */
  4470.           && strcmp (nb_el, "LP") && strcmp (nb_el, "DU"))
  4471.         {                       /* added 'D ' in v0.3n */
  4472.           if (bond[get_bond (a, nb[i]) - 1].btype == 'S')
  4473.             hbc += 1.0;
  4474.           if (bond[get_bond (a, nb[i]) - 1].btype == 'A')
  4475.             hbc += 1.5;
  4476.           if (bond[get_bond (a, nb[i]) - 1].btype == 'D')
  4477.             hbc += 2.0;
  4478.           if (bond[get_bond (a, nb[i]) - 1].btype == 'T')
  4479.             hbc += 3.0;
  4480.         }
  4481.     }
  4482.   return ((int) floor (hbc + 0.5));
  4483. }
  4484.  
  4485.  
  4486. static int
  4487. hetatom_count (int a)
  4488. {
  4489.   int i;
  4490.   neighbor_rec nb;
  4491.   str2 nb_el;
  4492.   int hac = 0;
  4493.   int FORLIM;
  4494.  
  4495.   if (a <= 0 || a > n_atoms)
  4496.     return hac;
  4497.   memset (nb, 0, sizeof (neighbor_rec));
  4498.   get_neighbors (nb, a);
  4499.   if (atom[a - 1].neighbor_count <= 0)
  4500.     return hac;
  4501.   FORLIM = atom[a - 1].neighbor_count;
  4502.   for (i = 0; i < FORLIM; i++)
  4503.     {
  4504.       strcpy (nb_el, atom[nb[i] - 1].element);
  4505.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  4506.           /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "LP")
  4507.           && strcmp (nb_el, "DU"))
  4508.         /* added 'D ' in v0.3n */
  4509.         hac++;
  4510.     }
  4511.   return hac;
  4512. }
  4513.  
  4514. #if 0
  4515. static int
  4516. ndl_hetbond_count (int a)
  4517. {
  4518.   int i;
  4519.   neighbor_rec nb;
  4520.   str2 nb_el;
  4521.   float hbc = 0.0;
  4522.   int FORLIM;
  4523.  
  4524.   if (a <= 0 || a > n_atoms)
  4525.     return ((int) floor (hbc + 0.5));
  4526.   memset (nb, 0, sizeof (neighbor_rec));
  4527.   get_ndl_neighbors (nb, a);
  4528.   if (ndl_atom[a - 1].neighbor_count <= 0)
  4529.     return ((int) floor (hbc + 0.5));
  4530.   FORLIM = ndl_atom[a - 1].neighbor_count;
  4531.   for (i = 0; i < FORLIM; i++)
  4532.     {
  4533.       strcpy (nb_el, ndl_atom[nb[i] - 1].element);
  4534.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  4535.           /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "LP")
  4536.           && strcmp (nb_el, "DU"))
  4537.         {                       /* added 'D ' in v0.3n */
  4538.           if (ndl_bond[get_ndl_bond (a, nb[i]) - 1].btype == 'S')
  4539.             hbc += 1.0;
  4540.           if (ndl_bond[get_ndl_bond (a, nb[i]) - 1].btype == 'A')
  4541.             hbc += 1.5;
  4542.           if (ndl_bond[get_ndl_bond (a, nb[i]) - 1].btype == 'D')
  4543.             hbc += 2.0;
  4544.           if (ndl_bond[get_ndl_bond (a, nb[i]) - 1].btype == 'T')
  4545.             hbc += 3.0;
  4546.         }
  4547.     }
  4548.   return ((int) floor (hbc + 0.5));
  4549. }
  4550. #endif
  4551.  
  4552. static int
  4553. ndl_hetatom_count (int a)
  4554. {
  4555.   int i;
  4556.   neighbor_rec nb;
  4557.   str2 nb_el;
  4558.   int hac = 0;
  4559.   int FORLIM;
  4560.  
  4561.   if (a <= 0 || a > ndl_n_atoms)
  4562.     return hac;
  4563.   memset (nb, 0, sizeof (neighbor_rec));
  4564.   get_ndl_neighbors (nb, a);
  4565.   if (ndl_atom[a - 1].neighbor_count <= 0)
  4566.     return hac;
  4567.   FORLIM = ndl_atom[a - 1].neighbor_count;
  4568.   for (i = 0; i < FORLIM; i++)
  4569.     {                           /* note: query atoms like 'A' should be present only in the needle */
  4570.       strcpy (nb_el, ndl_atom[nb[i] - 1].element);
  4571.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "A ") && strcmp (nb_el, "H ")  /*&&  strcmp (nb_el, "D ") */
  4572.           && strcmp (nb_el, "LP") && strcmp (nb_el, "DU"))
  4573.         /* added 'D ' in v0.3n */
  4574.         hac++;
  4575.     }
  4576.   return hac;
  4577. }
  4578.  
  4579.  
  4580. static boolean
  4581. is_oxo_C (int id)
  4582. {
  4583.   int i;
  4584.   boolean r = false;
  4585.   neighbor_rec nb;
  4586.   int FORLIM;
  4587.  
  4588.   memset (nb, 0, sizeof (neighbor_rec));
  4589.   if (id < 1 || id > n_atoms)
  4590.     return false;
  4591.   get_neighbors (nb, id);
  4592.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4593.     return false;
  4594.   FORLIM = atom[id - 1].neighbor_count;
  4595.   for (i = 0; i < FORLIM; i++)
  4596.     {
  4597.       if (bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  4598.           !strcmp (atom[nb[i] - 1].element, "O "))
  4599.         /* no N, amidines are different... */
  4600.         r = true;
  4601.       /* or
  4602.          (atom^[(nb[i])].element = 'S ')  or
  4603.          (atom^[(nb[i])].element = 'SE') */
  4604.     }
  4605.   return r;
  4606. }
  4607.  
  4608.  
  4609. static boolean
  4610. is_thioxo_C (int id)
  4611. {
  4612.   int i;
  4613.   boolean r = false;
  4614.   neighbor_rec nb;
  4615.   int FORLIM;
  4616.  
  4617.   memset (nb, 0, sizeof (neighbor_rec));
  4618.   if (id < 1 || id > n_atoms)
  4619.     return false;
  4620.   get_neighbors (nb, id);
  4621.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4622.     return false;
  4623.   FORLIM = atom[id - 1].neighbor_count;
  4624.   for (i = 0; i < FORLIM; i++)
  4625.     {
  4626.       if (bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  4627.           (!strcmp (atom[nb[i] - 1].element, "S ") ||
  4628.            !strcmp (atom[nb[i] - 1].element, "SE")))
  4629.         /* no N, amidines are different... */
  4630.         r = true;
  4631.     }
  4632.   return r;
  4633. }
  4634.  
  4635.  
  4636. static boolean
  4637. is_imino_C (int id)
  4638. {
  4639.   int i;
  4640.   boolean r = false;
  4641.   neighbor_rec nb;
  4642.   int FORLIM;
  4643.  
  4644.   memset (nb, 0, sizeof (neighbor_rec));
  4645.   if (id < 1 || id > n_atoms)
  4646.     return false;
  4647.   get_neighbors (nb, id);
  4648.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4649.     return false;
  4650.   FORLIM = atom[id - 1].neighbor_count;
  4651.   for (i = 0; i < FORLIM; i++)
  4652.     {
  4653.       if (bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  4654.           !strcmp (atom[nb[i] - 1].element, "N "))
  4655.         r = true;
  4656.     }
  4657.   return r;
  4658. }
  4659.  
  4660.  
  4661. static boolean
  4662. is_true_imino_C (int id)
  4663. {
  4664.   int i;
  4665.   boolean r = true;
  4666.   neighbor_rec nb;
  4667.   str2 nb_el;
  4668.   int a_n = 0;
  4669.   int b;                        /* v0.3j */
  4670.   int FORLIM;
  4671.  
  4672. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  4673.   memset (nb, 0, sizeof (neighbor_rec));
  4674.   if (id < 1 || id > n_atoms)
  4675.     return false;
  4676.   get_neighbors (nb, id);
  4677.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4678.     return false;
  4679.   FORLIM = atom[id - 1].neighbor_count;
  4680.   for (i = 0; i < FORLIM; i++)
  4681.     {
  4682.       b = get_bond (id, nb[i]); /* v0.3j */
  4683.       if (bond[b - 1].btype == 'D' && bond[b - 1].arom == false &&
  4684.           !strcmp (atom[nb[i] - 1].element, "N "))
  4685.         /* v0.3j */
  4686.         a_n = nb[i];
  4687.     }
  4688.   if (a_n <= 0)
  4689.     return false;
  4690.   memset (nb, 0, sizeof (neighbor_rec));
  4691.   get_neighbors (nb, a_n);
  4692.   FORLIM = atom[a_n - 1].neighbor_count;
  4693.   for (i = 0; i < FORLIM; i++)
  4694.     {
  4695.       strcpy (nb_el, atom[nb[i] - 1].element);
  4696.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  4697.           /*&&  strcmp (nb_el, "D ") */ )
  4698.         /* v0.3n: D */
  4699.         r = false;
  4700.     }
  4701.   return r;
  4702. }
  4703.  
  4704.  
  4705. static boolean
  4706. is_true_exocyclic_imino_C (int id, int r_id)
  4707. {
  4708.   /* v0.3j */
  4709.   int i, j;
  4710.   boolean r = false;
  4711.   neighbor_rec nb;
  4712.   ringpath_type testring;
  4713.   int ring_size, b, FORLIM;
  4714.  
  4715.   memset (nb, 0, sizeof (neighbor_rec));
  4716.   if (id < 1 || id > n_atoms)
  4717.     return false;
  4718.   get_neighbors (nb, id);
  4719.   memset (testring, 0, sizeof (ringpath_type));
  4720.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  4721.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  4722.     testring[j] = ring[r_id - 1][j];
  4723.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4724.     return false;
  4725.   FORLIM = atom[id - 1].neighbor_count;
  4726.   for (i = 0; i < FORLIM; i++)
  4727.     {
  4728.       b = get_bond (id, nb[i]);
  4729.       if (bond[b - 1].btype == 'D' && bond[b - 1].arom == false &&
  4730.           !strcmp (atom[nb[i] - 1].element, "N "))
  4731.         {
  4732.           r = true;
  4733.           for (j = 0; j < ring_size; j++)
  4734.             {
  4735.               if (nb[i] == ring[r_id - 1][j])
  4736.                 r = false;
  4737.             }
  4738.         }
  4739.     }
  4740.   return r;
  4741. }
  4742.  
  4743.  
  4744. static boolean
  4745. is_exocyclic_imino_C (int id, int r_id)
  4746. {
  4747.   int i, j;
  4748.   boolean r = false;
  4749.   neighbor_rec nb;
  4750.   ringpath_type testring;
  4751.   int ring_size, FORLIM;
  4752.  
  4753.   memset (nb, 0, sizeof (neighbor_rec));
  4754.   if (id < 1 || id > n_atoms)
  4755.     return false;
  4756.   get_neighbors (nb, id);
  4757.   memset (testring, 0, sizeof (ringpath_type));
  4758.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  4759.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  4760.     testring[j] = ring[r_id - 1][j];
  4761.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4762.     return false;
  4763.   FORLIM = atom[id - 1].neighbor_count;
  4764.   for (i = 0; i < FORLIM; i++)
  4765.     {
  4766.       if (bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  4767.           !strcmp (atom[nb[i] - 1].element, "N "))
  4768.         {
  4769.           r = true;
  4770.           for (j = 0; j < ring_size; j++)
  4771.             {
  4772.               if (nb[i] == ring[r_id - 1][j])
  4773.                 r = false;
  4774.             }
  4775.         }
  4776.     }
  4777.   return r;
  4778. }
  4779.  
  4780.  
  4781. static int
  4782. find_exocyclic_methylene_C (int id, int r_id)
  4783. {
  4784.   /* renamed and rewritten in v0.3j */
  4785.   int i, j;
  4786.   int r = 0;
  4787.   neighbor_rec nb;
  4788.   ringpath_type testring;
  4789.   int ring_size, FORLIM;
  4790.  
  4791.   memset (nb, 0, sizeof (neighbor_rec));
  4792.   if (id < 1 || id > n_atoms)
  4793.     return 0;
  4794.   get_neighbors (nb, id);
  4795.   memset (testring, 0, sizeof (ringpath_type));
  4796.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  4797.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  4798.     testring[j] = ring[r_id - 1][j];
  4799.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  4800.     return r;
  4801.   FORLIM = atom[id - 1].neighbor_count;
  4802.   for (i = 0; i < FORLIM; i++)
  4803.     {
  4804.       if (bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  4805.           !strcmp (atom[nb[i] - 1].element, "C "))
  4806.         {
  4807.           r = nb[i];
  4808.           for (j = 0; j < ring_size; j++)
  4809.             {
  4810.               if (nb[i] == ring[r_id - 1][j])
  4811.                 r = 0;
  4812.             }
  4813.         }
  4814.     }
  4815.   return r;
  4816. }
  4817.  
  4818.  
  4819. static boolean
  4820. is_hydroxy (int a_view, int a_ref)
  4821. {
  4822.   boolean r = false;
  4823.  
  4824.   if (atom[a_view - 1].
  4825.       heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4826.     {
  4827.       if (!strcmp (atom[a_ref - 1].atype, "O3 ") &&
  4828.           atom[a_ref - 1].neighbor_count == 1)
  4829.         r = true;
  4830.     }
  4831.   return r;
  4832. }
  4833.  
  4834.  
  4835. static boolean
  4836. is_sulfanyl (int a_view, int a_ref)
  4837. {
  4838.   boolean r = false;
  4839.  
  4840.   if (atom[a_view - 1].
  4841.       heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4842.     {
  4843.       if (!strcmp (atom[a_ref - 1].atype, "S3 ") &&
  4844.           atom[a_ref - 1].neighbor_count == 1)
  4845.         r = true;
  4846.     }
  4847.   return r;
  4848. }
  4849.  
  4850.  
  4851. static boolean
  4852. is_amino (int a_view, int a_ref)
  4853. {
  4854.   boolean r = false;
  4855.  
  4856.   if (atom[a_view - 1].
  4857.       heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4858.     {
  4859.       if ((!strcmp (atom[a_ref - 1].atype, "N3 ") ||
  4860.            !strcmp (atom[a_ref - 1].atype, "N3+")) &&
  4861.           atom[a_ref - 1].neighbor_count == 1)
  4862.         r = true;
  4863.     }
  4864.   return r;
  4865. }
  4866.  
  4867.  
  4868. static boolean
  4869. is_alkyl (int a_view, int a_ref)
  4870. {
  4871.   int i;
  4872.   boolean r = false;
  4873.   neighbor_rec nb;
  4874.   str2 nb_el;
  4875.   int het_count = 0;
  4876.   int FORLIM;
  4877.  
  4878.   memset (nb, 0, sizeof (neighbor_rec));
  4879.   if (!
  4880.       (atom[a_view - 1].
  4881.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4882.       || strcmp (atom[a_ref - 1].atype, "C3 ")
  4883.       || atom[a_ref - 1].arom != false)
  4884.     return false;
  4885.   get_nextneighbors (nb, a_ref, a_view);
  4886.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  4887.   for (i = 0; i <= FORLIM; i++)
  4888.     {
  4889.       strcpy (nb_el, atom[nb[i] - 1].element);
  4890.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  4891.           /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU")
  4892.           && strcmp (nb_el, "LP"))
  4893.         /* added 'D ' in v0.3n */
  4894.         het_count++;
  4895.     }
  4896.   if (het_count <= 1)           /* we consider (e.g.) alkoxyalkyl groups as alkyl */
  4897.     r = true;
  4898.   return r;
  4899. }
  4900.  
  4901.  
  4902. static boolean
  4903. is_true_alkyl (int a_view, int a_ref)
  4904. {
  4905.   int i;
  4906.   boolean r = false;
  4907.   neighbor_rec nb;
  4908.   str2 nb_el;
  4909.   int het_count = 0;
  4910.   int FORLIM;
  4911.  
  4912.   memset (nb, 0, sizeof (neighbor_rec));
  4913.   if (!
  4914.       (atom[a_view - 1].
  4915.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4916.       || strcmp (atom[a_ref - 1].atype, "C3 ")
  4917.       || atom[a_ref - 1].arom != false)
  4918.     return false;
  4919.   get_nextneighbors (nb, a_ref, a_view);
  4920.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  4921.   for (i = 0; i <= FORLIM; i++)
  4922.     {
  4923.       strcpy (nb_el, atom[nb[i] - 1].element);
  4924.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  4925.           /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU"))
  4926.         /* added 'D ' in v0.3n */
  4927.         het_count++;
  4928.     }
  4929.   if (het_count == 0)           /* */
  4930.     r = true;
  4931.   return r;
  4932. }
  4933.  
  4934.  
  4935. static boolean
  4936. is_alkenyl (int a_view, int a_ref)
  4937. {
  4938.   /* new in v0.3j */
  4939.   int i;
  4940.   boolean r = false;
  4941.   neighbor_rec nb;
  4942.   str2 nb_el;
  4943.   str3 nb_at;
  4944.   int c2_count = 0, het_count = 0;
  4945.   int FORLIM;
  4946.  
  4947.   memset (nb, 0, sizeof (neighbor_rec));
  4948.   if (!
  4949.       (atom[a_view - 1].
  4950.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4951.       || strcmp (atom[a_ref - 1].atype, "C2 ")
  4952.       || atom[a_ref - 1].arom != false)
  4953.     {
  4954.       return false;
  4955.     }                           /* v0.3k: changed c2_count = 1 into c2_count >= 1 */
  4956.   get_nextneighbors (nb, a_ref, a_view);
  4957.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  4958.   for (i = 0; i <= FORLIM; i++)
  4959.     {
  4960.       strcpy (nb_el, atom[nb[i] - 1].element);
  4961.       strcpy (nb_at, atom[nb[i] - 1].atype);
  4962.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  4963.           /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU")
  4964.           && strcmp (nb_el, "LP"))
  4965.         /* added 'D ' in v0.3n */
  4966.         het_count++;
  4967.       if (!strcmp (nb_at, "C2 "))
  4968.         c2_count++;
  4969.     }
  4970.   if (c2_count >= 1 && het_count <= 1)
  4971.     /* we consider (e.g.) alkoxyalkenyl groups as alkenyl */
  4972.     r = true;
  4973.   return r;
  4974. }
  4975.  
  4976.  
  4977. static boolean
  4978. is_alkynyl (int a_view, int a_ref)
  4979. {
  4980.   /* new in v0.3j */
  4981.   int i;
  4982.   boolean r = false;
  4983.   neighbor_rec nb;
  4984.   str3 nb_at;
  4985.   int c1_count = 0;
  4986.   int FORLIM;
  4987.  
  4988.   memset (nb, 0, sizeof (neighbor_rec));
  4989.   if (!
  4990.       (atom[a_view - 1].
  4991.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  4992.       || strcmp (atom[a_ref - 1].atype, "C1 ")
  4993.       || atom[a_ref - 1].arom != false)
  4994.     return false;
  4995.   get_nextneighbors (nb, a_ref, a_view);
  4996.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  4997.   for (i = 0; i <= FORLIM; i++)
  4998.     {
  4999.       strcpy (nb_at, atom[nb[i] - 1].atype);
  5000.       if (!strcmp (nb_at, "C1 "))
  5001.         c1_count++;
  5002.     }
  5003.   if (c1_count == 1)
  5004.     r = true;
  5005.   return r;
  5006. }
  5007.  
  5008.  
  5009. static boolean
  5010. is_aryl (int a_view, int a_ref)
  5011. {
  5012.   boolean r = false;
  5013.  
  5014.   if ((atom[a_view - 1].
  5015.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S'))
  5016.       && !strcmp (atom[a_ref - 1].element, "C ")
  5017.       && atom[a_ref - 1].arom == true)
  5018.     r = true;
  5019.   return r;
  5020. }
  5021.  
  5022.  
  5023. static boolean
  5024. is_alkoxy (int a_view, int a_ref)
  5025. {
  5026.   boolean r = false;
  5027.   neighbor_rec nb;
  5028.  
  5029.   memset (nb, 0, sizeof (neighbor_rec));
  5030.   if (!
  5031.       (atom[a_view - 1].
  5032.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5033.     return false;
  5034.   if (strcmp (atom[a_ref - 1].atype, "O3 ")
  5035.       || atom[a_ref - 1].neighbor_count != 2)
  5036.     return false;
  5037.   get_nextneighbors (nb, a_ref, a_view);
  5038.   if (is_alkyl (a_ref, nb[0]))
  5039.     r = true;
  5040.   return r;
  5041. }
  5042.  
  5043.  
  5044. static boolean
  5045. is_siloxy (int a_view, int a_ref)
  5046. {
  5047.   boolean r = false;
  5048.   neighbor_rec nb;
  5049.  
  5050.   memset (nb, 0, sizeof (neighbor_rec));
  5051.   if (!
  5052.       (atom[a_view - 1].
  5053.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5054.     return false;
  5055.   if (strcmp (atom[a_ref - 1].atype, "O3 ")
  5056.       || atom[a_ref - 1].neighbor_count != 2)
  5057.     return false;
  5058.   get_nextneighbors (nb, a_ref, a_view);
  5059.   if (!strcmp (atom[nb[0] - 1].element, "SI"))
  5060.     r = true;
  5061.   return r;
  5062. }
  5063.  
  5064.  
  5065. static boolean
  5066. is_true_alkoxy (int a_view, int a_ref)
  5067. {
  5068.   boolean r = false;
  5069.   neighbor_rec nb;
  5070.  
  5071.   memset (nb, 0, sizeof (neighbor_rec));
  5072.   if (!
  5073.       (atom[a_view - 1].
  5074.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5075.     return false;
  5076.   if (strcmp (atom[a_ref - 1].atype, "O3 ")
  5077.       || atom[a_ref - 1].neighbor_count != 2)
  5078.     return false;
  5079.   get_nextneighbors (nb, a_ref, a_view);
  5080.   if (is_true_alkyl (a_ref, nb[0]))
  5081.     r = true;
  5082.   return r;
  5083. }
  5084.  
  5085.  
  5086. static boolean
  5087. is_aryloxy (int a_view, int a_ref)
  5088. {
  5089.   boolean r = false;
  5090.   neighbor_rec nb;
  5091.  
  5092.   memset (nb, 0, sizeof (neighbor_rec));
  5093.   if (!
  5094.       (atom[a_view - 1].
  5095.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5096.     return false;
  5097.   if (strcmp (atom[a_ref - 1].atype, "O3 ")
  5098.       || atom[a_ref - 1].neighbor_count != 2)
  5099.     return false;
  5100.   get_nextneighbors (nb, a_ref, a_view);
  5101.   if (is_aryl (a_ref, nb[0]))
  5102.     r = true;
  5103.   return r;
  5104. }
  5105.  
  5106.  
  5107. static boolean
  5108. is_alkenyloxy (int a_view, int a_ref)
  5109. {
  5110.   /* v0.3j */
  5111.   boolean r = false;
  5112.   neighbor_rec nb;
  5113.  
  5114.   memset (nb, 0, sizeof (neighbor_rec));
  5115.   if (!
  5116.       (atom[a_view - 1].
  5117.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5118.     return false;
  5119.   if (strcmp (atom[a_ref - 1].atype, "O3 ")
  5120.       || atom[a_ref - 1].neighbor_count != 2)
  5121.     return false;
  5122.   get_nextneighbors (nb, a_ref, a_view);
  5123.   if (is_alkenyl (a_ref, nb[0]))
  5124.     r = true;
  5125.   return r;
  5126. }
  5127.  
  5128.  
  5129. static boolean
  5130. is_alkynyloxy (int a_view, int a_ref)
  5131. {
  5132.   /* v0.3j */
  5133.   boolean r = false;
  5134.   neighbor_rec nb;
  5135.  
  5136.   memset (nb, 0, sizeof (neighbor_rec));
  5137.   if (!
  5138.       (atom[a_view - 1].
  5139.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5140.     return false;
  5141.   if (strcmp (atom[a_ref - 1].atype, "O3 ")
  5142.       || atom[a_ref - 1].neighbor_count != 2)
  5143.     return false;
  5144.   get_nextneighbors (nb, a_ref, a_view);
  5145.   if (is_alkynyl (a_ref, nb[0]))
  5146.     r = true;
  5147.   return r;
  5148. }
  5149.  
  5150.  
  5151. static boolean
  5152. is_alkylsulfanyl (int a_view, int a_ref)
  5153. {
  5154.   boolean r = false;
  5155.   neighbor_rec nb;
  5156.  
  5157.   memset (nb, 0, sizeof (neighbor_rec));
  5158.   if (!
  5159.       (atom[a_view - 1].
  5160.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5161.     return false;
  5162.   if (strcmp (atom[a_ref - 1].atype, "S3 ")
  5163.       || atom[a_ref - 1].neighbor_count != 2)
  5164.     return false;
  5165.   get_nextneighbors (nb, a_ref, a_view);
  5166.   if (is_alkyl (a_ref, nb[0]))
  5167.     r = true;
  5168.   return r;
  5169. }
  5170.  
  5171.  
  5172. static boolean
  5173. is_true_alkylsulfanyl (int a_view, int a_ref)
  5174. {
  5175.   boolean r = false;
  5176.   neighbor_rec nb;
  5177.  
  5178.   memset (nb, 0, sizeof (neighbor_rec));
  5179.   if (!
  5180.       (atom[a_view - 1].
  5181.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5182.     return false;
  5183.   if (strcmp (atom[a_ref - 1].atype, "S3 ")
  5184.       || atom[a_ref - 1].neighbor_count != 2)
  5185.     return false;
  5186.   get_nextneighbors (nb, a_ref, a_view);
  5187.   if (is_true_alkyl (a_ref, nb[0]))
  5188.     r = true;
  5189.   return r;
  5190. }
  5191.  
  5192.  
  5193. static boolean
  5194. is_arylsulfanyl (int a_view, int a_ref)
  5195. {
  5196.   boolean r = false;
  5197.   neighbor_rec nb;
  5198.  
  5199.   memset (nb, 0, sizeof (neighbor_rec));
  5200.   if (!
  5201.       (atom[a_view - 1].
  5202.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5203.     return false;
  5204.   if (strcmp (atom[a_ref - 1].atype, "S3 ")
  5205.       || atom[a_ref - 1].neighbor_count != 2)
  5206.     return false;
  5207.   get_nextneighbors (nb, a_ref, a_view);
  5208.   if (is_aryl (a_ref, nb[0]))
  5209.     r = true;
  5210.   return r;
  5211. }
  5212.  
  5213.  
  5214. static boolean
  5215. is_alkenylsulfanyl (a_view, a_ref)
  5216.      int a_view, a_ref;
  5217. {
  5218.   /* v0.3j */
  5219.   boolean r = false;
  5220.   neighbor_rec nb;
  5221.  
  5222.   memset (nb, 0, sizeof (neighbor_rec));
  5223.   if (!
  5224.       (atom[a_view - 1].
  5225.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5226.     return false;
  5227.   if (strcmp (atom[a_ref - 1].atype, "S3 ")
  5228.       || atom[a_ref - 1].neighbor_count != 2)
  5229.     return false;
  5230.   get_nextneighbors (nb, a_ref, a_view);
  5231.   if (is_alkenyl (a_ref, nb[0]))
  5232.     r = true;
  5233.   return r;
  5234. }
  5235.  
  5236.  
  5237. static boolean
  5238. is_alkynylsulfanyl (a_view, a_ref)
  5239.      int a_view, a_ref;
  5240. {
  5241.   /* v0.3j */
  5242.   boolean r = false;
  5243.   neighbor_rec nb;
  5244.  
  5245.   memset (nb, 0, sizeof (neighbor_rec));
  5246.   if (!
  5247.       (atom[a_view - 1].
  5248.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5249.     return false;
  5250.   if (strcmp (atom[a_ref - 1].atype, "S3 ")
  5251.       || atom[a_ref - 1].neighbor_count != 2)
  5252.     return false;
  5253.   get_nextneighbors (nb, a_ref, a_view);
  5254.   if (is_alkynyl (a_ref, nb[0]))
  5255.     r = true;
  5256.   return r;
  5257. }
  5258.  
  5259.  
  5260. static boolean
  5261. is_alkylamino (a_view, a_ref)
  5262.      int a_view, a_ref;
  5263. {
  5264.   boolean r = false;
  5265.   neighbor_rec nb;
  5266.   int alkyl_count = 0;
  5267.  
  5268.   memset (nb, 0, sizeof (neighbor_rec));
  5269.   if (!
  5270.       (atom[a_view - 1].
  5271.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5272.     return false;
  5273.   if (strcmp (atom[a_ref - 1].element, "N ")
  5274.       || atom[a_ref - 1].neighbor_count != 2)
  5275.     return false;
  5276.   get_nextneighbors (nb, a_ref, a_view);
  5277.   if (is_alkyl (a_ref, nb[0]))
  5278.     alkyl_count++;
  5279.   if (alkyl_count == 1)
  5280.     r = true;
  5281.   return r;
  5282. }
  5283.  
  5284.  
  5285. static boolean
  5286. is_dialkylamino (a_view, a_ref)
  5287.      int a_view, a_ref;
  5288. {
  5289.   int i;
  5290.   boolean r = false;
  5291.   neighbor_rec nb;
  5292.   int alkyl_count = 0;
  5293.  
  5294.   memset (nb, 0, sizeof (neighbor_rec));
  5295.   if (!
  5296.       (atom[a_view - 1].
  5297.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5298.     return false;
  5299.   if (strcmp (atom[a_ref - 1].element, "N ")
  5300.       || atom[a_ref - 1].neighbor_count != 3)
  5301.     return false;
  5302.   get_nextneighbors (nb, a_ref, a_view);
  5303.   for (i = 0; i <= 1; i++)
  5304.     {
  5305.       if (is_alkyl (a_ref, nb[i]))
  5306.         alkyl_count++;
  5307.     }
  5308.   if (alkyl_count == 2)
  5309.     r = true;
  5310.   return r;
  5311. }
  5312.  
  5313.  
  5314. static boolean
  5315. is_arylamino (a_view, a_ref)
  5316.      int a_view, a_ref;
  5317. {
  5318.   boolean r = false;
  5319.   neighbor_rec nb;
  5320.   int aryl_count = 0;
  5321.  
  5322.   memset (nb, 0, sizeof (neighbor_rec));
  5323.   if (!
  5324.       (atom[a_view - 1].
  5325.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5326.     return false;
  5327.   if (strcmp (atom[a_ref - 1].element, "N ")
  5328.       || atom[a_ref - 1].neighbor_count != 2)
  5329.     return false;
  5330.   get_nextneighbors (nb, a_ref, a_view);
  5331.   if (is_aryl (a_ref, nb[0]))
  5332.     aryl_count++;
  5333.   if (aryl_count == 1)
  5334.     r = true;
  5335.   return r;
  5336. }
  5337.  
  5338.  
  5339. static boolean
  5340. is_diarylamino (a_view, a_ref)
  5341.      int a_view, a_ref;
  5342. {
  5343.   int i;
  5344.   boolean r = false;
  5345.   neighbor_rec nb;
  5346.   int aryl_count = 0;
  5347.  
  5348.   memset (nb, 0, sizeof (neighbor_rec));
  5349.   if (!
  5350.       (atom[a_view - 1].
  5351.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5352.     return false;
  5353.   if (strcmp (atom[a_ref - 1].element, "N ")
  5354.       || atom[a_ref - 1].neighbor_count != 3)
  5355.     return false;
  5356.   get_nextneighbors (nb, a_ref, a_view);
  5357.   for (i = 0; i <= 1; i++)
  5358.     {
  5359.       if (is_aryl (a_ref, nb[i]))
  5360.         aryl_count++;
  5361.     }
  5362.   if (aryl_count == 2)
  5363.     r = true;
  5364.   return r;
  5365. }
  5366.  
  5367.  
  5368. static boolean
  5369. is_alkylarylamino (a_view, a_ref)
  5370.      int a_view, a_ref;
  5371. {
  5372.   int i;
  5373.   boolean r = false;
  5374.   neighbor_rec nb;
  5375.   int alkyl_count = 0, aryl_count = 0;
  5376.  
  5377.   memset (nb, 0, sizeof (neighbor_rec));
  5378.   if (!
  5379.       (atom[a_view - 1].
  5380.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5381.     return false;
  5382.   if (strcmp (atom[a_ref - 1].element, "N ")
  5383.       || atom[a_ref - 1].neighbor_count != 3)
  5384.     return false;
  5385.   get_nextneighbors (nb, a_ref, a_view);
  5386.   for (i = 0; i <= 1; i++)
  5387.     {
  5388.       if (is_alkyl (a_ref, nb[i]))
  5389.         alkyl_count++;
  5390.       if (is_aryl (a_ref, nb[i]))
  5391.         aryl_count++;
  5392.     }
  5393.   if (alkyl_count == 1 && aryl_count == 1)
  5394.     r = true;
  5395.   return r;
  5396. }
  5397.  
  5398.  
  5399. static boolean
  5400. is_C_monosubst_amino (a_view, a_ref)
  5401.      int a_view, a_ref;
  5402. {
  5403.   /* new in v0.3j */
  5404.   boolean r = false;
  5405.   neighbor_rec nb;
  5406.   int c_count = 0;
  5407.  
  5408.   memset (nb, 0, sizeof (neighbor_rec));
  5409.   if (!
  5410.       (atom[a_view - 1].
  5411.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5412.     return false;
  5413.   if ((strcmp (atom[a_ref - 1].atype, "N3 ")
  5414.       && strcmp (atom[a_ref - 1].atype, "NAM"))
  5415.       || atom[a_ref - 1].neighbor_count != 2)
  5416.     return false;
  5417.   get_nextneighbors (nb, a_ref, a_view);
  5418.   if (!strcmp (atom[nb[0] - 1].element, "C "))
  5419.     c_count++;
  5420.   if (c_count == 1)
  5421.     r = true;
  5422.   return r;
  5423. }
  5424.  
  5425.  
  5426. static boolean
  5427. is_C_disubst_amino (a_view, a_ref)
  5428.      int a_view, a_ref;
  5429. {
  5430.   /* new in v0.3j */
  5431.   int i;
  5432.   boolean r = false;
  5433.   neighbor_rec nb;
  5434.   int b;
  5435.   int c_count = 0;
  5436.  
  5437.   b = get_bond (a_view, a_ref);
  5438.   memset (nb, 0, sizeof (neighbor_rec));
  5439.   if (!(atom[a_view - 1].heavy && bond[b - 1].btype == 'S' &&
  5440.         bond[b - 1].arom == false))
  5441.     return false;
  5442.   if ((strcmp (atom[a_ref - 1].atype, "N3 ")
  5443.       && strcmp (atom[a_ref - 1].atype, "NAM"))
  5444.       || atom[a_ref - 1].neighbor_count != 3)
  5445.     return false;
  5446.   get_nextneighbors (nb, a_ref, a_view);
  5447.   for (i = 0; i <= 1; i++)
  5448.     {
  5449.       if (!strcmp (atom[nb[i] - 1].element, "C "))
  5450.         c_count++;
  5451.     }
  5452.   if (c_count == 2)
  5453.     r = true;
  5454.   return r;
  5455. }
  5456.  
  5457.  
  5458. static boolean
  5459. is_subst_amino (a_view, a_ref)
  5460.      int a_view, a_ref;
  5461. {
  5462.   boolean r = false;
  5463.  
  5464.   if (is_amino (a_view, a_ref) || is_alkylamino (a_view, a_ref) |
  5465.       is_arylamino (a_view, a_ref) || is_dialkylamino (a_view, a_ref) |
  5466.       is_alkylarylamino (a_view, a_ref) || is_diarylamino (a_view, a_ref))
  5467.     r = true;
  5468.   return r;
  5469. }
  5470.  
  5471.  
  5472. static boolean
  5473. is_true_alkylamino (a_view, a_ref)
  5474.      int a_view, a_ref;
  5475. {
  5476.   boolean r = false;
  5477.   neighbor_rec nb;
  5478.   int alkyl_count = 0;
  5479.  
  5480.   memset (nb, 0, sizeof (neighbor_rec));
  5481.   if (!
  5482.       (atom[a_view - 1].
  5483.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5484.     return false;
  5485.   if ((strcmp (atom[a_ref - 1].atype, "N3 ")
  5486.       && strcmp (atom[a_ref - 1].atype, "N3+"))
  5487.       || atom[a_ref - 1].neighbor_count != 2)
  5488.     return false;
  5489.   get_nextneighbors (nb, a_ref, a_view);
  5490.   if (is_true_alkyl (a_ref, nb[0]))
  5491.     alkyl_count++;
  5492.   if (alkyl_count == 1)
  5493.     r = true;
  5494.   return r;
  5495. }
  5496.  
  5497.  
  5498. static boolean
  5499. is_true_dialkylamino (a_view, a_ref)
  5500.      int a_view, a_ref;
  5501. {
  5502.   int i;
  5503.   boolean r = false;
  5504.   neighbor_rec nb;
  5505.   int alkyl_count = 0;
  5506.  
  5507.   memset (nb, 0, sizeof (neighbor_rec));
  5508.   if (!
  5509.       (atom[a_view - 1].
  5510.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5511.     return false;
  5512.   if ((strcmp (atom[a_ref - 1].atype, "N3 ")
  5513.       && strcmp (atom[a_ref - 1].atype, "N3+"))
  5514.       || atom[a_ref - 1].neighbor_count != 3)
  5515.     return false;
  5516.   get_nextneighbors (nb, a_ref, a_view);
  5517.   for (i = 0; i <= 1; i++)
  5518.     {
  5519.       if (is_true_alkyl (a_ref, nb[i]))
  5520.         alkyl_count++;
  5521.     }
  5522.   if (alkyl_count == 2)
  5523.     r = true;
  5524.   return r;
  5525. }
  5526.  
  5527. #if 0
  5528. static boolean
  5529. is_true_alkylarylamino (a_view, a_ref)
  5530.      int a_view, a_ref;
  5531. {
  5532.   int i;
  5533.   boolean r = false;
  5534.   neighbor_rec nb;
  5535.   int alkyl_count = 0, aryl_count = 0;
  5536.  
  5537.   memset (nb, 0, sizeof (neighbor_rec));
  5538.   if (!
  5539.       (atom[a_view - 1].
  5540.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5541.     return false;
  5542.   if ((strcmp (atom[a_ref - 1].atype, "N3 ")
  5543.       && strcmp (atom[a_ref - 1].atype, "N3+"))
  5544.       || atom[a_ref - 1].neighbor_count != 3)
  5545.     return false;
  5546.   get_nextneighbors (nb, a_ref, a_view);
  5547.   for (i = 0; i <= 1; i++)
  5548.     {
  5549.       if (is_true_alkyl (a_ref, nb[i]))
  5550.         alkyl_count++;
  5551.       if (is_aryl (a_ref, nb[i]))
  5552.         aryl_count++;
  5553.     }
  5554.   if (alkyl_count == 1 && aryl_count == 1)
  5555.     r = true;
  5556.   return r;
  5557. }
  5558. #endif
  5559.  
  5560. static boolean
  5561. is_hydroxylamino (a_view, a_ref)
  5562.      int a_view, a_ref;
  5563. {
  5564.   int i;
  5565.   boolean r = false;
  5566.   neighbor_rec nb;
  5567.   int oh_count = 0, het_count = 0;      /* v0.3k */
  5568.   str2 nb_el;                   /* v0.3k */
  5569.   int FORLIM;
  5570.  
  5571.   memset (nb, 0, sizeof (neighbor_rec));
  5572.   if (!
  5573.       (atom[a_view - 1].
  5574.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5575.     return false;
  5576.   if (strcmp (atom[a_ref - 1].element, "N ")
  5577.       || atom[a_ref - 1].neighbor_count < 2)
  5578.     /* v0.3c */
  5579.     return false;
  5580.   get_nextneighbors (nb, a_ref, a_view);
  5581.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  5582.   for (i = 0; i <= FORLIM; i++)
  5583.     {                           /* v0.3c */
  5584.       if (is_hydroxy (a_ref, nb[i]))
  5585.         oh_count++;
  5586.       strcpy (nb_el, atom[nb[i] - 1].element);  /* v0.3k */
  5587.       if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  5588.           /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU")
  5589.           && strcmp (nb_el, "LP"))
  5590.         /* v0.3k */
  5591.         het_count++;
  5592.       /* v0.3n: D */
  5593.     }
  5594.   if (oh_count == 1 && het_count == 1)
  5595.     r = true;
  5596.   return r;
  5597. }
  5598.  
  5599.  
  5600. static boolean
  5601. is_nitro (a_view, a_ref)
  5602.      int a_view, a_ref;
  5603. {
  5604.   int i;
  5605.   boolean r = false;
  5606.   neighbor_rec nb;
  5607.   int o_count = 0, bond_count = 0;
  5608.  
  5609.   memset (nb, 0, sizeof (neighbor_rec));
  5610.   if (!
  5611.       (atom[a_view - 1].
  5612.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5613.     return false;
  5614.   if (strcmp (atom[a_ref - 1].element, "N ")
  5615.       || atom[a_ref - 1].neighbor_count != 3)
  5616.     return false;
  5617.   get_nextneighbors (nb, a_ref, a_view);
  5618.   for (i = 0; i <= 1; i++)
  5619.     {
  5620.       if (!strcmp (atom[nb[i] - 1].element, "O "))
  5621.         o_count++;
  5622.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  5623.         bond_count++;
  5624.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'D')
  5625.         bond_count += 2;
  5626.     }
  5627.   if (o_count == 2 && bond_count >= 3)
  5628.     r = true;
  5629.   return r;
  5630. }
  5631.  
  5632.  
  5633. static boolean
  5634. is_azido (a_view, a_ref)
  5635.      int a_view, a_ref;
  5636. {
  5637.   boolean r = false;
  5638.   neighbor_rec nb;
  5639.   int bond_count = 0, n1 = 0, n2 = 0, n3 = 0;
  5640.  
  5641.   if (!
  5642.       (atom[a_view - 1].
  5643.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5644.     return false;
  5645.   if (strcmp (atom[a_ref - 1].element, "N ")
  5646.       || atom[a_ref - 1].neighbor_count != 2)
  5647.     return false;
  5648.   n1 = a_ref;
  5649.   memset (nb, 0, sizeof (neighbor_rec));
  5650.   get_nextneighbors (nb, n1, a_view);
  5651.   if (!strcmp (atom[nb[0] - 1].element, "N "))
  5652.     {
  5653.       n2 = nb[0];
  5654.       if (bond[get_bond (n1, n2) - 1].btype == 'S')
  5655.         bond_count++;
  5656.       if (bond[get_bond (n1, n2) - 1].btype == 'D')
  5657.         bond_count += 2;
  5658.       if (bond[get_bond (n1, n2) - 1].btype == 'T')
  5659.         bond_count += 3;
  5660.     }
  5661.   if (n2 > 0 && atom[n2 - 1].neighbor_count == 2)
  5662.     {
  5663.       memset (nb, 0, sizeof (neighbor_rec));
  5664.       get_nextneighbors (nb, n2, n1);
  5665.       if (!strcmp (atom[nb[0] - 1].element, "N "))
  5666.         {
  5667.           n3 = nb[0];
  5668.           if (bond[get_bond (n2, n3) - 1].btype == 'S')
  5669.             bond_count++;
  5670.           if (bond[get_bond (n2, n3) - 1].btype == 'D')
  5671.             bond_count += 2;
  5672.           if (bond[get_bond (n2, n3) - 1].btype == 'T')
  5673.             bond_count += 3;
  5674.         }
  5675.     }
  5676.   if (n1 > 0 && n2 > 0 && n3 > 0 && atom[n3 - 1].neighbor_count == 1 &&
  5677.       bond_count > 3)
  5678.     r = true;
  5679.   return r;
  5680. }
  5681.  
  5682.  
  5683. static boolean
  5684. is_diazonium (a_view, a_ref)
  5685.      int a_view, a_ref;
  5686. {
  5687.   boolean r = false;
  5688.   neighbor_rec nb;
  5689.   int bond_count = 0, chg_count = 0, n1 = 0, n2 = 0;
  5690.  
  5691.   if (!
  5692.       (atom[a_view - 1].
  5693.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5694.     return false;
  5695.   if (strcmp (atom[a_ref - 1].element, "N ")
  5696.       || atom[a_ref - 1].neighbor_count != 2)
  5697.     return false;
  5698.   n1 = a_ref;
  5699.   chg_count = atom[n1 - 1].formal_charge;
  5700.   memset (nb, 0, sizeof (neighbor_rec));
  5701.   get_nextneighbors (nb, n1, a_view);
  5702.   if (!strcmp (atom[nb[0] - 1].element, "N "))
  5703.     {
  5704.       n2 = nb[0];
  5705.       chg_count += atom[n2 - 1].formal_charge;
  5706.       if (bond[get_bond (n1, n2) - 1].btype == 'S')
  5707.         bond_count++;
  5708.       if (bond[get_bond (n1, n2) - 1].btype == 'D')
  5709.         bond_count += 2;
  5710.       if (bond[get_bond (n1, n2) - 1].btype == 'T')
  5711.         bond_count += 3;
  5712.     }
  5713.   if (n1 > 0 && n2 > 0 && atom[n2 - 1].neighbor_count == 1
  5714.       && bond_count >= 2 && chg_count > 0)
  5715.     r = true;
  5716.   return r;
  5717. }
  5718.  
  5719.  
  5720. static boolean
  5721. is_hydroximino_C (id)
  5722.      int id;
  5723. {
  5724.   int i;
  5725.   boolean r = false;
  5726.   neighbor_rec nb;
  5727.   int a_het = 0;
  5728.   int FORLIM;
  5729.  
  5730.   memset (nb, 0, sizeof (neighbor_rec));
  5731.   if (id < 1 || id > n_atoms)
  5732.     return false;
  5733.   get_neighbors (nb, id);
  5734.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  5735.     return false;
  5736.   FORLIM = atom[id - 1].neighbor_count;
  5737.   for (i = 0; i < FORLIM; i++)
  5738.     {
  5739.       if ((bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  5740.            !strcmp (atom[nb[i] - 1].element,
  5741.                     "N ")) && (hetbond_count (nb[i]) == 3))
  5742.         a_het = nb[i];
  5743.     }
  5744.   if (a_het <= 0)
  5745.     return false;
  5746.   memset (nb, 0, sizeof (neighbor_rec));
  5747.   get_neighbors (nb, a_het);
  5748.   if (strcmp (atom[a_het - 1].element, "N ")
  5749.       || atom[a_het - 1].neighbor_count <= 0)
  5750.     return false;
  5751.   FORLIM = atom[a_het - 1].neighbor_count;
  5752.   for (i = 0; i < FORLIM; i++)
  5753.     {
  5754.       if (is_hydroxy (a_het, nb[i]))
  5755.         r = true;
  5756.     }
  5757.   return r;
  5758. }
  5759.  
  5760.  
  5761. static boolean
  5762. is_hydrazono_C (id)
  5763.      int id;
  5764. {
  5765.   int i;
  5766.   boolean r = false;
  5767.   neighbor_rec nb;
  5768.   int a_het = 0;
  5769.   int FORLIM;
  5770.  
  5771.   memset (nb, 0, sizeof (neighbor_rec));
  5772.   if (id < 1 || id > n_atoms)
  5773.     return false;
  5774.   get_neighbors (nb, id);
  5775.   if (strcmp (atom[id - 1].element, "C ") || atom[id - 1].neighbor_count <= 0)
  5776.     return false;
  5777.   FORLIM = atom[id - 1].neighbor_count;
  5778.   for (i = 0; i < FORLIM; i++)
  5779.     {
  5780.       if (bond[get_bond (id, nb[i]) - 1].btype == 'D' &&
  5781.           !strcmp (atom[nb[i] - 1].element, "N "))
  5782.         {
  5783.           /* and
  5784.              (hetbond_count(nb[i]) = 3)  */
  5785.           a_het = nb[i];
  5786.         }
  5787.     }
  5788.   if (a_het <= 0)
  5789.     return false;
  5790.   memset (nb, 0, sizeof (neighbor_rec));
  5791.   get_neighbors (nb, a_het);
  5792.   if (strcmp (atom[a_het - 1].element, "N ")
  5793.       || atom[a_het - 1].neighbor_count <= 0)
  5794.     return false;
  5795.   FORLIM = atom[a_het - 1].neighbor_count;
  5796.   for (i = 0; i < FORLIM; i++)
  5797.     {
  5798.       if (is_amino (a_het, nb[i]) || is_alkylamino (a_het, nb[i]) |
  5799.           is_alkylarylamino (a_het, nb[i]) || is_arylamino (a_het, nb[i]) |
  5800.           is_dialkylamino (a_het, nb[i]) || is_diarylamino (a_het, nb[i]))
  5801.         r = true;
  5802.     }
  5803.   return r;
  5804. }
  5805.  
  5806.  
  5807. static boolean
  5808. is_alkoxycarbonyl (a_view, a_ref)
  5809.      int a_view, a_ref;
  5810. {
  5811.   int i;
  5812.   boolean r = false;
  5813.   neighbor_rec nb;
  5814.  
  5815.   memset (nb, 0, sizeof (neighbor_rec));
  5816.   if (!
  5817.       (atom[a_view - 1].
  5818.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5819.     return false;
  5820.   if (!(is_oxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5821.     return false;
  5822.   get_nextneighbors (nb, a_ref, a_view);
  5823.   for (i = 0; i <= 1; i++)
  5824.     {
  5825.       if (is_alkoxy (a_ref, nb[i]))
  5826.         r = true;
  5827.     }
  5828.   return r;
  5829. }
  5830.  
  5831.  
  5832. static boolean
  5833. is_aryloxycarbonyl (a_view, a_ref)
  5834.      int a_view, a_ref;
  5835. {
  5836.   int i;
  5837.   boolean r = false;
  5838.   neighbor_rec nb;
  5839.  
  5840.   memset (nb, 0, sizeof (neighbor_rec));
  5841.   if (!
  5842.       (atom[a_view - 1].
  5843.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5844.     return false;
  5845.   if (!(is_oxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5846.     return false;
  5847.   get_nextneighbors (nb, a_ref, a_view);
  5848.   for (i = 0; i <= 1; i++)
  5849.     {
  5850.       if (is_aryloxy (a_ref, nb[i]))
  5851.         r = true;
  5852.     }
  5853.   return r;
  5854. }
  5855.  
  5856.  
  5857. static boolean
  5858. is_carbamoyl (a_view, a_ref)
  5859.      int a_view, a_ref;
  5860. {
  5861.   int i;
  5862.   boolean r = false;
  5863.   neighbor_rec nb;
  5864.  
  5865.   memset (nb, 0, sizeof (neighbor_rec));
  5866.   if (!
  5867.       (atom[a_view - 1].
  5868.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5869.     return false;
  5870.   if (!(is_oxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5871.     return false;
  5872.   get_nextneighbors (nb, a_ref, a_view);
  5873.   for (i = 0; i <= 1; i++)
  5874.     {
  5875.       if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  5876.           !strcmp (atom[nb[i] - 1].atype, "NAM"))
  5877.         r = true;
  5878.     }
  5879.   return r;
  5880. }
  5881.  
  5882.  
  5883. static boolean
  5884. is_alkoxythiocarbonyl (a_view, a_ref)
  5885.      int a_view, a_ref;
  5886. {
  5887.   int i;
  5888.   boolean r = false;
  5889.   neighbor_rec nb;
  5890.  
  5891.   memset (nb, 0, sizeof (neighbor_rec));
  5892.   if (!
  5893.       (atom[a_view - 1].
  5894.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5895.     return false;
  5896.   if (!(is_thioxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5897.     return false;
  5898.   get_nextneighbors (nb, a_ref, a_view);
  5899.   for (i = 0; i <= 1; i++)
  5900.     {
  5901.       if (is_alkoxy (a_ref, nb[i]))
  5902.         r = true;
  5903.     }
  5904.   return r;
  5905. }
  5906.  
  5907.  
  5908. static boolean
  5909. is_aryloxythiocarbonyl (a_view, a_ref)
  5910.      int a_view, a_ref;
  5911. {
  5912.   int i;
  5913.   boolean r = false;
  5914.   neighbor_rec nb;
  5915.  
  5916.   memset (nb, 0, sizeof (neighbor_rec));
  5917.   if (!
  5918.       (atom[a_view - 1].
  5919.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5920.     return false;
  5921.   if (!(is_thioxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5922.     return false;
  5923.   get_nextneighbors (nb, a_ref, a_view);
  5924.   for (i = 0; i <= 1; i++)
  5925.     {
  5926.       if (is_aryloxy (a_ref, nb[i]))
  5927.         r = true;
  5928.     }
  5929.   return r;
  5930. }
  5931.  
  5932.  
  5933. static boolean
  5934. is_thiocarbamoyl (a_view, a_ref)
  5935.      int a_view, a_ref;
  5936. {
  5937.   int i;
  5938.   boolean r = false;
  5939.   neighbor_rec nb;
  5940.  
  5941.   memset (nb, 0, sizeof (neighbor_rec));
  5942.   if (!
  5943.       (atom[a_view - 1].
  5944.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5945.     return false;
  5946.   if (!(is_thioxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5947.     return false;
  5948.   get_nextneighbors (nb, a_ref, a_view);
  5949.   for (i = 0; i <= 1; i++)
  5950.     {
  5951.       if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  5952.           !strcmp (atom[nb[i] - 1].atype, "NAM"))
  5953.         r = true;
  5954.     }
  5955.   return r;
  5956. }
  5957.  
  5958.  
  5959. static boolean
  5960. is_alkanoyl (a_view, a_ref)
  5961.      int a_view, a_ref;
  5962. {
  5963.   int i;
  5964.   boolean r = false;
  5965.   neighbor_rec nb;
  5966.  
  5967.   memset (nb, 0, sizeof (neighbor_rec));
  5968.   if (!
  5969.       (atom[a_view - 1].
  5970.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5971.     return false;
  5972.   if (!(is_oxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5973.     return false;
  5974.   get_nextneighbors (nb, a_ref, a_view);
  5975.   for (i = 0; i <= 1; i++)
  5976.     {
  5977.       if (is_alkyl (a_ref, nb[i]))
  5978.         r = true;
  5979.     }
  5980.   return r;
  5981. }
  5982.  
  5983.  
  5984. static boolean
  5985. is_aroyl (a_view, a_ref)
  5986.      int a_view, a_ref;
  5987. {
  5988.   int i;
  5989.   boolean r = false;
  5990.   neighbor_rec nb;
  5991.  
  5992.   memset (nb, 0, sizeof (neighbor_rec));
  5993.   if (!
  5994.       (atom[a_view - 1].
  5995.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  5996.     return false;
  5997.   if (!(is_oxo_C (a_ref) && atom[a_ref - 1].neighbor_count == 3))
  5998.     return false;
  5999.   get_nextneighbors (nb, a_ref, a_view);
  6000.   for (i = 0; i <= 1; i++)
  6001.     {
  6002.       if (is_aryl (a_ref, nb[i]))
  6003.         r = true;
  6004.     }
  6005.   return r;
  6006. }
  6007.  
  6008.  
  6009. static boolean
  6010. is_acyl (a_view, a_ref)
  6011.      int a_view, a_ref;
  6012. {
  6013.   boolean r = false;
  6014.  
  6015.   if (is_alkanoyl (a_view, a_ref) || is_aroyl (a_view, a_ref))
  6016.     r = true;
  6017.   return r;
  6018. }
  6019.  
  6020.  
  6021. static boolean
  6022. is_acyl_gen (a_view, a_ref)
  6023.      int a_view, a_ref;
  6024. {
  6025.   /* new in v0.3j */
  6026.   boolean r = false;
  6027.  
  6028.   if (is_oxo_C (a_ref))
  6029.     r = true;
  6030.   return r;
  6031. }
  6032.  
  6033.  
  6034. static boolean
  6035. is_acylamino (a_view, a_ref)
  6036.      int a_view, a_ref;
  6037. {
  6038.   boolean r = false;
  6039.   neighbor_rec nb;
  6040.   int acyl_count = 0;
  6041.  
  6042.   memset (nb, 0, sizeof (neighbor_rec));
  6043.   if (!
  6044.       (atom[a_view - 1].
  6045.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  6046.     return false;
  6047.   if (strcmp (atom[a_ref - 1].element, "N ")
  6048.       || atom[a_ref - 1].neighbor_count != 2)
  6049.     return false;
  6050.   get_nextneighbors (nb, a_ref, a_view);
  6051.   if (is_acyl (a_ref, nb[0]))
  6052.     acyl_count++;
  6053.   if (acyl_count == 1)
  6054.     r = true;
  6055.   return r;
  6056. }
  6057.  
  6058.  
  6059. static boolean
  6060. is_subst_acylamino (a_view, a_ref)
  6061.      int a_view, a_ref;
  6062. {
  6063.   /* may be substituted _or_ unsubstituted acylamino group! */
  6064.   int i;
  6065.   boolean r = false;
  6066.   neighbor_rec nb;
  6067.   int acyl_count = 0;
  6068.   int FORLIM;
  6069.  
  6070.   memset (nb, 0, sizeof (neighbor_rec));
  6071.   if (!
  6072.       (atom[a_view - 1].
  6073.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  6074.     return false;
  6075.   if (strcmp (atom[a_ref - 1].element, "N ")
  6076.       || atom[a_ref - 1].neighbor_count < 2)
  6077.     return false;
  6078.   get_nextneighbors (nb, a_ref, a_view);
  6079.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  6080.   for (i = 0; i <= FORLIM; i++)
  6081.     {
  6082.       if (is_acyl_gen (a_ref, nb[i]))   /* v0.3j */
  6083.         acyl_count++;
  6084.     }
  6085.   if (acyl_count > 0)
  6086.     r = true;
  6087.   return r;
  6088. }
  6089.  
  6090.  
  6091. static boolean
  6092. is_hydrazino (a_view, a_ref)
  6093.      int a_view, a_ref;
  6094. {
  6095.   int i;
  6096.   boolean r = false;
  6097.   neighbor_rec nb;
  6098.   int nr_count = 0;
  6099.   int FORLIM;
  6100.  
  6101.   memset (nb, 0, sizeof (neighbor_rec));
  6102.   if (!
  6103.       (atom[a_view - 1].
  6104.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  6105.     return false;
  6106.   if (strcmp (atom[a_ref - 1].element, "N ")
  6107.       || atom[a_ref - 1].neighbor_count < 2)
  6108.     return false;
  6109.   get_nextneighbors (nb, a_ref, a_view);
  6110.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  6111.   for (i = 0; i <= FORLIM; i++)
  6112.     {                           /* fixed in v0.3c */
  6113.       if (is_amino (a_ref, nb[i]) || is_subst_amino (a_ref, nb[i]))
  6114.         nr_count++;
  6115.     }
  6116.   if (nr_count == 1)
  6117.     r = true;
  6118.   return r;
  6119. }
  6120.  
  6121.  
  6122. static boolean
  6123. is_nitroso (a_view, a_ref)
  6124.      int a_view, a_ref;
  6125. {
  6126.   /* new in v0.3j */
  6127.   boolean r = false;
  6128.   neighbor_rec nb;
  6129.   int o_count = 0;
  6130.   int a2;
  6131.  
  6132.   memset (nb, 0, sizeof (neighbor_rec));
  6133.   if (!
  6134.       (atom[a_view - 1].
  6135.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  6136.     return false;
  6137.   if (strcmp (atom[a_ref - 1].element, "N ")
  6138.       || atom[a_ref - 1].neighbor_count != 2)
  6139.     return false;
  6140.   get_nextneighbors (nb, a_ref, a_view);
  6141.   a2 = nb[0];
  6142.   if ((strcmp (atom[a2 - 1].element, "O ") == 0) &
  6143.       (bond[get_bond (a_ref, a2) - 1].btype == 'D'))
  6144.     o_count++;
  6145.   if (o_count == 1)
  6146.     r = true;
  6147.   return r;
  6148. }
  6149.  
  6150.  
  6151. static boolean
  6152. is_subst_hydrazino (a_view, a_ref)
  6153.      int a_view, a_ref;
  6154. {
  6155.   int i;
  6156.   boolean r = false;
  6157.   neighbor_rec nb;
  6158.   int nr_count = 0;
  6159.   int a2, FORLIM;
  6160.  
  6161.   memset (nb, 0, sizeof (neighbor_rec));
  6162.   if (!
  6163.       (atom[a_view - 1].
  6164.        heavy && (bond[get_bond (a_view, a_ref) - 1].btype == 'S')))
  6165.     return false;
  6166.   if (strcmp (atom[a_ref - 1].element, "N ")
  6167.       || atom[a_ref - 1].neighbor_count < 2)
  6168.     return false;
  6169.   get_nextneighbors (nb, a_ref, a_view);
  6170.   FORLIM = atom[a_ref - 1].neighbor_count - 2;
  6171.   for (i = 0; i <= FORLIM; i++)
  6172.     {
  6173.       a2 = nb[i];
  6174.       if ((strcmp (atom[a2 - 1].element, "N ") ==
  6175.            0) && (!is_nitroso (a_ref, a2)))
  6176.         /* v0.3j */
  6177.         nr_count++;
  6178.     }
  6179.   if (nr_count == 1)
  6180.     r = true;
  6181.   return r;
  6182. }
  6183.  
  6184.  
  6185. static boolean
  6186. is_cyano (a_view, a_ref)
  6187.      int a_view, a_ref;
  6188. {
  6189.   boolean r = false;
  6190.  
  6191.   if (((strcmp (atom[a_view - 1].atype, "C1 ") == 0) &
  6192.        (bond[get_bond (a_view, a_ref) - 1].btype == 'T')) &&
  6193.       !strcmp (atom[a_ref - 1].atype, "N1 ") &&
  6194.       atom[a_ref - 1].neighbor_count == 1)
  6195.     r = true;
  6196.   return r;
  6197. }
  6198.  
  6199.  
  6200. static boolean
  6201. is_cyano_c (a_ref)
  6202.      int a_ref;
  6203. {
  6204.   int i;
  6205.   boolean r = false;
  6206.   neighbor_rec nb;
  6207.   int FORLIM;
  6208.  
  6209.   memset (nb, 0, sizeof (neighbor_rec));
  6210.   if (strcmp (atom[a_ref - 1].atype, "C1 ")
  6211.       || atom[a_ref - 1].neighbor_count <= 0)
  6212.     return false;
  6213.   get_neighbors (nb, a_ref);
  6214.   FORLIM = atom[a_ref - 1].neighbor_count;
  6215.   for (i = 0; i < FORLIM; i++)
  6216.     {
  6217.       if (is_cyano (a_ref, nb[i]))
  6218.         r = true;
  6219.     }
  6220.   return r;
  6221. }
  6222.  
  6223.  
  6224. static boolean
  6225. is_nitrile (a_view, a_ref)
  6226.      int a_view, a_ref;
  6227. {
  6228.   boolean r = false;
  6229.   neighbor_rec nb;
  6230.   str2 nb_el;
  6231.  
  6232.   if (!is_cyano (a_view, a_ref))
  6233.     return false;
  6234.   if (atom[a_view - 1].neighbor_count == 1
  6235.       && atom[a_view - 1].formal_charge == 0)
  6236.     return true;
  6237. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  6238.   get_nextneighbors (nb, a_view, a_ref);
  6239.   strcpy (nb_el, atom[nb[0] - 1].element);
  6240.   if (!strcmp (nb_el, "C ")
  6241.       || !strcmp (nb_el, "H ") /*|| !strcmp (nb_el, "D ") */ )
  6242.     /* v0.3n: D */
  6243.     r = true;
  6244.   /* HCN is also a nitrile! */
  6245.   return r;
  6246. }
  6247.  
  6248.  
  6249. static boolean
  6250. is_isonitrile (a_view, a_ref)
  6251.      int a_view, a_ref;
  6252. {
  6253.   /* only recognized with CN triple bond! */
  6254.   boolean r = false;
  6255.  
  6256.   if (((strcmp (atom[a_view - 1].atype, "C1 ") == 0) &
  6257.        (bond[get_bond (a_view, a_ref) - 1].btype == 'T')) &&
  6258.       !strcmp (atom[a_ref - 1].atype, "N1 ") &&
  6259.       atom[a_ref - 1].neighbor_count == 2
  6260.       && atom[a_view - 1].neighbor_count == 1)
  6261.     r = true;
  6262.   return r;
  6263. }
  6264.  
  6265.  
  6266. static boolean
  6267. is_cyanate (a_view, a_ref)
  6268.      int a_view, a_ref;
  6269. {
  6270.   boolean r = false;
  6271.   neighbor_rec nb;
  6272.  
  6273.   if (!is_cyano (a_view, a_ref))
  6274.     return false;
  6275.   if (atom[a_view - 1].neighbor_count != 2)
  6276.     return false;
  6277.   get_nextneighbors (nb, a_view, a_ref);
  6278.   if (is_alkoxy (a_view, nb[0]) || is_aryloxy (a_view, nb[0]))
  6279.     r = true;
  6280.   return r;
  6281. }
  6282.  
  6283.  
  6284. static boolean
  6285. is_thiocyanate (a_view, a_ref)
  6286.      int a_view, a_ref;
  6287. {
  6288.   boolean r = false;
  6289.   neighbor_rec nb;
  6290.  
  6291.   if (!is_cyano (a_view, a_ref))
  6292.     return false;
  6293.   if (atom[a_view - 1].neighbor_count != 2)
  6294.     return false;
  6295.   get_nextneighbors (nb, a_view, a_ref);
  6296.   if (is_alkylsulfanyl (a_view, nb[0]) || is_arylsulfanyl (a_view, nb[0]))
  6297.     r = true;
  6298.   return r;
  6299. }
  6300.  
  6301.  
  6302. static void
  6303. update_Htotal ()
  6304. {
  6305.   int i, j, b_id;
  6306.   neighbor_rec nb;
  6307.   int single_count, double_count, triple_count, arom_count, total_bonds,
  6308.     Htotal, nval;
  6309.   /* new in v0.3 */
  6310.   boolean diazon = false;       /* new in v0.3j */
  6311.   neighbor_rec nb2;             /* new in v0.3j */
  6312.   int a1, a2, a3;               /* new in v0.3j */
  6313.   int FORLIM, FORLIM1;
  6314.  
  6315.   if (n_atoms < 1)
  6316.     return;
  6317.   memset (nb, 0, sizeof (neighbor_rec));
  6318.   FORLIM = n_atoms;
  6319.   for (i = 1; i <= FORLIM; i++)
  6320.     {
  6321.       single_count = 0;
  6322.       double_count = 0;
  6323.       triple_count = 0;
  6324.       arom_count = 0;
  6325.       total_bonds = 0;
  6326.       Htotal = 0;
  6327.       get_neighbors (nb, i);
  6328.       if (atom[i - 1].neighbor_count > 0)
  6329.         {
  6330.           /* count single, double, triple, and aromatic bonds to all neighbor atoms */
  6331.           FORLIM1 = atom[i - 1].neighbor_count;
  6332.           for (j = 0; j < FORLIM1; j++)
  6333.             {
  6334.               b_id = get_bond (i, nb[j]);
  6335.               if (b_id > 0)
  6336.                 {
  6337.                   if (bond[b_id - 1].btype == 'S')
  6338.                     single_count++;
  6339.                   if (bond[b_id - 1].btype == 'D')
  6340.                     double_count++;
  6341.                   if (bond[b_id - 1].btype == 'T')
  6342.                     triple_count++;
  6343.                   if (bond[b_id - 1].btype == 'A')
  6344.                     arom_count++;
  6345.                 }
  6346.             }
  6347.           /*check for diazonium salts */
  6348.           a1 = i;
  6349.           a2 = nb[0];
  6350.           if (!strcmp (atom[a1 - 1].element, "N ") &&
  6351.               !strcmp (atom[a2 - 1].element, "N "))
  6352.             {
  6353.               if (atom[a2 - 1].neighbor_count == 2)
  6354.                 {
  6355.                   get_nextneighbors (nb2, a2, a1);
  6356.                   a3 = nb2[0];
  6357.                   if ((strcmp (atom[a3 - 1].element, "C ") ==
  6358.                        0) && is_diazonium (a3, a2))
  6359.                     diazon = true;
  6360.                 }
  6361.             }
  6362.         }
  6363.       total_bonds = single_count + double_count * 2 + triple_count * 3 +
  6364.         (int) (1.5 * arom_count);
  6365.       /* calculate number of total hydrogens per atom */
  6366.       /*nval := nvalences(atom^[i].element);    (* new in v0.3 */
  6367.       nval = atom[i - 1].nvalences;     /* new in v0.3m */
  6368.       if (!strcmp (atom[i - 1].element, "P "))
  6369.         {
  6370.           if (total_bonds - atom[i - 1].formal_charge > 3)      /* refined in v0.3n */
  6371.             nval = 5;
  6372.         }                       /*  */
  6373.       if (!strcmp (atom[i - 1].element, "S "))
  6374.         {                       /* v0.3h */
  6375.           if (total_bonds > 2 && atom[i - 1].formal_charge < 1)
  6376.             /* updated in v0.3j */
  6377.             nval = 4;
  6378.           if (total_bonds > 4)  /* this will need some refinement... */
  6379.             nval = 6;
  6380.         }                       /*  */
  6381.       Htotal = nval - total_bonds + atom[i - 1].formal_charge;
  6382.       if (diazon)               /* v0.3j */
  6383.         Htotal = 0;
  6384.       if (Htotal < 0)           /* e.g., N in nitro group */
  6385.         Htotal = 0;
  6386.       atom[i - 1].Htot = Htotal;
  6387.       if (atom[i - 1].Hexp > atom[i - 1].Htot)  /* v0.3n; just to be sure... */
  6388.         atom[i - 1].Htot = atom[i - 1].Hexp;
  6389.     }
  6390. }
  6391.  
  6392.  
  6393. static void
  6394. update_atypes ()
  6395. {
  6396.   int i, j, b_id;
  6397.   neighbor_rec nb;
  6398.   int single_count, double_count, triple_count, arom_count, acyl_count,
  6399.     C_count, O_count, total_bonds, NdO_count, NdC_count, Htotal, FORLIM,
  6400.     FORLIM1;
  6401.  
  6402.   if (n_atoms < 1)
  6403.     return;
  6404.   memset (nb, 0, sizeof (neighbor_rec));
  6405.   FORLIM = n_atoms;
  6406.   for (i = 0; i < FORLIM; i++)
  6407.     {
  6408.       single_count = 0;
  6409.       double_count = 0;
  6410.       triple_count = 0;
  6411.       arom_count = 0;
  6412.       total_bonds = 0;
  6413.       acyl_count = 0;
  6414.       C_count = 0;
  6415.       O_count = 0;
  6416.       NdO_count = 0;
  6417.       NdC_count = 0;
  6418.       Htotal = 0;
  6419.       get_neighbors (nb, i + 1);
  6420.       if (atom[i].neighbor_count > 0)
  6421.         {
  6422.           /* count single, double, triple, and aromatic bonds to all neighbor atoms */
  6423.           FORLIM1 = atom[i].neighbor_count;
  6424.           for (j = 0; j < FORLIM1; j++)
  6425.             {
  6426.               if (is_oxo_C (nb[j]) || is_thioxo_C (nb[j]))
  6427.                 acyl_count++;
  6428.               if (!strcmp (atom[nb[j] - 1].element, "C "))
  6429.                 C_count++;
  6430.               if (!strcmp (atom[nb[j] - 1].element, "O "))
  6431.                 O_count++;
  6432.               b_id = get_bond (i + 1, nb[j]);
  6433.               if (b_id > 0)
  6434.                 {
  6435.                   if (bond[b_id - 1].btype == 'S')
  6436.                     single_count++;
  6437.                   if (bond[b_id - 1].btype == 'D')
  6438.                     double_count++;
  6439.                   if (bond[b_id - 1].btype == 'T')
  6440.                     triple_count++;
  6441.                   if (bond[b_id - 1].btype == 'A')
  6442.                     /* v0.3n: special treatment for acyclic bonds */
  6443.                     {           /* flagged as "aromatic" (in query structures) */
  6444.                       if (bond[b_id - 1].ring_count > 0)
  6445.                         arom_count++;
  6446.                       else
  6447.                         double_count++;
  6448.                     }
  6449.                   if ((!strcmp (atom[i].element, "N ") &&
  6450.                        !strcmp (atom[nb[j] - 1].element, "O ")) ||
  6451.                       (!strcmp (atom[i].element, "O ") &&
  6452.                        !strcmp (atom[nb[j] - 1].element, "N ")))
  6453.                     {
  6454.                       /* check if it is an N-oxide drawn with a double bond ==> should be N3 */
  6455.                       if (bond[b_id - 1].btype == 'D')
  6456.                         NdO_count++;
  6457.                     }
  6458.                   if ((!strcmp (atom[i].element, "N ") &&
  6459.                        !strcmp (atom[nb[j] - 1].element, "C ")) ||
  6460.                       (!strcmp (atom[i].element, "C ") &&
  6461.                        !strcmp (atom[nb[j] - 1].element, "N ")))
  6462.                     {
  6463.                       if (bond[b_id - 1].btype == 'D')
  6464.                         NdC_count++;
  6465.                     }
  6466.                 }
  6467.             }
  6468.           total_bonds = single_count + double_count * 2 + triple_count * 3 +
  6469.             (int) (1.5 * arom_count);
  6470.           /* calculate number of total hydrogens per atom */
  6471.           /*Htotal := nvalences(atom^[i].element) - total_bonds + atom^[i].formal_charge; */
  6472.           Htotal = atom[i].nvalences - total_bonds + atom[i].formal_charge;
  6473.           if (Htotal < 0)       /* e.g., N in nitro group */
  6474.             Htotal = 0;
  6475.           atom[i].Htot = Htotal;
  6476.           /* refine atom types, based on bond types */
  6477.           if (!strcmp (atom[i].element, "C "))
  6478.             {
  6479.               if (arom_count > 1)
  6480.                 strcpy (atom[i].atype, "CAR");
  6481.               if (triple_count == 1 || double_count == 2)
  6482.                 strcpy (atom[i].atype, "C1 ");
  6483.               if (double_count == 1)
  6484.                 strcpy (atom[i].atype, "C2 ");
  6485.               if (triple_count == 0 && double_count == 0 && arom_count < 2)
  6486.                 strcpy (atom[i].atype, "C3 ");
  6487.             }
  6488.           if (!strcmp (atom[i].element, "O "))
  6489.             {
  6490.               if (double_count == 1)
  6491.                 strcpy (atom[i].atype, "O2 ");
  6492.               if (double_count == 0)
  6493.                 strcpy (atom[i].atype, "O3 ");
  6494.             }
  6495.           if (!strcmp (atom[i].element, "N "))
  6496.             {
  6497.               if (total_bonds > 3)
  6498.                 {
  6499.                   if (O_count == 0)
  6500.                     {
  6501.                       if (single_count > 3 ||
  6502.                           (single_count == 2 && double_count == 1
  6503.                           && C_count >= 2))
  6504.                         atom[i].formal_charge = 1;
  6505.                     }
  6506.                   else
  6507.                     {
  6508.                       if (O_count == 1 && atom[i].formal_charge == 0)   /* v0.3m */
  6509.                         strcpy (atom[i].atype, "N3 ");
  6510.                       if (O_count == 2 && atom[i].formal_charge == 0)
  6511.                         {
  6512.                           if (atom[i].neighbor_count > 2)       /* nitro v0.3o */
  6513.                             strcpy (atom[i].atype, "N2 ");
  6514.                           if (atom[i].neighbor_count == 2)      /* NO2   v0.3o */
  6515.                             strcpy (atom[i].atype, "N1 ");
  6516.                         }
  6517.                       /* the rest is left empty, so far.... */
  6518.                     }
  6519.                 }
  6520.               /* could be an N-oxide -> should be found elsewhere  */
  6521.               if (triple_count == 1 ||
  6522.                   (double_count == 2 && atom[i].neighbor_count == 2))
  6523.                 /* v0.3n */
  6524.                 strcpy (atom[i].atype, "N1 ");
  6525.               if (double_count == 1)
  6526.                 {
  6527.                   /*if NdC_count > 0 then atom^[i].atype := 'N2 '; */
  6528.                   if (NdC_count == 0 && NdO_count > 0 && C_count >= 2)
  6529.                     strcpy (atom[i].atype, "N3 ");
  6530.                   /* N-oxide is N3 except in hetarene etc. */
  6531.                   else
  6532.                     strcpy (atom[i].atype, "N2 ");
  6533.                 }
  6534.               /* fallback, added in v0.3g  */
  6535.               if (arom_count > 1 || atom[i].arom == true)       /* v0.3n */
  6536.                 strcpy (atom[i].atype, "NAR");
  6537.               if (triple_count == 0 && double_count == 0)
  6538.                 {
  6539.                   if (atom[i].formal_charge == 0)
  6540.                     {
  6541.                       if (acyl_count == 0)
  6542.                         strcpy (atom[i].atype, "N3 ");
  6543.                       if (acyl_count > 0)
  6544.                         strcpy (atom[i].atype, "NAM");
  6545.                     }
  6546.                   if (atom[i].formal_charge == 1)
  6547.                     strcpy (atom[i].atype, "N3+");
  6548.                 }
  6549.             }
  6550.           if (!strcmp (atom[i].element, "P "))
  6551.             {
  6552.               if (single_count > 4)
  6553.                 strcpy (atom[i].atype, "P4 ");
  6554.               if (single_count <= 4 && double_count == 0)
  6555.                 strcpy (atom[i].atype, "P3 ");
  6556.               if (double_count == 2)
  6557.                 strcpy (atom[i].atype, "P3D");
  6558.             }
  6559.           if (!strcmp (atom[i].element, "S "))
  6560.             {
  6561.               if (double_count == 1 && single_count == 0)
  6562.                 strcpy (atom[i].atype, "S2 ");
  6563.               if (double_count == 0)
  6564.                 strcpy (atom[i].atype, "S3 ");
  6565.               if (double_count == 1 && single_count > 0)
  6566.                 strcpy (atom[i].atype, "SO ");
  6567.               if (double_count == 2 && single_count > 0)
  6568.                 strcpy (atom[i].atype, "SO2");
  6569.             }
  6570.           /* further atom types should go here */
  6571.         }
  6572.     }
  6573. }
  6574.  
  6575.  
  6576. static void
  6577. chk_arom ()
  6578. {
  6579.   int i, j, pi_count, ring_size, b, a1, a2;     /* v0.3n */
  6580.   ringpath_type testring;
  6581.   int a_ref, a_prev, a_next, b_bk, b_fw, b_exo;
  6582.   char bt_bk, bt_fw;
  6583.   boolean ar_bk, ar_fw, ar_exo; /* new in v0.3 */
  6584.   boolean conj_intr, ko, aromatic, aromatic_bt; /* v0.3n */
  6585.   int n_db, n_sb, n_ar;
  6586.   boolean cumul;
  6587.   int exo_mC;                   /* v0.3j */
  6588.   int arom_pi_diff;             /* v0.3j */
  6589.   int FORLIM;
  6590.  
  6591.   if (n_rings < 1)
  6592.     return;
  6593.   FORLIM = n_rings;
  6594.   /* first, do a very quick check for benzene, pyridine, etc. */
  6595.   for (i = 0; i < FORLIM; i++)
  6596.     {
  6597.       ring_size = ringprop[i].size;
  6598.       if (ring_size == 6)
  6599.         {
  6600.           memset (testring, 0, sizeof (ringpath_type));
  6601.           for (j = 0; j < ring_size; j++)
  6602.             testring[j] = ring[i][j];
  6603.           cumul = false;
  6604.           n_sb = 0;
  6605.           n_db = 0;
  6606.           n_ar = 0;
  6607.           a_prev = testring[ring_size - 1];
  6608.           for (j = 1; j <= ring_size; j++)
  6609.             {
  6610.               a_ref = testring[j - 1];
  6611.               if (j < ring_size)
  6612.                 a_next = testring[j];
  6613.               else
  6614.                 a_next = testring[0];
  6615.               b_bk = get_bond (a_prev, a_ref);
  6616.               b_fw = get_bond (a_ref, a_next);
  6617.               bt_bk = bond[b_bk - 1].btype;
  6618.               bt_fw = bond[b_fw - 1].btype;
  6619.               if (bt_fw == 'S')
  6620.                 n_sb++;
  6621.               if (bt_fw == 'D')
  6622.                 n_db++;
  6623.               if (bt_fw == 'A')
  6624.                 n_ar++;
  6625.               if (bt_fw != 'A' && bt_bk == bt_fw)
  6626.                 cumul = true;
  6627.               a_prev = a_ref;
  6628.             }
  6629.           if (n_ar == 6 || (n_sb == 3 && n_db == 3 && cumul == false))
  6630.             {                   /* this ring is aromatic */
  6631.               a_prev = testring[ring_size - 1];
  6632.               for (j = 0; j < ring_size; j++)
  6633.                 {
  6634.                   a_ref = testring[j];
  6635.                   b_bk = get_bond (a_prev, a_ref);
  6636.                   bond[b_bk - 1].arom = true;
  6637.                   a_prev = a_ref;
  6638.                 }
  6639.               ringprop[i].arom = true;
  6640.             }
  6641.         }
  6642.     }
  6643.   FORLIM = n_rings;
  6644.   for (i = 1; i <= FORLIM; i++)
  6645.     {
  6646.       if (ringprop[i - 1].arom == false)
  6647.         {
  6648.           /* do the hard work only for those rings which are not yet flagged aromatic */
  6649.           memset (testring, 0, sizeof (ringpath_type));
  6650.           ring_size = ringprop[i - 1].size;     /* v0.3j */
  6651.           for (j = 0; j < ring_size; j++)       /* v0.3j */
  6652.             testring[j] = ring[i - 1][j];
  6653.           pi_count = 0;
  6654.           arom_pi_diff = 0;     /* v0.3j */
  6655. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  6656.           ko = false;
  6657.           a_prev = testring[ring_size - 1];
  6658.           for (j = 1; j <= ring_size; j++)
  6659.             {
  6660.               a_ref = testring[j - 1];
  6661.               if (j < ring_size)
  6662.                 a_next = testring[j];
  6663.               else
  6664.                 a_next = testring[0];
  6665.               b_bk = get_bond (a_prev, a_ref);
  6666.               b_fw = get_bond (a_ref, a_next);
  6667.               bt_bk = bond[b_bk - 1].btype;
  6668.               bt_fw = bond[b_fw - 1].btype;
  6669.               ar_bk = bond[b_bk - 1].arom;
  6670.               ar_fw = bond[b_fw - 1].arom;
  6671.               if (bt_bk == 'S' && bt_fw == 'S' && ar_bk == false
  6672.                   && ar_fw == false)
  6673.                 {
  6674.                   /* first, assume the worst case (interrupted conjugation) */
  6675.                   conj_intr = true;
  6676.                   /* conjugation can be restored by hetero atoms */
  6677.                   if (!strcmp (atom[a_ref - 1].atype, "O3 ") ||
  6678.                       !strcmp (atom[a_ref - 1].atype, "S3 ") ||
  6679.                       !strcmp (atom[a_ref - 1].element, "N ") ||
  6680.                       !strcmp (atom[a_ref - 1].element, "SE"))
  6681.                     {
  6682.                       conj_intr = false;
  6683.                       pi_count += 2;    /* lone pair adds for 2 pi electrons */
  6684.                     }
  6685.                   /* conjugation can be restored by a formal charge at a methylene group */
  6686.                   if (!strcmp (atom[a_ref - 1].element, "C ") &&
  6687.                       atom[a_ref - 1].formal_charge != 0)
  6688.                     {
  6689.                       conj_intr = false;
  6690.                       pi_count -= atom[a_ref - 1].formal_charge;
  6691.                       /* neg. charge increases pi_count! */
  6692.                     }
  6693.                   /* conjugation can be restored by carbonyl groups etc. */
  6694.                   if (is_oxo_C (a_ref) || is_thioxo_C (a_ref) |
  6695.                       is_exocyclic_imino_C (a_ref, i))
  6696.                     conj_intr = false;
  6697.                   /* conjugation can be restored by exocyclic C=C double bond, */
  6698.                   /* adds 2 pi electrons to 5-membered rings, not to 7-membered rings (CAUTION!) */
  6699.                   /* apply only to non-aromatic exocyclic C=C bonds */
  6700.                   exo_mC = find_exocyclic_methylene_C (a_ref, i);       /* v0.3j */
  6701.                   if (exo_mC > 0 && (ring_size & 1))
  6702.                     {           /* v0.3j */
  6703.                       b_exo = get_bond (a_ref, exo_mC); /* v0.3j  */
  6704.                       ar_exo = bond[b_exo - 1].arom;
  6705.                       if (((ring_size - 1) & 3) == 0)
  6706.                         {       /* 5-membered rings and related */
  6707.                           conj_intr = false;
  6708.                           pi_count += 2;
  6709.                         }
  6710.                       else
  6711.                         {
  6712.                           if (!ar_exo)
  6713.                             conj_intr = false;
  6714.                         }
  6715.                     }
  6716.                   /* 7-membered rings and related */
  6717.                   /* if conjugation is still interrupted ==> knock-out */
  6718.                   if (conj_intr)
  6719.                     ko = true;
  6720.                 }
  6721.               else
  6722.                 {
  6723.                   if (bt_bk == 'S' && bt_fw == 'S' && ar_bk == true
  6724.                       && ar_fw == true)
  6725.                     {
  6726.                       if (!strcmp (atom[a_ref - 1].atype, "O3 ") ||
  6727.                           !strcmp (atom[a_ref - 1].atype, "S3 ") ||
  6728.                           !strcmp (atom[a_ref - 1].element, "N ") ||
  6729.                           !strcmp (atom[a_ref - 1].element, "SE"))
  6730.                         pi_count += 2;  /* lone pair adds for 2 pi electrons */
  6731.                       if (!strcmp (atom[a_ref - 1].element, "C ") &&
  6732.                           atom[a_ref - 1].formal_charge != 0)
  6733.                         pi_count -= atom[a_ref - 1].formal_charge;
  6734.                       /* neg. charge increases pi_count! */
  6735.                       exo_mC = find_exocyclic_methylene_C (a_ref, i);   /* v0.3j */
  6736.                       if (exo_mC > 0 && (ring_size & 1))
  6737.                         {       /* v0.3j */
  6738.                           b_exo = get_bond (a_ref, exo_mC);     /* v0.3j */
  6739. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  6740.                           if (((ring_size - 1) & 3) == 0)
  6741.                             /* 5-membered rings and related */
  6742.                             pi_count += 2;
  6743.                         }
  6744.                     }
  6745.                   else
  6746.                     {
  6747.                       pi_count++;       /* v0.3j; adjustment for bridgehead N: see below */
  6748.                       if (bt_bk == 'S' && bt_fw == 'S' &&
  6749.                           ((ar_bk == true && ar_fw == false) ||
  6750.                            (ar_bk == false && ar_fw == true)))
  6751.                         {
  6752.                           /* v0.3j; if a bridgehead N were not aromatic, it could  */
  6753.                           /* contribute 2 pi electrons --> try also this variant */
  6754.                           /* (example: CAS 32278-54-9) */
  6755.                           if (!strcmp (atom[a_ref - 1].element, "N "))
  6756.                             {
  6757.                               arom_pi_diff++;
  6758.                               /* any other case: increase pi count by one electron */
  6759.                             }
  6760.                         }
  6761.                     }
  6762.                 }
  6763.               /* last command: */
  6764.               a_prev = a_ref;
  6765.             }                   /* for j := 1 to ring_size */
  6766.           /* now we can draw our conclusion */
  6767.           /*if not ((ko) or (odd(pi_count))) then */
  6768.           if (!ko)
  6769.             /* v0.3j; odd pi_count might be compensated by arom_pi_diff */
  6770.             {                   /* apply Hueckel's rule */
  6771.               if (labs (ring_size - pi_count) < 2 &&
  6772.                   (((pi_count - 2) & 3) == 0 ||
  6773.                    ((pi_count + arom_pi_diff - 2) & 3) == 0))
  6774.                 {
  6775.                   /* this ring is aromatic */
  6776.                   ringprop[i - 1].arom = true;
  6777.                   /* now mark _all_ bonds in the ring as aromatic */
  6778.                   a_prev = testring[ring_size - 1];
  6779.                   for (j = 0; j < ring_size; j++)
  6780.                     {
  6781.                       a_ref = testring[j];
  6782.                       bond[get_bond (a_prev, a_ref) - 1].arom = true;
  6783.                       a_prev = a_ref;
  6784.                     }
  6785.                 }
  6786.             }
  6787.         }
  6788.     }                           /* (for i := 1 to n_rings) */
  6789.   FORLIM = n_bonds;
  6790.   /* finally, mark all involved atoms as aromatic */
  6791.   for (i = 0; i < FORLIM; i++)
  6792.     {
  6793.       if (bond[i].arom)
  6794.         {
  6795.           a1 = bond[i].a1;      /* v0.3n */
  6796.           a2 = bond[i].a2;      /* v0.3n */
  6797.           atom[a1 - 1].arom = true;
  6798.           atom[a2 - 1].arom = true;
  6799.           /* v0.3n: update atom types if applicable (C and N) */
  6800.           if (!strcmp (atom[a1 - 1].element, "C "))
  6801.             strcpy (atom[a1 - 1].atype, "CAR");
  6802.           if (!strcmp (atom[a2 - 1].element, "C "))
  6803.             strcpy (atom[a2 - 1].atype, "CAR");
  6804.           if (!strcmp (atom[a1 - 1].element, "N "))
  6805.             strcpy (atom[a1 - 1].atype, "NAR");
  6806.           if (!strcmp (atom[a2 - 1].element, "N "))
  6807.             strcpy (atom[a2 - 1].atype, "NAR");
  6808.         }
  6809.     }
  6810.   FORLIM = n_rings;
  6811.   /* update aromaticity information in ringprop */
  6812.   /* new in v0.3n: accept rings as aromatic if all bonds are of type 'A' */
  6813.   for (i = 0; i < FORLIM; i++)
  6814.     {
  6815.       memcpy (testring, ring[i], sizeof (ringpath_type));
  6816.       /*ring_size := path_length(testring); */
  6817.       ring_size = ringprop[i].size;     /* v0.3j */
  6818.       aromatic = true;
  6819.       aromatic_bt = true;       /* v0.3n */
  6820.       a_prev = testring[ring_size - 1];
  6821.       for (j = 0; j < ring_size; j++)
  6822.         {
  6823.           a_ref = testring[j];
  6824.           b = get_bond (a_prev, a_ref); /* v0.3n */
  6825.           if (!bond[b - 1].arom)
  6826.             aromatic = false;
  6827.           if (bond[b - 1].btype != 'A') /* v0.3n */
  6828.             aromatic_bt = false;
  6829.           a_prev = a_ref;
  6830.         }
  6831.       if (aromatic_bt && !aromatic)
  6832.         {                       /* v0.3n: update aromaticity flag */
  6833.           a_prev = testring[ring_size - 1];
  6834.           for (j = 0; j < ring_size; j++)
  6835.             {
  6836.               a_ref = testring[j];
  6837.               b = get_bond (a_prev, a_ref);
  6838.               bond[b - 1].arom = true;
  6839.               if (!strcmp (atom[a_ref - 1].element, "C "))
  6840.                 strcpy (atom[a_ref - 1].atype, "CAR");
  6841.               if (!strcmp (atom[a_ref - 1].element, "N "))
  6842.                 strcpy (atom[a_ref - 1].atype, "NAR");
  6843.               a_prev = a_ref;
  6844.             }
  6845.           aromatic = true;
  6846.         }                       /* end v0.3n block   */
  6847.       if (aromatic)
  6848.         ringprop[i].arom = true;
  6849.       else
  6850.         ringprop[i].arom = false;
  6851.     }
  6852. }
  6853.  
  6854.  
  6855. static void
  6856. write_mol ()
  6857. {
  6858.   int i, j;
  6859.   ringpath_type testring;
  6860.   int ring_size, FORLIM;
  6861.  
  6862.   /*aromatic : boolean; */
  6863.   /*a_prev, a_ref : integer; */
  6864.   if (progmode == pmCheckMol)
  6865.     printf ("Molecule name: %s\n", molname);
  6866.   else
  6867.     printf ("Molecule name (haystack): %s\n", molname);
  6868.   printf ("atoms: %d  bonds: %d  rings: %d\n", n_atoms, n_bonds, n_rings);
  6869.   if (n_atoms < 1)
  6870.     return;
  6871.   if (n_bonds < 1)
  6872.     return;
  6873.   FORLIM = n_atoms;
  6874.   for (i = 1; i <= FORLIM; i++)
  6875.     {
  6876.       if (i < 10)
  6877.         putchar (' ');
  6878.       if (i < 100)
  6879.         putchar (' ');
  6880.       if (i < 1000)
  6881.         putchar (' ');
  6882.       printf ("%d %s %s %f %f ",
  6883.               i, atom[i - 1].element, atom[i - 1].atype, atom[i - 1].x,
  6884.               atom[i - 1].y);
  6885.       printf ("%f", atom[i - 1].z);
  6886.       printf ("  (%d heavy-atom neighbors, Hexp: %d Htot: %d)",
  6887.               atom[i - 1].neighbor_count, atom[i - 1].Hexp, atom[i - 1].Htot);
  6888.       if (atom[i - 1].formal_charge != 0)
  6889.         printf ("  charge: %d", atom[i - 1].formal_charge);
  6890.       putchar ('\n');
  6891.     }
  6892.   FORLIM = n_bonds;
  6893.   for (i = 1; i <= FORLIM; i++)
  6894.     {
  6895.       if (i < 10)
  6896.         putchar (' ');
  6897.       if (i < 100)
  6898.         putchar (' ');
  6899.       if (i < 1000)
  6900.         putchar (' ');
  6901.       printf ("%d %d %d %c",
  6902.               i, bond[i - 1].a1, bond[i - 1].a2, bond[i - 1].btype);
  6903.       if (bond[i - 1].ring_count > 0)
  6904.         printf (", contained in %d ring(s)", bond[i - 1].ring_count);
  6905.       if (bond[i - 1].arom)
  6906.         printf (" (aromatic) ");
  6907.       putchar ('\n');
  6908.     }
  6909.   if (n_rings <= 0)
  6910.     return;
  6911.   FORLIM = n_rings;
  6912.   for (i = 0; i < FORLIM; i++)
  6913.     {
  6914.       printf ("ring %d: ", i + 1);
  6915.       /*aromatic := true; */
  6916.       memset (testring, 0, sizeof (ringpath_type));
  6917.       ring_size = ringprop[i].size;     /* v0.3j */
  6918.       /*for j := 1 to max_ringsize do if ring^[i,j] > 0 then testring[j] := ring^[i,j]; */
  6919.       for (j = 0; j < ring_size; j++)   /* v0.3j */
  6920.         testring[j] = ring[i][j];
  6921.       /*ring_size := path_length(testring); */
  6922.       /*a_prev := testring[ring_size]; */
  6923.       for (j = 0; j < ring_size; j++)
  6924.         {
  6925.           printf ("%d ", testring[j]);
  6926.           /*a_ref := testring[j]; */
  6927.           /*if (not bond^[get_bond(a_prev,a_ref)].arom) then aromatic := false; */
  6928.           /*a_prev := a_ref; */
  6929.         }
  6930.       /*if aromatic then write(' (aromatic)'); */
  6931.       if (ringprop[i].arom)
  6932.         printf (" (aromatic)");
  6933.       if (ringprop[i].envelope)
  6934.         printf (" (env)");
  6935.       putchar ('\n');
  6936.     }
  6937. }
  6938.  
  6939.  
  6940. static void
  6941. write_needle_mol ()
  6942. {
  6943.   int i, j;
  6944.   ringpath_type testring;
  6945.   int ring_size;
  6946.   boolean aromatic;
  6947.   int a_prev, a_ref, FORLIM;
  6948.  
  6949.   printf ("Molecule name (needle): %s\n", ndl_molname);
  6950.   printf ("atoms: %d  bonds: %d  rings: %d\n",
  6951.           ndl_n_atoms, ndl_n_bonds, ndl_n_rings);
  6952.   if (ndl_n_atoms < 1)
  6953.     return;
  6954.   if (ndl_n_bonds < 1)
  6955.     return;
  6956.   FORLIM = ndl_n_atoms;
  6957.   for (i = 1; i <= FORLIM; i++)
  6958.     {
  6959.       if (i < 10)
  6960.         putchar (' ');
  6961.       if (i < 100)
  6962.         putchar (' ');
  6963.       if (i < 1000)
  6964.         putchar (' ');
  6965.       printf ("%d %s %s %f %f ",
  6966.               i, ndl_atom[i - 1].element, ndl_atom[i - 1].atype,
  6967.               ndl_atom[i - 1].x, atom[i - 1].y);
  6968.       printf ("%f", ndl_atom[i - 1].z);
  6969.       printf ("  (%d heavy-atom neighbors, Hexp: %d Htot: %d)",
  6970.               ndl_atom[i - 1].neighbor_count, ndl_atom[i - 1].Hexp,
  6971.               ndl_atom[i - 1].Htot);
  6972.       if (ndl_atom[i - 1].formal_charge != 0)
  6973.         printf ("  charge: %d", ndl_atom[i - 1].formal_charge);
  6974.       putchar ('\n');
  6975.     }
  6976.   FORLIM = ndl_n_bonds;
  6977.   for (i = 1; i <= FORLIM; i++)
  6978.     {
  6979.       if (i < 10)
  6980.         putchar (' ');
  6981.       if (i < 100)
  6982.         putchar (' ');
  6983.       if (i < 1000)
  6984.         putchar (' ');
  6985.       printf ("%d %d %d %c",
  6986.               i, ndl_bond[i - 1].a1, ndl_bond[i - 1].a2,
  6987.               ndl_bond[i - 1].btype);
  6988.       if (ndl_bond[i - 1].ring_count > 0)
  6989.         printf (", contained in %d ring(s)", ndl_bond[i - 1].ring_count);
  6990.       if (ndl_bond[i - 1].arom)
  6991.         printf (" (aromatic) ");
  6992.       putchar ('\n');
  6993.     }
  6994.   if (ndl_n_rings <= 0)
  6995.     return;
  6996.   FORLIM = ndl_n_rings;
  6997.   for (i = 0; i < FORLIM; i++)
  6998.     {
  6999.       aromatic = true;
  7000.       memset (testring, 0, sizeof (ringpath_type));
  7001.       for (j = 0; j < max_ringsize; j++)
  7002.         {
  7003.           if (ndl_ring[i][j] > 0)
  7004.             testring[j] = ndl_ring[i][j];
  7005.         }
  7006.       ring_size = path_length (testring);
  7007.       printf ("ring %d: ", i + 1);
  7008.       a_prev = testring[ring_size - 1];
  7009.       for (j = 0; j < ring_size; j++)
  7010.         {
  7011.           printf ("%d ", testring[j]);
  7012.           a_ref = testring[j];
  7013.           if (!ndl_bond[get_ndl_bond (a_prev, a_ref) - 1].arom) /* v0.3k */
  7014.             aromatic = false;
  7015.           a_prev = a_ref;
  7016.         }
  7017.       if (aromatic)
  7018.         printf (" (aromatic)");
  7019.       putchar ('\n');
  7020.     }
  7021. }
  7022.  
  7023.  
  7024. static void
  7025. chk_so2_deriv (a_ref)
  7026.      int a_ref;
  7027. {
  7028.   int i;
  7029.   neighbor_rec nb;
  7030.   str2 nb_el;
  7031.   int het_count = 0, o_count = 0, or_count = 0, hal_count = 0, n_count = 0,
  7032.     c_count = 0;
  7033.   int FORLIM;
  7034.  
  7035.   memset (nb, 0, sizeof (neighbor_rec));
  7036.   if (strcmp (atom[a_ref - 1].atype, "SO2"))
  7037.     return;
  7038.   get_neighbors (nb, a_ref);
  7039.   FORLIM = atom[a_ref - 1].neighbor_count;
  7040.   for (i = 0; i < FORLIM; i++)
  7041.     {
  7042.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  7043.         {
  7044.           strcpy (nb_el, atom[nb[i] - 1].element);
  7045.           if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  7046.               /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU")
  7047.               && strcmp (nb_el, "LP"))
  7048.             /* added 'D ' in v0.3n */
  7049.             het_count++;
  7050.           if (!strcmp (nb_el, "O "))
  7051.             {
  7052.               o_count++;
  7053.               if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]))
  7054.                 or_count++;
  7055.             }
  7056.           if (!strcmp (nb_el, "N "))
  7057.             n_count++;
  7058.           if (!strcmp (nb_el, "C "))
  7059.             c_count++;
  7060.           if (!strcmp (nb_el, "F ") || !strcmp (nb_el, "CL") ||
  7061.               !strcmp (nb_el, "BR") || !strcmp (nb_el, "I ")
  7062.               || !strcmp (nb_el, "AT"))
  7063.             hal_count++;
  7064.         }
  7065.     }
  7066.   if (het_count == 2)
  7067.     {                           /* sulfuric acid derivative */
  7068.       fg[fg_sulfuric_acid_deriv - 1] = true;
  7069.       if (o_count == 2)
  7070.         {
  7071.           if (or_count == 0)
  7072.             fg[fg_sulfuric_acid - 1] = true;
  7073.           if (or_count == 1)
  7074.             fg[fg_sulfuric_acid_monoester - 1] = true;
  7075.           if (or_count == 2)
  7076.             fg[fg_sulfuric_acid_diester - 1] = true;
  7077.         }
  7078.       if (o_count == 1)
  7079.         {
  7080.           if (or_count == 1 && n_count == 1)
  7081.             fg[fg_sulfuric_acid_amide_ester - 1] = true;
  7082.           if (or_count == 0 && n_count == 1)
  7083.             fg[fg_sulfuric_acid_amide - 1] = true;
  7084.         }
  7085.       if (n_count == 2)
  7086.         fg[fg_sulfuric_acid_diamide - 1] = true;
  7087.       if (hal_count > 0)
  7088.         fg[fg_sulfuryl_halide - 1] = true;
  7089.     }
  7090.   if (het_count == 1 && c_count == 1)
  7091.     {                           /* sulfonic acid derivative */
  7092.       fg[fg_sulfonic_acid_deriv - 1] = true;
  7093.       if (o_count == 1 && or_count == 0)
  7094.         fg[fg_sulfonic_acid - 1] = true;
  7095.       if (o_count == 1 && or_count == 1)
  7096.         fg[fg_sulfonic_acid_ester - 1] = true;
  7097.       if (n_count == 1)
  7098.         fg[fg_sulfonamide - 1] = true;
  7099.       if (hal_count == 1)
  7100.         fg[fg_sulfonyl_halide - 1] = true;
  7101.     }
  7102.   if (het_count == 0 && c_count == 2)   /* sulfone */
  7103.     fg[fg_sulfone - 1] = true;
  7104. }
  7105.  
  7106.  
  7107. static void
  7108. chk_p_deriv (a_ref)
  7109.      int a_ref;
  7110. {
  7111.   int i;
  7112.   neighbor_rec nb;
  7113.   str2 nb_el, dbl_het;
  7114.   int het_count;
  7115.   int oh_count = 0, or_count = 0, hal_count = 0, n_count = 0, c_count = 0;
  7116.   int FORLIM;
  7117.  
  7118.   if (strcmp (atom[a_ref - 1].element, "P "))
  7119.     return;
  7120.   memset (nb, 0, sizeof (neighbor_rec));
  7121.   get_neighbors (nb, a_ref);
  7122.   *dbl_het = '\0';
  7123. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  7124.   FORLIM = atom[a_ref - 1].neighbor_count;
  7125.   for (i = 0; i < FORLIM; i++)
  7126.     {
  7127.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'D')
  7128.         strcpy (dbl_het, atom[nb[i] - 1].element);
  7129.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  7130.         {
  7131.           strcpy (nb_el, atom[nb[i] - 1].element);
  7132.           if (!strcmp (nb_el, "C "))
  7133.             c_count++;
  7134.           if (is_hydroxy (a_ref, nb[i]))
  7135.             oh_count++;
  7136.           if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]))
  7137.             or_count++;
  7138.           if (!strcmp (nb_el, "N "))
  7139.             n_count++;
  7140.           if (!strcmp (nb_el, "F ") || !strcmp (nb_el, "CL") ||
  7141.               !strcmp (nb_el, "BR") || !strcmp (nb_el, "I ")
  7142.               || !strcmp (nb_el, "AT"))
  7143.             hal_count++;
  7144.         }
  7145.     }
  7146.   het_count = oh_count + or_count + hal_count + n_count;
  7147.   if (!strcmp (atom[a_ref - 1].atype, "P3D") ||
  7148.       !strcmp (atom[a_ref - 1].atype, "P4 "))
  7149.     {
  7150.       if (!strcmp (dbl_het, "O "))
  7151.         {
  7152.           if (c_count == 0)
  7153.             {
  7154.               fg[fg_phosphoric_acid_deriv - 1] = true;
  7155.               if (oh_count == 3)
  7156.                 fg[fg_phosphoric_acid - 1] = true;
  7157.               if (or_count > 0)
  7158.                 fg[fg_phosphoric_acid_ester - 1] = true;
  7159.               if (hal_count > 0)
  7160.                 fg[fg_phosphoric_acid_halide - 1] = true;
  7161.               if (n_count > 0)
  7162.                 fg[fg_phosphoric_acid_amide - 1] = true;
  7163.             }
  7164.           if (c_count == 1)
  7165.             {
  7166.               fg[fg_phosphonic_acid_deriv - 1] = true;
  7167.               if (oh_count == 2)
  7168.                 fg[fg_phosphonic_acid - 1] = true;
  7169.               if (or_count > 0)
  7170.                 fg[fg_phosphonic_acid_ester - 1] = true;
  7171.               /*if (hal_count > 0)  then fg[fg_phosphonic_acid_halide] := true;             */
  7172.               /*if (n_count > 0)    then fg[fg_phosphonic_acid_amide]  := true; */
  7173.             }
  7174.           if (c_count == 3)
  7175.             fg[fg_phosphinoxide - 1] = true;
  7176.         }
  7177.       if (!strcmp (dbl_het, "S "))
  7178.         {
  7179.           if (c_count == 0)
  7180.             {
  7181.               fg[fg_thiophosphoric_acid_deriv - 1] = true;
  7182.               if (oh_count == 3)
  7183.                 fg[fg_thiophosphoric_acid - 1] = true;
  7184.               if (or_count > 0)
  7185.                 fg[fg_thiophosphoric_acid_ester - 1] = true;
  7186.               if (hal_count > 0)
  7187.                 fg[fg_thiophosphoric_acid_halide - 1] = true;
  7188.               if (n_count > 0)
  7189.                 fg[fg_thiophosphoric_acid_amide - 1] = true;
  7190.             }
  7191.         }
  7192.     }
  7193.   /*  if (atom^[a_ref].atype = 'P4 ') then fg[fg_phosphoric_acid_deriv] := true; */
  7194.   if (strcmp (atom[a_ref - 1].atype, "P3 "))    /* changed P3D into P3 in v0.3b */
  7195.     return;
  7196.   if (c_count == 3 && het_count == 0)
  7197.     fg[fg_phosphine - 1] = true;
  7198.   if (c_count == 3 && oh_count == 1)
  7199.     fg[fg_phosphinoxide - 1] = true;
  7200. }
  7201.  
  7202.  
  7203. static void
  7204. chk_b_deriv (a_ref)
  7205.      int a_ref;
  7206. {
  7207.   int i;
  7208.   neighbor_rec nb;
  7209.   str2 nb_el;
  7210.   int het_count = 0, oh_count = 0, or_count = 0, hal_count = 0, n_count = 0,
  7211.     c_count = 0;
  7212.   int FORLIM;
  7213.  
  7214.   if (strcmp (atom[a_ref - 1].element, "B "))
  7215.     return;
  7216.   memset (nb, 0, sizeof (neighbor_rec));
  7217.   get_neighbors (nb, a_ref);
  7218.   FORLIM = atom[a_ref - 1].neighbor_count;
  7219.   for (i = 0; i < FORLIM; i++)
  7220.     {
  7221.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  7222.         {
  7223.           strcpy (nb_el, atom[nb[i] - 1].element);
  7224.           if (!strcmp (nb_el, "C "))
  7225.             c_count++;
  7226.           else if (strcmp (nb_el, "H ") /*&& strcmp (nb_el, "D ") */  &&
  7227.                    strcmp (nb_el, "LP"))
  7228.             /* v0.3n: D */
  7229.             het_count++;
  7230.           if (is_hydroxy (a_ref, nb[i]))
  7231.             oh_count++;
  7232.           if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]))
  7233.             /* fixed in v0.3b */
  7234.             or_count++;
  7235.           if (!strcmp (nb_el, "N "))
  7236.             n_count++;
  7237.           if (!strcmp (nb_el, "F ") || !strcmp (nb_el, "CL") ||
  7238.               !strcmp (nb_el, "BR") || !strcmp (nb_el, "I ")
  7239.               || !strcmp (nb_el, "AT"))
  7240.             hal_count++;
  7241.         }
  7242.     }
  7243.   het_count = oh_count + or_count + hal_count + n_count;
  7244.   /* fixed in v0.3b */
  7245.   if (c_count != 1 || het_count != 2)
  7246.     return;
  7247.   fg[fg_boronic_acid_deriv - 1] = true;
  7248.   if (oh_count == 2)
  7249.     fg[fg_boronic_acid - 1] = true;
  7250.   if (or_count > 0)
  7251.     fg[fg_boronic_acid_ester - 1] = true;
  7252. }
  7253.  
  7254.  
  7255. static void
  7256. chk_ammon (a_ref)
  7257.      int a_ref;
  7258. {
  7259.   int i;
  7260.   neighbor_rec nb;
  7261.   str2 nb_el;
  7262.   int het_count = 0, o_count = 0, or_count = 0, r_count = 0;
  7263.   char bt;                      /* v0.3k */
  7264.   float bo_sum = 0.0;
  7265.   boolean ha;
  7266.   int FORLIM;
  7267.  
  7268.   memset (nb, 0, sizeof (neighbor_rec));
  7269.   if (strcmp (atom[a_ref - 1].atype, "N3+")
  7270.       && atom[a_ref - 1].formal_charge == 0)
  7271.     return;
  7272.   if (strcmp (atom[a_ref - 1].element, "N "))   /* just to be sure;  v0.3i */
  7273.     return;
  7274.   get_neighbors (nb, a_ref);
  7275.   FORLIM = atom[a_ref - 1].neighbor_count;
  7276.   for (i = 0; i < FORLIM; i++)
  7277.     {
  7278.       bt = bond[get_bond (a_ref, nb[i]) - 1].btype;     /* v0.3k */
  7279.       strcpy (nb_el, atom[nb[i] - 1].element);  /* v0.3k */
  7280.       ha = atom[nb[i] - 1].heavy;       /* v0.3k */
  7281.       if (bt == 'S')
  7282.         {
  7283.           if (ha)
  7284.             bo_sum += 1.0;
  7285.           if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  7286.               /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU"))
  7287.             {                   /* added 'D ' in v0.3n */
  7288.               het_count++;
  7289.               if (!strcmp (nb_el, "O "))
  7290.                 {
  7291.                   o_count++;
  7292.                   if (atom[nb[i] - 1].neighbor_count > 1)
  7293.                     or_count++;
  7294.                 }
  7295.             }
  7296.           if (is_alkyl (a_ref, nb[i]) || is_aryl (a_ref, nb[i]) |
  7297.               is_alkenyl (a_ref, nb[i]) || is_alkynyl (a_ref, nb[i]))
  7298.             /* v0.3k */
  7299.             r_count++;
  7300.         }
  7301.       if (bt == 'D')
  7302.         {
  7303.           if (ha)
  7304.             bo_sum += 2.0;
  7305.           if (strcmp (nb_el, "C "))
  7306.             {
  7307.               het_count += 2;
  7308.               if (!strcmp (nb_el, "O "))
  7309.                 o_count += 2;
  7310.             }
  7311.           if (!strcmp (nb_el, "C "))
  7312.             r_count++;
  7313.         }
  7314.       if (bt == 'A' && ha)
  7315.         bo_sum += 1.5;
  7316.     }                           /* v0.3k: corrected end of "for ..." loop */
  7317.   if (het_count == 0 && r_count == 4)
  7318.     fg[fg_quart_ammonium - 1] = true;
  7319.   if (het_count != 1 || atom[a_ref - 1].neighbor_count < 3)
  7320.     return;
  7321.   if (o_count == 1 && or_count == 0 && bo_sum > 3)
  7322.     fg[fg_n_oxide - 1] = true;  /* finds only aliphatic N-oxides! */
  7323.   if (((o_count == 1 && or_count == 1) || o_count == 0) &&
  7324.       atom[a_ref - 1].arom == true)
  7325.     fg[fg_quart_ammonium - 1] = true;
  7326. }
  7327.  
  7328.  
  7329. static void
  7330. swap_atoms (a1, a2)
  7331.      int *a1, *a2;
  7332. {
  7333.   int a_tmp;
  7334.  
  7335.   a_tmp = *a1;
  7336.   *a1 = *a2;
  7337.   *a2 = a_tmp;
  7338. }
  7339.  
  7340.  
  7341. static void
  7342. orient_bond (a1, a2)
  7343.      int *a1, *a2;
  7344. {
  7345.   str2 a1_el, a2_el;
  7346.  
  7347.   strcpy (a1_el, atom[*a1 - 1].element);
  7348.   strcpy (a2_el, atom[*a2 - 1].element);
  7349.   if (!strcmp (a1_el, "H ") || !strcmp (a2_el, "H ")
  7350.       || !strcmp (a1_el, "D ") || !strcmp (a2_el, "D "))
  7351.     /* v0.3n: D */
  7352.     return;
  7353.   if (!strcmp (a2_el, "C ") && strcmp (a1_el, "C "))
  7354.     swap_atoms (a1, a2);
  7355.   if (!strcmp (a2_el, a1_el))
  7356.     {
  7357.       if (hetbond_count (*a1) > hetbond_count (*a2))
  7358.         swap_atoms (a1, a2);
  7359.     }
  7360.   if (strcmp (a2_el, "C ") && strcmp (a1_el, "C ") && strcmp (a1_el, a2_el))
  7361.     {
  7362.       if (!strcmp (a1_el, "O ") || !strcmp (a2_el, "O "))
  7363.         {
  7364.           if (!strcmp (a1_el, "O "))
  7365.             swap_atoms (a1, a2);
  7366.         }
  7367.     }
  7368.   if (strcmp (a2_el, "C ") && strcmp (a1_el, "C ") && !strcmp (a1_el, a2_el))
  7369.     {
  7370.       if (atom[*a2 - 1].neighbor_count - hetbond_count (*a2) >
  7371.           atom[*a1 - 1].neighbor_count - hetbond_count (*a1))
  7372.         swap_atoms (a1, a2);
  7373.     }
  7374. }
  7375.  
  7376.  
  7377. static void
  7378. chk_imine (a_ref, a_view)
  7379.      int a_ref, a_view;
  7380. {
  7381.   /* a_ref = C, a_view = N */
  7382.   int i;
  7383.   neighbor_rec nb;
  7384.   str2 nb_el;
  7385.   int a_het = 0, a_c;
  7386.   int het_count = 0, c_count = 0, o_count = 0;  /* v0.3k */
  7387.   int FORLIM;
  7388.  
  7389.   /* v0.3k */
  7390.   if (atom[a_view - 1].neighbor_count == 1)
  7391.     {
  7392.       if (atom[a_ref - 1].arom == false)
  7393.         fg[fg_imine - 1] = true;
  7394.       return;
  7395.     }
  7396.   memset (nb, 0, sizeof (neighbor_rec));
  7397.   get_neighbors (nb, a_view);
  7398.   if (atom[a_view - 1].neighbor_count <= 1)
  7399.     return;
  7400.   FORLIM = atom[a_view - 1].neighbor_count;
  7401.   for (i = 0; i < FORLIM; i++)
  7402.     {
  7403.       if ((nb[i] != a_ref) && (bond[get_bond (a_view, nb[i]) - 1].btype ==
  7404.                                'S'))
  7405.         {
  7406.           strcpy (nb_el, atom[nb[i] - 1].element);
  7407.           if (!strcmp (nb_el, "C "))
  7408.             {
  7409.               a_c = nb[i];
  7410.               c_count++;
  7411.             }
  7412.           if (!strcmp (nb_el, "O ") || !strcmp (nb_el, "N "))
  7413.             {
  7414.               a_het = nb[i];
  7415.               het_count++;
  7416.             }
  7417.           if ((!strcmp (nb_el, "O ")
  7418.                && atom[nb[i] - 1].neighbor_count ==
  7419.                1) && (bond[get_bond (a_view, nb[i]) - 1].arom == false))
  7420.             /* v0.3k */
  7421.             o_count++;
  7422.         }
  7423.       if ((nb[i] != a_ref) && (bond[get_bond (a_view, nb[i]) - 1].btype ==
  7424.                                'D'))
  7425.         {                       /* v0.3k; make sure we do not count nitro groups in "azi" form etc. */
  7426.           strcpy (nb_el, atom[nb[i] - 1].element);
  7427.           if (!strcmp (nb_el, "O ") || !strcmp (nb_el, "N ")
  7428.               || !strcmp (nb_el, "S "))
  7429.             {
  7430.               a_het = nb[i];    /* v0.3m */
  7431.               het_count++;
  7432.             }
  7433.           if ((!strcmp (nb_el, "O ")
  7434.                && atom[nb[i] - 1].neighbor_count ==
  7435.                1) && (bond[get_bond (a_view, nb[i]) - 1].arom == false))
  7436.             /* v0.3k */
  7437.             o_count++;
  7438.         }
  7439.     }
  7440.   if (c_count == 1)
  7441.     {
  7442.       if ((is_alkyl (a_view, a_c) || is_aryl (a_view, a_c) |
  7443.            is_alkenyl (a_view, a_c) || is_alkynyl (a_view, a_c))
  7444.           && atom[a_ref - 1].arom == false && het_count == 0)
  7445.         /* v0.3k */
  7446.         fg[fg_imine - 1] = true;
  7447.     }
  7448.   if (het_count == 1)
  7449.     {
  7450.       strcpy (nb_el, atom[a_het - 1].element);
  7451.       if (!strcmp (nb_el, "O "))
  7452.         {
  7453.           if (is_hydroxy (a_view, a_het))
  7454.             fg[fg_oxime - 1] = true;
  7455.           if (is_alkoxy (a_view, a_het) || is_aryloxy (a_view, a_het) |
  7456.               is_alkenyloxy (a_view, a_het) || is_alkynyloxy (a_view, a_het))
  7457.             fg[fg_oxime_ether - 1] = true;
  7458.         }
  7459.       if (!strcmp (nb_el, "N "))
  7460.         {
  7461.           if (is_amino (a_view, a_het) || is_alkylamino (a_view, a_het) |
  7462.               is_dialkylamino (a_view, a_het) || is_alkylarylamino (a_view,
  7463.                                                                     a_het) |
  7464.               is_arylamino (a_view, a_het) || is_diarylamino (a_view, a_het))
  7465.             fg[fg_hydrazone - 1] = true;
  7466.           else
  7467.             {
  7468.               memset (nb, 0, sizeof (neighbor_rec));
  7469.               get_neighbors (nb, a_het);
  7470.               if (atom[a_het - 1].neighbor_count > 1)
  7471.                 {
  7472.                   FORLIM = atom[a_het - 1].neighbor_count;
  7473.                   for (i = 0; i < FORLIM; i++)
  7474.                     {
  7475.                       if (nb[i] != a_view)
  7476.                         {
  7477.                           if (is_carbamoyl (a_het, nb[i]))
  7478.                             fg[fg_semicarbazone - 1] = true;
  7479.                           if (is_thiocarbamoyl (a_het, nb[i]))
  7480.                             fg[fg_thiosemicarbazone - 1] = true;
  7481.                         }
  7482.                     }
  7483.                 }
  7484.             }
  7485.         }
  7486.     }                           /* v0.3k: nitro groups in "azi" form */
  7487.   /* check for semicarbazone or thiosemicarbazone */
  7488.   if (het_count == 2 && o_count == 2)
  7489.     fg[fg_nitro_compound - 1] = true;
  7490. }
  7491.  
  7492.  
  7493. static void
  7494. chk_carbonyl_deriv (a_view, a_ref)
  7495.      int a_view, a_ref;
  7496. {
  7497.   /* a_view = C */
  7498.   int i;
  7499.   neighbor_rec nb;
  7500.   str2 nb_el;
  7501.   int c_count = 0, cn_count = 0;
  7502.   char bt;                      /* new in v0.3b */
  7503.   int n_db = 0;                 /* new in v0.3b */
  7504.   int FORLIM;
  7505.  
  7506.   memset (nb, 0, sizeof (neighbor_rec));
  7507.   get_neighbors (nb, a_view);
  7508.   FORLIM = atom[a_view - 1].neighbor_count;
  7509.   /* new in v0.3b */
  7510.   for (i = 0; i < FORLIM; i++)
  7511.     {
  7512.       bt = bond[get_bond (a_view, nb[i]) - 1].btype;
  7513.       if (bt == 'S')
  7514.         {
  7515.           strcpy (nb_el, atom[nb[i] - 1].element);
  7516.           if (!strcmp (nb_el, "C "))
  7517.             {
  7518.               if (is_cyano_c (nb[i]))
  7519.                 cn_count++;
  7520.               else
  7521.                 c_count++;
  7522.             }
  7523.         }
  7524.       else
  7525.         {
  7526.           if (bt == 'D')
  7527.             n_db++;
  7528.         }
  7529.     }
  7530.   /* new in v0.3b */
  7531.   if (is_oxo_C (a_view))
  7532.     {
  7533.       fg[fg_carbonyl - 1] = true;
  7534.       if (c_count + cn_count < 2)
  7535.         {                       /* new in v0.3b (detection of ketenes) */
  7536.           if (n_db <= 1)
  7537.             fg[fg_aldehyde - 1] = true;
  7538.           else
  7539.             fg[fg_ketene - 1] = true;
  7540.         }
  7541.       if (c_count == 2)
  7542.         {
  7543.           if (atom[a_view - 1].arom)
  7544.             fg[fg_oxohetarene - 1] = true;
  7545.           else
  7546.             fg[fg_ketone - 1] = true;
  7547.         }
  7548.       if (cn_count > 0)
  7549.         fg[fg_acyl_cyanide - 1] = true;
  7550.     }
  7551.   if (is_thioxo_C (a_view))
  7552.     {
  7553.       fg[fg_thiocarbonyl - 1] = true;
  7554.       if (c_count < 2)
  7555.         fg[fg_thioaldehyde - 1] = true;
  7556.       if (c_count == 2)
  7557.         {
  7558.           if (atom[a_view - 1].arom)
  7559.             fg[fg_thioxohetarene - 1] = true;
  7560.           else
  7561.             fg[fg_thioketone - 1] = true;
  7562.         }
  7563.     }
  7564.   if (is_imino_C (a_view))
  7565.     chk_imine (a_view, a_ref);
  7566. }
  7567.  
  7568.  
  7569. static void
  7570. chk_carboxyl_deriv (a_view, a_ref)
  7571.      int a_view, a_ref;
  7572. {
  7573.   int i;
  7574.   neighbor_rec nb;
  7575.   str2 nb_el;
  7576.   int o_count = 0, n_count = 0, s_count = 0;
  7577.   int a_o = 0, a_n = 0, a_s = 0, FORLIM;
  7578.  
  7579.   memset (nb, 0, sizeof (neighbor_rec));
  7580.   get_neighbors (nb, a_view);
  7581.   FORLIM = atom[a_view - 1].neighbor_count;
  7582.   for (i = 0; i < FORLIM; i++)
  7583.     {
  7584.       if (bond[get_bond (a_view, nb[i]) - 1].btype == 'S')
  7585.         {
  7586.           strcpy (nb_el, atom[nb[i] - 1].element);
  7587.           if (strcmp (nb_el, "C "))
  7588.             {
  7589.               if (!strcmp (nb_el, "O "))
  7590.                 {
  7591.                   o_count++;
  7592.                   a_o = nb[i];
  7593.                 }
  7594.               if (!strcmp (nb_el, "N "))
  7595.                 {
  7596.                   n_count++;
  7597.                   a_n = nb[i];
  7598.                 }
  7599.               if (!strcmp (nb_el, "S "))
  7600.                 {
  7601.                   s_count++;
  7602.                   a_s = nb[i];
  7603.                 }
  7604.             }
  7605.         }
  7606.     }
  7607.   if (is_oxo_C (a_view))
  7608.     {
  7609.       if (o_count == 1)
  7610.         {                       /* anhydride is checked somewhere else */
  7611.           if (bond[get_bond (a_view, a_o) - 1].arom == false)
  7612.             fg[fg_carboxylic_acid_deriv - 1] = true;
  7613.           if (is_hydroxy (a_view, a_o))
  7614.             {
  7615.               if (atom[a_o - 1].formal_charge == 0)
  7616.                 fg[fg_carboxylic_acid - 1] = true;
  7617.               if (atom[a_o - 1].formal_charge == -1)
  7618.                 fg[fg_carboxylic_acid_salt - 1] = true;
  7619.             }
  7620.           if (is_alkoxy (a_view, a_o) || is_aryloxy (a_view, a_o) |
  7621.               is_alkenyloxy (a_view, a_o) || is_alkynyloxy (a_view, a_o))
  7622.             {
  7623.               if (bond[get_bond (a_view, a_o) - 1].arom == false)
  7624.                 fg[fg_carboxylic_acid_ester - 1] = true;
  7625.               if (bond[get_bond (a_view, a_o) - 1].ring_count > 0)
  7626.                 {
  7627.                   if (bond[get_bond (a_view, a_o) - 1].arom == true)
  7628.                     {
  7629.                       /*fg[fg_lactone_heteroarom] := true else fg[fg_lactone] := true; */
  7630.                       fg[fg_oxohetarene - 1] = true;
  7631.                     }
  7632.                   else
  7633.                     fg[fg_lactone - 1] = true;
  7634.                 }
  7635.             }
  7636.         }
  7637.       if (n_count == 1)
  7638.         {
  7639.           if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7640.             fg[fg_carboxylic_acid_deriv - 1] = true;
  7641.           else
  7642.             {
  7643.               /*fg[fg_lactam_heteroarom] := true;  (* catches also pyridazines, 1,2,3-triazines, etc. */
  7644.               fg[fg_oxohetarene - 1] = true;
  7645.             }
  7646.           if (is_amino (a_view, a_n)
  7647.               || (!strcmp (atom[a_n - 1].atype, "NAM")
  7648.                   && atom[a_n - 1].neighbor_count == 1))
  7649.             {
  7650.               fg[fg_carboxylic_acid_amide - 1] = true;
  7651.               fg[fg_carboxylic_acid_prim_amide - 1] = true;
  7652.             }
  7653.           /*if (is_alkylamino(a_view,a_n)) or (is_arylamino(a_view,a_n)) then  */
  7654.           if (is_C_monosubst_amino (a_view, a_n) &
  7655.               (!is_subst_acylamino (a_view, a_n)))
  7656.             {                   /* v0.3j */
  7657.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7658.                 fg[fg_carboxylic_acid_amide - 1] = true;
  7659.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7660.                 fg[fg_carboxylic_acid_sec_amide - 1] = true;
  7661.               if (bond[get_bond (a_view, a_n) - 1].ring_count > 0)
  7662.                 {
  7663.                   if (bond[get_bond (a_view, a_n) - 1].arom == true)
  7664.                     {
  7665.                       /*fg[fg_lactam_heteroarom]    := true else  */
  7666.                       fg[fg_oxohetarene - 1] = true;
  7667.                     }
  7668.                   else
  7669.                     fg[fg_lactam - 1] = true;
  7670.                 }
  7671.             }
  7672.           /*if (is_dialkylamino(a_view,a_n)) or (is_alkylarylamino(a_view,a_n)) or */
  7673.           /*   (is_diarylamino(a_view,a_n)) then  */
  7674.           if (is_C_disubst_amino (a_view, a_n) &
  7675.               (!is_subst_acylamino (a_view, a_n)))
  7676.             {                   /* v0.3j */
  7677.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7678.                 fg[fg_carboxylic_acid_amide - 1] = true;
  7679.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7680.                 fg[fg_carboxylic_acid_tert_amide - 1] = true;
  7681.               if (bond[get_bond (a_view, a_n) - 1].ring_count > 0)
  7682.                 {
  7683.                   if (bond[get_bond (a_view, a_n) - 1].arom == true)
  7684.                     {
  7685.                       /*fg[fg_lactam_heteroarom]    := true else  */
  7686.                       fg[fg_oxohetarene - 1] = true;
  7687.                     }
  7688.                   else
  7689.                     fg[fg_lactam - 1] = true;
  7690.                 }
  7691.             }
  7692.           if (is_hydroxylamino (a_view, a_n))
  7693.             fg[fg_hydroxamic_acid - 1] = true;
  7694.           if (is_hydrazino (a_view, a_n))
  7695.             fg[fg_carboxylic_acid_hydrazide - 1] = true;
  7696.           if (is_azido (a_view, a_n))
  7697.             fg[fg_carboxylic_acid_azide - 1] = true;
  7698.         }
  7699.       if (s_count == 1)
  7700.         {                       /* anhydride is checked somewhere else */
  7701.           if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7702.             fg[fg_thiocarboxylic_acid_deriv - 1] = true;
  7703.           if (is_sulfanyl (a_view, a_s))
  7704.             fg[fg_thiocarboxylic_acid - 1] = true;
  7705.           if (is_alkylsulfanyl (a_view, a_s) || is_arylsulfanyl (a_view, a_s))
  7706.             {
  7707.               if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7708.                 fg[fg_thiocarboxylic_acid_ester - 1] = true;
  7709.               if (bond[get_bond (a_view, a_s) - 1].ring_count > 0)
  7710.                 {
  7711.                   if (bond[get_bond (a_view, a_s) - 1].arom == true)
  7712.                     {
  7713.                       /*fg[fg_thiolactone_heteroarom] := true else fg[fg_thiolactone] := true; */
  7714.                       fg[fg_oxohetarene - 1] = true;
  7715.                     }
  7716.                   else
  7717.                     fg[fg_thiolactone - 1] = true;
  7718.                 }
  7719.             }
  7720.         }
  7721.     }                           /* end Oxo-C */
  7722.   if (is_thioxo_C (a_view))
  7723.     {
  7724.       /* fg[fg_thiocarboxylic_acid_deriv]  := true; */
  7725.       if (o_count == 1)
  7726.         {                       /* anhydride is checked somewhere else */
  7727.           if (bond[get_bond (a_view, a_o) - 1].arom == false)
  7728.             fg[fg_thiocarboxylic_acid_deriv - 1] = true;
  7729.           if (is_hydroxy (a_view, a_o))
  7730.             fg[fg_thiocarboxylic_acid - 1] = true;      /* fixed in v0.3c */
  7731.           if (is_alkoxy (a_view, a_o) || is_aryloxy (a_view, a_o))
  7732.             {
  7733.               if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7734.                 fg[fg_thiocarboxylic_acid_ester - 1] = true;
  7735.               if (bond[get_bond (a_view, a_o) - 1].ring_count > 0)
  7736.                 {
  7737.                   if (bond[get_bond (a_view, a_o) - 1].arom == true)
  7738.                     {
  7739.                       /*fg[fg_thiolactone_heteroarom] := true else fg[fg_thiolactone] := true; */
  7740.                       fg[fg_thioxohetarene - 1] = true;
  7741.                     }
  7742.                   else
  7743.                     fg[fg_thiolactone - 1] = true;
  7744.                 }
  7745.             }
  7746.         }
  7747.       if (n_count == 1)
  7748.         {
  7749.           if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7750.             fg[fg_thiocarboxylic_acid_deriv - 1] = true;
  7751.           else
  7752.             {
  7753.               /*fg[fg_thiolactam_heteroarom] := true;  (* catches also pyridazines, 1,2,3-triazines, etc. */
  7754.               fg[fg_thioxohetarene - 1] = true;
  7755.             }
  7756.           /* catches also pyridazines, 1,2,3-triazines, etc. */
  7757.           if (is_amino (a_view, a_n))
  7758.             {
  7759.               fg[fg_thiocarboxylic_acid_amide - 1] = true;
  7760.               /* fg[fg_thiocarboxylic_acid_prim_amide] := true; */
  7761.             }
  7762.           /*if (is_alkylamino(a_view,a_n)) or (is_arylamino(a_view,a_n)) then  */
  7763.           if (is_C_monosubst_amino (a_view, a_n) &
  7764.               (!is_subst_acylamino (a_view, a_n)))
  7765.             {                   /* v0.3j */
  7766.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7767.                 fg[fg_thiocarboxylic_acid_amide - 1] = true;
  7768.               /*fg[fg_thiocarboxylic_acid_sec_amide]  := true; */
  7769.               if (bond[get_bond (a_view, a_n) - 1].ring_count > 0)
  7770.                 {
  7771.                   if (bond[get_bond (a_view, a_n) - 1].arom == true)
  7772.                     {
  7773.                       /*fg[fg_thiolactam_heteroarom] := true else fg[fg_thiolactam] := true; */
  7774.                       fg[fg_thioxohetarene - 1] = true;
  7775.                     }
  7776.                   else
  7777.                     fg[fg_thiolactam - 1] = true;
  7778.                 }
  7779.             }
  7780.           /*if (is_dialkylamino(a_view,a_n)) or (is_alkylarylamino(a_view,a_n)) or */
  7781.           /*   (is_diarylamino(a_view,a_n)) then  */
  7782.           if (is_C_disubst_amino (a_view, a_n) &
  7783.               (!is_subst_acylamino (a_view, a_n)))
  7784.             {                   /* v0.3j */
  7785.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7786.                 fg[fg_thiocarboxylic_acid_amide - 1] = true;
  7787.               /*fg[fg_thiocarboxylic_acid_tert_amide] := true; */
  7788.               if (bond[get_bond (a_view, a_n) - 1].ring_count > 0)
  7789.                 {
  7790.                   if (bond[get_bond (a_view, a_n) - 1].arom == true)
  7791.                     {
  7792.                       /*fg[fg_thiolactam_heteroarom] := true else fg[fg_thiolactam] := true; */
  7793.                       fg[fg_thioxohetarene - 1] = true;
  7794.                     }
  7795.                   else
  7796.                     fg[fg_thiolactam - 1] = true;
  7797.                 }
  7798.             }
  7799.         }
  7800.       if (s_count == 1)
  7801.         {                       /* anhydride is checked somewhere else */
  7802.           if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7803.             fg[fg_thiocarboxylic_acid_deriv - 1] = true;
  7804.           if (is_sulfanyl (a_view, a_s))
  7805.             fg[fg_thiocarboxylic_acid - 1] = true;
  7806.           if (is_alkylsulfanyl (a_view, a_s) || is_arylsulfanyl (a_view, a_s))
  7807.             {
  7808.               if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7809.                 fg[fg_thiocarboxylic_acid_ester - 1] = true;
  7810.               if (bond[get_bond (a_view, a_s) - 1].ring_count > 0)
  7811.                 {
  7812.                   if (bond[get_bond (a_view, a_s) - 1].arom == true)
  7813.                     {
  7814.                       /*fg[fg_thiolactone_heteroarom] := true else fg[fg_thiolactone] := true; */
  7815.                       fg[fg_thioxohetarene - 1] = true;
  7816.                     }
  7817.                   else
  7818.                     fg[fg_thiolactone - 1] = true;
  7819.                 }
  7820.             }
  7821.         }
  7822.     }                           /* end Thioxo-C */
  7823.   if (is_true_imino_C (a_view))
  7824.     {
  7825.       if (o_count == 1)
  7826.         {
  7827.           if (bond[get_bond (a_view, a_o) - 1].arom == false)
  7828.             fg[fg_carboxylic_acid_deriv - 1] = true;
  7829.           if (is_alkoxy (a_view, a_o) || is_aryloxy (a_view, a_o))
  7830.             {
  7831.               if (bond[get_bond (a_view, a_o) - 1].arom == false)
  7832.                 fg[fg_imido_ester - 1] = true;
  7833.             }
  7834.         }
  7835.       if ((n_count == 1) && (bond[get_bond (a_view, a_n) - 1].arom == false))
  7836.         {
  7837.           if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7838.             fg[fg_carboxylic_acid_deriv - 1] = true;
  7839.           if (is_amino (a_view, a_n) || is_subst_amino (a_view, a_n))
  7840.             {
  7841.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7842.                 fg[fg_carboxylic_acid_deriv - 1] = true;
  7843.               fg[fg_carboxylic_acid_amidine - 1] = true;
  7844.             }
  7845.           if (is_hydrazino (a_view, a_n))
  7846.             {
  7847.               if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7848.                 fg[fg_carboxylic_acid_amidrazone - 1] = true;
  7849.             }
  7850.         }
  7851.       if ((n_count == 1) && (bond[get_bond (a_view, a_n) - 1].arom == true))
  7852.         /* catches also pyridazines, 1,2,3-triazines, etc. */
  7853.         fg[fg_iminohetarene - 1] = true;
  7854.       if (s_count == 1)
  7855.         {
  7856.           if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7857.             fg[fg_carboxylic_acid_deriv - 1] = true;
  7858.           if (is_alkylsulfanyl (a_view, a_s) || is_arylsulfanyl (a_view, a_s))
  7859.             {
  7860.               if (bond[get_bond (a_view, a_s) - 1].arom == false)
  7861.                 fg[fg_imido_thioester - 1] = true;
  7862.             }
  7863.         }
  7864.     }
  7865.   if (is_hydroximino_C (a_view))
  7866.     {
  7867.       if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7868.         fg[fg_carboxylic_acid_deriv - 1] = true;
  7869.       if (o_count == 1)
  7870.         {
  7871.           if (is_hydroxy (a_view, a_o))
  7872.             fg[fg_hydroxamic_acid - 1] = true;
  7873.         }
  7874.     }
  7875.   if (!is_hydrazono_C (a_view))
  7876.     return;
  7877.   if (bond[get_bond (a_view, a_n) - 1].arom == false)
  7878.     fg[fg_carboxylic_acid_deriv - 1] = true;
  7879.   if (n_count == 1)
  7880.     {
  7881.       if (is_amino (a_view, a_n) || is_subst_amino (a_view, a_n))
  7882.         fg[fg_carboxylic_acid_amidrazone - 1] = true;
  7883.     }
  7884. }
  7885.  
  7886.  
  7887. static void
  7888. chk_co2_sp2 (a_view, a_ref)
  7889.      int a_view, a_ref;
  7890. {
  7891.   int i;
  7892.   neighbor_rec nb;
  7893.   str2 nb_el;
  7894.   int o_count = 0, or_count = 0, n_count = 0, nn_count = 0, nnx_count = 0,
  7895.     s_count = 0, sr_count = 0;
  7896.   int FORLIM;
  7897.  
  7898.   memset (nb, 0, sizeof (neighbor_rec));
  7899.   get_neighbors (nb, a_view);
  7900.   FORLIM = atom[a_view - 1].neighbor_count;
  7901.   for (i = 0; i < FORLIM; i++)
  7902.     {
  7903.       if (bond[get_bond (a_view, nb[i]) - 1].btype == 'S')
  7904.         {
  7905.           strcpy (nb_el, atom[nb[i] - 1].element);
  7906.           if (strcmp (nb_el, "C "))
  7907.             {
  7908.               if (!strcmp (nb_el, "O "))
  7909.                 {
  7910.                   o_count++;
  7911.                   if (is_alkoxy (a_view, nb[i]) |
  7912.                       is_alkenyloxy (a_view, nb[i]) || is_aryloxy (a_view,
  7913.                                                                    nb[i]))
  7914.                     /* v0.3j */
  7915.                     or_count++;
  7916.                 }
  7917.               if (!strcmp (nb_el, "N "))
  7918.                 {
  7919.                   n_count++;
  7920.                   if (is_hydrazino (a_view, nb[i]))
  7921.                     nn_count++;
  7922.                   if (is_subst_hydrazino (a_view, nb[i]))       /* more general... */
  7923.                     nnx_count++;
  7924.                 }
  7925.               if (!strcmp (nb_el, "S "))
  7926.                 {
  7927.                   s_count++;
  7928.                   if (is_alkylsulfanyl (a_view, nb[i]) |
  7929.                       is_arylsulfanyl (a_view, nb[i]))
  7930.                     sr_count++;
  7931.                 }
  7932.             }
  7933.         }
  7934.     }
  7935.   if (is_oxo_C (a_view))
  7936.     {
  7937.       if (o_count == 2)
  7938.         {
  7939.           fg[fg_carbonic_acid_deriv - 1] = true;
  7940.           if (or_count == 1)
  7941.             fg[fg_carbonic_acid_monoester - 1] = true;
  7942.           if (or_count == 2)
  7943.             fg[fg_carbonic_acid_diester - 1] = true;
  7944.         }
  7945.       if (o_count == 1 && s_count == 1)
  7946.         {
  7947.           fg[fg_thiocarbonic_acid_deriv - 1] = true;
  7948.           if (or_count + sr_count == 1)
  7949.             fg[fg_thiocarbonic_acid_monoester - 1] = true;
  7950.           if (or_count + sr_count == 2)
  7951.             fg[fg_thiocarbonic_acid_diester - 1] = true;
  7952.         }
  7953.       if (s_count == 2)
  7954.         {
  7955.           fg[fg_thiocarbonic_acid_deriv - 1] = true;
  7956.           if (sr_count == 1)
  7957.             fg[fg_thiocarbonic_acid_monoester - 1] = true;
  7958.           if (sr_count == 2)
  7959.             fg[fg_thiocarbonic_acid_diester - 1] = true;
  7960.         }
  7961.       if (o_count == 1 && n_count == 1)
  7962.         {
  7963.           fg[fg_carbamic_acid_deriv - 1] = true;
  7964.           if (or_count == 0)
  7965.             fg[fg_carbamic_acid - 1] = true;
  7966.           if (or_count == 1)
  7967.             fg[fg_carbamic_acid_ester - 1] = true;
  7968.         }
  7969.       if (s_count == 1 && n_count == 1)
  7970.         {
  7971.           fg[fg_thiocarbamic_acid_deriv - 1] = true;
  7972.           if (sr_count == 0)
  7973.             fg[fg_thiocarbamic_acid - 1] = true;
  7974.           if (sr_count == 1)
  7975.             fg[fg_thiocarbamic_acid_ester - 1] = true;
  7976.         }
  7977.       if (n_count == 2)
  7978.         {
  7979.           if (nn_count == 1)
  7980.             fg[fg_semicarbazide - 1] = true;
  7981.           else
  7982.             {
  7983.               if (nnx_count == 0)       /* excludes semicarbazones */
  7984.                 fg[fg_urea - 1] = true;
  7985.             }
  7986.         }
  7987.     }                           /* end Oxo-C */
  7988.   if (is_thioxo_C (a_view))
  7989.     {
  7990.       if (o_count == 2)
  7991.         {
  7992.           fg[fg_thiocarbonic_acid_deriv - 1] = true;
  7993.           if (or_count == 1)
  7994.             fg[fg_thiocarbonic_acid_monoester - 1] = true;
  7995.           if (or_count == 2)
  7996.             fg[fg_thiocarbonic_acid_diester - 1] = true;
  7997.         }
  7998.       if (o_count == 1 && s_count == 1)
  7999.         {
  8000.           fg[fg_thiocarbonic_acid_deriv - 1] = true;
  8001.           if (or_count + sr_count == 1)
  8002.             fg[fg_thiocarbonic_acid_monoester - 1] = true;
  8003.           if (or_count + sr_count == 2)
  8004.             fg[fg_thiocarbonic_acid_diester - 1] = true;
  8005.         }
  8006.       if (s_count == 2)
  8007.         {
  8008.           fg[fg_thiocarbonic_acid_deriv - 1] = true;
  8009.           if (sr_count == 1)
  8010.             fg[fg_thiocarbonic_acid_monoester - 1] = true;
  8011.           if (sr_count == 2)
  8012.             fg[fg_thiocarbonic_acid_diester - 1] = true;
  8013.         }
  8014.       if (o_count == 1 && n_count == 1)
  8015.         {
  8016.           fg[fg_thiocarbamic_acid_deriv - 1] = true;
  8017.           if (or_count == 0)
  8018.             fg[fg_thiocarbamic_acid - 1] = true;
  8019.           if (or_count == 1)
  8020.             fg[fg_thiocarbamic_acid_ester - 1] = true;
  8021.         }
  8022.       if (s_count == 1 && n_count == 1)
  8023.         {
  8024.           fg[fg_thiocarbamic_acid_deriv - 1] = true;
  8025.           if (sr_count == 0)
  8026.             fg[fg_thiocarbamic_acid - 1] = true;
  8027.           if (sr_count == 1)
  8028.             fg[fg_thiocarbamic_acid_ester - 1] = true;
  8029.         }
  8030.       if (n_count == 2)
  8031.         {
  8032.           if (nn_count == 1)
  8033.             fg[fg_thiosemicarbazide - 1] = true;
  8034.           else
  8035.             {
  8036.               if (nnx_count == 0)       /* excludes thiosemicarbazones */
  8037.                 fg[fg_thiourea - 1] = true;
  8038.             }
  8039.         }
  8040.     }                           /* end Thioxo-C */
  8041.   if (!
  8042.       (is_true_imino_C (a_view) &
  8043.        (bond[get_bond (a_view, a_ref) - 1].arom == false)))
  8044.     {
  8045.       return;
  8046.     }                           /* end Imino-C */
  8047.   if (o_count == 1 && n_count == 1)
  8048.     fg[fg_isourea - 1] = true;
  8049.   if (s_count == 1 && n_count == 1)
  8050.     fg[fg_isothiourea - 1] = true;
  8051.   if (n_count == 2)
  8052.     fg[fg_guanidine - 1] = true;
  8053. }
  8054.  
  8055.  
  8056. static void
  8057. chk_co2_sp (a_view, a_ref)
  8058.      int a_view, a_ref;
  8059. {
  8060.   int i;
  8061.   neighbor_rec nb;
  8062.   str2 nb_el;
  8063.   int o_count = 0, n_count = 0, s_count = 0;
  8064.   int FORLIM;
  8065.  
  8066.   memset (nb, 0, sizeof (neighbor_rec));
  8067.   get_neighbors (nb, a_view);
  8068.   FORLIM = atom[a_view - 1].neighbor_count;
  8069.   for (i = 0; i < FORLIM; i++)
  8070.     {
  8071.       if (bond[get_bond (a_view, nb[i]) - 1].btype == 'D')
  8072.         {
  8073.           strcpy (nb_el, atom[nb[i] - 1].element);
  8074.           if (strcmp (nb_el, "C "))
  8075.             {
  8076.               if (!strcmp (nb_el, "O "))
  8077.                 o_count++;
  8078.               if (!strcmp (nb_el, "N "))
  8079.                 n_count++;
  8080.               if (!strcmp (nb_el, "S "))
  8081.                 s_count++;
  8082.             }
  8083.         }
  8084.     }
  8085.   if (o_count + s_count == 2)   /* new in v0.3b */
  8086.     fg[fg_co2_deriv - 1] = true;
  8087.   if (o_count == 1 && n_count == 1)
  8088.     fg[fg_isocyanate - 1] = true;
  8089.   if (s_count == 1 && n_count == 1)
  8090.     fg[fg_isothiocyanate - 1] = true;
  8091.   if (n_count == 2)
  8092.     fg[fg_carbodiimide - 1] = true;
  8093. }
  8094.  
  8095.  
  8096. static void
  8097. chk_triple (a1, a2)
  8098.      int a1, a2;
  8099. {
  8100.   str2 a1_el, a2_el;
  8101.  
  8102.   strcpy (a1_el, atom[a1 - 1].element);
  8103.   strcpy (a2_el, atom[a2 - 1].element);
  8104.   if ((!strcmp (a1_el, "C ") && !strcmp (a2_el, "C ")) &
  8105.       (bond[get_bond (a1, a2) - 1].arom == false))
  8106.     fg[fg_alkyne - 1] = true;
  8107.   if (is_nitrile (a1, a2))
  8108.     fg[fg_nitrile - 1] = true;
  8109.   if (is_isonitrile (a1, a2))
  8110.     fg[fg_isonitrile - 1] = true;
  8111.   if (is_cyanate (a1, a2))
  8112.     fg[fg_cyanate - 1] = true;
  8113.   if (is_thiocyanate (a1, a2))
  8114.     fg[fg_thiocyanate - 1] = true;
  8115. }
  8116.  
  8117.  
  8118. static void
  8119. chk_ccx (a_view, a_ref)
  8120.      int a_view, a_ref;
  8121. {
  8122.   int i;
  8123.   neighbor_rec nb;
  8124.   int oh_count = 0, or_count = 0, n_count = 0;
  8125.   int FORLIM;
  8126.  
  8127.   memset (nb, 0, sizeof (neighbor_rec));
  8128.   get_neighbors (nb, a_ref);
  8129.   FORLIM = atom[a_ref - 1].neighbor_count;
  8130.   for (i = 0; i < FORLIM; i++)
  8131.     {
  8132.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  8133.         {
  8134.           if (is_hydroxy (a_ref, nb[i]))
  8135.             oh_count++;
  8136.           if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]) |
  8137.               is_siloxy (a_ref, nb[i]))
  8138.             or_count++;
  8139.           if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  8140.               !strcmp (atom[nb[i] - 1].atype, "NAM"))
  8141.             n_count++;
  8142.         }
  8143.     }
  8144.   if (oh_count == 1)
  8145.     fg[fg_enol - 1] = true;
  8146.   if (or_count == 1)
  8147.     fg[fg_enolether - 1] = true;
  8148.   if (n_count == 1)
  8149.     fg[fg_enamine - 1] = true;
  8150.   /* new in v0.2f   (regard anything else as an alkene) */
  8151.   if (oh_count + or_count + n_count == 0)
  8152.     fg[fg_alkene - 1] = true;
  8153. }
  8154.  
  8155.  
  8156. static void
  8157. chk_xccx (a_view, a_ref)
  8158.      int a_view, a_ref;
  8159. {
  8160.   int i;
  8161.   neighbor_rec nb;
  8162.   int oh_count = 0, or_count = 0, n_count = 0;
  8163.   int FORLIM;
  8164.  
  8165.   memset (nb, 0, sizeof (neighbor_rec));
  8166.   get_neighbors (nb, a_view);
  8167.   FORLIM = atom[a_view - 1].neighbor_count;
  8168.   for (i = 0; i < FORLIM; i++)
  8169.     {
  8170.       if (bond[get_bond (a_view, nb[i]) - 1].btype == 'S')
  8171.         {
  8172.           if (is_hydroxy (a_view, nb[i]))
  8173.             oh_count++;
  8174.           if (is_alkoxy (a_view, nb[i]) || is_aryloxy (a_view, nb[i]) |
  8175.               is_siloxy (a_view, nb[i]))
  8176.             or_count++;
  8177.           if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  8178.               !strcmp (atom[nb[i] - 1].atype, "NAM"))
  8179.             n_count++;
  8180.         }
  8181.     }
  8182.   memset (nb, 0, sizeof (neighbor_rec));
  8183.   get_neighbors (nb, a_ref);
  8184.   FORLIM = atom[a_ref - 1].neighbor_count;
  8185.   for (i = 0; i < FORLIM; i++)
  8186.     {
  8187.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  8188.         {
  8189.           if (is_hydroxy (a_ref, nb[i]))
  8190.             oh_count++;
  8191.           if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]) |
  8192.               is_siloxy (a_ref, nb[i]))
  8193.             or_count++;
  8194.           if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  8195.               !strcmp (atom[nb[i] - 1].atype, "NAM"))
  8196.             n_count++;
  8197.         }
  8198.     }
  8199.   if (oh_count == 2)
  8200.     fg[fg_enediol - 1] = true;
  8201.   /* new in v0.2f   (regard anything else as an alkene) */
  8202.   if (oh_count + or_count + n_count == 0)
  8203.     fg[fg_alkene - 1] = true;
  8204. }
  8205.  
  8206.  
  8207. static void
  8208. chk_n_o_dbl (a1, a2)
  8209.      int a1, a2;
  8210. {
  8211.   int i;
  8212.   neighbor_rec nb;
  8213.   str2 nb_el;
  8214.   int or_count = 0, n_count = 0, c_count = 0;
  8215.   int b;                        /* v0.3j */
  8216.   int het_count = 0;            /* v0.3k */
  8217.   char bt;                      /* v0.3k */
  8218.   float bo_sum = 0.0;           /* v0.3k */
  8219.   int FORLIM;
  8220.  
  8221.   memset (nb, 0, sizeof (neighbor_rec));
  8222.   get_neighbors (nb, a1);
  8223.   FORLIM = atom[a1 - 1].neighbor_count;
  8224.   /* v0.3k */
  8225.   /* v0.3k */
  8226.   for (i = 0; i < FORLIM; i++)
  8227.     {
  8228.       if (nb[i] != a2)
  8229.         {
  8230.           b = get_bond (a1, nb[i]);     /* v0.3j */
  8231.           strcpy (nb_el, atom[nb[i] - 1].element);
  8232.           bt = bond[b - 1].btype;       /* v0.3k */
  8233.           if (strcmp (nb_el, "C ") && strcmp (nb_el, "H ")
  8234.               /*&&  strcmp (nb_el, "D ") */  && strcmp (nb_el, "DU")
  8235.               && strcmp (nb_el, "LP") && bond[b - 1].arom == false)
  8236.             /* added 'D ' in v0.3n */
  8237.             het_count++;
  8238.           /* v0.3k: ignore hetero atoms */
  8239.           /* in aromatic rings like isoxazole  */
  8240.           if (bt == 'S')
  8241.             bo_sum += 1.0;
  8242.           if (bt == 'D')
  8243.             bo_sum += 2.0;
  8244.           if (bt == 'A')
  8245.             bo_sum += 1.5;
  8246.           if (!strcmp (nb_el, "O "))
  8247.             or_count++;
  8248.           if (!strcmp (nb_el, "N "))
  8249.             n_count++;
  8250.           if (!strcmp (nb_el, "C ") && bond[b - 1].btype == 'S')        /* v0.3k */
  8251.             c_count++;
  8252.           /* if (is_alkyl(a1,nb[i])) or (is_aryl(a1,nb[i])) then inc(c_count); */
  8253.         }
  8254.     }
  8255.   if (or_count + n_count + c_count == 1 && atom[a1 - 1].neighbor_count == 2)
  8256.     {                           /* excludes nitro etc. */
  8257.       if (or_count == 1)
  8258.         fg[fg_nitrite - 1] = true;
  8259.       if (c_count == 1)
  8260.         fg[fg_nitroso_compound - 1] = true;
  8261.       if (n_count == 1)         /* instead of nitrosamine  v0.3j */
  8262.         fg[fg_nitroso_compound - 1] = true;
  8263.       /*if (n_count = 1) then fg[fg_nitrosamine]   := true;  (* still missing */
  8264.     }
  8265.   /*if ((c_count > 1) and (or_count = 0) and (n_count = 0)) then */
  8266.   /*  begin */
  8267.   /*    fg[fg_n_oxide] := true; */
  8268.   /*  end; */
  8269.   /* new approach in v0.3k */
  8270.   if (het_count == 0 && bo_sum > 2)     /* =O does not count! */
  8271.     fg[fg_n_oxide - 1] = true;
  8272. }
  8273.  
  8274.  
  8275. static void
  8276. chk_sulfoxide (a1, a2)
  8277.      int a1, a2;
  8278. {
  8279.   int i;
  8280.   neighbor_rec nb;
  8281.   str2 nb_el;
  8282.   int o_count = 0, c_count = 0;
  8283.   int FORLIM;
  8284.  
  8285.   memset (nb, 0, sizeof (neighbor_rec));
  8286.   get_neighbors (nb, a1);
  8287.   FORLIM = atom[a1 - 1].neighbor_count;
  8288.   for (i = 0; i < FORLIM; i++)
  8289.     {
  8290.       strcpy (nb_el, atom[nb[i] - 1].element);
  8291.       if (!strcmp (nb_el, "O "))
  8292.         o_count++;
  8293.       if (is_alkyl (a1, nb[i]) || is_aryl (a1, nb[i]))
  8294.         c_count++;
  8295.     }
  8296.   if (o_count == 1 && c_count == 2)
  8297.     fg[fg_sulfoxide - 1] = true;
  8298. }
  8299.  
  8300.  
  8301. static void
  8302. chk_double (a1, a2)
  8303.      int a1, a2;
  8304. {
  8305.   str2 a1_el, a2_el;
  8306.  
  8307.   strcpy (a1_el, atom[a1 - 1].element);
  8308.   strcpy (a2_el, atom[a2 - 1].element);
  8309.   if ((!strcmp (a1_el, "C ") && strcmp (a2_el, "C ")) &
  8310.       (bond[get_bond (a1, a2) - 1].arom == false))
  8311.     {
  8312.       if (hetbond_count (a1) == 2)
  8313.         chk_carbonyl_deriv (a1, a2);
  8314.       if (hetbond_count (a1) == 3)
  8315.         chk_carboxyl_deriv (a1, a2);
  8316.       if (hetbond_count (a1) == 4)
  8317.         {
  8318.           if (!strcmp (atom[a1 - 1].atype, "C2 "))
  8319.             chk_co2_sp2 (a1, a2);
  8320.           if (!strcmp (atom[a1 - 1].atype, "C1 "))
  8321.             chk_co2_sp (a1, a2);
  8322.         }
  8323.     }                           /* end C=X */
  8324.   if ((!strcmp (atom[a1 - 1].atype, "C2 ")
  8325.        && !strcmp (atom[a2 - 1].atype,
  8326.                    "C2 ")) && (bond[get_bond (a1, a2) - 1].arom == false))
  8327.     {
  8328.       if ((hetbond_count (a1) == 0) && (hetbond_count (a2) == 2))
  8329.         fg[fg_ketene_acetal_deriv - 1] = true;
  8330.       if ((hetbond_count (a1) == 0) && (hetbond_count (a2) == 1))
  8331.         chk_ccx (a1, a2);
  8332.       if ((hetbond_count (a1) == 1) && (hetbond_count (a2) == 1))
  8333.         chk_xccx (a1, a2);
  8334.       if (((hetbond_count (a1) == 0) && (hetbond_count (a2) == 0)) &&
  8335.           atom[a1 - 1].arom == false && atom[a2 - 1].arom == false)
  8336.         fg[fg_alkene - 1] = true;
  8337.     }
  8338.   if (((!strcmp (a1_el, "N ")
  8339.         && !strcmp (a2_el,
  8340.                     "N ")) && (hetbond_count (a1) ==
  8341.                                2) && (hetbond_count (a2) ==
  8342.                                       2) && (bond[get_bond (a1, a2) -
  8343.                                                   1].arom == false))
  8344.       && atom[a1 - 1].neighbor_count == 2 && atom[a2 - 1].neighbor_count == 2)
  8345.     fg[fg_azo_compound - 1] = true;
  8346.   if (!strcmp (a1_el, "N ") && !strcmp (a2_el, "O "))
  8347.     chk_n_o_dbl (a1, a2);
  8348.   if (!strcmp (a1_el, "S ") && !strcmp (a2_el, "O "))
  8349.     chk_sulfoxide (a1, a2);
  8350. }
  8351.  
  8352.  
  8353. static void
  8354. chk_c_hal (a1, a2)
  8355.      int a1, a2;
  8356. {
  8357.   str2 a2_el;
  8358.  
  8359.   strcpy (a2_el, atom[a2 - 1].element);
  8360.   fg[fg_halogen_deriv - 1] = true;
  8361.   if (atom[a1 - 1].arom)
  8362.     {
  8363.       fg[fg_aryl_halide - 1] = true;
  8364.       if (!strcmp (a2_el, "F "))
  8365.         fg[fg_aryl_fluoride - 1] = true;
  8366.       if (!strcmp (a2_el, "CL"))
  8367.         fg[fg_aryl_chloride - 1] = true;
  8368.       if (!strcmp (a2_el, "BR"))
  8369.         fg[fg_aryl_bromide - 1] = true;
  8370.       if (!strcmp (a2_el, "I "))
  8371.         fg[fg_aryl_iodide - 1] = true;
  8372.       return;
  8373.     }
  8374.   if ((strcmp (atom[a1 - 1].atype, "C3 ") == 0) && (hetbond_count (a1) <= 2))
  8375.     {                           /* alkyl halides */
  8376.       fg[fg_alkyl_halide - 1] = true;
  8377.       if (!strcmp (a2_el, "F "))
  8378.         fg[fg_alkyl_fluoride - 1] = true;
  8379.       if (!strcmp (a2_el, "CL"))
  8380.         fg[fg_alkyl_chloride - 1] = true;
  8381.       if (!strcmp (a2_el, "BR"))
  8382.         fg[fg_alkyl_bromide - 1] = true;
  8383.       if (!strcmp (a2_el, "I "))
  8384.         fg[fg_alkyl_iodide - 1] = true;
  8385.     }
  8386.   if ((strcmp (atom[a1 - 1].atype, "C2 ") == 0) && (hetbond_count (a1) == 3))
  8387.     {                           /* acyl halides and related compounds */
  8388.       if (is_oxo_C (a1))
  8389.         {
  8390.           fg[fg_acyl_halide - 1] = true;
  8391.           if (!strcmp (a2_el, "F "))
  8392.             fg[fg_acyl_fluoride - 1] = true;
  8393.           if (!strcmp (a2_el, "CL"))
  8394.             fg[fg_acyl_chloride - 1] = true;
  8395.           if (!strcmp (a2_el, "BR"))
  8396.             fg[fg_acyl_bromide - 1] = true;
  8397.           if (!strcmp (a2_el, "I "))
  8398.             fg[fg_acyl_iodide - 1] = true;
  8399.         }
  8400.       if (is_thioxo_C (a1))
  8401.         fg[fg_thiocarboxylic_acid_deriv - 1] = true;
  8402.       if (is_imino_C (a1))
  8403.         fg[fg_imidoyl_halide - 1] = true;
  8404.     }
  8405.   if (!
  8406.       ((strcmp (atom[a1 - 1].atype, "C2 ") == 0)
  8407.        && (hetbond_count (a1) == 4)))
  8408.     /* chloroformates etc. */
  8409.     return;
  8410.   /* still missing: polyhalogen compounds (-CX2H, -CX3) */
  8411.   fg[fg_co2_deriv - 1] = true;
  8412.   if (is_oxo_C (a1))
  8413.     {
  8414.       fg[fg_carbonic_acid_deriv - 1] = true;
  8415.       if (is_alkoxycarbonyl (a2, a1) || is_aryloxycarbonyl (a2, a1))
  8416.         fg[fg_carbonic_acid_ester_halide - 1] = true;
  8417.       if (is_carbamoyl (a2, a1))
  8418.         {
  8419.           fg[fg_carbamic_acid_deriv - 1] = true;
  8420.           fg[fg_carbamic_acid_halide - 1] = true;
  8421.         }
  8422.     }
  8423.   if (!is_thioxo_C (a1))
  8424.     return;
  8425.   fg[fg_thiocarbonic_acid_deriv - 1] = true;
  8426.   if (is_alkoxythiocarbonyl (a2, a1) || is_aryloxythiocarbonyl (a2, a1))
  8427.     fg[fg_thiocarbonic_acid_ester_halide - 1] = true;
  8428.   if (is_thiocarbamoyl (a2, a1))
  8429.     {
  8430.       fg[fg_thiocarbamic_acid_deriv - 1] = true;
  8431.       fg[fg_thiocarbamic_acid_halide - 1] = true;
  8432.       /* end of non-aromatic halogen compounds */
  8433.     }
  8434. }
  8435.  
  8436.  
  8437. static void
  8438. chk_c_o (a1, a2)
  8439.      int a1, a2;
  8440. {
  8441.   /* ignore heteroaromatic rings (like furan, thiophene, etc.) */
  8442.   if (bond[get_bond (a1, a2) - 1].arom == true)
  8443.     return;
  8444.   if (is_true_alkyl (a2, a1) && is_hydroxy (a1, a2))
  8445.     {
  8446.       fg[fg_hydroxy - 1] = true;
  8447.       fg[fg_alcohol - 1] = true;
  8448.       if (atom[a1 - 1].neighbor_count <= 2)
  8449.         fg[fg_prim_alcohol - 1] = true;
  8450.       if (atom[a1 - 1].neighbor_count == 3)
  8451.         fg[fg_sec_alcohol - 1] = true;
  8452.       if (atom[a1 - 1].neighbor_count == 4)
  8453.         fg[fg_tert_alcohol - 1] = true;
  8454.     }
  8455.   if (is_aryl (a2, a1) && is_hydroxy (a1, a2))
  8456.     {
  8457.       fg[fg_hydroxy - 1] = true;
  8458.       fg[fg_phenol - 1] = true;
  8459.     }
  8460.   if (is_true_alkyl (a2, a1) && is_true_alkoxy (a1, a2))
  8461.     {
  8462.       fg[fg_ether - 1] = true;
  8463.       fg[fg_dialkylether - 1] = true;
  8464.     }
  8465.   if ((is_true_alkyl (a2, a1) && is_aryloxy (a1, a2)) |
  8466.       (is_aryl (a2, a1) && is_true_alkoxy (a1, a2)))
  8467.     {
  8468.       fg[fg_ether - 1] = true;
  8469.       fg[fg_alkylarylether - 1] = true;
  8470.     }
  8471.   if (is_aryl (a2, a1) && is_aryloxy (a1, a2))
  8472.     {
  8473.       fg[fg_ether - 1] = true;
  8474.       fg[fg_diarylether - 1] = true;
  8475.     }
  8476.   if ((is_true_alkyl (a2, a1) || is_aryl (a2, a1)) && is_alkynyloxy (a1, a2))
  8477.     {
  8478.       fg[fg_ether - 1] = true;
  8479.       ether_generic = true;
  8480.     }
  8481.   if (is_alkynyl (a2, a1) && is_hydroxy (a1, a2))
  8482.     {
  8483.       fg[fg_hydroxy - 1] = true;
  8484.       hydroxy_generic = true;
  8485.     }
  8486.  
  8487. }
  8488.  
  8489.  
  8490. static void
  8491. chk_c_s (a1, a2)
  8492.      int a1, a2;
  8493. {
  8494.   int i;
  8495.   neighbor_rec nb;
  8496.   str2 nb_el;
  8497.   int o_count = 0, oh_count = 0, or_count = 0, n_count = 0, c_count = 0,
  8498.     hal_count = 0;
  8499.   int FORLIM;
  8500.  
  8501.   /* ignore heteroaromatic rings (like furan, thiophene, etc.) */
  8502.   if (bond[get_bond (a1, a2) - 1].arom == true)
  8503.     return;
  8504.   if (is_alkyl (a2, a1) && is_sulfanyl (a1, a2))
  8505.     {
  8506.       fg[fg_thiol - 1] = true;
  8507.       fg[fg_alkylthiol - 1] = true;
  8508.     }
  8509.   if (is_aryl (a2, a1) && is_sulfanyl (a1, a2))
  8510.     {
  8511.       fg[fg_thiol - 1] = true;
  8512.       fg[fg_arylthiol - 1] = true;
  8513.     }
  8514.   if (is_true_alkyl (a2, a1) && is_true_alkylsulfanyl (a1, a2))
  8515.     fg[fg_thioether - 1] = true;
  8516.   if ((is_true_alkyl (a2, a1) && is_arylsulfanyl (a1, a2)) |
  8517.       (is_aryl (a2, a1) && is_true_alkylsulfanyl (a1, a2)))
  8518.     fg[fg_thioether - 1] = true;
  8519.   if (is_aryl (a2, a1) && is_arylsulfanyl (a1, a2))
  8520.     fg[fg_thioether - 1] = true;
  8521.   /* check for sulfinic/sulfenic acid derivatives */
  8522.   memset (nb, 0, sizeof (neighbor_rec));
  8523.   get_neighbors (nb, a2);
  8524.   FORLIM = atom[a2 - 1].neighbor_count;
  8525.   for (i = 0; i < FORLIM; i++)
  8526.     {
  8527.       strcpy (nb_el, atom[nb[i] - 1].element);
  8528.       if (is_alkyl (a2, nb[i]) || is_aryl (a2, nb[i]))
  8529.         c_count++;
  8530.       if (is_hydroxy (a2, nb[i]))
  8531.         oh_count++;
  8532.       if (is_alkoxy (a2, nb[i]) || is_aryloxy (a2, nb[i]))
  8533.         or_count++;
  8534.       if (is_amino (a2, nb[i]) || is_subst_amino (a2, nb[i]))
  8535.         n_count++;
  8536.       if (!strcmp (nb_el, "F ") || !strcmp (nb_el, "CL") ||
  8537.           !strcmp (nb_el, "BR") || !strcmp (nb_el, "I "))
  8538.         hal_count++;
  8539.       if (!strcmp (nb_el, "O "))
  8540.         o_count++;
  8541.     }
  8542.   if (c_count != 1)
  8543.     return;
  8544.   if (atom[a2 - 1].neighbor_count == 3 && o_count - oh_count - or_count == 1)
  8545.     {                           /* sulfinic acid && derivs */
  8546.       fg[fg_sulfinic_acid_deriv - 1] = true;
  8547.       if (oh_count == 1)
  8548.         fg[fg_sulfinic_acid - 1] = true;
  8549.       if (or_count == 1)
  8550.         fg[fg_sulfinic_acid_ester - 1] = true;
  8551.       if (hal_count == 1)
  8552.         fg[fg_sulfinic_acid_halide - 1] = true;
  8553.       if (n_count == 1)
  8554.         fg[fg_sulfinic_acid_amide - 1] = true;
  8555.     }
  8556.   if (atom[a2 - 1].neighbor_count != 2 || o_count - oh_count - or_count != 0)
  8557.     /* sulfenic acid && derivs */
  8558.     return;
  8559.  
  8560.   fg[fg_sulfenic_acid_deriv - 1] = true;
  8561.   if (oh_count == 1)
  8562.     fg[fg_sulfenic_acid - 1] = true;
  8563.   if (or_count == 1)
  8564.     fg[fg_sulfenic_acid_ester - 1] = true;
  8565.   if (hal_count == 1)
  8566.     fg[fg_sulfenic_acid_halide - 1] = true;
  8567.   if (n_count == 1)
  8568.     fg[fg_sulfenic_acid_amide - 1] = true;
  8569. }
  8570.  
  8571.  
  8572. static void
  8573. chk_c_n (a1, a2)
  8574.      int a1, a2;
  8575. {
  8576.   /* ignore heteroaromatic rings (like furan, thiophene, pyrrol, etc.) */
  8577.   if (atom[a2 - 1].arom == true)
  8578.     return;
  8579.   if (is_true_alkyl (a2, a1) && is_amino (a1, a2))
  8580.     {
  8581.       fg[fg_amine - 1] = true;
  8582.       fg[fg_prim_amine - 1] = true;
  8583.       fg[fg_prim_aliph_amine - 1] = true;
  8584.     }
  8585.   if (is_aryl (a2, a1) && is_amino (a1, a2))
  8586.     {
  8587.       fg[fg_amine - 1] = true;
  8588.       fg[fg_prim_amine - 1] = true;
  8589.       fg[fg_prim_arom_amine - 1] = true;
  8590.     }
  8591.   if (is_true_alkyl (a2, a1) && is_true_alkylamino (a1, a2))
  8592.     {
  8593.       fg[fg_amine - 1] = true;
  8594.       fg[fg_sec_amine - 1] = true;
  8595.       fg[fg_sec_aliph_amine - 1] = true;
  8596.     }
  8597.   if (is_aryl (a2, a1) && is_true_alkylamino (a1, a2))
  8598.     {
  8599.       fg[fg_amine - 1] = true;
  8600.       fg[fg_sec_amine - 1] = true;
  8601.       fg[fg_sec_mixed_amine - 1] = true;
  8602.     }
  8603.   if (is_aryl (a2, a1) && is_arylamino (a1, a2))
  8604.     {
  8605.       fg[fg_amine - 1] = true;
  8606.       fg[fg_sec_amine - 1] = true;
  8607.       fg[fg_sec_arom_amine - 1] = true;
  8608.     }
  8609.   if (is_true_alkyl (a2, a1) && is_true_dialkylamino (a1, a2))
  8610.     {
  8611.       fg[fg_amine - 1] = true;
  8612.       fg[fg_tert_amine - 1] = true;
  8613.       fg[fg_tert_aliph_amine - 1] = true;
  8614.     }
  8615.   if ((is_true_alkyl (a2, a1) && is_diarylamino (a1, a2)) |
  8616.       (is_aryl (a2, a1) && is_true_dialkylamino (a1, a2)))
  8617.     {
  8618.       fg[fg_amine - 1] = true;
  8619.       fg[fg_tert_amine - 1] = true;
  8620.       fg[fg_tert_mixed_amine - 1] = true;
  8621.     }
  8622.   if (is_aryl (a2, a1) && is_diarylamino (a1, a2))
  8623.     {
  8624.       fg[fg_amine - 1] = true;
  8625.       fg[fg_tert_amine - 1] = true;
  8626.       fg[fg_tert_arom_amine - 1] = true;
  8627.     }
  8628.   if ((is_alkyl (a2, a1) || is_aryl (a2, a1) || is_alkenyl (a2, a1) |
  8629.        is_alkynyl (a2, a1)) && is_hydroxylamino (a1, a2) && (is_acyl_gen (a2,
  8630.                                                                           a1)
  8631.                                                              == false))
  8632.     /* v0.3k */
  8633.     fg[fg_hydroxylamine - 1] = true;
  8634.   /* v0.3k */
  8635.   /* v0.3k  */
  8636.   if ((is_alkyl (a2, a1) || is_aryl (a2, a1) || is_acyl (a2, a1) |
  8637.        is_alkenyl (a2, a1) || is_alkynyl (a2, a1)) && is_hydrazino (a1, a2))
  8638.     fg[fg_hydrazine - 1] = true;
  8639.   if ((is_alkyl (a2, a1) || is_aryl (a2, a1) || is_alkenyl (a2, a1) |
  8640.        is_alkynyl (a2, a1)) && is_azido (a1, a2))
  8641.     /* v0.3k */
  8642.     fg[fg_azide - 1] = true;
  8643.   if ((is_alkyl (a2, a1) || is_aryl (a2, a1) || is_alkenyl (a2, a1) |
  8644.        is_alkynyl (a2, a1)) && is_diazonium (a1, a2))
  8645.     /* v0.3k */
  8646.     fg[fg_diazonium_salt - 1] = true;
  8647.   if ((is_alkyl (a2, a1) || is_aryl (a2, a1) || is_alkenyl (a2, a1) |
  8648.        is_alkynyl (a2, a1)) && is_nitro (a1, a2))
  8649.     /* v0.3k */
  8650.     fg[fg_nitro_compound - 1] = true;
  8651.   if (is_alkynyl (a2, a1) &
  8652.       (is_amino (a1, a2) || is_C_monosubst_amino (a1, a2) |
  8653.        (is_C_disubst_amino (a1, a2) && (!is_acylamino (a1, a2)))))
  8654.     {
  8655.       fg[fg_amine - 1] = true;
  8656.       amine_generic = true;
  8657.     }
  8658. }
  8659.  
  8660.  
  8661. static void
  8662. chk_c_c (a1, a2)
  8663.      int a1, a2;
  8664. {
  8665.   int i;
  8666.   neighbor_rec nb;
  8667.   int oh_count, nhr_count, FORLIM;
  8668.  
  8669.   /* ignore aromatic rings */
  8670.   if (atom[a2 - 1].arom == true)
  8671.     return;
  8672.   /*check for 1,2-diols and 1,2-aminoalcoholes */
  8673.   if (!strcmp (atom[a1 - 1].atype, "C3 ")
  8674.       && !strcmp (atom[a2 - 1].atype, "C3 "))
  8675.     {
  8676.       if ((hetbond_count (a1) == 1) && (hetbond_count (a2) == 1))
  8677.         {
  8678.           oh_count = 0;
  8679.           nhr_count = 0;
  8680.           memset (nb, 0, sizeof (neighbor_rec));
  8681.           get_neighbors (nb, a1);
  8682.           FORLIM = atom[a1 - 1].neighbor_count;
  8683.           for (i = 0; i < FORLIM; i++)
  8684.             {
  8685.               if (nb[i] != a2)
  8686.                 {
  8687.                   if (is_hydroxy (a1, nb[i]))
  8688.                     oh_count++;
  8689.                   if (is_amino (a1, nb[i]) || is_alkylamino (a1, nb[i]) |
  8690.                       is_arylamino (a1, nb[i]))
  8691.                     nhr_count++;
  8692.                 }
  8693.             }
  8694.           memset (nb, 0, sizeof (neighbor_rec));
  8695.           get_neighbors (nb, a2);
  8696.           FORLIM = atom[a2 - 1].neighbor_count;
  8697.           for (i = 0; i < FORLIM; i++)
  8698.             {
  8699.               if (nb[i] != a1)
  8700.                 {
  8701.                   if (is_hydroxy (a2, nb[i]))
  8702.                     oh_count++;
  8703.                   if (is_amino (a2, nb[i]) || is_alkylamino (a2, nb[i]) |
  8704.                       is_arylamino (a2, nb[i]))
  8705.                     nhr_count++;
  8706.                 }
  8707.             }
  8708.           if (oh_count == 2)
  8709.             fg[fg_1_2_diol - 1] = true;
  8710.           if (oh_count == 1 && nhr_count == 1)
  8711.             fg[fg_1_2_aminoalcohol - 1] = true;
  8712.         }
  8713.     }
  8714.   /* check for alpha-aminoacids and alpha-hydroxyacids */
  8715.   if (strcmp (atom[a1 - 1].atype, "C3 ")
  8716.       || strcmp (atom[a2 - 1].atype, "C2 "))
  8717.     return;
  8718.   if (!((hetbond_count (a1) == 1) && (hetbond_count (a2) == 3)))
  8719.     return;
  8720.   oh_count = 0;
  8721.   nhr_count = 0;
  8722.   memset (nb, 0, sizeof (neighbor_rec));
  8723.   get_neighbors (nb, a1);
  8724.   FORLIM = atom[a1 - 1].neighbor_count;
  8725.   for (i = 0; i < FORLIM; i++)
  8726.     {
  8727.       if (nb[i] != a2)
  8728.         {
  8729.           if (is_hydroxy (a1, nb[i]))
  8730.             oh_count++;
  8731.           if (is_amino (a1, nb[i]) || is_alkylamino (a1, nb[i]) |
  8732.               is_arylamino (a1, nb[i]))
  8733.             nhr_count++;
  8734.         }
  8735.     }
  8736.   memset (nb, 0, sizeof (neighbor_rec));
  8737.   get_neighbors (nb, a2);
  8738.   FORLIM = atom[a2 - 1].neighbor_count;
  8739.   for (i = 0; i < FORLIM; i++)
  8740.     {
  8741.       if (nb[i] != a1)
  8742.         {
  8743.           if (is_hydroxy (a2, nb[i]))
  8744.             oh_count++;
  8745.         }
  8746.     }
  8747.   if ((oh_count == 2) && is_oxo_C (a2))
  8748.     fg[fg_alpha_hydroxyacid - 1] = true;
  8749.   if ((oh_count == 1 && nhr_count == 1) && is_oxo_C (a2))
  8750.     fg[fg_alpha_aminoacid - 1] = true;
  8751. }
  8752.  
  8753.  
  8754. static void
  8755. chk_x_y_single (a_view, a_ref)
  8756.      int a_view, a_ref;
  8757. {
  8758.   if (!strcmp (atom[a_view - 1].atype, "O3 ") &&
  8759.       !strcmp (atom[a_ref - 1].atype, "O3 "))
  8760.     {
  8761.       if (is_hydroxy (a_ref, a_view) || is_hydroxy (a_view, a_ref))
  8762.         fg[fg_hydroperoxide - 1] = true;
  8763.       if ((is_alkoxy (a_ref, a_view) || is_aryloxy (a_ref, a_view) |
  8764.            is_siloxy (a_ref, a_view)) && (is_alkoxy (a_view,
  8765.                                                      a_ref) |
  8766.                                           is_aryloxy (a_view,
  8767.                                                       a_ref) |
  8768.                                           is_siloxy (a_view, a_ref)))
  8769.         fg[fg_peroxide - 1] = true;
  8770.     }                           /* still missing: peracid */
  8771.   if (!strcmp (atom[a_view - 1].atype, "S3 ") &&
  8772.       !strcmp (atom[a_ref - 1].atype, "S3 "))
  8773.     {
  8774.       if (atom[a_view - 1].neighbor_count == 2 &&
  8775.           atom[a_ref - 1].neighbor_count == 2)
  8776.         fg[fg_disulfide - 1] = true;
  8777.     }
  8778.   if ((!strcmp (atom[a_view - 1].element, "N ") &&
  8779.        !strcmp (atom[a_ref - 1].element,
  8780.                 "N ")) && (hetbond_count (a_view) ==
  8781.                            1) && (hetbond_count (a_ref) == 1))
  8782.     {
  8783.       /*if ((is_amino(a_ref,a_view)) or  */
  8784.       /*    (is_subst_amino(a_ref,a_view)) or */
  8785.       /*    (is_acylamino(a_ref,a_view))) and */
  8786.       /*   ((is_amino(a_view,a_ref)) or  */
  8787.       /*    (is_subst_amino(a_view,a_ref)) or */
  8788.       /*    (is_acylamino(a_ref,a_view))) then  */
  8789.       if (bond[get_bond (a_view, a_ref) - 1].arom == false)
  8790.         fg[fg_hydrazine - 1] = true;
  8791.     }
  8792.   if (!strcmp (atom[a_view - 1].element, "N ") &&
  8793.       !strcmp (atom[a_ref - 1].atype, "O3 "))
  8794.     {                           /* bond is in "opposite" direction */
  8795.       if ((is_alkoxy (a_view, a_ref) || is_aryloxy (a_view, a_ref)) &
  8796.           is_nitro (a_ref, a_view))
  8797.         fg[fg_nitrate - 1] = true;
  8798.       if ((is_nitro (a_ref, a_view) == false
  8799.            && atom[a_view - 1].arom == false) && (is_amino (a_ref,
  8800.                                                             a_view) |
  8801.                                                   is_subst_amino (a_ref,
  8802.                                                                   a_view)) &
  8803.           (is_acylamino (a_ref, a_view) == false))
  8804.         fg[fg_hydroxylamine - 1] = true;        /* new in v0.3c */
  8805.     }
  8806.   if (!strcmp (atom[a_view - 1].element, "S ") &&
  8807.       !strcmp (atom[a_ref - 1].element, "O "))
  8808.     chk_sulfoxide (a_view, a_ref);
  8809. }
  8810.  
  8811.  
  8812. static void
  8813. chk_single (a1, a2)
  8814.      int a1, a2;
  8815. {
  8816.   str2 a1_el, a2_el;
  8817.  
  8818.   strcpy (a1_el, atom[a1 - 1].element);
  8819.   strcpy (a2_el, atom[a2 - 1].element);
  8820.   if (!strcmp (a1_el, "C ") &&
  8821.       (!strcmp (a2_el, "F ") || !strcmp (a2_el, "CL")
  8822.        || !strcmp (a2_el, "BR") || !strcmp (a2_el, "I ")))
  8823.     chk_c_hal (a1, a2);
  8824.   if (!strcmp (a1_el, "C ") && !strcmp (a2_el, "O "))
  8825.     chk_c_o (a1, a2);
  8826.   if (!strcmp (a1_el, "C ") && !strcmp (a2_el, "S "))
  8827.     chk_c_s (a1, a2);
  8828.   if (!strcmp (a1_el, "C ") && !strcmp (a2_el, "N "))
  8829.     chk_c_n (a1, a2);
  8830.   if ((strcmp (a1_el, "C ") == 0) && atom[a2 - 1].metal && (is_cyano_c (a1) ==
  8831.                                                             false))
  8832.     {
  8833.       fg[fg_organometallic - 1] = true;
  8834.       if (!strcmp (a2_el, "LI"))
  8835.         fg[fg_organolithium - 1] = true;
  8836.       if (!strcmp (a2_el, "MG"))
  8837.         fg[fg_organomagnesium - 1] = true;
  8838.     }
  8839.   if (!strcmp (a1_el, "C ") && !strcmp (a2_el, "C "))
  8840.     chk_c_c (a1, a2);
  8841.   if (strcmp (a1_el, "C ") && strcmp (a2_el, "C "))
  8842.     chk_x_y_single (a1, a2);
  8843. }
  8844.  
  8845.  
  8846. static void
  8847. chk_carbonyl_deriv_sp3 (a_ref)
  8848.      int a_ref;
  8849. {
  8850.   int i;
  8851.   neighbor_rec nb;
  8852.   int oh_count = 0, or_count = 0, n_count = 0, sh_count = 0, sr_count = 0;
  8853.   int FORLIM;
  8854.  
  8855.   memset (nb, 0, sizeof (neighbor_rec));
  8856.   get_neighbors (nb, a_ref);
  8857.   FORLIM = atom[a_ref - 1].neighbor_count;
  8858.   for (i = 0; i < FORLIM; i++)
  8859.     {
  8860.       if (is_hydroxy (a_ref, nb[i]))
  8861.         oh_count++;
  8862.       if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]) |
  8863.           is_alkenyloxy (a_ref, nb[i]) || is_alkynyloxy (a_ref, nb[i]))
  8864.         or_count++;
  8865.       if (is_sulfanyl (a_ref, nb[i]))
  8866.         sh_count++;
  8867.       if (is_alkylsulfanyl (a_ref, nb[i]) || is_arylsulfanyl (a_ref, nb[i]) |
  8868.           is_alkenylsulfanyl (a_ref, nb[i]) || is_alkynylsulfanyl (a_ref,
  8869.                                                                    nb[i]))
  8870.         sr_count++;
  8871.       if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  8872.           !strcmp (atom[nb[i] - 1].atype, "NAM"))
  8873.         n_count++;
  8874.     }
  8875.   if (oh_count == 2)
  8876.     fg[fg_carbonyl_hydrate - 1] = true;
  8877.   if (oh_count == 1 && or_count == 1)
  8878.     fg[fg_hemiacetal - 1] = true;
  8879.   if (or_count == 2)
  8880.     fg[fg_acetal - 1] = true;
  8881.   if ((oh_count == 1 || or_count == 1) && n_count == 1)
  8882.     fg[fg_hemiaminal - 1] = true;
  8883.   if (n_count == 2)
  8884.     fg[fg_aminal - 1] = true;
  8885.   if ((sh_count == 1 || sr_count == 1) && n_count == 1)
  8886.     fg[fg_thiohemiaminal - 1] = true;
  8887.   if (sr_count == 2 || (or_count == 1 && sr_count == 1))
  8888.     fg[fg_thioacetal - 1] = true;
  8889. }
  8890.  
  8891.  
  8892. static void
  8893. chk_carboxyl_deriv_sp3 (a_ref)
  8894.      int a_ref;
  8895. {
  8896.   int i;
  8897.   neighbor_rec nb;
  8898.   int or_count = 0, oh_count = 0, n_count = 0;  /* oh_count new in v0.3c */
  8899.   int electroneg_count = 0;     /* new in v0.3j */
  8900.   int hal_count = 0;
  8901.   str2 nb_el;
  8902.   int FORLIM;
  8903.  
  8904.   memset (nb, 0, sizeof (neighbor_rec));
  8905.   get_neighbors (nb, a_ref);
  8906.   FORLIM = atom[a_ref - 1].neighbor_count;
  8907.   for (i = 0; i < FORLIM; i++)
  8908.     {
  8909.       strcpy (nb_el, atom[nb[i] - 1].element);  /* v0.3j */
  8910.       if (is_electroneg (nb_el))
  8911.         electroneg_count++;
  8912.       if (!strcmp (nb_el, "F ") || !strcmp (nb_el, "CL") ||
  8913.           !strcmp (nb_el, "BR") || !strcmp (nb_el, "I ")
  8914.           || !strcmp (nb_el, "AT"))
  8915.         hal_count++;
  8916.       if (is_alkoxy (a_ref, nb[i]) || is_aryloxy (a_ref, nb[i]) |
  8917.           is_siloxy (a_ref, nb[i]))
  8918.         or_count++;
  8919.       if (is_hydroxy (a_ref, nb[i]))    /* new in v0.3c    */
  8920.         oh_count++;
  8921.       if (!strcmp (atom[nb[i] - 1].atype, "N3 ") ||
  8922.           !strcmp (atom[nb[i] - 1].atype, "NAM"))
  8923.         n_count++;
  8924.     }
  8925.   /*if (or_count + n_count > 1) then fg[fg_orthocarboxylic_acid_deriv] := true;  (* until v0.3i */
  8926.   if (electroneg_count == 3 && hal_count < 3)   /* v0.3j */
  8927.     fg[fg_orthocarboxylic_acid_deriv - 1] = true;
  8928.   if (or_count == 3)
  8929.     fg[fg_carboxylic_acid_orthoester - 1] = true;
  8930.   if (or_count == 2 && n_count == 1)
  8931.     fg[fg_carboxylic_acid_amide_acetal - 1] = true;
  8932.   if (oh_count > 0 && oh_count + or_count + n_count == 3)       /* new in v0.3c */
  8933.     fg[fg_orthocarboxylic_acid_deriv - 1] = true;
  8934. }
  8935.  
  8936.  
  8937. static void
  8938. chk_anhydride (a_ref)
  8939.      int a_ref;
  8940. {
  8941.   int i;
  8942.   neighbor_rec nb;
  8943.   int acyl_count = 0;
  8944.   int FORLIM;
  8945.  
  8946.   memset (nb, 0, sizeof (neighbor_rec));
  8947.   get_neighbors (nb, a_ref);
  8948.   FORLIM = atom[a_ref - 1].neighbor_count;
  8949.   for (i = 0; i < FORLIM; i++)
  8950.     {
  8951.       if (is_acyl (a_ref, nb[i]) || is_carbamoyl (a_ref, nb[i]))
  8952.         acyl_count++;
  8953.     }
  8954.   if (acyl_count == 2 && !strcmp (atom[a_ref - 1].atype, "O3 "))
  8955.     {
  8956.       fg[fg_carboxylic_acid_deriv - 1] = true;
  8957.       fg[fg_carboxylic_acid_anhydride - 1] = true;
  8958.     }
  8959. }
  8960.  
  8961.  
  8962. static void
  8963. chk_imide (a_ref)
  8964.      int a_ref;
  8965. {
  8966.   int i;
  8967.   neighbor_rec nb;
  8968.   int acyl_count = 0;
  8969.   int FORLIM;
  8970.  
  8971.   memset (nb, 0, sizeof (neighbor_rec));
  8972.   get_neighbors (nb, a_ref);
  8973.   FORLIM = atom[a_ref - 1].neighbor_count;
  8974.   for (i = 0; i < FORLIM; i++)
  8975.     {
  8976.       if (is_acyl_gen (a_ref, nb[i]) || is_carbamoyl (a_ref, nb[i]))    /* v0.3j */
  8977.         acyl_count++;
  8978.     }
  8979.   if (acyl_count < 2 || strcmp (atom[a_ref - 1].element, "N "))
  8980.     /* v0.3j: accept also N-acyl-imides */
  8981.     return;
  8982.   fg[fg_carboxylic_acid_deriv - 1] = true;
  8983.   fg[fg_carboxylic_acid_imide - 1] = true;
  8984.   if (atom[a_ref - 1].neighbor_count == 2)
  8985.     fg[fg_carboxylic_acid_unsubst_imide - 1] = true;
  8986.   if (atom[a_ref - 1].neighbor_count == 3)
  8987.     fg[fg_carboxylic_acid_subst_imide - 1] = true;
  8988. }
  8989.  
  8990.  
  8991. static void
  8992. chk_12diphenol (a_view, a_ref)
  8993.      int a_view, a_ref;
  8994. {
  8995.   int i;
  8996.   neighbor_rec nb;
  8997.   int oh_count = 0;
  8998.   int FORLIM;
  8999.  
  9000.   memset (nb, 0, sizeof (neighbor_rec));
  9001.   get_neighbors (nb, a_view);
  9002.   FORLIM = atom[a_view - 1].neighbor_count;
  9003.   for (i = 0; i < FORLIM; i++)
  9004.     {
  9005.       if (bond[get_bond (a_view, nb[i]) - 1].btype == 'S')
  9006.         {
  9007.           if (is_hydroxy (a_view, nb[i]))
  9008.             oh_count++;
  9009.         }
  9010.     }
  9011.   memset (nb, 0, sizeof (neighbor_rec));
  9012.   get_neighbors (nb, a_ref);
  9013.   FORLIM = atom[a_ref - 1].neighbor_count;
  9014.   for (i = 0; i < FORLIM; i++)
  9015.     {
  9016.       if (bond[get_bond (a_ref, nb[i]) - 1].btype == 'S')
  9017.         {
  9018.           if (is_hydroxy (a_ref, nb[i]))
  9019.             oh_count++;
  9020.         }
  9021.     }
  9022.   if (oh_count == 2)
  9023.     fg[fg_1_2_diphenol - 1] = true;
  9024. }
  9025.  
  9026.  
  9027. static void
  9028. chk_arom_fg (a1, a2)
  9029.      int a1, a2;
  9030. {
  9031.   if ((hetbond_count (a1) == 1) && (hetbond_count (a2) == 1))
  9032.     chk_12diphenol (a1, a2);
  9033. }
  9034.  
  9035.  
  9036. static boolean
  9037. is_arene (r_id)
  9038.      int r_id;
  9039. {
  9040.   int i, j;
  9041.   boolean r = true;
  9042.   ringpath_type testring;
  9043.   int ring_size, a_prev, a_ref;
  9044.  
  9045. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  9046.   if (r_id < 1 || r_id > n_rings)
  9047.     return false;
  9048.   memset (testring, 0, sizeof (ringpath_type));
  9049.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  9050.   /*for j := 1 to max_ringsize do if ring^[r_id,j] > 0 then testring[j] := ring^[r_id,j]; */
  9051.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  9052.     testring[j] = ring[r_id - 1][j];
  9053.   /*ring_size := path_length(testring); */
  9054.   if (ring_size <= 2)
  9055.     return false;
  9056.   a_prev = testring[ring_size - 1];
  9057.   for (i = 0; i < ring_size; i++)
  9058.     {
  9059.       a_ref = testring[i];
  9060.       if (bond[get_bond (a_prev, a_ref) - 1].arom == false)
  9061.         r = false;
  9062.       a_prev = a_ref;
  9063.     }
  9064.   return r;
  9065. }
  9066.  
  9067.  
  9068. static boolean
  9069. is_heterocycle (r_id)
  9070.      int r_id;
  9071. {
  9072.   int i, j;
  9073.   boolean r = false;
  9074.   ringpath_type testring;
  9075.   int ring_size, a_ref;
  9076.  
  9077.   if (r_id < 1 || r_id > n_rings)
  9078.     return false;
  9079.   memset (testring, 0, sizeof (ringpath_type));
  9080.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  9081.   /*for j := 1 to max_ringsize do if ring^[r_id,j] > 0 then testring[j] := ring^[r_id,j]; */
  9082.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  9083.     testring[j] = ring[r_id - 1][j];
  9084.   /*ring_size := path_length(testring); */
  9085.   if (ring_size <= 2)
  9086.     return false;
  9087.   for (i = 0; i < ring_size; i++)
  9088.     {
  9089.       a_ref = testring[i];
  9090.       if (strcmp (atom[a_ref - 1].element, "C "))
  9091.         r = true;
  9092.     }
  9093.   return r;
  9094. }
  9095.  
  9096.  
  9097. static void
  9098. chk_oxo_thioxo_imino_hetarene (r_id)
  9099.      int r_id;
  9100. {
  9101.   int i, j;
  9102.   ringpath_type testring;
  9103.   int ring_size, a_ref;
  9104.  
  9105.   if (r_id < 1 || r_id > n_rings)
  9106.     return;
  9107.   memset (testring, 0, sizeof (ringpath_type));
  9108.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  9109.   /*for j := 1 to max_ringsize do if ring^[r_id,j] > 0 then testring[j] := ring^[r_id,j]; */
  9110.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  9111.     testring[j] = ring[r_id - 1][j];
  9112.   /*ring_size := path_length(testring); */
  9113.   /*if (is_arene(r_id)) and (odd(ring_size) = false) then */
  9114.   if (!is_arene (r_id))         /* v0.3j */
  9115.     return;
  9116.   for (i = 0; i < ring_size; i++)
  9117.     {
  9118.       a_ref = testring[i];
  9119.       if (is_oxo_C (a_ref))
  9120.         fg[fg_oxohetarene - 1] = true;
  9121.       if (is_thioxo_C (a_ref))
  9122.         fg[fg_thioxohetarene - 1] = true;
  9123.       if (is_true_exocyclic_imino_C (a_ref, r_id))      /* v0.3j */
  9124.         fg[fg_iminohetarene - 1] = true;
  9125.     }
  9126. }
  9127.  
  9128.  
  9129. static void
  9130. chk_ion (a_ref)
  9131.      int a_ref;
  9132. {
  9133.   int i;
  9134.   neighbor_rec nb;
  9135.   int charge, FORLIM;
  9136.  
  9137.   memset (nb, 0, sizeof (neighbor_rec));
  9138.   get_neighbors (nb, a_ref);
  9139.   charge = atom[a_ref - 1].formal_charge;
  9140.   if (charge == 0)
  9141.     /* check if charge is neutralized by an adjacent opposite charge */
  9142.     return;
  9143.   FORLIM = atom[a_ref - 1].neighbor_count;
  9144.   for (i = 0; i < FORLIM; i++)
  9145.     charge += atom[nb[i] - 1].formal_charge;
  9146.   if (charge > 0)
  9147.     fg[fg_cation - 1] = true;
  9148.   if (charge < 0)
  9149.     fg[fg_anion - 1] = true;
  9150. }
  9151.  
  9152.  
  9153. static void
  9154. chk_functionalgroups ()
  9155. {
  9156.   int i, a1, a2;
  9157.   char bt;
  9158.   int pos_chg = 0, neg_chg = 0;
  9159.   int FORLIM;
  9160.  
  9161.   if (n_atoms < 1 || n_bonds < 1)
  9162.     return;
  9163.   FORLIM = n_atoms;
  9164.   for (i = 1; i <= FORLIM; i++)
  9165.     {                           /* a few groups are best discovered in the atom list */
  9166.       if (!strcmp (atom[i - 1].atype, "SO2"))
  9167.         chk_so2_deriv (i);
  9168.       /*if (atom^[i].atype = 'SO ') then fg[fg_sulfoxide] := true;  (* do another check in the bond list!! */
  9169.       if (!strcmp (atom[i - 1].element, "P "))
  9170.         chk_p_deriv (i);
  9171.       if (!strcmp (atom[i - 1].element, "B "))
  9172.         chk_b_deriv (i);
  9173.       if (!strcmp (atom[i - 1].atype, "N3+") || atom[i - 1].formal_charge > 0)
  9174.         chk_ammon (i);
  9175.       if ((strcmp (atom[i - 1].atype, "C3 ") == 0)
  9176.           && (hetbond_count (i) == 2))
  9177.         chk_carbonyl_deriv_sp3 (i);
  9178.       if ((strcmp (atom[i - 1].atype, "C3 ") == 0)
  9179.           && (hetbond_count (i) == 3))
  9180.         chk_carboxyl_deriv_sp3 (i);
  9181.       if (!strcmp (atom[i - 1].atype, "O3 ")
  9182.           && atom[i - 1].neighbor_count == 2)
  9183.         chk_anhydride (i);
  9184.       if ((!strcmp (atom[i - 1].atype, "N3 ")
  9185.            || !strcmp (atom[i - 1].atype, "NAM"))
  9186.           && atom[i - 1].neighbor_count >= 2)
  9187.         chk_imide (i);
  9188.       if (atom[i - 1].formal_charge > 0)
  9189.         pos_chg += atom[i - 1].formal_charge;
  9190.       if (atom[i - 1].formal_charge < 0)
  9191.         neg_chg += atom[i - 1].formal_charge;
  9192.       chk_ion (i);
  9193.     }
  9194.   FORLIM = n_bonds;
  9195.   for (i = 0; i < FORLIM; i++)
  9196.     {                           /* most groups are best discovered in the bond list */
  9197.       a1 = bond[i].a1;
  9198.       a2 = bond[i].a2;
  9199.       bt = bond[i].btype;
  9200.       if (atom[a1 - 1].heavy && atom[a2 - 1].heavy)
  9201.         {
  9202.           orient_bond (&a1, &a2);
  9203.           if (bt == 'T')
  9204.             chk_triple (a1, a2);
  9205.           if (bt == 'D')
  9206.             chk_double (a1, a2);
  9207.           if (bt == 'S')
  9208.             chk_single (a1, a2);
  9209.           if (bond[i].arom)
  9210.             chk_arom_fg (a1, a2);
  9211.         }
  9212.     }
  9213.   if (n_rings > 0)
  9214.     {
  9215.       FORLIM = n_rings;
  9216.       for (i = 1; i <= FORLIM; i++)
  9217.         {
  9218.           chk_oxo_thioxo_imino_hetarene (i);
  9219.           if (is_arene (i))
  9220.             fg[fg_aromatic - 1] = true;
  9221.           if (is_heterocycle (i))
  9222.             fg[fg_heterocycle - 1] = true;
  9223.         }
  9224.     }
  9225.   if (pos_chg + neg_chg > 0)
  9226.     fg[fg_cation - 1] = true;
  9227.   if (pos_chg + neg_chg < 0)
  9228.     fg[fg_anion - 1] = true;
  9229. }
  9230.  
  9231.  
  9232. static void
  9233. write_fg_text ()
  9234. {
  9235.   if (fg[fg_cation - 1])
  9236.     printf ("cation\n");
  9237.   if (fg[fg_anion - 1])
  9238.     printf ("anion\n");
  9239.   /*  if fg[fg_carbonyl]                       then writeln('carbonyl compound'); */
  9240.   if (fg[fg_aldehyde - 1])
  9241.     printf ("aldehyde\n");
  9242.   if (fg[fg_ketone - 1])
  9243.     printf ("ketone\n");
  9244.   /*  if fg[fg_thiocarbonyl]                   then writeln('thiocarbonyl compound'); */
  9245.   if (fg[fg_thioaldehyde - 1])
  9246.     printf ("thioaldehyde\n");
  9247.   if (fg[fg_thioketone - 1])
  9248.     printf ("thioketone\n");
  9249.   if (fg[fg_imine - 1])
  9250.     printf ("imine\n");
  9251.   if (fg[fg_hydrazone - 1])
  9252.     printf ("hydrazone\n");
  9253.   if (fg[fg_semicarbazone - 1])
  9254.     printf ("semicarbazone\n");
  9255.   if (fg[fg_thiosemicarbazone - 1])
  9256.     printf ("thiosemicarbazone\n");
  9257.   if (fg[fg_oxime - 1])
  9258.     printf ("oxime\n");
  9259.   if (fg[fg_oxime_ether - 1])
  9260.     printf ("oxime ether\n");
  9261.   if (fg[fg_ketene - 1])
  9262.     printf ("ketene\n");
  9263.   if (fg[fg_ketene_acetal_deriv - 1])
  9264.     printf ("ketene acetal or derivative\n");
  9265.   if (fg[fg_carbonyl_hydrate - 1])
  9266.     printf ("carbonyl hydrate\n");
  9267.   if (fg[fg_hemiacetal - 1])
  9268.     printf ("hemiacetal\n");
  9269.   if (fg[fg_acetal - 1])
  9270.     printf ("acetal\n");
  9271.   if (fg[fg_hemiaminal - 1])
  9272.     printf ("hemiaminal\n");
  9273.   if (fg[fg_aminal - 1])
  9274.     printf ("aminal\n");
  9275.   if (fg[fg_thiohemiaminal - 1])
  9276.     printf ("hemithioaminal\n");
  9277.   if (fg[fg_thioacetal - 1])
  9278.     printf ("thioacetal\n");
  9279.   if (fg[fg_enamine - 1])
  9280.     printf ("enamine\n");
  9281.   if (fg[fg_enol - 1])
  9282.     printf ("enol\n");
  9283.   if (fg[fg_enolether - 1])
  9284.     printf ("enol ether\n");
  9285.   if (fg[fg_hydroxy - 1] && hydroxy_generic)
  9286.     printf ("hydroxy compound\n");
  9287.   /*  if fg[fg_alcohol]                        then writeln('alcohol'); */
  9288.   if (fg[fg_prim_alcohol - 1])
  9289.     printf ("primary alcohol\n");
  9290.   if (fg[fg_sec_alcohol - 1])
  9291.     printf ("secondary alcohol\n");
  9292.   if (fg[fg_tert_alcohol - 1])
  9293.     printf ("tertiary alcohol\n");
  9294.   if (fg[fg_1_2_diol - 1])
  9295.     printf ("1,2-diol\n");
  9296.   if (fg[fg_1_2_aminoalcohol - 1])
  9297.     printf ("1,2-aminoalcohol\n");
  9298.   if (fg[fg_phenol - 1])
  9299.     printf ("phenol or hydroxyhetarene\n");
  9300.   if (fg[fg_1_2_diphenol - 1])
  9301.     printf ("1,2-diphenol\n");
  9302.   if (fg[fg_enediol - 1])
  9303.     printf ("enediol\n");
  9304.   if (fg[fg_ether - 1] && ether_generic)
  9305.     printf ("ether\n");
  9306.   if (fg[fg_dialkylether - 1])
  9307.     printf ("dialkyl ether\n");
  9308.   if (fg[fg_alkylarylether - 1])
  9309.     printf ("alkyl aryl ether \n");
  9310.   if (fg[fg_diarylether - 1])
  9311.     printf ("diaryl ether\n");
  9312.   if (fg[fg_thioether - 1])
  9313.     printf ("thioether\n");
  9314.   if (fg[fg_disulfide - 1])
  9315.     printf ("disulfide\n");
  9316.   if (fg[fg_peroxide - 1])
  9317.     printf ("peroxide\n");
  9318.   if (fg[fg_hydroperoxide - 1])
  9319.     printf ("hydroperoxide \n");
  9320.   if (fg[fg_hydrazine - 1])
  9321.     printf ("hydrazine derivative\n");
  9322.   if (fg[fg_hydroxylamine - 1])
  9323.     printf ("hydroxylamine\n");
  9324.   if (fg[fg_amine - 1] && amine_generic)
  9325.     printf ("amine\n");
  9326.   if (fg[fg_prim_amine - 1])
  9327.     printf ("primary amine\n");
  9328.   if (fg[fg_prim_aliph_amine - 1])
  9329.     printf ("primary aliphatic amine (alkylamine)\n");
  9330.   if (fg[fg_prim_arom_amine - 1])
  9331.     printf ("primary aromatic amine\n");
  9332.   if (fg[fg_sec_amine - 1])
  9333.     printf ("secondary amine\n");
  9334.   if (fg[fg_sec_aliph_amine - 1])
  9335.     printf ("secondary aliphatic amine (dialkylamine)\n");
  9336.   if (fg[fg_sec_mixed_amine - 1])
  9337.     printf ("secondary aliphatic/aromatic amine (alkylarylamine)\n");
  9338.   if (fg[fg_sec_arom_amine - 1])
  9339.     printf ("secondary aromatic amine (diarylamine)\n");
  9340.   if (fg[fg_tert_amine - 1])
  9341.     printf ("tertiary amine\n");
  9342.   if (fg[fg_tert_aliph_amine - 1])
  9343.     printf ("tertiary aliphatic amine (trialkylamine)\n");
  9344.   if (fg[fg_tert_mixed_amine - 1])
  9345.     printf ("tertiary aliphatic/aromatic amine (alkylarylamine)\n");
  9346.   if (fg[fg_tert_arom_amine - 1])
  9347.     printf ("tertiary aromatic amine (triarylamine)\n");
  9348.   if (fg[fg_quart_ammonium - 1])
  9349.     printf ("quaternary ammonium salt\n");
  9350.   if (fg[fg_n_oxide - 1])
  9351.     printf ("N-oxide\n");
  9352.   /* new in v0.2f */
  9353.   if (fg[fg_halogen_deriv - 1])
  9354.     {
  9355.       if (!fg[fg_alkyl_halide - 1] && !fg[fg_aryl_halide - 1] &&
  9356.           !fg[fg_acyl_halide - 1])
  9357.         printf ("halogen derivative\n");
  9358.     }
  9359.   /*  if fg[fg_alkyl_halide]                   then writeln('alkyl halide'); */
  9360.   if (fg[fg_alkyl_fluoride - 1])
  9361.     printf ("alkyl fluoride\n");
  9362.   if (fg[fg_alkyl_chloride - 1])
  9363.     printf ("alkyl chloride\n");
  9364.   if (fg[fg_alkyl_bromide - 1])
  9365.     printf ("alkyl bromide\n");
  9366.   if (fg[fg_alkyl_iodide - 1])
  9367.     printf ("alkyl iodide\n");
  9368.   /*  if fg[fg_aryl_halide]                    then writeln('aryl halide'); */
  9369.   if (fg[fg_aryl_fluoride - 1])
  9370.     printf ("aryl fluoride\n");
  9371.   if (fg[fg_aryl_chloride - 1])
  9372.     printf ("aryl chloride\n");
  9373.   if (fg[fg_aryl_bromide - 1])
  9374.     printf ("aryl bromide\n");
  9375.   if (fg[fg_aryl_iodide - 1])
  9376.     printf ("aryl iodide\n");
  9377.   if (fg[fg_organometallic - 1])
  9378.     printf ("organometallic compound\n");
  9379.   if (fg[fg_organolithium - 1])
  9380.     printf ("organolithium compound\n");
  9381.   if (fg[fg_organomagnesium - 1])
  9382.     printf ("organomagnesium compound\n");
  9383.   /*  if fg[fg_carboxylic_acid_deriv]          then writeln('carboxylic acid derivative'); */
  9384.   if (fg[fg_carboxylic_acid - 1])
  9385.     printf ("carboxylic acid\n");
  9386.   if (fg[fg_carboxylic_acid_salt - 1])
  9387.     printf ("carboxylic acid salt\n");
  9388.   if (fg[fg_carboxylic_acid_ester - 1])
  9389.     printf ("carboxylic acid ester\n");
  9390.   if (fg[fg_lactone - 1])
  9391.     printf ("lactone\n");
  9392.   /*  if fg[fg_carboxylic_acid_amide]          then writeln('carboxylic acid amide'); */
  9393.   if (fg[fg_carboxylic_acid_prim_amide - 1])
  9394.     printf ("primary carboxylic acid amide\n");
  9395.   if (fg[fg_carboxylic_acid_sec_amide - 1])
  9396.     printf ("secondary carboxylic acid amide\n");
  9397.   if (fg[fg_carboxylic_acid_tert_amide - 1])
  9398.     printf ("tertiary carboxylic acid amide\n");
  9399.   if (fg[fg_lactam - 1])
  9400.     printf ("lactam\n");
  9401.   if (fg[fg_carboxylic_acid_hydrazide - 1])
  9402.     printf ("carboxylic acid hydrazide\n");
  9403.   if (fg[fg_carboxylic_acid_azide - 1])
  9404.     printf ("carboxylic acid azide\n");
  9405.   if (fg[fg_hydroxamic_acid - 1])
  9406.     printf ("hydroxamic acid\n");
  9407.   if (fg[fg_carboxylic_acid_amidine - 1])
  9408.     printf ("carboxylic acid amidine\n");
  9409.   if (fg[fg_carboxylic_acid_amidrazone - 1])
  9410.     printf ("carboxylic acid amidrazone\n");
  9411.   if (fg[fg_nitrile - 1])
  9412.     printf ("carbonitrile\n");
  9413.   /*  if fg[fg_acyl_halide]                    then writeln('acyl halide'); */
  9414.   if (fg[fg_acyl_fluoride - 1])
  9415.     printf ("acyl fluoride\n");
  9416.   if (fg[fg_acyl_chloride - 1])
  9417.     printf ("acyl chloride\n");
  9418.   if (fg[fg_acyl_bromide - 1])
  9419.     printf ("acyl bromide\n");
  9420.   if (fg[fg_acyl_iodide - 1])
  9421.     printf ("acyl iodide\n");
  9422.   if (fg[fg_acyl_cyanide - 1])
  9423.     printf ("acyl cyanide\n");
  9424.   if (fg[fg_imido_ester - 1])
  9425.     printf ("imido ester\n");
  9426.   if (fg[fg_imidoyl_halide - 1])
  9427.     printf ("imidoyl halide\n");
  9428.   /*  if fg[fg_thiocarboxylic_acid_deriv]      then writeln('thiocarboxylic acid derivative'); */
  9429.   if (fg[fg_thiocarboxylic_acid - 1])
  9430.     printf ("thiocarboxylic acid\n");
  9431.   if (fg[fg_thiocarboxylic_acid_ester - 1])
  9432.     printf ("thiocarboxylic acid ester\n");
  9433.   if (fg[fg_thiolactone - 1])
  9434.     printf ("thiolactone\n");
  9435.   if (fg[fg_thiocarboxylic_acid_amide - 1])
  9436.     printf ("thiocarboxylic acid amide\n");
  9437.   if (fg[fg_thiolactam - 1])
  9438.     printf ("thiolactam\n");
  9439.   if (fg[fg_imido_thioester - 1])
  9440.     printf ("imidothioester\n");
  9441.   if (fg[fg_oxohetarene - 1])
  9442.     printf ("oxo(het)arene\n");
  9443.   if (fg[fg_thioxohetarene - 1])
  9444.     printf ("thioxo(het)arene\n");
  9445.   if (fg[fg_iminohetarene - 1])
  9446.     printf ("imino(het)arene\n");
  9447.   if (fg[fg_orthocarboxylic_acid_deriv - 1])
  9448.     printf ("orthocarboxylic acid derivative\n");
  9449.   if (fg[fg_carboxylic_acid_orthoester - 1])
  9450.     printf ("orthoester\n");
  9451.   if (fg[fg_carboxylic_acid_amide_acetal - 1])
  9452.     printf ("amide acetal\n");
  9453.   if (fg[fg_carboxylic_acid_anhydride - 1])
  9454.     printf ("carboxylic acid anhydride\n");
  9455.   /*  if fg[fg_carboxylic_acid_imide]          then writeln('carboxylic acid imide'); */
  9456.   if (fg[fg_carboxylic_acid_unsubst_imide - 1])
  9457.     printf ("carboxylic acid imide, N-unsubstituted\n");
  9458.   if (fg[fg_carboxylic_acid_subst_imide - 1])
  9459.     printf ("carboxylic acid imide, N-substituted\n");
  9460.   if (fg[fg_co2_deriv - 1])
  9461.     printf ("CO2 derivative (general)\n");
  9462.   if (fg[fg_carbonic_acid_deriv - 1] &&
  9463.       !(fg[fg_carbonic_acid_monoester - 1]
  9464.         || fg[fg_carbonic_acid_diester - 1]
  9465.         || fg[fg_carbonic_acid_ester_halide - 1]))
  9466.     /* changed in v0.3c */
  9467.     printf ("carbonic acid derivative\n");
  9468.   if (fg[fg_carbonic_acid_monoester - 1])
  9469.     printf ("carbonic acid monoester\n");
  9470.   if (fg[fg_carbonic_acid_diester - 1])
  9471.     printf ("carbonic acid diester\n");
  9472.   if (fg[fg_carbonic_acid_ester_halide - 1])
  9473.     printf ("carbonic acid ester halide (alkyl/aryl haloformate)\n");
  9474.   if (fg[fg_thiocarbonic_acid_deriv - 1])
  9475.     printf ("thiocarbonic acid derivative\n");
  9476.   if (fg[fg_thiocarbonic_acid_monoester - 1])
  9477.     printf ("thiocarbonic acid monoester\n");
  9478.   if (fg[fg_thiocarbonic_acid_diester - 1])
  9479.     printf ("thiocarbonic acid diester\n");
  9480.   if (fg[fg_thiocarbonic_acid_ester_halide - 1])
  9481.     printf ("thiocarbonic acid ester halide (alkyl/aryl halothioformate)\n");
  9482.   if (fg[fg_carbamic_acid_deriv - 1]
  9483.       && !(fg[fg_carbamic_acid - 1] || fg[fg_carbamic_acid_ester - 1]
  9484.            || fg[fg_carbamic_acid_halide - 1]))
  9485.     /* changed in v0.3c */
  9486.     printf ("carbamic acid derivative\n");
  9487.   if (fg[fg_carbamic_acid - 1])
  9488.     printf ("carbamic acid\n");
  9489.   if (fg[fg_carbamic_acid_ester - 1])
  9490.     printf ("carbamic acid ester (urethane)\n");
  9491.   if (fg[fg_carbamic_acid_halide - 1])
  9492.     printf ("carbamic acid halide (haloformic acid amide)\n");
  9493.   if (fg[fg_thiocarbamic_acid_deriv - 1] &&
  9494.       !(fg[fg_thiocarbamic_acid - 1] || fg[fg_thiocarbamic_acid_ester - 1]
  9495.         || fg[fg_thiocarbamic_acid_halide - 1]))
  9496.     /* changed in v0.3c */
  9497.     printf ("thiocarbamic acid derivative\n");
  9498.   if (fg[fg_thiocarbamic_acid - 1])
  9499.     printf ("thiocarbamic acid\n");
  9500.   if (fg[fg_thiocarbamic_acid_ester - 1])
  9501.     printf ("thiocarbamic acid ester\n");
  9502.   if (fg[fg_thiocarbamic_acid_halide - 1])
  9503.     printf ("thiocarbamic acid halide (halothioformic acid amide)\n");
  9504.   if (fg[fg_urea - 1])
  9505.     printf ("urea\n");
  9506.   if (fg[fg_isourea - 1])
  9507.     printf ("isourea\n");
  9508.   if (fg[fg_thiourea - 1])
  9509.     printf ("thiourea\n");
  9510.   if (fg[fg_isothiourea - 1])
  9511.     printf ("isothiourea\n");
  9512.   if (fg[fg_guanidine - 1])
  9513.     printf ("guanidine\n");
  9514.   if (fg[fg_semicarbazide - 1])
  9515.     printf ("semicarbazide\n");
  9516.   if (fg[fg_thiosemicarbazide - 1])
  9517.     printf ("thiosemicarbazide\n");
  9518.   if (fg[fg_azide - 1])
  9519.     printf ("azide\n");
  9520.   if (fg[fg_azo_compound - 1])
  9521.     printf ("azo compound\n");
  9522.   if (fg[fg_diazonium_salt - 1])
  9523.     printf ("diazonium salt\n");
  9524.   if (fg[fg_isonitrile - 1])
  9525.     printf ("isonitrile\n");
  9526.   if (fg[fg_cyanate - 1])
  9527.     printf ("cyanate\n");
  9528.   if (fg[fg_isocyanate - 1])
  9529.     printf ("isocyanate\n");
  9530.   if (fg[fg_thiocyanate - 1])
  9531.     printf ("thiocyanate\n");
  9532.   if (fg[fg_isothiocyanate - 1])
  9533.     printf ("isothiocyanate\n");
  9534.   if (fg[fg_carbodiimide - 1])
  9535.     printf ("carbodiimide\n");
  9536.   if (fg[fg_nitroso_compound - 1])
  9537.     printf ("nitroso compound\n");
  9538.   if (fg[fg_nitro_compound - 1])
  9539.     printf ("nitro compound\n");
  9540.   if (fg[fg_nitrite - 1])
  9541.     printf ("nitrite\n");
  9542.   if (fg[fg_nitrate - 1])
  9543.     printf ("nitrate\n");
  9544.   /*  if fg[fg_sulfuric_acid_deriv]            then writeln('sulfuric acid derivative'); */
  9545.   if (fg[fg_sulfuric_acid - 1])
  9546.     printf ("sulfuric acid\n");
  9547.   if (fg[fg_sulfuric_acid_monoester - 1])
  9548.     printf ("sulfuric acid monoester\n");
  9549.   if (fg[fg_sulfuric_acid_diester - 1])
  9550.     printf ("sulfuric acid diester\n");
  9551.   if (fg[fg_sulfuric_acid_amide_ester - 1])
  9552.     printf ("sulfuric acid amide ester\n");
  9553.   if (fg[fg_sulfuric_acid_amide - 1])
  9554.     printf ("sulfuric acid amide\n");
  9555.   if (fg[fg_sulfuric_acid_diamide - 1])
  9556.     printf ("sulfuric acid diamide\n");
  9557.   if (fg[fg_sulfuryl_halide - 1])
  9558.     printf ("sulfuryl halide\n");
  9559.   /*  if fg[fg_sulfonic_acid_deriv]            then writeln('sulfonic acid derivative '); */
  9560.   if (fg[fg_sulfonic_acid - 1])
  9561.     printf ("sulfonic acid\n");
  9562.   if (fg[fg_sulfonic_acid_ester - 1])
  9563.     printf ("sulfonic acid ester\n");
  9564.   if (fg[fg_sulfonamide - 1])
  9565.     printf ("sulfonamide\n");
  9566.   if (fg[fg_sulfonyl_halide - 1])
  9567.     printf ("sulfonyl halide\n");
  9568.   if (fg[fg_sulfone - 1])
  9569.     printf ("sulfone\n");
  9570.   if (fg[fg_sulfoxide - 1])
  9571.     printf ("sulfoxide\n");
  9572.   /*  if fg[fg_sulfinic_acid_deriv]            then writeln('sulfinic acid derivative'); */
  9573.   if (fg[fg_sulfinic_acid - 1])
  9574.     printf ("sulfinic acid\n");
  9575.   if (fg[fg_sulfinic_acid_ester - 1])
  9576.     printf ("sulfinic acid ester\n");
  9577.   if (fg[fg_sulfinic_acid_halide - 1])
  9578.     printf ("sulfinic acid halide\n");
  9579.   if (fg[fg_sulfinic_acid_amide - 1])
  9580.     printf ("sulfinic acid amide\n");
  9581.   /*  if fg[fg_sulfenic_acid_deriv]            then writeln('sulfenic acid derivative'); */
  9582.   if (fg[fg_sulfenic_acid - 1])
  9583.     printf ("sulfenic acid\n");
  9584.   if (fg[fg_sulfenic_acid_ester - 1])
  9585.     printf ("sulfenic acid ester\n");
  9586.   if (fg[fg_sulfenic_acid_halide - 1])
  9587.     printf ("sulfenic acid halide\n");
  9588.   if (fg[fg_sulfenic_acid_amide - 1])
  9589.     printf ("sulfenic acid amide\n");
  9590.   if (fg[fg_thiol - 1])
  9591.     printf ("thiol (sulfanyl compound)\n");
  9592.   if (fg[fg_alkylthiol - 1])
  9593.     printf ("alkylthiol\n");
  9594.   if (fg[fg_arylthiol - 1])
  9595.     printf ("arylthiol\n");
  9596.   /*  if fg[fg_phosphoric_acid_deriv]          then writeln('phosphoric acid derivative'); */
  9597.   if (fg[fg_phosphoric_acid - 1])
  9598.     printf ("phosphoric acid\n");
  9599.   if (fg[fg_phosphoric_acid_ester - 1])
  9600.     printf ("phosphoric acid ester\n");
  9601.   if (fg[fg_phosphoric_acid_halide - 1])
  9602.     printf ("phosphoric acid halide\n");
  9603.   if (fg[fg_phosphoric_acid_amide - 1])
  9604.     printf ("phosphoric acid amide\n");
  9605.   /*  if fg[fg_thiophosphoric_acid_deriv]      then writeln('thiophosphoric acid derivative'); */
  9606.   if (fg[fg_thiophosphoric_acid - 1])
  9607.     printf ("thiophosphoric acid\n");
  9608.   if (fg[fg_thiophosphoric_acid_ester - 1])
  9609.     printf ("thiophosphoric acid ester\n");
  9610.   if (fg[fg_thiophosphoric_acid_halide - 1])
  9611.     printf ("thiophosphoric acid halide\n");
  9612.   if (fg[fg_thiophosphoric_acid_amide - 1])
  9613.     printf ("thiophosphoric acid amide\n");
  9614.   if (fg[fg_phosphonic_acid_deriv - 1])
  9615.     printf ("phosphonic acid derivative \n");
  9616.   if (fg[fg_phosphonic_acid - 1])
  9617.     printf ("phosphonic acid\n");
  9618.   if (fg[fg_phosphonic_acid_ester - 1])
  9619.     printf ("phosphonic acid ester\n");
  9620.   if (fg[fg_phosphine - 1])
  9621.     printf ("phosphine\n");
  9622.   if (fg[fg_phosphinoxide - 1])
  9623.     printf ("phosphine oxide\n");
  9624.   if (fg[fg_boronic_acid_deriv - 1])
  9625.     printf ("boronic acid derivative\n");
  9626.   if (fg[fg_boronic_acid - 1])
  9627.     printf ("boronic acid\n");
  9628.   if (fg[fg_boronic_acid_ester - 1])
  9629.     printf ("boronic acid ester\n");
  9630.   if (fg[fg_alkene - 1])
  9631.     printf ("alkene\n");
  9632.   if (fg[fg_alkyne - 1])
  9633.     printf ("alkyne\n");
  9634.   if (fg[fg_aromatic - 1])
  9635.     printf ("aromatic compound\n");
  9636.   if (fg[fg_heterocycle - 1])
  9637.     printf ("heterocyclic compound\n");
  9638.   if (fg[fg_alpha_aminoacid - 1])
  9639.     printf ("alpha-aminoacid\n");
  9640.   if (fg[fg_alpha_hydroxyacid - 1])
  9641.     printf ("alpha-hydroxyacid\n");
  9642. }
  9643.  
  9644.  
  9645. static void
  9646. write_fg_text_de ()
  9647. {
  9648.   if (fg[fg_cation - 1])
  9649.     printf ("Kation\n");
  9650.   if (fg[fg_anion - 1])
  9651.     printf ("Anion\n");
  9652.   /*  if fg[fg_carbonyl]                       then writeln('Carbonylverbindung'); */
  9653.   if (fg[fg_aldehyde - 1])
  9654.     printf ("Aldehyd\n");
  9655.   if (fg[fg_ketone - 1])
  9656.     printf ("Keton\n");
  9657.   /*  if fg[fg_thiocarbonyl]                   then writeln('Thiocarbonylverbindung'); */
  9658.   if (fg[fg_thioaldehyde - 1])
  9659.     printf ("Thioaldehyd\n");
  9660.   if (fg[fg_thioketone - 1])
  9661.     printf ("Thioketon\n");
  9662.   if (fg[fg_imine - 1])
  9663.     printf ("Imin\n");
  9664.   if (fg[fg_hydrazone - 1])
  9665.     printf ("Hydrazon\n");
  9666.   if (fg[fg_semicarbazone - 1])
  9667.     printf ("Semicarbazon\n");
  9668.   if (fg[fg_thiosemicarbazone - 1])
  9669.     printf ("Thiosemicarbazon\n");
  9670.   if (fg[fg_oxime - 1])
  9671.     printf ("Oxim\n");
  9672.   if (fg[fg_oxime_ether - 1])
  9673.     printf ("Oximether\n");
  9674.   if (fg[fg_ketene - 1])
  9675.     printf ("Keten\n");
  9676.   if (fg[fg_ketene_acetal_deriv - 1])
  9677.     printf ("Keten-Acetal oder Derivat\n");
  9678.   if (fg[fg_carbonyl_hydrate - 1])
  9679.     printf ("Carbonyl-Hydrat\n");
  9680.   if (fg[fg_hemiacetal - 1])
  9681.     printf ("Halbacetal\n");
  9682.   if (fg[fg_acetal - 1])
  9683.     printf ("Acetal\n");
  9684.   if (fg[fg_hemiaminal - 1])
  9685.     printf ("Halbaminal\n");
  9686.   if (fg[fg_aminal - 1])
  9687.     printf ("Aminal\n");
  9688.   if (fg[fg_thiohemiaminal - 1])
  9689.     printf ("Thiohalbaminal\n");
  9690.   if (fg[fg_thioacetal - 1])
  9691.     printf ("Thioacetal\n");
  9692.   if (fg[fg_enamine - 1])
  9693.     printf ("Enamin\n");
  9694.   if (fg[fg_enol - 1])
  9695.     printf ("Enol\n");
  9696.   if (fg[fg_enolether - 1])
  9697.     printf ("Enolether\n");
  9698.   if (fg[fg_hydroxy - 1] && hydroxy_generic)
  9699.     printf ("Hydroxy-Verbindung\n");
  9700.   /*  if fg[fg_alcohol]                        then writeln('Alkohol'); */
  9701.   if (fg[fg_prim_alcohol - 1])
  9702.     printf ("prim\344rer Alkohol\n");
  9703. /* p2c: checkmol.pas, line 7283: Note: character >= 128 encountered [281] */
  9704.   if (fg[fg_sec_alcohol - 1])
  9705.     printf ("sekund\344rer Alkohol\n");
  9706. /* p2c: checkmol.pas, line 7284: Note: character >= 128 encountered [281] */
  9707.   if (fg[fg_tert_alcohol - 1])
  9708.     printf ("terti\344rer Alkohol\n");
  9709. /* p2c: checkmol.pas, line 7285: Note: character >= 128 encountered [281] */
  9710.   if (fg[fg_1_2_diol - 1])
  9711.     printf ("1,2-Diol\n");
  9712.   if (fg[fg_1_2_aminoalcohol - 1])
  9713.     printf ("1,2-Aminoalkohol\n");
  9714.   if (fg[fg_phenol - 1])
  9715.     printf ("Phenol oder Hydroxyhetaren\n");
  9716.   if (fg[fg_1_2_diphenol - 1])
  9717.     printf ("1,2-Diphenol\n");
  9718.   if (fg[fg_enediol - 1])
  9719.     printf ("Endiol\n");
  9720.   if (fg[fg_ether - 1] && ether_generic)
  9721.     printf ("Ether\n");
  9722.   if (fg[fg_dialkylether - 1])
  9723.     printf ("Dialkylether\n");
  9724.   if (fg[fg_alkylarylether - 1])
  9725.     printf ("Alkylarylether \n");
  9726.   if (fg[fg_diarylether - 1])
  9727.     printf ("Diarylether\n");
  9728.   if (fg[fg_thioether - 1])
  9729.     printf ("Thioether\n");
  9730.   if (fg[fg_disulfide - 1])
  9731.     printf ("Disulfid\n");
  9732.   if (fg[fg_peroxide - 1])
  9733.     printf ("Peroxid\n");
  9734.   if (fg[fg_hydroperoxide - 1])
  9735.     printf ("Hydroperoxid\n");
  9736.   if (fg[fg_hydrazine - 1])
  9737.     printf ("Hydrazin-Derivat\n");
  9738.   if (fg[fg_hydroxylamine - 1])
  9739.     printf ("Hydroxylamin\n");
  9740.   if (fg[fg_amine - 1] && amine_generic)
  9741.     printf ("Amin\n");
  9742.   if (fg[fg_prim_amine - 1])
  9743.     printf ("prim\344res Amin\n");
  9744. /* p2c: checkmol.pas, line 7302: Note: character >= 128 encountered [281] */
  9745.   if (fg[fg_prim_aliph_amine - 1])
  9746.     printf ("prim\344res aliphatisches Amin (Alkylamin)\n");
  9747. /* p2c: checkmol.pas, line 7303: Note: character >= 128 encountered [281] */
  9748.   if (fg[fg_prim_arom_amine - 1])
  9749.     printf ("prim\344res aromatisches Amin\n");
  9750. /* p2c: checkmol.pas, line 7304: Note: character >= 128 encountered [281] */
  9751.   if (fg[fg_sec_amine - 1])
  9752.     printf ("sekund\344res Amin\n");
  9753. /* p2c: checkmol.pas, line 7305: Note: character >= 128 encountered [281] */
  9754.   if (fg[fg_sec_aliph_amine - 1])
  9755.     printf ("sekund\344res aliphatisches Amin (Dialkylamin)\n");
  9756. /* p2c: checkmol.pas, line 7306: Note: character >= 128 encountered [281] */
  9757.   if (fg[fg_sec_mixed_amine - 1])
  9758.     printf
  9759.       ("sekund\344res aliphatisches/aromatisches Amin (Alkylarylamin)\n");
  9760. /* p2c: checkmol.pas, line 7307: Note: character >= 128 encountered [281] */
  9761.   if (fg[fg_sec_arom_amine - 1])
  9762.     printf ("sekund\344res aromatisches Amin (Diarylamin)\n");
  9763. /* p2c: checkmol.pas, line 7308: Note: character >= 128 encountered [281] */
  9764.   if (fg[fg_tert_amine - 1])
  9765.     printf ("terti\344res Amin\n");
  9766. /* p2c: checkmol.pas, line 7309: Note: character >= 128 encountered [281] */
  9767.   if (fg[fg_tert_aliph_amine - 1])
  9768.     printf ("terti\344res aliphatisches Amin (Trialkylamin)\n");
  9769. /* p2c: checkmol.pas, line 7310: Note: character >= 128 encountered [281] */
  9770.   if (fg[fg_tert_mixed_amine - 1])
  9771.     printf ("terti\344res aliphatisches/aromatisches Amin (Alkylarylamin)\n");
  9772. /* p2c: checkmol.pas, line 7311: Note: character >= 128 encountered [281] */
  9773.   if (fg[fg_tert_arom_amine - 1])
  9774.     printf ("terti\344res aromatisches Amin (Triarylamin)\n");
  9775. /* p2c: checkmol.pas, line 7312: Note: character >= 128 encountered [281] */
  9776.   if (fg[fg_quart_ammonium - 1])
  9777.     printf ("quart\344res Ammoniumsalz\n");
  9778. /* p2c: checkmol.pas, line 7313: Note: character >= 128 encountered [281] */
  9779.   if (fg[fg_n_oxide - 1])
  9780.     printf ("N-Oxid\n");
  9781.   /* new in v0.2f */
  9782.   if (fg[fg_halogen_deriv - 1])
  9783.     {
  9784.       if (!fg[fg_alkyl_halide - 1] && !fg[fg_aryl_halide - 1] &&
  9785.           !fg[fg_acyl_halide - 1])
  9786.         printf ("Halogenverbindung\n");
  9787.     }
  9788.   /*  if fg[fg_alkyl_halide]                   then writeln('Alkylhalogenid'); */
  9789.   if (fg[fg_alkyl_fluoride - 1])
  9790.     printf ("Alkylfluorid\n");
  9791.   if (fg[fg_alkyl_chloride - 1])
  9792.     printf ("Alkylchlorid\n");
  9793.   if (fg[fg_alkyl_bromide - 1])
  9794.     printf ("Alkylbromid\n");
  9795.   if (fg[fg_alkyl_iodide - 1])
  9796.     printf ("Alkyliodid\n");
  9797.   /*  if fg[fg_aryl_halide]                    then writeln('Arylhalogenid'); */
  9798.   if (fg[fg_aryl_fluoride - 1])
  9799.     printf ("Arylfluorid\n");
  9800.   if (fg[fg_aryl_chloride - 1])
  9801.     printf ("Arylchlorid\n");
  9802.   if (fg[fg_aryl_bromide - 1])
  9803.     printf ("Arylbromid\n");
  9804.   if (fg[fg_aryl_iodide - 1])
  9805.     printf ("Aryliodid\n");
  9806.   if (fg[fg_organometallic - 1])
  9807.     printf ("Organometall-Verbindung\n");
  9808.   if (fg[fg_organolithium - 1])
  9809.     printf ("Organolithium-Verbindung\n");
  9810.   if (fg[fg_organomagnesium - 1])
  9811.     printf ("Organomagnesium-Verbindung\n");
  9812.   /*  if fg[fg_carboxylic_acid_deriv]          then writeln('Carbonsäure-Derivat'); */
  9813.   if (fg[fg_carboxylic_acid - 1])
  9814.     printf ("Carbons\344ure\n");
  9815. /* p2c: checkmol.pas, line 7335: Note: character >= 128 encountered [281] */
  9816.   if (fg[fg_carboxylic_acid_salt - 1])
  9817.     printf ("Carbons\344uresalz\n");
  9818. /* p2c: checkmol.pas, line 7336: Note: character >= 128 encountered [281] */
  9819.   if (fg[fg_carboxylic_acid_ester - 1])
  9820.     printf ("Carbons\344ureester\n");
  9821. /* p2c: checkmol.pas, line 7337: Note: character >= 128 encountered [281] */
  9822.   if (fg[fg_lactone - 1])
  9823.     printf ("Lacton\n");
  9824.   /*  if fg[fg_carboxylic_acid_amide]          then writeln('Carbonsäureamid'); */
  9825.   if (fg[fg_carboxylic_acid_prim_amide - 1])
  9826.     printf ("prim\344res Carbons\344ureamid\n");
  9827. /* p2c: checkmol.pas, line 7340:
  9828.  * Note: characters >= 128 encountered [281] */
  9829.   if (fg[fg_carboxylic_acid_sec_amide - 1])
  9830.     printf ("sekund\344res Carbons\344ureamid\n");
  9831. /* p2c: checkmol.pas, line 7341:
  9832.  * Note: characters >= 128 encountered [281] */
  9833.   if (fg[fg_carboxylic_acid_tert_amide - 1])
  9834.     printf ("terti\344res Carbons\344ureamid\n");
  9835. /* p2c: checkmol.pas, line 7342:
  9836.  * Note: characters >= 128 encountered [281] */
  9837.   if (fg[fg_lactam - 1])
  9838.     printf ("Lactam\n");
  9839.   if (fg[fg_carboxylic_acid_hydrazide - 1])
  9840.     printf ("Carbons\344urehydrazid\n");
  9841. /* p2c: checkmol.pas, line 7344: Note: character >= 128 encountered [281] */
  9842.   if (fg[fg_carboxylic_acid_azide - 1])
  9843.     printf ("Carbons\344ureazid\n");
  9844. /* p2c: checkmol.pas, line 7345: Note: character >= 128 encountered [281] */
  9845.   if (fg[fg_hydroxamic_acid - 1])
  9846.     printf ("Hydroxams\344ure\n");
  9847. /* p2c: checkmol.pas, line 7346: Note: character >= 128 encountered [281] */
  9848.   if (fg[fg_carboxylic_acid_amidine - 1])
  9849.     printf ("Carbons\344ureamidin\n");
  9850. /* p2c: checkmol.pas, line 7347: Note: character >= 128 encountered [281] */
  9851.   if (fg[fg_carboxylic_acid_amidrazone - 1])
  9852.     printf ("Carbons\344ureamidrazon\n");
  9853. /* p2c: checkmol.pas, line 7348: Note: character >= 128 encountered [281] */
  9854.   if (fg[fg_nitrile - 1])
  9855.     printf ("Carbonitril\n");
  9856.   /*  if fg[fg_acyl_halide]                    then writeln('Acylhalogenid'); */
  9857.   if (fg[fg_acyl_fluoride - 1])
  9858.     printf ("Acylfluorid\n");
  9859.   if (fg[fg_acyl_chloride - 1])
  9860.     printf ("Acylchlorid\n");
  9861.   if (fg[fg_acyl_bromide - 1])
  9862.     printf ("Acylbromid\n");
  9863.   if (fg[fg_acyl_iodide - 1])
  9864.     printf ("Acyliodid\n");
  9865.   if (fg[fg_acyl_cyanide - 1])
  9866.     printf ("Acylcyanid\n");
  9867.   if (fg[fg_imido_ester - 1])
  9868.     printf ("Imidoester\n");
  9869.   if (fg[fg_imidoyl_halide - 1])
  9870.     printf ("Imidoylhalogenid\n");
  9871.   /*  if fg[fg_thiocarboxylic_acid_deriv]      then writeln('Thiocarbonsäure-Derivat'); */
  9872.   if (fg[fg_thiocarboxylic_acid - 1])
  9873.     printf ("Thiocarbons\344ure\n");
  9874. /* p2c: checkmol.pas, line 7359: Note: character >= 128 encountered [281] */
  9875.   if (fg[fg_thiocarboxylic_acid_ester - 1])
  9876.     printf ("Thiocarbons\344ureester\n");
  9877. /* p2c: checkmol.pas, line 7360: Note: character >= 128 encountered [281] */
  9878.   if (fg[fg_thiolactone - 1])
  9879.     printf ("Thiolacton\n");
  9880.   if (fg[fg_thiocarboxylic_acid_amide - 1])
  9881.     printf ("Thiocarbons\344ureamid\n");
  9882. /* p2c: checkmol.pas, line 7362: Note: character >= 128 encountered [281] */
  9883.   if (fg[fg_thiolactam - 1])
  9884.     printf ("Thiolactam\n");
  9885.   if (fg[fg_imido_thioester - 1])
  9886.     printf ("Imidothioester\n");
  9887.   if (fg[fg_oxohetarene - 1])
  9888.     printf ("Oxo(het)aren\n");
  9889.   if (fg[fg_thioxohetarene - 1])
  9890.     printf ("Thioxo(het)aren\n");
  9891.   if (fg[fg_iminohetarene - 1])
  9892.     printf ("Imino(het)aren\n");
  9893.   if (fg[fg_orthocarboxylic_acid_deriv - 1])
  9894.     printf ("Orthocarbons\344ure-Derivat\n");
  9895. /* p2c: checkmol.pas, line 7368: Note: character >= 128 encountered [281] */
  9896.   if (fg[fg_carboxylic_acid_orthoester - 1])
  9897.     printf ("Orthoester\n");
  9898.   if (fg[fg_carboxylic_acid_amide_acetal - 1])
  9899.     printf ("Amidacetal\n");
  9900.   if (fg[fg_carboxylic_acid_anhydride - 1])
  9901.     printf ("Carbons\344ureanhydrid\n");
  9902. /* p2c: checkmol.pas, line 7371: Note: character >= 128 encountered [281] */
  9903.   /*  if fg[fg_carboxylic_acid_imide]          then writeln('Carbonsäureimid'); */
  9904.   if (fg[fg_carboxylic_acid_unsubst_imide - 1])
  9905.     printf ("Carbons\344ureimid, N-unsubstituiert\n");
  9906. /* p2c: checkmol.pas, line 7373: Note: character >= 128 encountered [281] */
  9907.   if (fg[fg_carboxylic_acid_subst_imide - 1])
  9908.     printf ("Carbons\344ureimid, N-substituiert\n");
  9909. /* p2c: checkmol.pas, line 7374: Note: character >= 128 encountered [281] */
  9910.   if (fg[fg_co2_deriv - 1])
  9911.     printf ("CO2-Derivat (allgemein)\n");
  9912.   if (fg[fg_carbonic_acid_deriv - 1] &&
  9913.       !(fg[fg_carbonic_acid_monoester - 1]
  9914.         || fg[fg_carbonic_acid_diester - 1]
  9915.         || fg[fg_carbonic_acid_ester_halide - 1]))
  9916.     /* changed in v0.3c */
  9917.     printf ("Kohlens\344ure-Derivat\n");
  9918. /* p2c: checkmol.pas, line 7379: Note: character >= 128 encountered [281] */
  9919.   if (fg[fg_carbonic_acid_monoester - 1])
  9920.     printf ("Kohlens\344uremonoester\n");
  9921. /* p2c: checkmol.pas, line 7380: Note: character >= 128 encountered [281] */
  9922.   if (fg[fg_carbonic_acid_diester - 1])
  9923.     printf ("Kohlens\344urediester\n");
  9924. /* p2c: checkmol.pas, line 7381: Note: character >= 128 encountered [281] */
  9925.   if (fg[fg_carbonic_acid_ester_halide - 1])
  9926.     printf ("Kohlens\344ureesterhalogenid (Alkyl/Aryl-Halogenformiat)\n");
  9927. /* p2c: checkmol.pas, line 7382: Note: character >= 128 encountered [281] */
  9928.   if (fg[fg_thiocarbonic_acid_deriv - 1])
  9929.     printf ("Thiokohlens\344ure-Derivat\n");
  9930. /* p2c: checkmol.pas, line 7383: Note: character >= 128 encountered [281] */
  9931.   if (fg[fg_thiocarbonic_acid_monoester - 1])
  9932.     printf ("Thiokohlens\344uremonoester\n");
  9933. /* p2c: checkmol.pas, line 7384: Note: character >= 128 encountered [281] */
  9934.   if (fg[fg_thiocarbonic_acid_diester - 1])
  9935.     printf ("Thiokohlens\344urediester\n");
  9936. /* p2c: checkmol.pas, line 7385: Note: character >= 128 encountered [281] */
  9937.   if (fg[fg_thiocarbonic_acid_ester_halide - 1])
  9938.     printf
  9939.       ("Thiokohlens\344ureesterhalogenid (Alkyl/Aryl-Halogenthioformiat)\n");
  9940. /* p2c: checkmol.pas, line 7386: Note: character >= 128 encountered [281] */
  9941.   if (fg[fg_carbamic_acid_deriv - 1] &&
  9942.       !(fg[fg_carbamic_acid - 1] || fg[fg_carbamic_acid_ester - 1] ||
  9943.         fg[fg_carbamic_acid_halide - 1]))
  9944.     /* changed in v0.3c */
  9945.     printf ("Carbamins\344ure-Derivat\n");
  9946. /* p2c: checkmol.pas, line 7390: Note: character >= 128 encountered [281] */
  9947.   if (fg[fg_carbamic_acid - 1])
  9948.     printf ("Carbamins\344ure\n");
  9949. /* p2c: checkmol.pas, line 7391: Note: character >= 128 encountered [281] */
  9950.   if (fg[fg_carbamic_acid_ester - 1])
  9951.     printf ("Carbamins\344ureester (Urethan)\n");
  9952. /* p2c: checkmol.pas, line 7392: Note: character >= 128 encountered [281] */
  9953.   if (fg[fg_carbamic_acid_halide - 1])
  9954.     printf ("Carbamins\344urehalogenid (Halogenformamid)\n");
  9955. /* p2c: checkmol.pas, line 7393: Note: character >= 128 encountered [281] */
  9956.   if (fg[fg_thiocarbamic_acid_deriv - 1] &&
  9957.       !(fg[fg_thiocarbamic_acid - 1] || fg[fg_thiocarbamic_acid_ester - 1]
  9958.         || fg[fg_thiocarbamic_acid_halide - 1]))
  9959.     /* changed in v0.3c */
  9960.     printf ("Thiocarbamins\344ure-Derivat\n");
  9961. /* p2c: checkmol.pas, line 7397: Note: character >= 128 encountered [281] */
  9962.   if (fg[fg_thiocarbamic_acid - 1])
  9963.     printf ("Thiocarbamins\344ure\n");
  9964. /* p2c: checkmol.pas, line 7398: Note: character >= 128 encountered [281] */
  9965.   if (fg[fg_thiocarbamic_acid_ester - 1])
  9966.     printf ("Thiocarbamins\344ureester\n");
  9967. /* p2c: checkmol.pas, line 7399: Note: character >= 128 encountered [281] */
  9968.   if (fg[fg_thiocarbamic_acid_halide - 1])
  9969.     printf ("Thiocarbamins\344urehalogenid (Halogenthioformamid)\n");
  9970. /* p2c: checkmol.pas, line 7400: Note: character >= 128 encountered [281] */
  9971.   if (fg[fg_urea - 1])
  9972.     printf ("Harnstoff\n");
  9973.   if (fg[fg_isourea - 1])
  9974.     printf ("Isoharnstoff\n");
  9975.   if (fg[fg_thiourea - 1])
  9976.     printf ("Thioharnstoff\n");
  9977.   if (fg[fg_isothiourea - 1])
  9978.     printf ("Isothioharnstoff\n");
  9979.   if (fg[fg_guanidine - 1])
  9980.     printf ("Guanidin\n");
  9981.   if (fg[fg_semicarbazide - 1])
  9982.     printf ("Semicarbazid\n");
  9983.   if (fg[fg_thiosemicarbazide - 1])
  9984.     printf ("Thiosemicarbazid\n");
  9985.   if (fg[fg_azide - 1])
  9986.     printf ("Azid\n");
  9987.   if (fg[fg_azo_compound - 1])
  9988.     printf ("Azoverbindung\n");
  9989.   if (fg[fg_diazonium_salt - 1])
  9990.     printf ("Diazoniumsalz\n");
  9991.   if (fg[fg_isonitrile - 1])
  9992.     printf ("Isonitril\n");
  9993.   if (fg[fg_cyanate - 1])
  9994.     printf ("Cyanat\n");
  9995.   if (fg[fg_isocyanate - 1])
  9996.     printf ("Isocyanat\n");
  9997.   if (fg[fg_thiocyanate - 1])
  9998.     printf ("Thiocyanat\n");
  9999.   if (fg[fg_isothiocyanate - 1])
  10000.     printf ("Isothiocyanat\n");
  10001.   if (fg[fg_carbodiimide - 1])
  10002.     printf ("Carbodiimid\n");
  10003.   if (fg[fg_nitroso_compound - 1])
  10004.     printf ("Nitroso-Verbindung\n");
  10005.   if (fg[fg_nitro_compound - 1])
  10006.     printf ("Nitro-Verbindung\n");
  10007.   if (fg[fg_nitrite - 1])
  10008.     printf ("Nitrit\n");
  10009.   if (fg[fg_nitrate - 1])
  10010.     printf ("Nitrat\n");
  10011.   /*  if fg[fg_sulfuric_acid_deriv]            then writeln('Schwefelsäure-Derivat'); */
  10012.   if (fg[fg_sulfuric_acid - 1])
  10013.     printf ("Schwefels\344ure\n");
  10014. /* p2c: checkmol.pas, line 7422: Note: character >= 128 encountered [281] */
  10015.   if (fg[fg_sulfuric_acid_monoester - 1])
  10016.     printf ("Schwefels\344uremonoester\n");
  10017. /* p2c: checkmol.pas, line 7423: Note: character >= 128 encountered [281] */
  10018.   if (fg[fg_sulfuric_acid_diester - 1])
  10019.     printf ("Schwefels\344urediester\n");
  10020. /* p2c: checkmol.pas, line 7424: Note: character >= 128 encountered [281] */
  10021.   if (fg[fg_sulfuric_acid_amide_ester - 1])
  10022.     printf ("Schwefels\344ureamidester\n");
  10023. /* p2c: checkmol.pas, line 7425: Note: character >= 128 encountered [281] */
  10024.   if (fg[fg_sulfuric_acid_amide - 1])
  10025.     printf ("Schwefels\344ureamid\n");
  10026. /* p2c: checkmol.pas, line 7426: Note: character >= 128 encountered [281] */
  10027.   if (fg[fg_sulfuric_acid_diamide - 1])
  10028.     printf ("Schwefels\344urediamid\n");
  10029. /* p2c: checkmol.pas, line 7427: Note: character >= 128 encountered [281] */
  10030.   if (fg[fg_sulfuryl_halide - 1])
  10031.     printf ("Sulfurylhalogenid\n");
  10032.   /*  if fg[fg_sulfonic_acid_deriv]            then writeln('Sulfonsäure-Derivat '); */
  10033.   if (fg[fg_sulfonic_acid - 1])
  10034.     printf ("Sulfons\344ure\n");
  10035. /* p2c: checkmol.pas, line 7430: Note: character >= 128 encountered [281] */
  10036.   if (fg[fg_sulfonic_acid_ester - 1])
  10037.     printf ("Sulfons\344ureester\n");
  10038. /* p2c: checkmol.pas, line 7431: Note: character >= 128 encountered [281] */
  10039.   if (fg[fg_sulfonamide - 1])
  10040.     printf ("Sulfonamid\n");
  10041.   if (fg[fg_sulfonyl_halide - 1])
  10042.     printf ("Sulfonylhalogenid\n");
  10043.   if (fg[fg_sulfone - 1])
  10044.     printf ("Sulfon\n");
  10045.   if (fg[fg_sulfoxide - 1])
  10046.     printf ("Sulfoxid\n");
  10047.   /*  if fg[fg_sulfinic_acid_deriv]            then writeln('Sulfinsäure-Derivat'); */
  10048.   if (fg[fg_sulfinic_acid - 1])
  10049.     printf ("Sulfins\344ure\n");
  10050. /* p2c: checkmol.pas, line 7437: Note: character >= 128 encountered [281] */
  10051.   if (fg[fg_sulfinic_acid_ester - 1])
  10052.     printf ("Sulfins\344ureester\n");
  10053. /* p2c: checkmol.pas, line 7438: Note: character >= 128 encountered [281] */
  10054.   if (fg[fg_sulfinic_acid_halide - 1])
  10055.     printf ("Sulfins\344urehalogenid\n");
  10056. /* p2c: checkmol.pas, line 7439: Note: character >= 128 encountered [281] */
  10057.   if (fg[fg_sulfinic_acid_amide - 1])
  10058.     printf ("Sulfins\344ureamid\n");
  10059. /* p2c: checkmol.pas, line 7440: Note: character >= 128 encountered [281] */
  10060.   /*  if fg[fg_sulfenic_acid_deriv]            then writeln('Sulfensäure-Derivat'); */
  10061.   if (fg[fg_sulfenic_acid - 1])
  10062.     printf ("Sulfens\344ure\n");
  10063. /* p2c: checkmol.pas, line 7442: Note: character >= 128 encountered [281] */
  10064.   if (fg[fg_sulfenic_acid_ester - 1])
  10065.     printf ("Sulfens\344ureester\n");
  10066. /* p2c: checkmol.pas, line 7443: Note: character >= 128 encountered [281] */
  10067.   if (fg[fg_sulfenic_acid_halide - 1])
  10068.     printf ("Sulfens\344urehalogenid\n");
  10069. /* p2c: checkmol.pas, line 7444: Note: character >= 128 encountered [281] */
  10070.   if (fg[fg_sulfenic_acid_amide - 1])
  10071.     printf ("Sulfens\344ureamid\n");
  10072. /* p2c: checkmol.pas, line 7445: Note: character >= 128 encountered [281] */
  10073.   if (fg[fg_thiol - 1])
  10074.     printf ("Thiol (Sulfanyl-Verbindung, Mercaptan)\n");
  10075.   if (fg[fg_alkylthiol - 1])
  10076.     printf ("Alkylthiol\n");
  10077.   if (fg[fg_arylthiol - 1])
  10078.     printf ("Arylthiol\n");
  10079.   /*  if fg[fg_phosphoric_acid_deriv]          then writeln('Phosphorsäure-Derivat'); */
  10080.   if (fg[fg_phosphoric_acid - 1])
  10081.     printf ("Phosphors\344ure\n");
  10082. /* p2c: checkmol.pas, line 7450: Note: character >= 128 encountered [281] */
  10083.   if (fg[fg_phosphoric_acid_ester - 1])
  10084.     printf ("Phosphors\344ureester\n");
  10085. /* p2c: checkmol.pas, line 7451: Note: character >= 128 encountered [281] */
  10086.   if (fg[fg_phosphoric_acid_halide - 1])
  10087.     printf ("Phosphors\344urehalogenid\n");
  10088. /* p2c: checkmol.pas, line 7452: Note: character >= 128 encountered [281] */
  10089.   if (fg[fg_phosphoric_acid_amide - 1])
  10090.     printf ("Phosphors\344ureamid\n");
  10091. /* p2c: checkmol.pas, line 7453: Note: character >= 128 encountered [281] */
  10092.   /*  if fg[fg_thiophosphoric_acid_deriv]      then writeln('Thiophosphorsäure-Derivat'); */
  10093.   if (fg[fg_thiophosphoric_acid - 1])
  10094.     printf ("Thiophosphors\344ure\n");
  10095. /* p2c: checkmol.pas, line 7455: Note: character >= 128 encountered [281] */
  10096.   if (fg[fg_thiophosphoric_acid_ester - 1])
  10097.     printf ("Thiophosphors\344ureester\n");
  10098. /* p2c: checkmol.pas, line 7456: Note: character >= 128 encountered [281] */
  10099.   if (fg[fg_thiophosphoric_acid_halide - 1])
  10100.     printf ("Thiophosphors\344urehalogenid\n");
  10101. /* p2c: checkmol.pas, line 7457: Note: character >= 128 encountered [281] */
  10102.   if (fg[fg_thiophosphoric_acid_amide - 1])
  10103.     printf ("Thiophosphors\344ureamid\n");
  10104. /* p2c: checkmol.pas, line 7458: Note: character >= 128 encountered [281] */
  10105.   if (fg[fg_phosphonic_acid_deriv - 1])
  10106.     printf ("Phosphons\344ure-Derivat \n");
  10107. /* p2c: checkmol.pas, line 7459: Note: character >= 128 encountered [281] */
  10108.   if (fg[fg_phosphonic_acid - 1])
  10109.     printf ("Phosphons\344ure\n");
  10110. /* p2c: checkmol.pas, line 7460: Note: character >= 128 encountered [281] */
  10111.   if (fg[fg_phosphonic_acid_ester - 1])
  10112.     printf ("Phosphons\344ureester\n");
  10113. /* p2c: checkmol.pas, line 7461: Note: character >= 128 encountered [281] */
  10114.   if (fg[fg_phosphine - 1])
  10115.     printf ("Phosphin\n");
  10116.   if (fg[fg_phosphinoxide - 1])
  10117.     printf ("Phosphinoxid\n");
  10118.   if (fg[fg_boronic_acid_deriv - 1])
  10119.     printf ("Borons\344ure-Derivat\n");
  10120. /* p2c: checkmol.pas, line 7464: Note: character >= 128 encountered [281] */
  10121.   if (fg[fg_boronic_acid - 1])
  10122.     printf ("Borons\344ure\n");
  10123. /* p2c: checkmol.pas, line 7465: Note: character >= 128 encountered [281] */
  10124.   if (fg[fg_boronic_acid_ester - 1])
  10125.     printf ("Borons\344ureester\n");
  10126. /* p2c: checkmol.pas, line 7466: Note: character >= 128 encountered [281] */
  10127.   if (fg[fg_alkene - 1])
  10128.     printf ("Alken\n");
  10129.   if (fg[fg_alkyne - 1])
  10130.     printf ("Alkin\n");
  10131.   if (fg[fg_aromatic - 1])
  10132.     printf ("aromatische Verbindung\n");
  10133.   if (fg[fg_heterocycle - 1])
  10134.     printf ("heterocyclische Verbindung\n");
  10135.   if (fg[fg_alpha_aminoacid - 1])
  10136.     printf ("alpha-Aminos\344ure\n");
  10137. /* p2c: checkmol.pas, line 7471: Note: character >= 128 encountered [281] */
  10138.   if (fg[fg_alpha_hydroxyacid - 1])
  10139.     printf ("alpha-Hydroxys\344ure\n");
  10140. /* p2c: checkmol.pas, line 7472: Note: character >= 128 encountered [281] */
  10141. }
  10142.  
  10143.  
  10144. #define sc              ';'
  10145.  
  10146.  
  10147. static void
  10148. write_fg_code ()
  10149. {
  10150.   if (fg[fg_cation - 1])
  10151.     printf ("000000T2%c", sc);
  10152.   if (fg[fg_anion - 1])
  10153.     printf ("000000T1%c", sc);
  10154.   /*  if fg[fg_carbonyl]                       then write('C2O10000',sc); */
  10155.   if (fg[fg_aldehyde - 1])
  10156.     printf ("C2O1H000%c", sc);
  10157.   if (fg[fg_ketone - 1])
  10158.     printf ("C2O1C000%c", sc);
  10159.   /*  if fg[fg_thiocarbonyl]                   then write('C2S10000',sc); */
  10160.   if (fg[fg_thioaldehyde - 1])
  10161.     printf ("C2S1H000%c", sc);
  10162.   if (fg[fg_thioketone - 1])
  10163.     printf ("C2S1C000%c", sc);
  10164.   if (fg[fg_imine - 1])
  10165.     printf ("C2N10000%c", sc);
  10166.   if (fg[fg_hydrazone - 1])
  10167.     printf ("C2N1N000%c", sc);
  10168.   if (fg[fg_semicarbazone - 1])
  10169.     printf ("C2NNC4ON%c", sc);
  10170.   if (fg[fg_thiosemicarbazone - 1])
  10171.     printf ("C2NNC4SN%c", sc);
  10172.   if (fg[fg_oxime - 1])
  10173.     printf ("C2N1OH00%c", sc);
  10174.   if (fg[fg_oxime_ether - 1])
  10175.     printf ("C2N1OC00%c", sc);
  10176.   if (fg[fg_ketene - 1])
  10177.     printf ("C3OC0000%c", sc);
  10178.   if (fg[fg_ketene_acetal_deriv - 1])
  10179.     printf ("C3OCC000%c", sc);
  10180.   if (fg[fg_carbonyl_hydrate - 1])
  10181.     printf ("C2O2H200%c", sc);
  10182.   if (fg[fg_hemiacetal - 1])
  10183.     printf ("C2O2HC00%c", sc);
  10184.   if (fg[fg_acetal - 1])
  10185.     printf ("C2O2CC00%c", sc);
  10186.   if (fg[fg_hemiaminal - 1])
  10187.     printf ("C2NOHC10%c", sc);
  10188.   if (fg[fg_aminal - 1])
  10189.     printf ("C2N2CC10%c", sc);
  10190.   if (fg[fg_thiohemiaminal - 1])
  10191.     printf ("C2NSHC10%c", sc);
  10192.   if (fg[fg_thioacetal - 1])
  10193.     printf ("C2S2CC00%c", sc);
  10194.   if (fg[fg_enamine - 1])
  10195.     printf ("C2CNH000%c", sc);
  10196.   if (fg[fg_enol - 1])
  10197.     printf ("C2COH000%c", sc);
  10198.   if (fg[fg_enolether - 1])
  10199.     printf ("C2COC000%c", sc);
  10200.   if (fg[fg_hydroxy - 1] && hydroxy_generic)
  10201.     printf ("O1H00000%c", sc);
  10202.   /*  if fg[fg_alcohol]                        then write('O1H0C000',sc); */
  10203.   if (fg[fg_prim_alcohol - 1])
  10204.     printf ("O1H1C000%c", sc);
  10205.   if (fg[fg_sec_alcohol - 1])
  10206.     printf ("O1H2C000%c", sc);
  10207.   if (fg[fg_tert_alcohol - 1])
  10208.     printf ("O1H3C000%c", sc);
  10209.   if (fg[fg_1_2_diol - 1])
  10210.     printf ("O1H0CO1H%c", sc);
  10211.   if (fg[fg_1_2_aminoalcohol - 1])
  10212.     printf ("O1H0CN1C%c", sc);
  10213.   if (fg[fg_phenol - 1])
  10214.     printf ("O1H1A000%c", sc);
  10215.   if (fg[fg_1_2_diphenol - 1])
  10216.     printf ("O1H2A000%c", sc);
  10217.   if (fg[fg_enediol - 1])
  10218.     printf ("C2COH200%c", sc);
  10219.   if (fg[fg_ether - 1] && ether_generic)
  10220.     printf ("O1C00000%c", sc);
  10221.   if (fg[fg_dialkylether - 1])
  10222.     printf ("O1C0CC00%c", sc);
  10223.   if (fg[fg_alkylarylether - 1])
  10224.     printf ("O1C0CA00%c", sc);
  10225.   if (fg[fg_diarylether - 1])
  10226.     printf ("O1C0AA00%c", sc);
  10227.   if (fg[fg_thioether - 1])
  10228.     printf ("S1C00000%c", sc);
  10229.   if (fg[fg_disulfide - 1])
  10230.     printf ("S1S1C000%c", sc);
  10231.   if (fg[fg_peroxide - 1])
  10232.     printf ("O1O1C000%c", sc);
  10233.   if (fg[fg_hydroperoxide - 1])
  10234.     printf ("O1O1H000%c", sc);
  10235.   if (fg[fg_hydrazine - 1])
  10236.     printf ("N1N10000%c", sc);
  10237.   if (fg[fg_hydroxylamine - 1])
  10238.     printf ("N1O1H000%c", sc);
  10239.   if (fg[fg_amine - 1] && amine_generic)
  10240.     printf ("N1C00000%c", sc);
  10241.   /*  if fg[fg_prim_amine]                     then write('N1C10000',sc); */
  10242.   if (fg[fg_prim_aliph_amine - 1])
  10243.     printf ("N1C1C000%c", sc);
  10244.   if (fg[fg_prim_arom_amine - 1])
  10245.     printf ("N1C1A000%c", sc);
  10246.   /*  if fg[fg_sec_amine]                      then write('N1C20000',sc); */
  10247.   if (fg[fg_sec_aliph_amine - 1])
  10248.     printf ("N1C2CC00%c", sc);
  10249.   if (fg[fg_sec_mixed_amine - 1])
  10250.     printf ("N1C2AC00%c", sc);
  10251.   if (fg[fg_sec_arom_amine - 1])
  10252.     printf ("N1C2AA00%c", sc);
  10253.   /*  if fg[fg_tert_amine]                     then write('N1C30000',sc); */
  10254.   if (fg[fg_tert_aliph_amine - 1])
  10255.     printf ("N1C3CC00%c", sc);
  10256.   if (fg[fg_tert_mixed_amine - 1])
  10257.     printf ("N1C3AC00%c", sc);
  10258.   if (fg[fg_tert_arom_amine - 1])
  10259.     printf ("N1C3AA00%c", sc);
  10260.   if (fg[fg_quart_ammonium - 1])
  10261.     printf ("N1C400T2%c", sc);
  10262.   if (fg[fg_n_oxide - 1])
  10263.     printf ("N0O10000%c", sc);
  10264.   /*  if fg[fg_halogen_deriv]                  then write('XX000000',sc); */
  10265.   /* new in v0.2f */
  10266.   if (fg[fg_halogen_deriv - 1])
  10267.     {
  10268.       if (!fg[fg_alkyl_halide - 1] && !fg[fg_aryl_halide - 1] &&
  10269.           !fg[fg_acyl_halide - 1])
  10270.         printf ("XX000000%c", sc);
  10271.     }
  10272.   /*  if fg[fg_alkyl_halide]                   then write('XX00C000',sc); */
  10273.   if (fg[fg_alkyl_fluoride - 1])
  10274.     printf ("XF00C000%c", sc);
  10275.   if (fg[fg_alkyl_chloride - 1])
  10276.     printf ("XC00C000%c", sc);
  10277.   if (fg[fg_alkyl_bromide - 1])
  10278.     printf ("XB00C000%c", sc);
  10279.   if (fg[fg_alkyl_iodide - 1])
  10280.     printf ("XI00C000%c", sc);
  10281.   /*  if fg[fg_aryl_halide]                    then write('XX00A000',sc); */
  10282.   if (fg[fg_aryl_fluoride - 1])
  10283.     printf ("XF00A000%c", sc);
  10284.   if (fg[fg_aryl_chloride - 1])
  10285.     printf ("XC00A000%c", sc);
  10286.   if (fg[fg_aryl_bromide - 1])
  10287.     printf ("XB00A000%c", sc);
  10288.   if (fg[fg_aryl_iodide - 1])
  10289.     printf ("XI00A000%c", sc);
  10290.   if (fg[fg_organometallic - 1])
  10291.     printf ("000000MX%c", sc);
  10292.   if (fg[fg_organolithium - 1])
  10293.     printf ("000000ML%c", sc);
  10294.   if (fg[fg_organomagnesium - 1])
  10295.     printf ("000000MM%c", sc);
  10296.   /*  if fg[fg_carboxylic_acid_deriv]          then write('C3O20000',sc); */
  10297.   if (fg[fg_carboxylic_acid - 1])
  10298.     printf ("C3O2H000%c", sc);
  10299.   if (fg[fg_carboxylic_acid_salt - 1])
  10300.     printf ("C3O200T1%c", sc);
  10301.   if (fg[fg_carboxylic_acid_ester - 1])
  10302.     printf ("C3O2C000%c", sc);
  10303.   if (fg[fg_lactone - 1])
  10304.     printf ("C3O2CZ00%c", sc);
  10305.   /*  if fg[fg_carboxylic_acid_amide]          then write('C3ONC000',sc); */
  10306.   if (fg[fg_carboxylic_acid_prim_amide - 1])
  10307.     printf ("C3ONC100%c", sc);
  10308.   if (fg[fg_carboxylic_acid_sec_amide - 1])
  10309.     printf ("C3ONC200%c", sc);
  10310.   if (fg[fg_carboxylic_acid_tert_amide - 1])
  10311.     printf ("C3ONC300%c", sc);
  10312.   if (fg[fg_lactam - 1])
  10313.     printf ("C3ONCZ00%c", sc);
  10314.   if (fg[fg_carboxylic_acid_hydrazide - 1])
  10315.     printf ("C3ONN100%c", sc);
  10316.   if (fg[fg_carboxylic_acid_azide - 1])
  10317.     printf ("C3ONN200%c", sc);
  10318.   if (fg[fg_hydroxamic_acid - 1])
  10319.     printf ("C3ONOH00%c", sc);
  10320.   if (fg[fg_carboxylic_acid_amidine - 1])
  10321.     printf ("C3N2H000%c", sc);
  10322.   if (fg[fg_carboxylic_acid_amidrazone - 1])
  10323.     printf ("C3NNN100%c", sc);
  10324.   if (fg[fg_nitrile - 1])
  10325.     printf ("C3N00000%c", sc);
  10326.   /*  if fg[fg_acyl_halide]                    then write('C3OXX000',sc); */
  10327.   if (fg[fg_acyl_fluoride - 1])
  10328.     printf ("C3OXF000%c", sc);
  10329.   if (fg[fg_acyl_chloride - 1])
  10330.     printf ("C3OXC000%c", sc);
  10331.   if (fg[fg_acyl_bromide - 1])
  10332.     printf ("C3OXB000%c", sc);
  10333.   if (fg[fg_acyl_iodide - 1])
  10334.     printf ("C3OXI000%c", sc);
  10335.   if (fg[fg_acyl_cyanide - 1])
  10336.     printf ("C2OC3N00%c", sc);
  10337.   if (fg[fg_imido_ester - 1])
  10338.     printf ("C3NOC000%c", sc);
  10339.   if (fg[fg_imidoyl_halide - 1])
  10340.     printf ("C3NXX000%c", sc);
  10341.   /*  if fg[fg_thiocarboxylic_acid_deriv]      then write('C3SO0000',sc); */
  10342.   if (fg[fg_thiocarboxylic_acid - 1])
  10343.     printf ("C3SOH000%c", sc);
  10344.   if (fg[fg_thiocarboxylic_acid_ester - 1])
  10345.     printf ("C3SOC000%c", sc);
  10346.   if (fg[fg_thiolactone - 1])
  10347.     printf ("C3SOCZ00%c", sc);
  10348.   if (fg[fg_thiocarboxylic_acid_amide - 1])
  10349.     printf ("C3SNH000%c", sc);
  10350.   if (fg[fg_thiolactam - 1])
  10351.     printf ("C3SNCZ00%c", sc);
  10352.   if (fg[fg_imido_thioester - 1])
  10353.     printf ("C3NSC000%c", sc);
  10354.   if (fg[fg_oxohetarene - 1])
  10355.     printf ("C3ONAZ00%c", sc);
  10356.   if (fg[fg_thioxohetarene - 1])
  10357.     printf ("C3SNAZ00%c", sc);
  10358.   if (fg[fg_iminohetarene - 1])
  10359.     printf ("C3NNAZ00%c", sc);
  10360.   if (fg[fg_orthocarboxylic_acid_deriv - 1])
  10361.     printf ("C3O30000%c", sc);
  10362.   if (fg[fg_carboxylic_acid_orthoester - 1])
  10363.     printf ("C3O3C000%c", sc);
  10364.   if (fg[fg_carboxylic_acid_amide_acetal - 1])
  10365.     printf ("C3O3NC00%c", sc);
  10366.   if (fg[fg_carboxylic_acid_anhydride - 1])
  10367.     printf ("C3O2C3O2%c", sc);
  10368.   /*  if fg[fg_carboxylic_acid_imide]          then write('C3ONC000',sc); */
  10369.   if (fg[fg_carboxylic_acid_unsubst_imide - 1])
  10370.     printf ("C3ONCH10%c", sc);
  10371.   if (fg[fg_carboxylic_acid_subst_imide - 1])
  10372.     printf ("C3ONCC10%c", sc);
  10373.   if (fg[fg_co2_deriv - 1])
  10374.     printf ("C4000000%c", sc);
  10375.   if (fg[fg_carbonic_acid_deriv - 1])
  10376.     printf ("C4O30000%c", sc);
  10377.   if (fg[fg_carbonic_acid_monoester - 1])
  10378.     printf ("C4O3C100%c", sc);
  10379.   if (fg[fg_carbonic_acid_diester - 1])
  10380.     printf ("C4O3C200%c", sc);
  10381.   if (fg[fg_carbonic_acid_ester_halide - 1])
  10382.     printf ("C4O3CX00%c", sc);
  10383.   if (fg[fg_thiocarbonic_acid_deriv - 1])
  10384.     printf ("C4SO0000%c", sc);
  10385.   if (fg[fg_thiocarbonic_acid_monoester - 1])
  10386.     printf ("C4SOC100%c", sc);
  10387.   if (fg[fg_thiocarbonic_acid_diester - 1])
  10388.     printf ("C4SOC200%c", sc);
  10389.   if (fg[fg_thiocarbonic_acid_ester_halide - 1])
  10390.     printf ("C4SOX_00%c", sc);
  10391.   if (fg[fg_carbamic_acid_deriv - 1])
  10392.     printf ("C4O2N000%c", sc);
  10393.   if (fg[fg_carbamic_acid - 1])
  10394.     printf ("C4O2NH00%c", sc);
  10395.   if (fg[fg_carbamic_acid_ester - 1])
  10396.     printf ("C4O2NC00%c", sc);
  10397.   if (fg[fg_carbamic_acid_halide - 1])
  10398.     printf ("C4O2NX00%c", sc);
  10399.   if (fg[fg_thiocarbamic_acid_deriv - 1])
  10400.     printf ("C4SN0000%c", sc);
  10401.   if (fg[fg_thiocarbamic_acid - 1])
  10402.     printf ("C4SNOH00%c", sc);
  10403.   if (fg[fg_thiocarbamic_acid_ester - 1])
  10404.     printf ("C4SNOC00%c", sc);
  10405.   if (fg[fg_thiocarbamic_acid_halide - 1])
  10406.     printf ("C4SNXX00%c", sc);
  10407.   if (fg[fg_urea - 1])
  10408.     printf ("C4O1N200%c", sc);
  10409.   if (fg[fg_isourea - 1])
  10410.     printf ("C4N2O100%c", sc);
  10411.   if (fg[fg_thiourea - 1])
  10412.     printf ("C4S1N200%c", sc);
  10413.   if (fg[fg_isothiourea - 1])
  10414.     printf ("C4N2S100%c", sc);
  10415.   if (fg[fg_guanidine - 1])
  10416.     printf ("C4N30000%c", sc);
  10417.   if (fg[fg_semicarbazide - 1])
  10418.     printf ("C4ON2N00%c", sc);
  10419.   if (fg[fg_thiosemicarbazide - 1])
  10420.     printf ("C4SN2N00%c", sc);
  10421.   if (fg[fg_azide - 1])
  10422.     printf ("N4N20000%c", sc);
  10423.   if (fg[fg_azo_compound - 1])
  10424.     printf ("N2N10000%c", sc);
  10425.   if (fg[fg_diazonium_salt - 1])
  10426.     printf ("N3N100T2%c", sc);
  10427.   if (fg[fg_isonitrile - 1])
  10428.     printf ("N3C10000%c", sc);
  10429.   if (fg[fg_cyanate - 1])
  10430.     printf ("C4NO1000%c", sc);
  10431.   if (fg[fg_isocyanate - 1])
  10432.     printf ("C4NO2000%c", sc);
  10433.   if (fg[fg_thiocyanate - 1])
  10434.     printf ("C4NS1000%c", sc);
  10435.   if (fg[fg_isothiocyanate - 1])
  10436.     printf ("C4NS2000%c", sc);
  10437.   if (fg[fg_carbodiimide - 1])
  10438.     printf ("C4N20000%c", sc);
  10439.   if (fg[fg_nitroso_compound - 1])
  10440.     printf ("N2O10000%c", sc);
  10441.   if (fg[fg_nitro_compound - 1])
  10442.     printf ("N4O20000%c", sc);
  10443.   if (fg[fg_nitrite - 1])
  10444.     printf ("N3O20000%c", sc);
  10445.   if (fg[fg_nitrate - 1])
  10446.     printf ("N4O30000%c", sc);
  10447.   if (fg[fg_sulfuric_acid_deriv - 1])
  10448.     printf ("S6O00000%c", sc);
  10449.   if (fg[fg_sulfuric_acid - 1])
  10450.     printf ("S6O4H000%c", sc);
  10451.   if (fg[fg_sulfuric_acid_monoester - 1])
  10452.     printf ("S6O4HC00%c", sc);
  10453.   if (fg[fg_sulfuric_acid_diester - 1])
  10454.     printf ("S6O4CC00%c", sc);
  10455.   if (fg[fg_sulfuric_acid_amide_ester - 1])
  10456.     printf ("S6O3NC00%c", sc);
  10457.   if (fg[fg_sulfuric_acid_amide - 1])
  10458.     printf ("S6O3N100%c", sc);
  10459.   if (fg[fg_sulfuric_acid_diamide - 1])
  10460.     printf ("S6O2N200%c", sc);
  10461.   if (fg[fg_sulfuryl_halide - 1])
  10462.     printf ("S6O3XX00%c", sc);
  10463.   if (fg[fg_sulfonic_acid_deriv - 1])
  10464.     printf ("S5O00000%c", sc);
  10465.   if (fg[fg_sulfonic_acid - 1])
  10466.     printf ("S5O3H000%c", sc);
  10467.   if (fg[fg_sulfonic_acid_ester - 1])
  10468.     printf ("S5O3C000%c", sc);
  10469.   if (fg[fg_sulfonamide - 1])
  10470.     printf ("S5O2N000%c", sc);
  10471.   if (fg[fg_sulfonyl_halide - 1])
  10472.     printf ("S5O2XX00%c", sc);
  10473.   if (fg[fg_sulfone - 1])
  10474.     printf ("S4O20000%c", sc);
  10475.   if (fg[fg_sulfoxide - 1])
  10476.     printf ("S2O10000%c", sc);
  10477.   if (fg[fg_sulfinic_acid_deriv - 1])
  10478.     printf ("S3O00000%c", sc);
  10479.   if (fg[fg_sulfinic_acid - 1])
  10480.     printf ("S3O2H000%c", sc);
  10481.   if (fg[fg_sulfinic_acid_ester - 1])
  10482.     printf ("S3O2C000%c", sc);
  10483.   if (fg[fg_sulfinic_acid_halide - 1])
  10484.     printf ("S3O1XX00%c", sc);
  10485.   if (fg[fg_sulfinic_acid_amide - 1])
  10486.     printf ("S3O1N000%c", sc);
  10487.   if (fg[fg_sulfenic_acid_deriv - 1])
  10488.     printf ("S1O00000%c", sc);
  10489.   if (fg[fg_sulfenic_acid - 1])
  10490.     printf ("S1O1H000%c", sc);
  10491.   if (fg[fg_sulfenic_acid_ester - 1])
  10492.     printf ("S1O1C000%c", sc);
  10493.   if (fg[fg_sulfenic_acid_halide - 1])
  10494.     printf ("S1O0XX00%c", sc);
  10495.   if (fg[fg_sulfenic_acid_amide - 1])
  10496.     printf ("S1O0N100%c", sc);
  10497.   /*  if fg[fg_thiol]                          then write('S1H10000',sc); */
  10498.   if (fg[fg_alkylthiol - 1])
  10499.     printf ("S1H1C000%c", sc);
  10500.   if (fg[fg_arylthiol - 1])
  10501.     printf ("S1H1A000%c", sc);
  10502.   if (fg[fg_phosphoric_acid_deriv - 1])
  10503.     printf ("P5O0H000%c", sc);
  10504.   if (fg[fg_phosphoric_acid - 1])
  10505.     printf ("P5O4H200%c", sc);
  10506.   if (fg[fg_phosphoric_acid_ester - 1])
  10507.     printf ("P5O4HC00%c", sc);
  10508.   if (fg[fg_phosphoric_acid_halide - 1])
  10509.     printf ("P5O3HX00%c", sc);
  10510.   if (fg[fg_phosphoric_acid_amide - 1])
  10511.     printf ("P5O3HN00%c", sc);
  10512.   if (fg[fg_thiophosphoric_acid_deriv - 1])
  10513.     printf ("P5O0S000%c", sc);
  10514.   if (fg[fg_thiophosphoric_acid - 1])
  10515.     printf ("P5O3SH00%c", sc);
  10516.   if (fg[fg_thiophosphoric_acid_ester - 1])
  10517.     printf ("P5O3SC00%c", sc);
  10518.   if (fg[fg_thiophosphoric_acid_halide - 1])
  10519.     printf ("P5O2SX00%c", sc);
  10520.   if (fg[fg_thiophosphoric_acid_amide - 1])
  10521.     printf ("P5O2SN00%c", sc);
  10522.   if (fg[fg_phosphonic_acid_deriv - 1])
  10523.     printf ("P4O30000%c", sc);
  10524.   if (fg[fg_phosphonic_acid - 1])
  10525.     printf ("P4O3H000%c", sc);
  10526.   if (fg[fg_phosphonic_acid_ester - 1])
  10527.     printf ("P4O3C000%c", sc);
  10528.   if (fg[fg_phosphine - 1])
  10529.     printf ("P3000000%c", sc);
  10530.   if (fg[fg_phosphinoxide - 1])
  10531.     printf ("P2O00000%c", sc);
  10532.   if (fg[fg_boronic_acid_deriv - 1])
  10533.     printf ("B2O20000%c", sc);
  10534.   if (fg[fg_boronic_acid - 1])
  10535.     printf ("B2O2H000%c", sc);
  10536.   if (fg[fg_boronic_acid_ester - 1])
  10537.     printf ("B2O2C000%c", sc);
  10538.   if (fg[fg_alkene - 1])
  10539.     printf ("000C2C00%c", sc);
  10540.   if (fg[fg_alkyne - 1])
  10541.     printf ("000C3C00%c", sc);
  10542.   if (fg[fg_aromatic - 1])
  10543.     printf ("0000A000%c", sc);
  10544.   if (fg[fg_heterocycle - 1])
  10545.     printf ("0000CZ00%c", sc);
  10546.   if (fg[fg_alpha_aminoacid - 1])
  10547.     printf ("C3O2HN1C%c", sc);
  10548.   if (fg[fg_alpha_hydroxyacid - 1])
  10549.     printf ("C3O2HO1H%c", sc);
  10550. }
  10551.  
  10552. #undef sc
  10553.  
  10554.  
  10555. static void
  10556. write_fg_binary ()
  10557. {
  10558.   int i, n;
  10559.   char o;
  10560.  
  10561.   for (i = 1; i <= max_fg / 8; i++)
  10562.     {
  10563.       n = 0;
  10564.       if (fg[i * 8 - 1])
  10565.         n++;
  10566.       if (fg[i * 8 - 2])
  10567.         n += 2;
  10568.       if (fg[i * 8 - 3])
  10569.         n += 4;
  10570.       if (fg[i * 8 - 4])
  10571.         n += 8;
  10572.       if (fg[i * 8 - 5])
  10573.         n += 16;
  10574.       if (fg[i * 8 - 6])
  10575.         n += 32;
  10576.       if (fg[i * 8 - 7])
  10577.         n += 64;
  10578.       if (fg[i * 8 - 8])
  10579.         n += 128;
  10580.       o = (char) n;
  10581.       putchar (o);
  10582.     }
  10583. }
  10584.  
  10585.  
  10586. static void
  10587. write_fg_bitstring ()
  10588. {
  10589.   int i;
  10590.  
  10591.   for (i = 0; i < max_fg; i++)
  10592.     {
  10593.       if (fg[i])
  10594.         putchar ('1');
  10595.       else
  10596.         putchar ('0');
  10597.     }
  10598. }
  10599.  
  10600.  
  10601. #if 0
  10602. static void readinputfile (molfilename) char *molfilename;
  10603.      {
  10604.      /* new version in v0.2g */
  10605.      char rline[256];
  10606.      char *TEMP;
  10607.  
  10608.      molbufindex = 0;
  10609.      if (!opt_stdin)
  10610.      {
  10611.      if (!rfile_is_open)
  10612.      {
  10613.      assign (rfile, molfilename);
  10614.      rewind (rfile);
  10615.      rfile_is_open = true;
  10616.      }
  10617.      /* p2c: checkmol.pas, line 7733: Warning:
  10618.      * Don't know how to ASSIGN to a non-explicit file variable [207] */
  10619.      *rline = '\0';
  10620.      mol_in_queue = false;
  10621.      while ((!P_eof (rfile)) && (strpos2 (rline, "$$$$", 1) == 0))
  10622.      {
  10623.      fgets (rline, 256, rfile);
  10624.      TEMP = strchr (rline, '\n');
  10625.      if (TEMP != NULL)
  10626.      *TEMP = 0;
  10627.      /*mol_in_queue := false; */
  10628.      if (molbufindex >= max_atoms + max_bonds + 64)
  10629.      {
  10630.      printf ("Not enough memory for molfile! %12ld\n",
  10631.      molbufindex);
  10632.      if (rfile != NULL)
  10633.      fclose (rfile);
  10634.      rfile = NULL;
  10635.      _Escape (1);
  10636.      }
  10637.      molbufindex++;
  10638.      strcpy (molbuf[molbufindex - 1], rline);
  10639.      if (strpos2 (rline, "$$$$", 1) > 0)
  10640.      mol_in_queue = true;
  10641.      }
  10642.      if (!P_eof (rfile))
  10643.      return;
  10644.      if (rfile != NULL)
  10645.      fclose (rfile);
  10646.      rfile = NULL;
  10647.      rfile_is_open = false;
  10648.      mol_in_queue = false;
  10649.      return;
  10650.      }
  10651.      *rline = '\0';
  10652.      mol_in_queue = false;
  10653.      while ((!P_eof (stdin)) && (strpos2 (rline, "$$$$", 1) == 0))
  10654.      {
  10655.      gets (rline);
  10656.      if (molbufindex >= max_atoms + max_bonds + 64)
  10657.      {
  10658.      printf ("Not enough memory!\n");
  10659.      _Escape (1);
  10660.      }
  10661.      molbufindex++;
  10662.      strcpy (molbuf[molbufindex - 1], rline);
  10663.      if (strpos2 (rline, "$$$$", 1) > 0)
  10664.      {
  10665.      mol_in_queue = true;
  10666.      /* read from standard input
  10667.      }
  10668.      }
  10669.      } */
  10670. #endif
  10671.  
  10672. static void
  10673. readinputfile (char *molfilename)
  10674. {
  10675.   /* new version in v0.2g */
  10676.   char rline[256];
  10677.   char *TEMP;
  10678.  
  10679.   molbufindex = 0;
  10680.   if (!opt_stdin)
  10681.     {
  10682.       if (!rfile_is_open)
  10683.         {
  10684.           rfile = fopen (molfilename, "r");
  10685.           rewind (rfile);
  10686.           rfile_is_open = true;
  10687.         }
  10688. /* p2c: checkmol.pas, line 7226: Warning:
  10689.  * Don't know how to ASSIGN to a non-explicit file variable [207] */
  10690.       *rline = '\0';
  10691.       mol_in_queue = false;
  10692.       while ((fgets (rline, 256, rfile) != NULL)
  10693.              && (strstr (rline, "$$$$") == NULL))
  10694.         {
  10695.           TEMP = strchr (rline, '\n');
  10696.           if (TEMP != NULL)
  10697.             *TEMP = 0;
  10698.           /*mol_in_queue := false; */
  10699.           if (molbufindex >= max_atoms + max_bonds + 64)
  10700.             {
  10701.               printf ("Not enough memory for molfile! %d\n", molbufindex);
  10702.               if (rfile != NULL)
  10703.                 fclose (rfile);
  10704.               rfile = NULL;
  10705.               exit (1);
  10706.             }
  10707.           //molbufindex++;
  10708.           strcpy (molbuf[molbufindex++], rline);
  10709.           if (strstr (rline, "$$$$") != NULL)
  10710.             mol_in_queue = true;
  10711.         }
  10712.       if (!feof (rfile))
  10713.         return;
  10714.       if (rfile != NULL)
  10715.         fclose (rfile);
  10716.       rfile = NULL;
  10717.       rfile_is_open = false;
  10718.       mol_in_queue = false;
  10719.       return;
  10720.     }
  10721.   *rline = '\0';
  10722.   mol_in_queue = false;
  10723.   do
  10724.     {
  10725.       if(fgets (rline, 256, stdin)==NULL || feof (stdin))
  10726.         return;
  10727.       TEMP = strchr (rline, '\n');
  10728.       if (TEMP != NULL)
  10729.         *TEMP = '\0';
  10730.       if (molbufindex >= max_atoms + max_bonds + 64)
  10731.         {
  10732.           printf ("Not enough memory!\n");
  10733.           exit (1);
  10734.         }
  10735.       //molbufindex++;
  10736.       strcpy (molbuf[molbufindex++], rline);
  10737.       if (strstr (rline, "$$$$") != NULL)
  10738.         {
  10739.           mol_in_queue = true;
  10740.           /* read from standard input */
  10741.         }
  10742.     }
  10743.   while (strstr (rline, "$$$$") == NULL);
  10744. }
  10745.  
  10746. #if 0
  10747. static void copy_mol_to_needle()
  10748. {
  10749.   int i, j, FORLIM;
  10750.  
  10751.   if (n_atoms == 0)
  10752.     return;
  10753.   /* try */
  10754.   ndl_atom = (atom_rec *)safe_malloc(n_atoms * sizeof(atom_rec));
  10755.   ndl_bond = (bond_rec *)safe_malloc(n_bonds * sizeof(bond_rec));
  10756.   ndl_ring = (ringpath_type *)safe_malloc(sizeof(ringlist));
  10757.   ndl_ringprop = (ringprop_rec *)safe_malloc(sizeof(ringprop_type));
  10758.   /* except*/
  10759.     on e:Eoutofmemory do
  10760.       begin
  10761.         writeln('Not enough memory');
  10762.         halt(4);
  10763.       end;
  10764.   end;
  10765.   ndl_n_atoms = n_atoms;
  10766.   ndl_n_bonds = n_bonds;
  10767.   ndl_n_rings = n_rings;
  10768.   ndl_n_heavyatoms = n_heavyatoms;
  10769.   ndl_n_heavybonds = n_heavybonds;
  10770.   strcpy(ndl_molname, molname);
  10771.   ndl_n_Ctot = n_Ctot;
  10772.   ndl_n_Otot = n_Otot;
  10773.   ndl_n_Ntot = n_Ntot;
  10774.   FORLIM = n_atoms;
  10775.   for (i = 0; i < FORLIM; i++) {
  10776.     strcpy(ndl_atom[i].element, atom[i].element);
  10777.     strcpy(ndl_atom[i].atype, atom[i].atype);
  10778.     ndl_atom[i].x = atom[i].x;
  10779.     ndl_atom[i].y = atom[i].y;
  10780.     ndl_atom[i].z = atom[i].z;
  10781.     ndl_atom[i].formal_charge = atom[i].formal_charge;
  10782.     ndl_atom[i].real_charge = atom[i].real_charge;
  10783.     ndl_atom[i].Hexp = atom[i].Hexp;
  10784.     ndl_atom[i].Htot = atom[i].Htot;
  10785.     ndl_atom[i].neighbor_count = atom[i].neighbor_count;
  10786.     ndl_atom[i].ring_count = atom[i].ring_count;
  10787.     ndl_atom[i].arom = atom[i].arom;
  10788.     ndl_atom[i].stereo_care = atom[i].stereo_care;
  10789.     ndl_atom[i].heavy = atom[i].heavy;   /* v0.3l */
  10790.     ndl_atom[i].metal = atom[i].metal;   /* v0.3l */
  10791.     ndl_atom[i].tag = atom[i].tag;      /* v0.3o */
  10792.                                            }
  10793.                                            if (n_bonds > 0) {
  10794.                                            FORLIM = n_bonds;
  10795.                                            for (i = 0; i < FORLIM; i++) {
  10796.                                            ndl_bond[i].a1 = bond[i].a1;
  10797.                                            ndl_bond[i].a2 = bond[i].a2;
  10798.                                            ndl_bond[i].btype = bond[i].btype;
  10799.                                            ndl_bond[i].arom = bond[i].arom;
  10800.                                            ndl_bond[i].ring_count = bond[i].ring_count;   /* new in v0.3d */
  10801.                                            ndl_bond[i].topo = bond[i].topo;   /* new in v0.3d */
  10802.                                            ndl_bond[i].stereo = bond[i].stereo;   /* new in v0.3d */
  10803.                                            }
  10804.                                            }
  10805.                                            if (n_rings > 0) {
  10806.                                            FORLIM = n_rings;
  10807.                                            for (i = 0; i < FORLIM; i++) {
  10808.                                            for (j = 0; j < max_ringsize; j++)
  10809.                                            ndl_ring[i][j] = ring[i][j];
  10810.                                            }
  10811.                                            for (i = 0; i < max_rings; i++) {   /* new in v0.3 */
  10812.                                            ndl_ringprop[i].size = ringprop[i].size;
  10813.                                            ndl_ringprop[i].arom = ringprop[i].arom;
  10814.                                            ndl_ringprop[i].envelope = ringprop[i].envelope;
  10815.                                            }
  10816.                                            }
  10817.                                            ndl_molstat.n_QA = molstat.n_QA;
  10818.                                            ndl_molstat.n_QB = molstat.n_QB;
  10819.                                            ndl_molstat.n_chg = molstat.n_chg;
  10820.                                            ndl_molstat.n_C1 = molstat.n_C1;
  10821.                                            ndl_molstat.n_C2 = molstat.n_C2;
  10822.                                            ndl_molstat.n_C = molstat.n_C;
  10823.                                            ndl_molstat.n_CHB1p = molstat.n_CHB1p;
  10824.                                            ndl_molstat.n_CHB2p = molstat.n_CHB2p;
  10825.                                            ndl_molstat.n_CHB3p = molstat.n_CHB3p;
  10826.                                            ndl_molstat.n_CHB4 = molstat.n_CHB4;
  10827.                                            ndl_molstat.n_O2 = molstat.n_O2;
  10828.                                            ndl_molstat.n_O3 = molstat.n_O3;
  10829.                                            ndl_molstat.n_N1 = molstat.n_N1;
  10830.                                            ndl_molstat.n_N2 = molstat.n_N2;
  10831.                                            ndl_molstat.n_N3 = molstat.n_N3;
  10832.                                            ndl_molstat.n_S = molstat.n_S;
  10833.                                            ndl_molstat.n_SeTe = molstat.n_SeTe;
  10834.                                            ndl_molstat.n_F = molstat.n_F;
  10835.                                            ndl_molstat.n_Cl = molstat.n_Cl;
  10836.                                            ndl_molstat.n_Br = molstat.n_Br;
  10837.                                            ndl_molstat.n_I = molstat.n_I;
  10838.                                            ndl_molstat.n_P = molstat.n_P;
  10839.                                            ndl_molstat.n_B = molstat.n_B;
  10840.                                            ndl_molstat.n_Met = molstat.n_Met;
  10841.                                            ndl_molstat.n_X = molstat.n_X;
  10842.                                            ndl_molstat.n_b1 = molstat.n_b1;
  10843.                                            ndl_molstat.n_b2 = molstat.n_b2;
  10844.                                            ndl_molstat.n_b3 = molstat.n_b3;
  10845.                                            ndl_molstat.n_bar = molstat.n_bar;
  10846.                                            ndl_molstat.n_C1O = molstat.n_C1O;
  10847.                                            ndl_molstat.n_C2O = molstat.n_C2O;
  10848.                                            ndl_molstat.n_CN = molstat.n_CN;
  10849.                                            ndl_molstat.n_XY = molstat.n_XY;
  10850.                                            ndl_molstat.n_r3 = molstat.n_r3;
  10851.                                            ndl_molstat.n_r4 = molstat.n_r4;
  10852.                                            ndl_molstat.n_r5 = molstat.n_r5;
  10853.                                            ndl_molstat.n_r6 = molstat.n_r6;
  10854.                                            ndl_molstat.n_r7 = molstat.n_r7;
  10855.                                            ndl_molstat.n_r8 = molstat.n_r8;
  10856.                                            ndl_molstat.n_r9 = molstat.n_r9;
  10857.                                            ndl_molstat.n_r10 = molstat.n_r10;
  10858.                                            ndl_molstat.n_r11 = molstat.n_r11;
  10859.                                            ndl_molstat.n_r12 = molstat.n_r12;
  10860.                                            ndl_molstat.n_r13p = molstat.n_r13p;
  10861.                                            ndl_molstat.n_rN = molstat.n_rN;
  10862.                                            ndl_molstat.n_rN1 = molstat.n_rN1;
  10863.                                            ndl_molstat.n_rN2 = molstat.n_rN2;
  10864.                                            ndl_molstat.n_rN3p = molstat.n_rN3p;
  10865.                                            ndl_molstat.n_rO = molstat.n_rO;
  10866.                                            ndl_molstat.n_rO1 = molstat.n_rO1;
  10867.                                            ndl_molstat.n_rO2p = molstat.n_rO2p;
  10868.                                            ndl_molstat.n_rS = molstat.n_rS;
  10869.                                            ndl_molstat.n_rX = molstat.n_rX;
  10870.                                            ndl_molstat.n_rAr = molstat.n_rAr;
  10871.                                            ndl_molstat.n_rBz = molstat.n_rBz;   /* v0.3l */
  10872.                                            ndl_molstat.n_br2p = molstat.n_br2p;   /* v0.3n */
  10873.                                            /* p2c: checkmol.pas, line 7875:
  10874.                                            * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  10875.                                            /*$IFDEF extended_molstat
  10876.                                             v0.3m */
  10877.                                            ndl_molstat.n_psg01 = molstat.n_psg01;
  10878.                                            ndl_molstat.n_psg02 = molstat.n_psg02;
  10879.                                            ndl_molstat.n_psg13 = molstat.n_psg13;
  10880.                                            ndl_molstat.n_psg14 = molstat.n_psg14;
  10881.                                            ndl_molstat.n_psg15 = molstat.n_psg15;
  10882.                                            ndl_molstat.n_psg16 = molstat.n_psg16;
  10883.                                            ndl_molstat.n_psg17 = molstat.n_psg17;
  10884.                                            ndl_molstat.n_psg18 = molstat.n_psg18;
  10885.                                            ndl_molstat.n_pstm = molstat.n_pstm;
  10886.                                            ndl_molstat.n_psla = molstat.n_psla;
  10887.                                            $ENDIF*/
  10888.                                            /* make sure some modes can be switched on only by the query file *M*/
  10889.                                            /* and not by subsequent haystack file(s) */
  10890.                                            if (ez_flag)   /* new in v0.3f */
  10891.                                            ez_search = true;
  10892.                                            if (chir_flag)   /* new in v0.3f */
  10893.                                            rs_search = true;
  10894.                                            }
  10895. #endif
  10896.  
  10897.  
  10898. static void
  10899. copy_mol_to_needle ()
  10900. {
  10901.   //int i, j, FORLIM;
  10902.  
  10903.   /*if (n_atoms == 0)
  10904.      return; *///If a NoStruct is read, this leads to madness and illegal memory access
  10905.  
  10906.  
  10907.   ndl_atom = (atom_rec *) safe_calloc (n_atoms, sizeof (atom_rec));
  10908.   ndl_bond = (bond_rec *) safe_calloc (n_bonds, sizeof (bond_rec));
  10909.   ndl_ring = (ringpath_type *) safe_calloc (1, sizeof (ringlist));
  10910.   ndl_ringprop = (ringprop_rec *) safe_calloc (1, sizeof (ringprop_type));
  10911.  
  10912.  
  10913.   ndl_n_atoms = n_atoms;
  10914.   ndl_n_bonds = n_bonds;
  10915.   ndl_n_rings = n_rings;
  10916.   ndl_n_heavyatoms = n_heavyatoms;
  10917.   ndl_n_heavybonds = n_heavybonds;
  10918.   strcpy (ndl_molname, molname);
  10919.   ndl_n_Ctot = n_Ctot;
  10920.   ndl_n_Otot = n_Otot;
  10921.   ndl_n_Ntot = n_Ntot;
  10922.   memcpy (ndl_atom, atom, n_atoms * sizeof (atom_rec));
  10923.  
  10924.   if (n_bonds > 0)
  10925.     memcpy (ndl_bond, bond, n_bonds * sizeof (bond_rec));
  10926.  
  10927.   if (n_rings > 0)
  10928.     {
  10929.       memcpy (ndl_ring, ring, sizeof (ringlist));
  10930.       memcpy (ndl_ringprop, ringprop, sizeof (ringprop_type));
  10931.     }
  10932.  
  10933.   memcpy (&ndl_molstat, &molstat, sizeof (molstat));
  10934.  
  10935.  
  10936.   // make sure some modes can be switched on only by the query file
  10937.   // and not by subsequent haystack file(s)
  10938.   if (ez_flag)                  // new in v0.3f
  10939.     ez_search = true;
  10940.  
  10941.   if (chir_flag)                // new in v0.3f
  10942.     rs_search = true;
  10943.  
  10944.   ndl_querymol = found_querymol;        /* 0.3p */
  10945.  
  10946. }
  10947.  
  10948. static void
  10949. copy_mol_to_tmp ()
  10950. {
  10951.   //int i, j, FORLIM;
  10952.  
  10953.   /*if (n_atoms == 0)
  10954.      return; *///If a NoStruct is read, this leads to madness and illegal memory access
  10955.  
  10956.  
  10957.   tmp_atom = (atom_rec *) safe_calloc (n_atoms, sizeof (atom_rec));
  10958.   tmp_bond = (bond_rec *) safe_calloc (n_bonds, sizeof (bond_rec));
  10959.   tmp_ring = (ringpath_type *) safe_calloc (1, sizeof (ringlist));
  10960.   tmp_ringprop = (ringprop_rec *) safe_calloc (1, sizeof (ringprop_type));
  10961.  
  10962.  
  10963.   tmp_n_atoms = n_atoms;
  10964.   tmp_n_bonds = n_bonds;
  10965.   tmp_n_rings = n_rings;
  10966.   tmp_n_heavyatoms = n_heavyatoms;
  10967.   tmp_n_heavybonds = n_heavybonds;
  10968.   strcpy (tmp_molname, molname);
  10969.   tmp_n_Ctot = n_Ctot;
  10970.   tmp_n_Otot = n_Otot;
  10971.   tmp_n_Ntot = n_Ntot;
  10972.   memcpy (tmp_atom, atom, n_atoms * sizeof (atom_rec));
  10973.  
  10974.   if (n_bonds > 0)
  10975.     memcpy (tmp_bond, bond, n_bonds * sizeof (bond_rec));
  10976.  
  10977.   if (n_rings > 0)
  10978.     {
  10979.       memcpy (tmp_ring, ring, sizeof (ringlist));
  10980.       memcpy (tmp_ringprop, ringprop, sizeof (ringprop_type));
  10981.     }
  10982.  
  10983.   memcpy (&tmp_molstat, &molstat, sizeof (molstat));
  10984.  
  10985.  
  10986.   // make sure some modes can be switched on only by the query file
  10987.   // and not by subsequent haystack file(s)
  10988.   if (ez_flag)                  // new in v0.3f
  10989.     ez_search = true;
  10990.  
  10991.   if (chir_flag)                // new in v0.3f
  10992.     rs_search = true;
  10993.  
  10994.   ndl_querymol = found_querymol;        /* 0.3p */
  10995.  
  10996. }
  10997.  
  10998. #if 0
  10999. static void copy_mol_to_tmp()
  11000. {
  11001.   int i, j, FORLIM;
  11002.  
  11003.   if (n_atoms == 0)
  11004.     return;
  11005.   /* try */
  11006.   tmp_atom = (atom_rec *)safe_malloc(n_atoms * sizeof(atom_rec));
  11007.   tmp_bond = (bond_rec *)safe_malloc(n_bonds * sizeof(bond_rec));
  11008.   tmp_ring = (ringpath_type *)safe_malloc(sizeof(ringlist));
  11009.   tmp_ringprop = (ringprop_rec *)safe_malloc(sizeof(ringprop_type));
  11010.   /* except */
  11011.     on e:Eoutofmemory do
  11012.       begin
  11013.         writeln('Not enough memory');
  11014.         halt(4);
  11015.       end;
  11016.   end;
  11017.   tmp_n_atoms = n_atoms;
  11018.   tmp_n_bonds = n_bonds;
  11019.   tmp_n_rings = n_rings;
  11020.   tmp_n_heavyatoms = n_heavyatoms;
  11021.   tmp_n_heavybonds = n_heavybonds;
  11022.   strcpy(tmp_molname, molname);
  11023.   tmp_n_Ctot = n_Ctot;
  11024.   tmp_n_Otot = n_Otot;
  11025.   tmp_n_Ntot = n_Ntot;
  11026.   FORLIM = n_atoms;
  11027.   for (i = 0; i < FORLIM; i++) {
  11028.     strcpy(tmp_atom[i].element, atom[i].element);
  11029.     strcpy(tmp_atom[i].atype, atom[i].atype);
  11030.     tmp_atom[i].x = atom[i].x;
  11031.     tmp_atom[i].y = atom[i].y;
  11032.     tmp_atom[i].z = atom[i].z;
  11033.     tmp_atom[i].formal_charge = atom[i].formal_charge;
  11034.     tmp_atom[i].real_charge = atom[i].real_charge;
  11035.     tmp_atom[i].Hexp = atom[i].Hexp;
  11036.     tmp_atom[i].Htot = atom[i].Htot;
  11037.     tmp_atom[i].neighbor_count = atom[i].neighbor_count;
  11038.     tmp_atom[i].ring_count = atom[i].ring_count;
  11039.     tmp_atom[i].arom = atom[i].arom;
  11040.     tmp_atom[i].stereo_care = atom[i].stereo_care;
  11041.     tmp_atom[i].heavy = atom[i].heavy;   /* v0.3l */
  11042.     tmp_atom[i].metal = atom[i].metal;   /* v0.3l */
  11043.     tmp_atom[i].tag = atom[i].tag;   /* v0.3o */
  11044.   }
  11045.   if (n_bonds > 0) {
  11046.     FORLIM = n_bonds;
  11047.     for (i = 0; i < FORLIM; i++) {
  11048.       tmp_bond[i].a1 = bond[i].a1;
  11049.       tmp_bond[i].a2 = bond[i].a2;
  11050.       tmp_bond[i].btype = bond[i].btype;
  11051.       tmp_bond[i].arom = bond[i].arom;
  11052.       tmp_bond[i].ring_count = bond[i].ring_count;   /* new in v0.3d */
  11053.       tmp_bond[i].topo = bond[i].topo;   /* new in v0.3d */
  11054.       tmp_bond[i].stereo = bond[i].stereo;   /* new in v0.3d */
  11055.     }
  11056.   }
  11057.   if (n_rings > 0) {
  11058.     FORLIM = n_rings;
  11059.     for (i = 0; i < FORLIM; i++) {
  11060.       for (j = 0; j < max_ringsize; j++)
  11061.         tmp_ring[i][j] = ring[i][j];
  11062.     }
  11063.     for (i = 0; i < max_rings; i++) {   /* new in v0.3 */
  11064.       tmp_ringprop[i].size = ringprop[i].size;
  11065.       tmp_ringprop[i].arom = ringprop[i].arom;
  11066.       tmp_ringprop[i].envelope = ringprop[i].envelope;
  11067.     }
  11068.   }
  11069.   tmp_molstat.n_QA = molstat.n_QA;
  11070.   tmp_molstat.n_QB = molstat.n_QB;
  11071.   tmp_molstat.n_chg = molstat.n_chg;
  11072.   tmp_molstat.n_C1 = molstat.n_C1;
  11073.   tmp_molstat.n_C2 = molstat.n_C2;
  11074.   tmp_molstat.n_C = molstat.n_C;
  11075.   tmp_molstat.n_CHB1p = molstat.n_CHB1p;
  11076.   tmp_molstat.n_CHB2p = molstat.n_CHB2p;
  11077.   tmp_molstat.n_CHB3p = molstat.n_CHB3p;
  11078.   tmp_molstat.n_CHB4 = molstat.n_CHB4;
  11079.   tmp_molstat.n_O2 = molstat.n_O2;
  11080.   tmp_molstat.n_O3 = molstat.n_O3;
  11081.   tmp_molstat.n_N1 = molstat.n_N1;
  11082.   tmp_molstat.n_N2 = molstat.n_N2;
  11083.   tmp_molstat.n_N3 = molstat.n_N3;
  11084.   tmp_molstat.n_S = molstat.n_S;
  11085.   tmp_molstat.n_SeTe = molstat.n_SeTe;
  11086.   tmp_molstat.n_F = molstat.n_F;
  11087.   tmp_molstat.n_Cl = molstat.n_Cl;
  11088.   tmp_molstat.n_Br = molstat.n_Br;
  11089.   tmp_molstat.n_I = molstat.n_I;
  11090.   tmp_molstat.n_P = molstat.n_P;
  11091.   tmp_molstat.n_B = molstat.n_B;
  11092.   tmp_molstat.n_Met = molstat.n_Met;
  11093.   tmp_molstat.n_X = molstat.n_X;
  11094.   tmp_molstat.n_b1 = molstat.n_b1;
  11095.   tmp_molstat.n_b2 = molstat.n_b2;
  11096.   tmp_molstat.n_b3 = molstat.n_b3;
  11097.   tmp_molstat.n_bar = molstat.n_bar;
  11098.   tmp_molstat.n_C1O = molstat.n_C1O;
  11099.   tmp_molstat.n_C2O = molstat.n_C2O;
  11100.   tmp_molstat.n_CN = molstat.n_CN;
  11101.   tmp_molstat.n_XY = molstat.n_XY;
  11102.   tmp_molstat.n_r3 = molstat.n_r3;
  11103.   tmp_molstat.n_r4 = molstat.n_r4;
  11104.   tmp_molstat.n_r5 = molstat.n_r5;
  11105.   tmp_molstat.n_r6 = molstat.n_r6;
  11106.   tmp_molstat.n_r7 = molstat.n_r7;
  11107.   tmp_molstat.n_r8 = molstat.n_r8;
  11108.   tmp_molstat.n_r9 = molstat.n_r9;
  11109.   tmp_molstat.n_r10 = molstat.n_r10;
  11110.   tmp_molstat.n_r11 = molstat.n_r11;
  11111.   tmp_molstat.n_r12 = molstat.n_r12;
  11112.   tmp_molstat.n_r13p = molstat.n_r13p;
  11113.   tmp_molstat.n_rN = molstat.n_rN;
  11114.   tmp_molstat.n_rN1 = molstat.n_rN1;
  11115.   tmp_molstat.n_rN2 = molstat.n_rN2;
  11116.   tmp_molstat.n_rN3p = molstat.n_rN3p;
  11117.   tmp_molstat.n_rO = molstat.n_rO;
  11118.   tmp_molstat.n_rO1 = molstat.n_rO1;
  11119.   tmp_molstat.n_rO2p = molstat.n_rO2p;
  11120.   tmp_molstat.n_rS = molstat.n_rS;
  11121.   tmp_molstat.n_rX = molstat.n_rX;
  11122.   tmp_molstat.n_rAr = molstat.n_rAr;
  11123.   tmp_molstat.n_rBz = molstat.n_rBz;   /* v0.3l */
  11124.   tmp_molstat.n_br2p = molstat.n_br2p;   /* v0.3n */
  11125. /* p2c: checkmol.pas, line 8022:
  11126.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11127.   /*$IFDEF extended_molstat
  11128.    v0.3m
  11129.   tmp_molstat.n_psg01 = molstat.n_psg01;
  11130.   tmp_molstat.n_psg02 = molstat.n_psg02;
  11131.   tmp_molstat.n_psg13 = molstat.n_psg13;
  11132.   tmp_molstat.n_psg14 = molstat.n_psg14;
  11133.   tmp_molstat.n_psg15 = molstat.n_psg15;
  11134.   tmp_molstat.n_psg16 = molstat.n_psg16;
  11135.   tmp_molstat.n_psg17 = molstat.n_psg17;
  11136.   tmp_molstat.n_psg18 = molstat.n_psg18;
  11137.   tmp_molstat.n_pstm = molstat.n_pstm;
  11138.   tmp_molstat.n_psla = molstat.n_psla;
  11139.   $ENDIF*/
  11140.   /* make sure some modes can be switched on only by the query file */
  11141.   /* and not by subsequent haystack file(s) */
  11142.   if (ez_flag)   /* new in v0.3f */
  11143.     ez_search = true;
  11144.   if (chir_flag)   /* new in v0.3f */
  11145.     rs_search = true;
  11146. }
  11147. #endif
  11148.  
  11149. static void
  11150. copy_tmp_to_mol ()
  11151. {
  11152.   //int i, j, FORLIM;
  11153.  
  11154.   /*if (n_atoms == 0)
  11155.      return; *///If a NoStruct is read, this leads to madness and illegal memory access
  11156.  
  11157.  
  11158.   atom = (atom_rec *) safe_calloc (n_atoms, sizeof (atom_rec));
  11159.   bond = (bond_rec *) safe_calloc (n_bonds, sizeof (bond_rec));
  11160.   ring = (ringpath_type *) safe_calloc (1, sizeof (ringlist));
  11161.   ringprop = (ringprop_rec *) safe_calloc (1, sizeof (ringprop_type));
  11162.  
  11163.  
  11164.   n_atoms = tmp_n_atoms;
  11165.   n_bonds = tmp_n_bonds;
  11166.   n_rings = tmp_n_rings;
  11167.   n_heavyatoms = tmp_n_heavyatoms;
  11168.   n_heavybonds = tmp_n_heavybonds;
  11169.   strcpy (molname, tmp_molname);
  11170.   n_Ctot = tmp_n_Ctot;
  11171.   n_Otot = tmp_n_Otot;
  11172.   n_Ntot = tmp_n_Ntot;
  11173.   memcpy (atom, tmp_atom, tmp_n_atoms * sizeof (atom_rec));
  11174.  
  11175.   if (tmp_n_bonds > 0)
  11176.     memcpy (bond, tmp_bond, tmp_n_bonds * sizeof (bond_rec));
  11177.  
  11178.   if (tmp_n_rings > 0)
  11179.     {
  11180.       memcpy (ring, tmp_ring, sizeof (ringlist));
  11181.       memcpy (ringprop, tmp_ringprop, sizeof (ringprop_type));
  11182.     }
  11183.  
  11184.   memcpy (&molstat, &tmp_molstat, sizeof (tmp_molstat));
  11185.  
  11186.  
  11187.   // make sure some modes can be switched on only by the query file
  11188.   // and not by subsequent haystack file(s)
  11189.   if (ez_flag)                  // new in v0.3f
  11190.     ez_search = true;
  11191.  
  11192.   if (chir_flag)                // new in v0.3f
  11193.     rs_search = true;
  11194.  
  11195. }
  11196.  
  11197. #if 0
  11198. static void copy_tmp_to_mol()
  11199. {
  11200.   int i, j, FORLIM;
  11201.  
  11202.   if (tmp_n_atoms == 0)
  11203.     return;
  11204.   n_atoms = tmp_n_atoms;
  11205.   n_bonds = tmp_n_bonds;
  11206.   n_rings = tmp_n_rings;
  11207.   n_heavyatoms = tmp_n_heavyatoms;
  11208.   n_heavybonds = tmp_n_heavybonds;
  11209.   strcpy(molname, tmp_molname);
  11210.   n_Ctot = tmp_n_Ctot;
  11211.   n_Otot = tmp_n_Otot;
  11212.   n_Ntot = tmp_n_Ntot;
  11213.   /* try */
  11214.   atom = (atom_rec *)safe_malloc(n_atoms * sizeof(atom_rec));
  11215.   bond = (bond_rec *)safe_malloc(n_bonds * sizeof(bond_rec));
  11216.   ring = (ringpath_type *)safe_malloc(sizeof(ringlist));
  11217.   ringprop = (ringprop_rec *)safe_malloc(sizeof(ringprop_type));
  11218.   FORLIM = tmp_n_atoms;
  11219.   /* except*/
  11220.     on e:Eoutofmemory do
  11221.       begin
  11222.         writeln('Not enough memory');
  11223.         halt(4);
  11224.       end;
  11225.   end;
  11226.   for (i = 0; i < FORLIM; i++) {
  11227.     strcpy(atom[i].element, tmp_atom[i].element);
  11228.     strcpy(atom[i].atype, tmp_atom[i].atype);
  11229.     atom[i].x = tmp_atom[i].x;
  11230.     atom[i].y = tmp_atom[i].y;
  11231.     atom[i].z = tmp_atom[i].z;
  11232.     atom[i].formal_charge = tmp_atom[i].formal_charge;
  11233.     atom[i].real_charge = tmp_atom[i].real_charge;
  11234.     atom[i].Hexp = tmp_atom[i].Hexp;
  11235.     atom[i].Htot = tmp_atom[i].Htot;
  11236.     atom[i].neighbor_count = tmp_atom[i].neighbor_count;
  11237.     atom[i].ring_count = tmp_atom[i].ring_count;
  11238.     atom[i].arom = tmp_atom[i].arom;
  11239.     atom[i].stereo_care = tmp_atom[i].stereo_care;
  11240.     atom[i].heavy = tmp_atom[i].heavy;   /* v0.3l */
  11241.     atom[i].metal = tmp_atom[i].metal;   /* v0.3l */
  11242.     atom[i].tag = tmp_atom[i].tag;   /* v0.3o */
  11243.   }
  11244.   if (tmp_n_bonds > 0) {
  11245.     FORLIM = tmp_n_bonds;
  11246.     for (i = 0; i < FORLIM; i++) {
  11247.       bond[i].a1 = tmp_bond[i].a1;
  11248.       bond[i].a2 = tmp_bond[i].a2;
  11249.       bond[i].btype = tmp_bond[i].btype;
  11250.       bond[i].arom = tmp_bond[i].arom;
  11251.       bond[i].ring_count = tmp_bond[i].ring_count;   /* new in v0.3d */
  11252.       bond[i].topo = tmp_bond[i].topo;   /* new in v0.3d */
  11253.       bond[i].stereo = tmp_bond[i].stereo;   /* new in v0.3d */
  11254.     }
  11255.   }
  11256.   if (tmp_n_rings > 0) {
  11257.     FORLIM = tmp_n_rings;
  11258.     for (i = 0; i < FORLIM; i++) {
  11259.       for (j = 0; j < max_ringsize; j++)
  11260.         ring[i][j] = tmp_ring[i][j];
  11261.     }
  11262.     for (i = 0; i < max_rings; i++) {   /* new in v0.3 */
  11263.       ringprop[i].size = tmp_ringprop[i].size;
  11264.       ringprop[i].arom = tmp_ringprop[i].arom;
  11265.       ringprop[i].envelope = tmp_ringprop[i].envelope;
  11266.     }
  11267.   }
  11268.   molstat.n_QA = tmp_molstat.n_QA;
  11269.   molstat.n_QB = tmp_molstat.n_QB;
  11270.   molstat.n_chg = tmp_molstat.n_chg;
  11271.   molstat.n_C1 = tmp_molstat.n_C1;
  11272.   molstat.n_C2 = tmp_molstat.n_C2;
  11273.   molstat.n_C = tmp_molstat.n_C;
  11274.   molstat.n_CHB1p = tmp_molstat.n_CHB1p;
  11275.   molstat.n_CHB2p = tmp_molstat.n_CHB2p;
  11276.   molstat.n_CHB3p = tmp_molstat.n_CHB3p;
  11277.   molstat.n_CHB4 = tmp_molstat.n_CHB4;
  11278.   molstat.n_O2 = tmp_molstat.n_O2;
  11279.   molstat.n_O3 = tmp_molstat.n_O3;
  11280.   molstat.n_N1 = tmp_molstat.n_N1;
  11281.   molstat.n_N2 = tmp_molstat.n_N2;
  11282.   molstat.n_N3 = tmp_molstat.n_N3;
  11283.   molstat.n_S = tmp_molstat.n_S;
  11284.   molstat.n_SeTe = tmp_molstat.n_SeTe;
  11285.   molstat.n_F = tmp_molstat.n_F;
  11286.   molstat.n_Cl = tmp_molstat.n_Cl;
  11287.   molstat.n_Br = tmp_molstat.n_Br;
  11288.   molstat.n_I = tmp_molstat.n_I;
  11289.   molstat.n_P = tmp_molstat.n_P;
  11290.   molstat.n_B = tmp_molstat.n_B;
  11291.   molstat.n_Met = tmp_molstat.n_Met;
  11292.   molstat.n_X = tmp_molstat.n_X;
  11293.   molstat.n_b1 = tmp_molstat.n_b1;
  11294.   molstat.n_b2 = tmp_molstat.n_b2;
  11295.   molstat.n_b3 = tmp_molstat.n_b3;
  11296.   molstat.n_bar = tmp_molstat.n_bar;
  11297.   molstat.n_C1O = tmp_molstat.n_C1O;
  11298.   molstat.n_C2O = tmp_molstat.n_C2O;
  11299.   molstat.n_CN = tmp_molstat.n_CN;
  11300.   molstat.n_XY = tmp_molstat.n_XY;
  11301.   molstat.n_r3 = tmp_molstat.n_r3;
  11302.   molstat.n_r4 = tmp_molstat.n_r4;
  11303.   molstat.n_r5 = tmp_molstat.n_r5;
  11304.   molstat.n_r6 = tmp_molstat.n_r6;
  11305.   molstat.n_r7 = tmp_molstat.n_r7;
  11306.   molstat.n_r8 = tmp_molstat.n_r8;
  11307.   molstat.n_r9 = tmp_molstat.n_r9;
  11308.   molstat.n_r10 = tmp_molstat.n_r10;
  11309.   molstat.n_r11 = tmp_molstat.n_r11;
  11310.   molstat.n_r12 = tmp_molstat.n_r12;
  11311.   molstat.n_r13p = tmp_molstat.n_r13p;
  11312.   molstat.n_rN = tmp_molstat.n_rN;
  11313.   molstat.n_rN1 = tmp_molstat.n_rN1;
  11314.   molstat.n_rN2 = tmp_molstat.n_rN2;
  11315.   molstat.n_rN3p = tmp_molstat.n_rN3p;
  11316.   molstat.n_rO = tmp_molstat.n_rO;
  11317.   molstat.n_rO1 = tmp_molstat.n_rO1;
  11318.   molstat.n_rO2p = tmp_molstat.n_rO2p;
  11319.   molstat.n_rS = tmp_molstat.n_rS;
  11320.   molstat.n_rX = tmp_molstat.n_rX;
  11321.   molstat.n_rAr = tmp_molstat.n_rAr;
  11322.   molstat.n_rBz = tmp_molstat.n_rBz;   /* v0.3l */
  11323.   molstat.n_br2p = tmp_molstat.n_br2p;   /* v0.3n */
  11324. /* p2c: checkmol.pas, line 8169:
  11325.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11326.   /*$IFDEF extended_molstat
  11327.      molstat.n_psg01 = tmp_molstat.n_psg01;
  11328.      molstat.n_psg02 = tmp_molstat.n_psg02;
  11329.      molstat.n_psg13 = tmp_molstat.n_psg13;
  11330.      molstat.n_psg14 = tmp_molstat.n_psg14;
  11331.      molstat.n_psg15 = tmp_molstat.n_psg15;
  11332.      molstat.n_psg16 = tmp_molstat.n_psg16;
  11333.      molstat.n_psg17 = tmp_molstat.n_psg17;
  11334.      molstat.n_psg18 = tmp_molstat.n_psg18;
  11335.      molstat.n_pstm = tmp_molstat.n_pstm;
  11336.      molstat.n_psla = tmp_molstat.n_psla;
  11337.      $ENDIF */
  11338.   /* make sure some modes can be switched on only by the query file */
  11339.   /* and not by subsequent haystack file(s) */
  11340.      if (ez_flag)
  11341.      ez_search = true;
  11342.      if (chir_flag)
  11343.      rs_search = true;
  11344.      }
  11345. #endif
  11346.  
  11347.  
  11348.  
  11349.  
  11350.  
  11351. static void
  11352. get_ringstat (r_id)
  11353.      int r_id;
  11354. {
  11355.   int i, j;
  11356.   ringpath_type testring;
  11357.   int ring_size, a_ref;
  11358.   str2 elem;
  11359.   int nN = 0, nO = 0, nS = 0, nX = 0;
  11360.  
  11361.   if (r_id < 1 || r_id > n_rings)
  11362.     return;
  11363.   memset (testring, 0, sizeof (ringpath_type));
  11364.   ring_size = ringprop[r_id - 1].size;  /* v0.3j */
  11365.   for (j = 0; j < ring_size; j++)       /* v0.3j */
  11366.     testring[j] = ring[r_id - 1][j];
  11367. /* p2c: checkmol.pas, line 8238:
  11368.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11369. #ifdef reduced_SAR
  11370.   if (ring_size <= 2 || ringprop[r_id - 1].envelope != false)
  11371.     /* v0.3n: ignore envelope rings */
  11372.     return;
  11373. #else
  11374.   if (ring_size <= 2)
  11375.     return;
  11376. #endif
  11377.   for (i = 0; i < ring_size; i++)
  11378.     {
  11379.       a_ref = testring[i];
  11380.       strcpy (elem, atom[a_ref - 1].element);
  11381.       if (strcmp (elem, "C ") && strcmp (elem, "A "))
  11382.         {
  11383.           nX++;                 /* general heteroatom count */
  11384.           if (!strcmp (elem, "N "))
  11385.             nN++;
  11386.           if (!strcmp (elem, "O "))
  11387.             nO++;
  11388.           if (!strcmp (elem, "S "))
  11389.             nS++;
  11390.         }
  11391.     }
  11392.   if (nN > 0)
  11393.     {
  11394.       molstat.n_rN++;
  11395.       if (nN == 1)
  11396.         molstat.n_rN1++;
  11397.       if (nN == 2)
  11398.         molstat.n_rN2++;
  11399.       if (nN > 2)
  11400.         molstat.n_rN3p++;
  11401.     }
  11402.   if (nO > 0)
  11403.     {
  11404.       molstat.n_rO++;
  11405.       if (nO == 1)
  11406.         molstat.n_rO1++;
  11407.       if (nO == 2)
  11408.         molstat.n_rO2p++;
  11409.     }
  11410.   if (nS > 0)
  11411.     molstat.n_rS++;
  11412.   if (nX > 0)
  11413.     molstat.n_rX++;
  11414.   /* general ringsize descriptors; v0.3m */
  11415.   switch (ring_size)
  11416.     {
  11417.  
  11418.     case 3:
  11419.       molstat.n_r3++;
  11420.       break;
  11421.  
  11422.     case 4:
  11423.       molstat.n_r4++;
  11424.       break;
  11425.  
  11426.     case 5:
  11427.       molstat.n_r5++;
  11428.       break;
  11429.  
  11430.     case 6:
  11431.       molstat.n_r6++;
  11432.       break;
  11433.  
  11434.     case 7:
  11435.       molstat.n_r7++;
  11436.       break;
  11437.  
  11438.     case 8:
  11439.       molstat.n_r8++;
  11440.       break;
  11441.  
  11442.     case 9:
  11443.       molstat.n_r9++;
  11444.       break;
  11445.  
  11446.     case 10:
  11447.       molstat.n_r10++;
  11448.       break;
  11449.  
  11450.     case 11:
  11451.       molstat.n_r11++;
  11452.       break;
  11453.  
  11454.     case 12:
  11455.       molstat.n_r12++;
  11456.       break;
  11457.  
  11458.     default:
  11459.       molstat.n_r13p++;
  11460.       break;
  11461.     }                           /* end v0.3m        */
  11462. }
  11463.  
  11464.  
  11465. static void
  11466. get_molstat ()
  11467. {
  11468.   int i;
  11469.   str2 elem;
  11470.   str3 atype;
  11471.   int a1, a2;
  11472.   str2 a1el, a2el;
  11473.   char btype;
  11474.   int hbc;
  11475.   int n_b2formal = 0;           /* new in v0.2e */
  11476.   int FORLIM;
  11477.  
  11478.   if (n_atoms == 0)
  11479.     return;
  11480.   FORLIM = n_atoms;
  11481.   for (i = 0; i < FORLIM; i++)
  11482.     {
  11483.       if (atom[i].heavy)
  11484.         {
  11485.           strcpy (elem, atom[i].element);
  11486.           strcpy (atype, atom[i].atype);
  11487.           if (!strcmp (atype, "C1 "))
  11488.             molstat.n_C1++;
  11489.           if (!strcmp (atype, "C2 ") || !strcmp (atype, "CAR"))
  11490.             molstat.n_C2++;
  11491.           if (!strcmp (elem, "C "))
  11492.             molstat.n_C++;
  11493.           if (!strcmp (atype, "O2 "))
  11494.             molstat.n_O2++;
  11495.           if (!strcmp (atype, "O3 "))
  11496.             molstat.n_O3++;
  11497.           if (!strcmp (atype, "N1 "))
  11498.             molstat.n_N1++;
  11499.           if (!strcmp (atype, "N2 ") || !strcmp (atype, "NAR") ||
  11500.               (!strcmp (atype, "NAM") && atom[i].arom == true))
  11501.             /* v0.3n */
  11502.             molstat.n_N2++;
  11503.           if (!strcmp (atype, "N3 ") || !strcmp (atype, "NPL") ||
  11504.               !strcmp (atype, "N3+") ||
  11505.               (!strcmp (atype, "NAM") && atom[i].arom == false))
  11506.             /* v0.3n */
  11507.             molstat.n_N3++;
  11508.           if (!strcmp (elem, "A "))     /* query atom */
  11509.             molstat.n_QA++;
  11510.           if (!strcmp (elem, "Q "))     /* query atom */
  11511.             molstat.n_QA++;
  11512.           if (!strcmp (elem, "X "))     /* query atom */
  11513.             molstat.n_QA++;
  11514.           if (!strcmp (elem, "S "))
  11515.             molstat.n_S++;
  11516.           if (!strcmp (elem, "SE"))
  11517.             molstat.n_SeTe++;
  11518.           if (!strcmp (elem, "TE"))
  11519.             molstat.n_SeTe++;
  11520.           if (!strcmp (elem, "F "))
  11521.             molstat.n_F++;
  11522.           if (!strcmp (elem, "CL"))
  11523.             molstat.n_Cl++;
  11524.           if (!strcmp (elem, "BR"))
  11525.             molstat.n_Br++;
  11526.           if (!strcmp (elem, "I "))
  11527.             molstat.n_I++;
  11528.           if (!strcmp (elem, "P "))
  11529.             molstat.n_P++;
  11530.           if (!strcmp (elem, "B "))
  11531.             molstat.n_B++;
  11532.           /* check for known metals */
  11533.           if (atom[i].metal)    /* v0.3l */
  11534.             molstat.n_Met++;
  11535.           /* still missing: unknown elements */
  11536.  
  11537.           /* check number of heteroatom bonds per C atom */
  11538.           if (!strcmp (elem, "C "))
  11539.             {
  11540.               hbc = raw_hetbond_count (i + 1);
  11541.               /* new in v0.2j (replaces hetbond_count) */
  11542.               if (hbc >= 1)
  11543.                 molstat.n_CHB1p++;
  11544.               if (hbc >= 2)
  11545.                 molstat.n_CHB2p++;
  11546.               if (hbc >= 3)
  11547.                 molstat.n_CHB3p++;
  11548.               if (hbc == 4)
  11549.                 molstat.n_CHB4++;
  11550.             }
  11551.           if (atom[i].formal_charge != 0)
  11552.             {
  11553.               molstat.n_chg++;
  11554.               //n_charges++;
  11555.             }
  11556.           if (atom[i].nucleon_number != 0)
  11557.             {
  11558.               molstat.n_iso++;
  11559.             }
  11560.           if (atom[i].radical_type != 0)
  11561.             {
  11562.               molstat.n_rad++;
  11563.             }
  11564.           /* check for "other" elements;  v0.3l */
  11565.           if (!atom[i].metal && strcmp (elem, "C ") && strcmp (elem, "N ")
  11566.               && strcmp (elem, "O ") && strcmp (elem, "S ")
  11567.               && strcmp (elem, "SE") && strcmp (elem, "TE")
  11568.               && strcmp (elem, "P ") && strcmp (elem, "B ")
  11569.               && strcmp (elem, "A ") && strcmp (elem, "Q "))
  11570.             molstat.n_X++;
  11571.           /*(elem = 'F ') or (elem = 'CL') or (elem = 'BR') or (elem = 'I ') or  (* leave halogens as type X, v0.3m */
  11572. /* p2c: checkmol.pas, line 8353:
  11573.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11574.           /*$IFDEF extended_molstat */
  11575.           if (!strcmp (elem, "LI") || !strcmp (elem, "NA")
  11576.               || !strcmp (elem, "K ") || !strcmp (elem, "RB")
  11577.               || !strcmp (elem, "CS") || !strcmp (elem, "FR"))
  11578.             molstat.n_psg01++;
  11579.           if (!strcmp (elem, "BE") || !strcmp (elem, "MG")
  11580.               || !strcmp (elem, "CA") || !strcmp (elem, "SR")
  11581.               || !strcmp (elem, "BA") || !strcmp (elem, "RA"))
  11582.             molstat.n_psg02++;
  11583.           if (!strcmp (elem, "B ") || !strcmp (elem, "AL")
  11584.               || !strcmp (elem, "GA") || !strcmp (elem, "IN")
  11585.               || !strcmp (elem, "TL"))
  11586.             molstat.n_psg13++;
  11587.           if (!strcmp (elem, "C ") || !strcmp (elem, "SI")
  11588.               || !strcmp (elem, "GE") || !strcmp (elem, "SN")
  11589.               || !strcmp (elem, "PB"))
  11590.             molstat.n_psg14++;
  11591.           if (!strcmp (elem, "N ") || !strcmp (elem, "P ")
  11592.               || !strcmp (elem, "AS") || !strcmp (elem, "SB")
  11593.               || !strcmp (elem, "BI"))
  11594.             molstat.n_psg15++;
  11595.           if (!strcmp (elem, "O ") || !strcmp (elem, "S ")
  11596.               || !strcmp (elem, "SE") || !strcmp (elem, "TE")
  11597.               || !strcmp (elem, "PO"))
  11598.             molstat.n_psg16++;
  11599.           if (!strcmp (elem, "F ") || !strcmp (elem, "CL")
  11600.               || !strcmp (elem, "BR") || !strcmp (elem, "I ")
  11601.               || !strcmp (elem, "AT"))
  11602.             molstat.n_psg17++;
  11603.           if (!strcmp (elem, "HE") || !strcmp (elem, "NE")
  11604.               || !strcmp (elem, "AR") || !strcmp (elem, "KR")
  11605.               || !strcmp (elem, "XE") || !strcmp (elem, "RN"))
  11606.             molstat.n_psg18++;
  11607.           if (!strcmp (elem, "SC") || !strcmp (elem, "Y ")
  11608.               || !strcmp (elem, "LU") || !strcmp (elem, "LR")
  11609.               || !strcmp (elem, "TI") || !strcmp (elem, "ZR")
  11610.               || !strcmp (elem, "HF") || !strcmp (elem, "RF")
  11611.               || !strcmp (elem, "V ") || !strcmp (elem, "NB")
  11612.               || !strcmp (elem, "TA") || !strcmp (elem, "DB")
  11613.               || !strcmp (elem, "CR") || !strcmp (elem, "MO")
  11614.               || !strcmp (elem, "W ") || !strcmp (elem, "SG")
  11615.               || !strcmp (elem, "MN") || !strcmp (elem, "TC")
  11616.               || !strcmp (elem, "RE") || !strcmp (elem, "BH")
  11617.               || !strcmp (elem, "FE") || !strcmp (elem, "RU")
  11618.               || !strcmp (elem, "OS") || !strcmp (elem, "HS")
  11619.               || !strcmp (elem, "CO") || !strcmp (elem, "RH")
  11620.               || !strcmp (elem, "IR") || !strcmp (elem, "MT")
  11621.               || !strcmp (elem, "NI") || !strcmp (elem, "PD")
  11622.               || !strcmp (elem, "PT") || !strcmp (elem, "DS")
  11623.               || !strcmp (elem, "CU") || !strcmp (elem, "AG")
  11624.               || !strcmp (elem, "AU") || !strcmp (elem, "RG")
  11625.               || !strcmp (elem, "ZN") || !strcmp (elem, "CD")
  11626.               || !strcmp (elem, "HG"))
  11627. /* p2c: checkmol.pas, line 8439:
  11628.  * Note: Line breaker spent 0.0 seconds, 5000 tries on line 10035 [251] */
  11629.             molstat.n_pstm++;
  11630.           if (!strcmp (elem, "LA") || !strcmp (elem, "CE")
  11631.               || !strcmp (elem, "PR") || !strcmp (elem, "ND")
  11632.               || !strcmp (elem, "PM") || !strcmp (elem, "SM")
  11633.               || !strcmp (elem, "EU") || !strcmp (elem, "GD")
  11634.               || !strcmp (elem, "TB") || !strcmp (elem, "DY")
  11635.               || !strcmp (elem, "HO") || !strcmp (elem, "ER")
  11636.               || !strcmp (elem, "TM") || !strcmp (elem, "YB")
  11637.               || !strcmp (elem, "AC") || !strcmp (elem, "TH")
  11638.               || !strcmp (elem, "PA") || !strcmp (elem, "U ")
  11639.               || !strcmp (elem, "NP") || !strcmp (elem, "PU")
  11640.               || !strcmp (elem, "AM") || !strcmp (elem, "CM")
  11641.               || !strcmp (elem, "BK") || !strcmp (elem, "CF")
  11642.               || !strcmp (elem, "ES") || !strcmp (elem, "FM")
  11643.               || !strcmp (elem, "MD") || !strcmp (elem, "NO"))
  11644. /* p2c: checkmol.pas, line 8439:
  11645.  * Note: Line breaker spent 0.0 seconds, 5000 tries on line 10048 [251] */
  11646.             molstat.n_psla++;
  11647.           /*$ENDIF */
  11648.         }                       /* is heavy */
  11649.     }                           /* atoms */
  11650.   if (n_bonds > 0)
  11651.     {
  11652.       FORLIM = n_bonds;
  11653.       for (i = 0; i < FORLIM; i++)
  11654.         {
  11655.           a1 = bond[i].a1;
  11656.           a2 = bond[i].a2;
  11657.           strcpy (a1el, atom[a1 - 1].element);
  11658.           strcpy (a2el, atom[a2 - 1].element);
  11659.           btype = bond[i].btype;
  11660.           if (bond[i].arom)
  11661.             molstat.n_bar++;
  11662.           else
  11663.             {
  11664.               if (btype == 'S' && atom[a1 - 1].heavy && atom[a2 - 1].heavy)
  11665.                 molstat.n_b1++;
  11666.               if (btype == 'D')
  11667.                 molstat.n_b2++;
  11668.               if (btype == 'T')
  11669.                 molstat.n_b3++;
  11670.             }
  11671.           /* v0.3n: ignore bonds to (explicit) hydrogens */
  11672.           if ((!strcmp (a1el, "C ") && !strcmp (a2el, "O ")) ||
  11673.               (!strcmp (a1el, "O ") && !strcmp (a2el, "C ")))
  11674.             {
  11675.               if (btype == 'S')
  11676.                 molstat.n_C1O++;
  11677.               if (btype == 'D')
  11678.                 molstat.n_C2O++;
  11679.             }
  11680.           if ((!strcmp (a1el, "C ") && !strcmp (a2el, "N ")) ||
  11681.               (!strcmp (a1el, "N ") && !strcmp (a2el, "C ")))
  11682.             molstat.n_CN++;
  11683.           if (strcmp (a1el, "C ") && atom[a1 - 1].heavy
  11684.               && strcmp (a2el, "C ") && atom[a2 - 1].heavy)
  11685.             molstat.n_XY++;
  11686.           /* new in v0.3n: number of bonds belonging to more than one ring */
  11687.           if (bond[i].ring_count > 1)
  11688.             molstat.n_br2p++;
  11689.         }
  11690.     }                           /* bonds */
  11691.   if (n_rings <= 0)
  11692.     {
  11693.       return;
  11694.     }                           /* rings */
  11695.   /* v0.3n */
  11696.   n_countablerings = 0;         /* v0.3n */
  11697.   FORLIM = n_rings;
  11698.   for (i = 1; i <= FORLIM; i++)
  11699.     {
  11700.       if (ringprop[i - 1].envelope == false)    /* v0.3n */
  11701.         n_countablerings++;
  11702.       if (is_arene (i) && ringprop[i - 1].envelope == false)
  11703.         {                       /* v0.3n: ignore envelope rings */
  11704.           molstat.n_rAr++;
  11705.           if ((ringprop[i - 1].size == 6) && (is_heterocycle (i) == false))
  11706.             /* v0.3l */
  11707.             molstat.n_rBz++;
  11708.         }
  11709.       get_ringstat (i);
  11710.       if (ringprop[i - 1].arom == true && ringprop[i - 1].envelope == false)
  11711.         /* new in v0.3n; replaces assignment below */
  11712.         n_b2formal++;
  11713.     }
  11714.   /*n_b2formal := n_rar;  (* new in v0.2e; adds 1 formal double bond for each aromatic ring */
  11715.   /* in order to allow an isolated double bond in the needle */
  11716.   /* to be matched as a ring fragment of an aromatic ring */
  11717.   if (n_b2formal > molstat.n_bar / 2)
  11718.     n_b2formal = molstat.n_bar / 2;
  11719.   molstat.n_b2 += n_b2formal;
  11720. }
  11721.  
  11722.  
  11723. static void
  11724. fix_ssr_ringcounts ()
  11725. {
  11726.   /* new in v0.3n */
  11727.   /* if SAR -> SSR fallback happens, set some molstat values */
  11728.   /* to a maximum (ring counts for various ring sizes); */
  11729.   /* this should be necessary only for ring sizes which */
  11730.   /* are a) too large for the SSR (depending on ssr_vringsize) */
  11731.   /* and b) which are likely to contain "envelope rings" */
  11732.   /* (size 6 and above) */
  11733.   /*  if (molstat.n_r3 = 0) then molstat.n_r3 := max_rings; */
  11734.   /*  if (molstat.n_r4 = 0) then molstat.n_r4 := max_rings; */
  11735.   /*  if (molstat.n_r5 = 0) then molstat.n_r5 := max_rings; */
  11736.   if (molstat.n_r6 == 0)
  11737.     molstat.n_r6 = max_rings;
  11738.   if (molstat.n_r7 == 0)
  11739.     molstat.n_r7 = max_rings;
  11740.   if (molstat.n_r8 == 0)
  11741.     molstat.n_r8 = max_rings;
  11742.   if (molstat.n_r9 == 0)
  11743.     molstat.n_r9 = max_rings;
  11744.   if (molstat.n_r10 == 0)
  11745.     molstat.n_r10 = max_rings;
  11746.   if (molstat.n_r11 == 0)
  11747.     molstat.n_r11 = max_rings;
  11748.   if (molstat.n_r12 == 0)
  11749.     molstat.n_r12 = max_rings;
  11750.   if (molstat.n_r13p == 0)
  11751.     molstat.n_r13p = max_rings;
  11752. }
  11753.  
  11754.  
  11755.  
  11756. static void
  11757. write_molstat ()
  11758. {
  11759.   if (auto_ssr)                 /* v0.3n */
  11760.     fix_ssr_ringcounts ();
  11761.   printf ("n_atoms:%d;", n_heavyatoms);
  11762.   /* count only non-H atoms (some molfiles contain explicit H's) */
  11763.   if (n_bonds > 0)              /* count only bonds between non-H atoms */
  11764.     printf ("n_bonds:%d;", n_heavybonds);
  11765. /* p2c: checkmol.pas, line 8471:
  11766.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11767. #ifdef REDUCED_SAR
  11768.   if (n_rings > 0)              /* changed to non-envelope rings in v0.3n */
  11769.     printf ("n_rings:%d;", n_countablerings);
  11770. #else
  11771.   if (n_rings > 0)              /* changed to non-envelope rings in v0.3n */
  11772.     printf ("n_rings:%d;", n_rings);
  11773. #endif
  11774.   /*      if n_QA    > 0 then write('n_QA:',n_QA,';'); */
  11775.   /*      if n_QB    > 0 then write('n_QB:',n_QB,';'); */
  11776.   if (molstat.n_chg > 0)        /* 0.3x */
  11777.     printf ("n_chg:%d;", molstat.n_chg);
  11778.  
  11779.   if (molstat.n_C1 > 0)
  11780.     printf ("n_C1:%d;", molstat.n_C1);
  11781.   if (molstat.n_C2 > 0)
  11782.     printf ("n_C2:%d;", molstat.n_C2);
  11783.   /* requirement of a given number of sp3 carbons might be too restrictive, */
  11784.   /* so we use the total number of carbons instead  (initially used variable n_C3 is now n_C) */
  11785.   if (molstat.n_C > 0)
  11786.     printf ("n_C:%d;", molstat.n_C);
  11787.   if (molstat.n_CHB1p > 0)
  11788.     printf ("n_CHB1p:%d;", molstat.n_CHB1p);
  11789.   if (molstat.n_CHB2p > 0)
  11790.     printf ("n_CHB2p:%d;", molstat.n_CHB2p);
  11791.   if (molstat.n_CHB3p > 0)
  11792.     printf ("n_CHB3p:%d;", molstat.n_CHB3p);
  11793.   if (molstat.n_CHB4 > 0)
  11794.     printf ("n_CHB4:%d;", molstat.n_CHB4);
  11795.   if (molstat.n_O2 > 0)
  11796.     printf ("n_O2:%d;", molstat.n_O2);
  11797.   if (molstat.n_O3 > 0)
  11798.     printf ("n_O3:%d;", molstat.n_O3);
  11799.   if (molstat.n_N1 > 0)
  11800.     printf ("n_N1:%d;", molstat.n_N1);
  11801.   if (molstat.n_N2 > 0)
  11802.     printf ("n_N2:%d;", molstat.n_N2);
  11803.   if (molstat.n_N3 > 0)
  11804.     printf ("n_N3:%d;", molstat.n_N3);
  11805.   if (molstat.n_S > 0)
  11806.     printf ("n_S:%d;", molstat.n_S);
  11807.   if (molstat.n_SeTe > 0)
  11808.     printf ("n_SeTe:%d;", molstat.n_SeTe);
  11809.   if (molstat.n_F > 0)
  11810.     printf ("n_F:%d;", molstat.n_F);
  11811.   if (molstat.n_Cl > 0)
  11812.     printf ("n_Cl:%d;", molstat.n_Cl);
  11813.   if (molstat.n_Br > 0)
  11814.     printf ("n_Br:%d;", molstat.n_Br);
  11815.   if (molstat.n_I > 0)
  11816.     printf ("n_I:%d;", molstat.n_I);
  11817.   if (molstat.n_P > 0)
  11818.     printf ("n_P:%d;", molstat.n_P);
  11819.   if (molstat.n_B > 0)
  11820.     printf ("n_B:%d;", molstat.n_B);
  11821.   if (molstat.n_Met > 0)
  11822.     printf ("n_Met:%d;", molstat.n_Met);
  11823.   if (molstat.n_X > 0)
  11824.     printf ("n_X:%d;", molstat.n_X);
  11825.   if (molstat.n_b1 > 0)
  11826.     printf ("n_b1:%d;", molstat.n_b1);
  11827.   if (molstat.n_b2 > 0)
  11828.     printf ("n_b2:%d;", molstat.n_b2);
  11829.   if (molstat.n_b3 > 0)
  11830.     printf ("n_b3:%d;", molstat.n_b3);
  11831.   if (molstat.n_bar > 0)
  11832.     printf ("n_bar:%d;", molstat.n_bar);
  11833.   if (molstat.n_C1O > 0)
  11834.     printf ("n_C1O:%d;", molstat.n_C1O);
  11835.   if (molstat.n_C2O > 0)
  11836.     printf ("n_C2O:%d;", molstat.n_C2O);
  11837.   if (molstat.n_CN > 0)
  11838.     printf ("n_CN:%d;", molstat.n_CN);
  11839.   if (molstat.n_XY > 0)
  11840.     printf ("n_XY:%d;", molstat.n_XY);
  11841.   if (molstat.n_r3 > 0)
  11842.     printf ("n_r3:%d;", molstat.n_r3);
  11843.   if (molstat.n_r4 > 0)
  11844.     printf ("n_r4:%d;", molstat.n_r4);
  11845.   if (molstat.n_r5 > 0)
  11846.     printf ("n_r5:%d;", molstat.n_r5);
  11847.   if (molstat.n_r6 > 0)
  11848.     printf ("n_r6:%d;", molstat.n_r6);
  11849.   if (molstat.n_r7 > 0)
  11850.     printf ("n_r7:%d;", molstat.n_r7);
  11851.   if (molstat.n_r8 > 0)
  11852.     printf ("n_r8:%d;", molstat.n_r8);
  11853.   if (molstat.n_r9 > 0)
  11854.     printf ("n_r9:%d;", molstat.n_r9);
  11855.   if (molstat.n_r10 > 0)
  11856.     printf ("n_r10:%d;", molstat.n_r10);
  11857.   if (molstat.n_r11 > 0)
  11858.     printf ("n_r11:%d;", molstat.n_r11);
  11859.   if (molstat.n_r12 > 0)
  11860.     printf ("n_r12:%d;", molstat.n_r12);
  11861.   if (molstat.n_r13p > 0)
  11862.     printf ("n_r13p:%d;", molstat.n_r13p);
  11863.   if (molstat.n_rN > 0)
  11864.     printf ("n_rN:%d;", molstat.n_rN);
  11865.   if (molstat.n_rN1 > 0)
  11866.     printf ("n_rN1:%d;", molstat.n_rN1);
  11867.   if (molstat.n_rN2 > 0)
  11868.     printf ("n_rN2:%d;", molstat.n_rN2);
  11869.   if (molstat.n_rN3p > 0)
  11870.     printf ("n_rN3p:%d;", molstat.n_rN3p);
  11871.   if (molstat.n_rO > 0)
  11872.     printf ("n_rO:%d;", molstat.n_rO);
  11873.   if (molstat.n_rO1 > 0)
  11874.     printf ("n_rO1:%d;", molstat.n_rO1);
  11875.   if (molstat.n_rO2p > 0)
  11876.     printf ("n_rO2p:%d;", molstat.n_rO2p);
  11877.   if (molstat.n_rS > 0)
  11878.     printf ("n_rS:%d;", molstat.n_rS);
  11879.   if (molstat.n_rX > 0)
  11880.     printf ("n_rX:%d;", molstat.n_rX);
  11881.   if (molstat.n_rAr > 0)
  11882.     printf ("n_rar:%d;", molstat.n_rAr);
  11883. /* p2c: checkmol.pas, line 8532:
  11884.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11885.   /*$IFDEF extended_molstat */
  11886.   if (molstat.n_rBz > 0)
  11887.     printf ("n_rbz:%d;", molstat.n_rBz);
  11888.   if (molstat.n_br2p > 0)
  11889.     printf ("n_br2p:%d;", molstat.n_br2p);
  11890.   if (molstat.n_psg01 > 0)
  11891.     printf ("n_psg01:%d;", molstat.n_psg01);
  11892.   if (molstat.n_psg02 > 0)
  11893.     printf ("n_psg02:%d;", molstat.n_psg02);
  11894.   if (molstat.n_psg13 > 0)
  11895.     printf ("n_psg13:%d;", molstat.n_psg13);
  11896.   if (molstat.n_psg14 > 0)
  11897.     printf ("n_psg14:%d;", molstat.n_psg14);
  11898.   if (molstat.n_psg15 > 0)
  11899.     printf ("n_psg15:%d;", molstat.n_psg15);
  11900.   if (molstat.n_psg16 > 0)
  11901.     printf ("n_psg16:%d;", molstat.n_psg16);
  11902.   if (molstat.n_psg17 > 0)
  11903.     printf ("n_psg17:%d;", molstat.n_psg17);
  11904.   if (molstat.n_psg18 > 0)
  11905.     printf ("n_psg18:%d;", molstat.n_psg18);
  11906.   if (molstat.n_pstm > 0)
  11907.     printf ("n_pstm:%d;", molstat.n_pstm);
  11908.   if (molstat.n_psla > 0)
  11909.     printf ("n_psla:%d;", molstat.n_psla);
  11910.   if (molstat.n_iso > 0)
  11911.     printf ("n_iso:%d;", molstat.n_iso);
  11912.   if (molstat.n_rad > 0)
  11913.     printf ("n_rad:%d;", molstat.n_rad);
  11914.   /*$ENDIF */
  11915.   putchar ('\n');
  11916. }
  11917.  
  11918.  
  11919. static void
  11920. write_molstat_X ()
  11921. {
  11922.   if (auto_ssr)                 /* v0.3n */
  11923.     fix_ssr_ringcounts ();
  11924. /* p2c: checkmol.pas, line 8556:
  11925.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11926. #ifdef REDUCED_SAR
  11927.   printf ("%d,", n_heavyatoms);
  11928.   printf ("%d,", n_heavybonds);
  11929.   printf ("%d,", n_countablerings);
  11930.   /* v0.3n: n_rings =?> n_countablerings */
  11931. #else
  11932.   printf ("%d,", n_heavyatoms);
  11933.   printf ("%d,", n_heavybonds);
  11934.   printf ("%d,", n_rings);      /* v0.3n: n_rings ==> n_countablerings */
  11935. #endif
  11936.   printf ("%d,", molstat.n_QA);
  11937.   printf ("%d,", molstat.n_QB);
  11938.  
  11939.   /* 0.3x */
  11940.   printf ("%d,", molstat.n_chg);
  11941.  
  11942.  
  11943.   printf ("%d,", molstat.n_C1);
  11944.   printf ("%d,", molstat.n_C2);
  11945.   printf ("%d,", molstat.n_C);
  11946.   printf ("%d,", molstat.n_CHB1p);
  11947.   printf ("%d,", molstat.n_CHB2p);
  11948.   printf ("%d,", molstat.n_CHB3p);
  11949.   printf ("%d,", molstat.n_CHB4);
  11950.   printf ("%d,", molstat.n_O2);
  11951.   printf ("%d,", molstat.n_O3);
  11952.   printf ("%d,", molstat.n_N1);
  11953.   printf ("%d,", molstat.n_N2);
  11954.   printf ("%d,", molstat.n_N3);
  11955.   printf ("%d,", molstat.n_S);
  11956.   printf ("%d,", molstat.n_SeTe);
  11957.   printf ("%d,", molstat.n_F);
  11958.   printf ("%d,", molstat.n_Cl);
  11959.   printf ("%d,", molstat.n_Br);
  11960.   printf ("%d,", molstat.n_I);
  11961.   printf ("%d,", molstat.n_P);
  11962.   printf ("%d,", molstat.n_B);
  11963.   printf ("%d,", molstat.n_Met);
  11964.   printf ("%d,", molstat.n_X);
  11965.   printf ("%d,", molstat.n_b1);
  11966.   printf ("%d,", molstat.n_b2);
  11967.   printf ("%d,", molstat.n_b3);
  11968.   printf ("%d,", molstat.n_bar);
  11969.   printf ("%d,", molstat.n_C1O);
  11970.   printf ("%d,", molstat.n_C2O);
  11971.   printf ("%d,", molstat.n_CN);
  11972.   printf ("%d,", molstat.n_XY);
  11973.   printf ("%d,", molstat.n_r3);
  11974.   printf ("%d,", molstat.n_r4);
  11975.   printf ("%d,", molstat.n_r5);
  11976.   printf ("%d,", molstat.n_r6);
  11977.   printf ("%d,", molstat.n_r7);
  11978.   printf ("%d,", molstat.n_r8);
  11979.   printf ("%d,", molstat.n_r9);
  11980.   printf ("%d,", molstat.n_r10);
  11981.   printf ("%d,", molstat.n_r11);
  11982.   printf ("%d,", molstat.n_r12);
  11983.   printf ("%d,", molstat.n_r13p);
  11984.   printf ("%d,", molstat.n_rN);
  11985.   printf ("%d,", molstat.n_rN1);
  11986.   printf ("%d,", molstat.n_rN2);
  11987.   printf ("%d,", molstat.n_rN3p);
  11988.   printf ("%d,", molstat.n_rO);
  11989.   printf ("%d,", molstat.n_rO1);
  11990.   printf ("%d,", molstat.n_rO2p);
  11991.   printf ("%d,", molstat.n_rS);
  11992.   printf ("%d,", molstat.n_rX);
  11993.   printf ("%d", molstat.n_rAr);
  11994. /* p2c: checkmol.pas, line 8579:
  11995.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  11996.   /*$IFDEF extended_molstat */
  11997.   printf (",%d", molstat.n_rBz);
  11998.   printf (",%d", molstat.n_br2p);
  11999.   printf (",%d", molstat.n_psg01);
  12000.   printf (",%d", molstat.n_psg02);
  12001.   printf (",%d", molstat.n_psg13);
  12002.   printf (",%d", molstat.n_psg14);
  12003.   printf (",%d", molstat.n_psg15);
  12004.   printf (",%d", molstat.n_psg16);
  12005.   printf (",%d", molstat.n_psg17);
  12006.   printf (",%d", molstat.n_psg18);
  12007.   printf (",%d", molstat.n_pstm);
  12008.   printf (",%d", molstat.n_psla);
  12009.   printf (",%d", molstat.n_iso);
  12010.   printf (",%d\n", molstat.n_rad);
  12011.   /*$ENDIF */
  12012. }
  12013.  
  12014.  
  12015. /* routines for substructure matching */
  12016.  
  12017.  
  12018. static int
  12019. find_ndl_ref_atom ()
  12020. {
  12021.   int i;
  12022.   int score = -1, index = 0;
  12023.   int n_nb, n_hc, FORLIM;
  12024.  
  12025.   /* finds a characteristic atom in the needle molecule, */
  12026.   /* i.e., one with as many substituents as possible and */
  12027.   /* with as many heteroatom substitutents as possible; */
  12028.   /* added in v0.2d: make sure that reference atom is a heavy atom */
  12029.   /* and not (accidentally) an explicit hydrogen; */
  12030.   /* new in v0.3d: special treatment in case of E/Z geometry search */
  12031.   /* to ensure that the entire A-B=C-D fragment is enclosed in one */
  12032.   /* matchpath, regardless where the recursive search starts; */
  12033.   /* refined in v0.3f: exclude only alkene-C as reference atoms */
  12034.   /* added in v0.3o: needle atom must be "tagged" in order to be */
  12035.   /* selected (prevents unconnected fragments from being overlooked) */
  12036.   if (ndl_n_atoms == 0)
  12037.     return false;
  12038.   if (ez_search && ndl_n_heavyatoms > 2)
  12039.     {
  12040.       FORLIM = ndl_n_atoms;
  12041.       for (i = 1; i <= FORLIM; i++)
  12042.         {                       /* ignore sp2-carbons if not aromatic */
  12043.           /*if ((ndl_atom^[i].atype <> 'C2 ') or (ndl_atom^[i].arom = true)) then */
  12044.           if (ndl_alkene_C (i) == false && ndl_atom[i - 1].tag)
  12045.             {                   /* v0.3o */
  12046.               n_nb = ndl_atom[i - 1].neighbor_count;
  12047.               n_hc = ndl_hetatom_count (i);
  12048.               if (n_nb * 11 + n_hc * 7 > score && ndl_atom[i - 1].heavy)
  12049.                 {
  12050.                   /* v0.3j */
  12051.                   index = i;
  12052.                   score = n_nb * 11 + n_hc * 7; /* changed in v0.3j */
  12053.                 }
  12054.             }
  12055.         }
  12056.     }
  12057.   /* it is possible that no suitable reference atom has been found here */
  12058.   /* (e.g., with "pure" polyenes), so we need a fallback option anyway */
  12059.   if (index == 0)
  12060.     {
  12061.       ez_search = false;        /* just in case it was true */
  12062.       opt_geom = false;         /* just in case it was true */
  12063.       FORLIM = ndl_n_atoms;
  12064.       for (i = 1; i <= FORLIM; i++)
  12065.         {
  12066.           n_nb = ndl_atom[i - 1].neighbor_count;
  12067.           n_hc = ndl_hetatom_count (i);
  12068.           if (n_nb * 11 + n_hc * 7 > score && ndl_atom[i - 1].heavy &&
  12069.               ndl_atom[i - 1].tag)
  12070.             {                   /* v0.3j */
  12071.               index = i;
  12072.               score = n_nb * 11 + n_hc * 7;     /* changed in v0.3j */
  12073.             }
  12074.           /* v0.3o */
  12075.         }
  12076.     }
  12077.   /* now index must be > 0 in any case (except for H2, or all tags have been cleared) */
  12078.   if (index == 0)               /* just to be sure... */
  12079.     index++;
  12080.   return index;
  12081. }
  12082.  
  12083.  
  12084. static void
  12085. cv_init ()
  12086. {
  12087.   /* new in v0.3j */
  12088.   int i;
  12089.  
  12090.   if (cv == NULL)
  12091.     return;
  12092.   memset (cv, 0, sizeof (connval_type));
  12093.  
  12094.   for (i = 0; i < ndl_n_atoms; i++)
  12095.     cv[i].def = ndl_atom[i].neighbor_count;
  12096. }
  12097.  
  12098.  
  12099. static int
  12100. cv_count ()
  12101. {
  12102.   /* new in v0.3j, modified in v0.3m */
  12103.   int i, j;
  12104.   int cvlist[max_atoms];
  12105.   int cvdef;
  12106.   boolean isnew;
  12107.   int entries = 0;
  12108.   int FORLIM;
  12109.  
  12110.   if (cv == NULL)
  12111.     return 0;
  12112.   memset (cvlist, 0, sizeof (int) * max_atoms);
  12113.   FORLIM = ndl_n_atoms;
  12114.   for (i = 0; i < FORLIM; i++)
  12115.     {
  12116.       if (ndl_atom[i].heavy == true)
  12117.         {
  12118.           cvdef = cv[i].def;
  12119.           isnew = true;
  12120.           if (entries > 0)
  12121.             {
  12122.               for (j = 0; j < entries; j++)
  12123.                 {
  12124.                   if (cvlist[j] == cvdef)
  12125.                     isnew = false;
  12126.                 }
  12127.             }
  12128.           if (isnew)
  12129.             {
  12130.               entries++;
  12131.               cvlist[entries - 1] = cvdef;
  12132.             }
  12133.           /* now we have a list of unique connection values */
  12134.         }
  12135.     }
  12136.   return entries;
  12137. }
  12138.  
  12139.  
  12140. static int
  12141. cv_iterate (n_cv_prev)
  12142.      int n_cv_prev;
  12143. {
  12144.   /* new in v0.3j, modified in v0.3m */
  12145.   int i, j;
  12146.   neighbor_rec nb;
  12147.   int nnb, nsum, n_cv, FORLIM;
  12148.  
  12149.   if (cv == NULL || ndl_n_atoms == 0)
  12150.     return false;
  12151.   FORLIM = ndl_n_atoms;
  12152.   /* update the connection values (Morgan algorithm) */
  12153.  
  12154.   memset (nb, 0, sizeof (neighbor_rec));
  12155.  
  12156.   for (i = 1; i <= FORLIM; i++)
  12157.     {
  12158.       if (ndl_atom[i - 1].heavy == true)
  12159.         {
  12160.           get_ndl_neighbors (nb, i);
  12161.           nnb = ndl_atom[i - 1].neighbor_count;
  12162.           nsum = 0;
  12163.           if (nnb > 0)
  12164.             {
  12165.               for (j = 0; j < nnb; j++)
  12166.                 {
  12167.                   if (ndl_atom[nb[j] - 1].heavy == true)
  12168.                     nsum += cv[nb[j] - 1].def;
  12169.                 }
  12170.             }
  12171.           cv[i - 1].tmp = nsum;
  12172.         }
  12173.     }
  12174.   n_cv = cv_count ();
  12175.   if (n_cv > n_cv_prev)
  12176.     {
  12177.       FORLIM = ndl_n_atoms;
  12178.       for (i = 0; i < FORLIM; i++)
  12179.         cv[i].def = cv[i].tmp;
  12180.     }
  12181.   return n_cv;
  12182. }
  12183.  
  12184.  
  12185. static int
  12186. find_ndl_ref_atom_cv ()
  12187. {
  12188.   /* new in v0.3j, modified in v0.3m */
  12189.   int Result, i;
  12190.   int res = 1, it = 0;
  12191.   int n_cv;
  12192.   int n_cv_prev = 0;
  12193.   boolean finished = false;
  12194.   int cvmax = 0;
  12195.   int FORLIM;
  12196.  
  12197.   if (ndl_n_atoms == 0)
  12198.     return 0;
  12199.   /* try */
  12200.   cv = (connval_rec *) safe_malloc (sizeof (connval_type));
  12201.   /* except
  12202.      on e:Eoutofmemory do
  12203.      begin
  12204.      res := find_ndl_ref_atom;
  12205.      $IFDEF debug
  12206.      debugoutput('memory allocation for connection values failed, reverting to standard procedure');
  12207.      $ENDIF
  12208.      end;
  12209.      end; */
  12210.   cv_init ();
  12211.   do
  12212.     {
  12213.       it++;                     /* iteration counter (a safeguard against infinite loops) */
  12214.       n_cv = cv_iterate (n_cv_prev);
  12215.       if (n_cv <= n_cv_prev)
  12216.         finished = true;
  12217.       n_cv_prev = n_cv;
  12218.     }
  12219.   while (!(finished || it > 10000));
  12220.   FORLIM = ndl_n_atoms;
  12221.   /* now that we have canonical connection values (Morgan algorithm), */
  12222.   /* pick the atom with the highest value */
  12223.   /* added in v0.3o: atom must be "tagged" */
  12224.   for (i = 1; i <= FORLIM; i++)
  12225.     {
  12226.       /*writeln('cv for atom ',i,': ',cv^[i].def); */
  12227.       if (((cv[i - 1].def > cvmax) && (ndl_alkene_C (i) == false ||
  12228.                                        ez_search == false))
  12229.           && ndl_atom[i - 1].tag)
  12230.         {                       /* v0.3o */
  12231.           cvmax = cv[i - 1].def;
  12232.           res = i;
  12233.         }
  12234.     }
  12235.   Result = res;
  12236.   /* try */
  12237.   if (cv != NULL)
  12238.     {
  12239.       free (cv);
  12240.       cv = NULL;
  12241.     }
  12242.   /* except
  12243.      on e:Einvalidpointer do begin end;
  12244.      end; */
  12245.   return Result;
  12246. }
  12247.  
  12248.  
  12249. static boolean
  12250. atomtypes_OK_strict (ndl_a, hst_a)
  12251.      int ndl_a, hst_a;
  12252. {
  12253.   /* new in v0.2f */
  12254.   str2 ndl_el;
  12255.   str3 ndl_atype;
  12256.   str2 hst_el;
  12257.   str3 hst_atype;
  12258.   int ndl_nbc, hst_nbc, ndl_Hexp, hst_Htot;
  12259.   boolean res = false;
  12260.  
  12261.   strcpy (ndl_el, ndl_atom[ndl_a - 1].element);
  12262.   strcpy (ndl_atype, ndl_atom[ndl_a - 1].atype);
  12263.   ndl_nbc = ndl_atom[ndl_a - 1].neighbor_count;
  12264.   ndl_Hexp = ndl_atom[ndl_a - 1].Hexp;
  12265.   strcpy (hst_el, atom[hst_a - 1].element);
  12266.   strcpy (hst_atype, atom[hst_a - 1].atype);
  12267.   hst_nbc = atom[hst_a - 1].neighbor_count;
  12268.   hst_Htot = atom[hst_a - 1].Htot;
  12269.   /* v0.3o: formal charges must be the same */
  12270.  
  12271.   if (ndl_atom[ndl_a - 1].formal_charge != atom[hst_a - 1].formal_charge)
  12272.     return false;
  12273.  
  12274.   /* v0.3x: isotope nucleon numbers must be the same */
  12275.  
  12276.   if (ndl_atom[ndl_a - 1].nucleon_number != atom[hst_a - 1].nucleon_number)
  12277.     return false;
  12278.  
  12279.   /* v0.3x: radicals must be the same */
  12280.  
  12281.   if (ndl_atom[ndl_a - 1].radical_type != atom[hst_a - 1].radical_type)
  12282.     return false;
  12283.  
  12284.   if (!strcmp (ndl_atype, hst_atype))
  12285.     res = true;
  12286.   else
  12287.     {
  12288.       if (!strcmp (ndl_el, hst_el) && ndl_atom[ndl_a - 1].arom &&
  12289.           atom[hst_a - 1].arom)
  12290.         res = true;
  12291.       if (ndl_querymol
  12292.           && (ndl_atom[ndl_a - 1].q_arom && atom[hst_a - 1].arom))
  12293.         res = true;             /* 0.3 p */
  12294.     }
  12295.   if (!strcmp (ndl_el, "A ") && atom[hst_a - 1].heavy)
  12296.     res = true;
  12297.   if (!strcmp (ndl_el, "Q "))
  12298.     {
  12299.       if (atom[hst_a - 1].heavy && strcmp (hst_el, "C "))
  12300.         res = true;
  12301.     }
  12302.   if (!strcmp (ndl_el, "X "))
  12303.     {
  12304.       if (!strcmp (hst_el, "F ") || !strcmp (hst_el, "CL") ||
  12305.           !strcmp (hst_el, "BR") || !strcmp (hst_el, "I ")
  12306.           || !strcmp (hst_el, "AT"))
  12307.         res = true;
  12308.     }
  12309.   /* if needle atom has more substituents than haystack atom ==> no match */
  12310.   if (ndl_nbc > hst_nbc)
  12311.     res = false;
  12312.   /* check for explicit hydrogens */
  12313.   if (ndl_Hexp > hst_Htot)
  12314.     res = false;
  12315. /* p2c: checkmol.pas, line 8859:
  12316.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12317.   /*$IFDEF debug */
  12318.   /* if res then debugoutput('atom types OK ('+inttostr(ndl_a)+'/'+inttostr(hst_a)+')')
  12319.      else debugoutput('atom types not OK ('+inttostr(ndl_a)+':'+ndl_atype+'/'+inttostr(hst_a)+':'+hst_atype+')'); */
  12320.   /*$ENDIF */
  12321.   /* new in v0.3m: in "fingerprint mode", also query atom symbols must match */
  12322.   if (opt_fp)
  12323.     {
  12324.       if (strcmp (ndl_el, hst_el))
  12325.         res = false;
  12326.     }
  12327.   return res;
  12328. }
  12329.  
  12330.  
  12331. static boolean
  12332. atomtypes_OK (ndl_a, hst_a)
  12333.      int ndl_a, hst_a;
  12334. {
  12335.   str2 ndl_el, hst_el;
  12336.   int ndl_nbc, hst_nbc, ndl_Hexp, hst_Htot;
  12337.   boolean res = false;
  12338.  
  12339.   if (ndl_a < 1 || ndl_a > ndl_n_atoms || hst_a < 1 || hst_a > n_atoms)
  12340.     return false;
  12341.   /* check for opposite charges;  v0.3l, refined in v0.3o, 0.3x */
  12342.   /* except in strict mode, matching pairs of charged+uncharged atoms  */
  12343.   /* are tolerated (this is a feature, not a bug) */
  12344.   if (opt_chg)
  12345.     {
  12346.       if (ndl_atom[ndl_a - 1].formal_charge != atom[hst_a - 1].formal_charge)
  12347.         return false;
  12348.     }
  12349. //  else
  12350. //    {
  12351. //      if (ndl_atom[ndl_a - 1].formal_charge != 0 &&
  12352. //        atom[hst_a - 1].formal_charge != 0 &&
  12353. //        ndl_atom[ndl_a - 1].formal_charge != atom[hst_a - 1].formal_charge)
  12354. //      return false;
  12355. //    }
  12356. //
  12357. //  /* v0.3x: isotopes must be the same */
  12358.   if (opt_iso)
  12359.     {
  12360.       if (ndl_atom[ndl_a - 1].nucleon_number !=
  12361.           atom[hst_a - 1].nucleon_number)
  12362.         return false;
  12363.     }
  12364. //  else
  12365. //    {
  12366. //      if (ndl_atom[ndl_a - 1].nucleon_number != 0 &&
  12367. //        atom[hst_a - 1].nucleon_number != 0 &&
  12368. //        ndl_atom[ndl_a - 1].nucleon_number !=
  12369. //        atom[hst_a - 1].nucleon_number)
  12370. //      return false;
  12371. //    }
  12372. //
  12373. //  /* v0.3x: radicals must be the same */
  12374.   if (opt_rad)
  12375.     {
  12376.       if (ndl_atom[ndl_a - 1].radical_type != atom[hst_a - 1].radical_type)
  12377.         return false;
  12378.     }
  12379. //  else
  12380. //    {
  12381. //      if (ndl_atom[ndl_a - 1].radical_type != 0 &&
  12382. //        atom[hst_a - 1].radical_type != 0 &&
  12383. //        ndl_atom[ndl_a - 1].radical_type != atom[hst_a - 1].radical_type)
  12384. //      return false;
  12385. //    }
  12386.  
  12387.   /* in exact mode, check if (disconnected) fragment is already tagged; v0.3o */
  12388.   if (opt_exact && atom[hst_a - 1].tag == true)
  12389.     {
  12390. /* p2c: checkmol.pas, line 8899:
  12391.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12392.       /*$IFDEF debug */
  12393.       /* debugoutput('fragmnet already tagged at '+inttostr(hst_a)); */
  12394.       /*$ENDIF */
  12395.       return false;
  12396.     }
  12397.   if (opt_strict)               /* new in v0.2f */
  12398.     return (atomtypes_OK_strict (ndl_a, hst_a));
  12399.   strcpy (ndl_el, ndl_atom[ndl_a - 1].element);
  12400.   ndl_nbc = ndl_atom[ndl_a - 1].neighbor_count;
  12401.   ndl_Hexp = ndl_atom[ndl_a - 1].Hexp;
  12402.   strcpy (hst_el, atom[hst_a - 1].element);
  12403.   hst_nbc = atom[hst_a - 1].neighbor_count;
  12404.   hst_Htot = atom[hst_a - 1].Htot;
  12405.   if (!strcmp (ndl_el, hst_el)) /* very simplified... */
  12406.     res = true;
  12407.   if (!strcmp (ndl_el, "A ") && atom[hst_a - 1].heavy)
  12408.     res = true;
  12409.   if (!strcmp (ndl_el, "Q "))
  12410.     {
  12411.       if (atom[hst_a - 1].heavy && strcmp (hst_el, "C "))
  12412.         res = true;
  12413.     }
  12414.   if (!strcmp (ndl_el, "X "))
  12415.     {
  12416.       if (!strcmp (hst_el, "F ") || !strcmp (hst_el, "CL") ||
  12417.           !strcmp (hst_el, "BR") || !strcmp (hst_el, "I ")
  12418.           || !strcmp (hst_el, "AT"))
  12419.         res = true;
  12420.     }
  12421.   /* v0.3o: in exact mode, check for identical neighbor_count */
  12422.   if (opt_exact)
  12423.     {
  12424.       if (ndl_nbc != hst_nbc)
  12425.         {
  12426.           res = false;
  12427. /* p2c: checkmol.pas, line 8934:
  12428.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12429.           /*$IFDEF debug */
  12430.           //debugoutput
  12431.           //  ("exact match failed: different number of neighbor atoms");
  12432.           /*$ENDIF */
  12433.         }
  12434.     }
  12435.   /* if needle atom has more substituents than haystack atom ==> no match */
  12436.   if (ndl_nbc > hst_nbc)
  12437.     res = false;
  12438.   /* check for explicit hydrogens */
  12439.   if (ndl_Hexp > hst_Htot)
  12440.     res = false;
  12441. /* p2c: checkmol.pas, line 8943:
  12442.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12443.   /*$IFDEF debug */
  12444.   /* if res then debugoutput('atom types OK ('+inttostr(ndl_a)+'/'+inttostr(hst_a)+')')
  12445.      else debugoutput('atom types not OK ('+inttostr(ndl_a)+'/'+inttostr(hst_a)+')'); */
  12446.   /*$ENDIF */
  12447.   return res;
  12448. }
  12449.  
  12450.  
  12451. static boolean
  12452. bondtypes_OK_strict (ndl_b, hst_b)
  12453.      int ndl_b, hst_b;
  12454. {
  12455.   boolean ndl_arom, hst_arom;
  12456.   char ndl_btype, hst_btype;
  12457.   int ndl_rc;                   /* new in v0.3d */
  12458.   int hst_rc;                   /* new in v0.3d */
  12459.   int ndl_btopo;                /* new in v0.3d */
  12460.   boolean res = false;
  12461. /* p2c: checkmol.pas, line 8960:
  12462.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12463.   /*$IFDEF debug */
  12464.   /*char na[256]; char ha[256];*/
  12465.   char tstr[256];
  12466.  
  12467.   /*$ENDIF */
  12468. /* p2c: checkmol.pas, line 8966:
  12469.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12470.   /*$IFDEF debug */
  12471.   *tstr = '\0';                 /* for debugging purposes only */
  12472.   /*$ENDIF */
  12473.   ndl_arom = ndl_bond[ndl_b - 1].arom;
  12474.   ndl_btype = ndl_bond[ndl_b - 1].btype;
  12475.   ndl_rc = ndl_bond[ndl_b - 1].ring_count;
  12476.   ndl_btopo = ndl_bond[ndl_b - 1].topo;
  12477.   hst_arom = bond[hst_b - 1].arom;
  12478.   hst_btype = bond[hst_b - 1].btype;
  12479.   hst_rc = bond[hst_b - 1].ring_count;
  12480. /* p2c: checkmol.pas, line 8976:
  12481.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12482.   /*$IFDEF debug */
  12483.   /*if (ndl_arom)
  12484.     strcpy (na, "(ar)");
  12485.   else
  12486.     *na = '\0';
  12487.   if (hst_arom)
  12488.     strcpy (ha, "(ar)");
  12489.   else
  12490.     *ha = '\0';*/
  12491.   /*$ENDIF */
  12492.   if (ndl_arom == true && hst_arom == true)
  12493.     res = true;
  12494.   if (ndl_arom == false && hst_arom == false)
  12495.     {
  12496.       if (ndl_btype == hst_btype)
  12497.         res = true;
  12498.       if (ndl_btype == 'l' && (hst_btype == 'S' || hst_btype == 'D'))
  12499.         res = true;
  12500.       if (ndl_btype == 's' && hst_btype == 'S')
  12501.         res = true;
  12502.       if (ndl_btype == 'd' && hst_btype == 'D')
  12503.         res = true;
  12504.     }
  12505.   /* a little exception: */
  12506.   if (ndl_arom == false && hst_arom == true)
  12507.     {
  12508.       if (ndl_btype == 'A')
  12509.         res = true;
  12510.       if (ndl_btype == 's' || ndl_btype == 'd')
  12511.         res = true;
  12512.       if (ndl_bond[ndl_b - 1].q_arom)
  12513.         res = true;             /* 0.3p */
  12514.     }
  12515.   if (ndl_btype == 'a')
  12516.     res = true;
  12517.   /* new in v0.3d: strict comparison of topology (and even ring_count!) */
  12518.   if (ndl_btopo < btopo_always_any || ndl_btopo == btopo_exact_rc)
  12519.     {
  12520.       if (ndl_rc != hst_rc)
  12521.         {
  12522.           res = false;          /* this excludes further ring annulations as well as */
  12523. /* p2c: checkmol.pas, line 9001:
  12524.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12525.           /*$IFDEF debug */
  12526.           /* open-chains query structures to be found in rings */
  12527.           /*
  12528.              tstr := ' ringcount mismatch ('+inttostr(ndl_rc)+'/'+inttostr(hst_rc)+')';   */
  12529.           /*$ENDIF */
  12530.         }
  12531.     }
  12532.   else
  12533.     {
  12534.       if (ndl_btopo == btopo_excess_rc && hst_rc <= ndl_rc)
  12535.         {
  12536.           res = false;
  12537. /* p2c: checkmol.pas, line 9010:
  12538.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12539.           /*$IFDEF debug */
  12540.           /* tstr := ' ringcount mismatch ('+inttostr(ndl_rc)+'/'+inttostr(hst_rc)+')'; */
  12541.           /*$ENDIF */
  12542.         }
  12543.     }
  12544. /* p2c: checkmol.pas, line 9015:
  12545.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12546.   /*$IFDEF debug */
  12547.   /* if res then debugoutput('bond types OK ('+inttostr(ndl_b)+':'+ndl_btype+na+'/'+inttostr(hst_b)+':'+hst_btype+ha+')') else
  12548.      debugoutput('bond types not OK ('+inttostr(ndl_b)+':'+ndl_btype+na+'/'+inttostr(hst_b)+':'+hst_btype+ha+tstr+')'); */
  12549.   /*$ENDIF */
  12550.   return res;
  12551. }
  12552.  
  12553.  
  12554. static boolean
  12555. bondtypes_OK (ndl_b, hst_b)
  12556.      int ndl_b, hst_b;
  12557. {
  12558.   boolean ndl_arom, hst_arom;
  12559.   char ndl_btype, hst_btype;
  12560.   int ndl_rc;                   /* new in v0.3d */
  12561.   int hst_rc;                   /* new in v0.3d */
  12562.   int ndl_btopo;                /* new in v0.3d */
  12563.   boolean res = false;
  12564. /* p2c: checkmol.pas, line 9032:
  12565.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12566.   /*$IFDEF debug */
  12567.   /*char na[256], ha[256];*/
  12568.   char tstr[256];
  12569.   /*$ENDIF */
  12570.   int a1, a2;
  12571.   str2 a1_el, a2_el;
  12572.  
  12573.   if (ndl_b < 1 || ndl_b > ndl_n_bonds || hst_b < 1 || hst_b > n_bonds)
  12574.     return false;
  12575.   if (opt_strict)               /* new in v0.2f */
  12576.     return (bondtypes_OK_strict (ndl_b, hst_b));
  12577. /* p2c: checkmol.pas, line 9051:
  12578.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12579.   /*$IFDEF debug */
  12580.   *tstr = '\0';                 /* for debug purposes only */
  12581.   /*$ENDIF */
  12582.   ndl_arom = ndl_bond[ndl_b - 1].arom;
  12583.   ndl_btype = ndl_bond[ndl_b - 1].btype;
  12584.   hst_arom = bond[hst_b - 1].arom;
  12585.   hst_btype = bond[hst_b - 1].btype;
  12586.   ndl_rc = ndl_bond[ndl_b - 1].ring_count;
  12587.   hst_rc = bond[hst_b - 1].ring_count;
  12588.   ndl_btopo = ndl_bond[ndl_b - 1].topo;
  12589. /* p2c: checkmol.pas, line 9061:
  12590.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12591.   /*$IFDEF debug */
  12592.   //if (ndl_arom)
  12593. //    strcpy (na, "(ar)");
  12594. //  else
  12595. //    *na = '\0';
  12596. //  if (hst_arom)
  12597. //    strcpy (ha, "(ar)");
  12598. //  else
  12599. //    *ha = '\0';
  12600.   /*$ENDIF */
  12601.   if (ndl_arom == true && hst_arom == true)
  12602.     res = true;
  12603.   if (ndl_arom == false && hst_arom == false)
  12604.     {
  12605.       if (ndl_btype == hst_btype)
  12606.         res = true;
  12607.       if (ndl_btype == 'l' && (hst_btype == 'S' || hst_btype == 'D'))
  12608.         res = true;
  12609.       if (ndl_btype == 's' && hst_btype == 'S')
  12610.         res = true;
  12611.       if (ndl_btype == 'd' && hst_btype == 'D')
  12612.         res = true;
  12613.     }
  12614.   /* a little exception: */
  12615.   if (ndl_arom == false && hst_arom == true)
  12616.     {
  12617.       if (ndl_btype == 'A')
  12618.         res = true;
  12619.       if (ndl_btype == 's' || ndl_btype == 'd')
  12620.         res = true;
  12621.       if (ndl_btype == 'D')
  12622.         {                       /* added in 0.2d: do not accept C=O etc. as C-O/arom */
  12623.           a1 = ndl_bond[ndl_b - 1].a1;
  12624.           a2 = ndl_bond[ndl_b - 1].a2;
  12625.           strcpy (a1_el, ndl_atom[a1 - 1].element);
  12626.           strcpy (a2_el, ndl_atom[a2 - 1].element);
  12627.           if (strcmp (a1_el, "O ") && strcmp (a2_el, "O ")
  12628.               && strcmp (a1_el, "S ") && strcmp (a2_el, "S ")
  12629.               && strcmp (a1_el, "SE") && strcmp (a2_el, "SE")
  12630.               && strcmp (a1_el, "TE") && strcmp (a2_el, "TE"))
  12631.             res = true;
  12632.         }
  12633.       if (ndl_bond[ndl_b - 1].q_arom)
  12634.         res = true;             /* 0.3p */
  12635.     }
  12636.   if (ndl_btype == 'a')
  12637.     res = true;
  12638.   /* new in v0.3d: obey topology requirements in query structure */
  12639.   if (ndl_btopo != btopo_any && ndl_btopo != btopo_always_any)
  12640.     {
  12641.   if (ndl_btopo == btopo_ring && hst_rc == 0)
  12642.     res = false;
  12643.   if (ndl_btopo == btopo_chain && hst_rc > 0)
  12644.     res = false;
  12645.   if (ndl_btopo == btopo_excess_rc && hst_rc <= ndl_rc)
  12646.     res = false;
  12647.   if (ndl_btopo == btopo_exact_rc && hst_rc != ndl_rc)
  12648.     res = false;
  12649. }    
  12650. /* p2c: checkmol.pas, line 9098:
  12651.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12652.   /*$IFDEF debug */
  12653.   /* if res = false then tstr := ' bond topology mismatch '+inttostr(ndl_rc)+'/'+inttostr(hst_rc); */
  12654.   /*$ENDIF */
  12655. /* p2c: checkmol.pas, line 9102:
  12656.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  12657.   /*$IFDEF debug */
  12658.   /*
  12659.      if res then debugoutput('bond types OK ('+inttostr(ndl_b)+':'+ndl_btype+na+'/'+inttostr(hst_b)+':'+hst_btype+ha+')') else
  12660.      debugoutput('bond types not OK ('+inttostr(ndl_b)+':'+ndl_btype+na+'/'+inttostr(hst_b)+':'+hst_btype+ha+tstr+')'); */
  12661.   /*$ENDIF */
  12662.   return res;
  12663. }
  12664.  
  12665.  
  12666. static boolean
  12667. matrix_OK (m, ndl_dim, hst_dim)
  12668. boolean (*m)[max_neighbors];
  12669.      int ndl_dim, hst_dim;
  12670. {
  12671.   /* new, recursive version in v0.2i: can handle up to max_neighbors substituents */
  12672.   boolean mr = false;
  12673.   matchmatrix lm;
  12674.   int i, ii, j, lndl_dim, lhst_dim;
  12675.  
  12676.   if (ndl_dim < 1 || ndl_dim > max_neighbors || hst_dim < 1 ||
  12677.       hst_dim > max_neighbors || ndl_dim > hst_dim)
  12678.     return false;
  12679.   if (ndl_dim == 1)
  12680.     {
  12681.       for (i = 0; i < hst_dim; i++)
  12682.         {
  12683.           if (m[0][i])
  12684.             mr = true;
  12685.         }
  12686.       return mr;
  12687.     }
  12688.   for (i = 1; i <= hst_dim; i++)
  12689.     {
  12690.       if (m[0][i - 1])
  12691.         {
  12692.           /* write remaining fields into a new matchmatrix which is smaller by 1x1 */
  12693.           memset (lm, false, sizeof (matchmatrix));
  12694.           for (j = 2; j <= ndl_dim; j++)
  12695.             {
  12696.               lhst_dim = 0;
  12697.               for (ii = 1; ii <= hst_dim; ii++)
  12698.                 {
  12699.                   if (ii != i)
  12700.                     {
  12701.                       lhst_dim++;
  12702.                       lm[j - 2][lhst_dim - 1] = m[j - 1][ii - 1];
  12703.                     }
  12704.                 }
  12705.             }
  12706.           lndl_dim = ndl_dim - 1;
  12707.           if (matrix_OK (lm, lndl_dim, lhst_dim))
  12708.             {                   /* recursive call to matrix_OK */
  12709.               return true;
  12710.               /* stop any further work immediately */
  12711.             }
  12712.         }
  12713.     }
  12714.   return false;
  12715. }
  12716.  
  12717.  
  12718. static boolean
  12719. is_flat (angle_deg)
  12720.      double angle_deg;
  12721. {
  12722.   /* new in v0.3j */
  12723.   if (fabs (angle_deg) > 5 && fabs (angle_deg) < 175)
  12724.     return false;
  12725.   else
  12726.     return true;
  12727. }
  12728.  
  12729.  
  12730. static boolean
  12731. chirality_OK (ndl_cp, hst_cp)
  12732.      int *ndl_cp, *hst_cp;
  12733. {
  12734.   boolean res = true;
  12735.   double ndl_ct, hst_ct, ndl_ct_deg, hst_ct_deg;
  12736.   p_3d np1, np2, np3, np4, hp1, hp2, hp3, hp4;
  12737.   int level = 0;
  12738.   int i;
  12739.   boolean up = false, down = false, updown = false;
  12740.   int ta1, ta2, ta3, ta4, ba1, ba2, FORLIM;
  12741.  
  12742.   /* fill temporary atom variables */
  12743.   ta1 = ndl_cp[0];              /* this is the central atom */
  12744.   ta2 = ndl_cp[1];
  12745.   ta3 = ndl_cp[2];
  12746.   ta4 = ndl_cp[3];
  12747.   /* first, get the central atom of the needle */
  12748.   np2.x = ndl_atom[ta1 - 1].x;
  12749.   np2.y = ndl_atom[ta1 - 1].y;
  12750.   np2.z = ndl_atom[ta1 - 1].z;
  12751.   /* next, do the same for all 3 substituent atoms */
  12752.   np1.x = ndl_atom[ta2 - 1].x;
  12753.   np1.y = ndl_atom[ta2 - 1].y;
  12754.   np1.z = ndl_atom[ta2 - 1].z;
  12755.   np3.x = ndl_atom[ta3 - 1].x;
  12756.   np3.y = ndl_atom[ta3 - 1].y;
  12757.   np3.z = ndl_atom[ta3 - 1].z;
  12758.   np4.x = ndl_atom[ta4 - 1].x;
  12759.   np4.y = ndl_atom[ta4 - 1].y;
  12760.   np4.z = ndl_atom[ta4 - 1].z;
  12761.   /* now check all needle bonds if we should care about up/down bonds */
  12762.   if (ndl_n_bonds > 0)
  12763.     {
  12764.       FORLIM = ndl_n_bonds;
  12765.       for (i = 0; i < FORLIM; i++)
  12766.         {
  12767.           if (ndl_bond[i].stereo == bstereo_up ||
  12768.               ndl_bond[i].stereo == bstereo_down)
  12769.             {
  12770.               ba1 = ndl_bond[i].a1;
  12771.               ba2 = ndl_bond[i].a2;
  12772.               if (ba1 == ta1 && ndl_bond[i].stereo == bstereo_up)
  12773.                 {
  12774.                   up = true;
  12775.                   if (ba2 == ta2 || ba2 == ta3 || ba2 == ta4)
  12776.                     {
  12777.                       updown = true;
  12778.                       if (ba2 == ta2)
  12779.                         np1.z += 0.8;
  12780.                       if (ba2 == ta3)
  12781.                         np3.z += 0.8;
  12782.                       if (ba2 == ta4)
  12783.                         np4.z += 0.8;
  12784.                     }
  12785.                   else
  12786.                     level++;
  12787.                 }
  12788.               if (ba1 == ta1 && ndl_bond[i].stereo == bstereo_down)
  12789.                 {
  12790.                   down = true;
  12791.                   if (ba2 == ta2 || ba2 == ta3 || ba2 == ta4)
  12792.                     {
  12793.                       updown = true;
  12794.                       if (ba2 == ta2)
  12795.                         np1.z -= 0.8;
  12796.                       if (ba2 == ta3)
  12797.                         np3.z -= 0.8;
  12798.                       if (ba2 == ta4)
  12799.                         np4.z -= 0.8;
  12800.                     }
  12801.                   else
  12802.                     level--;
  12803.                 }
  12804.               if (ba2 == ta1 && ndl_bond[i].stereo == bstereo_up)
  12805.                 {
  12806.                   down = true;
  12807.                   if (ba1 == ta2 || ba1 == ta3 || ba1 == ta4)
  12808.                     {
  12809.                       updown = true;
  12810.                       if (ba1 == ta2)
  12811.                         np1.z -= 0.8;
  12812.                       if (ba1 == ta3)
  12813.                         np3.z -= 0.8;
  12814.                       if (ba1 == ta4)
  12815.                         np4.z -= 0.8;
  12816.                     }
  12817.                   else
  12818.                     level--;
  12819.                 }
  12820.               if (ba2 == ta1 && ndl_bond[i].stereo == bstereo_down)
  12821.                 {
  12822.                   up = true;
  12823.                   if (ba1 == ta2 || ba1 == ta3 || ba1 == ta4)
  12824.                     {
  12825.                       updown = true;
  12826.                       if (ba1 == ta2)
  12827.                         np1.z += 0.8;
  12828.                       if (ba1 == ta3)
  12829.                         np3.z += 0.8;
  12830.                       if (ba1 == ta4)
  12831.                         np4.z += 0.8;
  12832.                     }
  12833.                   else
  12834.                     level++;
  12835.                 }
  12836.             }
  12837.         }                       /* for i ... */
  12838.       if (updown == false && level != 0)
  12839.         {
  12840.           if (level > 0)
  12841.             np2.z += 0.3;
  12842.           if (level < 0)
  12843.             np2.z -= 0.3;
  12844.         }
  12845.       else
  12846.         {
  12847.           if (up)
  12848.             np2.z += 0.1;
  12849.           if (down)
  12850.             np2.z -= 0.1;
  12851.         }
  12852.     }
  12853.   /* fill temporary atom variables again */
  12854.   ta1 = hst_cp[0];
  12855.   ta2 = hst_cp[1];
  12856.   ta3 = hst_cp[2];
  12857.   ta4 = hst_cp[3];
  12858.   /* then, get the central atom of the haystack */
  12859.   hp2.x = atom[ta1 - 1].x;
  12860.   hp2.y = atom[ta1 - 1].y;
  12861.   hp2.z = atom[ta1 - 1].z;
  12862.   /* next, do the same for all 3 substituent atoms */
  12863.   hp1.x = atom[ta2 - 1].x;
  12864.   hp1.y = atom[ta2 - 1].y;
  12865.   hp1.z = atom[ta2 - 1].z;
  12866.   hp3.x = atom[ta3 - 1].x;
  12867.   hp3.y = atom[ta3 - 1].y;
  12868.   hp3.z = atom[ta3 - 1].z;
  12869.   hp4.x = atom[ta4 - 1].x;
  12870.   hp4.y = atom[ta4 - 1].y;
  12871.   hp4.z = atom[ta4 - 1].z;
  12872.   /* now check all haystack bonds if we should care about up/down bonds */
  12873.   level = 0;
  12874.   updown = false;
  12875.   up = false;
  12876.   down = false;
  12877.   if (n_bonds > 0)
  12878.     {
  12879.       FORLIM = n_bonds;
  12880.       for (i = 0; i < FORLIM; i++)
  12881.         {
  12882.           if (bond[i].stereo == bstereo_up || bond[i].stereo == bstereo_down)
  12883.             {
  12884.               ba1 = bond[i].a1;
  12885.               ba2 = bond[i].a2;
  12886.               if (ba1 == ta1 && bond[i].stereo == bstereo_up)
  12887.                 {
  12888.                   up = true;
  12889.                   if (ba2 == ta2 || ba2 == ta3 || ba2 == ta4)
  12890.                     {
  12891.                       updown = true;
  12892.                       if (ba2 == ta2)
  12893.                         hp1.z += 0.8;
  12894.                       if (ba2 == ta3)
  12895.                         hp3.z += 0.8;
  12896.                       if (ba2 == ta4)
  12897.                         hp4.z += 0.8;
  12898.                     }
  12899.                   else
  12900.                     level++;
  12901.                 }
  12902.               if (ba1 == ta1 && bond[i].stereo == bstereo_down)
  12903.                 {
  12904.                   down = true;
  12905.                   if (ba2 == ta2 || ba2 == ta3 || ba2 == ta4)
  12906.                     {
  12907.                       updown = true;
  12908.                       if (ba2 == ta2)
  12909.                         hp1.z -= 0.8;
  12910.                       if (ba2 == ta3)
  12911.                         hp3.z -= 0.8;
  12912.                       if (ba2 == ta4)
  12913.                         hp4.z -= 0.8;
  12914.                     }
  12915.                   else
  12916.                     level--;
  12917.                 }
  12918.               if (ba2 == ta1 && bond[i].stereo == bstereo_up)
  12919.                 {
  12920.                   down = true;
  12921.                   if (ba1 == ta2 || ba1 == ta3 || ba1 == ta4)
  12922.                     {
  12923.                       updown = true;
  12924.                       if (ba1 == ta2)
  12925.                         hp1.z -= 0.8;
  12926.                       if (ba1 == ta3)
  12927.                         hp3.z -= 0.8;
  12928.                       if (ba1 == ta4)
  12929.                         hp4.z -= 0.8;
  12930.                     }
  12931.                   else
  12932.                     level--;
  12933.                 }
  12934.               if (ba2 == ta1 && bond[i].stereo == bstereo_down)
  12935.                 {
  12936.                   up = true;
  12937.                   if (ba1 == ta2 || ba1 == ta3 || ba1 == ta4)
  12938.                     {
  12939.                       updown = true;
  12940.                       if (ba1 == ta2)
  12941.                         hp1.z += 0.8;
  12942.                       if (ba1 == ta3)
  12943.                         hp3.z += 0.8;
  12944.                       if (ba1 == ta4)
  12945.                         hp4.z += 0.8;
  12946.                     }
  12947.                   else
  12948.                     level++;
  12949.                 }
  12950.             }
  12951.         }                       /* for i ... */
  12952.       if (updown == false && level != 0)
  12953.         {
  12954.           if (level > 0)
  12955.             hp2.z += 0.3;
  12956.           if (level < 0)
  12957.             hp2.z -= 0.3;
  12958.         }
  12959.       else
  12960.         {
  12961.           if (up)
  12962.             hp2.z += 0.1;
  12963.           if (down)
  12964.             hp2.z -= 0.1;
  12965.         }
  12966.     }
  12967.   /* get the pseudo-torsion angles */
  12968.   ndl_ct = ctorsion (np1, np2, np3, np4);
  12969.   hst_ct = ctorsion (hp1, hp2, hp3, hp4);
  12970.   ndl_ct_deg = radtodeg (ndl_ct);
  12971.   hst_ct_deg = radtodeg (hst_ct);
  12972.   /* now do a plausibility check and finally check the sense */
  12973.   /* (clockwise or counterclockwise) */
  12974.   /*
  12975.      if (abs(ndl_ct_deg) > 5) and (abs(ndl_ct_deg) < 175) and
  12976.      (abs(hst_ct_deg) > 5) and (abs(hst_ct_deg) < 175) and
  12977.      (ndl_ct_deg * hst_ct_deg < 0) then res := false;
  12978.    */
  12979.   if (((!is_flat (ndl_ct_deg)) && (!is_flat (hst_ct_deg))) &&
  12980.       ndl_ct_deg * hst_ct_deg < 0)
  12981.     res = false;
  12982.   if (rs_strict)
  12983.     {
  12984.       if (((is_flat (ndl_ct_deg) && (!is_flat (hst_ct_deg))) |
  12985.            (is_flat (hst_ct_deg) && (!is_flat (ndl_ct_deg)))) ||
  12986.           ndl_ct_deg * hst_ct_deg < 0)
  12987.         res = false;
  12988.     }
  12989.   return res;
  12990. }
  12991.  
  12992.  
  12993. static boolean
  12994. ndl_maybe_chiral (na)
  12995.      int na;
  12996. {
  12997.   /* new in v0.3h */
  12998.   boolean res = false;
  12999.   str2 el;
  13000.   str3 at;
  13001.   int n_nb;
  13002.  
  13003.   strcpy (el, ndl_atom[na - 1].element);
  13004.   strcpy (at, ndl_atom[na - 1].atype);
  13005.   n_nb = ndl_atom[na - 1].neighbor_count;
  13006.   if (!strcmp (at, "C3 ") && n_nb > 2)
  13007.     res = true;
  13008.   if (!strcmp (el, "N "))
  13009.     {
  13010.       if (!strcmp (at, "N3+") && n_nb == 4)
  13011.         res = true;
  13012.     }
  13013.   if (!strcmp (el, "S "))
  13014.     {                           /* sulfoxide */
  13015.       if ((n_nb == 3) && (ndl_hetatom_count (na) == 1))
  13016.         res = true;
  13017.     }
  13018.   if (strcmp (el, "P ") && strcmp (el, "AS"))   /* "As" added in v0.3j */
  13019.     return res;
  13020.   if (n_nb > 3)                 /* are we missing something here? */
  13021.     res = true;
  13022.   if (ndl_hetatom_count (na) >= 2)      /* v0.3m; ignore phosphates etc. */
  13023.     res = false;
  13024.   return res;
  13025. }
  13026.  
  13027.  
  13028. static boolean
  13029. is_matching (ndl_xmp, hst_xmp)
  13030.      int *ndl_xmp, *hst_xmp;
  13031. {
  13032.   int i, j, k, l, m, ndl_n_nb, n_nb, ndl_a, hst_a;
  13033.   int ndl_b = 0, hst_b = 0, prev_ndl_a = 0, prev_hst_a = 0;
  13034.   int next_ndl_a, next_hst_a;
  13035.   neighbor_rec ndl_nb, hst_nb;
  13036.   matchmatrix mm;
  13037.   int ndl_mp_len, hst_mp_len;
  13038.   matchpath_type ndl_mp, hst_mp;
  13039.   boolean emptyline, res, ndl_cis, hst_cis;
  13040.   int na1, na2, na3, na4;       /* v0.3d */
  13041.   int ha1, ha2, ha3, ha4;       /* atom variables for E/Z check */
  13042.   int prev_ndl_b;
  13043.   int prev_hst_b;
  13044.   p_3d p1, p2, p3, p4;
  13045.   /*hst_torsion, ndl_torsion : double; */
  13046.   chirpath_type ncp, hcp;
  13047.   int n_hits, n_singlehits;
  13048. /* p2c: checkmol.pas, line 9433:
  13049.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13050.   /*$IFDEF debug */
  13051.   //char tmpstr[256];
  13052.  
  13053.   /*$ENDIF */
  13054.   /* initialize local matchpath variables */
  13055.   //memset (ndl_mp, 0, sizeof (matchpath_type));
  13056.   //memset (hst_mp, 0, sizeof (matchpath_type));
  13057.   /* copy content of external variables into local ones */
  13058.   memcpy (ndl_mp, ndl_xmp, sizeof (matchpath_type));
  13059.   memcpy (hst_mp, hst_xmp, sizeof (matchpath_type));
  13060.  
  13061.   /*for (i = 0; i < max_matchpath_length; i++)
  13062.      {
  13063.      ndl_mp[i] = ndl_xmp[i];
  13064.      hst_mp[i] = hst_xmp[i];
  13065.      } */
  13066.  
  13067.  
  13068.   ndl_mp_len = matchpath_length (ndl_mp);
  13069.   hst_mp_len = matchpath_length (hst_mp);
  13070.   if (ndl_mp_len != hst_mp_len)
  13071.     {
  13072.       /* this should never happen.... */
  13073. /* p2c: checkmol.pas, line 9451:
  13074.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13075.       /*$IFDEF debug */
  13076.       //debugoutput ("needle and haystack matchpaths are of different length");
  13077.       /*$ENDIF */
  13078.       return false;
  13079.     }
  13080.   ndl_a = ndl_mp[ndl_mp_len - 1];
  13081.   hst_a = hst_mp[hst_mp_len - 1];
  13082.   ndl_atom[ndl_a - 1].tag = false;
  13083.   /* new in v0.3o: mark the last needle atom as "visited" */
  13084.   if (ndl_mp_len > 1)
  13085.     {
  13086.       prev_ndl_a = ndl_mp[ndl_mp_len - 2];
  13087.       prev_hst_a = hst_mp[hst_mp_len - 2];
  13088.     }
  13089.   /* if geometry checking is on, check it here */
  13090.   if (ez_search == true && ndl_mp_len > 3)
  13091.     {
  13092.       na1 = ndl_mp[ndl_mp_len - 1];
  13093.       na2 = ndl_mp[ndl_mp_len - 2];
  13094.       na3 = ndl_mp[ndl_mp_len - 3];
  13095.       na4 = ndl_mp[ndl_mp_len - 4];
  13096.       ha1 = hst_mp[hst_mp_len - 1];
  13097.       ha2 = hst_mp[hst_mp_len - 2];
  13098.       ha3 = hst_mp[hst_mp_len - 3];
  13099.       ha4 = hst_mp[hst_mp_len - 4];
  13100.       prev_ndl_b = get_ndl_bond (na2, na3);
  13101.       prev_hst_b = get_bond (ha2, ha3);
  13102.       if (ndl_bond[prev_ndl_b - 1].btype == 'D' &&
  13103.           bond[prev_hst_b - 1].arom == false
  13104.           && (ndl_bond[prev_ndl_b - 1].stereo !=
  13105.               bstereo_double_either && bond[prev_hst_b - 1].stereo !=
  13106.               bstereo_double_either)
  13107.           /* 0.3x always match if needle and/or haystack bond is double_either */
  13108.           &&
  13109.           (!strcmp (atom[ha2 - 1].element, "C ")
  13110.            || !strcmp (atom[ha2 - 1].element, "N "))
  13111.           && (!strcmp (atom[ha3 - 1].element, "C ")
  13112.               || !strcmp (atom[ha3 - 1].element, "N ")))
  13113.         {                       /* v0.3g; check C=C, C=N, N=N bonds */
  13114.           p1.x = atom[ha1 - 1].x;
  13115.           p1.y = atom[ha1 - 1].y;
  13116.           p1.z = atom[ha1 - 1].z;
  13117.           p2.x = atom[ha2 - 1].x;
  13118.           p2.y = atom[ha2 - 1].y;
  13119.           p2.z = atom[ha2 - 1].z;
  13120.           p3.x = atom[ha3 - 1].x;
  13121.           p3.y = atom[ha3 - 1].y;
  13122.           p3.z = atom[ha3 - 1].z;
  13123.           p4.x = atom[ha4 - 1].x;
  13124.           p4.y = atom[ha4 - 1].y;
  13125.           p4.z = atom[ha4 - 1].z;
  13126.           hst_cis = is_cis (p1, p2, p3, p4);
  13127.           /*hst_torsion := torsion(p1,p2,p3,p4); */
  13128.           p1.x = ndl_atom[na1 - 1].x;
  13129.           p1.y = ndl_atom[na1 - 1].y;
  13130.           p1.z = ndl_atom[na1 - 1].z;
  13131.           p2.x = ndl_atom[na2 - 1].x;
  13132.           p2.y = ndl_atom[na2 - 1].y;
  13133.           p2.z = ndl_atom[na2 - 1].z;
  13134.           p3.x = ndl_atom[na3 - 1].x;
  13135.           p3.y = ndl_atom[na3 - 1].y;
  13136.           p3.z = ndl_atom[na3 - 1].z;
  13137.           p4.x = ndl_atom[na4 - 1].x;
  13138.           p4.y = ndl_atom[na4 - 1].y;
  13139.           p4.z = ndl_atom[na4 - 1].z;
  13140.           /*ndl_torsion := torsion(p1,p2,p3,p4); */
  13141.           ndl_cis = is_cis (p1, p2, p3, p4);
  13142.           if (ndl_cis != hst_cis)
  13143.             {
  13144. /* p2c: checkmol.pas, line 9501:
  13145.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13146.               /*$IFDEF debug */
  13147.               //debugoutput ("E/Z geometry mismatch");
  13148.               /*$ENDIF */
  13149.               return false;
  13150.             }
  13151.         }
  13152.     }                           /* end of E/Z geometry check */
  13153.   /* check whatever can be checked as early as now: */
  13154.   /* e.g. different elements or more substituents on needle atom than on haystack */
  13155.   if (!atomtypes_OK (ndl_a, hst_a))
  13156.     return false;
  13157.   /* positive scenarios, e.g. one-atom fragments  (v0.3o) */
  13158.   if (atom[hst_a - 1].neighbor_count == 0 &&
  13159.       ndl_atom[ndl_a - 1].neighbor_count == 0)
  13160.     {
  13161.       if (!atomtypes_OK (ndl_a, hst_a))
  13162.         return false;
  13163. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  13164.       atom[hst_a - 1].tag = true;
  13165.       return true;
  13166.     }
  13167.   /* and other possibilities: */
  13168.   ndl_b = get_ndl_bond (prev_ndl_a, ndl_a);
  13169.   hst_b = get_bond (prev_hst_a, hst_a);
  13170. /* p2c: checkmol.pas, line 9529:
  13171.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13172.   /*$IFDEF debug */
  13173.   /* debugoutput('Now checking atoms '+inttostr(ndl_a)+'/'+inttostr(hst_a)+', bonds '+inttostr(ndl_b)+'/'+inttostr(hst_b)); */
  13174.   /*$ENDIF */
  13175.   if (ndl_b > 0 && hst_b > 0)
  13176.     {
  13177.       /* do a quick check if bond types match */
  13178.       if (!bondtypes_OK (ndl_b, hst_b))
  13179.         {
  13180. /* p2c: checkmol.pas, line 9537:
  13181.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13182.           /*$IFDEF debug */
  13183.           /*
  13184.              debugoutput('  failed match of bonds '+inttostr(ndl_b)+'/'+inttostr(hst_b)); */
  13185.           /*$ENDIF */
  13186.           return false;
  13187.         }
  13188.     }
  13189.   /* a) we reached the end of our needle fragment (and atom/bond types match) */
  13190.   if ((ndl_atom[ndl_a - 1].neighbor_count == 1) && atomtypes_OK (ndl_a,
  13191.                                                                  hst_a) &&
  13192.       bondtypes_OK (ndl_b, hst_b))
  13193.     {
  13194.       return true;
  13195. /* p2c: checkmol.pas, line 9549:
  13196.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13197.       /*$IFDEF debug */
  13198.       /* debugoutput('  ==> end of needle fragment at atom '+inttostr(ndl_a)+' (match)'); */
  13199.       /*$ENDIF */
  13200.     }
  13201.   /* a.1) haystack fragment forms a ring, but needle does not;  v0.3m */
  13202.   if ((matchpath_pos (ndl_a, ndl_mp) == matchpath_length (ndl_mp)) &&
  13203.       (matchpath_pos (hst_a, hst_mp) < matchpath_length (hst_mp)))
  13204.     {
  13205.       return false;
  13206. /* p2c: checkmol.pas, line 9559:
  13207.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13208.       /*$IFDEF debug */
  13209.       /*
  13210.          debugoutput('  haystack forms a ring and needle does not at '+inttostr(hst_a));
  13211.          {$ENDIF */
  13212.     }
  13213.   /* b) a ring is formed (ndl_a is already in the path) and atom/bond types match */
  13214.   if ((matchpath_pos (ndl_a, ndl_mp) > 0) &&
  13215.       (matchpath_pos (ndl_a, ndl_mp) < matchpath_length (ndl_mp)))
  13216.     {
  13217.       if ((matchpath_pos (ndl_a, ndl_mp) == matchpath_pos (hst_a, hst_mp)) &&
  13218.           atomtypes_OK (ndl_a, hst_a) && bondtypes_OK (ndl_b, hst_b))
  13219.         {
  13220.           /* 1st chirality check */
  13221.           if (!((matchpath_pos (ndl_a, ndl_mp) > 1 && (rs_search ||
  13222.                                                        ndl_atom[ndl_a -
  13223.                                                                 1].
  13224.                                                        stereo_care)) &&
  13225.                 ndl_maybe_chiral (ndl_a)))
  13226.             {                   /* new in v0.3h */
  13227.               return true;
  13228.             }                   /* end of 1st chirality check */
  13229.           na1 = ndl_a;          /* the (potential) chiral center (v0.3f) */
  13230.           na2 = ndl_mp[matchpath_pos (ndl_a, ndl_mp) - 2];
  13231.           na3 = ndl_mp[matchpath_pos (ndl_a, ndl_mp)];
  13232.           na4 = ndl_mp[matchpath_length (ndl_mp) - 2];
  13233.           ha1 = hst_a;
  13234.           ha2 = hst_mp[matchpath_pos (hst_a, hst_mp) - 2];
  13235.           ha3 = hst_mp[matchpath_pos (hst_a, hst_mp)];
  13236.           ha4 = hst_mp[matchpath_length (hst_mp) - 2];
  13237.           memset (ncp, 0, sizeof (chirpath_type));
  13238.           memset (hcp, 0, sizeof (chirpath_type));
  13239.           ncp[0] = na1;
  13240.           ncp[1] = na2;
  13241.           ncp[2] = na3;
  13242.           ncp[3] = na4;
  13243.           hcp[0] = ha1;
  13244.           hcp[1] = ha2;
  13245.           hcp[2] = ha3;
  13246.           hcp[3] = ha4;
  13247.           if (!chirality_OK (ncp, hcp))
  13248.             {
  13249. /* p2c: checkmol.pas, line 9589:
  13250.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13251.               /*$IFDEF debug */
  13252.               //debugoutput ("chirality check failed at ring junction");
  13253.               /*$ENDIF */
  13254.               return false;
  13255.             }
  13256. /* p2c: checkmol.pas, line 9596:
  13257.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13258.           /*$IFDEF debug */
  13259.           //debugoutput ("chirality check succeeded at ring junction");
  13260.           /*$ENDIF */
  13261.           return true;
  13262. /* p2c: checkmol.pas, line 9602:
  13263.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13264.           /*$IFDEF debug */
  13265.           /* debugoutput('matchpath forms ring at: '+inttostr(ndl_a)+' (match)'); */
  13266.           /*$ENDIF */
  13267.         }
  13268.       else
  13269.         {
  13270.           return false;
  13271. /* p2c: checkmol.pas, line 9609:
  13272.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13273.           /*$IFDEF debug */
  13274.           /*
  13275.              debugoutput('matchpath forms ring at: '+inttostr(ndl_a)+' (no match)'); */
  13276.           /*$ENDIF */
  13277.         }
  13278.     }
  13279.   /* in all other cases, do the hard work: */
  13280.   /* first, get all heavy-atom neighbors of needle and haystack; */
  13281.   /* at the beginning of the search, this means all neighbors, then it means */
  13282.   /* all but the previous atom (where we came from) */
  13283.   memset (ndl_nb, 0, sizeof (neighbor_rec));
  13284.   memset (hst_nb, 0, sizeof (neighbor_rec));
  13285.  
  13286.   if (matchpath_length (ndl_mp) == 1)
  13287.     {
  13288.       ndl_n_nb = ndl_atom[ndl_a - 1].neighbor_count;
  13289.       n_nb = atom[hst_a - 1].neighbor_count;
  13290.       get_ndl_neighbors (ndl_nb, ndl_a);
  13291.       get_neighbors (hst_nb, hst_a);
  13292.     }
  13293.   else
  13294.     {
  13295.       ndl_n_nb = ndl_atom[ndl_a - 1].neighbor_count - 1;
  13296.       n_nb = atom[hst_a - 1].neighbor_count - 1;
  13297.       get_ndl_nextneighbors (ndl_nb, ndl_a, prev_ndl_a);
  13298.       get_nextneighbors (hst_nb, hst_a, prev_hst_a);
  13299.     }
  13300.   /* v0.3o: mark all neighbor atoms as "visited" */
  13301.   for (i = 0; i < ndl_n_nb; i++)
  13302.     ndl_atom[ndl_nb[i] - 1].tag = false;
  13303.   /* now that the neighbor-arrays are filled, get all */
  13304.   /* combinations of matches recursively; */
  13305.   /* first, initialize the match matrix */
  13306.   memset (mm, false, sizeof (matchmatrix));     /* new in v0.2i */
  13307.   /* make sure there are not too many neighbors (max. max_neighbors)   */
  13308.   if (ndl_n_nb > max_neighbors || n_nb > max_neighbors)
  13309.     {                           /* updated in v0.2i */
  13310. /* p2c: checkmol.pas, line 9644:
  13311.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13312.       /*$IFDEF debug */
  13313.       //debugoutput ("too many neighbors - exiting");
  13314.       /*$ENDIF */
  13315.       return false;
  13316.     }
  13317.   /* check if matchpath is not already filled up */
  13318.   if (matchpath_length (ndl_mp) == max_matchpath_length)
  13319.     {
  13320. /* p2c: checkmol.pas, line 9653:
  13321.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13322.       /*$IFDEF debug */
  13323.       //debugoutput ("matchpath too int - exiting");
  13324.       /*$ENDIF */
  13325.       return false;
  13326.     }
  13327.   /* next, check which chain of the needle matches which chain of the haystack  */
  13328.   for (i = 0; i < ndl_n_nb; i++)
  13329.     {
  13330.       emptyline = true;
  13331.       next_ndl_a = ndl_nb[i];
  13332.       for (j = 0; j < n_nb; j++)
  13333.         {
  13334.           next_hst_a = hst_nb[j];
  13335.           ndl_mp[ndl_mp_len] = next_ndl_a;
  13336.           hst_mp[hst_mp_len] = next_hst_a;
  13337.           if (is_matching (ndl_mp, hst_mp))
  13338.             {                   /* recursive function call */
  13339.  
  13340.               if (max_match_recursion_depth != 0
  13341.                   && ++recursion_depth > max_match_recursion_depth)
  13342.                 {
  13343. #ifndef MAKE_SHARED_LIBRARY
  13344.                   if (opt_verbose)
  13345. #endif
  13346.                     printf
  13347.                       ("Warning: max. number of match recursions (%i) reached, reverting to non-exhaustive match\n",
  13348.                        max_match_recursion_depth);
  13349.                   //n_rings = max_rings;
  13350.                   return true;
  13351.                 }
  13352.  
  13353.               mm[i][j] = true;
  13354.               emptyline = false;
  13355.             }
  13356.         }
  13357.       /* if a needle substituent does not match any of the haystack substituents, */
  13358.       /* stop any further work immediately */
  13359.       if (emptyline)
  13360.         return false;
  13361.     }
  13362.   /* finally, check the content of the matrix */
  13363.   res = matrix_OK (mm, ndl_n_nb, n_nb);
  13364.   /* optional: chirality check */
  13365.   if (!((res && (rs_search || ndl_atom[ndl_a - 1].stereo_care)) &&
  13366.         ndl_maybe_chiral (ndl_a)))
  13367.     return res;
  13368.   /* first, we have to clean up the match matrix in order to remove */
  13369.   /* "impossible" multiple matches (new in v0.3h) */
  13370.   for (i = 1; i <= 3; i++)
  13371.     {
  13372.       for (j = 1; j <= max_neighbors; j++)
  13373.         {                       /* haystack dimension */
  13374.           n_hits = 0;
  13375.           l = 0;
  13376.           for (k = 1; k <= max_neighbors; k++)
  13377.             {                   /* needle dimension */
  13378.               if (mm[k - 1][j - 1])
  13379.                 {
  13380.                   n_hits++;
  13381.                   l = k;
  13382.                 }
  13383.             }
  13384.           if (n_hits == 1)
  13385.             {                   /* a unique match ==> kick out any other match at this pos. */
  13386.               for (m = 1; m <= max_neighbors; m++)
  13387.                 {
  13388.                   if (m != j)
  13389.                     mm[l - 1][m - 1] = false;
  13390.                 }
  13391.             }
  13392.         }
  13393.     }
  13394.   /* end of match matrix clean-up */
  13395.   if (prev_ndl_a > 0)
  13396.     {
  13397.       n_singlehits = 1;
  13398.       ncp[1] = prev_ndl_a;
  13399.       hcp[1] = prev_hst_a;
  13400.     }
  13401.   else
  13402.     n_singlehits = 0;
  13403.   ncp[0] = ndl_a;
  13404.   hcp[0] = hst_a;
  13405.   i = 0;
  13406.   l = 0;
  13407.   while (n_singlehits < 3 && i < 4)
  13408.     {
  13409.       i++;
  13410.       n_hits = 0;
  13411.       for (k = 1; k <= n_nb; k++)
  13412.         {
  13413.           if (mm[i - 1][k - 1])
  13414.             {
  13415.               n_hits++;
  13416.               l = k;
  13417.             }
  13418.         }
  13419.       if (n_hits == 1)
  13420.         {
  13421.           n_singlehits++;
  13422.           ncp[n_singlehits] = ndl_nb[i - 1];
  13423.           hcp[n_singlehits] = hst_nb[l - 1];
  13424.         }
  13425.     }
  13426.   if (n_singlehits != 3)
  13427.     return res;
  13428.   if (!chirality_OK (ncp, hcp))
  13429.     {
  13430. /* p2c: checkmol.pas, line 9749:
  13431.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13432.       /*$IFDEF debug */
  13433.       //debugoutput ("chirality check failed");
  13434.       /*$ENDIF */
  13435.       res = false;
  13436.     }
  13437.   else
  13438.     {
  13439. /* p2c: checkmol.pas, line 9755:
  13440.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13441.       /*$IFDEF debug */
  13442.       //debugoutput ("chirality check OK");
  13443.       /*$ENDIF */
  13444.     }
  13445.   return res;
  13446. /* p2c: checkmol.pas, line 9762:
  13447.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13448.   /*$IFDEF debug */
  13449.   /* if res then tmpstr := ' MATCH' else tmpstr := ' NO MATCH';
  13450.      debugoutput('result for atoms '+inttostr(ndl_a)+'/'+inttostr(hst_a)+', bonds '+inttostr(ndl_b)+'/'+inttostr(hst_b)+':'+tmpstr); */
  13451.   /*$ENDIF */
  13452. }
  13453.  
  13454.  
  13455. static boolean
  13456. quick_match ()
  13457. {
  13458.   /* added in v0.2c */
  13459.   int i;
  13460.   boolean res = true;
  13461.  /* str3 ndl_atype;*/
  13462.   str2 ndl_el;                  /* v0.3l */
  13463.   int ndl_chg = 0;              /* v0.3l */
  13464.   int ndl_rad = 0;              /* v0.3x */
  13465.   int ndl_iso = 0;              /* v0.3x */
  13466.  
  13467.  
  13468.   if ((ez_search || rs_search) && ndl_n_heavyatoms > 3)
  13469.     /* v0.3f, v0.3m, v0.3o */
  13470.     return false;
  13471.   if (ndl_n_atoms < 1 || n_atoms < 1 || ndl_n_atoms > n_atoms ||
  13472.       ndl_n_bonds > n_bonds)
  13473.     {                           /* just to be sure... */
  13474. /* p2c: checkmol.pas, line 9786:
  13475.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13476.       /*$IFDEF debug */
  13477. /* p2c: checkmol.pas: Note: Eliminated unused assignment statement [338] */
  13478.       //debugoutput (" ==> quick_match failed");
  13479.       /*$ENDIF */
  13480.       return false;
  13481.     }
  13482.  
  13483.   if (ndl_n_heavyatoms > 1)
  13484.     {
  13485.       for (i = 0; i < ndl_n_atoms; i++)
  13486.         {
  13487.           /*if atom^[i].atype <> ndl_atom^[i].atype then res := false;    (* changed in */
  13488.           if (strcmp (atom[i].element, ndl_atom[i].element))    /* v0.2k */
  13489.             return false;
  13490.           //  if (atom[i].formal_charge != ndl_atom[i].formal_charge) /* v0.3o */
  13491.           //res = false;
  13492.  
  13493.  
  13494.           if (opt_chg)
  13495.             {
  13496.               if (ndl_atom[i].formal_charge != atom[i].formal_charge)
  13497.                 return false;
  13498.             }
  13499. /*  else
  13500.     {
  13501.       if (ndl_atom[i].formal_charge != 0 &&
  13502.           atom[i].formal_charge != 0 &&
  13503.           ndl_atom[i].formal_charge != atom[i].formal_charge)
  13504.         return false;
  13505.     } */
  13506.  
  13507.           /* v0.3x: isotopes must be the same */
  13508.           if (opt_iso)
  13509.             {
  13510.               if (ndl_atom[i].nucleon_number != atom[i].nucleon_number)
  13511.                 return false;
  13512.             }
  13513. /*  else
  13514.     {
  13515.       if (ndl_atom[i].nucleon_number != 0 &&
  13516.           atom[i].nucleon_number != 0 &&
  13517.           ndl_atom[i].nucleon_number !=
  13518.           atom[i].nucleon_number)
  13519.         return false;
  13520.     }*/
  13521.  
  13522.           /* v0.3x: radicals must be the same */
  13523.           if (opt_rad)
  13524.             {
  13525.               if (ndl_atom[i].radical_type != atom[i].radical_type)
  13526.                 return false;
  13527.             }
  13528. /*  else
  13529.     {
  13530.       if (ndl_atom[i].radical_type != 0 &&
  13531.           atom[i].radical_type != 0 &&
  13532.           ndl_atom[i].radical_type != atom[i].radical_type)
  13533.         return false;
  13534.     }*/
  13535.  
  13536.         }
  13537. /* p2c: checkmol.pas, line 9798:
  13538.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13539.       /*$IFDEF debug */
  13540.       //if (res)
  13541.       //debugoutput (" ==> quick_match: atoms OK");
  13542.       //else
  13543.       //  debugoutput (" ==> quick_match: atoms not OK");
  13544.       /*$ENDIF */
  13545.       if (ndl_n_bonds > 0)
  13546.         {
  13547.  
  13548.           for (i = 0; i < ndl_n_bonds; i++)
  13549.             {
  13550.               if (ndl_bond[i].a1 != bond[i].a1 || ndl_bond[i].a2 != bond[i].a2
  13551.                   || ndl_bond[i].btype != bond[i].btype)
  13552.                 return false;
  13553.             }
  13554.         }
  13555. /* p2c: checkmol.pas, line 9810:
  13556.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13557.       /*$IFDEF debug */
  13558.       //if (res)
  13559.       //  debugoutput (" ==> quick_match: bonds OK");
  13560.       //else
  13561.       //  debugoutput (" ==> quick_match: bonds not OK");
  13562.       /*$ENDIF */
  13563.       /* added in v0.2d: special case: needle contains only one heavy atom; refined in v0.3l, v0.3o */
  13564.     }
  13565.   else
  13566.     {
  13567.  
  13568.       /* first, find out the element and atom type of the only heavy atom       */
  13569.       for (i = 0; i < ndl_n_atoms; i++)
  13570.         {
  13571.           if (ndl_atom[i].heavy)
  13572.             {
  13573.               //strcpy (ndl_atype, ndl_atom[i].atype);
  13574.               strcpy (ndl_el, ndl_atom[i].element);     /* v0.3l */
  13575.               ndl_chg = ndl_atom[i].formal_charge;      /* v0.3l */
  13576.               ndl_iso = ndl_atom[i].nucleon_number;     /* 0.3x */
  13577.               ndl_rad = ndl_atom[i].radical_type;       /* 0.3x */
  13578.             }
  13579.         }
  13580.  
  13581.       for (i = 0; i < n_atoms; i++)
  13582.         {                       /* v0.3l, v0.3o */
  13583.           if (          //      !strcmp (atom[i].atype, ndl_atype) &&
  13584.                !strcmp (atom[i].element, ndl_el))
  13585.             {
  13586.            
  13587.  
  13588.               if (opt_chg || opt_strict)
  13589.                 {
  13590.                   if (ndl_chg != atom[i].formal_charge)
  13591.                     return false;
  13592.                 }
  13593.  
  13594.  
  13595.               if (opt_iso || opt_strict)
  13596.                 {
  13597.                   if (ndl_iso != atom[i].nucleon_number)
  13598.                     return false;
  13599.                 }
  13600.  
  13601.  
  13602.  
  13603.               if (opt_rad || opt_strict)
  13604.                 {
  13605.                   if (ndl_rad != atom[i].radical_type)
  13606.                     return false;
  13607.                 }
  13608.                   return true;
  13609.             } else {
  13610.                 res=false;
  13611.             }    
  13612.         }
  13613.     }
  13614. /* p2c: checkmol.pas, line 9828:
  13615.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13616.   /*$IFDEF debug */
  13617.   //if (res)
  13618.   //  debugoutput (" ==> quick_match succeeded");
  13619.   //else
  13620.   //  debugoutput (" ==> quick_match failed (2)");
  13621.   /*$ENDIF */
  13622.   return res;
  13623. }
  13624.  
  13625. static void
  13626. perform_match ()
  13627. {
  13628.   int i = 0;
  13629.   int j;
  13630.   /*ndl_ref_atom : integer;  (* since v0.3j as a global variable */
  13631.   int ndl_n_nb, ndl_n_hc, n_nb, n_hc;
  13632.   boolean qm;                   /* v0.3l */
  13633.   /* check for NoStruct (0 atoms);  v0.3l */
  13634.   if (n_atoms == 0 || ndl_n_atoms == 0)
  13635.     {
  13636.       matchresult = false;
  13637. /* p2c: checkmol.pas, line 9849:
  13638.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13639.       /*$IFDEF debug */
  13640.       //debugoutput ("NoStruct encountered - aborted match routine");
  13641.       /*$ENDIF */
  13642.       return;
  13643.     }
  13644.   /* if we perform an exact match, needle and haystack must have */
  13645.   /* the same number of atoms, bonds, and rings */
  13646.   if (opt_exact && opt_iso)     /* 0.3x */
  13647.     {
  13648.       if (n_heavyatoms != ndl_n_heavyatoms
  13649.           || n_heavybonds != ndl_n_heavybonds)
  13650.         {
  13651.           matchresult = false;
  13652. /* p2c: checkmol.pas, line 9861:
  13653.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13654.           /*$IFDEF debug */
  13655.           //debugoutput ("different number of heavy atoms and/or bonds");
  13656.           /*$ENDIF */
  13657.           //return;
  13658.         }
  13659.     }
  13660.  
  13661.   /* have a quick look if needle and haystack are identical molfiles */
  13662.   qm = quick_match ();          /* v0.3l */
  13663.   if (qm)
  13664.     {
  13665.       matchresult = true;
  13666.       clear_ndl_atom_tags ();   /* v0.3o */
  13667.       return;
  13668.     }
  13669.   /* if we have only one heavy atom and quick_match fails, return "false";  v0.3l */
  13670.   if (ndl_n_heavyatoms == 1)
  13671.     {
  13672.       matchresult = false;
  13673.       return;
  13674.     }
  13675. /* p2c: checkmol.pas, line 9881:
  13676.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13677.   /*$IFDEF debug */
  13678.   /* debugoutput('needle reference atom: '+inttostr(ndl_ref_atom)+' ('+ndl_atom^[ndl_ref_atom].atype+')'); */
  13679.   /*$ENDIF */
  13680.   ndl_n_nb = ndl_atom[ndl_ref_atom - 1].neighbor_count;
  13681.   ndl_n_hc = ndl_hetatom_count (ndl_ref_atom);
  13682. /* p2c: checkmol.pas, line 9886:
  13683.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13684.   /*$IFDEF debug */
  13685.   /* debugoutput('neighbor atoms: '+inttostr(ndl_n_nb)+'  heteroatom neighbors: '+inttostr(ndl_n_hc)); */
  13686.   /*$ENDIF */
  13687.   matchresult = false;
  13688.   for (j = 0; j < max_matchpath_length; j++)
  13689.     {
  13690.       ndl_matchpath[j] = 0;
  13691.       hst_matchpath[j] = 0;
  13692.     }
  13693.   ndl_matchpath[0] = ndl_ref_atom;
  13694.   while (i < n_atoms && matchresult == false)
  13695.     {
  13696.       i++;
  13697.       n_nb = atom[i - 1].neighbor_count;
  13698.       n_hc = hetatom_count (i);
  13699.       if (n_nb >= ndl_n_nb && n_hc >= ndl_n_hc)
  13700.         {
  13701. /* p2c: checkmol.pas, line 9904:
  13702.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13703.           /*$IFDEF debug */
  13704.           /* debugoutput('trying atom '+inttostr(i)+'; neighbor atoms: '+inttostr(n_nb)+' heteroatom neighbors: '+inttostr(n_hc)); */
  13705.           /*$ENDIF */
  13706.  
  13707.           recursion_depth = 0;
  13708.           hst_matchpath[0] = i;
  13709.           matchresult = is_matching (ndl_matchpath, hst_matchpath);
  13710. /* p2c: checkmol.pas, line 9909:
  13711.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13712.           /*$IFDEF debug */
  13713.           /* if matchresult then debugoutput('matching atom in haystack: '+inttostr(i)+' ('+atom^[i].atype+')'); */
  13714.           /*$ENDIF */
  13715.           if (matchresult)      /* v0.3o; mark this fragment as matched */
  13716.             atom[i - 1].tag = true;
  13717.         }
  13718.     }
  13719. }
  13720.  
  13721.  
  13722. static void
  13723. clear_rings ()
  13724. {
  13725.   int i, FORLIM;
  13726.   n_rings = 0;
  13727.   memset (ring, 0, sizeof (ringlist));
  13728.   for (i = 0; i < max_rings; i++)
  13729.     {                           /* new in v0.3 */
  13730.       ringprop[i].size = 0;
  13731.       ringprop[i].arom = false;
  13732.       ringprop[i].envelope = false;
  13733.     }
  13734.   if (n_atoms > 0)
  13735.     {
  13736.       FORLIM = n_atoms;
  13737.       for (i = 0; i < FORLIM; i++)
  13738.         atom[i].ring_count = 0;
  13739.     }
  13740.   if (n_bonds > 0)
  13741.     {
  13742.       FORLIM = n_bonds;
  13743.       for (i = 0; i < FORLIM; i++)
  13744.         bond[i].ring_count = 0;
  13745.     }
  13746. }
  13747.  
  13748.  
  13749. static int
  13750. ring_lastpos (s)
  13751.      int *s;
  13752. {
  13753.   int i, rc;
  13754.   int rlp = 0;
  13755.   int FORLIM;
  13756.   if (n_rings <= 0)
  13757.     return rlp;
  13758.   FORLIM = n_rings;
  13759.   for (i = 1; i <= FORLIM; i++)
  13760.     {
  13761.       rc = ringcompare (s, ring[i - 1]);
  13762.       if (rc_identical (rc))
  13763.         rlp = i;
  13764.     }
  13765.   return rlp;
  13766. }
  13767.  
  13768.  
  13769. static void
  13770. remove_redundant_rings ()
  13771. {
  13772.   int i, j, k, rlp;
  13773.   ringpath_type tmp_path;
  13774.   int FORLIM, FORLIM1;
  13775.   if (n_rings < 2)
  13776.     return;
  13777.   FORLIM = n_rings;
  13778.   for (i = 1; i < FORLIM; i++)
  13779.     {
  13780.       memcpy (tmp_path, ring[i - 1], sizeof (ringpath_type));
  13781.       rlp = ring_lastpos (tmp_path);
  13782.       while (rlp > i)
  13783.         {
  13784.           FORLIM1 = n_rings;
  13785. /* p2c: checkmol.pas, line 9970:
  13786.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  13787.           /*$IFDEF debug */
  13788.           /* debugoutput('removing redundant ring: '+inttostr(rlp)+' (identical to ring '+inttostr(i)+')'); */
  13789.           /*$ENDIF */
  13790.           for (j = rlp; j < FORLIM1; j++)
  13791.             {
  13792.               memcpy (ring[j - 1], ring[j], sizeof (ringpath_type));
  13793.               ringprop[j - 1].size = ringprop[j].size;  /* new in v0.3 */
  13794.               ringprop[j - 1].arom = ringprop[j].arom;
  13795.               ringprop[j - 1].envelope = ringprop[j].envelope;
  13796.             }
  13797.           for (k = 0; k < max_ringsize; k++)
  13798.             ring[n_rings - 1][k] = 0;
  13799.           n_rings--;
  13800.           rlp = ring_lastpos (tmp_path);
  13801.         }
  13802.     }
  13803. }
  13804.  
  13805.  
  13806. static int
  13807. count_aromatic_rings ()
  13808. {
  13809.   int i;
  13810.   int n = 0;
  13811.   int FORLIM;
  13812.   if (n_rings <= 0)
  13813.     return n;
  13814.   FORLIM = n_rings;
  13815.   for (i = 0; i < FORLIM; i++)
  13816.     {
  13817.       if (ringprop[i].arom)
  13818.         n++;
  13819.     }
  13820.   return n;
  13821. }
  13822.  
  13823.  
  13824. static void
  13825. chk_envelopes ()
  13826. {
  13827.   /* new in v0.3d */
  13828.   /* checks if a ring completely contains one or more other rings */
  13829.   int a, i, j, k, l, pl, pli;
  13830.   boolean found_atom, found_all_atoms, found_ring;
  13831.   int FORLIM;
  13832.   if (n_rings < 2)
  13833.     return;
  13834.   FORLIM = n_rings;
  13835.   for (i = 1; i < FORLIM; i++)
  13836.     {
  13837.       found_ring = false;
  13838.       j = 0;
  13839.       pli = ringprop[i].size;   /* path_length(ring^[i]); */
  13840.       while (j < i && found_ring == false)
  13841.         {
  13842.           j++;
  13843.           found_all_atoms = true;
  13844.           pl = ringprop[j - 1].size;    /* path_length(ring^[j]); */
  13845.           for (k = 0; k < pl; k++)
  13846.             {
  13847.               found_atom = false;
  13848.               a = ring[j - 1][k];
  13849.               for (l = 0; l < pli; l++)
  13850.                 {
  13851.                   if (ring[i][l] == a)
  13852.                     found_atom = true;
  13853.                 }
  13854.               if (found_atom == false)
  13855.                 found_all_atoms = false;
  13856.             }
  13857.           if (found_all_atoms)
  13858.             found_ring = true;
  13859.         }
  13860.       if (found_ring)
  13861.         ringprop[i].envelope = true;
  13862.     }
  13863. }
  13864.  
  13865.  
  13866. static void
  13867. update_ringcount ()
  13868. {
  13869.   int i, j, a1, a2, b, pl, FORLIM;
  13870.   if (n_rings <= 0)
  13871.     return;
  13872.   chk_envelopes ();
  13873.   FORLIM = n_rings;
  13874.   for (i = 0; i < FORLIM; i++)
  13875.     {
  13876.       if (ringprop[i].envelope == false)
  13877.         {
  13878.           pl = ringprop[i].size;        /* path_length(ring^[i]);  (* v0.3d */
  13879.           a2 = ring[i][pl - 1];
  13880.           for (j = 0; j < pl; j++)
  13881.             {
  13882.               a1 = ring[i][j];
  13883.               atom[a1 - 1].ring_count++;
  13884.               b = get_bond (a1, a2);
  13885.               bond[b - 1].ring_count++;
  13886.               a2 = a1;
  13887.             }
  13888.         }
  13889.     }
  13890. }
  13891.  
  13892.  
  13893. static boolean
  13894. normalize_ionic_bonds ()
  13895. {
  13896.   /* v0.3k */
  13897.   /* changed from a procedure into a function in v0.3m */
  13898.   int i, a1, a2, fc1, fc2;
  13899.   char bt;
  13900.   boolean res = false;          /* v0.3m */
  13901.   int FORLIM;
  13902.   /* v0.3m */
  13903.   if (n_bonds == 0)
  13904.     return false;
  13905.   FORLIM = n_bonds;
  13906.   for (i = 0; i < FORLIM; i++)
  13907.     {
  13908.       a1 = bond[i].a1;
  13909.       a2 = bond[i].a2;
  13910.       bt = bond[i].btype;
  13911.       fc1 = atom[a1 - 1].formal_charge;
  13912.       fc2 = atom[a2 - 1].formal_charge;
  13913.       if (fc1 * fc2 == -1 && (bt == 'S' || bt == 'D'))
  13914.         {
  13915.           atom[a1 - 1].formal_charge = 0;
  13916.           atom[a2 - 1].formal_charge = 0;
  13917.           if (!strcmp (atom[a1 - 1].atype, "N3+"))      /* v0.3m */
  13918.             strcpy (atom[a1 - 1].atype, "N3 ");
  13919.           if (!strcmp (atom[a2 - 1].atype, "N3+"))      /* v0.3m */
  13920.             strcpy (atom[a2 - 1].atype, "N3 ");
  13921.           if (bt == 'D')
  13922.             bond[i].btype = 'T';
  13923.           if (bt == 'S')
  13924.             bond[i].btype = 'D';
  13925.           res = true;           /* v0.3m */
  13926.         }
  13927.     }
  13928.   return res;                   /* v0.3m (return true if any change was made */
  13929. }
  13930.  
  13931. #if 0
  13932. static void
  13933. chk_wildcard_rings ()           // new in v0.3p
  13934. // checks if there are any wildcard atom types or bond types
  13935. // in a ring of the needle; if yes ==> set the q_arom flag in the
  13936. // atom and bond record of all ring members in order to perform the
  13937. // match a bit more generously
  13938. {
  13939.  
  13940.   int i, j, rs;
  13941.   int a1, a2, b;
  13942.   boolean wcr;
  13943.   str3 at;
  13944.   char bt;
  13945.  
  13946.   if (ndl_querymol == false)
  13947.     return;
  13948.   if (ndl_n_rings == 0)
  13949.     return;
  13950.   // now look for any not-yet-aromatic rings which contain a wildcard
  13951.   for (i = 0; i < ndl_n_rings; i++)
  13952.     {
  13953.       wcr = false;
  13954.       if (ndl_ringprop[i].arom == false)
  13955.         {
  13956.           rs = ndl_ringprop[i].size;
  13957.           a2 = ndl_ring[i][rs];
  13958.           for (j = 0; j < rs; j++)
  13959.             {
  13960.               a1 = ndl_ring[i][j];
  13961.               b = get_ndl_bond (a1, a2);
  13962.               strcpy (at, ndl_atom[a1].atype);
  13963.               bt = ndl_bond[b].btype;
  13964.               if (!strcmp (at, "A  ") || !strcmp (at, "Q  "))
  13965.                 wcr = true;
  13966.               if (bt == 'l' || bt == 's' || bt == 'd' || bt == 'a')
  13967.                 wcr = true;
  13968.               a2 = a1;
  13969.             }
  13970.           if (wcr)
  13971.             {                   // if yes, flag all atoms and bonds in this ring as "potentially" aromatic
  13972.               // {$IFDEF debug}
  13973.               // debugoutput('wildcard ring found');
  13974.               // {$ENDIF}
  13975.               a2 = ndl_ring[i][rs];
  13976.               for (j = 0; j < rs; j++)
  13977.                 {
  13978.                   a1 = ndl_ring[i][j];
  13979.                   b = get_ndl_bond (a1, a2);
  13980.                   strcpy (at, ndl_atom[a1].atype);
  13981.                   bt = ndl_bond[b].btype;
  13982.                   ndl_atom[a1].q_arom = true;
  13983.                   ndl_bond[b].q_arom = true;
  13984.                   a2 = a1;
  13985.                 }
  13986.             }
  13987.         }
  13988.     }
  13989.   // and now undo this flagging for all rings which contain no wildcard
  13990.   for (i = 0; i < ndl_n_rings; i++)
  13991.     {
  13992.       wcr = false;
  13993.       rs = ndl_ringprop[i].size;
  13994.       a2 = ndl_ring[i][rs];
  13995.       for (j = 0; j < rs; j++)
  13996.         {
  13997.           a1 = ndl_ring[i][j];
  13998.           b = get_ndl_bond (a1, a2);
  13999.           strcpy (at, ndl_atom[a1].atype);
  14000.           bt = ndl_bond[b].btype;
  14001.           if (!strcmp (at, "A  ") || !strcmp (at, "Q  "))
  14002.             wcr = true;
  14003.           if (bt == 'l' || bt == 's' || bt == 'd' || bt == 'a')
  14004.             wcr = true;
  14005.           a2 = a1;
  14006.         }
  14007.       if (!wcr)
  14008.         {                       // if yes, unflag all atoms and bonds in this ring
  14009.           a2 = ndl_ring[i][rs];
  14010.           for (j = 0; j < rs; j++)
  14011.             {
  14012.               a1 = ndl_ring[i][j];
  14013.               b = get_ndl_bond (a1, a2);
  14014.               strcpy (at, ndl_atom[a1].atype);
  14015.               bt = ndl_bond[b].btype;
  14016.               ndl_atom[a1].q_arom = false;
  14017.               ndl_bond[b].q_arom = false;
  14018.               a2 = a1;
  14019.             }
  14020.         }
  14021.     }
  14022.   // some further refinement would be necessary here in order to unflag everything
  14023.   // which contains a wildcard but which definitely cannot be aromatic
  14024. }
  14025. #endif
  14026.  
  14027. #ifndef MAKE_SHARED_LIBRARY
  14028.  
  14029. int
  14030. main (int argc, char *argv[])
  14031. {                               /* main routine */
  14032.   char STR1[256], STR6[256];
  14033.   int FORLIM;
  14034.   /* progmode = pmMatchMol */
  14035.   rfile = NULL;
  14036.   strcpy (progname, argv[0]);
  14037.   strncpy (STR1, progname, 253);
  14038.   if (strstr (STR1, "matchmol") != NULL)
  14039.     progmode = pmMatchMol;
  14040.   else
  14041.     {
  14042.       strncpy (STR6, progname, 253);
  14043.       if (strstr (STR6, "checkmol") == NULL)
  14044.         {
  14045.           printf ("THOU SHALLST NOT RENAME ME!\n");
  14046.           exit (9);
  14047.         }
  14048.       progmode = pmCheckMol;
  14049.     }
  14050.   if (argc == 1)
  14051.     {
  14052.       show_usage ();
  14053.       exit (1);
  14054.     }
  14055.   init_globals ();
  14056.   init_molstat (&molstat);
  14057.   parse_args (argc, argv);
  14058.   if (ringsearch_mode == rs_sar)
  14059.     max_vringsize = max_ringsize;
  14060.   else
  14061.     max_vringsize = ssr_vringsize;
  14062.   /* v0.3n (was: 10) */
  14063.   /*if opt_verbose then writeln(progname+' v',version,'  N. Haider 2003-2007'); */
  14064.   if (progmode == pmMatchMol)
  14065.     {
  14066.       left_trim (ndl_molfilename);
  14067.       left_trim (molfilename);
  14068.       if ((*molfilename == '\0' || *ndl_molfilename == '\0'
  14069.            || argc < 3) && !opt_stdin)
  14070.         {
  14071.  
  14072.           show_usage ();
  14073.           exit (2);             /* new in v0.2k */
  14074.         }
  14075.       if (!(file_exists (ndl_molfilename)) && !opt_stdin)
  14076.         {                       /*not  fileexists(ndl_molfilename) REPLACE!!! */
  14077.                                    printf("2");
  14078.                                    /* p2c: checkmol.pas, line 10128:
  14079.                                    * Warning: Expected an expression, found a ')' [227] */
  14080.           if (strlen (ndl_molfilename) > 1 && ndl_molfilename[0] == '-')
  14081.             show_usage ();
  14082.           else
  14083.             printf ("file %s not found!\n", ndl_molfilename);
  14084.           /* new in v0.2k */
  14085.           exit (2);
  14086.         }
  14087.     }
  14088.  
  14089.   if (!(file_exists (molfilename)) && !opt_stdin)
  14090.     {                           /*not  fileexists(ndl_molfilename) REPLACE!!! */
  14091. /* p2c: checkmol.pas, line 10128:
  14092.  * Warning: Expected an expression, found a ')' [227] */
  14093.  
  14094.       if (strlen (molfilename) > 1 && molfilename[0] == '-')
  14095.         show_usage ();
  14096.       else
  14097.         printf ("file %s not found!\n", molfilename);
  14098.       /* new in v0.2k */
  14099.       exit (2);
  14100.     }
  14101.  
  14102.   /* read the first molecule and process it; if we are in "matchmol" mode, */
  14103.   /* this is the "needle" */
  14104.   if (progmode == pmMatchMol)
  14105.     readinputfile (ndl_molfilename);
  14106.   else
  14107.     readinputfile (molfilename);
  14108.   li = 1;                       /* initialize line pointer for input buffer */
  14109.   get_filetype (filetype, ndl_molfilename);
  14110.   if (!strcmp (filetype, "unknown"))
  14111.     {
  14112.       printf ("unknown query file format!\n");
  14113.       if (!opt_verbose)
  14114.         exit (3);
  14115.       printf ("===========================================\n");
  14116.       FORLIM = molbufindex;
  14117.       for (i = 1; i <= FORLIM; i++)
  14118.         puts (molbuf[i - 1]);
  14119.       exit (3);
  14120.     }
  14121.   mol_OK = true;                /* added in v0.2i */
  14122.   if (!strcmp (filetype, "alchemy"))
  14123.     read_molfile (ndl_molfilename);
  14124.   if (!strcmp (filetype, "sybyl"))
  14125.     read_mol2file (ndl_molfilename);
  14126.   if (!strcmp (filetype, "mdl"))
  14127.     read_MDLmolfile (ndl_molfilename);
  14128.   count_neighbors ();
  14129.   if (!mol_OK || n_atoms < 1)
  14130.     {                           /* v0.3g; check if this is a valid query structure */
  14131.       printf ("invalid molecule\n");
  14132.       exit (3);
  14133.     }
  14134.   if (!found_arominfo || progmode == pmCheckMol)
  14135.     {                           /* added in v0.2b/0.2c */
  14136. /* p2c: checkmol.pas, line 10172:
  14137.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  14138.       /*$IFDEF debug
  14139.          if (!found_arominfo)
  14140.          debugoutput
  14141.          ("no aromaticity information found - checking myself...");
  14142.          else
  14143.          debugoutput ("performing full aromaticity check");
  14144.          // new in v0.3d
  14145.       $ENDIF */
  14146.       chk_ringbonds ();
  14147.       if (ringsearch_mode == rs_ssr)
  14148.         remove_redundant_rings ();
  14149.       if (n_rings >= max_rings)
  14150.         {
  14151.           if (opt_verbose)
  14152.             printf
  14153.               ("Warning: max. number of rings (%i) reached, reverting to SSR search\n",
  14154.                max_rings);
  14155.           ringsearch_mode = rs_ssr;
  14156.           auto_ssr = true;      /* v0.3n */
  14157.           clear_rings ();
  14158.           max_vringsize = ssr_vringsize;        /* v0.3n (was: 10) */
  14159.           chk_ringbonds ();
  14160.           remove_redundant_rings ();
  14161.         }
  14162.       update_ringcount ();
  14163.       /* new in v0.3k: if output is a molfile, leave the original */
  14164.       /* representation of N-oxides, S-oxides, nitro groups, etc. */
  14165.       /* unchanged (ionic or non-ionic), in any other case make covalent bonds */
  14166.       if (!opt_xmdlout)         /* v0.3k */
  14167.         normalize_ionic_bonds ();
  14168.       update_atypes ();
  14169.       update_Htotal ();         /* added in v0.3 */
  14170.       chk_arom ();
  14171.       if (ringsearch_mode == rs_ssr)
  14172.         {                       /* new in v0.3 */
  14173.           do
  14174.             {
  14175.               prev_n_ar = count_aromatic_rings ();
  14176.               chk_arom ();
  14177.               n_ar = count_aromatic_rings ();
  14178.             }
  14179.           while (prev_n_ar - n_ar != 0);
  14180.         }
  14181.     }
  14182.   else
  14183.     {                           /* v0.3k */
  14184. /* p2c: checkmol.pas, line 10206:
  14185.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  14186.       /*$IFDEF debug
  14187.          debugoutput ("found aromaticity information in input file");
  14188.          $ENDIF */
  14189.       if (!opt_xmdlout)
  14190.         normalize_ionic_bonds ();
  14191.       update_atypes ();         /* added in v0.2f */
  14192.       update_Htotal ();         /* end v0.2b snippet */
  14193.     }
  14194.   if (progmode == pmCheckMol)
  14195.     {
  14196.       if (opt_verbose)
  14197.         write_mol ();
  14198.       get_molstat ();
  14199.       if (opt_molstat)
  14200.         {
  14201.           if (opt_molstat_X)
  14202.             write_molstat_X ();
  14203.           else
  14204.             write_molstat ();
  14205.         }
  14206.       else
  14207.         {
  14208.           if (found_querymol)
  14209.             {
  14210.               printf ("input structure contains query atom or query bond!\n");
  14211.               exit (1);
  14212.             }
  14213.           chk_functionalgroups ();
  14214.           if (opt_none)
  14215.             opt_text = true;
  14216.           if (opt_text)
  14217.             write_fg_text ();
  14218.           if (opt_text_de)
  14219.             write_fg_text_de ();
  14220.           if (opt_code)
  14221.             write_fg_code ();
  14222.           if (opt_bin)
  14223.             write_fg_binary ();
  14224.           if (opt_bitstring)
  14225.             write_fg_bitstring ();
  14226.           if (opt_xmdlout)
  14227.             write_MDLmolfile ();
  14228.         }
  14229.       /*if opt_verbose   then write_mol; */
  14230.       zap_molecule ();
  14231.     }
  14232.   else
  14233.     {
  14234.       /* now transfer all data to the "needle" set of variables, except for "fingerprint" mode */
  14235.       if (!opt_fp)
  14236.         {                       /* v0.3m */
  14237.           copy_mol_to_needle ();
  14238.           //chk_wildcard_rings (); /* 0.3p */
  14239.           set_ndl_atom_tags (); /* v0.3o */
  14240.           if (opt_verbose)
  14241.             write_needle_mol ();
  14242.           if (rs_strict)        /* v0.3j */
  14243.             ndl_ref_atom = find_ndl_ref_atom_cv ();
  14244.           else
  14245.             ndl_ref_atom = find_ndl_ref_atom ();
  14246.         }
  14247.       else
  14248.         {
  14249.           copy_mol_to_tmp ();   /* v0.3m */
  14250.           if (opt_verbose)
  14251.             printf ("1st molecule stored in buffer: %s\n", tmp_molname);
  14252.         }
  14253.       /* next, read the "haystack" file and process it */
  14254.       li = 1;
  14255.       mol_count = 0;
  14256.       fpdecimal = 0;            /* v0.3m */
  14257.       fpindex = 0;              /* v0.3m */
  14258.       do
  14259.         {
  14260.           /* new in v0.3i: reset ringsearch_mode to its initial value */
  14261.           /* for each new molecule */
  14262.           ringsearch_mode = opt_rs;
  14263.           if (ringsearch_mode == rs_sar)
  14264.             max_vringsize = max_ringsize;
  14265.           else
  14266.             max_vringsize = ssr_vringsize;
  14267.           /* v0.3n (was: 10) */
  14268.           readinputfile (molfilename);
  14269.           li = 1;
  14270.           get_filetype (filetype, molfilename);
  14271.           if (strcmp (filetype, "unknown"))
  14272.             {
  14273.               found_arominfo = false;   /* added in v0.2b */
  14274.               mol_OK = true;    /* added in v0.2i */
  14275.               if (!strcmp (filetype, "alchemy"))
  14276.                 read_molfile (molfilename);
  14277.               if (!strcmp (filetype, "sybyl"))
  14278.                 read_mol2file (molfilename);
  14279.               if (!strcmp (filetype, "mdl"))
  14280.                 read_MDLmolfile (molfilename);
  14281.               mol_count++;
  14282.               fpindex++;
  14283.               count_neighbors ();
  14284.               /*if (not mol_OK) or (n_atoms < 1) then writeln(mol_count,':no valid structure found') else */
  14285.               if (!mol_OK || (n_atoms < 1
  14286.                   && !(opt_fp && fpformat == fpf_decimal)))
  14287.                 printf ("%i:F\n", mol_count);
  14288.               else
  14289.                 {
  14290.                   if (opt_exact
  14291.                       && (n_Ctot != ndl_n_Ctot || n_Otot != ndl_n_Otot
  14292.                           || n_Ntot != ndl_n_Ntot))
  14293.                     {           /* new in v0.3g */
  14294.                       if (!opt_molout && !(opt_fp && fpformat == fpf_decimal))
  14295.                         printf ("%i:F\n", mol_count);
  14296.                     }
  14297.                   else
  14298.                     {
  14299.                       if (!found_arominfo || (opt_strict && tmfmismatch))
  14300.                         {       /* added in v0.3m */
  14301. /* p2c: checkmol.pas, line 10294:
  14302.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  14303.                           /*$IFDEF debug
  14304.                              debugoutput
  14305.                              ("no aromaticity information found (or tweak mismatch) - checking myself...");
  14306.                             *$ENDIF */
  14307.                           chk_ringbonds ();
  14308.                           if (ringsearch_mode == rs_ssr)
  14309.                             remove_redundant_rings ();
  14310.                           if (n_rings == max_rings)
  14311.                             {
  14312.                               if (opt_verbose)
  14313.                                 printf
  14314.                                   ("Warning: max. number of rings (%i) reached, reverting to SSR search\n",
  14315.                                    max_rings);
  14316.                               ringsearch_mode = rs_ssr;
  14317.                               clear_rings ();
  14318.                               max_vringsize = ssr_vringsize;    /* v0.3n (was: 10) */
  14319.                               chk_ringbonds ();
  14320.                               remove_redundant_rings ();
  14321.                             }
  14322.                           update_ringcount ();
  14323.                           update_atypes ();
  14324.                           update_Htotal ();     /* added in v0.3 */
  14325.                           chk_arom ();
  14326.                           if (ringsearch_mode == rs_ssr)
  14327.                             {   /* new in v0.3 */
  14328.                               do
  14329.                                 {
  14330.                                   prev_n_ar = count_aromatic_rings ();
  14331.                                   chk_arom ();
  14332.                                   n_ar = count_aromatic_rings ();
  14333.                                 }
  14334.                               while (prev_n_ar - n_ar != 0);
  14335.                             }
  14336.                         }
  14337.                       else
  14338.                         {       /* added in v0.2f */
  14339. /* p2c: checkmol.pas, line 10322:
  14340.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  14341.                           /*$IFDEF debug
  14342.                              debugoutput
  14343.                              ("found aromaticity information in input file");
  14344.                              $ENDIF */
  14345.                           if (opt_strict)
  14346.                             update_atypes ();
  14347.                           update_Htotal ();
  14348.                         }
  14349.                       init_molstat (&ndl_molstat);
  14350.                       if (normalize_ionic_bonds ())
  14351.                         /* new in v0.3k, modified in v0.3m */
  14352.                         update_atypes ();
  14353.                       if (opt_verbose && !opt_fp)
  14354.                         write_mol ();
  14355.                       /* if in "fingerprint mode", exchange needle and haystack */
  14356.                       if (opt_fp)
  14357.                         {       /* v0.3m */
  14358.                           zap_needle ();
  14359.                           copy_mol_to_needle ();
  14360.                           //chk_wildcard_rings (); /* 0.3p */
  14361.                           zap_molecule ();
  14362.                           copy_tmp_to_mol ();
  14363.                           if (opt_verbose)
  14364.                             write_needle_mol ();
  14365.                           if (rs_strict)        /* v0.3j */
  14366.                             ndl_ref_atom = find_ndl_ref_atom_cv ();
  14367.                           else
  14368.                             ndl_ref_atom = find_ndl_ref_atom ();
  14369.                           if (opt_verbose)
  14370.                             write_mol ();
  14371.                         }       /* v0.3m */
  14372.                       /* now that we have both molecules, perform the comparison */
  14373.                       /* v0.3o: takes care of disconnected fragment... */
  14374.                       clear_atom_tags ();
  14375.                       set_ndl_atom_tags ();
  14376.                       matchsummary = true;
  14377.                       perform_match ();
  14378.                       matchsummary = matchresult;
  14379.                       if (count_tagged_ndl_heavyatoms () > 0
  14380.                           && matchsummary == true)
  14381.                         {
  14382.                           do
  14383.                             {
  14384.                               if (rs_strict)
  14385.                                 ndl_ref_atom = find_ndl_ref_atom_cv ();
  14386.                               else
  14387.                                 ndl_ref_atom = find_ndl_ref_atom ();
  14388.                               perform_match ();
  14389.                               if (matchresult == false)
  14390.                                 matchsummary = false;
  14391.                             }
  14392.                           while (count_tagged_ndl_heavyatoms () != 0 &&
  14393.                                  matchsummary != false);
  14394.                         }
  14395.                       /* end of disconnected-fragment matching (v0.3o) */
  14396.                       if (matchsummary == true)
  14397.                         {       /* v0.3o */
  14398.                           if (opt_molout)
  14399.                             {
  14400.                               FORLIM = molbufindex;
  14401.                               for (i = 1; i <= FORLIM; i++)
  14402.                                 puts (molbuf[i - 1]);
  14403.                             }
  14404.                           else
  14405.                             {
  14406.                               if (!opt_fp)      /* inttostr(mol_count) REPLACE!!!, */
  14407.                                 printf ("%i:T\n", mol_count);
  14408.                               else
  14409.                                 {
  14410.                                   if (ndl_n_heavyatoms == n_heavyatoms &&
  14411.                                       ndl_n_heavybonds == n_heavybonds)
  14412.                                     fp_exacthit = true;
  14413.                                   else
  14414.                                     fp_exacthit = false;
  14415.                                   if (fp_exacthit)
  14416.                                     fp_exactblock = true;
  14417.                                   if (fpformat == fpf_boolean)
  14418.                                     {
  14419.                                       if (fp_exacthit)  /* inttostr(mol_count), REPACE!!! */
  14420.                                         printf ("%i:TX\n", mol_count);
  14421.                                       else
  14422.                                         printf ("%i:T\n", mol_count);
  14423.                                     }
  14424.                                   /* inttostr(mol_count), REPLACE!!! */
  14425.                                   if (fpformat == fpf_decimal)
  14426.                                     {
  14427.                                       fpincrement = 1;
  14428.                                       FORLIM = fpindex;
  14429.                                       for (i = 1; i <= FORLIM; i++)
  14430.                                         fpincrement <<= 1;
  14431.                                       fpdecimal += fpincrement;
  14432.                                     }
  14433.                                 }
  14434.                             }
  14435.                         }
  14436.                       else
  14437.                         {
  14438.                           if (!
  14439.                               (opt_molout || (opt_fp
  14440.                                && fpformat == fpf_decimal)))
  14441.                             /* inttostr(mol_count), REPLACE!!! */
  14442.                             printf ("%i:F\n", mol_count);
  14443.                         }
  14444.                       if (opt_fp && fpformat == fpf_decimal
  14445.                           && fpindex == fp_blocksize)
  14446.                         {
  14447.                           if (fp_exactblock)
  14448.                             fpdecimal++;
  14449.                           printf ("%lld\n", fpdecimal);
  14450.                           fpindex = 0;
  14451.                           fpdecimal = 0;
  14452.                           fp_exactblock = false;
  14453.                         }
  14454.                       zap_molecule ();
  14455.                       molbufindex = 0;
  14456.                     }
  14457.                 }
  14458.             }
  14459.           else
  14460.             {
  14461.               /* v0.3l */
  14462.               /* mol_OK */
  14463.               printf ("%i:unknown file format\n", mol_count);
  14464.             }
  14465.         }
  14466.       while (mol_in_queue != false);
  14467.       /* if filetype <> 'unknown' */
  14468.       if (opt_fp && fpformat == fpf_decimal && fpindex > 0)
  14469.         {
  14470.           if (fp_exactblock)
  14471.             fpdecimal++;
  14472.           printf ("%lld\n", fpdecimal);
  14473.         }
  14474.       zap_needle ();
  14475.       if (rfile_is_open)
  14476.         {                       /* new in v0.2g */
  14477.           if (rfile != NULL)
  14478.             fclose (rfile);
  14479.           rfile = NULL;
  14480.         }
  14481.     }
  14482.   if (rfile != NULL)
  14483.     fclose (rfile);
  14484.   exit (0);
  14485. }
  14486.  
  14487. #else
  14488.  
  14489. static void
  14490. init_globals_dll (void)
  14491. {
  14492.  
  14493. //printf("init_globals_dll\n");
  14494.  
  14495.   int i;
  14496.   opt_verbose = false;
  14497.   opt_debug = false;
  14498.   opt_stdin = false;
  14499.   opt_text = false;
  14500.   opt_code = false;
  14501.   opt_bin = false;
  14502.   opt_bitstring = false;
  14503.   opt_molout = false;
  14504.   opt_molstat = false;
  14505.   opt_molstat_X = false;
  14506.   opt_xmdlout = false;
  14507.   opt_fp = false;               /* new in v0.3m */
  14508.   /*cm_mdlmolfile   := false; */
  14509.   found_arominfo = false;
  14510.   found_querymol = false;
  14511.   ndl_querymol = false;
  14512.   opt_rs = rs_sar;              /* v0.3i */
  14513.   ringsearch_mode = opt_rs;
  14514.   rfile_is_open = false;        /* new in v0.2g */
  14515.   ez_flag = false;              /* new in v0.3f */
  14516.   chir_flag = false;            /* new in v0.3f */
  14517.   n_Ctot = 0;
  14518.   n_Otot = 0;
  14519.   n_Ntot = 0;                   /* new in v0.3g */
  14520.   //for (i = 0; i < max_fg; i++)
  14521.   //  fg[i] = false;
  14522.   memset (fg, 0, sizeof (fglist));
  14523.  
  14524.   if (!yet_initialized)
  14525.     {
  14526.       molbuf = (void *) safe_malloc (sizeof (molbuftype));
  14527.       opt_exact = false;
  14528.       opt_strict = false;       /* new in v0.2f */
  14529.       opt_metalrings = false;   /* new in v0.3 */
  14530.       opt_geom = false;         /* new in v0.3d */
  14531.       opt_chiral = false;       /* new in v0.3f */
  14532.       opt_iso = false;          /* new in v0.3x */
  14533.       opt_chg = false;          /* new in v0.3x */
  14534.       opt_rad = false;          /* new in v0.3x */
  14535.       ez_search = false;        /* new in v0.3d */
  14536.       rs_search = false;        /* new in v0.3f */
  14537.       rs_strict = false;        /* new in v0.3j */
  14538.       ndl_n_Ctot = 0;
  14539.       ndl_n_Otot = 0;
  14540.       ndl_n_Ntot = 0;           /* new in v0.3g */
  14541.       yet_initialized = true;
  14542.     }
  14543.  
  14544.   ether_generic = false;        /* v0.3j */
  14545.   amine_generic = false;        /* v0.3j */
  14546.   hydroxy_generic = false;      /* v0.3j */
  14547.   fpformat = fpf_decimal;       /* v0.3m */
  14548.   fpindex = 0;                  /* v0.3m */
  14549.   fp_exacthit = false;          /* v0.3m */
  14550.   fp_exactblock = false;        /* v0.3m */
  14551.   tmfcode = 0;                  /* v0.3m */
  14552.   tmfmismatch = false;          /* v0.3m */
  14553.   auto_ssr = false;
  14554.   recursion_depth = 0;
  14555. }
  14556.  
  14557. static void
  14558. mm_init_mol (void)
  14559. {
  14560.  
  14561. //printf("mm_init_mol\n");
  14562.   init_globals_dll ();
  14563.   init_molstat (&molstat);
  14564.   if (opt_rs_dll == RPA_DEFAULT)
  14565.     {
  14566.       ringsearch_mode = opt_rs;
  14567.       //printf("DEFAULT: %i\n",ringsearch_mode);
  14568.     }
  14569.   else
  14570.     {
  14571.       ringsearch_mode = opt_rs_dll;
  14572.     }
  14573.   //printf("RPA: %i\n",ringsearch_mode);
  14574.  
  14575.   if (ringsearch_mode == rs_sar)
  14576.     {
  14577.       max_vringsize = max_ringsize;
  14578.     }
  14579.   else
  14580.     {
  14581.       max_vringsize = ssr_vringsize;
  14582.     }
  14583.   zap_molecule ();
  14584.   molbufindex = 0;
  14585.   mol_count = 0;
  14586. //printf("mm_init_mol\n");
  14587. }
  14588.  
  14589. static void
  14590. mm_elab_mol (boolean checkmol_mode, boolean normalize_ionic_bnds)
  14591. {
  14592. //printf("mm_elab_mol\n");
  14593.  
  14594.   li = 1;                       // initialize line pointer for input buffer
  14595.   get_filetype (filetype, ndl_molfilename);
  14596.   if (strcmp (filetype, "unknown") == 0)
  14597.     {
  14598.       //messagebox (0,'Error in mm_ElabMol: Unknown file format','MATCHMOLDLL ERROR',0);
  14599.       exit (3);
  14600.     }
  14601.  
  14602.   if (checkmol_mode == true)
  14603.     progmode = pmCheckMol;
  14604.   else
  14605.     progmode = pmMatchMol;
  14606.   if (strcmp (filetype, "alchemy") == 0)
  14607.     read_molfile (ndl_molfilename);
  14608.   if (strcmp (filetype, "sybyl") == 0)
  14609.     read_mol2file (ndl_molfilename);
  14610.   if (strcmp (filetype, "mdl") == 0)
  14611.     read_MDLmolfile (ndl_molfilename);
  14612.   if (checkmol_mode)
  14613.     {
  14614.       if (found_querymol)
  14615.         {
  14616.           printf
  14617.             ("Warning: Input structure contains query atom or query bond.\n");
  14618.         }
  14619.     }
  14620.  
  14621.   count_neighbors ();
  14622.   if (!found_arominfo || checkmol_mode || opt_strict)
  14623.     {
  14624.       //printf("No arom found or checkmol mode\n");
  14625.       chk_ringbonds ();
  14626.       if (ringsearch_mode == rs_ssr)
  14627.         remove_redundant_rings ();
  14628.       if (n_rings >= max_rings)
  14629.         {
  14630.  
  14631.           printf
  14632.             ("Warning: max. number of rings (%i) reached, reverting to SSR search\n",
  14633.              max_rings);
  14634.           ringsearch_mode = rs_ssr;
  14635.           auto_ssr = true;
  14636.           clear_rings ();
  14637.           max_vringsize = ssr_vringsize;
  14638.           chk_ringbonds ();
  14639.           remove_redundant_rings ();
  14640.         }
  14641.  
  14642.       update_ringcount ();
  14643.       if (normalize_ionic_bnds) /* v0.3k */
  14644.         normalize_ionic_bonds ();
  14645.       update_atypes ();
  14646.       update_Htotal ();
  14647.       chk_arom ();
  14648.       if (ringsearch_mode == rs_ssr)
  14649.         {                       /* new in v0.3 */
  14650.           do
  14651.             {
  14652.               prev_n_ar = count_aromatic_rings ();
  14653.               chk_arom ();
  14654.               n_ar = count_aromatic_rings ();
  14655.             }
  14656.           while (prev_n_ar - n_ar != 0);
  14657.         }
  14658.     }
  14659.   else
  14660.     {
  14661.       if (normalize_ionic_bnds) /* v0.3k  */
  14662.         normalize_ionic_bonds ();
  14663.       //if (opt_strict)
  14664.       update_atypes ();
  14665.       update_Htotal ();
  14666.     }
  14667.  
  14668.  
  14669.  
  14670. //printf("mm_elab_mol\n");
  14671. }
  14672.  
  14673. DLLEXPORT void
  14674. mm_set_current_mol_as_query (void)
  14675. {
  14676. //printf("mm_set_current_mol_as_query\n");
  14677.   zap_needle ();
  14678. //mm_ElabMol;
  14679.   copy_mol_to_needle ();
  14680.   //chk_wildcard_rings (); /* 0.3p */
  14681.   set_ndl_atom_tags ();         /* v0.3o */
  14682.   if (opt_geom)                 /* v0.3d */
  14683.     ez_search = true;
  14684.   else if (!ez_flag && ez_search)
  14685.     ez_search = false;          //chir_flag initialized in read_MDLmolfile, otherwise we lose that info
  14686.   if (opt_chiral)
  14687.     {                           /* v0.3f */
  14688.       rs_search = true;
  14689.  
  14690.       //printf("%i\n",rs_search);
  14691.     }
  14692.   else if (!chir_flag && rs_search)
  14693.     {
  14694.       rs_search = false;        //chir_flag initialized in read_MDLmolfile, otherwise we lose that info
  14695.       //printf("%i\n",rs_search);
  14696.     }
  14697.   if (opt_chiral && opt_strict && opt_exact)    /* new in v0.3j */
  14698.     rs_strict = true;
  14699.   else
  14700.     rs_strict = false;
  14701.   /* if (rs_strict)              // v0.3j
  14702.      ndl_ref_atom = find_ndl_ref_atom_cv ();
  14703.      //ndl_ref_atom = find_ndl_ref_atom ();
  14704.      else
  14705.      ndl_ref_atom = find_ndl_ref_atom (); */
  14706.  
  14707.  
  14708.  
  14709.   molbufindex = 0;
  14710.   mol_count = 0;
  14711. /*printf("mm_set_current_mol_as_query\n");*/
  14712. }
  14713.  
  14714. DLLEXPORT int
  14715. mm_get_rings (void)
  14716. {
  14717.   return n_rings;
  14718. }
  14719.  
  14720. DLLEXPORT void
  14721. xm_version (char *buffer)
  14722. {
  14723.   buffer[0] = '\0';
  14724.   strncpy (buffer, version, 255);
  14725. }
  14726.  
  14727. DLLEXPORT int
  14728. mm_get_atom_ring (int atom_number)
  14729. {
  14730.  
  14731.   int i, j, a1, pl;
  14732.   int ret = 0;
  14733.   a1 = atom[atom_number].ring_count;
  14734.   if (n_rings > 0)
  14735.     {
  14736.       for (i = 1; i < n_rings; i++)
  14737.         {
  14738.  
  14739.           pl = path_length (ring[i]);
  14740. //          a2 := ring^[i,pl];
  14741.           for (j = 1; j < pl; j++)
  14742.             {
  14743.  
  14744.               a1 = ring[i][j];
  14745.               if (atom_number == a1)
  14746.                 ret = i;
  14747. //
  14748. //              inc(atom^[a1].ring_count);
  14749. //              b := get_bond(a1,a2);
  14750. //              inc(bond^[b].ring_count);
  14751. //              a2 := a1;
  14752.             }
  14753.         }
  14754.     }
  14755.   return ret;
  14756. }
  14757.  
  14758. static void
  14759. mm_read_input_line (char *st)
  14760. {
  14761. //printf("mm_read_input_line_in\n");
  14762. //var
  14763. //yyy:pchar;
  14764.  
  14765.   mol_in_queue = false;
  14766.   if (molbufindex < (max_atoms + max_bonds + slack))
  14767.     {
  14768.  
  14769. //yyy:=Pchar(IntToStr(molbufindex));
  14770. //messagebox (0,yyy,'',0);
  14771. //printf("%i\n",molbufindex);
  14772. //printf("B:%s\n",st);
  14773.       strcpy (molbuf[molbufindex++], st);
  14774. //printf("%x %x\n",&molbuf,molbuf);
  14775. //printf("%s\n",molbuf[molbufindex-1]);
  14776.       //  molbufindex++;
  14777.     }
  14778.   else
  14779.     {
  14780.       //messagebox(0,'Error in mm_Readinputline; memory problem','ERROR',0);
  14781.       printf ("Not enough memory for molfile! %i\n", molbufindex);
  14782.       exit (1);
  14783.     }
  14784. //printf("mm_read_input_line_out\n");
  14785. }
  14786.  
  14787.  
  14788. static void
  14789. mm_set_mol_dll (const char *st, boolean checkmol_mode,
  14790.                 boolean normalize_ionic_bnds)
  14791. {
  14792. //printf("mm_set_mol\n");
  14793. //printf("%s\n",st);
  14794.   char bb;
  14795.   char aa;
  14796.   int i;
  14797.   int k;
  14798.   int J;
  14799.   int spt = 0;
  14800.   char tt[256];
  14801.   char bb10 = '\n';
  14802.   char bb13 = '\r';
  14803.   char bb0 = '\0';
  14804.   int lenst;
  14805. //char d[256];
  14806.   lenst = strlen (st);
  14807. //tt=(char*)safe_malloc(256*sizeof(char));
  14808.   tt[0] = '\0';
  14809. //messagebox(0,st,'',0);
  14810.   mm_init_mol ();
  14811.   for (i = spt; i < lenst; i++)
  14812.     {
  14813.       bb = st[i];
  14814.       if ((bb == bb10) || (i == lenst))
  14815.         {
  14816.           J = 0;
  14817.           // d:='';
  14818.           for (k = spt; k < i; k++)
  14819.             {
  14820.  
  14821.               aa = st[k];
  14822.               if ((aa != bb10) && (aa != bb13))
  14823.                 {
  14824.                   //d:=d+aa;
  14825.                   tt[J] = aa;
  14826.                   J++;
  14827.                 }
  14828.             }
  14829.           tt[J] = bb0;
  14830.           spt = i;
  14831.           //messagebox (0,tt,tt,0);
  14832. //printf("A:%s\n",tt);
  14833.           mm_read_input_line (tt);
  14834.         }
  14835.     }
  14836. //free(tt);
  14837.   mm_elab_mol (checkmol_mode, normalize_ionic_bnds);
  14838. //printf("mm_set_mol\n");
  14839. }
  14840.  
  14841. DLLEXPORT void
  14842. cm_set_mol (const char *st, int normalize_ionic_bnds)
  14843. {
  14844.   mm_set_mol_dll (st, true, (normalize_ionic_bnds != FEATURE_OFF));
  14845. }
  14846.  
  14847. DLLEXPORT void
  14848. mm_set_mol (const char *st)
  14849. {
  14850.   mm_set_mol_dll (st, false, true);
  14851. }
  14852.  
  14853. DLLEXPORT void
  14854. xm_set_strict_typing (int strict_typing)
  14855. {
  14856.   if (!yet_initialized)
  14857.     init_globals_dll ();
  14858.   opt_strict = (strict_typing != FEATURE_OFF);
  14859.   //opt_strict=false; //This never worked right and is harmful
  14860. }
  14861.  
  14862. DLLEXPORT void
  14863. mm_set_r_s_check (int r_s_check)
  14864. {
  14865.   if (!yet_initialized)
  14866.     init_globals_dll ();
  14867.   opt_chiral = (r_s_check != FEATURE_OFF);
  14868. }
  14869.  
  14870. DLLEXPORT void
  14871. mm_set_e_z_check (int e_z_check)
  14872. {
  14873.   if (!yet_initialized)
  14874.     init_globals_dll ();
  14875.   opt_geom = (e_z_check != FEATURE_OFF);
  14876. }
  14877.  
  14878. DLLEXPORT void
  14879. mm_set_chg_check (int chg_check)
  14880. {
  14881.   if (!yet_initialized)
  14882.     init_globals_dll ();
  14883.   opt_chg = (chg_check != FEATURE_OFF);
  14884. }
  14885.  
  14886. DLLEXPORT void
  14887. mm_set_iso_check (int iso_check)
  14888. {
  14889.   if (!yet_initialized)
  14890.     init_globals_dll ();
  14891.   opt_iso = (iso_check != FEATURE_OFF);
  14892. }
  14893.  
  14894. DLLEXPORT void
  14895. mm_set_rad_check (int rad_check)
  14896. {
  14897.   if (!yet_initialized)
  14898.     init_globals_dll ();
  14899.   opt_rad = (rad_check != FEATURE_OFF);
  14900. }
  14901.  
  14902. DLLEXPORT void
  14903. mm_set_exact_match (int exact)
  14904. {
  14905.   if (!yet_initialized)
  14906.     init_globals_dll ();
  14907.   opt_exact = (exact != FEATURE_OFF);
  14908. }
  14909.  
  14910. DLLEXPORT int
  14911. mm_match ()
  14912. {
  14913.   mol_count = 1;
  14914. //     mm_ElabMol;
  14915. /*printf("%i\n",opt_exact);
  14916. printf("%i\n",n_Ctot);
  14917. printf("%i\n",ndl_n_Ctot);
  14918. printf("%i\n",n_Otot);
  14919. printf("%i\n",ndl_n_Otot);
  14920. printf("%i\n",n_Ntot);
  14921. printf("%i\n",ndl_n_Ntot);*/
  14922.   if (opt_exact
  14923.       && (n_Ctot != ndl_n_Ctot || n_Otot != ndl_n_Otot
  14924.           || n_Ntot != ndl_n_Ntot))
  14925.     return 0;
  14926.   init_molstat (&ndl_molstat);
  14927.   //perform_match ();
  14928.   //---------------------------------------------------- 0.3o
  14929.   if (rs_strict)                /* v0.3j */
  14930.     ndl_ref_atom = find_ndl_ref_atom_cv ();
  14931.   //ndl_ref_atom = find_ndl_ref_atom ();
  14932.   else
  14933.     ndl_ref_atom = find_ndl_ref_atom ();
  14934.   clear_atom_tags ();
  14935.   set_ndl_atom_tags ();
  14936.   matchsummary = true;
  14937.   perform_match ();
  14938.   matchsummary = matchresult;
  14939.   if (count_tagged_ndl_heavyatoms () > 0 && matchsummary == true)
  14940.     {
  14941.       do
  14942.         {
  14943.           if (rs_strict)
  14944.             ndl_ref_atom = find_ndl_ref_atom_cv ();
  14945.           else
  14946.             ndl_ref_atom = find_ndl_ref_atom ();
  14947.           perform_match ();
  14948.           if (matchresult == false)
  14949.             matchsummary = false;
  14950.         }
  14951.       while (count_tagged_ndl_heavyatoms () != 0 && matchsummary != false);
  14952.     }
  14953.  
  14954.   //-----------------------------------------------------
  14955.  
  14956.   //mol_count = 0;
  14957.  
  14958.   //molbufindex = 0;
  14959.  
  14960.   //return matchresult ? 1 : 0;
  14961.  
  14962.   return matchsummary ? 1 : 0;
  14963. }
  14964.  
  14965. //-------------------------
  14966.  
  14967. DLLEXPORT void
  14968. xm_set_ring_perception_algorithm (int algo)
  14969. {
  14970.   switch (algo)
  14971.     {
  14972.     case RPA_SAR:
  14973.       opt_rs_dll = rs_sar;
  14974.       break;
  14975.     case RPA_SSR:
  14976.       opt_rs_dll = rs_ssr;
  14977.       break;
  14978.     default:
  14979.       opt_rs_dll = RPA_DEFAULT;
  14980.       break;
  14981.     }
  14982.   //printf("RPA_SET: %i\n",opt_rs_dll);
  14983. }
  14984.  
  14985. static void
  14986. write_molstat_X_dll (char *out_buffer)
  14987. {
  14988.   char tmp_buf[256];
  14989.   out_buffer[0] = '\0';
  14990.   if (auto_ssr)                 /* v0.3n */
  14991.     fix_ssr_ringcounts ();
  14992.   sprintf (tmp_buf, "%d,", n_heavyatoms);
  14993.   strcat (out_buffer, tmp_buf);
  14994.   sprintf (tmp_buf, "%d,", n_heavybonds);
  14995.   strcat (out_buffer, tmp_buf);
  14996. #ifdef REDUCED_SAR
  14997.   sprintf (tmp_buf, "%d,", n_countablerings);
  14998.   strcat (out_buffer, tmp_buf);
  14999. #else
  15000.   sprintf (tmp_buf, "%d,", n_rings);
  15001.   strcat (out_buffer, tmp_buf);
  15002. #endif
  15003.   sprintf (tmp_buf, "%d,", molstat.n_QA);
  15004.   strcat (out_buffer, tmp_buf);
  15005.   sprintf (tmp_buf, "%d,", molstat.n_QB);
  15006.   strcat (out_buffer, tmp_buf);
  15007.   //if (opt_chg)
  15008. //    {                         /* 0.3x */
  15009. //      sprintf (tmp_buf, "%d,", molstat.n_chg);
  15010. //    }
  15011. //  else
  15012. //    {
  15013.   sprintf (tmp_buf, "%d,", molstat.n_chg);
  15014.   //   }
  15015.   strcat (out_buffer, tmp_buf);
  15016.   sprintf (tmp_buf, "%d,", molstat.n_C1);
  15017.   strcat (out_buffer, tmp_buf);
  15018.   sprintf (tmp_buf, "%d,", molstat.n_C2);
  15019.   strcat (out_buffer, tmp_buf);
  15020.   sprintf (tmp_buf, "%d,", molstat.n_C);
  15021.   strcat (out_buffer, tmp_buf);
  15022.   sprintf (tmp_buf, "%d,", molstat.n_CHB1p);
  15023.   strcat (out_buffer, tmp_buf);
  15024.   sprintf (tmp_buf, "%d,", molstat.n_CHB2p);
  15025.   strcat (out_buffer, tmp_buf);
  15026.   sprintf (tmp_buf, "%d,", molstat.n_CHB3p);
  15027.   strcat (out_buffer, tmp_buf);
  15028.   sprintf (tmp_buf, "%d,", molstat.n_CHB4);
  15029.   strcat (out_buffer, tmp_buf);
  15030.   sprintf (tmp_buf, "%d,", molstat.n_O2);
  15031.   strcat (out_buffer, tmp_buf);
  15032.   sprintf (tmp_buf, "%d,", molstat.n_O3);
  15033.   strcat (out_buffer, tmp_buf);
  15034.   sprintf (tmp_buf, "%d,", molstat.n_N1);
  15035.   strcat (out_buffer, tmp_buf);
  15036.   sprintf (tmp_buf, "%d,", molstat.n_N2);
  15037.   strcat (out_buffer, tmp_buf);
  15038.   sprintf (tmp_buf, "%d,", molstat.n_N3);
  15039.   strcat (out_buffer, tmp_buf);
  15040.   sprintf (tmp_buf, "%d,", molstat.n_S);
  15041.   strcat (out_buffer, tmp_buf);
  15042.   sprintf (tmp_buf, "%d,", molstat.n_SeTe);
  15043.   strcat (out_buffer, tmp_buf);
  15044.   sprintf (tmp_buf, "%d,", molstat.n_F);
  15045.   strcat (out_buffer, tmp_buf);
  15046.   sprintf (tmp_buf, "%d,", molstat.n_Cl);
  15047.   strcat (out_buffer, tmp_buf);
  15048.   sprintf (tmp_buf, "%d,", molstat.n_Br);
  15049.   strcat (out_buffer, tmp_buf);
  15050.   sprintf (tmp_buf, "%d,", molstat.n_I);
  15051.   strcat (out_buffer, tmp_buf);
  15052.   sprintf (tmp_buf, "%d,", molstat.n_P);
  15053.   strcat (out_buffer, tmp_buf);
  15054.   sprintf (tmp_buf, "%d,", molstat.n_B);
  15055.   strcat (out_buffer, tmp_buf);
  15056.   sprintf (tmp_buf, "%d,", molstat.n_Met);
  15057.   strcat (out_buffer, tmp_buf);
  15058.   sprintf (tmp_buf, "%d,", molstat.n_X);
  15059.   strcat (out_buffer, tmp_buf);
  15060.   sprintf (tmp_buf, "%d,", molstat.n_b1);
  15061.   strcat (out_buffer, tmp_buf);
  15062.   sprintf (tmp_buf, "%d,", molstat.n_b2);
  15063.   strcat (out_buffer, tmp_buf);
  15064.   sprintf (tmp_buf, "%d,", molstat.n_b3);
  15065.   strcat (out_buffer, tmp_buf);
  15066.   sprintf (tmp_buf, "%d,", molstat.n_bar);
  15067.   strcat (out_buffer, tmp_buf);
  15068.   sprintf (tmp_buf, "%d,", molstat.n_C1O);
  15069.   strcat (out_buffer, tmp_buf);
  15070.   sprintf (tmp_buf, "%d,", molstat.n_C2O);
  15071.   strcat (out_buffer, tmp_buf);
  15072.   sprintf (tmp_buf, "%d,", molstat.n_CN);
  15073.   strcat (out_buffer, tmp_buf);
  15074.   sprintf (tmp_buf, "%d,", molstat.n_XY);
  15075.   strcat (out_buffer, tmp_buf);
  15076.   sprintf (tmp_buf, "%d,", molstat.n_r3);
  15077.   strcat (out_buffer, tmp_buf);
  15078.   sprintf (tmp_buf, "%d,", molstat.n_r4);
  15079.   strcat (out_buffer, tmp_buf);
  15080.   sprintf (tmp_buf, "%d,", molstat.n_r5);
  15081.   strcat (out_buffer, tmp_buf);
  15082.   sprintf (tmp_buf, "%d,", molstat.n_r6);
  15083.   strcat (out_buffer, tmp_buf);
  15084.   sprintf (tmp_buf, "%d,", molstat.n_r7);
  15085.   strcat (out_buffer, tmp_buf);
  15086.   sprintf (tmp_buf, "%d,", molstat.n_r8);
  15087.   strcat (out_buffer, tmp_buf);
  15088.   sprintf (tmp_buf, "%d,", molstat.n_r9);
  15089.   strcat (out_buffer, tmp_buf);
  15090.   sprintf (tmp_buf, "%d,", molstat.n_r10);
  15091.   strcat (out_buffer, tmp_buf);
  15092.   sprintf (tmp_buf, "%d,", molstat.n_r11);
  15093.   strcat (out_buffer, tmp_buf);
  15094.   sprintf (tmp_buf, "%d,", molstat.n_r12);
  15095.   strcat (out_buffer, tmp_buf);
  15096.   sprintf (tmp_buf, "%d,", molstat.n_r13p);
  15097.   strcat (out_buffer, tmp_buf);
  15098.   sprintf (tmp_buf, "%d,", molstat.n_rN);
  15099.   strcat (out_buffer, tmp_buf);
  15100.   sprintf (tmp_buf, "%d,", molstat.n_rN1);
  15101.   strcat (out_buffer, tmp_buf);
  15102.   sprintf (tmp_buf, "%d,", molstat.n_rN2);
  15103.   strcat (out_buffer, tmp_buf);
  15104.   sprintf (tmp_buf, "%d,", molstat.n_rN3p);
  15105.   strcat (out_buffer, tmp_buf);
  15106.   sprintf (tmp_buf, "%d,", molstat.n_rO);
  15107.   strcat (out_buffer, tmp_buf);
  15108.   sprintf (tmp_buf, "%d,", molstat.n_rO1);
  15109.   strcat (out_buffer, tmp_buf);
  15110.   sprintf (tmp_buf, "%d,", molstat.n_rO2p);
  15111.   strcat (out_buffer, tmp_buf);
  15112.   sprintf (tmp_buf, "%d,", molstat.n_rS);
  15113.   strcat (out_buffer, tmp_buf);
  15114.   sprintf (tmp_buf, "%d,", molstat.n_rX);
  15115.   strcat (out_buffer, tmp_buf);
  15116.   sprintf (tmp_buf, "%d,", molstat.n_rAr);
  15117.   strcat (out_buffer, tmp_buf);
  15118.   sprintf (tmp_buf, "%d,", molstat.n_rBz);
  15119.   strcat (out_buffer, tmp_buf);
  15120.   sprintf (tmp_buf, "%d,", molstat.n_br2p);
  15121.   strcat (out_buffer, tmp_buf);
  15122.   sprintf (tmp_buf, "%d,", molstat.n_psg01);
  15123.   strcat (out_buffer, tmp_buf);
  15124.   sprintf (tmp_buf, "%d,", molstat.n_psg02);
  15125.   strcat (out_buffer, tmp_buf);
  15126.   sprintf (tmp_buf, "%d,", molstat.n_psg13);
  15127.   strcat (out_buffer, tmp_buf);
  15128.   sprintf (tmp_buf, "%d,", molstat.n_psg14);
  15129.   strcat (out_buffer, tmp_buf);
  15130.   sprintf (tmp_buf, "%d,", molstat.n_psg15);
  15131.   strcat (out_buffer, tmp_buf);
  15132.   sprintf (tmp_buf, "%d,", molstat.n_psg16);
  15133.   strcat (out_buffer, tmp_buf);
  15134.   sprintf (tmp_buf, "%d,", molstat.n_psg17);
  15135.   strcat (out_buffer, tmp_buf);
  15136.   sprintf (tmp_buf, "%d,", molstat.n_psg18);
  15137.   strcat (out_buffer, tmp_buf);
  15138.   sprintf (tmp_buf, "%d,", molstat.n_pstm);
  15139.   strcat (out_buffer, tmp_buf);
  15140.   sprintf (tmp_buf, "%d,", molstat.n_psla);
  15141.   strcat (out_buffer, tmp_buf);
  15142.   sprintf (tmp_buf, "%d,", molstat.n_iso);
  15143.   strcat (out_buffer, tmp_buf);
  15144.   sprintf (tmp_buf, "%d", molstat.n_rad);
  15145.   strcat (out_buffer, tmp_buf);
  15146. }
  15147.  
  15148. static void
  15149. write_molstat_dll (char *out_buffer, int mode)
  15150. {
  15151.   char tmp_buf[256];
  15152.   char *sep1;
  15153.   char *sep2;
  15154.   switch (mode)
  15155.     {
  15156.     case 1:
  15157.       sep1 = "=";
  15158.       sep2 = " AND ";
  15159.       break;
  15160.     case 2:
  15161.       sep1 = "<=";
  15162.       sep2 = " AND ";
  15163.       break;
  15164.     default:
  15165.       sep1 = ":";
  15166.       sep2 = ";";
  15167.       break;
  15168.     }
  15169.  
  15170.  
  15171.  
  15172.   out_buffer[0] = '\0';
  15173.  
  15174.   if (auto_ssr)                 /* v0.3n */
  15175.     fix_ssr_ringcounts ();
  15176.   sprintf (tmp_buf, "n_atoms%s%d%s", sep1, n_heavyatoms, sep2);
  15177.   strcat (out_buffer, tmp_buf);
  15178.   if (n_bonds > 0)
  15179.     {
  15180.       sprintf (tmp_buf, "n_bonds%s%d%s", sep1, n_heavybonds, sep2);
  15181.       strcat (out_buffer, tmp_buf);
  15182.     }
  15183.  
  15184. #ifdef REDUCED_SAR
  15185.   if (n_rings > 0)
  15186.     {
  15187.       sprintf (tmp_buf, "n_rings%s%d%s", sep1, n_countablerings, sep2);
  15188.       strcat (out_buffer, tmp_buf);
  15189.     }
  15190. #else
  15191.   if (n_rings > 0)
  15192.     {
  15193.       sprintf (tmp_buf, "n_rings%s%d%s", sep1, n_rings, sep2);
  15194.       strcat (out_buffer, tmp_buf);
  15195.     }
  15196. #endif
  15197.  
  15198.   if (opt_chg && molstat.n_chg > 0)     /* 0.3x */
  15199.     {
  15200.       sprintf (tmp_buf, "n_chg%s%d%s", sep1, molstat.n_chg, sep2);
  15201.       strcat (out_buffer, tmp_buf);
  15202.     }
  15203.   if (molstat.n_C1 > 0)
  15204.     {
  15205.       sprintf (tmp_buf, "n_C1%s%d%s", sep1, molstat.n_C1, sep2);
  15206.       strcat (out_buffer, tmp_buf);
  15207.     }
  15208.   if (molstat.n_C2 > 0)
  15209.     {
  15210.       sprintf (tmp_buf, "n_C2%s%d%s", sep1, molstat.n_C2, sep2);
  15211.       strcat (out_buffer, tmp_buf);
  15212.     }
  15213.  
  15214.  
  15215.   if (molstat.n_C > 0)
  15216.     {
  15217.       sprintf (tmp_buf, "n_C%s%d%s", sep1, molstat.n_C, sep2);
  15218.       strcat (out_buffer, tmp_buf);
  15219.     }
  15220.   if (molstat.n_CHB1p > 0)
  15221.     {
  15222.       sprintf (tmp_buf, "n_CHB1p%s%d%s", sep1, molstat.n_CHB1p, sep2);
  15223.       strcat (out_buffer, tmp_buf);
  15224.     }
  15225.   if (molstat.n_CHB2p > 0)
  15226.     {
  15227.       sprintf (tmp_buf, "n_CHB2p%s%d%s", sep1, molstat.n_CHB2p, sep2);
  15228.       strcat (out_buffer, tmp_buf);
  15229.     }
  15230.   if (molstat.n_CHB3p > 0)
  15231.     {
  15232.       sprintf (tmp_buf, "n_CHB3p%s%d%s", sep1, molstat.n_CHB3p, sep2);
  15233.       strcat (out_buffer, tmp_buf);
  15234.     }
  15235.   if (molstat.n_CHB4 > 0)
  15236.     {
  15237.       sprintf (tmp_buf, "n_CHB4%s%d%s", sep1, molstat.n_CHB4, sep2);
  15238.       strcat (out_buffer, tmp_buf);
  15239.     }
  15240.   if (molstat.n_O2 > 0)
  15241.     {
  15242.       sprintf (tmp_buf, "n_O2%s%d%s", sep1, molstat.n_O2, sep2);
  15243.       strcat (out_buffer, tmp_buf);
  15244.     }
  15245.   if (molstat.n_O3 > 0)
  15246.     {
  15247.       sprintf (tmp_buf, "n_O3%s%d%s", sep1, molstat.n_O3, sep2);
  15248.       strcat (out_buffer, tmp_buf);
  15249.     }
  15250.   if (molstat.n_N1 > 0)
  15251.     {
  15252.       sprintf (tmp_buf, "n_N1%s%d%s", sep1, molstat.n_N1, sep2);
  15253.       strcat (out_buffer, tmp_buf);
  15254.     }
  15255.   if (molstat.n_N2 > 0)
  15256.     {
  15257.       sprintf (tmp_buf, "n_N2%s%d%s", sep1, molstat.n_N2, sep2);
  15258.       strcat (out_buffer, tmp_buf);
  15259.     }
  15260.   if (molstat.n_N3 > 0)
  15261.     {
  15262.       sprintf (tmp_buf, "n_N3%s%d%s", sep1, molstat.n_N3, sep2);
  15263.       strcat (out_buffer, tmp_buf);
  15264.     }
  15265.   if (molstat.n_S > 0)
  15266.     {
  15267.       sprintf (tmp_buf, "n_S%s%d%s", sep1, molstat.n_S, sep2);
  15268.       strcat (out_buffer, tmp_buf);
  15269.     }
  15270.   if (molstat.n_SeTe > 0)
  15271.     {
  15272.       sprintf (tmp_buf, "n_SeTe%s%d%s", sep1, molstat.n_SeTe, sep2);
  15273.       strcat (out_buffer, tmp_buf);
  15274.     }
  15275.   if (molstat.n_F > 0)
  15276.     {
  15277.       sprintf (tmp_buf, "n_F%s%d%s", sep1, molstat.n_F, sep2);
  15278.       strcat (out_buffer, tmp_buf);
  15279.     }
  15280.   if (molstat.n_Cl > 0)
  15281.     {
  15282.       sprintf (tmp_buf, "n_Cl%s%d%s", sep1, molstat.n_Cl, sep2);
  15283.       strcat (out_buffer, tmp_buf);
  15284.     }
  15285.   if (molstat.n_Br > 0)
  15286.     {
  15287.       sprintf (tmp_buf, "n_Br%s%d%s", sep1, molstat.n_Br, sep2);
  15288.       strcat (out_buffer, tmp_buf);
  15289.     }
  15290.   if (molstat.n_I > 0)
  15291.     {
  15292.       sprintf (tmp_buf, "n_I%s%d%s", sep1, molstat.n_I, sep2);
  15293.       strcat (out_buffer, tmp_buf);
  15294.     }
  15295.   if (molstat.n_P > 0)
  15296.     {
  15297.       sprintf (tmp_buf, "n_P%s%d%s", sep1, molstat.n_P, sep2);
  15298.       strcat (out_buffer, tmp_buf);
  15299.     }
  15300.   if (molstat.n_B > 0)
  15301.     {
  15302.       sprintf (tmp_buf, "n_B%s%d%s", sep1, molstat.n_B, sep2);
  15303.       strcat (out_buffer, tmp_buf);
  15304.     }
  15305.   if (molstat.n_Met > 0)
  15306.     {
  15307.       sprintf (tmp_buf, "n_Met%s%d%s", sep1, molstat.n_Met, sep2);
  15308.       strcat (out_buffer, tmp_buf);
  15309.     }
  15310.   if (molstat.n_X > 0)
  15311.     {
  15312.       sprintf (tmp_buf, "n_X%s%d%s", sep1, molstat.n_X, sep2);
  15313.       strcat (out_buffer, tmp_buf);
  15314.     }
  15315.   if (molstat.n_b1 > 0)
  15316.     {
  15317.       sprintf (tmp_buf, "n_b1%s%d%s", sep1, molstat.n_b1, sep2);
  15318.       strcat (out_buffer, tmp_buf);
  15319.     }
  15320.   if (molstat.n_b2 > 0)
  15321.     {
  15322.       sprintf (tmp_buf, "n_b2%s%d%s", sep1, molstat.n_b2, sep2);
  15323.       strcat (out_buffer, tmp_buf);
  15324.     }
  15325.   if (molstat.n_b3 > 0)
  15326.     {
  15327.       sprintf (tmp_buf, "n_b3%s%d%s", sep1, molstat.n_b3, sep2);
  15328.       strcat (out_buffer, tmp_buf);
  15329.     }
  15330.   if (molstat.n_bar > 0)
  15331.     {
  15332.       sprintf (tmp_buf, "n_bar%s%d%s", sep1, molstat.n_bar, sep2);
  15333.       strcat (out_buffer, tmp_buf);
  15334.     }
  15335.   if (molstat.n_C1O > 0)
  15336.     {
  15337.       sprintf (tmp_buf, "n_C1O%s%d%s", sep1, molstat.n_C1O, sep2);
  15338.       strcat (out_buffer, tmp_buf);
  15339.     }
  15340.   if (molstat.n_C2O > 0)
  15341.     {
  15342.       sprintf (tmp_buf, "n_C2O%s%d%s", sep1, molstat.n_C2O, sep2);
  15343.       strcat (out_buffer, tmp_buf);
  15344.     }
  15345.   if (molstat.n_CN > 0)
  15346.     {
  15347.       sprintf (tmp_buf, "n_CN%s%d%s", sep1, molstat.n_CN, sep2);
  15348.       strcat (out_buffer, tmp_buf);
  15349.     }
  15350.   if (molstat.n_XY > 0)
  15351.     {
  15352.       sprintf (tmp_buf, "n_XY%s%d%s", sep1, molstat.n_XY, sep2);
  15353.       strcat (out_buffer, tmp_buf);
  15354.     }
  15355.   if (molstat.n_r3 > 0)
  15356.     {
  15357.       sprintf (tmp_buf, "n_r3%s%d%s", sep1, molstat.n_r3, sep2);
  15358.       strcat (out_buffer, tmp_buf);
  15359.     }
  15360.   if (molstat.n_r4 > 0)
  15361.     {
  15362.       sprintf (tmp_buf, "n_r4%s%d%s", sep1, molstat.n_r4, sep2);
  15363.       strcat (out_buffer, tmp_buf);
  15364.     }
  15365.   if (molstat.n_r5 > 0)
  15366.     {
  15367.       sprintf (tmp_buf, "n_r5%s%d%s", sep1, molstat.n_r5, sep2);
  15368.       strcat (out_buffer, tmp_buf);
  15369.     }
  15370.   if (molstat.n_r6 > 0)
  15371.     {
  15372.       sprintf (tmp_buf, "n_r6%s%d%s", sep1, molstat.n_r6, sep2);
  15373.       strcat (out_buffer, tmp_buf);
  15374.     }
  15375.   if (molstat.n_r7 > 0)
  15376.     {
  15377.       sprintf (tmp_buf, "n_r7%s%d%s", sep1, molstat.n_r7, sep2);
  15378.       strcat (out_buffer, tmp_buf);
  15379.     }
  15380.   if (molstat.n_r8 > 0)
  15381.     {
  15382.       sprintf (tmp_buf, "n_r8%s%d%s", sep1, molstat.n_r8, sep2);
  15383.       strcat (out_buffer, tmp_buf);
  15384.     }
  15385.   if (molstat.n_r9 > 0)
  15386.     {
  15387.       sprintf (tmp_buf, "n_r9%s%d%s", sep1, molstat.n_r9, sep2);
  15388.       strcat (out_buffer, tmp_buf);
  15389.     }
  15390.   if (molstat.n_r10 > 0)
  15391.     {
  15392.       sprintf (tmp_buf, "n_r10%s%d%s", sep1, molstat.n_r10, sep2);
  15393.       strcat (out_buffer, tmp_buf);
  15394.     }
  15395.   if (molstat.n_r11 > 0)
  15396.     {
  15397.       sprintf (tmp_buf, "n_r11%s%d%s", sep1, molstat.n_r11, sep2);
  15398.       strcat (out_buffer, tmp_buf);
  15399.     }
  15400.   if (molstat.n_r12 > 0)
  15401.     {
  15402.       sprintf (tmp_buf, "n_r12%s%d%s", sep1, molstat.n_r12, sep2);
  15403.       strcat (out_buffer, tmp_buf);
  15404.     }
  15405.   if (molstat.n_r13p > 0)
  15406.     {
  15407.       sprintf (tmp_buf, "n_r13p%s%d%s", sep1, molstat.n_r13p, sep2);
  15408.       strcat (out_buffer, tmp_buf);
  15409.     }
  15410.   if (molstat.n_rN > 0)
  15411.     {
  15412.       sprintf (tmp_buf, "n_rN%s%d%s", sep1, molstat.n_rN, sep2);
  15413.       strcat (out_buffer, tmp_buf);
  15414.     }
  15415.   if (molstat.n_rN1 > 0)
  15416.     {
  15417.       sprintf (tmp_buf, "n_rN1%s%d%s", sep1, molstat.n_rN1, sep2);
  15418.       strcat (out_buffer, tmp_buf);
  15419.     }
  15420.   if (molstat.n_rN2 > 0)
  15421.     {
  15422.       sprintf (tmp_buf, "n_rN2%s%d%s", sep1, molstat.n_rN2, sep2);
  15423.       strcat (out_buffer, tmp_buf);
  15424.     }
  15425.   if (molstat.n_rN3p > 0)
  15426.     {
  15427.       sprintf (tmp_buf, "n_rN3p%s%d%s", sep1, molstat.n_rN3p, sep2);
  15428.       strcat (out_buffer, tmp_buf);
  15429.     }
  15430.   if (molstat.n_rO > 0)
  15431.     {
  15432.       sprintf (tmp_buf, "n_rO%s%d%s", sep1, molstat.n_rO, sep2);
  15433.       strcat (out_buffer, tmp_buf);
  15434.     }
  15435.   if (molstat.n_rO1 > 0)
  15436.     {
  15437.       sprintf (tmp_buf, "n_rO1%s%d%s", sep1, molstat.n_rO1, sep2);
  15438.       strcat (out_buffer, tmp_buf);
  15439.     }
  15440.   if (molstat.n_rO2p > 0)
  15441.     {
  15442.       sprintf (tmp_buf, "n_rO2p%s%d%s", sep1, molstat.n_rO2p, sep2);
  15443.       strcat (out_buffer, tmp_buf);
  15444.     }
  15445.   if (molstat.n_rS > 0)
  15446.     {
  15447.       sprintf (tmp_buf, "n_rS%s%d%s", sep1, molstat.n_rS, sep2);
  15448.       strcat (out_buffer, tmp_buf);
  15449.     }
  15450.   if (molstat.n_rX > 0)
  15451.     {
  15452.       sprintf (tmp_buf, "n_rX%s%d%s", sep1, molstat.n_rX, sep2);
  15453.       strcat (out_buffer, tmp_buf);
  15454.     }
  15455.   if (molstat.n_rAr > 0)
  15456.     {
  15457.       sprintf (tmp_buf, "n_rar%s%d%s", sep1, molstat.n_rAr, sep2);
  15458.       strcat (out_buffer, tmp_buf);
  15459.     }
  15460.  
  15461.   if (molstat.n_rBz > 0)
  15462.     {
  15463.       sprintf (tmp_buf, "n_rbz%s%d%s", sep1, molstat.n_rBz, sep2);
  15464.       strcat (out_buffer, tmp_buf);
  15465.     }
  15466.  
  15467.   if (molstat.n_br2p > 0)
  15468.     {
  15469.       sprintf (tmp_buf, "n_br2p%s%d%s", sep1, molstat.n_br2p, sep2);
  15470.       strcat (out_buffer, tmp_buf);
  15471.     }
  15472.  
  15473.   if (molstat.n_psg01 > 0)
  15474.     {
  15475.       sprintf (tmp_buf, "n_psg01%s%d%s", sep1, molstat.n_psg01, sep2);
  15476.       strcat (out_buffer, tmp_buf);
  15477.     }
  15478.  
  15479.   if (molstat.n_psg02 > 0)
  15480.     {
  15481.       sprintf (tmp_buf, "n_psg02%s%d%s", sep1, molstat.n_psg02, sep2);
  15482.       strcat (out_buffer, tmp_buf);
  15483.     }
  15484.  
  15485.   if (molstat.n_psg13 > 0)
  15486.     {
  15487.       sprintf (tmp_buf, "n_psg13%s%d%s", sep1, molstat.n_psg13, sep2);
  15488.       strcat (out_buffer, tmp_buf);
  15489.     }
  15490.  
  15491.   if (molstat.n_psg14 > 0)
  15492.     {
  15493.       sprintf (tmp_buf, "n_psg14%s%d%s", sep1, molstat.n_psg14, sep2);
  15494.       strcat (out_buffer, tmp_buf);
  15495.     }
  15496.  
  15497.   if (molstat.n_psg15 > 0)
  15498.     {
  15499.       sprintf (tmp_buf, "n_psg15%s%d%s", sep1, molstat.n_psg15, sep2);
  15500.       strcat (out_buffer, tmp_buf);
  15501.     }
  15502.  
  15503.   if (molstat.n_psg16 > 0)
  15504.     {
  15505.       sprintf (tmp_buf, "n_psg16%s%d%s", sep1, molstat.n_psg16, sep2);
  15506.       strcat (out_buffer, tmp_buf);
  15507.     }
  15508.  
  15509.   if (molstat.n_psg17 > 0)
  15510.     {
  15511.       sprintf (tmp_buf, "n_psg17%s%d%s", sep1, molstat.n_psg17, sep2);
  15512.       strcat (out_buffer, tmp_buf);
  15513.     }
  15514.  
  15515.   if (molstat.n_psg18 > 0)
  15516.     {
  15517.       sprintf (tmp_buf, "n_psg18%s%d%s", sep1, molstat.n_psg18, sep2);
  15518.       strcat (out_buffer, tmp_buf);
  15519.     }
  15520.  
  15521.   if (molstat.n_pstm > 0)
  15522.     {
  15523.       sprintf (tmp_buf, "n_pstm%s%d%s", sep1, molstat.n_pstm, sep2);
  15524.       strcat (out_buffer, tmp_buf);
  15525.     }
  15526.  
  15527.   if (molstat.n_psla > 0)
  15528.     {
  15529.       sprintf (tmp_buf, "n_psla%s%d%s", sep1, molstat.n_psla, sep2);
  15530.       strcat (out_buffer, tmp_buf);
  15531.     }
  15532.  
  15533.   if (opt_iso && molstat.n_iso > 0)
  15534.     {
  15535.       sprintf (tmp_buf, "n_iso%s%d%s", sep1, molstat.n_iso, sep2);
  15536.       strcat (out_buffer, tmp_buf);
  15537.     }
  15538.  
  15539.   if (opt_rad && molstat.n_rad > 0)
  15540.     {
  15541.       sprintf (tmp_buf, "n_rad%s%d%s", sep1, molstat.n_rad, sep2);
  15542.       strcat (out_buffer, tmp_buf);
  15543.     }
  15544. }
  15545.  
  15546. static void
  15547. write_fg_code_dll (char *out_buffer)
  15548. {
  15549.   char tmp_buf[256];
  15550.   out_buffer[0] = '\0';
  15551.   if (fg[fg_cation - 1])
  15552.     {
  15553.       sprintf (tmp_buf, "000000T2;");
  15554.       strcat (out_buffer, tmp_buf);
  15555.     }
  15556.   if (fg[fg_anion - 1])
  15557.     {
  15558.       sprintf (tmp_buf, "000000T1;");
  15559.       strcat (out_buffer, tmp_buf);
  15560.     }
  15561.  
  15562.   if (fg[fg_aldehyde - 1])
  15563.     {
  15564.       sprintf (tmp_buf, "C2O1H000;");
  15565.       strcat (out_buffer, tmp_buf);
  15566.     }
  15567.   if (fg[fg_ketone - 1])
  15568.     {
  15569.       sprintf (tmp_buf, "C2O1C000;");
  15570.       strcat (out_buffer, tmp_buf);
  15571.     }
  15572.  
  15573.   if (fg[fg_thioaldehyde - 1])
  15574.     {
  15575.       sprintf (tmp_buf, "C2S1H000;");
  15576.       strcat (out_buffer, tmp_buf);
  15577.     }
  15578.   if (fg[fg_thioketone - 1])
  15579.     {
  15580.       sprintf (tmp_buf, "C2S1C000;");
  15581.       strcat (out_buffer, tmp_buf);
  15582.     }
  15583.   if (fg[fg_imine - 1])
  15584.     {
  15585.       sprintf (tmp_buf, "C2N10000;");
  15586.       strcat (out_buffer, tmp_buf);
  15587.     }
  15588.   if (fg[fg_hydrazone - 1])
  15589.     {
  15590.       sprintf (tmp_buf, "C2N1N000;");
  15591.       strcat (out_buffer, tmp_buf);
  15592.     }
  15593.   if (fg[fg_semicarbazone - 1])
  15594.     {
  15595.       sprintf (tmp_buf, "C2NNC4ON;");
  15596.       strcat (out_buffer, tmp_buf);
  15597.     }
  15598.   if (fg[fg_thiosemicarbazone - 1])
  15599.     {
  15600.       sprintf (tmp_buf, "C2NNC4SN;");
  15601.       strcat (out_buffer, tmp_buf);
  15602.     }
  15603.   if (fg[fg_oxime - 1])
  15604.     {
  15605.       sprintf (tmp_buf, "C2N1OH00;");
  15606.       strcat (out_buffer, tmp_buf);
  15607.     }
  15608.   if (fg[fg_oxime_ether - 1])
  15609.     {
  15610.       sprintf (tmp_buf, "C2N1OC00;");
  15611.       strcat (out_buffer, tmp_buf);
  15612.     }
  15613.   if (fg[fg_ketene - 1])
  15614.     {
  15615.       sprintf (tmp_buf, "C3OC0000;");
  15616.       strcat (out_buffer, tmp_buf);
  15617.     }
  15618.   if (fg[fg_ketene_acetal_deriv - 1])
  15619.     {
  15620.       sprintf (tmp_buf, "C3OCC000;");
  15621.       strcat (out_buffer, tmp_buf);
  15622.     }
  15623.   if (fg[fg_carbonyl_hydrate - 1])
  15624.     {
  15625.       sprintf (tmp_buf, "C2O2H200;");
  15626.       strcat (out_buffer, tmp_buf);
  15627.     }
  15628.   if (fg[fg_hemiacetal - 1])
  15629.     {
  15630.       sprintf (tmp_buf, "C2O2HC00;");
  15631.       strcat (out_buffer, tmp_buf);
  15632.     }
  15633.   if (fg[fg_acetal - 1])
  15634.     {
  15635.       sprintf (tmp_buf, "C2O2CC00;");
  15636.       strcat (out_buffer, tmp_buf);
  15637.     }
  15638.   if (fg[fg_hemiaminal - 1])
  15639.     {
  15640.       sprintf (tmp_buf, "C2NOHC10;");
  15641.       strcat (out_buffer, tmp_buf);
  15642.     }
  15643.   if (fg[fg_aminal - 1])
  15644.     {
  15645.       sprintf (tmp_buf, "C2N2CC10;");
  15646.       strcat (out_buffer, tmp_buf);
  15647.     }
  15648.   if (fg[fg_thiohemiaminal - 1])
  15649.     {
  15650.       sprintf (tmp_buf, "C2NSHC10;");
  15651.       strcat (out_buffer, tmp_buf);
  15652.     }
  15653.   if (fg[fg_thioacetal - 1])
  15654.     {
  15655.       sprintf (tmp_buf, "C2S2CC00;");
  15656.       strcat (out_buffer, tmp_buf);
  15657.     }
  15658.   if (fg[fg_enamine - 1])
  15659.     {
  15660.       sprintf (tmp_buf, "C2CNH000;");
  15661.       strcat (out_buffer, tmp_buf);
  15662.     }
  15663.   if (fg[fg_enol - 1])
  15664.     {
  15665.       sprintf (tmp_buf, "C2COH000;");
  15666.       strcat (out_buffer, tmp_buf);
  15667.     }
  15668.   if (fg[fg_enolether - 1])
  15669.     {
  15670.       sprintf (tmp_buf, "C2COC000;");
  15671.       strcat (out_buffer, tmp_buf);
  15672.     }
  15673.  
  15674.  
  15675.   if (fg[fg_prim_alcohol - 1])
  15676.     {
  15677.       sprintf (tmp_buf, "O1H1C000;");
  15678.       strcat (out_buffer, tmp_buf);
  15679.     }
  15680.   if (fg[fg_sec_alcohol - 1])
  15681.     {
  15682.       sprintf (tmp_buf, "O1H2C000;");
  15683.       strcat (out_buffer, tmp_buf);
  15684.     }
  15685.   if (fg[fg_tert_alcohol - 1])
  15686.     {
  15687.       sprintf (tmp_buf, "O1H3C000;");
  15688.       strcat (out_buffer, tmp_buf);
  15689.     }
  15690.   if (fg[fg_1_2_diol - 1])
  15691.     {
  15692.       sprintf (tmp_buf, "O1H0CO1H;");
  15693.       strcat (out_buffer, tmp_buf);
  15694.     }
  15695.   if (fg[fg_1_2_aminoalcohol - 1])
  15696.     {
  15697.       sprintf (tmp_buf, "O1H0CN1C;");
  15698.       strcat (out_buffer, tmp_buf);
  15699.     }
  15700.   if (fg[fg_phenol - 1])
  15701.     {
  15702.       sprintf (tmp_buf, "O1H1A000;");
  15703.       strcat (out_buffer, tmp_buf);
  15704.     }
  15705.   if (fg[fg_1_2_diphenol - 1])
  15706.     {
  15707.       sprintf (tmp_buf, "O1H2A000;");
  15708.       strcat (out_buffer, tmp_buf);
  15709.     }
  15710.   if (fg[fg_enediol - 1])
  15711.     {
  15712.       sprintf (tmp_buf, "C2COH200;");
  15713.       strcat (out_buffer, tmp_buf);
  15714.     }
  15715.  
  15716.   if (fg[fg_dialkylether - 1])
  15717.     {
  15718.       sprintf (tmp_buf, "O1C0CC00;");
  15719.       strcat (out_buffer, tmp_buf);
  15720.     }
  15721.   if (fg[fg_alkylarylether - 1])
  15722.     {
  15723.       sprintf (tmp_buf, "O1C0CA00;");
  15724.       strcat (out_buffer, tmp_buf);
  15725.     }
  15726.   if (fg[fg_diarylether - 1])
  15727.     {
  15728.       sprintf (tmp_buf, "O1C0AA00;");
  15729.       strcat (out_buffer, tmp_buf);
  15730.     }
  15731.   if (fg[fg_thioether - 1])
  15732.     {
  15733.       sprintf (tmp_buf, "S1C00000;");
  15734.       strcat (out_buffer, tmp_buf);
  15735.     }
  15736.   if (fg[fg_disulfide - 1])
  15737.     {
  15738.       sprintf (tmp_buf, "S1S1C000;");
  15739.       strcat (out_buffer, tmp_buf);
  15740.     }
  15741.   if (fg[fg_peroxide - 1])
  15742.     {
  15743.       sprintf (tmp_buf, "O1O1C000;");
  15744.       strcat (out_buffer, tmp_buf);
  15745.     }
  15746.   if (fg[fg_hydroperoxide - 1])
  15747.     {
  15748.       sprintf (tmp_buf, "O1O1H000;");
  15749.       strcat (out_buffer, tmp_buf);
  15750.     }
  15751.   if (fg[fg_hydrazine - 1])
  15752.     {
  15753.       sprintf (tmp_buf, "N1N10000;");
  15754.       strcat (out_buffer, tmp_buf);
  15755.     }
  15756.   if (fg[fg_hydroxylamine - 1])
  15757.     {
  15758.       sprintf (tmp_buf, "N1O1H000;");
  15759.       strcat (out_buffer, tmp_buf);
  15760.     }
  15761.  
  15762.  
  15763.   if (fg[fg_prim_aliph_amine - 1])
  15764.     {
  15765.       sprintf (tmp_buf, "N1C1C000;");
  15766.       strcat (out_buffer, tmp_buf);
  15767.     }
  15768.   if (fg[fg_prim_arom_amine - 1])
  15769.     {
  15770.       sprintf (tmp_buf, "N1C1A000;");
  15771.       strcat (out_buffer, tmp_buf);
  15772.     }
  15773.  
  15774.   if (fg[fg_sec_aliph_amine - 1])
  15775.     {
  15776.       sprintf (tmp_buf, "N1C2CC00;");
  15777.       strcat (out_buffer, tmp_buf);
  15778.     }
  15779.   if (fg[fg_sec_mixed_amine - 1])
  15780.     {
  15781.       sprintf (tmp_buf, "N1C2AC00;");
  15782.       strcat (out_buffer, tmp_buf);
  15783.     }
  15784.   if (fg[fg_sec_arom_amine - 1])
  15785.     {
  15786.       sprintf (tmp_buf, "N1C2AA00;");
  15787.       strcat (out_buffer, tmp_buf);
  15788.     }
  15789.  
  15790.   if (fg[fg_tert_aliph_amine - 1])
  15791.     {
  15792.       sprintf (tmp_buf, "N1C3CC00;");
  15793.       strcat (out_buffer, tmp_buf);
  15794.     }
  15795.   if (fg[fg_tert_mixed_amine - 1])
  15796.     {
  15797.       sprintf (tmp_buf, "N1C3AC00;");
  15798.       strcat (out_buffer, tmp_buf);
  15799.     }
  15800.   if (fg[fg_tert_arom_amine - 1])
  15801.     {
  15802.       sprintf (tmp_buf, "N1C3AA00;");
  15803.       strcat (out_buffer, tmp_buf);
  15804.     }
  15805.   if (fg[fg_quart_ammonium - 1])
  15806.     {
  15807.       sprintf (tmp_buf, "N1C400T2;");
  15808.       strcat (out_buffer, tmp_buf);
  15809.     }
  15810.   if (fg[fg_n_oxide - 1])
  15811.     {
  15812.       sprintf (tmp_buf, "N0O10000;");
  15813.       strcat (out_buffer, tmp_buf);
  15814.     }
  15815.  
  15816.  
  15817.   if (fg[fg_halogen_deriv - 1])
  15818.     {
  15819.       if (!fg[fg_alkyl_halide - 1] && !fg[fg_aryl_halide - 1] &&
  15820.           !fg[fg_acyl_halide - 1])
  15821.         {
  15822.           sprintf (tmp_buf, "XX000000;");
  15823.           strcat (out_buffer, tmp_buf);
  15824.         }
  15825.     }
  15826.  
  15827.   if (fg[fg_alkyl_fluoride - 1])
  15828.     {
  15829.       sprintf (tmp_buf, "XF00C000;");
  15830.       strcat (out_buffer, tmp_buf);
  15831.     }
  15832.   if (fg[fg_alkyl_chloride - 1])
  15833.     {
  15834.       sprintf (tmp_buf, "XC00C000;");
  15835.       strcat (out_buffer, tmp_buf);
  15836.     }
  15837.   if (fg[fg_alkyl_bromide - 1])
  15838.     {
  15839.       sprintf (tmp_buf, "XB00C000;");
  15840.       strcat (out_buffer, tmp_buf);
  15841.     }
  15842.   if (fg[fg_alkyl_iodide - 1])
  15843.     {
  15844.       sprintf (tmp_buf, "XI00C000;");
  15845.       strcat (out_buffer, tmp_buf);
  15846.     }
  15847.  
  15848.   if (fg[fg_aryl_fluoride - 1])
  15849.     {
  15850.       sprintf (tmp_buf, "XF00A000;");
  15851.       strcat (out_buffer, tmp_buf);
  15852.     }
  15853.   if (fg[fg_aryl_chloride - 1])
  15854.     {
  15855.       sprintf (tmp_buf, "XC00A000;");
  15856.       strcat (out_buffer, tmp_buf);
  15857.     }
  15858.   if (fg[fg_aryl_bromide - 1])
  15859.     {
  15860.       sprintf (tmp_buf, "XB00A000;");
  15861.       strcat (out_buffer, tmp_buf);
  15862.     }
  15863.   if (fg[fg_aryl_iodide - 1])
  15864.     {
  15865.       sprintf (tmp_buf, "XI00A000;");
  15866.       strcat (out_buffer, tmp_buf);
  15867.     }
  15868.   if (fg[fg_organometallic - 1])
  15869.     {
  15870.       sprintf (tmp_buf, "000000MX;");
  15871.       strcat (out_buffer, tmp_buf);
  15872.     }
  15873.   if (fg[fg_organolithium - 1])
  15874.     {
  15875.       sprintf (tmp_buf, "000000ML;");
  15876.       strcat (out_buffer, tmp_buf);
  15877.     }
  15878.   if (fg[fg_organomagnesium - 1])
  15879.     {
  15880.       sprintf (tmp_buf, "000000MM;");
  15881.       strcat (out_buffer, tmp_buf);
  15882.     }
  15883.  
  15884.   if (fg[fg_carboxylic_acid - 1])
  15885.     {
  15886.       sprintf (tmp_buf, "C3O2H000;");
  15887.       strcat (out_buffer, tmp_buf);
  15888.     }
  15889.   if (fg[fg_carboxylic_acid_salt - 1])
  15890.     {
  15891.       sprintf (tmp_buf, "C3O200T1;");
  15892.       strcat (out_buffer, tmp_buf);
  15893.     }
  15894.   if (fg[fg_carboxylic_acid_ester - 1])
  15895.     {
  15896.       sprintf (tmp_buf, "C3O2C000;");
  15897.       strcat (out_buffer, tmp_buf);
  15898.     }
  15899.   if (fg[fg_lactone - 1])
  15900.     {
  15901.       sprintf (tmp_buf, "C3O2CZ00;");
  15902.       strcat (out_buffer, tmp_buf);
  15903.     }
  15904.  
  15905.   if (fg[fg_carboxylic_acid_prim_amide - 1])
  15906.     {
  15907.       sprintf (tmp_buf, "C3ONC100;");
  15908.       strcat (out_buffer, tmp_buf);
  15909.     }
  15910.   if (fg[fg_carboxylic_acid_sec_amide - 1])
  15911.     {
  15912.       sprintf (tmp_buf, "C3ONC200;");
  15913.       strcat (out_buffer, tmp_buf);
  15914.     }
  15915.   if (fg[fg_carboxylic_acid_tert_amide - 1])
  15916.     {
  15917.       sprintf (tmp_buf, "C3ONC300;");
  15918.       strcat (out_buffer, tmp_buf);
  15919.     }
  15920.   if (fg[fg_lactam - 1])
  15921.     {
  15922.       sprintf (tmp_buf, "C3ONCZ00;");
  15923.       strcat (out_buffer, tmp_buf);
  15924.     }
  15925.   if (fg[fg_carboxylic_acid_hydrazide - 1])
  15926.     {
  15927.       sprintf (tmp_buf, "C3ONN100;");
  15928.       strcat (out_buffer, tmp_buf);
  15929.     }
  15930.   if (fg[fg_carboxylic_acid_azide - 1])
  15931.     {
  15932.       sprintf (tmp_buf, "C3ONN200;");
  15933.       strcat (out_buffer, tmp_buf);
  15934.     }
  15935.   if (fg[fg_hydroxamic_acid - 1])
  15936.     {
  15937.       sprintf (tmp_buf, "C3ONOH00;");
  15938.       strcat (out_buffer, tmp_buf);
  15939.     }
  15940.   if (fg[fg_carboxylic_acid_amidine - 1])
  15941.     {
  15942.       sprintf (tmp_buf, "C3N2H000;");
  15943.       strcat (out_buffer, tmp_buf);
  15944.     }
  15945.   if (fg[fg_carboxylic_acid_amidrazone - 1])
  15946.     {
  15947.       sprintf (tmp_buf, "C3NNN100;");
  15948.       strcat (out_buffer, tmp_buf);
  15949.     }
  15950.   if (fg[fg_nitrile - 1])
  15951.     {
  15952.       sprintf (tmp_buf, "C3N00000;");
  15953.       strcat (out_buffer, tmp_buf);
  15954.     }
  15955.  
  15956.   if (fg[fg_acyl_fluoride - 1])
  15957.     {
  15958.       sprintf (tmp_buf, "C3OXF000;");
  15959.       strcat (out_buffer, tmp_buf);
  15960.     }
  15961.   if (fg[fg_acyl_chloride - 1])
  15962.     {
  15963.       sprintf (tmp_buf, "C3OXC000;");
  15964.       strcat (out_buffer, tmp_buf);
  15965.     }
  15966.   if (fg[fg_acyl_bromide - 1])
  15967.     {
  15968.       sprintf (tmp_buf, "C3OXB000;");
  15969.       strcat (out_buffer, tmp_buf);
  15970.     }
  15971.   if (fg[fg_acyl_iodide - 1])
  15972.     {
  15973.       sprintf (tmp_buf, "C3OXI000;");
  15974.       strcat (out_buffer, tmp_buf);
  15975.     }
  15976.   if (fg[fg_acyl_cyanide - 1])
  15977.     {
  15978.       sprintf (tmp_buf, "C2OC3N00;");
  15979.       strcat (out_buffer, tmp_buf);
  15980.     }
  15981.   if (fg[fg_imido_ester - 1])
  15982.     {
  15983.       sprintf (tmp_buf, "C3NOC000;");
  15984.       strcat (out_buffer, tmp_buf);
  15985.     }
  15986.   if (fg[fg_imidoyl_halide - 1])
  15987.     {
  15988.       sprintf (tmp_buf, "C3NXX000;");
  15989.       strcat (out_buffer, tmp_buf);
  15990.     }
  15991.  
  15992.   if (fg[fg_thiocarboxylic_acid - 1])
  15993.     {
  15994.       sprintf (tmp_buf, "C3SOH000;");
  15995.       strcat (out_buffer, tmp_buf);
  15996.     }
  15997.   if (fg[fg_thiocarboxylic_acid_ester - 1])
  15998.     {
  15999.       sprintf (tmp_buf, "C3SOC000;");
  16000.       strcat (out_buffer, tmp_buf);
  16001.     }
  16002.   if (fg[fg_thiolactone - 1])
  16003.     {
  16004.       sprintf (tmp_buf, "C3SOCZ00;");
  16005.       strcat (out_buffer, tmp_buf);
  16006.     }
  16007.   if (fg[fg_thiocarboxylic_acid_amide - 1])
  16008.     {
  16009.       sprintf (tmp_buf, "C3SNH000;");
  16010.       strcat (out_buffer, tmp_buf);
  16011.     }
  16012.   if (fg[fg_thiolactam - 1])
  16013.     {
  16014.       sprintf (tmp_buf, "C3SNCZ00;");
  16015.       strcat (out_buffer, tmp_buf);
  16016.     }
  16017.   if (fg[fg_imido_thioester - 1])
  16018.     {
  16019.       sprintf (tmp_buf, "C3NSC000;");
  16020.       strcat (out_buffer, tmp_buf);
  16021.     }
  16022.   if (fg[fg_oxohetarene - 1])
  16023.     {
  16024.       sprintf (tmp_buf, "C3ONAZ00;");
  16025.       strcat (out_buffer, tmp_buf);
  16026.     }
  16027.   if (fg[fg_thioxohetarene - 1])
  16028.     {
  16029.       sprintf (tmp_buf, "C3SNAZ00;");
  16030.       strcat (out_buffer, tmp_buf);
  16031.     }
  16032.   if (fg[fg_iminohetarene - 1])
  16033.     {
  16034.       sprintf (tmp_buf, "C3NNAZ00;");
  16035.       strcat (out_buffer, tmp_buf);
  16036.     }
  16037.   if (fg[fg_orthocarboxylic_acid_deriv - 1])
  16038.     {
  16039.       sprintf (tmp_buf, "C3O30000;");
  16040.       strcat (out_buffer, tmp_buf);
  16041.     }
  16042.   if (fg[fg_carboxylic_acid_orthoester - 1])
  16043.     {
  16044.       sprintf (tmp_buf, "C3O3C000;");
  16045.       strcat (out_buffer, tmp_buf);
  16046.     }
  16047.   if (fg[fg_carboxylic_acid_amide_acetal - 1])
  16048.     {
  16049.       sprintf (tmp_buf, "C3O3NC00;");
  16050.       strcat (out_buffer, tmp_buf);
  16051.     }
  16052.   if (fg[fg_carboxylic_acid_anhydride - 1])
  16053.     {
  16054.       sprintf (tmp_buf, "C3O2C3O2;");
  16055.       strcat (out_buffer, tmp_buf);
  16056.     }
  16057.  
  16058.   if (fg[fg_carboxylic_acid_unsubst_imide - 1])
  16059.     {
  16060.       sprintf (tmp_buf, "C3ONCH10;");
  16061.       strcat (out_buffer, tmp_buf);
  16062.     }
  16063.   if (fg[fg_carboxylic_acid_subst_imide - 1])
  16064.     {
  16065.       sprintf (tmp_buf, "C3ONCC10;");
  16066.       strcat (out_buffer, tmp_buf);
  16067.     }
  16068.   if (fg[fg_co2_deriv - 1])
  16069.     {
  16070.       sprintf (tmp_buf, "C4000000;");
  16071.       strcat (out_buffer, tmp_buf);
  16072.     }
  16073.   if (fg[fg_carbonic_acid_deriv - 1])
  16074.     {
  16075.       sprintf (tmp_buf, "C4O30000;");
  16076.       strcat (out_buffer, tmp_buf);
  16077.     }
  16078.   if (fg[fg_carbonic_acid_monoester - 1])
  16079.     {
  16080.       sprintf (tmp_buf, "C4O3C100;");
  16081.       strcat (out_buffer, tmp_buf);
  16082.     }
  16083.   if (fg[fg_carbonic_acid_diester - 1])
  16084.     {
  16085.       sprintf (tmp_buf, "C4O3C200;");
  16086.       strcat (out_buffer, tmp_buf);
  16087.     }
  16088.   if (fg[fg_carbonic_acid_ester_halide - 1])
  16089.     {
  16090.       sprintf (tmp_buf, "C4O3CX00;");
  16091.       strcat (out_buffer, tmp_buf);
  16092.     }
  16093.   if (fg[fg_thiocarbonic_acid_deriv - 1])
  16094.     {
  16095.       sprintf (tmp_buf, "C4SO0000;");
  16096.       strcat (out_buffer, tmp_buf);
  16097.     }
  16098.   if (fg[fg_thiocarbonic_acid_monoester - 1])
  16099.     {
  16100.       sprintf (tmp_buf, "C4SOC100;");
  16101.       strcat (out_buffer, tmp_buf);
  16102.     }
  16103.   if (fg[fg_thiocarbonic_acid_diester - 1])
  16104.     {
  16105.       sprintf (tmp_buf, "C4SOC200;");
  16106.       strcat (out_buffer, tmp_buf);
  16107.     }
  16108.   if (fg[fg_thiocarbonic_acid_ester_halide - 1])
  16109.     {
  16110.       sprintf (tmp_buf, "C4SOX_00;");
  16111.       strcat (out_buffer, tmp_buf);
  16112.     }
  16113.   if (fg[fg_carbamic_acid_deriv - 1])
  16114.     {
  16115.       sprintf (tmp_buf, "C4O2N000;");
  16116.       strcat (out_buffer, tmp_buf);
  16117.     }
  16118.   if (fg[fg_carbamic_acid - 1])
  16119.     {
  16120.       sprintf (tmp_buf, "C4O2NH00;");
  16121.       strcat (out_buffer, tmp_buf);
  16122.     }
  16123.   if (fg[fg_carbamic_acid_ester - 1])
  16124.     {
  16125.       sprintf (tmp_buf, "C4O2NC00;");
  16126.       strcat (out_buffer, tmp_buf);
  16127.     }
  16128.   if (fg[fg_carbamic_acid_halide - 1])
  16129.     {
  16130.       sprintf (tmp_buf, "C4O2NX00;");
  16131.       strcat (out_buffer, tmp_buf);
  16132.     }
  16133.   if (fg[fg_thiocarbamic_acid_deriv - 1])
  16134.     {
  16135.       sprintf (tmp_buf, "C4SN0000;");
  16136.       strcat (out_buffer, tmp_buf);
  16137.     }
  16138.   if (fg[fg_thiocarbamic_acid - 1])
  16139.     {
  16140.       sprintf (tmp_buf, "C4SNOH00;");
  16141.       strcat (out_buffer, tmp_buf);
  16142.     }
  16143.   if (fg[fg_thiocarbamic_acid_ester - 1])
  16144.     {
  16145.       sprintf (tmp_buf, "C4SNOC00;");
  16146.       strcat (out_buffer, tmp_buf);
  16147.     }
  16148.   if (fg[fg_thiocarbamic_acid_halide - 1])
  16149.     {
  16150.       sprintf (tmp_buf, "C4SNXX00;");
  16151.       strcat (out_buffer, tmp_buf);
  16152.     }
  16153.   if (fg[fg_urea - 1])
  16154.     {
  16155.       sprintf (tmp_buf, "C4O1N200;");
  16156.       strcat (out_buffer, tmp_buf);
  16157.     }
  16158.   if (fg[fg_isourea - 1])
  16159.     {
  16160.       sprintf (tmp_buf, "C4N2O100;");
  16161.       strcat (out_buffer, tmp_buf);
  16162.     }
  16163.   if (fg[fg_thiourea - 1])
  16164.     {
  16165.       sprintf (tmp_buf, "C4S1N200;");
  16166.       strcat (out_buffer, tmp_buf);
  16167.     }
  16168.   if (fg[fg_isothiourea - 1])
  16169.     {
  16170.       sprintf (tmp_buf, "C4N2S100;");
  16171.       strcat (out_buffer, tmp_buf);
  16172.     }
  16173.   if (fg[fg_guanidine - 1])
  16174.     {
  16175.       sprintf (tmp_buf, "C4N30000;");
  16176.       strcat (out_buffer, tmp_buf);
  16177.     }
  16178.   if (fg[fg_semicarbazide - 1])
  16179.     {
  16180.       sprintf (tmp_buf, "C4ON2N00;");
  16181.       strcat (out_buffer, tmp_buf);
  16182.     }
  16183.   if (fg[fg_thiosemicarbazide - 1])
  16184.     {
  16185.       sprintf (tmp_buf, "C4SN2N00;");
  16186.       strcat (out_buffer, tmp_buf);
  16187.     }
  16188.   if (fg[fg_azide - 1])
  16189.     {
  16190.       sprintf (tmp_buf, "N4N20000;");
  16191.       strcat (out_buffer, tmp_buf);
  16192.     }
  16193.   if (fg[fg_azo_compound - 1])
  16194.     {
  16195.       sprintf (tmp_buf, "N2N10000;");
  16196.       strcat (out_buffer, tmp_buf);
  16197.     }
  16198.   if (fg[fg_diazonium_salt - 1])
  16199.     {
  16200.       sprintf (tmp_buf, "N3N100T2;");
  16201.       strcat (out_buffer, tmp_buf);
  16202.     }
  16203.   if (fg[fg_isonitrile - 1])
  16204.     {
  16205.       sprintf (tmp_buf, "N3C10000;");
  16206.       strcat (out_buffer, tmp_buf);
  16207.     }
  16208.   if (fg[fg_cyanate - 1])
  16209.     {
  16210.       sprintf (tmp_buf, "C4NO1000;");
  16211.       strcat (out_buffer, tmp_buf);
  16212.     }
  16213.   if (fg[fg_isocyanate - 1])
  16214.     {
  16215.       sprintf (tmp_buf, "C4NO2000;");
  16216.       strcat (out_buffer, tmp_buf);
  16217.     }
  16218.   if (fg[fg_thiocyanate - 1])
  16219.     {
  16220.       sprintf (tmp_buf, "C4NS1000;");
  16221.       strcat (out_buffer, tmp_buf);
  16222.     }
  16223.   if (fg[fg_isothiocyanate - 1])
  16224.     {
  16225.       sprintf (tmp_buf, "C4NS2000;");
  16226.       strcat (out_buffer, tmp_buf);
  16227.     }
  16228.   if (fg[fg_carbodiimide - 1])
  16229.     {
  16230.       sprintf (tmp_buf, "C4N20000;");
  16231.       strcat (out_buffer, tmp_buf);
  16232.     }
  16233.   if (fg[fg_nitroso_compound - 1])
  16234.     {
  16235.       sprintf (tmp_buf, "N2O10000;");
  16236.       strcat (out_buffer, tmp_buf);
  16237.     }
  16238.   if (fg[fg_nitro_compound - 1])
  16239.     {
  16240.       sprintf (tmp_buf, "N4O20000;");
  16241.       strcat (out_buffer, tmp_buf);
  16242.     }
  16243.   if (fg[fg_nitrite - 1])
  16244.     {
  16245.       sprintf (tmp_buf, "N3O20000;");
  16246.       strcat (out_buffer, tmp_buf);
  16247.     }
  16248.   if (fg[fg_nitrate - 1])
  16249.     {
  16250.       sprintf (tmp_buf, "N4O30000;");
  16251.       strcat (out_buffer, tmp_buf);
  16252.     }
  16253.   if (fg[fg_sulfuric_acid_deriv - 1])
  16254.     {
  16255.       sprintf (tmp_buf, "S6O00000;");
  16256.       strcat (out_buffer, tmp_buf);
  16257.     }
  16258.   if (fg[fg_sulfuric_acid - 1])
  16259.     {
  16260.       sprintf (tmp_buf, "S6O4H000;");
  16261.       strcat (out_buffer, tmp_buf);
  16262.     }
  16263.   if (fg[fg_sulfuric_acid_monoester - 1])
  16264.     {
  16265.       sprintf (tmp_buf, "S6O4HC00;");
  16266.       strcat (out_buffer, tmp_buf);
  16267.     }
  16268.   if (fg[fg_sulfuric_acid_diester - 1])
  16269.     {
  16270.       sprintf (tmp_buf, "S6O4CC00;");
  16271.       strcat (out_buffer, tmp_buf);
  16272.     }
  16273.   if (fg[fg_sulfuric_acid_amide_ester - 1])
  16274.     {
  16275.       sprintf (tmp_buf, "S6O3NC00;");
  16276.       strcat (out_buffer, tmp_buf);
  16277.     }
  16278.   if (fg[fg_sulfuric_acid_amide - 1])
  16279.     {
  16280.       sprintf (tmp_buf, "S6O3N100;");
  16281.       strcat (out_buffer, tmp_buf);
  16282.     }
  16283.   if (fg[fg_sulfuric_acid_diamide - 1])
  16284.     {
  16285.       sprintf (tmp_buf, "S6O2N200;");
  16286.       strcat (out_buffer, tmp_buf);
  16287.     }
  16288.   if (fg[fg_sulfuryl_halide - 1])
  16289.     {
  16290.       sprintf (tmp_buf, "S6O3XX00;");
  16291.       strcat (out_buffer, tmp_buf);
  16292.     }
  16293.   if (fg[fg_sulfonic_acid_deriv - 1])
  16294.     {
  16295.       sprintf (tmp_buf, "S5O00000;");
  16296.       strcat (out_buffer, tmp_buf);
  16297.     }
  16298.   if (fg[fg_sulfonic_acid - 1])
  16299.     {
  16300.       sprintf (tmp_buf, "S5O3H000;");
  16301.       strcat (out_buffer, tmp_buf);
  16302.     }
  16303.   if (fg[fg_sulfonic_acid_ester - 1])
  16304.     {
  16305.       sprintf (tmp_buf, "S5O3C000;");
  16306.       strcat (out_buffer, tmp_buf);
  16307.     }
  16308.   if (fg[fg_sulfonamide - 1])
  16309.     {
  16310.       sprintf (tmp_buf, "S5O2N000;");
  16311.       strcat (out_buffer, tmp_buf);
  16312.     }
  16313.   if (fg[fg_sulfonyl_halide - 1])
  16314.     {
  16315.       sprintf (tmp_buf, "S5O2XX00;");
  16316.       strcat (out_buffer, tmp_buf);
  16317.     }
  16318.   if (fg[fg_sulfone - 1])
  16319.     {
  16320.       sprintf (tmp_buf, "S4O20000;");
  16321.       strcat (out_buffer, tmp_buf);
  16322.     }
  16323.   if (fg[fg_sulfoxide - 1])
  16324.     {
  16325.       sprintf (tmp_buf, "S2O10000;");
  16326.       strcat (out_buffer, tmp_buf);
  16327.     }
  16328.   if (fg[fg_sulfinic_acid_deriv - 1])
  16329.     {
  16330.       sprintf (tmp_buf, "S3O00000;");
  16331.       strcat (out_buffer, tmp_buf);
  16332.     }
  16333.   if (fg[fg_sulfinic_acid - 1])
  16334.     {
  16335.       sprintf (tmp_buf, "S3O2H000;");
  16336.       strcat (out_buffer, tmp_buf);
  16337.     }
  16338.   if (fg[fg_sulfinic_acid_ester - 1])
  16339.     {
  16340.       sprintf (tmp_buf, "S3O2C000;");
  16341.       strcat (out_buffer, tmp_buf);
  16342.     }
  16343.   if (fg[fg_sulfinic_acid_halide - 1])
  16344.     {
  16345.       sprintf (tmp_buf, "S3O1XX00;");
  16346.       strcat (out_buffer, tmp_buf);
  16347.     }
  16348.   if (fg[fg_sulfinic_acid_amide - 1])
  16349.     {
  16350.       sprintf (tmp_buf, "S3O1N000;");
  16351.       strcat (out_buffer, tmp_buf);
  16352.     }
  16353.   if (fg[fg_sulfenic_acid_deriv - 1])
  16354.     {
  16355.       sprintf (tmp_buf, "S1O00000;");
  16356.       strcat (out_buffer, tmp_buf);
  16357.     }
  16358.   if (fg[fg_sulfenic_acid - 1])
  16359.     {
  16360.       sprintf (tmp_buf, "S1O1H000;");
  16361.       strcat (out_buffer, tmp_buf);
  16362.     }
  16363.   if (fg[fg_sulfenic_acid_ester - 1])
  16364.     {
  16365.       sprintf (tmp_buf, "S1O1C000;");
  16366.       strcat (out_buffer, tmp_buf);
  16367.     }
  16368.   if (fg[fg_sulfenic_acid_halide - 1])
  16369.     {
  16370.       sprintf (tmp_buf, "S1O0XX00;");
  16371.       strcat (out_buffer, tmp_buf);
  16372.     }
  16373.   if (fg[fg_sulfenic_acid_amide - 1])
  16374.     {
  16375.       sprintf (tmp_buf, "S1O0N100;");
  16376.       strcat (out_buffer, tmp_buf);
  16377.     }
  16378.  
  16379.   if (fg[fg_alkylthiol - 1])
  16380.     {
  16381.       sprintf (tmp_buf, "S1H1C000;");
  16382.       strcat (out_buffer, tmp_buf);
  16383.     }
  16384.   if (fg[fg_arylthiol - 1])
  16385.     {
  16386.       sprintf (tmp_buf, "S1H1A000;");
  16387.       strcat (out_buffer, tmp_buf);
  16388.     }
  16389.   if (fg[fg_phosphoric_acid_deriv - 1])
  16390.     {
  16391.       sprintf (tmp_buf, "P5O0H000;");
  16392.       strcat (out_buffer, tmp_buf);
  16393.     }
  16394.   if (fg[fg_phosphoric_acid - 1])
  16395.     {
  16396.       sprintf (tmp_buf, "P5O4H200;");
  16397.       strcat (out_buffer, tmp_buf);
  16398.     }
  16399.   if (fg[fg_phosphoric_acid_ester - 1])
  16400.     {
  16401.       sprintf (tmp_buf, "P5O4HC00;");
  16402.       strcat (out_buffer, tmp_buf);
  16403.     }
  16404.   if (fg[fg_phosphoric_acid_halide - 1])
  16405.     {
  16406.       sprintf (tmp_buf, "P5O3HX00;");
  16407.       strcat (out_buffer, tmp_buf);
  16408.     }
  16409.   if (fg[fg_phosphoric_acid_amide - 1])
  16410.     {
  16411.       sprintf (tmp_buf, "P5O3HN00;");
  16412.       strcat (out_buffer, tmp_buf);
  16413.     }
  16414.   if (fg[fg_thiophosphoric_acid_deriv - 1])
  16415.     {
  16416.       sprintf (tmp_buf, "P5O0S000;");
  16417.       strcat (out_buffer, tmp_buf);
  16418.     }
  16419.   if (fg[fg_thiophosphoric_acid - 1])
  16420.     {
  16421.       sprintf (tmp_buf, "P5O3SH00;");
  16422.       strcat (out_buffer, tmp_buf);
  16423.     }
  16424.   if (fg[fg_thiophosphoric_acid_ester - 1])
  16425.     {
  16426.       sprintf (tmp_buf, "P5O3SC00;");
  16427.       strcat (out_buffer, tmp_buf);
  16428.     }
  16429.   if (fg[fg_thiophosphoric_acid_halide - 1])
  16430.     {
  16431.       sprintf (tmp_buf, "P5O2SX00;");
  16432.       strcat (out_buffer, tmp_buf);
  16433.     }
  16434.   if (fg[fg_thiophosphoric_acid_amide - 1])
  16435.     {
  16436.       sprintf (tmp_buf, "P5O2SN00;");
  16437.       strcat (out_buffer, tmp_buf);
  16438.     }
  16439.   if (fg[fg_phosphonic_acid_deriv - 1])
  16440.     {
  16441.       sprintf (tmp_buf, "P4O30000;");
  16442.       strcat (out_buffer, tmp_buf);
  16443.     }
  16444.   if (fg[fg_phosphonic_acid - 1])
  16445.     {
  16446.       sprintf (tmp_buf, "P4O3H000;");
  16447.       strcat (out_buffer, tmp_buf);
  16448.     }
  16449.   if (fg[fg_phosphonic_acid_ester - 1])
  16450.     {
  16451.       sprintf (tmp_buf, "P4O3C000;");
  16452.       strcat (out_buffer, tmp_buf);
  16453.     }
  16454.   if (fg[fg_phosphine - 1])
  16455.     {
  16456.       sprintf (tmp_buf, "P3000000;");
  16457.       strcat (out_buffer, tmp_buf);
  16458.     }
  16459.   if (fg[fg_phosphinoxide - 1])
  16460.     {
  16461.       sprintf (tmp_buf, "P2O00000;");
  16462.       strcat (out_buffer, tmp_buf);
  16463.     }
  16464.   if (fg[fg_boronic_acid_deriv - 1])
  16465.     {
  16466.       sprintf (tmp_buf, "B2O20000;");
  16467.       strcat (out_buffer, tmp_buf);
  16468.     }
  16469.   if (fg[fg_boronic_acid - 1])
  16470.     {
  16471.       sprintf (tmp_buf, "B2O2H000;");
  16472.       strcat (out_buffer, tmp_buf);
  16473.     }
  16474.   if (fg[fg_boronic_acid_ester - 1])
  16475.     {
  16476.       sprintf (tmp_buf, "B2O2C000;");
  16477.       strcat (out_buffer, tmp_buf);
  16478.     }
  16479.   if (fg[fg_alkene - 1])
  16480.     {
  16481.       sprintf (tmp_buf, "000C2C00;");
  16482.       strcat (out_buffer, tmp_buf);
  16483.     }
  16484.   if (fg[fg_alkyne - 1])
  16485.     {
  16486.       sprintf (tmp_buf, "000C3C00;");
  16487.       strcat (out_buffer, tmp_buf);
  16488.     }
  16489.   if (fg[fg_aromatic - 1])
  16490.     {
  16491.       sprintf (tmp_buf, "0000A000;");
  16492.       strcat (out_buffer, tmp_buf);
  16493.     }
  16494.   if (fg[fg_heterocycle - 1])
  16495.     {
  16496.       sprintf (tmp_buf, "0000CZ00;");
  16497.       strcat (out_buffer, tmp_buf);
  16498.     }
  16499.   if (fg[fg_alpha_aminoacid - 1])
  16500.     {
  16501.       sprintf (tmp_buf, "C3O2HN1C;");
  16502.       strcat (out_buffer, tmp_buf);
  16503.     }
  16504.   if (fg[fg_alpha_hydroxyacid - 1])
  16505.     {
  16506.       sprintf (tmp_buf, "C3O2HO1H;");
  16507.       strcat (out_buffer, tmp_buf);
  16508.     }
  16509. }
  16510.  
  16511. /*static void mm_elab_molstat(void)
  16512. {
  16513.                 count_neighbors();
  16514. //      init_molstat(&molstat);
  16515.         if (!found_arominfo) {
  16516.     chk_ringbonds();
  16517.     if (ringsearch_mode == rs_ssr)
  16518.       remove_redundant_rings();
  16519.     if (n_rings == max_rings) {
  16520.       if (opt_verbose)
  16521.         printf("warning: max. number of rings exceeded, reverting to SSR search\n");
  16522.       ringsearch_mode = rs_ssr;
  16523.       clear_rings();
  16524.       max_vringsize = 10;
  16525.       chk_ringbonds();
  16526.       remove_redundant_rings();
  16527.     }
  16528.    
  16529.     update_ringcount();
  16530.     update_atypes();
  16531.     update_Htotal();
  16532.     chk_arom();
  16533.  
  16534.     if (ringsearch_mode == rs_ssr) {
  16535.       do {
  16536.         prev_n_ar = count_aromatic_rings();
  16537.         chk_arom();
  16538.         n_ar = count_aromatic_rings();
  16539.       } while (prev_n_ar - n_ar != 0);
  16540.     }
  16541.         } else {
  16542.  update_atypes();
  16543.     update_Htotal();  
  16544.                
  16545.         }
  16546.  
  16547.  // get_molstat();
  16548. }*/
  16549.  
  16550. DLLEXPORT void
  16551. cm_molstat_X (char *buf)
  16552. {
  16553.   init_molstat (&molstat);
  16554. //mm_elab_molstat();
  16555.   get_molstat ();
  16556.   write_molstat_X_dll (buf);
  16557. }
  16558.  
  16559. DLLEXPORT void
  16560. cm_molstat (char *buf)
  16561. {
  16562.   init_molstat (&molstat);
  16563. //mm_elab_molstat();
  16564.   get_molstat ();
  16565.   write_molstat_dll (buf, 0);
  16566. }
  16567.  
  16568. DLLEXPORT void
  16569. cm_molstat_sql_exact (char *buf)
  16570. {
  16571.   init_molstat (&molstat);
  16572. //mm_elab_molstat();
  16573.   get_molstat ();
  16574.   write_molstat_dll (buf, 1);
  16575. }
  16576.  
  16577. DLLEXPORT void
  16578. cm_molstat_sql_substruct (char *buf)
  16579. {
  16580.   init_molstat (&molstat);
  16581. //mm_elab_molstat();
  16582.   get_molstat ();
  16583.   write_molstat_dll (buf, 2);
  16584. }
  16585.  
  16586. DLLEXPORT void
  16587. cm_fg_codes (char *buf)
  16588. {
  16589. //mm_elab_molstat();
  16590.   chk_functionalgroups ();
  16591.   write_fg_code_dll (buf);
  16592. }
  16593.  
  16594. static void
  16595. write_MDLmolfile_dll (char *out_buffer)
  16596. {
  16597.   int i;
  16598.   char tmpstr[256];
  16599.   char wline[256];
  16600.   int a_chg;
  16601.   int a_iso;
  16602.   int a_rad;
  16603.   char tmflabel[256];           /* v0.3m */
  16604.   char STR1[256], STR7[256];
  16605.   int FORLIM;
  16606.   *out_buffer = '\0';
  16607.   *tmpstr = '\0';
  16608.   *wline = '\0';
  16609.   sprintf (tmflabel, "%i", tweaklevel); /* v0.3m */
  16610.   while (strlen (tmflabel) < 2) /* v0.3m */
  16611.     sprintf (tmflabel, "0%s", strcpy (STR1, tmflabel));
  16612.   sprintf (tmflabel, "TMF%s", strcpy (STR1, tmflabel)); /* v0.3m */
  16613.   if (strlen (molname) > 80)
  16614.     sprintf (molname, "%.80s", strcpy (STR1, molname));
  16615.   strncat (out_buffer, molname, 80);
  16616.   sprintf (wline, "\n  CheckMol                        %s", tmflabel);  /* v0.3m */
  16617.   if (ringsearch_mode == rs_sar)        /* v0.3m */
  16618.     strcat (wline, ":r0");
  16619.   if (ringsearch_mode == rs_ssr)        /* v0.3m */
  16620.     strcat (wline, ":r1");
  16621.   if (opt_metalrings)
  16622.     strcat (wline, ":m1");
  16623.   else
  16624.     strcat (wline, ":m0");
  16625.   /* v0.3m */
  16626.   sprintf (tmpstr, "\n%s\n", molcomment);
  16627.   strcat (wline, tmpstr);
  16628.   sprintf (tmpstr, "%d", n_atoms);
  16629.   lblank (3L, tmpstr);
  16630.   strcat (wline, tmpstr);
  16631.   /* first 3 digits: number of atoms */
  16632.   sprintf (tmpstr, "%d", n_bonds);
  16633.   lblank (3L, tmpstr);
  16634.   strcat (wline, tmpstr);
  16635.   *tmpstr = '\0';               /* next 3 digits: number of bonds */
  16636.   strcpy (tmpstr, "  0");
  16637.   strcat (wline, tmpstr);
  16638.   /* next 3 digits: number of atom lists (not used by us) */
  16639. /* p2c: checkmol.pas, line 2388:
  16640.  * Note: Turbo Pascal conditional compilation directive was ignored [218] */
  16641. #ifdef REDUCED_SAR
  16642.   sprintf (tmpstr, "%d", n_countablerings);
  16643.   /* v0.3n; changed n_rings into n_countablerings */
  16644. #else
  16645.   sprintf (tmpstr, "%d", n_rings);
  16646. #endif
  16647.   lblank (3L, tmpstr);
  16648.   strcat (wline, tmpstr);
  16649.   /* officially "obsolete", we use it for the number of rings */
  16650.   strcat (wline, "  ");         /* v0.3n: obey chiral flag */
  16651.   if (chir_flag)
  16652.     strcat (wline, "1");
  16653.   else
  16654.     strcat (wline, "0");
  16655.   /* v0.3n */
  16656.   strcat (wline, "               999 V2000\n");
  16657.   /* v0.3n (adjust string length) */
  16658.   strcat (out_buffer, wline);
  16659.   FORLIM = n_atoms;
  16660.   for (i = 0; i < FORLIM; i++)
  16661.     {
  16662.       *wline = '\0';
  16663.       *tmpstr = '\0';
  16664.       sprintf (tmpstr, "%1.4f", atom[i].x);
  16665.       lblank (10L, tmpstr);
  16666.       strcat (wline, tmpstr);
  16667.       sprintf (tmpstr, "%1.4f", atom[i].y);
  16668.       lblank (10L, tmpstr);
  16669.       strcat (wline, tmpstr);
  16670.       sprintf (tmpstr, "%1.4f", atom[i].z);
  16671.       lblank (10L, tmpstr);
  16672.       strcat (wline, tmpstr);
  16673.       strcpy (tmpstr, atom[i].element);
  16674.       /* tmpstr := lowercase(tmpstr); REPLACE!!! */
  16675.       //tmpstr[0] = toupper (tmpstr[0]);
  16676.       all_lowercase (tmpstr);
  16677.       tmpstr[0] = toupper (tmpstr[0]);
  16678.       /*wline := wline + ' '+atom^[i].element+' '; */
  16679.       sprintf (wline + strlen (wline), " %s ", tmpstr);
  16680.       strcat (wline, " 0");     /* mass difference (isotopes) */
  16681.       /* now we code aromaticity into the old-style charge column (charges are now in the M  CHG line) */
  16682.       if (atom[i].arom)
  16683.         strcpy (tmpstr, " 00");
  16684.       else
  16685.         strcpy (tmpstr, "  0");
  16686.       strcat (wline, tmpstr);
  16687.       strcat (wline, "  0  0  0  0  0  0  0  0  0  0\n");
  16688.       strcat (out_buffer, wline);
  16689.     }
  16690.   FORLIM = n_bonds;
  16691.   for (i = 0; i < FORLIM; i++)
  16692.     {
  16693.       *wline = '\0';
  16694.       *tmpstr = '\0';
  16695.       sprintf (tmpstr, "%d", bond[i].a1);
  16696.       lblank (3L, tmpstr);
  16697.       strcat (wline, tmpstr);
  16698.       sprintf (tmpstr, "%d", bond[i].a2);
  16699.       lblank (3L, tmpstr);
  16700.       strcat (wline, tmpstr);
  16701.       if (bond[i].btype == 'S')
  16702.         strcpy (tmpstr, "  1");
  16703.       if (bond[i].btype == 'D')
  16704.         strcpy (tmpstr, "  2");
  16705.       if (bond[i].btype == 'T')
  16706.         strcpy (tmpstr, "  3");
  16707.       if (bond[i].btype == 'A')
  16708.         strcpy (tmpstr, "  4");
  16709.       if (bond[i].btype == 'l')
  16710.         strcpy (tmpstr, "  5");
  16711.       if (bond[i].btype == 's')
  16712.         strcpy (tmpstr, "  6");
  16713.       if (bond[i].btype == 'd')
  16714.         strcpy (tmpstr, "  7");
  16715.       if (bond[i].btype == 'a')
  16716.         strcpy (tmpstr, "  8");
  16717.       /* now encode our own aromaticity information */
  16718.       if (bond[i].arom)
  16719.         tmpstr[1] = '0';
  16720.       strcat (wline, tmpstr);   /* next, encode bond stereo property (v0.3f) */
  16721.       /*if (bond^[i].stereo = bstereo_up) then wline := wline + '  1' else */
  16722.       /*  if (bond^[i].stereo = bstereo_down) then wline := wline + '  6' else */
  16723.       /*    wline := wline + '  0'; */
  16724.       /* restore original value from MDL molfile (v0.3n) */
  16725.       /* wline := wline + '  ' + inttostr(bond^[i].mdl_stereo);    REPLACE!!! */
  16726.       *tmpstr = '\0';
  16727.       sprintf (tmpstr, "%i", bond[i].mdl_stereo);
  16728.       strcat (wline, "  ");
  16729.       strcat (wline, tmpstr);
  16730.       *tmpstr = '\0';
  16731.       /* now encode the ring_count of this bond (using a field which officially is "not used") */
  16732.       /* tmpstr := inttostr(bond^[i].ring_count); REPLACE!!! */
  16733.       sprintf (tmpstr, "%i", bond[i].ring_count);
  16734.       while (strlen (tmpstr) < 3)
  16735.         sprintf (tmpstr, " %s", strcpy (STR1, tmpstr));
  16736.       sprintf (wline + strlen (wline), "%s  0  0\n", tmpstr);
  16737.       strcat (out_buffer, wline);
  16738.     }
  16739.   FORLIM = n_atoms;
  16740.   for (i = 1; i <= FORLIM; i++)
  16741.     {
  16742.       a_chg = atom[i - 1].formal_charge;
  16743.       if (a_chg != 0)
  16744.         {
  16745.           strcpy (wline, "M  CHG  1 ");
  16746.           sprintf (tmpstr, "%d", i);
  16747.           lblank (3L, tmpstr);
  16748.           sprintf (wline + strlen (wline), "%s ", tmpstr);
  16749.           sprintf (tmpstr, "%d", a_chg);
  16750.           lblank (3L, tmpstr);
  16751.           strcat (wline, tmpstr);
  16752.           strcat (out_buffer, wline);
  16753.           strcat (out_buffer, "\n");
  16754.         }
  16755.     }
  16756.   for (i = 1; i <= FORLIM; i++) /* 0.3x */
  16757.     {
  16758.       a_iso = atom[i - 1].nucleon_number;
  16759.       if (a_iso != 0)
  16760.         {
  16761.           strcpy (wline, "M  ISO  1 ");
  16762.           sprintf (tmpstr, "%d", i);
  16763.           lblank (3L, tmpstr);
  16764.           sprintf (wline + strlen (wline), "%s ", tmpstr);
  16765.           sprintf (tmpstr, "%d", a_iso);
  16766.           lblank (3L, tmpstr);
  16767.           strcat (wline, tmpstr);
  16768.           strcat (out_buffer, wline);
  16769.           strcat (out_buffer, "\n");
  16770.         }
  16771.     }
  16772.   for (i = 1; i <= FORLIM; i++) /* 0.3x */
  16773.     {
  16774.       a_rad = atom[i - 1].radical_type;
  16775.       if (a_rad != 0)
  16776.         {
  16777.           strcpy (wline, "M  RAD  1 ");
  16778.           sprintf (tmpstr, "%d", i);
  16779.           lblank (3L, tmpstr);
  16780.           sprintf (wline + strlen (wline), "%s ", tmpstr);
  16781.           sprintf (tmpstr, "%d", a_rad);
  16782.           lblank (3L, tmpstr);
  16783.           strcat (wline, tmpstr);
  16784.           strcat (out_buffer, wline);
  16785.           strcat (out_buffer, "\n");
  16786.         }
  16787.     }
  16788.   strcat (out_buffer, "M  END\n");
  16789. }
  16790.  
  16791. DLLEXPORT void
  16792. cm_tweak_molfile (char *buf)
  16793. {
  16794. //chk_functionalgroups();
  16795.   write_MDLmolfile_dll (buf);
  16796. }
  16797. #endif
  16798.