Subversion Repositories HelenOS-historic

Rev

Rev 596 | Rev 602 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 596 Rev 601
Line 67... Line 67...
67
spinlock_t cmd_lock;    /**< Lock protecting command list. */
67
spinlock_t cmd_lock;    /**< Lock protecting command list. */
68
link_t cmd_head;    /**< Command list. */
68
link_t cmd_head;    /**< Command list. */
69
 
69
 
70
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
70
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
71
static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end);
71
static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end);
-
 
72
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
72
 
73
 
73
/** Initialize kconsole data structures. */
74
/** Initialize kconsole data structures. */
74
void kconsole_init(void)
75
void kconsole_init(void)
75
{
76
{
-
 
77
    int i;
-
 
78
 
76
    spinlock_initialize(&cmd_lock, "kconsole_cmd");
79
    spinlock_initialize(&cmd_lock, "kconsole_cmd");
77
    list_initialize(&cmd_head);
80
    list_initialize(&cmd_head);
78
 
81
 
79
    cmd_init();
82
    cmd_init();
-
 
83
    for (i=0; i<KCONSOLE_HISTORY; i++)
-
 
84
        history[i][0] = '\0';
80
}
85
}
81
 
86
 
82
 
87
 
83
/** Register kconsole command.
88
/** Register kconsole command.
84
 *
89
 *
Line 135... Line 140...
135
   
140
   
136
    spinlock_unlock(&cmd_lock);
141
    spinlock_unlock(&cmd_lock);
137
    return 1;
142
    return 1;
138
}
143
}
139
 
144
 
-
 
145
static void rdln_print_c(char ch, int count)
-
 
146
{
-
 
147
    int i;
-
 
148
    for (i=0;i<count;i++)
-
 
149
        putchar(ch);
-
 
150
}
-
 
151
 
-
 
152
static void insert_char(char *str, char ch, int pos)
-
 
153
{
-
 
154
    int i;
-
 
155
   
-
 
156
    for (i=strlen(str);i > pos; i--)
-
 
157
        str[i] = str[i-1];
-
 
158
    str[pos] = ch;
-
 
159
}
-
 
160
 
-
 
161
static const char * cmdtab_search_one(const char *name,link_t **startpos)
-
 
162
{
-
 
163
    int namelen = strlen(name);
-
 
164
    const char *curname;
-
 
165
    char *foundsym = NULL;
-
 
166
    int foundpos = 0;
-
 
167
 
-
 
168
    spinlock_lock(&cmd_lock);
-
 
169
 
-
 
170
    if (!*startpos)
-
 
171
        *startpos = cmd_head.next;
-
 
172
 
-
 
173
    for (;*startpos != &cmd_head;*startpos = (*startpos)->next) {
-
 
174
        cmd_info_t *hlp;
-
 
175
        hlp = list_get_instance(*startpos, cmd_info_t, link);
-
 
176
 
-
 
177
        curname = hlp->name;
-
 
178
        if (strlen(curname) < namelen)
-
 
179
            continue;
-
 
180
        if (strncmp(curname, name, namelen) == 0) {
-
 
181
            spinlock_unlock(&cmd_lock);
-
 
182
            return curname+namelen;
-
 
183
        }
-
 
184
    }
-
 
185
    spinlock_unlock(&cmd_lock);
-
 
186
    return NULL;
-
 
187
}
-
 
188
 
-
 
189
 
-
 
190
/** Command completion of the commands
-
 
191
 *
-
 
192
 * @param name - string to match, changed to hint on exit
-
 
193
 * @return number of found matches
-
 
194
 */
-
 
195
static int cmdtab_compl(char *name)
-
 
