shell_file.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include <stdlib.h>
  2. #include <assert.h>
  3. #include "lub/string.h"
  4. #include "private.h"
  5. /*----------------------------------------------------------- */
  6. static int clish_shell_push(clish_shell_t * this, FILE * file,
  7. const char *fname, bool_t stop_on_error)
  8. {
  9. /* Allocate a control node */
  10. clish_shell_file_t *node = malloc(sizeof(clish_shell_file_t));
  11. assert(this);
  12. assert(node);
  13. /* intialise the node */
  14. node->file = file;
  15. if (fname)
  16. node->fname = lub_string_dup(fname);
  17. else
  18. node->fname = NULL;
  19. node->line = 0;
  20. node->stop_on_error = stop_on_error;
  21. node->next = this->current_file;
  22. /* put the node at the top of the file stack */
  23. this->current_file = node;
  24. /* now switch the terminal's input stream */
  25. tinyrl__set_istream(this->tinyrl, file);
  26. return 0;
  27. }
  28. /*----------------------------------------------------------- */
  29. int clish_shell_push_file(clish_shell_t * this, const char * fname,
  30. bool_t stop_on_error)
  31. {
  32. FILE *file;
  33. int res;
  34. assert(this);
  35. if (!fname)
  36. return -1;
  37. file = fopen(fname, "r");
  38. if (!file)
  39. return -1;
  40. res = clish_shell_push(this, file, fname, stop_on_error);
  41. if (res)
  42. fclose(file);
  43. return res;
  44. }
  45. /*----------------------------------------------------------- */
  46. int clish_shell_push_fd(clish_shell_t *this, FILE *file,
  47. bool_t stop_on_error)
  48. {
  49. return clish_shell_push(this, file, NULL, stop_on_error);
  50. }
  51. /*----------------------------------------------------------- */
  52. int clish_shell_pop_file(clish_shell_t *this)
  53. {
  54. int result = -1;
  55. clish_shell_file_t *node = this->current_file;
  56. if (!node)
  57. return -1;
  58. /* remove the current file from the stack... */
  59. this->current_file = node->next;
  60. /* and close the current file... */
  61. fclose(node->file);
  62. if (node->next) {
  63. /* now switch the terminal's input stream */
  64. tinyrl__set_istream(this->tinyrl, node->next->file);
  65. result = 0;
  66. }
  67. /* and free up the memory */
  68. if (node->fname)
  69. lub_string_free(node->fname);
  70. free(node);
  71. return result;
  72. }
  73. /*----------------------------------------------------------- */