OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [readline/] [history.c] - Blame information for rev 817

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* history.c -- standalone history library */
2
 
3
/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
4
 
5
   This file contains the GNU History Library (the Library), a set of
6
   routines for managing the text of previously typed lines.
7
 
8
   The Library is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2, or (at your option)
11
   any later version.
12
 
13
   The Library is distributed in the hope that it will be useful, but
14
   WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
   General Public License for more details.
17
 
18
   The GNU General Public License is often shipped with GNU software, and
19
   is generally kept in a file called COPYING or LICENSE.  If you do not
20
   have a copy of the license, write to the Free Software Foundation,
21
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22
 
23
/* The goal is to make the implementation transparent, so that you
24
   don't have to know what data types are used, just what functions
25
   you can call.  I think I have done that. */
26
#define READLINE_LIBRARY
27
 
28
#if defined (HAVE_CONFIG_H)
29
#  include <config.h>
30
#endif
31
 
32
#include <stdio.h>
33
 
34
#if defined (HAVE_STDLIB_H)
35
#  include <stdlib.h>
36
#else
37
#  include "ansi_stdlib.h"
38
#endif /* HAVE_STDLIB_H */
39
 
40
#if defined (HAVE_UNISTD_H)
41
#  ifdef _MINIX
42
#    include <sys/types.h>
43
#  endif
44
#  include <unistd.h>
45
#endif
46
 
47
#include "history.h"
48
#include "histlib.h"
49
 
50
#include "xmalloc.h"
51
 
52
/* The number of slots to increase the_history by. */
53
#define DEFAULT_HISTORY_GROW_SIZE 50
54
 
55
static char *hist_inittime PARAMS((void));
56
 
57
/* **************************************************************** */
58
/*                                                                  */
59
/*                      History Functions                           */
60
/*                                                                  */
61
/* **************************************************************** */
62
 
63
/* An array of HIST_ENTRY.  This is where we store the history. */
64
static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
65
 
66
/* Non-zero means that we have enforced a limit on the amount of
67
   history that we save. */
68
static int history_stifled;
69
 
70
/* The current number of slots allocated to the input_history. */
71
static int history_size;
72
 
73
/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
74
   entries to remember. */
75
int history_max_entries;
76
int max_input_history;  /* backwards compatibility */
77
 
78
/* The current location of the interactive history pointer.  Just makes
79
   life easier for outside callers. */
80
int history_offset;
81
 
82
/* The number of strings currently stored in the history list. */
83
int history_length;
84
 
85
/* The logical `base' of the history array.  It defaults to 1. */
86
int history_base = 1;
87
 
88
/* Return the current HISTORY_STATE of the history. */
89
HISTORY_STATE *
90
history_get_history_state ()
91
{
92
  HISTORY_STATE *state;
93
 
94
  state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
95
  state->entries = the_history;
96
  state->offset = history_offset;
97
  state->length = history_length;
98
  state->size = history_size;
99
  state->flags = 0;
100
  if (history_stifled)
101
    state->flags |= HS_STIFLED;
102
 
103
  return (state);
104
}
105
 
106
/* Set the state of the current history array to STATE. */
107
void
108
history_set_history_state (state)
109
     HISTORY_STATE *state;
110
{
111
  the_history = state->entries;
112
  history_offset = state->offset;
113
  history_length = state->length;
114
  history_size = state->size;
115
  if (state->flags & HS_STIFLED)
116
    history_stifled = 1;
117
}
118
 
119
/* Begin a session in which the history functions might be used.  This
120
   initializes interactive variables. */
121
void
122
using_history ()
123
{
124
  history_offset = history_length;
125
}
126
 
127
/* Return the number of bytes that the primary history entries are using.
128
   This just adds up the lengths of the_history->lines and the associated
129
   timestamps. */
130
int
131
history_total_bytes ()
132
{
133
  register int i, result;
134
 
135
  for (i = result = 0; the_history && the_history[i]; i++)
136
    result += HISTENT_BYTES (the_history[i]);
137
 
138
  return (result);
139
}
140
 
141
/* Returns the magic number which says what history element we are
142
   looking at now.  In this implementation, it returns history_offset. */
143
int
144
where_history ()
145
{
146
  return (history_offset);
147
}
148
 
