"Fossies" - the Fresh Open Source Software Archive

Member "tnftp-20200705/libedit/TEST/wtc1.c" (4 Jul 2020, 6048 Bytes) of package /linux/privat/tnftp-20200705.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include <sys/wait.h>
    2 #include <ctype.h>
    3 #include <dirent.h>
    4 #include <err.h>
    5 #include <limits.h>
    6 #include <locale.h>
    7 #include <signal.h>
    8 #include <stdio.h>
    9 #include <stdlib.h>
   10 #include <string.h>
   11 #include <unistd.h>
   12 
   13 #include "../histedit.h"
   14 
   15 
   16 static int continuation;
   17 volatile sig_atomic_t gotsig;
   18 static const char hfile[] = ".whistory";
   19 
   20 static wchar_t *
   21 prompt(EditLine *el)
   22 {
   23     static wchar_t a[] = L"\1\033[7m\1Edit$\1\033[0m\1 ";
   24     static wchar_t b[] = L"Edit> ";
   25 
   26     return continuation ? b : a;
   27 }
   28 
   29 
   30 static void
   31 sig(int i)
   32 {
   33     gotsig = i;
   34 }
   35 
   36 const char *
   37 my_wcstombs(const wchar_t *wstr)
   38 {
   39     static struct {
   40         char *str;
   41         int len;
   42     } buf;
   43 
   44     int needed = wcstombs(0, wstr, 0) + 1;
   45     if (needed > buf.len) {
   46         buf.str = malloc(needed);
   47         buf.len = needed;
   48     }
   49     wcstombs(buf.str, wstr, needed);
   50     buf.str[needed - 1] = 0;
   51 
   52     return buf.str;
   53 }
   54 
   55 
   56 static unsigned char
   57 complete(EditLine *el, int ch)
   58 {
   59     DIR *dd = opendir(".");
   60     struct dirent *dp;
   61     const wchar_t *ptr;
   62     char *buf, *bptr;
   63     const LineInfoW *lf = el_wline(el);
   64     int len, mblen, i;
   65     unsigned char res = 0;
   66     wchar_t dir[1024];
   67 
   68     /* Find the last word */
   69     for (ptr = lf->cursor -1; !iswspace(*ptr) && ptr > lf->buffer; --ptr)
   70         continue;
   71     len = lf->cursor - ++ptr;
   72 
   73     /* Convert last word to multibyte encoding, so we can compare to it */
   74     wctomb(NULL, 0); /* Reset shift state */
   75     mblen = MB_LEN_MAX * len + 1;
   76     buf = bptr = malloc(mblen);
   77     if (buf == NULL)
   78         err(1, "malloc");
   79     for (i = 0; i < len; ++i) {
   80         /* Note: really should test for -1 return from wctomb */
   81         bptr += wctomb(bptr, ptr[i]);
   82     }
   83     *bptr = 0; /* Terminate multibyte string */
   84     mblen = bptr - buf;
   85 
   86     /* Scan directory for matching name */
   87     for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
   88         if (mblen > strlen(dp->d_name))
   89             continue;
   90         if (strncmp(dp->d_name, buf, mblen) == 0) {
   91             mbstowcs(dir, &dp->d_name[mblen],
   92                 sizeof(dir) / sizeof(*dir));
   93             if (el_winsertstr(el, dir) == -1)
   94                 res = CC_ERROR;
   95             else
   96                 res = CC_REFRESH;
   97             break;
   98         }
   99     }
  100 
  101     closedir(dd);
  102     free(buf);
  103     return res;
  104 }
  105 
  106 
  107 int
  108 main(int argc, char *argv[])
  109 {
  110     EditLine *el = NULL;
  111     int numc, ncontinuation;
  112     const wchar_t *line;
  113     TokenizerW *tok;
  114     HistoryW *hist;
  115     HistEventW ev;
  116 #ifdef DEBUG
  117     int i;
  118 #endif
  119 
  120     setlocale(LC_ALL, "");
  121 
  122     (void)signal(SIGINT,  sig);
  123     (void)signal(SIGQUIT, sig);
  124     (void)signal(SIGHUP,  sig);
  125     (void)signal(SIGTERM, sig);
  126 
  127     hist = history_winit();     /* Init built-in history     */
  128     history_w(hist, &ev, H_SETSIZE, 100);   /* Remember 100 events       */
  129     history_w(hist, &ev, H_LOAD, hfile);
  130 
  131     tok = tok_winit(NULL);          /* Init the tokenizer        */
  132 
  133     el = el_init(argv[0], stdin, stdout, stderr);
  134 
  135     el_wset(el, EL_EDITOR, L"vi");      /* Default editor is vi      */
  136     el_wset(el, EL_SIGNAL, 1);      /* Handle signals gracefully */
  137     el_wset(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */
  138 
  139     el_wset(el, EL_HIST, history_w, hist);  /* FIXME - history_w? */
  140 
  141                     /* Add a user-defined function  */
  142     el_wset(el, EL_ADDFN, L"ed-complete", L"Complete argument", complete);
  143 
  144                     /* Bind <tab> to it */
  145     el_wset(el, EL_BIND, L"^I", L"ed-complete", NULL);
  146 
  147     /*
  148     * Bind j, k in vi command mode to previous and next line, instead
  149     * of previous and next history.
  150     */
  151     el_wset(el, EL_BIND, L"-a", L"k", L"ed-prev-line", NULL);
  152     el_wset(el, EL_BIND, L"-a", L"j", L"ed-next-line", NULL);
  153 
  154     /* Source the user's defaults file. */
  155     el_source(el, NULL);
  156 
  157     while((line = el_wgets(el, &numc)) != NULL && numc != 0) {
  158         int ac, cc, co, rc;
  159         const wchar_t **av;
  160 
  161         const LineInfoW *li;
  162         li = el_wline(el);
  163 
  164 #ifdef DEBUG
  165         (void)fwprintf(stderr, L"==> got %d %ls", numc, line);
  166         (void)fwprintf(stderr, L"  > li `%.*ls_%.*ls'\n",
  167             (li->cursor - li->buffer), li->buffer,
  168             (li->lastchar - 1 - li->cursor),
  169             (li->cursor >= li->lastchar) ? L"" : li->cursor);
  170 #endif
  171 
  172         if (gotsig) {
  173             (void)fprintf(stderr, "Got signal %d.\n", (int)gotsig);
  174             gotsig = 0;
  175             el_reset(el);
  176         }
  177 
  178         if(!continuation && numc == 1)
  179             continue;   /* Only got a linefeed */
  180 
  181         ac = cc = co = 0;
  182         ncontinuation = tok_wline(tok, li, &ac, &av, &cc, &co);
  183         if (ncontinuation < 0) {
  184             (void) fprintf(stderr, "Internal error\n");
  185             continuation = 0;
  186             continue;
  187         }
  188 
  189 #ifdef DEBUG
  190         (void)fprintf(stderr, "  > nc %d ac %d cc %d co %d\n",
  191             ncontinuation, ac, cc, co);
  192 #endif
  193         history_w(hist, &ev, continuation ? H_APPEND : H_ENTER, line);
  194 
  195         continuation = ncontinuation;
  196         ncontinuation = 0;
  197         if(continuation)
  198             continue;
  199 
  200 #ifdef DEBUG
  201         for (i = 0; i < ac; ++i) {
  202             (void)fwprintf(stderr, L"  > arg# %2d ", i);
  203             if (i != cc)
  204                 (void)fwprintf(stderr, L"`%ls'\n", av[i]);
  205             else
  206                 (void)fwprintf(stderr, L"`%.*ls_%ls'\n",
  207                     co, av[i], av[i] + co);
  208         }
  209 #endif
  210 
  211         if (wcscmp (av[0], L"history") == 0) {
  212             switch(ac) {
  213             case 1:
  214                 for(rc = history_w(hist, &ev, H_LAST);
  215                      rc != -1;
  216                      rc = history_w(hist, &ev, H_PREV))
  217                     (void)fwprintf(stdout, L"%4d %ls",
  218                          ev.num, ev.str);
  219                 break;
  220             case 2:
  221                 if (wcscmp(av[1], L"clear") == 0)
  222                     history_w(hist, &ev, H_CLEAR);
  223                 else
  224                     goto badhist;
  225                 break;
  226             case 3:
  227                 if (wcscmp(av[1], L"load") == 0)
  228                     history_w(hist, &ev, H_LOAD,
  229                         my_wcstombs(av[2]));
  230                 else if (wcscmp(av[1], L"save") == 0)
  231                     history_w(hist, &ev, H_SAVE,
  232                         my_wcstombs(av[2]));
  233                 else
  234                     goto badhist;
  235                 break;
  236             badhist:
  237             default:
  238                 (void)fprintf(stderr,
  239                     "Bad history arguments\n");
  240                 break;
  241             }
  242         } else if (el_wparse(el, ac, av) == -1) {
  243             switch (fork()) {
  244             case 0: {
  245                 Tokenizer *ntok = tok_init(NULL);
  246                 int nargc;
  247                 const char **nav;
  248                 tok_str(ntok, my_wcstombs(line), &nargc, &nav);
  249                 execvp(nav[0],(char **)nav);
  250                 perror(nav[0]);
  251                 _exit(1);
  252                 /* NOTREACHED */
  253                 break;
  254             }
  255             case -1:
  256                 perror("fork");
  257                 break;
  258             default:
  259                 if (wait(&rc) == -1)
  260                     perror("wait");
  261                 (void)fprintf(stderr, "Exit %x\n", rc);
  262                 break;
  263             }
  264         }
  265 
  266         tok_wreset(tok);
  267     }
  268 
  269     el_end(el);
  270     tok_wend(tok);
  271     history_w(hist, &ev, H_SAVE, hfile);
  272     history_wend(hist);
  273 
  274     fprintf(stdout, "\n");
  275     return 0;
  276 }
  277 
  278