/* Return the absolute position of the node named NODENAME in BINDING. This is a brute force search, and we wish to avoid it when possible. This function is called when a tag (indirect or otherwise) doesn't really point to the right node. It returns the absolute position of the separator preceding the node. */ long find_node_in_binding (char *nodename, SEARCH_BINDING *binding) { long position; int offset, namelen; SEARCH_BINDING tmp_search; namelen = strlen (nodename); tmp_search.buffer = binding->buffer; tmp_search.start = binding->start; tmp_search.end = binding->end; tmp_search.flags = 0; while ((position = find_node_separator (&tmp_search)) != -1) { tmp_search.start = position; tmp_search.start += skip_node_separator (tmp_search.buffer + tmp_search.start); offset = string_in_line (INFO_NODE_LABEL, tmp_search.buffer + tmp_search.start); if (offset == -1) continue; tmp_search.start += offset; tmp_search.start += skip_whitespace (tmp_search.buffer + tmp_search.start); offset = skip_node_characters (tmp_search.buffer + tmp_search.start, DONT_SKIP_NEWLINES); /* Notice that this is an exact match. You cannot grovel through the buffer with this function looking for random nodes. */ if ((offset == namelen) && (tmp_search.buffer[tmp_search.start] == nodename[0]) && (strncmp (tmp_search.buffer + tmp_search.start, nodename, offset) == 0)) return position; } return -1; }
void info_parse_node (char *string, int flag) { register int i = 0; /* Default the answer. */ save_filename (NULL); save_nodename (NULL); /* Special case of nothing passed. Return nothing. */ if (!string || !*string) return; string += skip_whitespace (string); /* Check for (FILENAME)NODENAME. */ if (*string == '(') { int bcnt; int bfirst; i = 0; /* Advance past the opening paren. */ string++; /* Find the closing paren. Handle nested parens correctly. */ for (bcnt = 0, bfirst = -1; string[i]; i++) { if (string[i] == ')') { if (bcnt == 0) { bfirst = -1; break; } else if (!bfirst) bfirst = i; bcnt--; } else if (string[i] == '(') bcnt++; } if (bfirst >= 0) i = bfirst; /* Remember parsed filename. */ saven_filename (string, i); /* Point directly at the nodename. */ string += i; if (*string) string++; } /* Parse out nodename. */ i = skip_node_characters (string, flag); saven_nodename (string, i); canonicalize_whitespace (info_parsed_nodename); if (info_parsed_nodename && !*info_parsed_nodename) { free (info_parsed_nodename); info_parsed_nodename = NULL; } /* Parse ``(line ...)'' part of menus, if any. */ { char *rest = string + i; /* Advance only if it's not already at end of string. */ if (*rest) rest++; /* Skip any whitespace first, and then a newline in case the item was so long to contain the ``(line ...)'' string in the same physical line. */ while (whitespace(*rest)) rest++; if (*rest == '\n') { rest++; while (whitespace(*rest)) rest++; } /* Are we looking at an opening parenthesis? That can only mean we have a winner. :) */ if (strncmp (rest, "(line ", strlen ("(line ")) == 0) { rest += strlen ("(line "); info_parsed_line_number = strtol (rest, NULL, 0); } else info_parsed_line_number = 0; } }