Kommando Interpreter C

IBM-Compiler sind nicht standardkonform? Kann ich mir nicht vorstellen. Hast du den Code wirklich 1 zu 1 kopiert? (Nimm am besten die angehängte Datei).

Es scheint aber meine Makros nicht zu mögen. Naja. Ersetze alle strcpy_s(a, b, c) durch strcpy(a, c) und alle memcpy_s(a, b, c, d) durch memcpy(a, c, d).
(wobei a, b, c, d jeweils nur repräsentativ für das steht, was an der jeweiligen Stelle stand).
Dann löschst du die beiden defines für memcpy_s und strcpy_s.

Gruss
cwriter
 
IBM-Compiler sind nicht standardkonform? Kann ich mir nicht vorstellen. Hast du den Code wirklich 1 zu 1 kopiert? (Nimm am besten die angehängte Datei).

Es scheint aber meine Makros nicht zu mögen. Naja. Ersetze alle strcpy_s(a, b, c) durch strcpy(a, c) und alle memcpy_s(a, b, c, d) durch memcpy(a, c, d).
(wobei a, b, c, d jeweils nur repräsentativ für das steht, was an der jeweiligen Stelle stand).
Dann löschst du die beiden defines für memcpy_s und strcpy_s.

Gruss
cwriter
Wie gesagt ich habe die angeängte Datei verwendet und lediglich Zeilen 1-3 gelöscht bzw auskommentiert.
Ich nehme jetzt die Anpassungen vor und melde mich dann.
 
IBM-Compiler sind nicht standardkonform? Kann ich mir nicht vorstellen. Hast du den Code wirklich 1 zu 1 kopiert? (Nimm am besten die angehängte Datei).

Es scheint aber meine Makros nicht zu mögen. Naja. Ersetze alle strcpy_s(a, b, c) durch strcpy(a, c) und alle memcpy_s(a, b, c, d) durch memcpy(a, c, d).
(wobei a, b, c, d jeweils nur repräsentativ für das steht, was an der jeweiligen Stelle stand).
Dann löschst du die beiden defines für memcpy_s und strcpy_s.

Gruss
cwriter
Also ich habe nun folgenden Code versucht zu kompilieren (Anpassungen von strcpy und memcpy gemacht):
C++:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int (*cmd_func)(int argc, char* argv[]);

typedef struct {
 char* name; 
 int parc;  
 char** parv; 
 int argc;  
 char** argv; 
 cmd_func func;

} cmd_desc;


bool exfree(void* p)
{
 if (p != NULL) {
  free(p);
  return true;
 }
 return false;
}


void clear_cmd_desc(cmd_desc* to_clear)
{
 exfree(to_clear->name);
 for (int i = 0; i < to_clear->parc; i++) exfree(to_clear->parv[i]);
 for (int i = 0; i < to_clear->argc; i++) exfree(to_clear->argv[i]);
 memset(to_clear, 0, sizeof(cmd_desc));
}


cmd_desc* create_cmd_desc(const char* name, int parc, const char** parv, cmd_func func)
{
 if (parc < 0) return NULL;
 cmd_desc* ptr = (cmd_desc*)calloc(1, sizeof(cmd_desc)); /
 if (ptr == NULL) return NULL;
 ptr->name = (char*)malloc(strlen(name) + 1);
 strcpy(ptr->name, strlen(name) + 1);

 if (parc > 0)
 {
  ptr->parc = parc;

  ptr->parv = (char**)malloc(sizeof(char*)*parc);
 
  for (int i = 0; i < parc; i++)
  {
   ptr->parv[i] = (char*)malloc(strlen(parv[i]) + 1);
   strcpy(ptr->parv[i], strlen(parv[i]) + 1);
  }
 }
 ptr->func = func;

 return ptr;


}


bool push_input(cmd_desc* d, const char* input)
{
 char** tmp = (char**)realloc(d->argv, sizeof(char*) * (d->argc + 1));
 if (tmp == NULL) return false;
 else d->argv = tmp;
 d->argv[d->argc] = (char*)malloc(strlen(input) + 1);
 strcpy(d->argv[d->argc], strlen(input) + 1);
 d->argc++;
 return true;
}