149
/* Make the current history item be the one at POS, an absolute index.
150
   Returns zero if POS is out of range, else non-zero. */
151
int
152
history_set_pos (pos)
153
     int pos;
154
{
155
  if (pos > history_length || pos < 0 || !the_history)
156
    return (0);
157
  history_offset = pos;
158
  return (1);
159
}
160
 
161
/* Return the current history array.  The caller has to be carefull, since this
162
   is the actual array of data, and could be bashed or made corrupt easily.
163
   The array is terminated with a NULL pointer. */
164
HIST_ENTRY **
165
history_list ()
166
{
167
  return (the_history);
168
}
169
 
170
/* Return the history entry at the current position, as determined by
171
   history_offset.  If there is no entry there, return a NULL pointer. */
172
HIST_ENTRY *
173
current_history ()
174
{
175
  return ((history_offset == history_length) || the_history == 0)
176
                ? (HIST_ENTRY *)NULL
177
                : the_history[history_offset];
178
}
179
 
180
/* Back up history_offset to the previous history entry, and return
181
   a pointer to that entry.  If there is no previous entry then return
182
   a NULL pointer. */
183
HIST_ENTRY *
184
previous_history ()
185
{
186
  return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
187
}
188
 
189
/* Move history_offset forward to the next history entry, and return
190
   a pointer to that entry.  If there is no next entry then return a
191
   NULL pointer. */
192
HIST_ENTRY *
193
next_history ()
194
{
195
  return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
196
}
197
 
198
/* Return the history entry which is logically at OFFSET in the history array.
199
   OFFSET is relative to history_base. */
200
HIST_ENTRY *
201
history_get (offset)
202
     int offset;
203
{
204
  int local_index;
205
 
206
  local_index = offset - history_base;
207
  return (local_index >= history_length || local_index < 0 || the_history == 0)
208
                ? (HIST_ENTRY *)NULL
209
                : the_history[local_index];
210
}
211
 
212
time_t
213
history_get_time (hist)
214
     HIST_ENTRY *hist;
215
{
216
  char *ts;
217
  time_t t;
218
 
219
  if (hist == 0 || hist->timestamp == 0)
220
    return 0;
221
  ts = hist->timestamp;
222
  if (ts[0] != history_comment_char)
223
    return 0;
224
  t = (time_t) atol (ts + 1);           /* XXX - should use strtol() here */
225
  return t;
226
}
227
 
228
static char *
229
hist_inittime ()
230
{
231
  time_t t;
232
  char ts[64], *ret;
233
 
234
  t = (time_t) time ((time_t *)0);
235
#if defined (HAVE_VSNPRINTF)            /* assume snprintf if vsnprintf exists */
236
  snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
237
#else
238
  sprintf (ts, "X%lu", (unsigned long) t);
239
#endif
240
  ret = savestring (ts);
241
  ret[0] = history_comment_char;
242
 
243
  return ret;
244
}
245
 
246
/* Place STRING at the end of the history list.  The data field
247
   is  set to NULL. */
248
void
249
add_history (string)
250
     const char *string;
251
{
252
  HIST_ENTRY *temp;
253
 
254
  if (history_stifled && (history_length == history_max_entries))
255
    {
256
      register int i;
257
 
258
      /* If the history is stifled, and history_length is zero,
259
         and it equals history_max_entries, we don't save items. */
260
      if (history_length == 0)
261
        return;
262
 
263
      /* If there is something in the slot, then remove it. */
264
      if (the_history[0])
265
        (void) free_history_entry (the_history[0]);
266
 
267
      /* Copy the rest of the entries, moving down one slot. */
268
      for (i = 0; i < history_length; i++)
269
        the_history[i] = the_history[i + 1];
270
 
271
      history_base++;
272
    }
273
  else
274
    {
275
      if (history_size == 0)
276
        {
277
          history_size = DEFAULT_HISTORY_GROW_SIZE;
278
          the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
279
          history_length = 1;
280
        }
281
      else
282
        {
283
          if (history_length == (history_size - 1))
284
            {
285
              history_size += DEFAULT_HISTORY_GROW_SIZE;
286
              the_history = (HIST_ENTRY **)
287
                xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
288
            }
289
          history_length++;
290
        }
291
    }
292
 
293
  temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
294
  temp->line = savestring (string);
295
  temp->data = (char *)NULL;
296
 
297
  temp->timestamp = hist_inittime ();
298
 
299
  the_history[history_length] = (HIST_ENTRY *)NULL;
300
  the_history[history_length - 1] = temp;
301
}
302
 
