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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [cygmon/] [current/] [misc/] [ledit.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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