void clear_input(cmd_desc* d)
{
 for (int i = 0; i < d->argc; i++) exfree(d->argv[i]);
 exfree(d->argv);
 d->argv = NULL;
 d->argc = 0;
}


bool add_cmd_desc(cmd_desc** arr, size_t* index, size_t* arrsize, cmd_desc* desc)
{
 
 if (*index >= *arrsize)
 {
  cmd_desc* tmp = (cmd_desc*)realloc(*arr, sizeof(cmd_desc) * *arrsize * 2);
  if (tmp == NULL) return false;
  else {
   *arrsize *= 2;
   *arr = tmp;
  }
 }
 
 (*arr)[(*index)++] = *desc;

 
 free(desc);
 return true;
}


int adder(int argc, char* argv[])
{
 if (argc <= 0)
 {
  printf("Invalid parameters\n");
  return 0;
 }
 int sum = 0;
 for (int i = 0; i < argc; i++)
 {
  sum += atoi(argv[i]);
 }
 printf("Sum is %d, Average is %d and median is %d\n", sum, sum / argc, atoi(argv[argc / 2]));
 return sum;
}

int main(int argc, char* argv[])
{
 cmd_desc* cmd_desc_arr = NULL;
 size_t arr_ind = 0;
 size_t arr_size = 4;

 cmd_desc_arr = (cmd_desc*)calloc(arr_size, sizeof(cmd_desc));
 if (cmd_desc_arr == NULL) return -1;

 size_t bufstep = 256;
 size_t bufsize = 256;
 char* buf = (char*)calloc(bufsize, sizeof(char));
 char* bufbase = buf;

 if (buf == NULL)
 {
  free(cmd_desc_arr);
  return -1;
 }

 
 cmd_desc* d = create_cmd_desc("adder", 0, NULL, &adder);
 if (d == NULL) printf("Uh. Something really bad happened. And the programmer was too lazy to clean up... Take cover.\n");
 add_cmd_desc(&cmd_desc_arr, &arr_ind, &arr_size, d);

 printf("This is a little command line interface (cli) demo.\nEnter 'quit' to quit.\n");

 while (scanf("%255s", bufbase) > 0)
 {
  if (strcmp(bufbase, "quit") == 0) break;
  for (size_t i = 0; i < arr_ind; i++)
  {
  
   cmd_desc* d = &cmd_desc_arr[i];
  
   if (d->name == NULL) continue;

   if (strcmp(d->name, buf) == 0)
   {
    while (scanf("%255s", buf) > 0)
    {
     if (buf[0] == '<') break;

     if (buf[bufstep-2] != 0)
     {
      buf += bufstep-1;
     }

     if (bufbase[bufsize - 2] != 0) {
      char* tmp = (char*)realloc(bufbase, bufsize * 2);
      if (tmp == NULL) {
       printf("Failed to realloc.\n");
       goto end;
      }
      int diff = (buf - bufbase);
      bufbase = tmp;
      buf = buf + diff;

      bufsize *= 2;

      bufbase[bufsize - 2] = 0;
      bufbase[bufsize - 1] = 0;
     }

     push_input(d, bufbase);
    }

    d->func(d->argc, d->argv);

    clear_input(d);

    break;
   }
  }

  printf("Ladies and gentlemen, next round, your input please...\n");
 }
end:

 free(bufbase);

 for (size_t i = 0; i < arr_size; i++)
 {
  clear_cmd_desc(&cmd_desc_arr[i]);
 }
 exfree(cmd_desc_arr);

 getchar();
 return 0;
}

Folgende Fehler bekam ich raus (die Zeilennummer kann man glaub im Code oben an der Seite sehen oder?):

