pipe_redir_parsing.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "sh.h"
  2. /*
  3. ** Fill redirections
  4. ** Else: fill pipe
  5. */
  6. void fill_pipe_redir_data(t_e *e, t_pipe *p, t_pipe_redir **t)
  7. {
  8. int j;
  9. j = -1;
  10. p->i = 0;
  11. while (p->cmd_pipe[++j] != NULL)
  12. {
  13. if (parse_double_redir(e, p->cmd_pipe[j], p, t) == 0)
  14. pipe_creation(t, p, p->cmd_pipe[j]);
  15. }
  16. t[p->i] = NULL;
  17. }
  18. void pipe_creation(t_pipe_redir **t, t_pipe *p, char *cmd)
  19. {
  20. t[p->i] = (t_pipe_redir*)malloc(sizeof(t_pipe_redir));
  21. t[p->i]->itxt = cmd;
  22. t[p->i]->ifd = 1;
  23. t[p->i]->operator = "|";
  24. t[p->i]->ofd = 0;
  25. t[p->i++]->otxt = NULL;
  26. }
  27. /*
  28. ** cat << end >> toto
  29. ** cat << end > toto
  30. ** cat < tests.sh > toto
  31. ** cat < tests.sh >> toto
  32. **
  33. ** Detect if there is two redirections:
  34. ** - first one < or << and snd one: > or >>
  35. ** If so, handle one redirection to the other:
  36. ** - split in two parts:
  37. ** - first part for classic redirection
  38. ** - second part for snd redirection
  39. ** Else, mono-redirection
  40. */
  41. int parse_double_redir(t_e *e, char *str, t_pipe *p, t_pipe_redir **t)
  42. {
  43. int first_chev;
  44. int snd_chev;
  45. char *cmd;
  46. int nchev;
  47. int ret;
  48. first_chev = check_chev_is_on_non_coted_block(e, str, '<');
  49. snd_chev = first_chev + 1 + \
  50. check_chev_is_on_non_coted_block(e, &str[first_chev + 1], '>');
  51. if (first_chev != -1 && snd_chev != -1 && snd_chev - first_chev > 0)
  52. {
  53. cmd = ft_strsub(str, 0, snd_chev);
  54. ret = parse_redirection(e, p, cmd, t);
  55. ft_strdel(&cmd);
  56. nchev = str[snd_chev] == str[snd_chev + 1] ? 2 : 1;
  57. t[p->i] = (t_pipe_redir*)malloc(sizeof(t_pipe_redir));
  58. t[p->i]->itxt = NULL;
  59. t[p->i]->operator = ft_strsub(&str[snd_chev], 0, nchev);
  60. t[p->i]->otxt = ft_strtrim(&str[snd_chev + nchev]);
  61. t[p->i++]->ofd = -100;
  62. p->pnbr++;
  63. }
  64. else
  65. ret = parse_redirection(e, p, str, t);
  66. return (ret);
  67. }
  68. /*
  69. ** Get chevrons positions
  70. ** Take closer chevron
  71. ** Prevent segfault by checking there is something before and after chevron
  72. ** Parse redirections: split in four parts:
  73. ** Get position of the first chevron
  74. ** Before chevron, chevron, after chevron
  75. ** Check if fd is specified
  76. ** Check if there is two chevrons
  77. ** Split with strsub
  78. */
  79. int parse_redirection(t_e *e, t_pipe *p, char *str, t_pipe_redir **t)
  80. {
  81. int chev;
  82. int chev2;
  83. int nchev;
  84. int fd;
  85. chev = check_chev_is_on_non_coted_block(e, str, '>');
  86. chev2 = check_chev_is_on_non_coted_block(e, str, '<');
  87. if (chev == -1 && chev2 == -1)
  88. return (0);
  89. chev = (chev != -1 && chev < chev2) || chev2 == -1 ? chev : chev2;
  90. if (check_before_after_chevron(str, chev) == 1)
  91. return (0);
  92. fd = str[chev - 1] == '1' || str[chev - 1] == '2' ? 1 : 0;
  93. nchev = str[chev] == str[chev + 1] ? 2 : 1;
  94. t[p->i] = (t_pipe_redir*)malloc(sizeof(t_pipe_redir));
  95. t[p->i]->itxt = ft_strtrim(ft_strsub(str, 0, chev - fd));
  96. t[p->i]->operator = ft_strsub(str, chev - fd, nchev + fd);
  97. t[p->i]->ifd = ft_isdigit(t[p->i]->operator[0]) ? \
  98. ft_atoi(t[p->i]->operator) : 1;
  99. parse_and(str, t[p->i], chev + nchev);
  100. if (t[p->i]->otxt != NULL)
  101. parse_redirection(e, p, t[p->i]->otxt, t);
  102. p->i++;
  103. return (1);
  104. }