]> rtime.felk.cvut.cz Git - sysless.git/blob - libs4c/cmdproc/cmd_io_line.c
cmdproc: Erase end of line after backspace
[sysless.git] / libs4c / cmdproc / cmd_io_line.c
1 /*******************************************************************
2   Components for embedded applications builded for
3   laboratory and medical instruments firmware
4
5   cmd_proc.h - text line command processor
6                designed for instruments control and setup
7                over RS-232 line
8
9   Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
10             (C) 2002 by PiKRON Ltd. http://www.pikron.com
11             (C) 2007 by Michal Sojka <sojkam1@fel.cvut.cz>
12
13   This file can be used and copied according to next
14   license alternatives
15    - MPL - Mozilla Public License
16    - GPL - GNU Public License
17    - other license provided by project originators
18  *******************************************************************/
19
20 #include <cmd_proc.h>
21 #include "cmd_proc_priv.h"
22 #include <string.h>
23
24 /* cmd_io line editor */
25
26 /**
27  * Adds new characters to an edit line buffer.
28  *
29  * @param elb Edit line buffer.
30  * @param ch character to add.
31  *
32  * @return 1 in case of end of line, -1 if called at inaproprate time, 0 otherwise.
33  */
34 int cmd_ed_line_buf(ed_line_buf_t *elb, int ch)
35 {
36   int lastch=elb->lastch;
37   if (elb->flg&FL_ELB_INSEND)
38     return -1;
39   elb->lastch=ch;
40   if(!lastch){
41     elb->inbuf=0;               /* Start new line */
42   }
43   if(ch == '\b') {              /* backspace */
44     if (elb->inbuf > 0)
45       elb->inbuf--;
46     return 0;
47   }
48   if((!(elb->flg&FL_ELB_NOCRLF))&&((ch=='\n')||(ch=='\r'))){
49     if((lastch=='\n')&&(ch=='\r')) /* Empty line, ignore it. */
50       return 0;
51     elb->lastch=0;               /* End the string */
52     elb->buf[elb->inbuf]=0;
53     return 1;
54   }
55   if(elb->inbuf>=elb->alloc-1){
56     /* try to reallocate buffer len not implemented */
57     return 0;
58   }
59   elb->buf[elb->inbuf++]=ch;
60   return 0;
61 }
62
63 int cmd_io_line_putc(cmd_io_t *cmd_io,int ch)
64 {
65   return cmd_ed_line_buf(cmd_io->priv.ed_line.out,ch);
66 }
67
68 /* Process pending output */
69 int cmd_io_line_out(cmd_io_t *cmd_io)
70 {
71   cmd_io_t* io_stack=cmd_io->priv.ed_line.io_stack;
72   ed_line_buf_t* ed_line_out=cmd_io->priv.ed_line.out;
73
74   if(!ed_line_out->inbuf) return 0;
75   if(!io_stack)
76     return -1;
77
78   if(!(ed_line_out->flg&FL_ELB_INSEND)){
79     ed_line_out->flg|=FL_ELB_INSEND;
80     ed_line_out->lastch=0;
81   }
82   while(cmd_io_putc(io_stack, ed_line_out->buf[ed_line_out->lastch])>=0){
83     if(++ed_line_out->lastch >= ed_line_out->inbuf){
84       ed_line_out->lastch=0;
85       ed_line_out->inbuf=0;
86       ed_line_out->flg&=~FL_ELB_INSEND;
87       return 0;
88     }
89   }
90   return 1;
91 }
92
93 /* process input & perform echo if requested */
94 int cmd_io_line_in(cmd_io_t *cmd_io)
95 {
96   int ch;
97   cmd_io_t* io_stack = cmd_io->priv.ed_line.io_stack;
98   ed_line_buf_t *el = cmd_io->priv.ed_line.in;
99
100   if(!io_stack)
101       return -1;
102
103   while((ch=cmd_io_getc(io_stack))>=0){
104 //    DPRINT("Added %c (%d)\n", ch, ch);
105     int eol = cmd_ed_line_buf(el,ch);
106     if (eol == -1)
107       return -1;
108     if(eol){
109       if(el->flg&FL_ELB_ECHO){
110         while(cmd_io_putc(io_stack,'\r')<0);
111         while(cmd_io_putc(io_stack,'\n')<0);
112       }
113       return 1;
114     }
115     else
116       if(el->flg&FL_ELB_ECHO) {
117         while(cmd_io_putc(io_stack,ch)<0);
118         if (ch == '\b')
119           cmd_io_puts(io_stack, "\033[K"); /* Erase End of Line */
120       }
121   }
122   return 0;
123 }
124
125 /* The possibly blocking read of one line, should be used only
126    when other options fails */
127 char *cmd_io_line_rdline(cmd_io_t *cmd_io, int mode)
128 {
129   int ret;
130   while((ret=cmd_io_line_in(cmd_io))==0)
131     if(!mode) break;
132   if(ret<=0) return NULL;
133   return cmd_io->priv.ed_line.in->buf;
134 }
135
136 /* Local Variables: */
137 /* c-basic-offset: 2 */
138 /* End: */