ERROR CCN3166 ./com.c:18 Definition of function bool requires parentheses.
ERROR CCN3276 ./com.c:18 Syntax error: possible missing '{'?
ERROR CCN3045 ./com.c:20 Undeclared identifier p.
ERROR CCN3045 ./com.c:22 Undeclared identifier true.
ERROR CCN3045 ./com.c:24 Undeclared identifier false.
ERROR CCN3993 ./com.c:31 The declaration part of a "for" statement is not allowed.
ERROR CCN3275 ./com.c:31 Unexpected text 'int' encountered.
ERROR CCN3993 ./com.c:32 The declaration part of a "for" statement is not allowed.
ERROR CCN3334 ./com.c:32 Identifier i has already been defined on line 31 of "./com.c".
ERROR CCN3275 ./com.c:32 Unexpected text 'int' encountered.
ERROR CCN3046 ./com.c:40 Syntax error.
ERROR CCN3275 ./com.c:40 Unexpected text '/' encountered.
ERROR CCN3280 ./com.c:43 Function argument assignment between types "const char*" and "unsigned int" is not allowed.
ERROR CCN3993 ./com.c:51 The declaration part of a "for" statement is not allowed.
ERROR CCN3275 ./com.c:51 Unexpected text 'int' encountered.
ERROR CCN3280 ./com.c:54 Function argument assignment between types "const char*" and "unsigned int" is not allowed.
ERROR CCN3166 ./com.c:65 Definition of function bool requires parentheses.
ERROR CCN3276 ./com.c:65 Syntax error: possible missing '{'?
ERROR CCN3045 ./com.c:67 Undeclared identifier d.
ERROR CCN3045 ./com.c:68 Undeclared identifier false.
ERROR CCN3045 ./com.c:70 Undeclared identifier input.
ERROR CCN3280 ./com.c:71 Function argument assignment between types "const char*" and "unsigned int" is not allowed.
ERROR CCN3045 ./com.c:73 Undeclared identifier true.
ERROR CCN3993 ./com.c:79 The declaration part of a "for" statement is not allowed.
ERROR CCN3275 ./com.c:79 Unexpected text 'int' encountered.
ERROR CCN3166 ./com.c:86 Definition of function bool requires parentheses.
ERROR CCN3276 ./com.c:86 Syntax error: possible missing '{'?
ERROR CCN3045 ./com.c:89 Undeclared identifier index.
ERROR CCN3045 ./com.c:89 Undeclared identifier arrsize.
ERROR CCN3045 ./com.c:91 Undeclared identifier arr.
ERROR CCN3045 ./com.c:92 Undeclared identifier false.
ERROR CCN3045 ./com.c:99 Undeclared identifier desc.
ERROR CCN3045 ./com.c:103 Undeclared identifier true.
ERROR CCN3275 ./com.c:114 Unexpected text 'int' encountered.
ERROR CCN3993 ./com.c:115 The declaration part of a "for" statement is not allowed.
ERROR CCN3275 ./com.c:115 Unexpected text 'int' encountered.
ERROR CCN3046 ./com.c:132 Syntax error.
ERROR CCN3046 ./com.c:133 Syntax error.
ERROR CCN3275 ./com.c:134 Unexpected text 'char' encountered.
ERROR CCN3275 ./com.c:135 Unexpected text 'char' encountered.
ERROR CCN3046 ./com.c:144 Syntax error.
ERROR CCN3993 ./com.c:153 The declaration part of a "for" statement is not allowed.
ERROR CCN3275 ./com.c:153 Unexpected text 'size_t' encountered.
ERROR CCN3275 ./com.c:177 Unexpected text 'int' encountered.
ERROR CCN3993 ./com.c:204 The declaration part of a "for" statement is not allowed.
ERROR CCN3275 ./com.c:204 Unexpected text 'size_t' encountered.
 
Moin,

irgendwie fehlt das was , oder?
Soll das eine eigene Klasse sein??
Falls ja, warum geht es nach den includes direkt mit TypDefs los??

Hast Du mal die fehlernummern gegooglet? Es gibt beim IBM doch jede Menge Erklärungen ....