196
{
-
 
197
    char output[MAX_SYMBOL_NAME+1];
-
 
198
    link_t *startpos = NULL;
-
 
199
    const char *foundtxt;
-
 
200
    int found = 0;
-
 
201
    int i;
-
 
202
 
-
 
203
    output[0] = '\0';
-
 
204
    while ((foundtxt = cmdtab_search_one(name, &startpos))) {
-
 
205
        startpos = startpos->next;
-
 
206
        if (!found)
-
 
207
            strncpy(output, foundtxt, strlen(foundtxt)+1);
-
 
208
        else {
-
 
209
            for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
-
 
210
                ;
-
 
211
            output[i] = '\0';
-
 
212
        }
-
 
213
        found++;
-
 
214
    }
-
 
215
    if (!found)
-
 
216
        return 0;
-
 
217
 
-
 
218
    if (found > 1) {
-
 
219
        printf("\n");
-
 
220
        startpos = NULL;
-
 
221
        while ((foundtxt = cmdtab_search_one(name, &startpos))) {
-
 
222
            cmd_info_t *hlp;
-
 
223
            hlp = list_get_instance(startpos, cmd_info_t, link);
-
 
224
            printf("%s - %s\n", hlp->name, hlp->description);
-
 
225
            startpos = startpos->next;
-
 
226
        }
-
 
227
    }
-
 
228
    strncpy(name, output, MAX_SYMBOL_NAME);
-
 
229
    return found;
-
 
230
   
-
 
231
}
-
 
232
 
-
 
233
static char * clever_readline(const char *prompt, chardev_t *input)
-
 
234
{
-
 
235
    static int histposition = 0;
-
 
236
 
-
 
237
    char tmp[MAX_CMDLINE+1];
-
 
238
    int curlen = 0, position = 0;
-
 
239
    char *current = history[histposition];
-
 
240
    int i;
-
 
241
    char c;
-
 
242
 
-
 
243
    printf("%s> ", prompt);
-
 
244
    while (1) {
-
 
245
        c = _getc(input);
-
 
246
        if (c == '\n') {
-
 
247
            putchar(c);
-
 
248
            break;
-
 
249
        } if (c == '\b') {
-
 
250
            if (position == 0)
-
 
251
                continue;
-
 
252
            for (i=position; i<curlen;i++)
-
 
253
                current[i-1] = current[i];
-
 
254
            curlen--;
-
 
255
            position--;
-
 
256
            putchar('\b');
-
 
257
            for (i=position;i<curlen;i++)
-
 
258
                putchar(current[i]);
-
 
259
            putchar(' ');
-
 
260
            rdln_print_c('\b',curlen-position+1);
-
 
261
            continue;
-
 
262
        }
-
 
263
        if (c == '\t') {
-
 
264
            int found;
-
 
265
 
-
 
266
            /* Move to the end of the word */
-
 
267
            for (;position<curlen && current[position]!=' ';position++)
-
 
268
                putchar(current[position]);
-
 
269
            /* Copy to tmp last word */
-
 
270
            for (i=position-1;i >= 0 && current[i]!=' ' ;i--)
-
 
271
                ;
-
 
272
            /* If word begins with * or &, skip it */
-
 
273
            if (tmp[0] == '*' || tmp[0] == '&')
-
 
274
                for (i=1;tmp[i];i++)
-
 
275
                    tmp[i-1] = tmp[i];
-
 
276
            i++; /* I is at the start of the word */
-
 
277
            strncpy(tmp, current+i, position-i+1);
-
 
278
 
-
 
279
            if (i==0) { /* Command completion */
-
 
280
                found = cmdtab_compl(tmp);
-
 
281
            } else { /* Symtab completion */
-
 
282
                found = symtab_compl(tmp);
-
 
283
            }
-
 
284
 
-
 
285
            if (found == 0)
-
 
286
                continue;
-
 
287
            for (i=0;tmp[i] && curlen < MAX_CMDLINE;i++,curlen++)
-
 
288
                insert_char(current, tmp[i], i+position);
-
 
289
            if (found == 1) { /* One match */
-
 
290
                for (i=position;i<curlen;i++)
-
 
291
                    putchar(current[i]);
-
 
292
                position += strlen(tmp);
-
 
293
                /* Add space to end */
-
 
294
                if (position == curlen && curlen < MAX_CMDLINE) {
-
 
295
                    current[position] = ' ';
-
 
296
                    curlen++;
-
 
297
                    position++;
-
 
298
                    putchar(' ');
-
 
299
                }
-
 
300
            } else {
-
 
301
                printf("%s> ", prompt);
-
 
302
                for (i=0; i<curlen;i++)
-
 
303
                    putchar(current[i]);
-
 
304
                position += strlen(tmp);
-
 
305
            }
-
 
306
            rdln_print_c('\b', curlen-position);
-
 
307
            continue;
-
 
308
        }
-
 
309
        if (c == 0x1b) {
-
 
310
            c = _getc(input);
-
 
311
            if (c!= 0x5b)
-
 
312
                continue;
-
 
313
            c = _getc(input);
-
 
314
            if (c == 0x44) { /* Left */
-
 
315
                if (position > 0) {
-
 
316
                    putchar('\b');
-
 
317
                    position--;
-
 
318
                }
-
 
319
                continue;
-
 
320
            }
-
 
321
            if (c == 0x43) { /* Right */
-
 
322
                if (position < curlen) {
-
 
323
                    putchar(current[position]);
-
 
324
                    position++;
-
 
325
                }
-
 
326
                continue;
-
 
327
            }
-
 
328
            if (c == 0x41 || c == 0x42) { /* Up,down */
-
 
329
                rdln_print_c('\b',position);
-
 
330
                rdln_print_c(' ',curlen);
-
 
331
                rdln_print_c('\b',curlen);
-
 
332
                if (c == 0x41)
-
 
333
                    histposition--;
-
 
334
                else
-
 
335
                    histposition++;
-
 
336
                if (histposition < 0)
-
 
337
                    histposition = KCONSOLE_HISTORY -1 ;
-
 
338
                else
-
 
339
                    histposition =  histposition % KCONSOLE_HISTORY;
-
 
340
                current = history[histposition];
-
 
341
                printf("%s", current);
-
 
342
                curlen = strlen(current);
-
 
343
                position = curlen;
-
 
344
                continue;
-
 
345
            }
-
 
346
            continue;
-
 
347
        }
-
 
348
        if (curlen >= MAX_CMDLINE)
-
 
349
            continue;
-
 
350
 
-
 
351
        insert_char(current, c, position);
-
 
352
 
-
 
353
        curlen++;
-
 
354
        for (i=position;i<curlen;i++)
-
 
355
            putchar(current[i]);
-
 
356
        position++;
-
 
357
        rdln_print_c('\b',curlen-position);
-
 
358
    }
-
 
359
    histposition++;
-
 
360
    histposition = histposition % KCONSOLE_HISTORY;
-
 
361
    current[curlen] = '\0';
-
 
362
    return current;
-
 
363
}
-
 
