Check-in [357858a659]
Not logged in
Overview
SHA1:357858a65919303bcab6cdceedac43e46af121e4
Date: 2000-08-27 13:23:15
User: mpatton@jhu.edu
Comment:Made readline an object command to fix a number of memory leaks. Added commands "readline text" to retrieve the current input and "readline update" to redraw the current input.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2000-08-27
13:25
[4f73d8af60] Updated docs for text and update commands. (user: mpatton@jhu.edu, tags: trunk)
13:23
[357858a659] Made readline an object command to fix a number of memory leaks. Added commands "readline text" to retrieve the current input and "readline update" to redraw the current input. (user: mpatton@jhu.edu, tags: trunk)
2000-07-27
13:14
[5096b666f4] * configure.in: changed a == to = in a sh test (reported by "Daniel O'Connor" <darius@dons.net.au>) (user: johannes@zellner.org, tags: trunk)
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Modified tclreadline.c from [75b74b5625] to [bd4dbca0d1].

    67     67   /* forward declarations. */
    68     68   static char* stripleft(char* in);
    69     69   static char* stripright(char* in);
    70     70   static char* stripwhite(char* in);
    71     71   static int TclReadlineLineComplete(void);
    72     72   static void TclReadlineTerminate(int state);
    73     73   static char* TclReadlineQuote(char* text, char* quotechars);
    74         -static int TclReadlineCmd(ClientData clientData, Tcl_Interp* interp, int argc, char** argv);
           74  +static int TclReadlineCmd(ClientData clientData, Tcl_Interp *interp, int objc,
           75  +                   Tcl_Obj *CONST objv[]);
    75     76   static void TclReadlineReadHandler(ClientData clientData, int mask);
    76     77   static void TclReadlineLineCompleteHandler(char* ptr);
    77     78   static int TclReadlineInitialize(Tcl_Interp* interp, char* historyfile);
    78     79   static int blank_line(char* str);
    79     80   static char** TclReadlineCompletion(char* text, int start, int end);
    80     81   static char* TclReadline0generator(char* text, int state);
    81     82   static char* TclReadlineKnownCommands(char* text, int state, int mode);