Gruß Klaus
 
Oha. Mea Culpa.
Dir fehlt das include
#include <stdbool.h>
.
(Nur bei moderenen C-Versionen...)
Sag mal, nutzt dein Compiler irgendeinen prähistorischen Standard, aka c89 oder so? Kannst du das auf eine zeitgemässe Alternative (c99 oder c11) umstellen? Ansonsten wird das eine Menge Arbeit (und es gibt eigentlich keinen Grund mehr, heutzutage mit so alten Standards zu arbeiten...).
Warte mal... realloc und c89? Geht das überhaupt ohne void*?

Ansonsten müsstest du alle Variablen an den Anfang ihres Scopes setzen, bei allen for-Loops die Startkondition (int i = 0) aus dem Loop rausnehmen (also z.B. int i; for(i = 0; i < bla; i++)) und dann aufräumen, also Doppeldefinitionen eliminieren.

irgendwie fehlt das was , oder?
Was denn? :)

Soll das eine eigene Klasse sein??
In C? Unwahrscheinlich...

Falls ja, warum geht es nach den includes direkt mit TypDefs los??
Wo sollten die denn sonst hin?

size_t sollte aber eigentlich in stdio.h definiert sein.

Gruss
cwriter

OT: Oh Gott oh gott...
Lese gerade die Schauergeschichten von https://de.wikipedia.org/wiki/Varianten_der_Programmiersprache_C...
*Schauder*

Back to Topic: Nein, ernsthaft, tue dir C89 nicht an. Das ist völlig praxisfern. Wenn dein Prof das von dir verlangt, dann heuere einen Profikiller an hast du mein ernsthaftes Beileid.
 
Oha. Mea Culpa.
Dir fehlt das include
#include <stdbool.h>
.
(Nur bei moderenen C-Versionen...)
Sag mal, nutzt dein Compiler irgendeinen prähistorischen Standard, aka c89 oder so? Kannst du das auf eine zeitgemässe Alternative (c99 oder c11) umstellen? Ansonsten wird das eine Menge Arbeit (und es gibt eigentlich keinen Grund mehr, heutzutage mit so alten Standards zu arbeiten...).
Warte mal... realloc und c89? Geht das überhaupt ohne void*?

Ansonsten müsstest du alle Variablen an den Anfang ihres Scopes setzen, bei allen for-Loops die Startkondition (int i = 0) aus dem Loop rausnehmen (also z.B. int i; for(i = 0; i < bla; i++)) und dann aufräumen, also Doppeldefinitionen eliminieren.


Was denn? :)


In C? Unwahrscheinlich...


Wo sollten die denn sonst hin?

size_t sollte aber eigentlich in stdio.h definiert sein.

Gruss
cwriter

OT: Oh Gott oh gott...
Lese gerade die Schauergeschichten von https://de.wikipedia.org/wiki/Varianten_der_Programmiersprache_C...
*Schauder*

Back to Topic: Nein, ernsthaft, tue dir C89 nicht an. Das ist völlig praxisfern. Wenn dein Prof das von dir verlangt, dann heuere einen Profikiller an hast du mein ernsthaftes Beileid.

Also ich hab stdbool.h eingebaut, nun wurden die Fehler wieder weniger:

ERROR CCN3206 ./com_b.c:55 Suffix of integer constant 2nd is not valid.
ERROR CCN3010 ./com_b.c:55 Macro strcpy invoked with a null argument for parameter x.
ERROR CCN3041 ./com_b.c:55 The invocation of macro strcpy contains fewer arguments than are required by the macro definition.
ERROR CCN3209 ./com_b.c:165 Character constants must end before the end of a line.
WARNING CCN3076 ./com_b.c:165 Character constant 'cause I have no clue what they are for anyways.' has more than 4 characters. No more than rightmost 4 characters are used.
ERROR CCN3209 ./com_b.c:187 Character constants must end before the end of a line.
WARNING CCN3076 ./com_b.c:187 Character constant 'm too lazy now' has more than 4 characters. No more than rightmost 4 characters are used.
ERROR CCN3209 ./com_b.c:225 Character constants must end before the end of a line.
INFORMATIONAL CCN4118 ./com_b.c:225 Character constant 't.' has more than 1 character.


