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