................................................................................
   193    194   	}
   194    195   	Tcl_DStringAppend(&result, ptr, 1);
   195    196       }
   196    197       result_c = strdup(Tcl_DStringValue(&result));
   197    198       return result_c;
   198    199   }
   199    200   
   200         -static int
   201         -TclReadlineCmd(
   202         -    ClientData  clientData,
   203         -    Tcl_Interp* interp,     /* Current interpreter */
   204         -    int         argc,       /* Number of arguments */
   205         -    char**      argv        /* Argument strings    */
   206         -	      )
          201  +static int TclReadlineCmd(ClientData clientData, Tcl_Interp *interp, int objc,
          202  +			  Tcl_Obj *CONST objv[])
   207    203   {
   208    204       int i, obj_idx, status;
   209         -    Tcl_Obj** objv = (Tcl_Obj**) MALLOC((argc + 1) * sizeof(Tcl_Obj *));
   210    205   
   211    206       static char *subCmds[] = {
   212    207   	"read", "initialize", "write", "add", "complete",
   213    208   	"customcompleter", "builtincompleter", "eofchar",
   214         -	"reset-terminal", "bell",
          209  +	"reset-terminal", "bell", "text", "update",
   215    210   	(char *) NULL
   216    211       };
   217    212       enum SubCmdIdx {
   218    213   	TCLRL_READ, TCLRL_INITIALIZE, TCLRL_WRITE, TCLRL_ADD, TCLRL_COMPLETE,
   219    214   	TCLRL_CUSTOMCOMPLETER, TCLRL_BUILTINCOMPLETER, TCLRL_EOFCHAR,
   220         -	TCLRL_RESET_TERMINAL, TCLRL_BELL
          215  +	TCLRL_RESET_TERMINAL, TCLRL_BELL, TCLRL_TEXT, TCLRL_UPDATE
   221    216       };
   222         -
   223    217   
   224    218       Tcl_ResetResult(interp); /* clear the result space */
   225    219   
   226         -    for (i = 0;  i < argc;  i++) {
   227         -	Tcl_Obj* objPtr = Tcl_NewStringObj(argv[i], -1);
   228         -	Tcl_IncrRefCount(objPtr);
   229         -	objv[i] = objPtr;
   230         -    }
   231         -    objv[argc] = 0; /* terminate */
   232         -
   233         -    if (argc < 2) {
          220  +    if (objc < 2) {
   234    221   	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
   235    222   	return TCL_ERROR;
   236    223       }
   237    224   
   238    225       status = Tcl_GetIndexFromObj
   239    226       (interp, objv[1], subCmds, "option", 0, (int *) &obj_idx);
   240    227   
   241    228       if (status != TCL_OK) {
   242         -	FREE(objv)
   243    229   	return status;
   244    230       }
   245    231   
   246    232       switch (obj_idx) {
   247    233   
   248    234   	case TCLRL_READ:
   249    235   
   250         -	    rl_callback_handler_install(argc == 3 ? argv[2] : "%",
   251         -		TclReadlineLineCompleteHandler);
          236  +	    rl_callback_handler_install(
          237  +			       objc == 3 ? Tcl_GetStringFromObj(objv[2], 0)
          238  +			       : "%", TclReadlineLineCompleteHandler);
   252    239   
   253    240   	    Tcl_CreateFileHandler(0, TCL_READABLE,
   254    241   		TclReadlineReadHandler, (ClientData) NULL);
   255    242   
   256    243   	    /**
   257    244   	     * Main Loop.
   258    245   	     * XXX each modification of the global variables
................................................................................
   299    286   		    return tclrl_state;
   300    287   		    /* NOTREACHED */
   301    288   		    break;
   302    289   	    }
   303    290   	    break;
   304    291   
   305    292   	case TCLRL_INITIALIZE:
   306         -	    if (3 != argc) {
          293  +	    if (3 != objc) {
   307    294   		Tcl_WrongNumArgs(interp, 2, objv, "historyfile");
   308    295   		return TCL_ERROR;
   309    296   	    } else {
   310         -		return TclReadlineInitialize(interp, argv[2]);
          297  +		return TclReadlineInitialize(interp,
          298  +					     Tcl_GetStringFromObj(objv[2], 0));
   311    299   	    }
   312    300   	    break;
   313    301   
   314    302   	case TCLRL_WRITE:
   315         -	    if (3 != argc) {
          303  +	    if (3 != objc) {
   316    304   		Tcl_WrongNumArgs(interp, 2, objv, "historyfile");
   317    305   		return TCL_ERROR;
   318         -	    }  else if (write_history(argv[2])) {
          306  +	    }  else if (write_history(Tcl_GetStringFromObj(objv[2], 0))) {
   319    307   		Tcl_AppendResult(interp, "unable to write history to `",
   320         -		    argv[2], "'\n", (char*) NULL);
          308  +		    Tcl_GetStringFromObj(objv[2], 0), "'\n", (char*) NULL);
   321    309   		return TCL_ERROR;
   322    310   	    }
   323    311   	    if (tclrl_history_length >= 0) {
   324         -		history_truncate_file(argv[2], tclrl_history_length);
          312  +		history_truncate_file(Tcl_GetStringFromObj(objv[2], 0),
          313  +				      tclrl_history_length);
   325    314   	    }
   326    315   	    return TCL_OK;
   327    316   	    break;
   328    317   
   329    318   	case TCLRL_ADD:
   330         -	    if (3 != argc) {
          319  +	    if (3 != objc) {
   331    320   		Tcl_WrongNumArgs(interp, 2, objv, "completerLine");
   332    321   		return TCL_ERROR;
   333         -	    } else if (TclReadlineKnownCommands(argv[2], (int) 0, _CMD_SET)) {
          322  +	    } else if (TclReadlineKnownCommands(
          323  +				     Tcl_GetStringFromObj(objv[2], 0),
          324  +				     (int) 0, _CMD_SET)) {
   334    325   		Tcl_AppendResult(interp, "unable to add command \"",
   335         -		    argv[2], "\"\n", (char*) NULL);
          326  +		    Tcl_GetStringFromObj(objv[2], 0), "\"\n", (char*) NULL);
   336    327   	    }
   337    328   	    break;
   338    329   
   339    330   	case TCLRL_COMPLETE:
   340         -	    if (3 != argc) {
          331  +	    if (3 != objc) {
   341    332   		Tcl_WrongNumArgs(interp, 2, objv, "line");
   342    333   		return TCL_ERROR;
   343         -	    } else if (Tcl_CommandComplete(argv[2])) {
          334  +	    } else if (Tcl_CommandComplete(Tcl_GetStringFromObj(objv[2], 0))) {
   344    335   		Tcl_AppendResult(interp, "1", (char*) NULL);
   345    336   	    } else {
   346    337   		Tcl_AppendResult(interp, "0", (char*) NULL);
   347    338   	    }
   348    339   	    break;
   349    340   
   350    341   	case TCLRL_CUSTOMCOMPLETER:
   351         -	    if (argc > 3) {
          342  +	    if (objc > 3) {
   352    343   		Tcl_WrongNumArgs(interp, 2, objv, "?scriptCompleter?");
   353    344   		return TCL_ERROR;
   354         -	    } else if (3 == argc) {
          345  +	    } else if (3 == objc) {
   355    346   		if (tclrl_custom_completer)
   356    347   		    FREE(tclrl_custom_completer);
   357         -		if (!blank_line(argv[2]))
   358         -		    tclrl_custom_completer = stripwhite(strdup(argv[2]));
          348  +		if (!blank_line(Tcl_GetStringFromObj(objv[2], 0)))
          349  +		    tclrl_custom_completer =
          350  +		         stripwhite(strdup(Tcl_GetStringFromObj(objv[2], 0)));
   359    351   	    }
   360    352   	    Tcl_AppendResult(interp, tclrl_custom_completer, (char*) NULL);
   361    353   	    break;
   362    354   
   363    355   	case TCLRL_BUILTINCOMPLETER:
   364         -	    if (argc > 3) {
          356  +	    if (objc > 3) {
   365    357   		Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
   366    358   		return TCL_ERROR;
   367         -	    } else if (3 == argc) {
          359  +	    } else if (3 == objc) {
   368    360   		int bool = tclrl_use_builtin_completer;
   369         -		if (TCL_OK != Tcl_GetBoolean(interp, argv[2], &bool)) {
          361  +		if (TCL_OK != Tcl_GetBoolean(interp,
          362  +					     Tcl_GetStringFromObj(objv[2], 0),
          363  +					     &bool)) {
   370    364   		    Tcl_AppendResult(interp,
   371    365   			"wrong # args: should be a boolean value.",
   372    366   			(char*) NULL);
   373    367   		    return TCL_ERROR;
   374    368   		} else {
   375    369   		    tclrl_use_builtin_completer = bool;
   376    370   		}
   377    371   	    }
   378    372   	    Tcl_AppendResult(interp, tclrl_use_builtin_completer ? "1" : "0",
   379    373   		(char*) NULL);
   380    374   	    break;
   381    375   
   382    376   	case TCLRL_EOFCHAR:
   383         -	    if (argc > 3) {
          377  +	    if (objc > 3) {
   384    378   		Tcl_WrongNumArgs(interp, 2, objv, "?script?");
   385    379   		return TCL_ERROR;
   386         -	    } else if (3 == argc) {
          380  +	    } else if (3 == objc) {
   387    381   		if (tclrl_eof_string)
   388    382   		    FREE(tclrl_eof_string);
   389         -		if (!blank_line(argv[2]))
   390         -		    tclrl_eof_string = stripwhite(strdup(argv[2]));
          383  +		if (!blank_line(Tcl_GetStringFromObj(objv[2], 0)))
          384  +		    tclrl_eof_string = 
          385  +		        stripwhite(strdup(Tcl_GetStringFromObj(objv[2], 0)));
   391    386   	    }
   392    387   	    Tcl_AppendResult(interp, tclrl_eof_string, (char*) NULL);
   393    388   	    break;
   394    389   
   395    390   	case TCLRL_RESET_TERMINAL:
   396    391   	    /* TODO: add this to the completer */
   397         -	    if (argc > 3) {
          392  +	    if (objc > 3) {
   398    393   		Tcl_WrongNumArgs(interp, 2, objv, "?terminal-name?");
   399    394   		return TCL_ERROR;
   400    395   	    }
   401         -	    if (3 == argc) {
          396  +	    if (3 == objc) {
   402    397   		/*
   403         -		 * - tcl8.0 doesn't have Tcl_GetString()
          398  +		 * - tcl8.0 doesn't have Tcl_GetStringFromObj()
   404    399   		 * - rl_reset_terminal() might be defined
   405    400   		 *   to take no arguments. This might produce
   406    401   		 *   a compiler warning.
   407    402   		 */
   408         -		rl_reset_terminal(Tcl_GetStringFromObj(objv[2], (int*) NULL));
          403  +		rl_reset_terminal(Tcl_GetStringFromObj(objv[2], 0));
   409    404   #ifdef CLEANUP_AFER_SIGNAL
   410    405   	    } else {
   411    406   		rl_cleanup_after_signal();
   412    407   #endif
   413    408   	    }
   414    409   	    break;
   415    410   
   416    411   	case TCLRL_BELL:
          412  +	    if (objc != 2) {
          413  +		Tcl_WrongNumArgs(interp, 2, objv, "");
          414  +		return TCL_ERROR;
          415  +	    }
          416  +
          417  +
   417    418   	    /*
   418    419   	     * ring the terminal bell obeying the current
   419    420   	     * settings -- audible or visible.
   420    421   	     */
          422  +
   421    423   	    ding();
   422    424   	    break;
          425  +
          426  +        case TCLRL_UPDATE:
          427  +	    if (objc != 2) {
          428  +		Tcl_WrongNumArgs(interp, 2, objv, "");
          429  +		return TCL_ERROR;
          430  +	    }
          431  +
          432  +	    /* Update the input line */
          433  +
          434  +	    if (rl_line_buffer) {
          435  +	        rl_forced_update_display();
          436  +	    }
          437  +
          438  +	    break;
          439  +
          440  +
          441  +        case TCLRL_TEXT:
          442  +	    if (objc != 2) {
          443  +		Tcl_WrongNumArgs(interp, 2, objv, "");
          444  +		return TCL_ERROR;
          445  +	    }
          446  +
          447  +	    /* Return the current input line */
          448  +	    Tcl_SetObjResult(interp,
          449  +		   Tcl_NewStringObj(rl_line_buffer ? rl_line_buffer : "", -1));
          450  +	    break;
   423    451   
   424    452   	default:
   425    453   	    goto BAD_COMMAND;
   426    454   	    /* NOTREACHED */
   427    455   	    break;
   428    456       }
   429    457   
................................................................................
   528    556       return Tclreadline_Init(interp);
   529    557   }
   530    558   
   531    559   int
   532    560   Tclreadline_Init(Tcl_Interp *interp)
   533    561   {
   534    562       int status;
   535         -    Tcl_CreateCommand(interp, "::tclreadline::readline", TclReadlineCmd,
          563  +    Tcl_CreateObjCommand(interp, "::tclreadline::readline", TclReadlineCmd,
   536    564   	(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
   537    565       tclrl_interp = interp;
   538    566       if (TCL_OK != (status = Tcl_LinkVar(interp, "::tclreadline::historyLength",
   539    567   		(char*) &tclrl_history_length, TCL_LINK_INT)))
   540    568   	return status;
   541    569   
   542    570       if (TCL_OK != (status = Tcl_LinkVar(interp, "::tclreadline::library",