| 1204 | `------------------------------------------------------------------*/ |
| 1205 | |
| 1206 | static void |
| 1207 | define_all_fields (OCCURS *occurs) |
| 1208 | { |
| 1209 | ptrdiff_t tail_max_width; /* allowable width of tail field */ |
| 1210 | ptrdiff_t head_max_width; /* allowable width of head field */ |
| 1211 | char *cursor; /* running cursor in source text */ |
| 1212 | char *left_context_start; /* start of left context */ |
| 1213 | char *right_context_end; /* end of right context */ |
| 1214 | char *left_field_start; /* conservative start for 'head'/'before' */ |
| 1215 | char const *file_name; /* file name for reference */ |
| 1216 | intmax_t line_ordinal; /* line ordinal for reference */ |
| 1217 | char const *buffer_start; /* start of buffered file for this occurs */ |
| 1218 | char const *buffer_end; /* end of buffered file for this occurs */ |
| 1219 | |
| 1220 | /* Define 'keyafter', start of left context and end of right context. |
| 1221 | 'keyafter' starts at the saved position for keyword and extend to the |
| 1222 | right from the end of the keyword, eating separators or full words, but |
| 1223 | not beyond maximum allowed width for 'keyafter' field or limit for the |
| 1224 | right context. Suffix spaces will be removed afterwards. */ |
| 1225 | |
| 1226 | keyafter.start = occurs->key.start; |
| 1227 | keyafter.end = keyafter.start + occurs->key.size; |
| 1228 | left_context_start = keyafter.start + occurs->left; |
| 1229 | right_context_end = keyafter.start + occurs->right; |
| 1230 | |
| 1231 | buffer_start = text_buffers[occurs->file_index].start; |
| 1232 | buffer_end = text_buffers[occurs->file_index].end; |
| 1233 | |
| 1234 | cursor = keyafter.end; |
| 1235 | while (cursor < right_context_end |
| 1236 | && cursor <= keyafter.start + keyafter_max_width) |
| 1237 | { |
| 1238 | keyafter.end = cursor; |
| 1239 | SKIP_SOMETHING (cursor, right_context_end); |
| 1240 | } |
| 1241 | if (cursor <= keyafter.start + keyafter_max_width) |
| 1242 | keyafter.end = cursor; |
| 1243 | |
| 1244 | keyafter_truncation = truncation_string && keyafter.end < right_context_end; |
| 1245 | |
| 1246 | SKIP_WHITE_BACKWARDS (keyafter.end, keyafter.start); |
| 1247 | |
| 1248 | /* When the left context is wide, it might take some time to catch up from |
| 1249 | the left context boundary to the beginning of the 'head' or 'before' |
| 1250 | fields. So, in this case, to speed the catchup, we jump back from the |
| 1251 | keyword, using some secure distance, possibly falling in the middle of |
| 1252 | a word. A secure backward jump would be at least half the maximum |
| 1253 | width of a line, plus the size of the longest word met in the whole |
| 1254 | input. We conclude this backward jump by a skip forward of at least |
| 1255 | one word. In this manner, we should not inadvertently accept only part |
| 1256 | of a word. From the reached point, when it will be time to fix the |
| 1257 | beginning of 'head' or 'before' fields, we will skip forward words or |
| 1258 | delimiters until we get sufficiently near. */ |
| 1259 | |
| 1260 | if (-occurs->left > half_line_width + maximum_word_length) |
| 1261 | { |
| 1262 | left_field_start |
| 1263 | = keyafter.start - (half_line_width + maximum_word_length); |
no outgoing calls
no test coverage detected