Links/Find_Link [ Functions ]
NAME
Find_Link -- try to match word with a link
FUNCTION
Searches for the given word in the list of links and headers. There are three passes (or four, when the C option is selected). Each pass uses a different definition of "word":
- In the first pass it is any thing that ends with a 'space', a '.' or a ','.
- In the second pass it is any string that consists of alpha numerics, '_', ':', '.', or '-'.
- In the third pass (for C) it is any string that consists of alpha numerics or '_'.
SYNOPSIS
int Find_Link( char *word_begin, char **object_name, char **label_name, char **file_name )
INPUTS
- word_begin - pointer to a word (a string).
- object_name - pointer to a pointer to a string
- file_name - pointer to a pointer to a string
SIDE EFFECTS
label_name & file_name are modified
RESULT
- object_name -- points to the object if a match was found, NULL otherwise.
- file_name -- points to the file name if a match was found, NULL otherwise.
- label_name -- points to the labelname if a match was found,
- TRUE -- a match was found.
- FALSE -- no match was found.
NOTES
This is a rather sensitive algorithm. Don't mess with it too much.
SOURCE
{ char *cur_char = NULL, old_char; int low_index, high_index, cur_index, state, pass; unsigned int length = 0; for ( pass = 0; pass < 3; pass++ ) { switch ( pass ) { case 0: { for ( cur_char = word_begin; ( *cur_char == '_' ) || utf8_isalnum( *cur_char ) || utf8_ispunct( *cur_char ); cur_char++ ); break; } case 1: { for ( cur_char = word_begin; utf8_isalnum( *cur_char ) || ( *cur_char == '_' ) || ( *cur_char == '-' ) || ( *cur_char == '.' ) || ( *cur_char == ':' ); cur_char++ ); break; } case 2: { for ( cur_char = word_begin; utf8_isalnum( *cur_char ) || ( *cur_char == '_'); cur_char++ ); break; } } if ( ( ( *( cur_char - 1 ) ) == ',' ) || ( ( *( cur_char - 1 ) ) == '.' ) ) { cur_char--; } old_char = *cur_char; *cur_char = '\0'; /* * End the word with a '\0' */ if ( strlen( word_begin ) == length ) { /* Do not test the same word over and over. If * the current string and the string of the previous * pass are the same length, they are the same. */ /* RB_Say ("Skipping (pass %d) \"%s\"\n", SAY_INFO, pass, word_begin); */ } else { length = strlen( word_begin ); /* RB_Say ("Testing (pass %d) \"%s\"\n", SAY_INFO, pass, word_begin); */ /* * Search case sensitive for a link */ for ( cur_index = 0, low_index = 0, high_index = link_index_size - 1; high_index >= low_index; ) { cur_index = ( high_index - low_index ) / 2 + low_index; state = strcmp( word_begin, case_sensitive_link_index[cur_index]->object_name ); if ( state < 0 ) { high_index = cur_index - 1; } else if ( state == 0 ) { *object_name = case_sensitive_link_index[cur_index]->object_name; *label_name = case_sensitive_link_index[cur_index]->label_name; *file_name = case_sensitive_link_index[cur_index]->file_name; RB_Say( "linking \"%s\"->\"%s\" from \"%s\"\n", SAY_DEBUG, word_begin, *object_name, *file_name ); *cur_char = old_char; return ( TRUE ); } else if ( state > 0 ) { low_index = cur_index + 1; } } /* * Search case insensitive for a link. * But only when the user asks for this. */ if ( course_of_action.do_ignore_case_when_linking ) { for ( cur_index = 0, low_index = 0, high_index = link_index_size - 1; high_index >= low_index; ) { cur_index = ( high_index - low_index ) / 2 + low_index; state = RB_Str_Case_Cmp( word_begin, link_index[cur_index]->object_name ); if ( state < 0 ) { high_index = cur_index - 1; } else if ( state == 0 ) { *object_name = link_index[cur_index]->object_name; *label_name = link_index[cur_index]->label_name; *file_name = link_index[cur_index]->file_name; RB_Say( "linking \"%s\"->\"%s\" from \"%s\"\n", SAY_DEBUG, word_begin, *object_name, *file_name ); *cur_char = old_char; return ( TRUE ); } else if ( state > 0 ) { low_index = cur_index + 1; } } } } *cur_char = old_char; *file_name = NULL; *object_name = NULL; *label_name = NULL; } return ( FALSE ); }