in contrib/champ/champ.c [2867:3574]
int ChampParseAtomBlock(CChamp *I,char **c_ptr,int cur_atom)
{
int ok = true;
ListAtom *at;
char *c;
int not_flag = false;
int num;
int done=false;
int atom_seen = false;
/* int done;*/
c=*c_ptr;
at=I->Atom+cur_atom;
at->comp_imp_hydro_flag = false;
while(ok&&!done) {
switch(*c) {
case ']':
done=true;
c++;
break;
case 0:
done=true;
break;
case '!':
c++;
not_flag=true;
atom_seen = false;
break;
case ',':
c++;
atom_seen = false;
break;
case ';':
not_flag=false;
c++;
atom_seen = false;
break;
case '*': /* nonstandard */
c = ChampParseBlockAtom(I,c,cur_atom,cH_Any,1,not_flag);
atom_seen = true;
break;
case '?': /* nonstandard */
c = ChampParseBlockAtom(I,c,cur_atom,cH_NotH,1,not_flag);
atom_seen = true;
break;
case '@':
num = ChampParseNumeral(c+1);
if(num>=0) {
c+=2;
} else {
num = 1;
c++;
while(*c) {
if(*c!='@')
break;
else {
num++;
c++;
}
}
}
if(num&0x1) /* odd */
I->Atom[cur_atom].stereo = cH_Anticlock;
else
I->Atom[cur_atom].stereo = cH_Clockwise;
break;
case 'A': /* note there is no way to address the 'A' symbol ...*/
switch(*(c+1)) {
case 'c':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'g':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'l':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'm':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 's':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'u':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_class|=cH_Aliphatic;
} else {
I->Atom[cur_atom].pos_flag=true;
I->Atom[cur_atom].class|=cH_Aliphatic;
}
c++;
}
break;
case 'a':
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_class|=cH_Aromatic;
} else {
I->Atom[cur_atom].class|=cH_Aromatic;
I->Atom[cur_atom].pos_flag=true;
}
c++;
break;
case 'B':
switch(*(c+1)) {
case 'a':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'i':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Br,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_B,1,not_flag);
atom_seen = true;
break;
}
break;
case 'C':
switch(*(c+1)) {
case 'a':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Ca,2,not_flag);
atom_seen = true;
break;
case 'd':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'o':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 's':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'u':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Cu,2,not_flag);
atom_seen = true;
break;
case 'l':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Cl,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_C,1,not_flag);
atom_seen = true;
break;
}
break;
case 'D':
switch(*(c+1)) {
case 'y':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
num = ChampParseNumeral(c+1);
if(num>=0) {
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_degree|=num_to_degree[num];
} else {
I->Atom[cur_atom].pos_flag=true;
I->Atom[cur_atom].degree|=num_to_degree[num];
}
c+=2;
} else
ok=false;
break;
}
break;
case 'E':
switch(*(c+1)) {
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'u':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_E,1,not_flag);
atom_seen = true;
break;
}
break;
case 'F':
switch(*(c+1)) {
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Fe,2,not_flag);
atom_seen = true;
break;
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_F,1,not_flag);
atom_seen = true;
break;
}
break;
case 'G':
switch(*(c+1)) {
case 'a':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'd':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
}
break;
case 'H':
switch(*(c+1)) {
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'f':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'g':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'o':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
if(!atom_seen) {
c = ChampParseBlockAtom(I,c,cur_atom,cH_H,1,not_flag);
atom_seen = true;
} else {
num = ChampParseNumeral(c+1);
if(num>=0) {
c+=2;
} else {
num = 1;
c++;
while(*c) {
if(*c!='H')
break;
else {
num++;
c++;
}
}
}
I->Atom[cur_atom].imp_hydro = num;
I->Atom[cur_atom].tot_hydro = num;
I->Atom[cur_atom].hydro_flag = true;
/* turn on hydrogen count matching for this atom */
}
break;
}
break;
case 'I':
switch(*(c+1)) {
case 'n':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_I,1,not_flag);
atom_seen = true;
break;
}
break;
case 'J':
c = ChampParseBlockAtom(I,c,cur_atom,cH_J,1,not_flag);
atom_seen = true;
break;
case 'K':
c = ChampParseBlockAtom(I,c,cur_atom,cH_K,1,not_flag);
atom_seen = true;
break;
case 'L':
switch(*(c+1)) {
case 'a':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'i':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'u':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_L,1,not_flag);
atom_seen = true;
}
break;
case 'M':
switch(*(c+1)) {
case 'n':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'o':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'g':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Mg,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_M,1,not_flag);
atom_seen = true;
break;
}
break;
case 'N':
switch(*(c+1)) {
case 'a':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Na,2,not_flag);
atom_seen = true;
break;
case 'b':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'd':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'i':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_N,1,not_flag);
atom_seen = true;
break;
}
break;
case 'O':
switch(*(c+1)) {
case 's':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_O,1,not_flag);
atom_seen = true;
break;
}
break;
case 'P':
switch(*(c+1)) {
case 'b':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'd':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'o':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 't':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_P,1,not_flag);
atom_seen = true;
}
break;
case 'p': /* Pi system */
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_class|=cH_Pi;
} else {
I->Atom[cur_atom].pos_flag=true;
I->Atom[cur_atom].class|=cH_Pi;
}
c++;
break;
case 'R':
switch(*(c+1)) {
case 'b':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'h':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'u':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_R,1,not_flag);
atom_seen = true;
break;
}
break;
case 'r':
num = ChampParseNumeral(c+1);
if(num>=0) {
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_cycle|=num_to_ring[num];
} else {
I->Atom[cur_atom].pos_flag=true;
I->Atom[cur_atom].cycle|=num_to_ring[num];
}
c+=2;
} else {
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_cycle|=cH_Ring3|cH_Ring4|cH_Ring5|cH_Ring6|cH_Ring7|cH_Ring8;
} else {
I->Atom[cur_atom].pos_flag=true;
I->Atom[cur_atom].cycle|=cH_Ring3|cH_Ring4|cH_Ring5|cH_Ring6|cH_Ring7|cH_Ring8;
}
c++;
}
break;
case 'Q':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Q,1,not_flag);
atom_seen = true;
break;
case 'S':
switch(*(c+1)) {
case 'b':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'c':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Se,2,not_flag);
atom_seen = true;
break;
case 'i':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'm':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'n':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_S,1,not_flag);
atom_seen = true;
break;
}
break;
case 'T':
switch(*(c+1)) {
case 'a':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'b':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'e':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'i':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'h':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'l':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'm':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_T,1,not_flag);
atom_seen = true;
}
break;
case 'V':
switch(*(c+1)) {
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,1,not_flag);
atom_seen = true;
}
break;
case 'v':
num = ChampParseNumeral(c+1);
if(num>=0) {
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
I->Atom[cur_atom].not_valence|=num_to_valence[num];
} else {
I->Atom[cur_atom].pos_flag=true;
I->Atom[cur_atom].degree|=num_to_valence[num];
}
c+=2;
} else
ok=false;
break;
case 'W':
switch(*(c+1)) {
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,1,not_flag);
atom_seen = true;
break;
}
break;
case 'U':
switch(*(c+1)) {
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,1,not_flag);
atom_seen = true;
break;
}
break;
case 'Y':
switch(*(c+1)) {
case 'b':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,1,not_flag);
atom_seen = true;
break;
}
break;
case 'Z':
switch(*(c+1)) {
case 'r':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Sym,2,not_flag);
atom_seen = true;
break;
case 'n':
c = ChampParseBlockAtom(I,c,cur_atom,cH_Zn,2,not_flag);
atom_seen = true;
break;
default:
c = ChampParseBlockAtom(I,c,cur_atom,cH_Z,1,not_flag);
atom_seen = true;
break;
}
break;
case '+':
num = ChampParseNumeral(c+1);
if(num>=0) {
c+=2;
} else {
num = 1;
c++;
while(*c) {
if(*c!='+')
break;
else {
num++;
c++;
}
}
}
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
switch(num) {
case 0: I->Atom[cur_atom].not_charge|=cH_Neutral; break;
case 1: I->Atom[cur_atom].not_charge|=cH_Cation; break;
case 2: I->Atom[cur_atom].not_charge|=cH_Dication; break;
case 3: I->Atom[cur_atom].not_charge|=cH_Trication; break;
case 4: I->Atom[cur_atom].not_charge|=cH_Tetcation; break;
case 5: I->Atom[cur_atom].not_charge|=cH_Pentcation; break;
}
} else {
I->Atom[cur_atom].pos_flag=true;
switch(num) {
case 0: I->Atom[cur_atom].charge|=cH_Neutral; break;
case 1: I->Atom[cur_atom].charge|=cH_Cation; break;
case 2: I->Atom[cur_atom].charge|=cH_Dication; break;
case 3: I->Atom[cur_atom].charge|=cH_Trication; break;
case 4: I->Atom[cur_atom].charge|=cH_Tetcation; break;
case 5: I->Atom[cur_atom].charge|=cH_Pentcation; break;
}
}
break;
case '-':
num = ChampParseNumeral(c+1);
if(num>=0) {
c+=2;
} else {
num = 1;
c++;
while(*c) {
if(*c!='-')
break;
else {
num++;
c++;
}
}
}
if(not_flag) {
I->Atom[cur_atom].neg_flag=true;
switch(num) {
case 0: I->Atom[cur_atom].not_charge|=cH_Neutral; break;
case 1: I->Atom[cur_atom].not_charge|=cH_Anion; break;
case 2: I->Atom[cur_atom].not_charge|=cH_Dianion; break;
case 3: I->Atom[cur_atom].not_charge|=cH_Trianion; break;
case 4: I->Atom[cur_atom].not_charge|=cH_Tetanion; break;
case 5: I->Atom[cur_atom].not_charge|=cH_Pentanion; break;
}
} else {
I->Atom[cur_atom].pos_flag=true;
switch(num) {
case 0: I->Atom[cur_atom].charge|=cH_Neutral; break;
case 1: I->Atom[cur_atom].charge|=cH_Anion; break;
case 2: I->Atom[cur_atom].charge|=cH_Dianion; break;
case 3: I->Atom[cur_atom].charge|=cH_Trianion; break;
case 4: I->Atom[cur_atom].charge|=cH_Tetanion; break;
case 5: I->Atom[cur_atom].charge|=cH_Pentanion; break;
}
}
break;
default:
PRINTFB(FB_smiles_parsing,FB_errors)
" champ: error parsing atom block at '%c' in: '%s'\n",*c,*c_ptr
ENDFB;
c++;
break;
}
}
*c_ptr = c;
return ok;
}