364
 
140
/** Kernel console managing thread.
365
/** Kernel console managing thread.
141
 *
366
 *
142
 * @param arg Not used.
367
 * @param arg Not used.
143
 */
368
 */
144
void kconsole(void *arg)
369
void kconsole(void *arg)
145
{
370
{
146
    char cmdline[MAX_CMDLINE+1];
-
 
147
    cmd_info_t *cmd_info;
371
    cmd_info_t *cmd_info;
148
    count_t len;
372
    count_t len;
-
 
373
    char *cmdline;
149
 
374
 
150
    if (!stdin) {
375
    if (!stdin) {
151
        printf("%s: no stdin\n", __FUNCTION__);
376
        printf("%s: no stdin\n", __FUNCTION__);
152
        return;
377
        return;
153
    }
378
    }
154
   
379
   
155
    while (true) {
380
    while (true) {
156
        printf("%s> ", __FUNCTION__);
381
        cmdline = clever_readline(__FUNCTION__, stdin);
157
        if (!(len = gets(stdin, cmdline, sizeof(cmdline))))
382
        len = strlen(cmdline);
-
 
383
        if (!len)
158
            continue;
384
            continue;
159
        cmdline[len] = '\0';
-
 
160
        cmd_info = parse_cmdline(cmdline, len);
385
        cmd_info = parse_cmdline(cmdline, len);
161
        if (!cmd_info)
386
        if (!cmd_info)
162
            continue;
387
            continue;
163
        (void) cmd_info->func(cmd_info->argv);
388
        (void) cmd_info->func(cmd_info->argv);
164
    }
389
    }