** Read input from *in and process it. If *in==0 then input ** is interactive - the user is typing it it. Otherwise, input ** is coming from a file or device. A prompt is issued and history ** is saved only if input is interactive. An interrupt signal will ** cause this routine to exit immediately, unless input is interactive. ** ** Return the number of errors. */
| 2764 | ** Return the number of errors. |
| 2765 | */ |
| 2766 | int ShellState::ProcessInput(InputMode mode) { |
| 2767 | char *zLine = nullptr; /* A single input line */ |
| 2768 | char *zSql = nullptr; /* Accumulated SQL text */ |
| 2769 | idx_t nLine; /* Length of current line */ |
| 2770 | idx_t nSql = 0; /* Bytes of zSql[] used */ |
| 2771 | idx_t nAlloc = 0; /* Allocated zSql[] space */ |
| 2772 | idx_t nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ |
| 2773 | int rc; /* Error code */ |
| 2774 | idx_t errCnt = 0; /* Number of errors seen */ |
| 2775 | idx_t numCtrlC = 0; |
| 2776 | lineno = 0; |
| 2777 | while (errCnt == 0 || !GetBailOnError(mode) || (!in && stdin_is_interactive)) { |
| 2778 | fflush(out); |
| 2779 | zLine = OneInputLine(in, zLine, nSql > 0); |
| 2780 | if (!zLine) { |
| 2781 | /* End of input */ |
| 2782 | if (!in && stdin_is_interactive) { |
| 2783 | printf("\n"); |
| 2784 | } |
| 2785 | break; |
| 2786 | } |
| 2787 | // if we are receiving input after a query was interrupted |
| 2788 | // we need to clear the interrupt flag to be able to |
| 2789 | // print messages again |
| 2790 | if (seenInterrupt) { |
| 2791 | if (in) { |
| 2792 | break; |
| 2793 | } |
| 2794 | ClearInterrupt(); |
| 2795 | } |
| 2796 | if (*zLine == '\3') { |
| 2797 | // ctrl c: reset sql statement |
| 2798 | if (nSql == 0 && zLine[1] == '\0' && stdin_is_interactive) { |
| 2799 | // if in interactive mode and we press ctrl c twice |
| 2800 | // on an empty line, we print the ctrl d hint message |
| 2801 | numCtrlC++; |
| 2802 | if (numCtrlC >= 2) { |
| 2803 | Print("Interrupted, use Ctrl+D to exit\n"); |
| 2804 | } |
| 2805 | } |
| 2806 | nSql = 0; |
| 2807 | continue; |
| 2808 | } else { |
| 2809 | numCtrlC = 0; |
| 2810 | } |
| 2811 | if (mode == InputMode::DUCKDB_RC && !StringUtil::StartsWith(zLine, ".startup_text")) { |
| 2812 | if (startup_text == StartupText::ALL) { |
| 2813 | ShellHighlight highlight(*this); |
| 2814 | highlight.PrintText(StringUtil::Format("-- Loading resources from %s\n", duckdb_rc_path), |
| 2815 | PrintOutput::STDERR, HighlightElementType::STARTUP_TEXT); |
| 2816 | displayed_loading_resources_message = true; |
| 2817 | } |
| 2818 | mode = InputMode::FILE; |
| 2819 | } |
| 2820 | lineno++; |
| 2821 | if (nSql == 0 && _all_whitespace(zLine)) { |
| 2822 | if (ShellHasFlag(ShellFlags::SHFLG_Echo)) { |
| 2823 | printf("%s\n", zLine); |
no test coverage detected