Der Compiler benutzt c89,aber umstellen kann ich es nicht,da es bei der Arbeit benutzt wird...Leider...
Und strcpy habe ich auch geändert.Was sind die übrigen Fehler nun genau?Kannst du damit was anfangen?
 
Der Compiler benutzt c89,aber umstellen kann ich es nicht,da es bei der Arbeit benutzt wird...Leider...
Kleines OT:
Wir haben 2016, bald 2017. Es gibt seit 6 Jahren C11 bzw. C+11, seit ~3 Jahren ist es benutzbar.
Es gibt seit fast 18 Jahren(!) C99. C89 ist schwieriger zu optimieren (register loops), schlechter zu lesen (Variablen vor Kilometern an Quellcode definiert, wirre Casts) und hat keinen einzigen Vorteil gegenüber C99 (ausser für Masochisten). Ganz ehrlich: Hätte ich die Wahl zwischen C89 und Assembly, würde ich Assembly nehmen...
</rant>

*Seufz*
Hilft ja alles nichts.
Also: Alle Kommentare (//...) solltest du durch Zeilenkommentare (/*...*/) ersetzen.

Zum Makro strcpy: Ich habe keinen Schimmer, wie IBM das implementiert. (strcpy ist eigentlich eine Funktion, kein Makro). Was sagt denn deine IDE, was die Definition des Makros ist?
Ausser, dein System ist nicht POSIX-Compliant, aber dann haben wir eh ein ganz anderes Problem...
Du hast aber scheinbar schon die Loops umstrukturiert. Allerdings stimmen jetzt die Zeilennummern auch nicht mehr...

Wie sieht denn den Code momentan aus?
(Sorry, dass sich das so hinzieht :( )

Gruss
cwriter

/EDIT: Beschwert sich der Compiler nicht bei meinen Funktionen? Eigentlich müssten die nach C89 so aufgebaut sein (Das wäre der älteste Standard. Ganz so schlimm ist es dann doch nicht :) ):
char * strcpy (String1, String2) char *String1; const char *String2;

-> Entweder ist das nicht C89 oder IBM hält nicht allzuviel vom Standard.
Oder hast du das schon korrigiert?

-> Es ist C89 :)

/EDIT2: Bei strcpy scheinst du strcpy_s(a, b, c) zu strcpy(a, b) statt strcpy(a, c) geändert zu haben. Das ist ein Grund für ein paar Fehler im Code.
 
Zuletzt bearbeitet:
Kleines OT:
Wir haben 2016, bald 2017. Es gibt seit 6 Jahren C11 bzw. C+11, seit ~3 Jahren ist es benutzbar.
Es gibt seit fast 18 Jahren(!) C99. C89 ist schwieriger zu optimieren (register loops), schlechter zu lesen (Variablen vor Kilometern an Quellcode definiert, wirre Casts) und hat keinen einzigen Vorteil gegenüber C99 (ausser für Masochisten). Ganz ehrlich: Hätte ich die Wahl zwischen C89 und Assembly, würde ich Assembly nehmen...
</rant>

*Seufz*
Hilft ja alles nichts.
Also: Alle Kommentare (//...) solltest du durch Zeilenkommentare (/*...*/) ersetzen.

Zum Makro strcpy: Ich habe keinen Schimmer, wie IBM das implementiert. (strcpy ist eigentlich eine Funktion, kein Makro). Was sagt denn deine IDE, was die Definition des Makros ist?
Ausser, dein System ist nicht POSIX-Compliant, aber dann haben wir eh ein ganz anderes Problem...
Du hast aber scheinbar schon die Loops umstrukturiert. Allerdings stimmen jetzt die Zeilennummern auch nicht mehr...

Wie sieht denn den Code momentan aus?
(Sorry, dass sich das so hinzieht :( )

Gruss
cwriter

/EDIT: Beschwert sich der Compiler nicht bei meinen Funktionen? Eigentlich müssten die nach C89 so aufgebaut sein (Das wäre der älteste Standard. Ganz so schlimm ist es dann doch nicht :) ):
char * strcpy (String1, String2) char *String1; const char *String2;

-> Entweder ist das nicht C89 oder IBM hält nicht allzuviel vom Standard.
Oder hast du das schon korrigiert?

-> Es ist C89 :)

