Changeset d4d8255 in mainline
- Timestamp:
- 2016-03-09T20:01:43Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c1b8ad4
- Parents:
- df425da (diff), dc0e41c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- kernel
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/console/kconsole.h
rdf425da rd4d8255 43 43 #define KCONSOLE_HISTORY 10 44 44 45 /** Callback to be used to enum hints for cmd tab completion. */ 46 typedef const char *(*hints_enum_func_t)(const char *, const char **, void **); 47 45 48 typedef enum { 46 49 ARG_TYPE_INVALID = 0, … … 85 88 /** Function for printing detailed help. */ 86 89 void (* help)(void); 90 /** Function for enumerating hints for arguments. */ 91 hints_enum_func_t hints_enum; 87 92 } cmd_info_t; 88 93 … … 100 105 101 106 extern bool cmd_register(cmd_info_t *cmd); 107 extern const char *cmdtab_enum(const char *name, const char **h, void **ctx); 102 108 103 109 #endif -
kernel/generic/include/str.h
rdf425da rd4d8255 62 62 63 63 /**< Maximum size of a string containing cnt characters */ 64 #define STR_BOUNDS(cnt) ( cnt<< 2)64 #define STR_BOUNDS(cnt) ((cnt) << 2) 65 65 66 66 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz); -
kernel/generic/include/symtab.h
rdf425da rd4d8255 40 40 41 41 extern void symtab_print_search(const char *); 42 extern int symtab_compl(char *, size_t, indev_t*);42 extern const char* symtab_hints_enum(const char *, const char **, void **); 43 43 44 44 #endif -
kernel/generic/src/console/cmd.c
rdf425da rd4d8255 206 206 .func = cmd_test, 207 207 .argc = 1, 208 .argv = test_argv 208 .argv = test_argv, 209 .hints_enum = tests_hints_enum 209 210 }; 210 211 … … 246 247 .func = cmd_desc, 247 248 .argc = 1, 248 .argv = &desc_argv 249 .argv = &desc_argv, 250 .hints_enum = cmdtab_enum 249 251 }; 250 252 … … 262 264 .func = cmd_symaddr, 263 265 .argc = 1, 264 .argv = &symaddr_argv 266 .argv = &symaddr_argv, 267 .hints_enum = symtab_hints_enum, 265 268 }; 266 269 … … 303 306 .func = cmd_call0, 304 307 .argc = 1, 305 .argv = &call0_argv 308 .argv = &call0_argv, 309 .hints_enum = symtab_hints_enum 306 310 }; 307 311 … … 318 322 .func = cmd_mcall0, 319 323 .argc = 1, 320 .argv = &mcall0_argv 324 .argv = &mcall0_argv, 325 .hints_enum = symtab_hints_enum 321 326 }; 322 327 … … 340 345 .func = cmd_call1, 341 346 .argc = 2, 342 .argv = call1_argv 347 .argv = call1_argv, 348 .hints_enum = symtab_hints_enum 343 349 }; 344 350 … … 367 373 .func = cmd_call2, 368 374 .argc = 3, 369 .argv = call2_argv 375 .argv = call2_argv, 376 .hints_enum = symtab_hints_enum 370 377 }; 371 378 … … 400 407 .func = cmd_call3, 401 408 .argc = 4, 402 .argv = call3_argv 409 .argv = call3_argv, 410 .hints_enum = symtab_hints_enum 403 411 }; 404 412 -
kernel/generic/src/console/kconsole.c
rdf425da rd4d8255 165 165 166 166 /** Try to find a command beginning with prefix */ 167 NO_TRACE static const char *cmdtab_search_one(const char *name, 168 link_t **startpos) 169 { 167 const char *cmdtab_enum(const char *name, const char **h, void **ctx) 168 { 169 link_t **startpos = (link_t**)ctx; 170 170 size_t namelen = str_length(name); 171 171 … … 183 183 184 184 if (str_lcmp(curname, name, namelen) == 0) { 185 *startpos = (*startpos)->next; 186 if (h) { 187 *h = hlp->description; 188 } 185 189 spinlock_unlock(&cmd_lock); 186 190 return (curname + str_lsize(curname, namelen)); … … 200 204 * 201 205 */ 202 NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev) 206 NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev, 207 hints_enum_func_t hints_enum) 203 208 { 204 209 const char *name = input; … … 212 217 size_t max_match_len = size; 213 218 size_t max_match_len_tmp = size; 214 size_t input_len = str_length(input); 215 link_t *pos = NULL; 219 void *pos = NULL; 216 220 const char *hint; 221 const char *help; 217 222 char *output = malloc(MAX_CMDLINE, 0); 218 223 size_t hints_to_show = MAX_TAB_HINTS - 1; … … 222 227 output[0] = 0; 223 228 224 while ((hint = cmdtab_search_one(name, &pos))) {225 if ((found == 0) || (str_length( output) > str_length(hint)))229 while ((hint = hints_enum(name, NULL, &pos))) { 230 if ((found == 0) || (str_length(hint) > str_length(output))) 226 231 str_cpy(output, MAX_CMDLINE, hint); 227 232 228 pos = pos->next;229 233 found++; 230 234 } … … 243 247 printf("\n"); 244 248 pos = NULL; 245 while (cmdtab_search_one(name, &pos)) { 246 cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link); 249 while ((hint = hints_enum(name, &help, &pos))) { 247 250 248 251 if (continue_showing_hints) { 249 printf("%s (%s)\n", hlp->name, hlp->description); 252 253 if (help) 254 printf("%s%s (%s)\n", name, hint, help); 255 else 256 printf("%s%s\n", name, hint); 257 250 258 --hints_to_show; 251 259 ++total_hints_shown; … … 258 266 } 259 267 260 pos = pos->next;261 262 268 for (max_match_len_tmp = 0; 263 269 (output[max_match_len_tmp] == 264 h lp->name[input_len +max_match_len_tmp]) &&270 hint[max_match_len_tmp]) && 265 271 (max_match_len_tmp < max_match_len); ++max_match_len_tmp); 266 272 … … 277 283 free(output); 278 284 return found; 285 } 286 287 NO_TRACE static cmd_info_t *parse_cmd(const wchar_t *cmdline) 288 { 289 size_t start = 0; 290 size_t end; 291 char *tmp; 292 293 while (isspace(cmdline[start])) 294 start++; 295 end = start + 1; 296 while (!isspace(cmdline[end])) 297 end++; 298 299 tmp = malloc(STR_BOUNDS(end - start + 1), 0); 300 301 wstr_to_str(tmp, end - start + 1, &cmdline[start]); 302 303 spinlock_lock(&cmd_lock); 304 305 list_foreach(cmd_list, link, cmd_info_t, hlp) { 306 spinlock_lock(&hlp->lock); 307 308 if (str_cmp(hlp->name, tmp) == 0) { 309 spinlock_unlock(&hlp->lock); 310 spinlock_unlock(&cmd_lock); 311 free(tmp); 312 return hlp; 313 } 314 315 spinlock_unlock(&hlp->lock); 316 } 317 318 free(tmp); 319 spinlock_unlock(&cmd_lock); 320 321 return NULL; 279 322 } 280 323 … … 338 381 if (beg == 0) { 339 382 /* Command completion */ 340 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev); 383 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev, 384 cmdtab_enum); 341 385 } else { 342 /* Symbol completion */ 343 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev); 386 /* Arguments completion */ 387 cmd_info_t *cmd = parse_cmd(current); 388 if (!cmd || !cmd->hints_enum) 389 continue; 390 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev, 391 cmd->hints_enum); 344 392 } 345 393 -
kernel/generic/src/debug/symtab.c
rdf425da rd4d8255 202 202 } 203 203 204 /** Symtab completion 205 * 206 * @param input Search string, completes to symbol name 207 * @param size Input buffer size 208 * 209 * @return 0 - nothing found, 1 - success, >1 print duplicates 210 * 211 */ 212 int symtab_compl(char *input, size_t size, indev_t *indev) 213 { 214 #ifdef CONFIG_SYMTAB 215 const char *name = input; 216 217 /* Allow completion of pointers */ 218 if ((name[0] == '*') || (name[0] == '&')) 219 name++; 220 221 /* Do not print all symbols */ 222 if (str_length(name) == 0) 223 return 0; 224 225 size_t found = 0; 226 size_t pos = 0; 227 const char *hint; 228 char output[MAX_SYMBOL_NAME]; 229 230 /* 231 * Maximum Match Length: Length of longest matching common substring in 232 * case more than one match is found. 233 */ 234 size_t max_match_len = size; 235 size_t max_match_len_tmp = size; 236 size_t input_len = str_length(input); 237 char *sym_name; 238 size_t hints_to_show = MAX_TAB_HINTS - 1; 239 size_t total_hints_shown = 0; 240 bool continue_showing_hints = true; 241 242 output[0] = 0; 243 244 while ((hint = symtab_search_one(name, &pos))) 245 pos++; 246 247 pos = 0; 248 249 while ((hint = symtab_search_one(name, &pos))) { 250 if ((found == 0) || (str_length(output) > str_length(hint))) 251 str_cpy(output, MAX_SYMBOL_NAME, hint); 252 253 pos++; 254 found++; 255 } 256 257 /* 258 * If the number of possible completions is more than MAX_TAB_HINTS, 259 * ask the user whether to display them or not. 260 */ 261 if (found > MAX_TAB_HINTS) { 262 printf("\n"); 263 continue_showing_hints = 264 console_prompt_display_all_hints(indev, found); 265 } 266 267 if ((found > 1) && (str_length(output) != 0)) { 268 printf("\n"); 269 pos = 0; 270 while (symtab_search_one(name, &pos)) { 271 sym_name = symbol_table[pos].symbol_name; 272 pos++; 273 274 if (continue_showing_hints) { 275 /* We are still showing hints */ 276 printf("%s\n", sym_name); 277 --hints_to_show; 278 ++total_hints_shown; 279 280 if ((hints_to_show == 0) && (total_hints_shown != found)) { 281 /* Ask the user to continue */ 282 continue_showing_hints = 283 console_prompt_more_hints(indev, &hints_to_show); 284 } 285 } 286 287 for (max_match_len_tmp = 0; 288 (output[max_match_len_tmp] == 289 sym_name[input_len + max_match_len_tmp]) && 290 (max_match_len_tmp < max_match_len); ++max_match_len_tmp); 291 292 max_match_len = max_match_len_tmp; 204 /** Symtab completion enum, see kernel/generic/include/kconsole.h */ 205 const char* symtab_hints_enum(const char *input, const char **help, 206 void **ctx) 207 { 208 #ifdef CONFIG_SYMTAB 209 size_t len = str_length(input); 210 struct symtab_entry **entry = (struct symtab_entry**)ctx; 211 212 if (*entry == NULL) 213 *entry = symbol_table; 214 215 for (; (*entry)->address_le; (*entry)++) { 216 const char *curname = (*entry)->symbol_name; 217 218 /* Find a ':' in curname */ 219 const char *colon = str_chr(curname, ':'); 220 if (colon == NULL) 221 continue; 222 223 if (str_length(curname) < len) 224 continue; 225 226 if (str_lcmp(input, curname, len) == 0) { 227 (*entry)++; 228 if (help) 229 *help = NULL; 230 return (curname + str_lsize(curname, len)); 293 231 } 294 295 /* Keep only the characters common in all completions */ 296 output[max_match_len] = 0; 297 } 298 299 if (found > 0) 300 str_cpy(input, size, output); 301 302 return found; 303 304 #else 305 return 0; 232 } 233 234 return NULL; 235 236 #else 237 return NULL; 306 238 #endif 307 239 } -
kernel/test/test.c
rdf425da rd4d8255 34 34 35 35 #include <test.h> 36 #include <str.h> 36 37 37 38 bool test_quiet; … … 68 69 }; 69 70 71 const char* tests_hints_enum(const char *input, const char **help, 72 void **ctx) 73 { 74 size_t len = str_length(input); 75 test_t **test = (test_t**)ctx; 76 77 if (*test == NULL) 78 *test = tests; 79 80 for (; (*test)->name; (*test)++) { 81 const char *curname = (*test)->name; 82 83 if (str_length(curname) < len) 84 continue; 85 86 if (str_lcmp(input, curname, len) == 0) { 87 (*test)++; 88 if (help) 89 *help = (*test)->desc; 90 return (curname + str_lsize(curname, len)); 91 } 92 } 93 94 return NULL; 95 } 96 70 97 /** @} 71 98 */ -
kernel/test/test.h
rdf425da rd4d8255 85 85 extern test_t tests[]; 86 86 87 extern const char* tests_hints_enum(const char *, const char **, void **); 88 87 89 #endif 88 90
Note:
See TracChangeset
for help on using the changeset viewer.