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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [cygmon/] [v2_0/] [misc/] [ledit.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
//==========================================================================
2
//
3
//      ledit.c
4
//
5
//      Utterly simple line editor
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    
44
// Contributors: gthomas
45
// Date:         1999-10-20
46
// Purpose:      Udderly simple line editor
47
// Description:  
48
//               
49
//
50
//####DESCRIPTIONEND####
51
//
52
//=========================================================================
53
 
54
 
55
#include <monitor.h>
56
#include <stdlib.h>
57
#include <string.h>
58
#ifdef HAVE_BSP
59
#include <bsp/bsp.h>
60
#endif
61
#include "ledit.h"
62
 
63
#ifndef NULL
64
#define NULL 0
65
#endif
66
 
67
static char *cutBuf = NULL;
68
 
69
#ifdef NO_MALLOC
70
static char linebufArray [MAX_HIST_ENTS + 2][MAXLINELEN + 1];
71
#endif
72
 
73
static struct termcap
74
{
75
  char *relleft, *relright;
76
  char *oneleft;
77
  char *insertch;
78
  char *deletech;
79
  char *deleteonech;
80
  char *clreol;
81
  char *gobol;
82
  int width;
83
} terminal;
84
 
85
static struct linepos
86
{
87
  char *prompt;
88
  char *buffer;
89
  char *ebuf;
90
  int cursor;
91
} linebuf;
92
 
93
static struct history
94
{
95
  char *cmd;
96
  struct history *next, *prev;
97
} *list = NULL, *topl = NULL, *curl = NULL;
98
 
99
static int histlen = 0;
100
static int histLimit = MAX_HIST_ENTS;
101
 
102
static struct history histEnts[MAX_HIST_ENTS + 1], *histPtr = histEnts;
103
static struct history currLine = { NULL, NULL, NULL };
104
 
105
void
106
beep (void)
107
{
108
  xputchar ('\007');
109
}
110
 
111
void
112
printHistoryList ()
113
{
114
  struct history *hist = list;
115
  int hist_num = 1;
116
 
117
  if (hist != NULL)
118
  {
119
    while (hist->prev != NULL)
120
    {
121
      hist = hist->prev;
122
    }
123
 
124
    while (hist != NULL)
125
    {
126
      if (hist->cmd != NULL)
127
        xprintf(" %d %s\n", hist_num++, hist->cmd);
128
      hist = hist->next;
129
    }
130
  }
131
}
132
 
133
static void
134
outputParamStr (char *str, int val)
135
{
136
  char *i = strchr (str, '%');
137
  char *ptr;
138
  int dist = val;
139
 
140
  if (i == NULL)
141
    {
142
      while (dist-- > 0)
143
        xprintf (str);
144
    }
145
  else
146
    {
147
      for (ptr = str; *ptr && ptr < i; ptr++)
148
        xputchar (*ptr);
149
      if (dist > 99)
150
        {
151
          xputchar ('0' + dist / 100);
152
          dist = dist % 100;
153
        }
154
      if (dist > 9)
155
        {
156
          xputchar ('0' + dist / 10);
157
          dist = dist % 10;
158
        }
159
      xputchar ('0' + dist);
160
      if (*ptr)
161
        xprintf (ptr + 1);
162
    }
163
}
164
 
165
static void
166
absMoveCursor (int pos)
167
{
168
  int dist, oldpos = linebuf.cursor;
169
  int absdist;
170
  char *bigmove;
171
 
172
  if (pos > (linebuf.ebuf - linebuf.buffer))
173
    {
174
      beep ();
175
      pos = linebuf.ebuf - linebuf.buffer;
176
    }
177
  else if (pos < 0)
178
    pos = 0;
179
  dist = pos - linebuf.cursor;
180
  absdist = (dist < 0 ? -dist : dist);
181
  linebuf.cursor = pos;
182
  if (dist == 0)
183
    return;
184
  if (dist < 0)
185
    bigmove = terminal.relleft;
186
  else
187
    bigmove = terminal.relright;
188
 
189
  if ((absdist < 4) || (bigmove == NULL))
190
    {
191
      int x;
192
      int promptLen = strlen (linebuf.prompt);
193
 
194
      if (pos < (absdist - promptLen))
195
        {
196
          xprintf (terminal.gobol);
197
          xprintf (linebuf.prompt);
198
          for (x = 0; x < pos; x++)
199
            xputchar (linebuf.buffer[x]);
200
          return;
201
        }
202
 
203
      if (dist < 0)
204
        {
205
          for (x = 0; x < -dist ;x++)
206
            xprintf (terminal.oneleft);
207
        }
208
      else
209
        {
210
          for (x = 0; x < dist; x++)
211
            xputchar (linebuf.buffer [oldpos + x]);
212
        }
213
    }
214
  else
215
    {
216
      outputParamStr (bigmove, absdist);
217
    }
218
}
219
 
220
static void
221
clrScrToEol (void)
222
{
223
  int len = linebuf.ebuf - linebuf.buffer;
224
 
225
  if (len < linebuf.cursor)
226
    return;
227
 
228
  if(terminal.clreol)
229
    {
230
      xprintf (terminal.clreol);
231
    }
232
  else if (terminal.deletech)
233
    {
234
      outputParamStr (terminal.deletech, len - linebuf.cursor);
235
    }
236
  else
237
    {
238
      int oldcur = linebuf.cursor;
239
      while (linebuf.cursor < len)
240
        {
241
          xputchar (' ');
242
          linebuf.cursor++;
243
        }
244
 
245
      absMoveCursor (oldcur);
246
    }
247
}
248
 
249
static void
250
redrawCmd (void)
251
{
252
  xprintf (terminal.gobol);
253
  xprintf (linebuf.prompt);
254
  linebuf.buffer[linebuf.cursor] = 0;
255
  xprintf (linebuf.buffer);
256
  clrScrToEol ();
257
}
258
 
259
static void
260
instCmd (char *ncmd)
261
{
262
  linebuf.cursor = strlen (ncmd);
263
  strcpy (linebuf.buffer, ncmd);
264
  redrawCmd ();
265
  linebuf.ebuf = linebuf.buffer + linebuf.cursor;
266
}
267
 
268
static void
269
prevCmd (void)
270
{
271
  if (curl == &currLine)
272
    {
273
      if (list != NULL)
274
        {
275
          *linebuf.ebuf = 0;
276
#ifdef NO_MALLOC
277
          currLine.cmd = linebufArray[MAX_HIST_ENTS];
278
          strcpy (currLine.cmd, linebuf.buffer);
279
#else
280
          if (currLine.cmd != NULL)
281
            free (currLine.cmd);
282
          currLine.cmd = strdup (linebuf.buffer);
283
#endif
284
          curl = list;
285
        }
286
    }
287
  else
288
    {
289
      if (curl->prev != NULL)
290
        curl = curl->prev;
291
    }
292
  if (curl != NULL && curl->cmd != NULL)
293
    instCmd (curl->cmd);
294
  else
295
    beep ();
296
}
297
 
298
static void
299
nextCmd (void)
300
{
301
  if (curl->next == NULL)
302
    {
303
      beep ();
304
    }
305
  else
306
    {
307
      curl = curl->next;
308
      instCmd (curl->cmd);
309
    }
310
 
311
}
312
 
313
static int initted = 0;
314
 
315
void
316
initVt100 (void)
317
{
318
  terminal.gobol = "\r";
319
  terminal.oneleft = "\010";
320
  terminal.relleft = "\033[%D";
321
  terminal.relright = "\033[%C";
322
  terminal.insertch = "\033[%@";
323
  terminal.deletech = "\033[%P";
324
  terminal.deleteonech = "\033[P";
325
  terminal.clreol = "\033[K";
326
  terminal.width = 80;
327
  initted = 1;
328
}
329
 
330
void
331
initDumb (void)
332
{
333
  terminal.gobol = "\r";
334
  terminal.oneleft = "\010";
335
  terminal.relleft = NULL;
336
  terminal.relright = NULL;
337
  terminal.insertch = NULL;
338
  terminal.deletech = NULL;
339
  terminal.deleteonech = NULL;
340
  terminal.clreol = NULL;
341
  terminal.width = 80;
342
  initted = 1;
343
}
344
 
345
static void
346
insertChar (char *chars, int num)
347
{
348
  int len = linebuf.ebuf - linebuf.buffer + strlen (linebuf.prompt);
349
  int n = 0;
350
 
351
  if ((len + num) >= terminal.width)
352
    {
353
      beep ();
354
      return;
355
    }
356
  if ((linebuf.ebuf - linebuf.buffer) > linebuf.cursor)
357
    {
358
      char *ptr, *eptr = linebuf.buffer + linebuf.cursor;
359
 
360
      for (ptr = linebuf.ebuf; ptr >= eptr; ptr--)
361
        *(ptr+num) = *ptr;
362
 
363
      if (terminal.insertch != NULL)
364
        outputParamStr (terminal.insertch, num);
365
    }
366
  for (n = 0; n < num; n++)
367
    {
368
      xputchar (*chars);
369
      linebuf.buffer[linebuf.cursor++] = *(chars++);
370
    }
371
 
372
  linebuf.ebuf += num;
373
 
374
  if (terminal.insertch == NULL)
375
    {
376
      char *ptr = linebuf.buffer + linebuf.cursor;
377
      int oldcur = linebuf.cursor;
378
      for (; ptr < linebuf.ebuf; ptr++)
379
        xputchar (*ptr);
380
      linebuf.cursor = linebuf.ebuf - linebuf.buffer;
381
      absMoveCursor (oldcur);
382
    }
383
}
384
 
385
static void
386
deleteEol (int putInCutBuffer)
387
{
388
  int len = linebuf.ebuf - linebuf.buffer;
389
  if (linebuf.cursor < len)
390
    {
391
      clrScrToEol ();
392
 
393
      if (putInCutBuffer)
394
        {
395
          *linebuf.ebuf = 0;
396
#ifdef NO_MALLOC
397
          cutBuf = linebufArray[MAX_HIST_ENTS + 1];
398
          strcpy (cutBuf, linebuf.buffer + linebuf.cursor);
399
#else
400
          if (cutBuf != NULL)
401
            free (cutBuf);
402
          cutBuf = strdup (linebuf.buffer + linebuf.cursor);
403
#endif
404
        }
405
      linebuf.ebuf = linebuf.buffer + linebuf.cursor;
406
    }
407
}
408
 
409
static void
410
deleteCurrChar (void)
411
{
412
  int len = linebuf.ebuf - linebuf.buffer;
413
  char *ptr;
414
  if (len == linebuf.cursor || len == 0)
415
    return;
416
  for (ptr = linebuf.buffer + linebuf.cursor; ptr < (linebuf.ebuf - 1); ptr++)
417
    {
418
      *ptr = *(ptr + 1);
419
      if (terminal.deleteonech == NULL)
420
        xputchar (*ptr);
421
    }
422
  linebuf.ebuf--;
423
  if (terminal.deleteonech && (len - 1) != linebuf.cursor)
424
    xprintf (terminal.deleteonech);
425
  else
426
    {
427
      int oldcur = linebuf.cursor;
428
      xputchar (' ');
429
      linebuf.cursor = linebuf.ebuf - linebuf.buffer + 1;
430
      absMoveCursor (oldcur);
431
    }
432
}
433
 
434
static void
435
deleteChar (void)
436
{
437
  if (linebuf.cursor == 0)
438
    {
439
      beep ();
440
      return;
441
    }
442
  absMoveCursor (linebuf.cursor - 1);
443
  deleteCurrChar ();
444
}
445
 
446
int
447
lineedit (char *prompt, char *buffer, int maxLen)
448
{
449
  int c;
450
 
451
  curl = &currLine;
452
 
453
  if (!initted)
454
    {
455
      initted = 1;
456
      /*initVt100 ();*/
457
      initDumb();
458
    }
459
  linebuf.prompt = prompt;
460
  linebuf.buffer = buffer;
461
  linebuf.ebuf = buffer;
462
  buffer[0] = 0;
463
  linebuf.cursor = 0;
464
  redrawCmd ();
465
  while ((c=input_char ()) > 0)
466
    {
467
      switch (c)
468
        {
469
        case PREVCMD:
470
          prevCmd ();
471
          break;
472
        case NEXTCMD:
473
          nextCmd ();
474
          break;
475
        case LF:
476
        case CR:
477
          *linebuf.ebuf = 0;
478
#ifdef NO_MALLOC
479
          cutBuf = NULL;
480
          currLine.cmd = NULL;
481
#else
482
          if (cutBuf != NULL)
483
            {
484
              free (cutBuf);
485
              cutBuf = NULL;
486
            }
487
          if (currLine.cmd != NULL)
488
            {
489
              free (currLine.cmd);
490
              currLine.cmd = NULL;
491
            }
492
#endif
493
          return linebuf.ebuf - linebuf.buffer;
494
          break;
495
        case BOLCMD:
496
          absMoveCursor (0);
497
          break;
498
        case EOLCMD:
499
          absMoveCursor (linebuf.ebuf-linebuf.buffer);
500
          break;
501
        case FORWCMD:
502
          absMoveCursor (linebuf.cursor + 1);
503
          break;
504
        case BACKCMD:
505
          absMoveCursor (linebuf.cursor - 1);
506
          break;
507
        case DELBACK:
508
        case '\177':
509
          deleteChar ();
510
          break;
511
        case ERASELINE:
512
          absMoveCursor (0);
513
          deleteEol (0);
514
          break;
515
        case DELEOL:
516
          deleteEol (1);
517
          break;
518
        case DELCURRCH:
519
          deleteCurrChar ();
520
          break;
521
        case YANKCH:
522
          if (cutBuf != NULL)
523
            insertChar (cutBuf,strlen (cutBuf));
524
          break;
525
        default:
526
          if (c >= 32 && c < 127)
527
            {
528
              char ch = c;
529
              insertChar (&ch, 1);
530
            }
531
          break;
532
        }
533
    }
534
  return -1;
535
}
536
 
537
void
538
addHistoryCmd (char *cmd)
539
{
540
  struct history *newent = NULL;
541
 
542
  if (histlen >= histLimit)
543
    {
544
      newent = topl;
545
      topl = topl->next;
546
      topl->prev = NULL;
547
#ifdef NO_MALLOC
548
      newent->prev = NULL;
549
      newent->next = NULL;
550
#else
551
      free (newent->cmd);
552
      newent->cmd = NULL;
553
#endif
554
      histlen = histLimit - 1;
555
    }
556
 
557
  histlen++;
558
 
559
  if (newent == NULL)
560
    {
561
      newent = histPtr++;
562
#ifdef NO_MALLOC
563
      newent->cmd = linebufArray[histlen - 1];
564
#endif
565
    }
566
 
567
  if (list == NULL)
568
    {
569
      list = newent;
570
      list->prev = NULL;
571
      topl = list;
572
    }
573
  else
574
    {
575
      list->next = newent;
576
      list->next->prev = list;
577
      list = list->next;
578
    }
579
  currLine.prev = list;
580
  list->next = &currLine;
581
#ifdef NO_MALLOC
582
  strcpy (list->cmd, cmd);
583
#else
584
  list->cmd = strdup (cmd);
585
#endif
586
  curl = &currLine;
587
}
588
 
589
void
590
set_term_name (char *name)
591
{
592
  if (! strcmp (name, "vt100"))
593
    {
594
      initVt100 ();
595
    }
596
  else if (! strcmp (name, "dumb"))
597
    {
598
      initDumb ();
599
    }
600
  else
601
    {
602
      xprintf ("Unknown terminal name %s\n", name);
603
    }
604
}

powered by: WebSVN 2.1.0

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