You are viewing a plain text version of this content. The canonical link for it is here.
Posted to websh-cvs@tcl.apache.org by ro...@apache.org on 2005/09/09 14:35:07 UTC

cvs commit: tcl-websh/src/generic weboutint.c

ronnie      2005/09/09 05:35:07

  Modified:    src/generic weboutint.c
  Log:
  - Taguchi Takeshi rewrote webout_eval_tag to handle multibyte characters properly
  
  Revision  Changes    Path
  1.9       +94 -155   tcl-websh/src/generic/weboutint.c
  
  Index: weboutint.c
  ===================================================================
  RCS file: /home/cvs/tcl-websh/src/generic/weboutint.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- weboutint.c	15 Jul 2005 11:24:59 -0000	1.8
  +++ weboutint.c	9 Sep 2005 12:35:07 -0000	1.9
  @@ -368,171 +368,110 @@
       return TCL_OK;
   }
   
  -/* --------------------------------------------------------------------------
  - * quote_append (quote Tcl syntax characters and append to Tcl_DString)
  - * ----------------------------------------------------------------------- */
  -
  -int quote_append(Tcl_DString *str, char *in, int len)
  -{
  -    int i = 0;
  -    while (i < len) {
  -	switch (*in)
  -	{
  -	case '{':
  -	    Tcl_DStringAppend(str, "\\{", -1);
  -	    break;
  -	case '}':
  -	    Tcl_DStringAppend(str, "\\}", -1);
  -	    break;
  -	case '$':
  -	    Tcl_DStringAppend(str, "\\$", -1);
  -	    break;
  -	case '[':
  -	    Tcl_DStringAppend(str, "\\[", -1);
  -	    break;
  -	case ']':
  -	    Tcl_DStringAppend(str, "\\]", -1);
  -	    break;
  -	case '"':
  -	    Tcl_DStringAppend(str, "\\\"", -1);
  -	    break;
  -/* 	    case '\\':
  -	    Tcl_DStringAppend(str, "\\\\", -1);
  -	    break;  */
  -	default:
  -	    Tcl_DStringAppend(str, in, 1);
  -	    break;
  -	}
  -	in ++;
  -	i ++;
  -    }
  -    return 0;
  -}
  -
  -
   /* ----------------------------------------------------------------------------
    * webout_eval_tag (code in <? ?>)
    * ------------------------------------------------------------------------- */
   int webout_eval_tag(Tcl_Interp * interp, ResponseObj * responseObj,
   		    Tcl_Obj * in, const char *strstart, const char *strend)
   {
  -    Tcl_DString dstr;
  -    Tcl_Obj *tclo = NULL;
  +  Tcl_Obj *outbuf;
  +  Tcl_Obj *tclo;
  +  char *next;
  +  char *cur;
  +
  +  int endseqlen = strlen(strend);
  +  int startseqlen = strlen(strstart);
  +  int begin = 1;
  +  int firstScan = 1;
  +  int inside = 0, p = 0;
  +  int inLen = 0;
  +  int res = 0;
   
  -    int inLen;
  -    char *cur = NULL;
  -    char *prev = NULL;
  -    int cntOpen = 0;
  -    int res = 0;
  -    int startmatch = 0;
  -    int endmatch = 0;
  -
  -    int begin = 1;
  -    char *start;
  -
  -/*     const char *strstart = START_TAG;
  -    const char *strend = END_TAG;  */
  -/*     int endseqlen = strlen(END_TAG);
  -    int startseqlen = strlen(START_TAG);
  -  */
  -    int endseqlen = strlen(strstart);
  -    int startseqlen = strlen(strend);
  +  next = Tcl_GetStringFromObj(in, &inLen);
  +  outbuf = Tcl_NewStringObj("", -1);
   
  -    if ((responseObj == NULL) || (in == NULL))
  -	return TCL_ERROR;
  -
  -    Tcl_DStringInit(&dstr);
  +  if (inLen == 0)
  +    return 0;
   
  -    cur = Tcl_GetStringFromObj(in, &inLen);
  -    prev = cur;
  -    start = cur;
  -
  -    if (inLen == 0)
  -	return TCL_OK;
  -
  -    while (*cur != 0) {
  -	if (*cur == strstart[startmatch])
  -	{
  -	    if (*prev == '\\') {
  -		Tcl_DStringAppend(&dstr, cur, 1);
  -	    } else if ((++startmatch) == startseqlen) {
  -		/* We have matched the starting sequence. */
  -		if (cntOpen < 1) {
  -		    if (!((cur - (startseqlen - 1)) - start)) {
  -			begin = 0;
  -		    } else {
  -			Tcl_DStringAppend(&dstr, "\"\n", 2);
  -		    }
  -		} else {
  -		    Tcl_DStringAppend(&dstr, strstart, -1);
  -		}
  -		cntOpen ++;
  -		startmatch = 0;
  -	    }
  -	    prev = cur;
  -	    cur ++;
  -	    continue;
  -	} else if (*cur == strend[endmatch] && (cntOpen > 0 || *prev == '\\')) {
  -	    if (*prev == '\\') {
  -		Tcl_DStringAppend(&dstr, cur, 1);
  -	    } else if ((++endmatch) == endseqlen)
  -	    {
  -		/* We have matched the ending sequence. */
  -		if (cntOpen == 1) {
  -		    /* build up the command with the name of the channel. */
  -		    Tcl_DStringAppend(&dstr, "\n web::put \"", -1);
  -		} else {
  -		    Tcl_DStringAppend(&dstr, strend, -1);
  -		}
  -		cntOpen --;
  -		endmatch = 0;
  -	    }
  -	    prev = cur;
  -	    cur ++;
  -	    continue;
  -	} else if (startmatch) {
  -	    if (cntOpen < 1) {
  -		quote_append(&dstr, (char *)strstart, startmatch);
  -	    } else {
  -		Tcl_DStringAppend(&dstr, (char *)strstart, startmatch);
  -	    }
  -	    startmatch = 0;
  -	} else if (endmatch) {
  -	    if (cntOpen < 1) {
  -		quote_append(&dstr, (char *)strend, endmatch);
  -	    } else {
  -		Tcl_DStringAppend(&dstr, (char *)strend, endmatch);
  -	    }
  -	    endmatch = 0;
  -	}
  -	/* Put the current character in the output.  If we are in Tcl
  -	       code, then don't escape Tcl characters. */
  -	if (cntOpen < 1) {
  -	    quote_append(&dstr, cur, 1);
  +  while (*next != 0) {
  +    cur = next;
  +    next = (char *)Tcl_UtfNext(cur);
  +
  +    if (strncmp("\\", cur, 1) == 0) {
  +      if (firstScan == 1) { firstScan = 0; }
  +      if (strncmp(strstart, next, startseqlen) == 0) {
  +	Tcl_AppendToObj(outbuf, "\\", 1);
  +	Tcl_AppendToObj(outbuf, strstart, startseqlen);
  +	next += startseqlen;
  +      } else if (strncmp(strend, next, endseqlen) == 0) {
  +	Tcl_AppendToObj(outbuf, "\\", 1);
  +	Tcl_AppendToObj(outbuf, strend, endseqlen);
  +	next += endseqlen;
  +      } else if (inside < 1) {
  +	Tcl_AppendToObj(outbuf, "\\\\", 2);
  +      } else {
  +	Tcl_AppendToObj(outbuf, "\\", 1);
  +      }
  +    } else if (strncmp(strstart, cur, startseqlen) == 0) {
  +      if ((++inside) == 1) {
  +	if (firstScan == 1) {
  +	  begin = 0;
  +	  firstScan = 0;
  +	  Tcl_AppendToObj(outbuf, "\n", 1);
   	} else {
  -	    Tcl_DStringAppend(&dstr, cur, 1);
  +	  Tcl_AppendToObj(outbuf, "\"\n", 2);
   	}
  -	prev = cur;
  -	cur ++;
  -    }
  -
  -    /* build up the web::put with the name of the channel. */
  -    if (begin) {
  -	tclo = Tcl_NewStringObj("web::put \"", -1);
  +	if (startseqlen > 1) {
  +	  next += startseqlen - 1;
  +	}
  +      }  else {
  +	Tcl_AppendToObj(outbuf, cur, startseqlen);
  +	if (startseqlen > 1) {
  +	  next += startseqlen - 1;
  +	}
  +      }
  +    } else if (strncmp(strend, cur, endseqlen) == 0) {
  +      if (firstScan == 1) { firstScan = 0; }
  +      if ((--inside) == 0) {
  +	Tcl_AppendToObj(outbuf, "\nweb::put \"", -1);
  +	if (endseqlen > 1) {
  +	  next += endseqlen - 1;
  +	}
  +      } else {
  +	Tcl_AppendToObj(outbuf, cur, endseqlen);
  +	if (endseqlen > 1) {
  +	  next += endseqlen - 1;
  +	}
  +      }
  +      if (inside < 0) { inside = 0; }
  +    } else if (inside < 1) {
  +      if (firstScan == 1) { firstScan = 0; }
  +      switch (*cur) {
  +      case '{':
  +      case '}':
  +      case '$':
  +      case '[':
  +      case ']':
  +      case '"':
  +	Tcl_AppendToObj(outbuf, "\\", -1);
  +      default:
  +	Tcl_AppendToObj(outbuf, cur, next - cur);
  +	break;
  +      }
       } else {
  -	tclo = Tcl_NewStringObj("", -1);
  +      if (firstScan == 1) { firstScan = 0; }
  +      Tcl_AppendToObj(outbuf, cur, next - cur);
       }
  -
  -    Tcl_AppendToObj(tclo, Tcl_DStringValue(&dstr),
  -		    Tcl_DStringLength(&dstr));
  -
  -    if (cntOpen < 1) {
  -	Tcl_AppendToObj(tclo, "\"\n", 2);
  -    }
  -
  -    Tcl_DStringFree(&dstr); 
  -    res = Tcl_EvalObjEx(interp, tclo, TCL_EVAL_DIRECT);
  -    return res;
  +  }
  +  if (begin) {
  +    tclo = Tcl_NewStringObj("web::put \"", -1);
  +    Tcl_AppendObjToObj(tclo, outbuf);
  +  } else {
  +    tclo = outbuf;
  +  }
  +  Tcl_AppendToObj(tclo, "\"", -1);
  +  res = Tcl_EvalObjEx(interp, tclo, TCL_EVAL_DIRECT);
  +  return res;
   }
   
   /* ----------------------------------------------------------------------------
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: websh-cvs-unsubscribe@tcl.apache.org
For additional commands, e-mail: websh-cvs-help@tcl.apache.org