/EDIT2: Bei strcpy scheinst du strcpy_s(a, b, c) zu strcpy(a, b) statt strcpy(a, c) geändert zu haben. Das ist ein Grund für ein paar Fehler im Code.
SORRY!! Es ist C99, nicht C89..

Der Code sieht aktuell so aus:

C++:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

//Function signature definition
typedef int (*cmd_func)(int argc, char* argv[]);


typedef struct {
        char* name;                     //Command name; will be checked against
        int parc;                       //param count: How many strings there are in parv
        char** parv;            //Names of the parameters (for whatever reason we have them here...)
        int argc;                       //argument count: Value to be passed to func
        char** argv;            //argument vector: Value to be passed to func
        cmd_func func;          //Actual command function

} cmd_desc;

bool exfree(void* p)
{
        if (p != NULL) {
                free(p);
                return true;
        }
        return false;
}

void clear_cmd_desc(cmd_desc* to_clear)
{
        exfree(to_clear->name);
        for (int i = 0; i < to_clear->parc; i++) exfree(to_clear->parv[i]);     //Free parameter names
        for (int i = 0; i < to_clear->argc; i++) exfree(to_clear->argv[i]);     //Free arguments
        memset(to_clear, 0, sizeof(cmd_desc));
}

cmd_desc* create_cmd_desc(const char* name, int parc, const char** parv, cmd_func func)
{
        if (parc < 0) return NULL;
        cmd_desc* ptr = (cmd_desc*)calloc(1, sizeof(cmd_desc)); //calloc is very nice here: it automatically sets the memory to 0
        if (ptr == NULL) return NULL;
        ptr->name = (char*)malloc(strlen(name) + 1);
        strcpy(ptr->name, name);                //This is non-standard. If errors occur: Remove the 2nd param and change to strcpy().

        //Some (illegal) shortcut.
        if (parc > 0)
        {
                ptr->parc = parc;

                ptr->parv = (char**)malloc(sizeof(char*)*parc);
                //Loop over all arguments to copy, then allocate, then copy
                for (int i = 0; i < parc; i++) {
                        ptr->parv[i] = (char*)malloc(strlen(parv[i]) + 1);
                        strcpy(ptr->parv[i], parv[i]);  //Non-standard again
                }
        }
        ptr->func = func;

        return ptr;


}

bool push_input(cmd_desc* d, const char* input)
{
        char** tmp = (char**)realloc(d->argv, sizeof(char*) * (d->argc + 1));   //WARNING: This is really bad. If you fancy, try making this more efficient.
        //One way of making the line above more efficient: Double the current size each time we would exceed the current memory limit. This would logarithmically decrease the need of new allocations.
        if (tmp == NULL) return false;
        else d->argv = tmp;
        d->argv[d->argc] = (char*)malloc(strlen(input) + 1);
        strcpy(d->argv[d->argc], input);
        d->argc++;
        return true;
}

void clear_input(cmd_desc* d)
{
        for (int i = 0; i < d->argc; i++) exfree(d->argv[i]);
        exfree(d->argv);
        d->argv = NULL;
        d->argc = 0;
}

