LCOV - code coverage report
Current view: top level - mscb/src - cmdedit.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 148 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 1 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         cmdedit.c
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     Command-line editor for msc
       7              : 
       8              : \********************************************************************/
       9              : 
      10              : #include <stdio.h>
      11              : #include <string.h>
      12              : 
      13              : #define MAX_HISTORY 50
      14              : #define LINE_LENGTH 256
      15              : 
      16              : #define TRUE 1
      17              : #define FALSE 0
      18              : 
      19              : char history[MAX_HISTORY][LINE_LENGTH];
      20              : int his_index = 0;
      21              : 
      22              : extern int ss_getchar(int reset);
      23              : extern char *ss_gets(char *string, int size);
      24              : extern unsigned int ss_millitime(void);
      25              : 
      26              : /* special characters */
      27              : #define CH_BS             8
      28              : #define CH_TAB            9
      29              : #define CH_CR            13
      30              : 
      31              : #define CH_EXT 0x100
      32              : 
      33              : #define CH_HOME   (CH_EXT+0)
      34              : #define CH_INSERT (CH_EXT+1)
      35              : #define CH_DELETE (CH_EXT+2)
      36              : #define CH_END    (CH_EXT+3)
      37              : #define CH_PUP    (CH_EXT+4)
      38              : #define CH_PDOWN  (CH_EXT+5)
      39              : #define CH_UP     (CH_EXT+6)
      40              : #define CH_DOWN   (CH_EXT+7)
      41              : #define CH_RIGHT  (CH_EXT+8)
      42              : #define CH_LEFT   (CH_EXT+9)
      43              : 
      44              : /*------------------------------------------------------------------*/
      45              : 
      46            0 : int cmd_edit(const char *prompt, char *cmd, int(*dir) (char *, int *), int(*idle) (void))
      47              : {
      48              :    char line[LINE_LENGTH];
      49              :    int i, j, k, c, hi;
      50              :    int status;
      51            0 :    unsigned int last_time = 0;
      52            0 :    int escape_flag = 0;
      53              : 
      54            0 :    if (ss_getchar(0) == -1) {
      55              :       /* normal input if ss_getchar not supported */
      56            0 :       fputs(prompt, stdout);
      57            0 :       ss_gets(cmd, 256);
      58            0 :       return strlen(cmd);
      59              :    }
      60              : 
      61            0 :    fputs(prompt, stdout);
      62            0 :    fflush(stdout);
      63              : 
      64            0 :    hi = his_index;
      65            0 :    memset(line, 0, LINE_LENGTH);
      66            0 :    memset(history[hi], 0, LINE_LENGTH);
      67            0 :    strcpy(line, cmd);
      68            0 :    fputs(line, stdout);
      69            0 :    i = strlen(cmd);
      70            0 :    fflush(stdout);
      71              : 
      72              :    do {
      73            0 :       c = ss_getchar(0);
      74              : 
      75            0 :       if (c == 27)
      76            0 :          escape_flag = TRUE;
      77              : 
      78            0 :       if (c >= ' ' && c < CH_EXT && escape_flag) {
      79            0 :          escape_flag = FALSE;
      80            0 :          if (c == 'p')
      81            0 :             c = 6;
      82              :       }
      83              : 
      84              :       /* normal input */
      85            0 :       if (c >= ' ' && c < CH_EXT) {
      86            0 :          if (strlen(line) < LINE_LENGTH - 1) {
      87            0 :             for (j = strlen(line); j >= i; j--)
      88            0 :                line[j + 1] = line[j];
      89            0 :             if (i < LINE_LENGTH - 1) {
      90            0 :                line[i++] = c;
      91            0 :                fputc(c, stdout);
      92              :             }
      93            0 :             for (j = i; j < (int) strlen(line); j++)
      94            0 :                fputc(line[j], stdout);
      95            0 :             for (j = i; j < (int) strlen(line); j++)
      96            0 :                fputc('\b', stdout);
      97              :          }
      98              :       }
      99              : 
     100              :       /* BS */
     101            0 :       if (c == CH_BS && i > 0) {
     102            0 :          i--;
     103            0 :          fputc('\b', stdout);
     104            0 :          for (j = i; j <= (int) strlen(line); j++) {
     105            0 :             line[j] = line[j + 1];
     106            0 :             if (line[j])
     107            0 :                fputc(line[j], stdout);
     108              :             else
     109            0 :                fputc(' ', stdout);
     110              :          }
     111            0 :          for (k = 0; k < j - i; k++)
     112            0 :             fputc('\b', stdout);
     113              :       }
     114              : 
     115              :       /* DELETE/Ctrl-D */
     116            0 :       if (c == CH_DELETE || c == 4) {
     117            0 :          for (j = i; j <= (int) strlen(line); j++) {
     118            0 :             line[j] = line[j + 1];
     119            0 :             if (line[j])
     120            0 :                fputc(line[j], stdout);
     121              :             else
     122            0 :                fputc(' ', stdout);
     123              :          }
     124            0 :          for (k = 0; k < j - i; k++)
     125            0 :             fputc('\b', stdout);
     126              :       }
     127              : 
     128              :       /* Erase line: CTRL-W, CTRL-U */
     129            0 :       if (c == 23 || c == 21) {
     130            0 :          i = strlen(line);
     131            0 :          memset(line, 0, sizeof(line));
     132            0 :          printf("\r%s", prompt);
     133            0 :          for (j = 0; j < i; j++)
     134            0 :             fputc(' ', stdout);
     135            0 :          for (j = 0; j < i; j++)
     136            0 :             fputc('\b', stdout);
     137            0 :          i = 0;
     138              :       }
     139              : 
     140              :       /* Erase line from cursor: CTRL-K */
     141            0 :       if (c == 11) {
     142            0 :          for (j = i; j < (int) strlen(line); j++)
     143            0 :             fputc(' ', stdout);
     144            0 :          for (j = i; j < (int) strlen(line); j++)
     145            0 :             fputc('\b', stdout);
     146            0 :          for (j = strlen(line); j >= i; j--)
     147            0 :             line[j] = 0;
     148              :       }
     149              : 
     150              :       /* left arrow, CTRL-B */
     151            0 :       if ((c == CH_LEFT || c == 2) && i > 0) {
     152            0 :          i--;
     153            0 :          fputc('\b', stdout);
     154              :       }
     155              : 
     156              :       /* right arrow, CTRL-F */
     157            0 :       if ((c == CH_RIGHT || c == 6) && i < (int) strlen(line))
     158            0 :          fputc(line[i++], stdout);
     159              : 
     160              :       /* HOME, CTRL-A */
     161            0 :       if ((c == CH_HOME || c == 1) && i > 0) {
     162            0 :          for (j = 0; j < i; j++)
     163            0 :             fputc('\b', stdout);
     164            0 :          i = 0;
     165              :       }
     166              : 
     167              :       /* END, CTRL-E */
     168            0 :       if ((c == CH_END || c == 5) && i < (int) strlen(line)) {
     169            0 :          for (j = i; j < (int) strlen(line); j++)
     170            0 :             fputc(line[i++], stdout);
     171            0 :          i = strlen(line);
     172              :       }
     173              : 
     174              :       /* up arrow / CTRL-P */
     175            0 :       if (c == CH_UP || c == 16) {
     176            0 :          if (history[(hi + MAX_HISTORY - 1) % MAX_HISTORY][0]) {
     177            0 :             hi = (hi + MAX_HISTORY - 1) % MAX_HISTORY;
     178            0 :             i = strlen(line);
     179            0 :             fputc('\r', stdout);
     180            0 :             fputs(prompt, stdout);
     181            0 :             for (j = 0; j < i; j++)
     182            0 :                fputc(' ', stdout);
     183            0 :             for (j = 0; j < i; j++)
     184            0 :                fputc('\b', stdout);
     185            0 :             memcpy(line, history[hi], 256);
     186            0 :             i = strlen(line);
     187            0 :             for (j = 0; j < i; j++)
     188            0 :                fputc(line[j], stdout);
     189              :          }
     190              :       }
     191              : 
     192              :       /* down arrow / CTRL-N */
     193            0 :       if (c == CH_DOWN || c == 14) {
     194            0 :          if (history[hi][0]) {
     195            0 :             hi = (hi + 1) % MAX_HISTORY;
     196            0 :             i = strlen(line);
     197            0 :             fputc('\r', stdout);
     198            0 :             fputs(prompt, stdout);
     199            0 :             for (j = 0; j < i; j++)
     200            0 :                fputc(' ', stdout);
     201            0 :             for (j = 0; j < i; j++)
     202            0 :                fputc('\b', stdout);
     203            0 :             memcpy(line, history[hi], 256);
     204            0 :             i = strlen(line);
     205            0 :             for (j = 0; j < i; j++)
     206            0 :                fputc(line[j], stdout);
     207              :          }
     208              :       }
     209              : 
     210              :       /* CTRL-F */
     211            0 :       if (c == 6) {
     212            0 :          for (j = (hi + MAX_HISTORY - 1) % MAX_HISTORY; j != hi;
     213            0 :               j = (j + MAX_HISTORY - 1) % MAX_HISTORY)
     214            0 :             if (history[j][0] && strncmp(line, history[j], i) == 0) {
     215            0 :                memcpy(line, history[j], 256);
     216            0 :                fputs(line + i, stdout);
     217            0 :                i = strlen(line);
     218            0 :                break;
     219              :             }
     220            0 :          if (j == hi)
     221            0 :             fputc(7, stdout);
     222              :       }
     223              : 
     224              :       /* tab */
     225            0 :       if (c == 9 && dir != NULL) {
     226            0 :          status = dir(line, &i);
     227              : 
     228              :          /* redraw line */
     229            0 :          fputc('\r', stdout);
     230            0 :          fputs(prompt, stdout);
     231            0 :          fputs(line, stdout);
     232              : 
     233            0 :          for (j = 0; j < (int) strlen(line) - i; j++)
     234            0 :             fputc('\b', stdout);
     235              :       }
     236              : 
     237            0 :       if (c != 0) {
     238            0 :          last_time = ss_millitime();
     239            0 :          fflush(stdout);
     240              :       }
     241              : 
     242            0 :       if ((ss_millitime() - last_time > 300) && idle != NULL) {
     243            0 :          status = idle();
     244              : 
     245            0 :          if (status) {
     246            0 :             fputc('\r', stdout);
     247            0 :             fputs(prompt, stdout);
     248            0 :             fputs(line, stdout);
     249              : 
     250            0 :             for (j = 0; j < (int) strlen(line) - i; j++)
     251            0 :                fputc('\b', stdout);
     252              : 
     253            0 :             fflush(stdout);
     254              :          }
     255              :       }
     256              : 
     257            0 :    } while (c != CH_CR);
     258              : 
     259            0 :    strcpy(cmd, line);
     260              : 
     261            0 :    if (dir != NULL)
     262            0 :       if (strcmp(cmd, history[(his_index + MAX_HISTORY - 1) % MAX_HISTORY]) != 0 &&
     263            0 :           cmd[0]) {
     264            0 :          strcpy(history[his_index], cmd);
     265            0 :          his_index = (his_index + 1) % MAX_HISTORY;
     266              :       }
     267              : 
     268              :    /* reset terminal */
     269            0 :    ss_getchar(1);
     270              : 
     271            0 :    fputc('\n', stdout);
     272              : 
     273            0 :    return strlen(line);
     274              : }
        

Generated by: LCOV version 2.0-1