1 /* Copyright (C) 2003 Damir Zucic */
2
3 /*=============================================================================
4
5 parse_pattern.c
6
7 Purpose:
8 Parse the pattern. Pattern consists of residue name sets; each
9 set contains a number of residue names.
10
11 Input:
12 (1) Pointer to RuntimeS structure.
13 (2) Pointer to the string which contains the pattern.
14
15 Output:
16 (1) Sequence stored to the pattern buffer.
17 (2) Return value.
18
19 Return value:
20 (1) Positive on success.
21 (2) Negative on failure.
22
23 Notes:
24 (1) The pattern is expected in three letters code. One letter
25 code may be missinterpreted as valid three letters code.
26 To each position a set of residues is assigned. Use slash
27 to separate sets.
28
29 (2) Space, comma, tab and semicolon may be used as separators.
30
31 ========includes:============================================================*/
32
33 #include <stdio.h>
34
35 #include <string.h>
36
37 #include <X11/Xlib.h>
38 #include <X11/Xutil.h>
39 #include <X11/Xos.h>
40 #include <X11/Xatom.h>
41
42 #include "defines.h"
43 #include "commands.h"
44 #include "typedefs.h"
45
46 /*======function prototypes:=================================================*/
47
48 char *ExtractToken_ (char *, int, char *, char *);
49
50 /*======parse pattern:=======================================================*/
51
ParsePattern_(RuntimeS * runtimeSP,char * stringP)52 int ParsePattern_ (RuntimeS *runtimeSP, char *stringP)
53 {
54 int max_length, i;
55 char *remaining_stringP;
56 char tokenA[STRINGSIZE];
57 int setI = 0;
58 int residue_names_in_setN = 0;
59 int global_residueI = 0;
60 char *P;
61 char *remaining_substringP;
62 char subtokenA[SHORTSTRINGSIZE];
63
64 /* The maximal residue name length: */
65 max_length = RESNAMESIZE - 1;
66
67 /* Reset the pattern length: */
68 runtimeSP->pattern_length = 0;
69
70 /* Zero initialize the pattern buffer: */
71 for (i = 0; i < (int) runtimeSP->pattern_buffer_size; i++)
72 {
73 *(runtimeSP->patternP + i) = '\0';
74 }
75
76 /* Reset the array with the number of residues per set: */
77 for (i = 0; i < MAX_PATT_LENGTH; i++)
78 {
79 runtimeSP->namesNA[i] = 0;
80 }
81
82 /* Reset the total number of residues in pattern: */
83 runtimeSP->residues_in_patternN = 0;
84
85 /* Extract the tokens separated by slash, newline and */
86 /* end of line. These tokens are called residue sets. */
87 remaining_stringP = stringP;
88 while ((remaining_stringP = ExtractToken_ (tokenA, STRINGSIZE,
89 remaining_stringP, "/\n")) != NULL)
90 {
91 /* If this token contains wildcard, treat this set */
92 /* as the set which contains only one element: */
93 if (strstr (tokenA, "*") != NULL)
94 {
95 /* Copy the residue name to the pattern buffer: */
96 P = runtimeSP->patternP + max_length * global_residueI;
97 *P = '*';
98
99 /* This set contains only one residue name: */
100 runtimeSP->namesNA[setI] = 1;
101 }
102
103 /* Reset the local number of residue names in set: */
104 residue_names_in_setN = 0;
105
106 /* Parse the token to subtokens, separated by space, comma, */
107 /* semicolon, tab, newline and end of line. These subtokens */
108 /* should contain valid residue names (three letters code). */
109 remaining_substringP = tokenA;
110 while ((remaining_substringP = ExtractToken_ (subtokenA,
111 SHORTSTRINGSIZE,
112 remaining_substringP,
113 " ,;\t\n")) != NULL)
114 {
115 /* Check the residue name size: */
116 if ((int) strlen (subtokenA) > max_length)
117 {
118 sprintf (runtimeSP->messageA,
119 "Residue name %s too long!",
120 subtokenA);
121 runtimeSP->message_length =
122 strlen (runtimeSP->messageA);
123 return -1;
124 }
125
126 /* Copy the residue name to the pattern buffer: */
127 P = runtimeSP->patternP + max_length * global_residueI;
128 strcpy (P, subtokenA);
129
130 /* Increment the local number of residue names in set: */
131 residue_names_in_setN++;
132
133 /* Do not allow too many residue names in this set: */
134 if (residue_names_in_setN >= MAX_NAMES_IN_SET)
135 {
136 sprintf (runtimeSP->messageA,
137 "Too many residues in set!");
138 runtimeSP->message_length =
139 strlen (runtimeSP->messageA);
140 return -2;
141 }
142
143 /* Increment the global (cumulative) residue index: */
144 global_residueI++;
145
146 /* Do not allow array overflow: */
147 if (global_residueI >= MAX_RES_IN_PATT)
148 {
149 sprintf (runtimeSP->messageA, "Too many residues!");
150 runtimeSP->message_length =
151 strlen (runtimeSP->messageA);
152 return -3;
153 }
154 }
155
156 /* Store the number of residues in this set: */
157 runtimeSP->namesNA[setI] = residue_names_in_setN;
158
159 /* Increment the residue set index: */
160 setI++;
161
162 /* Do not allow array overflow: */
163 if (setI >= MAX_PATT_LENGTH)
164 {
165 sprintf (runtimeSP->messageA, "Pattern is too long!");
166 runtimeSP->message_length = strlen (runtimeSP->messageA);
167 return -4;
168 }
169 }
170
171 /* Store the total number of sets (the pattern length): */
172 runtimeSP->pattern_length = setI;
173
174 /* Store the total number of residues in pattern: */
175 runtimeSP->residues_in_patternN = global_residueI;
176
177 /* Return positive value on success: */
178 return 1;
179 }
180
181 /*===========================================================================*/
182
183
184