Diff
Not logged in

Differences From Artifact [3d6f99eaa5]:

To Artifact [9394d14783]:


     1      1   
     2      2    /* ==================================================================
     3      3   
     4         -    FILE: "/home/joze/src/tclreadline/tclreadline.c"
     5         -    LAST MODIFICATION: "Mon Sep 13 02:21:35 1999 (joze)"
            4  +    FILE: "/diska/home/joze/src/tclreadline/tclreadline.c"
            5  +    LAST MODIFICATION: "Mon Sep 13 18:04:01 1999 (joze)"
     6      6       (C) 1998, 1999 by Johannes Zellner, <johannes@zellner.org>
     7      7       $Id$
     8      8       ---
     9      9   
    10     10       tclreadline -- gnu readline for tcl
    11     11       Copyright (C) 1999  Johannes Zellner
    12     12   
................................................................................
    23     23       You should have received a copy of the GNU General Public License
    24     24       along with this program; if not, write to the Free Software
    25     25       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    26     26   
    27     27       <johannes@zellner.org>, http://www.zellner.org/tclreadline/
    28     28   
    29     29       ================================================================== */  
           30  +
           31  +#ifdef HAVE_CONFIG_H
           32  +#   include "config.h"
           33  +#endif
    30     34   
    31     35   #include <tcl.h>
    32     36   #include <stdio.h>
    33     37   #include <stdlib.h>
    34     38   #include <string.h>
    35     39   #define READLINE_LIBRARY
    36     40   #include <readline.h>
