WIZlib Library API  ver 1.0
WIZlib Library API User Menual
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
usermenu.c
Go to the documentation of this file.
1 
12 //#define FILE_LOG_SILENCE
14 
15 
16 struct menu_item {
17  //uint8 index;
18  int8 parent;
19  int8 *desc;
20  menu_func mfunc;
21 };
22 
23 struct menu_info {
24  uint8 total;
25  uint8 cur;
26 };
27 
28 struct menu_item mtree[MAX_MENU_COUNT];
29 struct menu_info mi;
30 
31 
36 void menu_init(void)
37 {
38  memset(mtree, 0, sizeof(mtree));
39  mi.total = 0;
40  mi.cur = 0;
41 }
42 
54 int8 menu_add(int8 *desc, int8 parent, menu_func mfunc)
55 {
56  int32 len;
57 
58  if(desc == NULL) {
59  ERR("description string is NULL");
60  return RET_NOK;
61  } else if(parent != 0 &&
62  (parent > mi.total || mtree[parent-1].mfunc != NULL))
63  {
64  if(parent > mi.total) ERR("wrong parent num");
65  else ERR("parent menu should be NULL function");
66  return RET_NOK;
67  } else if(mi.total >= MAX_MENU_COUNT) {
68  ERR("not enough menu space");
69  return RET_NOK;
70  }
71 
72  //mtree[mi.total].index = mi.total+1;
73  len = strlen((char*)desc);
74  mtree[mi.total].desc = malloc(len+1);
75  if(mtree[mi.total].desc == NULL) {
76  ERRA("malloc fail - size(%d)", len+1);
77  return RET_NOK;
78  }
79  strcpy((char*)mtree[mi.total].desc, (char*)desc);
80  //mtree[mi.total].desc = strdup(desc);
81  mtree[mi.total].parent = parent;
82  mtree[mi.total].mfunc = mfunc;
83  mi.total++;
84 
85  return mi.total;
86 }
87 
93 void menu_print_tree(void)
94 {
95  uint8 i;
96 
97  printf("=== Menu Tree ===========================\r\n");
98  printf(" Idx Exp Par Desc\r\n");
99  printf("-----------------------------------------\r\n");
100  for(i=0; i<MAX_MENU_COUNT; i++) {
101  printf(" %-3d %c %-3d %s\r\n",
102  i+1, mtree[i].mfunc==NULL?'v':' ', mtree[i].parent, mtree[i].desc);
103  }
104  printf("=========================================\r\n");
105 }
106 
112 void menu_run(void)
113 {
114  int8 recv_char;
115  static int8 buf[CMD_BUF_SIZE];
116  bool disp = FALSE;
117  int8 ret;
118  uint8 i, cnt, tmp8;
119  static uint8 depth = 1, buf_len = 0;
120 
121  recv_char = (int8)getchar_nonblk();
122  if(recv_char == RET_NOK) return; //printf("RECV: 0x%x\r\n", recv_char);
123 
124  if(isgraph(recv_char) == 0) { //printf("ctrl\r\n");
125  switch(recv_char) {
126  case 0x0a:
127  break;
128  case 0x0d: //printf("<ENT>\r\n");
129  printf("\r\n");
130  break;
131  case 0x20: //printf("<SP>\r\n");
132  buf[buf_len] = 0;
133  printf("\r\n");
134  for(i=0; i<depth; i++) PUTCHAR('>');
135  printf(" %s", buf);
136  break;
137  case 0x08: //printf("<BS>\r\n");
138  if(buf_len != 0) {
139  buf_len--;
140  buf[buf_len] = 0;
141  printf("\b \b");
142  }
143  break;
144  case 0x7f: //printf("<DEL>\r\n");
145  memset(buf, 0, CMD_BUF_SIZE);
146  buf_len = 0; //printf("DEL: cur(%d), mfunc(%c), depth(%d)\r\n", mi.cur, mtree[mi.cur-1].mfunc==NULL?'N':'Y', depth);
147  if(mi.cur != 0) {
148  if(mtree[mi.cur-1].mfunc)
149  mtree[mi.cur-1].mfunc(MC_END, buf);
150  mi.cur = mtree[mi.cur-1].parent;
151  depth--;
152  }
153  printf("\r\n");
154  break;
155  case 0x1b: //printf("<ESC>\r\n");
156  break;
157  }
158 
159  } else if(buf_len < CMD_BUF_SIZE-1){
160  buf[buf_len++] = (uint8_t)recv_char; //buf[buf_len] = 0;
161  PUTCHAR(recv_char); //printf(" buf(%c, %s)\r\n", recv_char, buf);
162  } else {
163  printf("input buffer stuffed\r\n");
164  }
165 
166  if(recv_char != 0x0d && recv_char != 0x7f) return; //LOGA("Command: %s", buf);
167 
168  if(mi.cur == 0 || mtree[mi.cur-1].mfunc == NULL) // Out of the tem
169  {
170  if(buf_len != 0) {
171  if(str_check(isdigit, buf) == RET_OK) {//printf("digit(%d)\r\n", atoi(buf));
172  tmp8 = atoi((char*)buf);
173  if(depth > 1 && tmp8 == 0) { // If 0 entered, return to upper menu
174  if(mi.cur != 0) {
175  if(mtree[mi.cur-1].mfunc)
176  mtree[mi.cur-1].mfunc(MC_END, buf);
177  mi.cur = mtree[mi.cur-1].parent;
178  depth--;
179  disp = TRUE;
180  } else printf("return tried despite root");
181  } else { // If not 0, search that menu
182  for(i=0; i<mi.total; i++) {
183  if(mi.cur == mtree[i].parent) {//printf("-i(%d)\r\n", i);
184  if(tmp8 == 1) break;
185  else tmp8--;
186  }
187  }
188 
189  if(i < mi.total) { //DBGA("-set cur(%d)", tmp8);
190  cnt = mi.cur;
191  mi.cur = i+1;
192  if(mtree[mi.cur-1].mfunc) {
193  ret = mtree[mi.cur-1].mfunc(MC_START, buf);
194  if(ret == RET_OK) {
195  mtree[mi.cur-1].mfunc(MC_END, buf);
196  mi.cur = cnt;
197  } else {
198  depth++;
199  }
200  } else {
201  depth++;
202  disp = TRUE;
203  }
204  } else printf("wrong number(%s)\r\n", buf);
205  }
206  } else printf("not digit(%s)\r\n", buf);
207  } else disp = TRUE;
208  }
209  else // In the Item
210  {
211  if(buf_len == 0) {
212  mtree[mi.cur-1].mfunc(MC_END, buf);
213  mi.cur = mtree[mi.cur-1].parent;
214  depth--;
215  disp = TRUE;
216  } else {
217  ret = mtree[mi.cur-1].mfunc(MC_DATA, buf);
218  if(ret != RET_OK) { //printf("process continue\r\n");
219  } else { //printf("process done\r\n");
220  mtree[mi.cur-1].mfunc(MC_END, buf);
221  mi.cur = mtree[mi.cur-1].parent;
222  depth--;
223  }
224  }
225  }
226 
227  if(disp) {
228  printf("\r\n=== MENU ================================\r\n");
229  if(depth > 1) printf(" 0: Back\r\n");
230  for(i=0, cnt=0; i<mi.total; i++) {
231  if(mi.cur == mtree[i].parent) {
232  cnt++;
233  if(mtree[i].mfunc == NULL) {
234  if(cnt < 10)
235  printf(" +%d: %s\r\n", cnt, mtree[i].desc);
236  else printf("+%2d: %s\r\n", cnt, mtree[i].desc);
237  } else {
238  if(cnt < 10)
239  printf(" %d: %s\r\n", cnt, mtree[i].desc);
240  else printf(" %2d: %s\r\n", cnt, mtree[i].desc);
241  }
242  }
243  }
244  printf("=========================================\r\n");
245  }
246 
247  memset(buf, 0, CMD_BUF_SIZE);
248  buf_len = 0;
249  printf("\r\n");
250  for(i=0; i<depth; i++) PUTCHAR('>');
251  PUTCHAR(' ');
252 
253 }
254 
255