cmd-list.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* $OpenBSD$ */
  2. /*
  3. * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
  14. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  15. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/types.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include "tmux.h"
  21. struct cmd_list *
  22. cmd_list_parse(int argc, char **argv, const char *file, u_int line,
  23. char **cause)
  24. {
  25. struct cmd_list *cmdlist;
  26. struct cmd *cmd;
  27. int i, lastsplit;
  28. size_t arglen, new_argc;
  29. char **copy_argv, **new_argv;
  30. copy_argv = cmd_copy_argv(argc, argv);
  31. cmdlist = xcalloc(1, sizeof *cmdlist);
  32. cmdlist->references = 1;
  33. TAILQ_INIT(&cmdlist->list);
  34. lastsplit = 0;
  35. for (i = 0; i < argc; i++) {
  36. arglen = strlen(copy_argv[i]);
  37. if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
  38. continue;
  39. copy_argv[i][arglen - 1] = '\0';
  40. if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
  41. copy_argv[i][arglen - 2] = ';';
  42. continue;
  43. }
  44. new_argc = i - lastsplit;
  45. new_argv = copy_argv + lastsplit;
  46. if (arglen != 1)
  47. new_argc++;
  48. cmd = cmd_parse(new_argc, new_argv, file, line, cause);
  49. if (cmd == NULL)
  50. goto bad;
  51. TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
  52. lastsplit = i + 1;
  53. }
  54. if (lastsplit != argc) {
  55. cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit,
  56. file, line, cause);
  57. if (cmd == NULL)
  58. goto bad;
  59. TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
  60. }
  61. cmd_free_argv(argc, copy_argv);
  62. return (cmdlist);
  63. bad:
  64. cmd_list_free(cmdlist);
  65. cmd_free_argv(argc, copy_argv);
  66. return (NULL);
  67. }
  68. void
  69. cmd_list_free(struct cmd_list *cmdlist)
  70. {
  71. struct cmd *cmd, *cmd1;
  72. if (--cmdlist->references != 0)
  73. return;
  74. TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) {
  75. TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
  76. args_free(cmd->args);
  77. free(cmd->file);
  78. free(cmd);
  79. }
  80. free(cmdlist);
  81. }
  82. char *
  83. cmd_list_print(struct cmd_list *cmdlist)
  84. {
  85. struct cmd *cmd;
  86. char *buf, *this;
  87. size_t len;
  88. len = 1;
  89. buf = xcalloc(1, len);
  90. TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
  91. this = cmd_print(cmd);
  92. len += strlen(this) + 3;
  93. buf = xrealloc(buf, len);
  94. strlcat(buf, this, len);
  95. if (TAILQ_NEXT(cmd, qentry) != NULL)
  96. strlcat(buf, " ; ", len);
  97. free(this);
  98. }
  99. return (buf);
  100. }