📄 tclencoding.c
字号:
* source string that were converted. This * may be less than the original source length * if there was a problem converting some * source characters. */ int *dstWrotePtr; /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ int *dstCharsPtr; /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */{ Encoding *encodingPtr; int result, srcRead, dstWrote, dstChars; Tcl_EncodingState state; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen < 0) { srcLen = (*encodingPtr->lengthProc)(src); } if (statePtr == NULL) { flags |= TCL_ENCODING_START | TCL_ENCODING_END; statePtr = &state; } if (srcReadPtr == NULL) { srcReadPtr = &srcRead; } if (dstWrotePtr == NULL) { dstWrotePtr = &dstWrote; } if (dstCharsPtr == NULL) { dstCharsPtr = &dstChars; } /* * If there are any null characters in the middle of the buffer, they will * converted to the UTF-8 null character (\xC080). To get the actual * \0 at the end of the destination buffer, we need to append it manually. */ dstLen--; result = (*encodingPtr->toUtfProc)(encodingPtr->clientData, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr); dst[*dstWrotePtr] = '\0'; return result;}/* *------------------------------------------------------------------------- * * Tcl_UtfToExternalDString -- * * Convert a source buffer from UTF-8 into the specified encoding. * If any of the bytes in the source buffer are invalid or cannot * be represented in the target encoding, a default fallback * character will be substituted. * * Results: * The converted bytes are stored in the DString, which is then * NULL terminated in an encoding-specific manner. The return value * is a pointer to the value stored in the DString. * * Side effects: * None. * *------------------------------------------------------------------------- */char *Tcl_UtfToExternalDString(encoding, src, srcLen, dstPtr) Tcl_Encoding encoding; /* The encoding for the converted string, * or NULL for the default system encoding. */ CONST char *src; /* Source string in UTF-8. */ int srcLen; /* Source string length in bytes, or < 0 for * strlen(). */ Tcl_DString *dstPtr; /* Uninitialized or free DString in which * the converted string is stored. */{ char *dst; Tcl_EncodingState state; Encoding *encodingPtr; int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars; Tcl_DStringInit(dstPtr); dst = Tcl_DStringValue(dstPtr); dstLen = dstPtr->spaceAvl - 1; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen < 0) { srcLen = strlen(src); } flags = TCL_ENCODING_START | TCL_ENCODING_END; while (1) { result = (*encodingPtr->fromUtfProc)(encodingPtr->clientData, src, srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote, &dstChars); soFar = dst + dstWrote - Tcl_DStringValue(dstPtr); if (result != TCL_CONVERT_NOSPACE) { if (encodingPtr->nullSize == 2) { Tcl_DStringSetLength(dstPtr, soFar + 1); } Tcl_DStringSetLength(dstPtr, soFar); return Tcl_DStringValue(dstPtr); } flags &= ~TCL_ENCODING_START; src += srcRead; srcLen -= srcRead; if (Tcl_DStringLength(dstPtr) == 0) { Tcl_DStringSetLength(dstPtr, dstLen); } Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1); dst = Tcl_DStringValue(dstPtr) + soFar; dstLen = Tcl_DStringLength(dstPtr) - soFar - 1; }}/* *------------------------------------------------------------------------- * * Tcl_UtfToExternal -- * * Convert a buffer from UTF-8 into the specified encoding. * * Results: * The return value is one of TCL_OK, TCL_CONVERT_MULTIBYTE, * TCL_CONVERT_SYNTAX, TCL_CONVERT_UNKNOWN, or TCL_CONVERT_NOSPACE, * as documented in tcl.h. * * Side effects: * The converted bytes are stored in the output buffer. * *------------------------------------------------------------------------- */intTcl_UtfToExternal(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) Tcl_Interp *interp; /* Interp for error return, if not NULL. */ Tcl_Encoding encoding; /* The encoding for the converted string, * or NULL for the default system encoding. */ CONST char *src; /* Source string in UTF-8. */ int srcLen; /* Source string length in bytes, or < 0 for * strlen(). */ int flags; /* Conversion control flags. */ Tcl_EncodingState *statePtr;/* Place for conversion routine to store * state information used during a piecewise * conversion. Contents of statePtr are * initialized and/or reset by conversion * routine under control of flags argument. */ char *dst; /* Output buffer in which converted string * is stored. */ int dstLen; /* The maximum length of output buffer in * bytes. */ int *srcReadPtr; /* Filled with the number of bytes from the * source string that were converted. This * may be less than the original source length * if there was a problem converting some * source characters. */ int *dstWrotePtr; /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ int *dstCharsPtr; /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */{ Encoding *encodingPtr; int result, srcRead, dstWrote, dstChars; Tcl_EncodingState state; if (encoding == NULL) { encoding = systemEncoding; } encodingPtr = (Encoding *) encoding; if (src == NULL) { srcLen = 0; } else if (srcLen < 0) { srcLen = strlen(src); } if (statePtr == NULL) { flags |= TCL_ENCODING_START | TCL_ENCODING_END; statePtr = &state; } if (srcReadPtr == NULL) { srcReadPtr = &srcRead; } if (dstWrotePtr == NULL) { dstWrotePtr = &dstWrote; } if (dstCharsPtr == NULL) { dstCharsPtr = &dstChars; } dstLen -= encodingPtr->nullSize; result = (*encodingPtr->fromUtfProc)(encodingPtr->clientData, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr); if (encodingPtr->nullSize == 2) { dst[*dstWrotePtr + 1] = '\0'; } dst[*dstWrotePtr] = '\0'; return result;}/* *--------------------------------------------------------------------------- * * Tcl_FindExecutable -- * * This procedure computes the absolute path name of the current * application, given its argv[0] value. * * Results: * None. * * Side effects: * The variable tclExecutableName gets filled in with the file * name for the application, if we figured it out. If we couldn't * figure it out, tclExecutableName is set to NULL. * *--------------------------------------------------------------------------- */voidTcl_FindExecutable(argv0) CONST char *argv0; /* The value of the application's argv[0] * (native). */{ CONST char *name; Tcl_DString buffer, nameString; TclInitSubsystems(argv0); if (argv0 == NULL) { goto done; } if (tclExecutableName != NULL) { ckfree(tclExecutableName); tclExecutableName = NULL; } if ((name = TclpFindExecutable(argv0)) == NULL) { goto done; } /* * The value returned from TclpNameOfExecutable is a UTF string that * is possibly dirty depending on when it was initialized. To assure * that the UTF string is a properly encoded native string for this * system, convert the UTF string to the default native encoding * before the default encoding is initialized. Then, convert it back * to UTF after the system encoding is loaded. */ Tcl_UtfToExternalDString(NULL, name, -1, &buffer); TclFindEncodings(argv0); /* * Now it is OK to convert the native string back to UTF and set * the value of the tclExecutableName. */ Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buffer), -1, &nameString); tclExecutableName = (char *) ckalloc((unsigned) (Tcl_DStringLength(&nameString) + 1)); strcpy(tclExecutableName, Tcl_DStringValue(&nameString)); Tcl_DStringFree(&buffer); Tcl_DStringFree(&nameString); return; done: TclFindEncodings(argv0);}/* *--------------------------------------------------------------------------- * * LoadEncodingFile -- * * Read a file that describes an encoding and create a new Encoding * from the data. * * Results: * The return value is the newly loaded Encoding, or NULL if * the file didn't exist of was in the incorrect format. If NULL was * returned, an error message is left in interp's result object, * unless interp was NULL. * * Side effects: * File read from disk. * *--------------------------------------------------------------------------- */static Tcl_EncodingLoadEncodingFile(interp, name) Tcl_Interp *interp; /* Interp for error reporting, if not NULL. */ CONST char *name; /* The name of the encoding file on disk * and also the name for new encoding. */{ int objc, i, ch; Tcl_Obj **objv; Tcl_Obj *pathPtr; Tcl_Channel chan; Tcl_Encoding encoding; pathPtr = TclGetLibraryPath(); if (pathPtr == NULL) { goto unknown; } objc = 0; Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv); chan = NULL; for (i = 0; i < objc; i++) { chan = OpenEncodingFile(Tcl_GetString(objv[i]), name); if (chan != NULL) { break; } } if (chan == NULL) { goto unknown; } Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8"); while (1) { Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_Gets(chan, &ds); ch = Tcl_DStringValue(&ds)[0]; Tcl_DStringFree(&ds); if (ch != '#') { break; } } encoding = NULL; switch (ch) { case 'S': { encoding = LoadTableEncoding(interp, name, ENCODING_SINGLEBYTE, chan); break; } case 'D': { encoding = LoadTableEncoding(interp, name, ENCODING_DOUBLEBYTE, chan); break; } case 'M': { encoding = LoadTableEncoding(interp, name, ENCODING_MULTIBYTE, chan); break; } case 'E': { encoding = LoadEscapeEncoding(name, chan); break; } } if ((encoding == NULL) && (interp != NULL)) { Tcl_AppendResult(interp, "invalid encoding file \"", name, "\"", NULL); } Tcl_Close(NULL, chan); return encoding; unknown: if (interp != NULL) { Tcl_AppendResult(interp, "unknown encoding \"", name, "\"", NULL); } return NULL;}/* *---------------------------------------------------------------------- * * OpenEncodingFile -- * * Look for the file encoding/<name>.enc in the specified * directory. * * Results: * Returns an open file channel if the file exists. * * Side effects: * None. * *---------------------------------------------------------------------- */static Tcl_ChannelOpenEncodingFile(dir, name) CONST char *dir; CONST char *name;{ CONST char *argv[3]; Tcl_DString pathString; CONST char *path; Tcl_Channel chan; Tcl_Obj *pathPtr; argv[0] = dir; argv[1] = "encoding"; argv[2] = name; Tcl_DStringInit(&pathString); Tcl_JoinPath(3, argv, &pathString); path = Tcl_DStringAppend(&pathString, ".enc", -1); pathPtr = Tcl_NewStringObj(path,-1); Tcl_IncrRefCount(pathPtr); chan = Tcl_FSOpenFileChannel(NULL, pathPtr, "r", 0); Tcl_DecrRefCount(pathPtr); Tcl_DStringFree(&pathString); return chan;}/* *-------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -