1 | //#define DYN_ARGS
|
2 | #include <stdio.h>
|
3 | #include <stdlib.h> /* Atoi */
|
4 | #include <conio.h> /* getch => kein Echo */
|
5 | #include "debug.h"
|
6 |
|
7 | #define MAX_ARGS 10 /* Anzahl der Argumente ohne realloc */
|
8 |
|
9 | /* Kommando-Struktur, einfach nach Belieben erweitern
|
10 | *
|
11 | * {"BEFEHL ... Kurzbeschreibung\n", funktionsname, "Syntaxhilfe\n"},
|
12 | * ^Leerzeichen zwischen BEFEHL und "..." zwingend notwendig!!!
|
13 | * Prototypen der Funktionen in debug.h eintragen!
|
14 | */
|
15 | const debug_commands f[] = {
|
16 | {"add ... add two numbers\n", cmd_add, "add <number> <number>\n"},
|
17 | {"mul ... multiply two numbers\n", cmd_mul, "mul <number> <number>\n"},
|
18 | {"help .. Command overview/help\n", cmd_help,"help [command]\n"},
|
19 | {"? .... Command overview/help\n", cmd_help,"? [command]\n"},
|
20 | {"exit .. exit\n", cmd_exit, "x\n"}
|
21 | };
|
22 |
|
23 | #define COMMANDS 5 /* Anzahl der Kommandos in debug_commands f[] */
|
24 | #define COMMAND_BUFFER 80 /* Eingabepuffer */
|
25 |
|
26 | int exit_debug = 0; /* Wird durch cmd_exit auf 1 gesetzt */
|
27 |
|
28 | /* Hauptfunktion, wird nicht verlassen
|
29 | *
|
30 | */
|
31 | void debug(){
|
32 | char debug[COMMAND_BUFFER]; /* Buffer für Debug-Kommando */
|
33 | unsigned char i;
|
34 |
|
35 | printf("\n========= Console ==========\n");
|
36 | printf("Enter '?' for command overview\n");
|
37 | while(1){
|
38 | i = 0;
|
39 |
|
40 | printf("\n# "); /* Weils toll aussieht */
|
41 |
|
42 | do{
|
43 | debug[i] = getch();
|
44 | putchar(debug[i]); /* Echo */
|
45 | if(debug[i] == '\b' && i){ /* Backspace? */
|
46 | printf(" \b"); /* Leerzeichen ausgeben + Cursor zurück*/
|
47 | i--; /* letztes Zeichen löschen */
|
48 | }
|
49 | else{
|
50 | i++;
|
51 | }
|
52 | if(i >= COMMAND_BUFFER -1){ /* Kommando zu lang */
|
53 | i = 0;
|
54 | printf("\nCommand too long\n");
|
55 | continue;
|
56 | }
|
57 | /* Schleife bei ENTER verlassen */
|
58 | }while(debug[i-1] != '\r' && debug[i-1] != '\n');
|
59 |
|
60 | if(i == 1) /* Kein Kommando eingegeben */
|
61 | continue;
|
62 | debug[i-1] = '\0'; /* Stringterminierung */
|
63 | putchar('\n');
|
64 |
|
65 | if(i > 0)
|
66 | parse_and_call_cmd(debug); /* Kommando suchen und ausführen */
|
67 | if(exit_debug) /* Wenn exit eingegeben */
|
68 | break;
|
69 | }
|
70 | }
|
71 |
|
72 | /* Addiert zwei Zahlen */
|
73 | void cmd_add(char argc, char **argv){
|
74 | int no1, no2;
|
75 | if(argc == 3){
|
76 | no1 = atoi(argv[1]);
|
77 | no2 = atoi(argv[2]);
|
78 | printf("%d + %d = %d", no1, no2, no1 + no2);
|
79 | }
|
80 | }
|
81 |
|
82 | /* Multipliziert zwei Zahlen */
|
83 | void cmd_mul(char argc, char **argv){
|
84 | int no1, no2;
|
85 | if(argc == 3){
|
86 | no1 = atoi(argv[1]);
|
87 | no2 = atoi(argv[2]);
|
88 | printf("%d * %d = %d", no1, no2, no1 * no2);
|
89 | }
|
90 | else
|
91 | cmd_help(2,argv-1); /* Kleiner Trick für Syntax-Ausgabe */
|
92 | }
|
93 |
|
94 | void cmd_exit(char argc, char **argv){
|
95 | exit_debug = 1;
|
96 | }
|
97 |
|
98 | void cmd_help(char argc, char **argv){
|
99 | unsigned char i;
|
100 | unsigned char cmd_pos;
|
101 |
|
102 | if(argc == 2){ /* Kommandospez. Hilfe? */
|
103 | cmd_pos = is_dbg_command(argv[1]);
|
104 | /* Debug-Kommando? Ja => Syntax ausgeben */
|
105 | if(cmd_pos != COMMANDS + 1 ){
|
106 | printf("\n[..] - optional argument\n<..> - required argument\n");
|
107 | printf("\n%sSyntax: %s", f[cmd_pos].nptr, f[cmd_pos].syntax);
|
108 | }
|
109 | else /* Kommando nicht gefunden */
|
110 | printf("Command not found\n");
|
111 | }
|
112 | else{ /* Befehlsübersicht ausgeben */
|
113 | for(i = 0; i < COMMANDS; i++)
|
114 | printf(f[i].nptr);
|
115 | }
|
116 | }
|
117 |
|
118 | /* Extrahiert und zählt die Argumente, sucht das Kommando über
|
119 | * is_dbg_command und führt es dann aus.
|
120 | *
|
121 | */
|
122 | void parse_and_call_cmd(char *cmdptr){
|
123 | unsigned char argc=0, cmd_pos;
|
124 |
|
125 | #ifndef DYN_ARGS
|
126 | unsigned char *argv[MAX_ARGS];
|
127 | #else
|
128 | unsigned char **argv = NULL;
|
129 | argv = (unsigned char **)malloc(sizeof(char **));
|
130 | #endif
|
131 |
|
132 | argv[argc++] = cmdptr; /* Kommando selbst in argv[0] */
|
133 | while(1){
|
134 | cmdptr++;
|
135 | if(*cmdptr == ' '){
|
136 | *cmdptr = '\0';
|
137 | while(*++cmdptr == ' '); /* Leerzeichen überspringen */
|
138 | #ifdef DYN_ARGS
|
139 | argv = realloc(argv, (argc+1)*sizeof(char **));
|
140 | #else
|
141 | if(argc > 9){
|
142 | printf("\nToo many arguments!\n");
|
143 | return;
|
144 | }
|
145 | #endif
|
146 | argv[argc++] = cmdptr;
|
147 | }
|
148 | else if(*cmdptr == '\0'){
|
149 | break;
|
150 | }
|
151 | }
|
152 | cmd_pos = is_dbg_command(argv[0]);
|
153 | if(cmd_pos == COMMANDS + 1) /* Befehl nicht gefunden */
|
154 | printf("\nUnknown command\n");
|
155 | else{
|
156 | (f[cmd_pos].fptr)(argc, (char **)argv); /* Funktion aufrufen */
|
157 | }
|
158 | #ifdef DYN_ARGS
|
159 | free(argv);
|
160 | #endif
|
161 | }
|
162 |
|
163 | /* Sucht das Kommando in dem debug_commands-Struct und liefert
|
164 | * die Position im Struct zurück
|
165 | */
|
166 | char is_dbg_command(char *cmdptr){
|
167 | unsigned char i=0, j=0, error;
|
168 |
|
169 | while(i < COMMANDS ){ /* Alle Kommandos durchsuchen */
|
170 | error = 0;
|
171 | while(f[i].nptr[j] != ' '){
|
172 | if(f[i].nptr[j] != cmdptr[j]){
|
173 | error = 1;
|
174 | break; /* Abweichung => nächsten Befehl testen */
|
175 | }
|
176 | j++;
|
177 | }
|
178 | if(!(error == 0 && (cmdptr[j] == ' ' || cmdptr[j] == '\0') )){
|
179 | error = 1;
|
180 | i++;
|
181 | j=0;
|
182 | }
|
183 | else /* Kommando gefunden, error = 0 */
|
184 | break;
|
185 | }
|
186 | if(error==0)
|
187 | return i;
|
188 | else
|
189 | return COMMANDS+1;
|
190 | }
|
191 |
|
192 | /* Main, nur zum testen */
|
193 | int main(){
|
194 | debug();
|
195 | return 0;
|
196 | }
|