Ccli.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "stdinc.h"
  2. #include "9.h"
  3. typedef struct {
  4. char* argv0;
  5. int (*cmd)(int, char*[]);
  6. } Cmd;
  7. static struct {
  8. VtLock* lock;
  9. Cmd* cmd;
  10. int ncmd;
  11. int hi;
  12. } cbox;
  13. enum {
  14. NCmdIncr = 20,
  15. };
  16. int
  17. cliError(char* fmt, ...)
  18. {
  19. char *p;
  20. va_list arg;
  21. va_start(arg, fmt);
  22. p = vsmprint(fmt, arg);
  23. vtSetError("%s", p);
  24. free(p);
  25. va_end(arg);
  26. return 0;
  27. }
  28. int
  29. cliExec(char* buf)
  30. {
  31. int argc, i, r;
  32. char *argv[20], *p;
  33. p = vtStrDup(buf);
  34. if((argc = tokenize(p, argv, nelem(argv)-1)) == 0){
  35. vtMemFree(p);
  36. return 1;
  37. }
  38. argv[argc] = 0;
  39. if(argv[0][0] == '#'){
  40. vtMemFree(p);
  41. return 1;
  42. }
  43. vtLock(cbox.lock);
  44. for(i = 0; i < cbox.hi; i++){
  45. if(strcmp(cbox.cmd[i].argv0, argv[0]) == 0){
  46. vtUnlock(cbox.lock);
  47. if(!(r = cbox.cmd[i].cmd(argc, argv)))
  48. consPrint("%s\n", vtGetError());
  49. vtMemFree(p);
  50. return r;
  51. }
  52. }
  53. vtUnlock(cbox.lock);
  54. consPrint("%s: - eh?\n", argv[0]);
  55. vtMemFree(p);
  56. return 0;
  57. }
  58. int
  59. cliAddCmd(char* argv0, int (*cmd)(int, char*[]))
  60. {
  61. int i;
  62. Cmd *opt;
  63. vtLock(cbox.lock);
  64. for(i = 0; i < cbox.hi; i++){
  65. if(strcmp(argv0, cbox.cmd[i].argv0) == 0){
  66. vtUnlock(cbox.lock);
  67. return 0;
  68. }
  69. }
  70. if(i >= cbox.hi){
  71. if(cbox.hi >= cbox.ncmd){
  72. cbox.cmd = vtMemRealloc(cbox.cmd,
  73. (cbox.ncmd+NCmdIncr)*sizeof(Cmd));
  74. memset(&cbox.cmd[cbox.ncmd], 0, NCmdIncr*sizeof(Cmd));
  75. cbox.ncmd += NCmdIncr;
  76. }
  77. }
  78. opt = &cbox.cmd[cbox.hi];
  79. opt->argv0 = argv0;
  80. opt->cmd = cmd;
  81. cbox.hi++;
  82. vtUnlock(cbox.lock);
  83. return 1;
  84. }
  85. int
  86. cliInit(void)
  87. {
  88. cbox.lock = vtLockAlloc();
  89. cbox.cmd = vtMemAllocZ(NCmdIncr*sizeof(Cmd));
  90. cbox.ncmd = NCmdIncr;
  91. cbox.hi = 0;
  92. return 1;
  93. }