303
/* Change the time stamp of the most recent history entry to STRING. */
304
void
305
add_history_time (string)
306
     const char *string;
307
{
308
  HIST_ENTRY *hs;
309
 
310
  hs = the_history[history_length - 1];
311
  FREE (hs->timestamp);
312
  hs->timestamp = savestring (string);
313
}
314
 
315
/* Free HIST and return the data so the calling application can free it
316
   if necessary and desired. */
317
histdata_t
318
free_history_entry (hist)
319
     HIST_ENTRY *hist;
320
{
321
  histdata_t x;
322
 
323
  if (hist == 0)
324
    return ((histdata_t) 0);
325
  FREE (hist->line);
326
  FREE (hist->timestamp);
327
  x = hist->data;
328
  free (hist);
329
  return (x);
330
}
331
 
332
/* Make the history entry at WHICH have LINE and DATA.  This returns
333
   the old entry so you can dispose of the data.  In the case of an
334
   invalid WHICH, a NULL pointer is returned. */
335
HIST_ENTRY *
336
replace_history_entry (which, line, data)
337
     int which;
338
     const char *line;
339
     histdata_t data;
340
{
341
  HIST_ENTRY *temp, *old_value;
342
 
343
  if (which < 0 || which >= history_length)
344
    return ((HIST_ENTRY *)NULL);
345
 
346
  temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
347
  old_value = the_history[which];
348
 
349
  temp->line = savestring (line);
350
  temp->data = data;
351
  temp->timestamp = savestring (old_value->timestamp);
352
  the_history[which] = temp;
353
 
354
  return (old_value);
355
}
356
 
357
/* Remove history element WHICH from the history.  The removed
358
   element is returned to you so you can free the line, data,
359
   and containing structure. */
360
HIST_ENTRY *
361
remove_history (which)
362
     int which;
363
{
364
  HIST_ENTRY *return_value;
365
  register int i;
366
 
367
  if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)
368
    return ((HIST_ENTRY *)NULL);
369
 
370
  return_value = the_history[which];
371
 
372
  for (i = which; i < history_length; i++)
373
    the_history[i] = the_history[i + 1];
374
 
375
  history_length--;
376
 
377
  return (return_value);
378
}
379
 
380
/* Stifle the history list, remembering only MAX number of lines. */
381
void
382
stifle_history (max)
383
     int max;
384
{
385
  register int i, j;
386
 
387
  if (max < 0)
388
    max = 0;
389
 
390
  if (history_length > max)
391
    {
392
      /* This loses because we cannot free the data. */
393
      for (i = 0, j = history_length - max; i < j; i++)
394
        free_history_entry (the_history[i]);
395
 
396
      history_base = i;
397
      for (j = 0, i = history_length - max; j < max; i++, j++)
398
        the_history[j] = the_history[i];
399
      the_history[j] = (HIST_ENTRY *)NULL;
400
      history_length = j;
401
    }
402
 
403
  history_stifled = 1;
404
  max_input_history = history_max_entries = max;
405
}
406
 
407
/* Stop stifling the history.  This returns the previous maximum
408
   number of history entries.  The value is positive if the history
409
   was stifled,  negative if it wasn't. */
410
int
411
unstifle_history ()
412
{
413
  if (history_stifled)
414
    {
415
      history_stifled = 0;
416
      return (history_max_entries);
417
    }
418
  else
419
    return (-history_max_entries);
420
}
421
 
422
int
423
history_is_stifled ()
424
{
425
  return (history_stifled);
426
}
427
 
428
void
429
clear_history ()
430
{
431
  register int i;
432
 
433
  /* This loses because we cannot free the data. */
434
  for (i = 0; i < history_length; i++)
435
    {
436
      free_history_entry (the_history[i]);
437
      the_history[i] = (HIST_ENTRY *)NULL;
438
    }
439
 
440
  history_offset = history_length = 0;
441
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.