kpargv.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /** @file kpargv.c
  2. */
  3. #include <assert.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <faux/list.h>
  8. #include <klish/khelper.h>
  9. #include <klish/kentry.h>
  10. #include <klish/kpargv.h>
  11. struct kpargv_s {
  12. faux_list_t *pargs;
  13. kpargv_status_e status; // Parse status
  14. size_t level; // Number of path's level where command was found
  15. const kentry_t *command; // ENTRY that consider as command (has ACTIONs)
  16. bool_t continuable; // Last argument can be expanded
  17. };
  18. // Level
  19. KGET(pargv, kpargv_status_e, status);
  20. KSET(pargv, kpargv_status_e, status);
  21. // Level
  22. KGET(pargv, size_t, level);
  23. KSET(pargv, size_t, level);
  24. // Command
  25. KGET(pargv, const kentry_t *, command);
  26. KSET(pargv, const kentry_t *, command);
  27. // Continuable
  28. KGET_BOOL(pargv, continuable);
  29. KSET_BOOL(pargv, continuable);
  30. // Pargs
  31. KGET(pargv, faux_list_t *, pargs);
  32. KADD_NESTED(pargv, parg);
  33. KNESTED_LEN(pargv, parg);
  34. KNESTED_IS_EMPTY(pargv, parg);
  35. KNESTED_ITER(pargv, parg);
  36. KNESTED_EACH(pargv, parg);
  37. int kpargv_pargs_kcompare(const void *key, const void *list_item)
  38. {
  39. const kentry_t *f = (const kentry_t *)key;
  40. const kparg_t *s = (const kparg_t *)list_item;
  41. if (f == kparg_entry(s))
  42. return 0;
  43. return 1;
  44. }
  45. kpargv_t *kpargv_new()
  46. {
  47. kpargv_t *pargv = NULL;
  48. pargv = faux_zmalloc(sizeof(*pargv));
  49. assert(pargv);
  50. if (!pargv)
  51. return NULL;
  52. // Initialization
  53. pargv->status = KPARSE_NONE;
  54. pargv->level = 0;
  55. pargv->command = NULL;
  56. // Parsed arguments list
  57. pargv->pargs = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
  58. NULL, kpargv_pargs_kcompare, (void (*)(void *))kparg_free);
  59. assert(pargv->pargs);
  60. return pargv;
  61. }
  62. void kpargv_free(kpargv_t *pargv)
  63. {
  64. if (!pargv)
  65. return;
  66. faux_list_free(pargv->pargs);
  67. free(pargv);
  68. }
  69. kparg_t *kpargv_pargs_last(const kpargv_t *pargv)
  70. {
  71. assert(pargv);
  72. if (!pargv)
  73. return NULL;
  74. if (kpargv_pargs_is_empty(pargv))
  75. return NULL;
  76. return (kparg_t *)faux_list_data(faux_list_tail(pargv->pargs));
  77. }
  78. kparg_t *kpargv_entry_exists(const kpargv_t *pargv, const void *entry)
  79. {
  80. assert(pargv);
  81. if (!pargv)
  82. return NULL;
  83. assert(entry);
  84. if (!entry)
  85. return NULL;
  86. return (kparg_t *)faux_list_kfind(pargv->pargs, entry);
  87. }
  88. const char *kpargv_status_str(const kpargv_t *pargv)
  89. {
  90. const char *s = "Unknown";
  91. assert(pargv);
  92. if (!pargv)
  93. return NULL;
  94. switch (kpargv_status(pargv)) {
  95. case KPARSE_NONE:
  96. s = "None";
  97. break;
  98. case KPARSE_OK:
  99. s = "Ok";
  100. break;
  101. case KPARSE_INPROGRESS:
  102. s = "In progress";
  103. break;
  104. case KPARSE_NOTFOUND:
  105. s = "Not found";
  106. break;
  107. case KPARSE_INCOMPLETED:
  108. s = "Incompleted";
  109. break;
  110. case KPARSE_ILLEGAL:
  111. s = "Illegal";
  112. break;
  113. case KPARSE_ERROR:
  114. s = "Error";
  115. break;
  116. }
  117. return s;
  118. }