bool add_cmd_desc(cmd_desc** arr, size_t* index, size_t* arrsize, cmd_desc* desc)
{
        //Logarithmic reallocation procedure
        if (*index >= *arrsize)
        {
                cmd_desc* tmp = (cmd_desc*)realloc(*arr, sizeof(cmd_desc) * *arrsize * 2);
                if (tmp == NULL) return false;
                else {
                        *arrsize *= 2;
                        *arr = tmp;
                }
        }
        //Set copy the contents of desc (*desc) to its location in the array
        (*arr)[(*index)++] = *desc;

        //Free desc as we have copied it already
        free(desc);
        return true;
}

int adder(int argc, char* argv[])
{
        if (argc <= 0)
        {
                printf("Invalid parameters\n");
                return 0;
        }
        int sum = 0;
        for (int i = 0; i < argc; i++)
        {
                sum += atoi(argv[i]);
        }
        printf("Sum is %d, Average is %d and median is %d\n", sum, sum / argc, atoi(argv[argc / 2]));
        return sum;
}

int main(int argc, char* argv[])
{
        cmd_desc* cmd_desc_arr = NULL;
        size_t arr_ind = 0;
        size_t arr_size = 4;

        cmd_desc_arr = (cmd_desc*)calloc(arr_size, sizeof(cmd_desc));
        if (cmd_desc_arr == NULL) return -1;

        size_t bufstep = 256;
        size_t bufsize = 256;
        char* buf = (char*)calloc(bufsize, sizeof(char));       //Input buffer
        char* bufbase = buf;

        if (buf == NULL)
        {
                free(cmd_desc_arr);     //Free some sad things
                return -1;
        }

        //Add our little example function. We shortcut the descriptions 'cause I have no clue what they are for anyways.
        cmd_desc* d = create_cmd_desc("adder", 0, NULL, &adder);
        if (d == NULL) printf("Uh. Something really bad happened. And the programmer was too lazy to clean up... Take cover.\n");
        add_cmd_desc(&cmd_desc_arr, &arr_ind, &arr_size, d);

        printf("This is a little command line interface (cli) demo.\nEnter 'quit' to quit.\n");



        while (scanf("%255s", bufbase) > 0) //Scanf string, 255 characters at max.
        {
                if (strcmp(bufbase, "quit") == 0) break;
                for (size_t i = 0; i < arr_ind; i++)
                {

                        cmd_desc* d = &cmd_desc_arr[i];

                        if (d->name == NULL) continue;

                        if (strcmp(d->name, buf) == 0)
                        {
                                //Function found, now we can read data in
                                while (scanf("%255s", buf) > 0) //This format string could be created with ssprintf, but I'm too lazy now
                                {
                                        if (buf[0] == '<') break;
                                        //If not full yet / Broken mid-word, so we need to fix it...
                                        if (buf[bufstep-2] != 0)
                                        {
                                                buf += bufstep-1;
                                        }

                                        if (bufbase[bufsize - 2] != 0) {
                                                //No more space here, so we have to increase the size
                                                char* tmp = (char*)realloc(bufbase, bufsize * 2);
                                                if (tmp == NULL) {
                                                        printf("Failed to realloc.\n");
                                                        goto end;
                                                }
                                                int diff = (buf - bufbase);
                                                bufbase = tmp;
                                                //Some magic here: Reset the buf to keep its relative offset to bufbase
                                                buf = buf + diff;

                                                bufsize *= 2;

                                                //Some safety measures
                                                bufbase[bufsize - 2] = 0;
                                                bufbase[bufsize - 1] = 0;
                                        }
                                        //Else we are done here and we can add the argument

                                        push_input(d, bufbase);
                                }

                                //Call the functions
                                d->func(d->argc, d->argv);

                                //Clean up
                                clear_input(d);

                                //We could cleanup, i.e. reduce the size of the input buffer here. I won't.
                                break;  //Break as there should only be one function per name
                        }
                }



                printf("Ladies and gentlemen, next round, your input please...\n");
        }
end:

        free(bufbase);

        for (size_t i = 0; i < arr_size; i++)
        {
                clear_cmd_desc(&cmd_desc_arr[i]);
        }
        exfree(cmd_desc_arr);

        getchar();
        return 0;
}
 
Zurück