Lines Matching defs:line

67   GlhLineSeg *next;     /* The next sub-string of the history line */
69 /* substring of a line, as indicated by 'next' */
85 * Each history line will be represented in the hash table by a
93 GlhLineSeg *head; /* The list of sub-strings which make up a line */
94 int len; /* The length of the line, excluding any '\0' */
98 /* a line isn't reported redundantly. */
106 static int _glh_is_line(GlhHashNode *hash, const char *line, size_t n);
107 static int _glh_line_matches_prefix(GlhHashNode *line, GlhHashNode *prefix);
108 static void _glh_return_line(GlhHashNode *hash, char *line, size_t dim);
118 static GlhHashBucket *glh_find_bucket(GlHistory *glh, const char *line,
120 static GlhHashNode *glh_find_hash_node(GlhHashBucket *bucket, const char *line,
133 long id; /* The unique identifier of this history line */
134 time_t timestamp; /* The time at which the line was archived */
136 /* the line belongs. */
137 GlhLineNode *next; /* The next youngest line in the list */
138 GlhLineNode *prev; /* The next oldest line in the list */
139 GlhHashNode *line; /* The hash-table entry of the history line */
152 GlhLineNode *head; /* The oldest line in the list */
153 GlhLineNode *tail; /* The newest line in the list */
172 GlhLineSeg *buffer; /* An array of sub-line nodes to be partitioned */
177 GlhLineNode *recall; /* The last line recalled, or NULL if no recall */
181 GlhHashNode *prefix; /* A pointer to a line containing the prefix that */
183 /* and prefix_len>0, this means that no line in */
189 int nbusy; /* The number of line segments in buffer[] that are */
191 int nfree; /* The number of line segments in buffer that are */
193 unsigned long seq; /* The next ID to assign to a line node */
210 static GlhHashNode *_glh_acquire_copy(GlHistory *glh, const char *line,
213 static int _glh_prepare_for_recall(GlHistory *glh, char *line);
217 * the characters of a segmented history line.
220 GlhLineSeg *seg; /* The line segment that the next character will */
222 int posn; /* The index in the above line segment, containing */
224 char c; /* The current character in the input line */
226 static void glh_init_stream(GlhLineStream *str, GlhHashNode *line);
234 * Match a line against a search pattern.
240 * Create a line history maintenance object.
329 * copy of a given history line. This will be resized when necessary.
390 * Append a new line to the history list, deleting old lines to make
394 * glh GlHistory * The input-line history maintenance object.
395 * line char * The line to be archived.
397 * archived. This flag requests that the line be
403 int _glh_add_history(GlHistory *glh, const char *line, int force)
405 int slen; /* The length of the line to be recorded (minus the '\0') */
407 const char *nlptr; /* A pointer to a newline character in line[] */
408 GlhHashNode *hnode; /* The hash-table node of the line */
414 if(!glh || !line) {
432 nlptr = strchr(line, '\n');
434 slen = (nlptr - line);
436 slen = strlen(line);
438 * Is the line empty?
442 empty = isspace((int)(unsigned char) line[i]);
444 * If the line is empty, don't add it to the buffer unless explicitly
456 * line without exceeding the specified line limit.
461 * We can't archive the line if the maximum number of lines allowed is
468 * Unless already stored, store a copy of the line in the history buffer,
471 hnode = _glh_acquire_copy(glh, line, slen);
473 _err_record_msg(glh->err, "No room to store history line", END_ERR_MSG);
482 * If a new line-node couldn't be allocated, discard our copy of the
483 * stored line before reporting the error.
487 _err_record_msg(glh->err, "No room to store history line", END_ERR_MSG);
492 * Record a pointer to the hash-table record of the line in the new
498 lnode->line = hnode;
510 * Record the addition of a line to the list.
517 * Recall the next oldest line that has the search prefix last recorded
521 * glh GlHistory * The input-line history maintenance object.
522 * line char * The input line buffer. On input this should contain
523 * the current input line, and on output, if anything
525 * with the matching line.
526 * dim size_t The allocated dimension of the line buffer.
528 * return char * A pointer to line[0], or NULL if not found.
530 char *_glh_find_backwards(GlHistory *glh, char *line, size_t dim)
532 GlhLineNode *node; /* The line location node being checked */
533 GlhHashNode *old_line; /* The previous recalled line */
537 if(!glh || !line) {
549 * Check the line dimensions.
551 if(dim < strlen(line) + 1) {
552 _err_record_msg(glh->err, "'dim' argument inconsistent with strlen(line)",
558 * Preserve the input line if needed.
560 if(_glh_prepare_for_recall(glh, line))
567 old_line = glh->recall->line;
574 * prefix string that differs from the last line that was recalled.
576 while(node && (node->group != glh->group || node->line == old_line ||
577 !_glh_line_matches_prefix(node->line, glh->prefix)))
580 * Was a matching line found?
589 * Copy the matching line into the provided line buffer.
591 _glh_return_line(node->line, line, dim);
595 return line;
604 * Recall the next newest line that has the search prefix last recorded
608 * glh GlHistory * The input-line history maintenance object.
609 * line char * The input line buffer. On input this should contain
610 * the current input line, and on output, if anything
612 * with the matching line.
613 * dim size_t The allocated dimensions of the line buffer.
615 * return char * The line requested, or NULL if no matching line
618 char *_glh_find_forwards(GlHistory *glh, char *line, size_t dim)
620 GlhLineNode *node; /* The line location node being checked */
621 GlhHashNode *old_line; /* The previous recalled line */
625 if(!glh || !line) {
637 * Check the line dimensions.
639 if(dim < strlen(line) + 1) {
640 _err_record_msg(glh->err, "'dim' argument inconsistent with strlen(line)",
650 old_line = glh->recall->line;
658 while(node && (node->group != glh->group || node->line == old_line ||
659 !_glh_line_matches_prefix(node->line, glh->prefix)))
662 * Was a matching line found?
666 * Copy the matching line into the provided line buffer.
668 _glh_return_line(node->line, line, dim);
674 * If we just returned the line that was being entered when the search
680 * Return the matching line to the user.
682 return line;
693 * This involves discarding the line that was temporarily saved by
698 * glh GlHistory * The input-line history maintenance object.
724 * Delete the node of the preserved line.
734 * glh GlHistory * The input-line history maintenance object.
735 * line const char * The command line who's prefix is to be used.
741 int _glh_search_prefix(GlHistory *glh, const char *line, int prefix_len)
766 glh->prefix = _glh_acquire_copy(glh, line, prefix_len);
781 * Recall the oldest recorded line.
784 * glh GlHistory * The input-line history maintenance object.
785 * line char * The input line buffer. On input this should contain
786 * the current input line, and on output, its contents
787 * will have been replaced with the oldest line.
788 * dim size_t The allocated dimensions of the line buffer.
790 * return char * A pointer to line[0], or NULL if not found.
792 char *_glh_oldest_line(GlHistory *glh, char *line, size_t dim)
794 GlhLineNode *node; /* The line location node being checked */
798 if(!glh || !line) {
810 * Check the line dimensions.
812 if(dim < strlen(line) + 1) {
813 _err_record_msg(glh->err, "'dim' argument inconsistent with strlen(line)",
819 * Preserve the input line if needed.
821 if(_glh_prepare_for_recall(glh, line))
824 * Locate the oldest line that belongs to the current group.
830 * No line found?
840 * Copy the recalled line into the provided line buffer.
842 _glh_return_line(node->line, line, dim);
844 * If we just returned the line that was being entered when the search
849 return line;
853 * Recall the line that was being entered when the search started.
856 * glh GlHistory * The input-line history maintenance object.
857 * line char * The input line buffer. On input this should contain
858 * the current input line, and on output, its contents
859 * will have been replaced with the line that was
861 * dim size_t The allocated dimensions of the line buffer.
863 * return char * A pointer to line[0], or NULL if not found.
865 char *_glh_current_line(GlHistory *glh, char *line, size_t dim)
870 if(!glh || !line) {
883 * Check the line dimensions.
885 if(dim < strlen(line) + 1) {
886 _err_record_msg(glh->err, "'dim' argument inconsistent with strlen(line)",
892 * Copy the recalled line into the provided line buffer.
894 _glh_return_line(glh->list.tail->line, line, dim);
899 return line;
903 * Query the id of a history line offset by a given number of lines from
909 * glh GlHistory * The input-line history maintenance object.
910 * offset int The line offset (0 for the current line, < 0
911 * for an older line, > 0 for a newer line.
913 * return GlhLineID The identifier of the line that is currently
919 GlhLineNode *node; /* The line location node being checked */
926 * Search forward 'offset' lines to find the required line.
943 * Recall a line by its history buffer ID. If the line is no longer
947 * glh GlHistory * The input-line history maintenance object.
948 * id GlhLineID The ID of the line to be returned.
949 * line char * The input line buffer. On input this should contain
950 * the current input line, and on output, its contents
951 * will have been replaced with the saved line.
952 * dim size_t The allocated dimensions of the line buffer.
954 * return char * A pointer to line[0], or NULL if not found.
956 char *_glh_recall_line(GlHistory *glh, GlhLineID id, char *line, size_t dim)
958 GlhLineNode *node; /* The line location node being checked */
965 * Preserve the input line if needed.
967 if(_glh_prepare_for_recall(glh, line))
970 * Search for the specified line.
979 * Record the node of the matching line as the starting point
984 * Copy the recalled line into the provided line buffer.
986 _glh_return_line(node->line, line, dim);
987 return line;
994 * glh GlHistory * The input-line history maintenance object.
998 * be recorded on a line started with this
1019 GlhLineNode *node; /* The line being saved */
1021 GlhLineSeg *seg; /* One segment of a line being saved */
1039 * that number of lines backwards, to find the first line to be saved.
1050 * associated data such as timestamps, to a line starting with the
1055 * Write peripheral information associated with the line, as a comment.
1063 * Write the history line.
1065 for(seg=node->line->head; seg; seg=seg->next) {
1089 * glh GlHistory * The input-line history maintenance object.
1144 * glh GlHistory * The input-line history maintenance object.
1149 * line char * A buffer into which lines can be read.
1150 * dim size_t The allocated dimension of line[].
1156 char *line, size_t dim)
1166 time_t timestamp; /* The timestamp of the history line */
1168 /* the line belongs. */
1169 int lineno; /* The line number being read */
1173 if(!glh || !filename || !comment || !line) {
1195 * Attempt to read each line and preceding peripheral info, and add these
1198 for(lineno=1; fgets(line, dim, fp) != NULL; lineno++) {
1199 char *lptr; /* A pointer into the input line */
1201 * Check that the line starts with the comment string.
1203 if(strncmp(line, comment, comment_len) != 0) {
1205 "Corrupt history parameter line", fp);
1210 for(lptr=line+comment_len; *lptr && (*lptr==' ' || *lptr=='\t'); lptr++)
1238 * There shouldn't be anything left on the line.
1242 "Corrupt parameter line", fp);
1245 * Now read the history line itself.
1248 if(fgets(line, dim, fp) == NULL)
1251 * Append the line to the history buffer.
1253 if(_glh_add_history(glh, line, 1)) {
1255 "Insufficient memory to record line", fp);
1258 * Record the group and timestamp information along with the line.
1282 * Convert the line number to a string.
1320 * If the time wasn't available at the time that the line was recorded
1377 * glh GlHistory * The input-line history maintenance object.
1421 * glh GlHistory * The input-line history maintenance object.
1434 * glh GlHistory * The input-line history maintenance object.
1435 * write_fn GlWriteFn * The function to call to write the line, or
1444 * line in the history buffer.
1445 * %G - The history group number of the line.
1447 * %H - The history line.
1461 GlhLineNode *node; /* The line being displayed */
1462 GlhLineNode *oldest; /* The oldest line to display */
1463 GlhLineSeg *seg; /* One segment of a line being displayed */
1505 * Find the node that follows the oldest line to be displayed.
1518 * maximum, start from the oldest line in the buffer.
1559 * Did we hit a new directive before the end of the line?
1592 case 'H': /* Display the history line */
1593 for(seg=node->line->head; seg; seg=seg->next) {
1620 * glh GlHistory * The input-line history maintenance object.
1690 int nbusy; /* The number of used line segments in the new buffer */
1692 * Starting from the oldest line in the buffer, discard lines until
1693 * the buffer contains at most 'nbuff' used line segments.
1751 * glh GlHistory * The input-line history maintenance object.
1767 * will be line number max_lines+1).
1777 GlhLineNode *oldest = node->next; /* The oldest line to be kept */
1798 * glh GlHistory * The input-line history maintenance object.
1833 * Move all line segment nodes back onto the list of unused segments.
1852 GlhLineNode *node; /* The line node being checked */
1853 GlhLineNode *next; /* The line node that follows 'node' */
1855 * Search out and delete the line nodes of the current group.
1877 * glh GlHistory * The input-line history maintenance object.
1888 * Discard a given archived input line.
1892 * node GlhLineNode * The line to be discarded, specified via its
1922 * Delete our copy of the line.
1924 node->line = _glh_discard_copy(glh, node->line);
1930 * Record the removal of a line from the list.
1937 * Lookup the details of a given history line, given its id.
1940 * glh GlHistory * The input-line history maintenance object.
1941 * id GlLineID The sequential number of the line.
1943 * line const char ** A pointer to a copy of the history line will be
1944 * assigned to *line. Beware that this pointer may
1947 * group unsigned * The group membership of the line will be assigned
1949 * timestamp time_t * The timestamp of the line will be assigned to
1952 * return int 0 - The requested line wasn't found.
1953 * 1 - The line was found.
1955 int _glh_lookup_history(GlHistory *glh, GlhLineID id, const char **line,
1958 GlhLineNode *node; /* The located line location node */
1965 * Search for the line that has the specified ID.
1974 * Has the history line been requested?
1976 if(line) {
1979 * a copy of the located line.
1981 if(node->line->len + 1 > glh->lbuf_dim) {
1982 int lbuf_dim = node->line->len + 1;
1992 * Copy the history line into the lookup buffer.
1994 _glh_return_line(node->line, glh->lbuf, glh->lbuf_dim);
1996 * Assign the lookup buffer as the returned line pointer.
1998 *line = glh->lbuf;
2001 * Does the caller want to know the group of the line?
2006 * Does the caller want to know the timestamp of the line?
2017 * glh GlHistory * The input-line history maintenance object.
2018 * id GlhLineID The ID of the line to be returned.
2063 * glh GlHistory * The input-line history maintenance object.
2090 * glh GlHistory * The input-line history maintenance object.
2093 * line in the history list will be assigned
2097 * line in the history list will be assigned
2121 * glh GlHistory * The input-line history maintenance object.
2157 * Unless already stored, store a copy of the line in the history buffer,
2162 * line const char * The history line to be recorded.
2166 * return GlhHashNode * The hash-node containing the stored line, or
2169 static GlhHashNode *_glh_acquire_copy(GlHistory *glh, const char *line,
2172 GlhHashBucket *bucket; /* The hash-table bucket of the line */
2173 GlhHashNode *hnode; /* The hash-table node of the line */
2176 * In which bucket should the line be recorded?
2178 bucket = glh_find_bucket(glh, line, n);
2180 * Is the line already recorded there?
2182 hnode = glh_find_hash_node(bucket, line, n);
2184 * If the line isn't recorded in the buffer yet, make room for it.
2187 GlhLineSeg *seg; /* A line segment */
2188 int offset; /* An offset into line[] */
2190 * How many string segments will be needed to record the new line,
2202 * If the buffer is smaller than the new line, don't attempt to truncate
2208 * Record the line in the first 'nseg' segments of the list of unused segments.
2212 memcpy(seg->s, line + offset, GLH_SEG_SIZE);
2213 memcpy(seg->s, line + offset, n-offset);
2216 * Create a new hash-node for the line.
2222 * Move the copy of the line from the list of unused segments to
2244 * Increment the reference count of the line.
2251 * Decrement the reference count of the history line of a given hash-node,
2253 * buffered copy of the line.
2267 * the reference count to zero, then the line is still in use in another
2287 * Return the line segments of the hash-node to the list of unused segments.
2290 GlhLineSeg *tail; /* The last node in the list of line segments */
2293 * Get the last node of the list of line segments referenced in the hash-node,
2294 * while counting the number of line segments used.
2299 * Prepend the list of line segments used by the hash node to the
2300 * list of unused line segments.
2317 * history line.
2325 * line const char * The historical line to look up.
2326 * n size_t The length of the line in line[], excluding
2331 static GlhHashBucket *glh_find_bucket(GlHistory *glh, const char *line,
2337 unsigned char c = line[i];
2344 * Find a given history line within a given hash-table bucket.
2348 * line const char * The historical line to lookup.
2349 * n size_t The length of the line in line[], excluding
2352 * return GlhHashNode * The hash-table entry of the line, or NULL
2355 static GlhHashNode *glh_find_hash_node(GlhHashBucket *bucket, const char *line,
2360 * Compare each of the lines in the list of lines, against 'line'.
2363 if(_glh_is_line(node, line, n))
2370 * Return non-zero if a given string is equal to a given segmented line
2374 * hash GlhHashNode * The hash-table entry of the line.
2375 * line const char * The string to be compared to the segmented
2376 * line.
2377 * n size_t The length of the line in line[], excluding
2383 static int _glh_is_line(GlhHashNode *hash, const char *line, size_t n)
2385 GlhLineSeg *seg; /* A node in the list of line segments */
2394 * of the line.
2399 if(*line++ != *s++)
2407 * Return non-zero if a given line has the specified segmented search
2411 * line GlhHashNode * The line to be compared against the prefix.
2414 * return int 0 - The line doesn't have the specified prefix.
2415 * 1 - The line has the specified prefix.
2417 static int _glh_line_matches_prefix(GlhHashNode *line, GlhHashNode *prefix)
2419 GlhLineStream lstr; /* The stream that is used to traverse 'line' */
2431 glh_init_stream(&lstr, line);
2440 * Is the prefix longer than the line being compared against it?
2442 if(prefix->len > line->len)
2445 * Compare the line to the prefix.
2459 * Copy a given history line into a specified output string.
2462 * hash GlhHashNode The hash-table entry of the history line to
2464 * line char * A copy of the history line.
2465 * dim size_t The allocated dimension of the line buffer.
2467 static void _glh_return_line(GlhHashNode *hash, char *line, size_t dim)
2469 GlhLineSeg *seg; /* A node in the list of line segments */
2474 *line++ = *s++;
2477 * If the line wouldn't fit in the output buffer, replace the last character
2481 line[-1] = '\0';
2485 * This function should be called whenever a new line recall is
2486 * attempted. It preserves a copy of the current input line in the
2491 * glh GlHistory * The input-line history maintenance object.
2492 * line char * The current contents of the input line buffer.
2497 static int _glh_prepare_for_recall(GlHistory *glh, char *line)
2501 * to the preserved copy of the input line, if the user has changed
2502 * this line, we should replace the preserved copy of the original
2503 * input line with the new one. To do this simply cancel the session,
2507 !_glh_is_line(glh->recall->line, line, strlen(line))) {
2511 * If this is the first line recall of a new recall session, save the
2512 * current line for potential recall later, and mark it as the last
2513 * line recalled.
2516 if(_glh_add_history(glh, line, 1))
2520 * The above call to _glh_add_history() will have incremented the line
2521 * sequence number, after adding the line. Since we only want this to
2533 * glh GlHistory * The input-line history maintenance object.
2545 * given history line. The first character of the line will be placed
2551 * line GlhHashNode * The history line to be iterated over (a
2555 static void glh_init_stream(GlhLineStream *str, GlhHashNode *line)
2557 str->seg = line ? line->head : NULL;
2563 * Copy the next unread character in the line being iterated, in str->c.
2564 * Once the end of the history line has been reached, all futher calls
2568 * str GlhLineStream * The history-line iterator to read from.
2573 * Get the character from the current iterator position within the line.
2578 * to the position of the next character in the line.
2603 * without worrying about line-segmentation.
2627 * Return non-zero if the history line matches a search prefix containing
2632 * the history line that is being matched.
2637 * 1 - The line matches the pattern.
2660 * rest of the line matches this.
2666 * the remaining characters of the line, attempt to match
2667 * the tail of the line against the tail of the pattern.
2675 * Restore the line and pattern iterators for a new try.
2680 * Prepare to try again, one character further into the line.
2698 * If we hit the end of the line, there is no character
2736 * To get here, pattern must have been exhausted. The line only
2737 * matches the pattern if the line as also been exhausted.