................................................................................
    37     41   #include <history.h>
    38     42   
    39     43   /**
    40     44    * this prototype is missing
    41     45    * in readline.h
    42     46    */
    43     47   void rl_extend_line_buffer(int len);
           48  +
           49  +#ifdef EXECUTING_MACRO_HACK
           50  +/**
           51  + * this prototype is private in readline's file `macro.c'.
           52  + * We need it here to decide, if we should read more
           53  + * characters from a macro. Dirty, but it should work.
           54  + */
           55  +extern char* _rl_executing_macro;
           56  +#endif
    44     57   
    45     58   #include "tclreadline.h"
    46     59   
    47     60   #define MALLOC(size) Tcl_Alloc((int) size)
    48     61   #define FREE(ptr) if (ptr) { Tcl_Free((char*) ptr); ptr = 0; }
    49     62   
    50     63   enum {
................................................................................
    67     80    */
    68     81   char* stripleft(char* in);
    69     82   char* stripright(char* in);
    70     83   char* stripwhite(char* in);
    71     84   char* TclReadlineQuote(char* text, char* quotechars);
    72     85   int TclReadlineCmd(ClientData clientData, Tcl_Interp* interp,
    73     86       int argc, char** argv);
    74         -int TclReadlineEventHook(void);
    75     87   void TclReadlineReadHandler(ClientData clientData, int mask);
    76         -void TclReadlineWriteHandler(ClientData clientData, int mask);
    77     88   void TclReadlineLineCompleteHandler(char* ptr);
    78     89   int Tclreadline_SafeInit(Tcl_Interp* interp);
    79     90   int Tclreadline_Init(Tcl_Interp* interp);
    80         -char *TclReadlineFilenameQuotingFunction(
    81         -    char *text, int match_type, char* quote_ptr);
    82     91   int TclReadlineInitialize(Tcl_Interp* interp, char* historyfile);
    83     92   int blank_line(char* str);
    84     93   char** TclReadlineCompletion(char* text, int start, int end);
    85     94   char* TclReadline0generator(char* text, int state);
    86     95   char* TclReadlineKnownCommands(char* text, int state, int mode);
    87     96   int TclReadlineParse(char** args, int maxargs, char* buf);
    88     97   
................................................................................
   172    181       length = strlen(argv[1]);
   173    182   
   174    183       if (c == 'r'  && strncmp(argv[1], "read", length) == 0) {
   175    184           
   176    185           char* expansion = (char*) NULL;
   177    186           int status;
   178    187           
   179         -#if 1
   180    188           tclrl_line_complete = LINE_PENDING;
   181    189           tclrl_state = TCL_OK;
   182    190           rl_callback_handler_install(argc == 3 ? argv[2] : "%",
   183    191                   TclReadlineLineCompleteHandler);
   184    192   
   185    193           Tcl_CreateFileHandler(0, TCL_READABLE,
   186    194                   TclReadlineReadHandler, (ClientData) NULL);
   187         -        /*
   188         -        Tcl_CreateFileHandler(1, TCL_WRITABLE,
   189         -                TclReadlineWriteHandler, (ClientData) NULL);
   190         -        */
   191    195   
   192    196           /**
   193    197            * Main Loop.
   194    198            * XXX each modification of the global variables
   195    199            *     which terminates the main loop must call
   196    200            *     rl_callback_handler_remove() to leave
   197    201            *     readline in a defined state.          XXX
   198    202            */
   199    203           while (LINE_PENDING == tclrl_line_complete
   200    204               && TCL_OK == tclrl_state && !rl_done) {
   201    205               Tcl_DoOneEvent(TCL_ALL_EVENTS);
   202         -            /*
   203         -            Tcl_DoOneEvent(0);
   204         -            fprintf (stderr, "(TclReadlineCmd) \n");
   205         -            rl_inhibit_completion = 0;
   206         -            */
   207    206           }
          207  +
   208    208           Tcl_DeleteFileHandler(0);
   209    209   
   210    210           if (TCL_OK != tclrl_state)
   211    211               return tclrl_state; /* !! */
   212    212   
   213    213   	if ((LINE_EOF == tclrl_line_complete) && tclrl_eof_string) {
   214    214   	    Tcl_Eval(interp, tclrl_eof_string);
   215    215               return tclrl_state;
   216    216   	}
   217         -#else
   218         -        rl_event_hook = TclReadlineEventHook;
   219         -        tclrl_line = readline(argc == 3 ? argv[2] : "%");
   220         -#endif
   221    217   
   222    218           status = history_expand(tclrl_line, &expansion);
   223    219           if (status >= 1) {
   224    220   #if 0
   225    221               Tcl_Channel channel = Tcl_MakeFileChannel(stdout, TCL_WRITABLE);
   226    222               /* Tcl_RegisterChannel(interp, channel); */
   227    223               (void) Tcl_WriteChars(channel, expansion, -1);
................................................................................
   323    319       Tcl_AppendResult(interp,
   324    320           "wrong # args: should be \"readline option ?arg ...?\"",
   325    321           (char*) NULL);
   326    322       return TCL_ERROR;
   327    323   
   328    324   }
   329    325   
   330         -int TclReadlineEventHook(void)
   331         -{
   332         -    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
   333         -    /*
   334         -        TCL_DONT_WAIT
   335         -        TCL_WINDOW_EVENTS
   336         -        TCL_FILE_EVENTS
   337         -        TCL_TIMER_EVENTS
   338         -        TCL_IDLE_EVENTS
   339         -        TCL_ALL_EVENTS
   340         -    */
   341         -    return TCL_OK;
   342         -}
   343    326   void
   344    327   TclReadlineReadHandler(ClientData clientData, int mask)
   345    328   {
   346         -#if 0
   347         -    fprintf(stderr, "(TclReadlineReadHandler) mask = %d\n",  mask);
   348         -#endif
   349    329       if (mask & TCL_READABLE) {
   350         -        /*
   351         -        fprintf(stderr, "(TclReadlineReadHandler) mask = readable\n");
   352         -        rl_event_hook = TclReadlineEventHook;
   353         -        while (!rl_done) {
   354         -        */
          330  +        rl_callback_read_char();
          331  +#ifdef EXECUTING_MACRO_HACK
          332  +        /**
          333  +         * check, if we're inside a macro and
          334  +         * if so, read all macro characters.
          335  +         */
          336  +        while (_rl_executing_macro) {
   355    337               rl_callback_read_char();
   356         -        /*
   357    338           }
   358         -        fflush(stdin);
   359         -        */
   360         -    }
   361         -}
   362         -
   363         -void
   364         -TclReadlineWriteHandler(ClientData clientData, int mask)
   365         -{
   366         -    if (mask & TCL_WRITABLE) {
   367         -        /*
   368         -        fprintf(stderr, "(TclReadlineReadHandler) mask = writable\n");
   369         -        */
   370         -        fflush(stdout);
   371         -        rl_redisplay();
          339  +#endif
   372    340       }
   373    341   }
   374    342   
   375    343   void
   376    344   TclReadlineLineCompleteHandler(char* ptr)
   377    345   {
   378    346   #if 1
................................................................................
   426    394           return status;
   427    395       if (TCL_OK != (status = Tcl_LinkVar(interp, "tclreadline_patchLevel",
   428    396            (char*) &TCLRL_PATCHLEVEL, TCL_LINK_STRING | TCL_LINK_READ_ONLY)))
   429    397           return status;
   430    398       return Tcl_PkgProvide(interp, "tclreadline", TCLRL_VERSION);
   431    399   }
   432    400   
   433         -#if 0
   434         -char *
   435         -TclReadlineFilenameQuotingFunction
   436         -(char *filename, int match_type, char* quote_ptr)
   437         -{
   438         -    char *res = (char*) malloc(sizeof(char) * (strlen(filename) + 2));
   439         -    int i = 0;
   440         -    fprintf (stderr, "(TclReadlineFilenameQuotingFunction) \n");
   441         -    if (quote_ptr && *quote_ptr) {
   442         -        *res = *quote_ptr;                     /* leading quote */
   443         -        i++;
   444         -    }
   445         -    strcpy (res + i, filename);              /* name          */
   446         -#if 0
   447         -    fprintf (stderr, "(Tclreadline_Init) filename=|%s|\n", filename);
   448         -    fprintf (stderr, "(Tclreadline_Init) *quote_ptr=|%c|\n", *quote_ptr);
   449         -#endif
   450         -    if (quote_ptr && '{' == *quote_ptr) {
   451         -        *quote_ptr = '}';
   452         -    }
   453         -    return res;
   454         -
   455         -#if 0
   456         -    switch (match_type) {
   457         -        case SINGLE_MATCH:
   458         -            break;
   459         -        default:
   460         -    }
   461         -#endif
   462         -}
   463         -#endif
   464         -
   465    401   int
   466    402   TclReadlineInitialize(Tcl_Interp* interp, char* historyfile)
   467    403   {
   468    404       rl_readline_name = "tclreadline";
   469    405       //    rl_special_prefixes = "${\"[";
   470    406       rl_special_prefixes = "$";
   471    407       /**
................................................................................
   477    413        * added "}"
   478    414        */
   479    415       /* 11.Sep rl_basic_word_break_characters = " \t\n\"\\@$}=;|&[]"; */
   480    416       /* besser (11. Sept) 2. (removed \") */
   481    417       /* rl_basic_word_break_characters = " \t\n\\@$}=;|&[]"; */
   482    418       /* besser (11. Sept) 3. (removed }) */
   483    419       rl_basic_word_break_characters = " \t\n\\@$=;|&[]";
   484         -    // rl_basic_quote_characters = "\"{"; // XXX ??? XXX
   485         -    // rl_completer_quote_characters = "\"";
          420  +#if 0
          421  +    rl_basic_quote_characters = "\"{"; // XXX ??? XXX
          422  +    rl_completer_quote_characters = "\"";
          423  +#endif
   486    424       /*
   487    425       rl_filename_quote_characters
   488    426       = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   489    427   
   490    428       rl_filename_quoting_function
   491    429           = (CPFunction*) TclReadlineFilenameQuotingFunction;
   492    430       */
................................................................................
   525    463   }
   526    464   
   527    465   char**
   528    466   TclReadlineCompletion(char* text, int start, int end)
   529    467   {
   530    468       char** matches = (char**) NULL;
   531    469       int status;
   532         -    // rl_attempted_completion_over = 0;
   533    470       rl_completion_append_character = ' '; /* reset, just in case ... */
   534    471   
   535         -#if 0
   536         -    fprintf(stderr, "DEBUG> TclReadlineCompletion: text=|%s|\n", text);
   537         -    fprintf(stderr, "DEBUG> TclReadlineCompletion: start=|%d|\n", start);
   538         -    fprintf(stderr, "DEBUG> TclReadlineCompletion: end=|%d|\n", end);
   539         -#endif
   540         -
   541         -#if 0
   542         -    char* history_event = (char*) NULL;
   543         -    if (text) {
   544         -        if ('!' == text[0])
   545         -            history_event = strdup(text);
   546         -        else if (start && rl_line_buffer[start - 1] == '!' /* for '$' */) {
   547         -            int len = strlen(text);
   548         -            history_event = strncpy((char*) malloc(sizeof(char) * (len + 1)),
   549         -                rl_line_buffer[start - 1], len);
   550         -            history_event[len] = '\0'; /* terminate */
   551         -        }
   552         -    }
   553         -    if (history_event)
   554         -#endif
   555         -
   556    472       if (text && ('!' == text[0]
   557    473               || (start && rl_line_buffer[start - 1] == '!' /* for '$' */))) {
   558    474           char* expansion = (char*) NULL;
   559    475           int oldlen = strlen(rl_line_buffer);
   560    476           status = history_expand(rl_line_buffer, &expansion);
   561    477           if (status >= 1) {
   562    478               rl_extend_line_buffer(strlen(expansion) + 1);
   563    479               strcpy(rl_line_buffer, expansion);
   564    480               rl_end = strlen(expansion);
   565    481               rl_point += strlen(expansion) - oldlen;
   566    482               FREE(expansion);
   567         -            /* rl_redisplay(); */
   568    483               /*
   569    484                * TODO:
   570    485                * because we return 0 == matches,
   571    486                * the filename completer will still beep.
   572    487               rl_inhibit_completion = 1;
   573    488                */
   574    489               return matches;
................................................................................
   580    495           char start_s[BUFSIZ], end_s[BUFSIZ];
   581    496           Tcl_Obj* obj;
   582    497           Tcl_Obj** objv;
   583    498           int objc;
   584    499           char* quoted_text = TclReadlineQuote(text, "$[]{}\"");
   585    500           char* quoted_rl_line_buffer
   586    501               = TclReadlineQuote(rl_line_buffer, "$[]{}\"");
   587         -#if 0
   588         -        fprintf (stderr, "(TclReadlineCompletion) rl_line_buffer = |%s|\n",
   589         -            rl_line_buffer);
   590         -        fprintf (stderr, "(TclReadlineCompletion) quoted_rl_line_buffer = |%s|\n",
   591         -            quoted_rl_line_buffer);
   592         -        fprintf (stderr, "(TclReadlineCompletion) text = |%s|\n", text);
   593         -        fprintf (stderr, "(TclReadlineCompletion) quoted_text = |%s|\n",
   594         -            quoted_text);
   595         -#endif
   596    502           sprintf(start_s, "%d", start);
   597    503           sprintf(end_s, "%d", end);
   598    504           Tcl_ResetResult(tclrl_interp); /* clear result space */
   599    505           tclrl_state = Tcl_VarEval(tclrl_interp, tclrl_custom_completer,
   600    506               " \"", quoted_text, "\" ", start_s, " ", end_s,
   601    507               " \"", quoted_rl_line_buffer, "\"", (char*) NULL);
   602    508           FREE(quoted_text);
................................................................................
   604    510           if (TCL_OK != tclrl_state) {
   605    511               rl_callback_handler_remove();
   606    512               Tcl_AppendResult (tclrl_interp, " `", tclrl_custom_completer,
   607    513                   " \"", quoted_text, "\" ", start_s, " ", end_s,
   608    514                   " \"", quoted_rl_line_buffer, "\"' failed.", (char*) NULL);
   609    515               return matches;
   610    516           }
   611         -#if 0
   612         -        fprintf(stderr, "\nscript returned |%s|\n",
   613         -            Tcl_GetStringResult(tclrl_interp));
   614         -#endif
   615    517           obj = Tcl_GetObjResult(tclrl_interp);
   616    518           status = Tcl_ListObjGetElements(tclrl_interp, obj, &objc, &objv);
   617    519           if (TCL_OK != status)
   618    520               return matches;
   619         -        /* fprintf (stderr, "(TclReadlineCompletion) objc = %d\n", objc); */
          521  +
   620    522           if (objc) {
   621    523               int i, length;
   622    524               matches = (char**) MALLOC(sizeof(char*) * (objc + 1));
   623    525               for (i = 0; i < objc; i++) {
   624    526                   matches[i] = strdup(Tcl_GetStringFromObj(objv[i], &length));
   625    527                   if (1 == objc && !strlen(matches[i])) {
   626         -                    // rl_attempted_completion_over = 1;
   627    528                       FREE(matches[i]);
   628    529                       FREE(matches);
   629    530                       return (char**) NULL;
   630    531                   }
   631         -                /*
   632         -                fprintf (stderr, "(TclReadlineCompletion) len[%s]=%d\n",
   633         -                    matches[i], strlen(matches[i]));
   634         -                */
   635    532               }
   636    533   
   637    534               /**
   638    535                * this is a special one:
   639    536                * if the script returns exactly two arguments
   640    537                * and the second argument is the empty string,
   641    538                * the rl_completion_append_character is set
................................................................................
   651    548           }
   652    549           Tcl_ResetResult(tclrl_interp); /* clear result space */
   653    550       }
   654    551   
   655    552       if (!matches && tclrl_use_builtin_completer) {
   656    553           matches = completion_matches(text, TclReadline0generator);
   657    554       }
   658         -#if 0
   659         -    {
   660         -        char **ptr;
   661         -        for (ptr = matches; ptr && *ptr; ptr++)
   662         -            fprintf (stderr, "(TclReadlineCompletion) |%s|\n", *ptr);
   663         -    }
   664         -#endif
   665    555       
   666    556       return matches;
   667    557   }
   668    558   
   669    559   char*
   670    560   TclReadline0generator(char* text, int state)
   671    561   {
................................................................................
   716    606               break;
   717    607   
   718    608   
   719    609           case _CMD_GET:
   720    610   
   721    611               local_line = strdup(rl_line_buffer);
   722    612               sub = TclReadlineParse(args, sizeof(args), local_line);
   723         -            /*
   724         -             * fprintf (stderr, "(TclReadlineKnownCommands) state=%d\n", state);
   725         -             * fprintf (stderr, "(TclReadlineKnownCommands) text = |%s|\n", text);
   726         -             */
   727    613   
   728    614               if (0 == sub || (1 == sub && '\0' != text[0])) {
   729    615                   if (!state) {
   730    616                       new = cmds;
   731    617                       len = strlen(text);
   732    618                   }
   733    619                   while (new && (name = new->cmd)) {