intl/icu/source/common/utrace.c

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2 *******************************************************************************
     3 *   Copyright (C) 2003-2008, International Business Machines
     4 *   Corporation and others.  All Rights Reserved.
     5 *******************************************************************************
     6 *   file name:  utrace.c
     7 *   encoding:   US-ASCII
     8 *   tab size:   8 (not used)
     9 *   indentation:4
    10 */
    12 #define   UTRACE_IMPL
    13 #include "unicode/utrace.h"
    14 #include "utracimp.h"
    15 #include "cstring.h"
    16 #include "uassert.h"
    17 #include "ucln_cmn.h"
    20 static UTraceEntry     *pTraceEntryFunc = NULL;
    21 static UTraceExit      *pTraceExitFunc  = NULL;
    22 static UTraceData      *pTraceDataFunc  = NULL;
    23 static const void      *gTraceContext   = NULL;
    25 U_EXPORT int32_t
    26 utrace_level = UTRACE_ERROR;
    28 U_CAPI void U_EXPORT2
    29 utrace_entry(int32_t fnNumber) {
    30     if (pTraceEntryFunc != NULL) {
    31         (*pTraceEntryFunc)(gTraceContext, fnNumber);
    32     }
    33 }
    36 static const char gExitFmt[]             = "Returns.";
    37 static const char gExitFmtValue[]        = "Returns %d.";
    38 static const char gExitFmtStatus[]       = "Returns.  Status = %d.";
    39 static const char gExitFmtValueStatus[]  = "Returns %d.  Status = %d.";
    40 static const char gExitFmtPtrStatus[]    = "Returns %d.  Status = %p.";
    42 U_CAPI void U_EXPORT2
    43 utrace_exit(int32_t fnNumber, int32_t returnType, ...) {
    44     if (pTraceExitFunc != NULL) {
    45         va_list     args;
    46         const char *fmt;
    48         switch (returnType) {
    49         case 0:
    50             fmt = gExitFmt;
    51             break;
    52         case UTRACE_EXITV_I32:
    53             fmt = gExitFmtValue;
    54             break;
    55         case UTRACE_EXITV_STATUS:
    56             fmt = gExitFmtStatus;
    57             break;
    58         case UTRACE_EXITV_I32 | UTRACE_EXITV_STATUS:
    59             fmt = gExitFmtValueStatus;
    60             break;
    61         case UTRACE_EXITV_PTR | UTRACE_EXITV_STATUS:
    62             fmt = gExitFmtPtrStatus;
    63             break;
    64         default:
    65             U_ASSERT(FALSE);
    66             fmt = gExitFmt;
    67         }
    69         va_start(args, returnType);
    70         (*pTraceExitFunc)(gTraceContext, fnNumber, fmt, args);
    71         va_end(args);
    72     }
    73 }
    77 U_CAPI void U_EXPORT2 
    78 utrace_data(int32_t fnNumber, int32_t level, const char *fmt, ...) {
    79     if (pTraceDataFunc != NULL) {
    80            va_list args;
    81            va_start(args, fmt ); 
    82            (*pTraceDataFunc)(gTraceContext, fnNumber, level, fmt, args);
    83            va_end(args);
    84     }
    85 }
    88 static void outputChar(char c, char *outBuf, int32_t *outIx, int32_t capacity, int32_t indent) {
    89     int32_t i;
    90     /* Check whether a start of line indenting is needed.  Three cases:
    91      *   1.  At the start of the first line  (output index == 0).
    92      *   2.  At the start of subsequent lines  (preceeding char in buffer == '\n')
    93      *   3.  When preflighting buffer len (buffer capacity is exceeded), when
    94      *       a \n is output.  Ideally we wouldn't do the indent until the following char
    95      *       is received, but that won't work because there's no place to remember that
    96      *       the preceding char was \n.  Meaning that we may overstimate the
    97      *       buffer size needed.  No harm done.
    98      */
    99     if (*outIx==0 ||   /* case 1. */
   100         (c!='\n' && c!=0 && *outIx < capacity && outBuf[(*outIx)-1]=='\n') ||  /* case 2. */
   101         (c=='\n' && *outIx>=capacity))    /* case 3 */
   102     {
   103         /* At the start of a line.  Indent. */
   104         for(i=0; i<indent; i++) {
   105             if (*outIx < capacity) {
   106                 outBuf[*outIx] = ' ';
   107             }
   108             (*outIx)++;
   109         }
   110     }
   112     if (*outIx < capacity) {
   113         outBuf[*outIx] = c;
   114     }
   115     if (c != 0) {
   116         /* Nulls only appear as end-of-string terminators.  Move them to the output
   117          *  buffer, but do not update the length of the buffer, so that any
   118          *  following output will overwrite the null. */
   119         (*outIx)++;
   120     }
   121 }
   123 static void outputHexBytes(int64_t val, int32_t charsToOutput,
   124                            char *outBuf, int32_t *outIx, int32_t capacity) {
   125     static const char gHexChars[] = "0123456789abcdef";
   126     int32_t shiftCount;
   127     for  (shiftCount=(charsToOutput-1)*4; shiftCount >= 0; shiftCount-=4) {
   128         char c = gHexChars[(val >> shiftCount) & 0xf];
   129         outputChar(c, outBuf, outIx, capacity, 0);
   130     }
   131 }
   133 /* Output a pointer value in hex.  Work with any size of pointer   */
   134 static void outputPtrBytes(void *val, char *outBuf, int32_t *outIx, int32_t capacity) {
   135     int32_t  i;
   136     int32_t  incVal = 1;              /* +1 for big endian, -1 for little endian          */
   137     char     *p     = (char *)&val;   /* point to current byte to output in the ptr val  */
   139 #if !U_IS_BIG_ENDIAN
   140     /* Little Endian.  Move p to most significant end of the value      */
   141     incVal = -1;
   142     p += sizeof(void *) - 1;
   143 #endif
   145     /* Loop through the bytes of the ptr as it sits in memory, from 
   146      * most significant to least significant end                    */
   147     for (i=0; i<sizeof(void *); i++) {
   148         outputHexBytes(*p, 2, outBuf, outIx, capacity);
   149         p += incVal;
   150     }
   151 }
   153 static void outputString(const char *s, char *outBuf, int32_t *outIx, int32_t capacity, int32_t indent) {
   154     int32_t i = 0;
   155     char    c;
   156     if (s==NULL) {
   157         s = "*NULL*";
   158     }
   159     do {
   160         c = s[i++];
   161         outputChar(c, outBuf, outIx, capacity, indent);
   162     } while (c != 0);
   163 }
   167 static void outputUString(const UChar *s, int32_t len, 
   168                           char *outBuf, int32_t *outIx, int32_t capacity, int32_t indent) {
   169     int32_t i = 0;
   170     UChar   c;
   171     if (s==NULL) {
   172         outputString(NULL, outBuf, outIx, capacity, indent);
   173         return;
   174     }
   176     for (i=0; i<len || len==-1; i++) {
   177         c = s[i];
   178         outputHexBytes(c, 4, outBuf, outIx, capacity);
   179         outputChar(' ', outBuf, outIx, capacity, indent);
   180         if (len == -1 && c==0) {
   181             break;
   182         }
   183     }
   184 }
   186 U_CAPI int32_t U_EXPORT2
   187 utrace_vformat(char *outBuf, int32_t capacity, int32_t indent, const char *fmt, va_list args) {
   188     int32_t   outIx  = 0;
   189     int32_t   fmtIx  = 0;
   190     char      fmtC;
   191     char      c;
   192     int32_t   intArg;
   193     int64_t   longArg = 0;
   194     char      *ptrArg;
   196     /*   Loop runs once for each character in the format string.
   197      */
   198     for (;;) {
   199         fmtC = fmt[fmtIx++];
   200         if (fmtC != '%') {
   201             /* Literal character, not part of a %sequence.  Just copy it to the output. */
   202             outputChar(fmtC, outBuf, &outIx, capacity, indent);
   203             if (fmtC == 0) {
   204                 /* We hit the null that terminates the format string.
   205                  * This is the normal (and only) exit from the loop that
   206                  * interprets the format
   207                  */
   208                 break;
   209             }
   210             continue;
   211         }
   213         /* We encountered a '%'.  Pick up the following format char */
   214         fmtC = fmt[fmtIx++];
   216         switch (fmtC) {
   217         case 'c':
   218             /* single 8 bit char   */
   219             c = (char)va_arg(args, int32_t);
   220             outputChar(c, outBuf, &outIx, capacity, indent);
   221             break;
   223         case 's':
   224             /* char * string, null terminated.  */
   225             ptrArg = va_arg(args, char *);
   226             outputString((const char *)ptrArg, outBuf, &outIx, capacity, indent);
   227             break;
   229         case 'S':
   230             /* UChar * string, with length, len==-1 for null terminated. */
   231             ptrArg = va_arg(args, void *);             /* Ptr    */
   232             intArg =(int32_t)va_arg(args, int32_t);    /* Length */
   233             outputUString((const UChar *)ptrArg, intArg, outBuf, &outIx, capacity, indent);
   234             break;
   236         case 'b':
   237             /*  8 bit int  */
   238             intArg = va_arg(args, int);
   239             outputHexBytes(intArg, 2, outBuf, &outIx, capacity);
   240             break;
   242         case 'h':
   243             /*  16 bit int  */
   244             intArg = va_arg(args, int);
   245             outputHexBytes(intArg, 4, outBuf, &outIx, capacity);
   246             break;
   248         case 'd':
   249             /*  32 bit int  */
   250             intArg = va_arg(args, int);
   251             outputHexBytes(intArg, 8, outBuf, &outIx, capacity);
   252             break;
   254         case 'l':
   255             /*  64 bit long  */
   256             longArg = va_arg(args, int64_t);
   257             outputHexBytes(longArg, 16, outBuf, &outIx, capacity);
   258             break;
   260         case 'p':
   261             /*  Pointers.   */
   262             ptrArg = va_arg(args, void *);
   263             outputPtrBytes(ptrArg, outBuf, &outIx, capacity);
   264             break;
   266         case 0:
   267             /* Single '%' at end of fmt string.  Output as literal '%'.   
   268              * Back up index into format string so that the terminating null will be
   269              * re-fetched in the outer loop, causing it to terminate.
   270              */
   271             outputChar('%', outBuf, &outIx, capacity, indent);
   272             fmtIx--;
   273             break;
   275         case 'v':
   276             {
   277                 /* Vector of values, e.g. %vh */
   278                 char     vectorType;
   279                 int32_t  vectorLen;
   280                 const char   *i8Ptr;
   281                 int16_t  *i16Ptr;
   282                 int32_t  *i32Ptr;
   283                 int64_t  *i64Ptr;
   284                 void     **ptrPtr;
   285                 int32_t   charsToOutput = 0;
   286                 int32_t   i;
   288                 vectorType = fmt[fmtIx];    /* b, h, d, l, p, etc. */
   289                 if (vectorType != 0) {
   290                     fmtIx++;
   291                 }
   292                 i8Ptr = (const char *)va_arg(args, void*);
   293                 i16Ptr = (int16_t *)i8Ptr;
   294                 i32Ptr = (int32_t *)i8Ptr;
   295                 i64Ptr = (int64_t *)i8Ptr;
   296                 ptrPtr = (void **)i8Ptr;
   297                 vectorLen =(int32_t)va_arg(args, int32_t);
   298                 if (ptrPtr == NULL) {
   299                     outputString("*NULL* ", outBuf, &outIx, capacity, indent);
   300                 } else {
   301                     for (i=0; i<vectorLen || vectorLen==-1; i++) { 
   302                         switch (vectorType) {
   303                         case 'b':
   304                             charsToOutput = 2;
   305                             longArg = *i8Ptr++;
   306                             break;
   307                         case 'h':
   308                             charsToOutput = 4;
   309                             longArg = *i16Ptr++;
   310                             break;
   311                         case 'd':
   312                             charsToOutput = 8;
   313                             longArg = *i32Ptr++;
   314                             break;
   315                         case 'l':
   316                             charsToOutput = 16;
   317                             longArg = *i64Ptr++;
   318                             break;
   319                         case 'p':
   320                             charsToOutput = 0;
   321                             outputPtrBytes(*ptrPtr, outBuf, &outIx, capacity);
   322                             longArg = *ptrPtr==NULL? 0: 1;    /* test for null terminated array. */
   323                             ptrPtr++;
   324                             break;
   325                         case 'c':
   326                             charsToOutput = 0;
   327                             outputChar(*i8Ptr, outBuf, &outIx, capacity, indent);
   328                             longArg = *i8Ptr;    /* for test for null terminated array. */
   329                             i8Ptr++;
   330                             break;
   331                         case 's':
   332                             charsToOutput = 0;
   333                             outputString(*ptrPtr, outBuf, &outIx, capacity, indent);
   334                             outputChar('\n', outBuf, &outIx, capacity, indent);
   335                             longArg = *ptrPtr==NULL? 0: 1;   /* for test for null term. array. */
   336                             ptrPtr++;
   337                             break;
   339                         case 'S':
   340                             charsToOutput = 0;
   341                             outputUString((const UChar *)*ptrPtr, -1, outBuf, &outIx, capacity, indent);
   342                             outputChar('\n', outBuf, &outIx, capacity, indent);
   343                             longArg = *ptrPtr==NULL? 0: 1;   /* for test for null term. array. */
   344                             ptrPtr++;
   345                             break;
   348                         }
   349                         if (charsToOutput > 0) {
   350                             outputHexBytes(longArg, charsToOutput, outBuf, &outIx, capacity);
   351                             outputChar(' ', outBuf, &outIx, capacity, indent);
   352                         }
   353                         if (vectorLen == -1 && longArg == 0) {
   354                             break;
   355                         }
   356                     }
   357                 }
   358                 outputChar('[', outBuf, &outIx, capacity, indent);
   359                 outputHexBytes(vectorLen, 8, outBuf, &outIx, capacity);
   360                 outputChar(']', outBuf, &outIx, capacity, indent);
   361             }
   362             break;
   365         default:
   366             /* %. in format string, where . is some character not in the set
   367              *    of recognized format chars.  Just output it as if % wasn't there.
   368              *    (Covers "%%" outputing a single '%')
   369              */
   370              outputChar(fmtC, outBuf, &outIx, capacity, indent);
   371         }
   372     }
   373     outputChar(0, outBuf, &outIx, capacity, indent);  /* Make sure that output is null terminated  */
   374     return outIx + 1;     /* outIx + 1 because outIx does not increment when outputing final null. */
   375 }
   380 U_CAPI int32_t U_EXPORT2
   381 utrace_format(char *outBuf, int32_t capacity,
   382                 int32_t indent, const char *fmt,  ...) {
   383     int32_t retVal;
   384     va_list args;
   385     va_start(args, fmt ); 
   386     retVal = utrace_vformat(outBuf, capacity, indent, fmt, args);
   387     va_end(args);
   388     return retVal;
   389 }
   392 U_CAPI void U_EXPORT2
   393 utrace_setFunctions(const void *context,
   394                     UTraceEntry *e, UTraceExit *x, UTraceData *d) {
   395     pTraceEntryFunc = e;
   396     pTraceExitFunc  = x;
   397     pTraceDataFunc  = d;
   398     gTraceContext   = context;
   399 }
   402 U_CAPI void U_EXPORT2
   403 utrace_getFunctions(const void **context,
   404                     UTraceEntry **e, UTraceExit **x, UTraceData **d) {
   405     *e = pTraceEntryFunc;
   406     *x = pTraceExitFunc;
   407     *d = pTraceDataFunc;
   408     *context = gTraceContext;
   409 }
   411 U_CAPI void U_EXPORT2
   412 utrace_setLevel(int32_t level) {
   413     if (level < UTRACE_OFF) {
   414         level = UTRACE_OFF;
   415     }
   416     if (level > UTRACE_VERBOSE) {
   417         level = UTRACE_VERBOSE;
   418     }
   419     utrace_level = level;
   420 }
   422 U_CAPI int32_t U_EXPORT2
   423 utrace_getLevel() {
   424     return utrace_level;
   425 }
   428 U_CFUNC UBool 
   429 utrace_cleanup() {
   430     pTraceEntryFunc = NULL;
   431     pTraceExitFunc  = NULL;
   432     pTraceDataFunc  = NULL;
   433     utrace_level    = UTRACE_OFF;
   434     gTraceContext   = NULL;
   435     return TRUE;
   436 }
   439 static const char * const
   440 trFnName[] = {
   441     "u_init",
   442     "u_cleanup",
   443     NULL
   444 };
   447 static const char * const
   448 trConvNames[] = {
   449     "ucnv_open",
   450     "ucnv_openPackage",
   451     "ucnv_openAlgorithmic",
   452     "ucnv_clone",
   453     "ucnv_close",
   454     "ucnv_flushCache",
   455     "ucnv_load",
   456     "ucnv_unload",
   457     NULL
   458 };
   461 static const char * const
   462 trCollNames[] = {
   463     "ucol_open",
   464     "ucol_close",
   465     "ucol_strcoll",
   466     "ucol_getSortKey",
   467     "ucol_getLocale",
   468     "ucol_nextSortKeyPart",
   469     "ucol_strcollIter",
   470     NULL
   471 };
   474 U_CAPI const char * U_EXPORT2
   475 utrace_functionName(int32_t fnNumber) {
   476     if(UTRACE_FUNCTION_START <= fnNumber && fnNumber < UTRACE_FUNCTION_LIMIT) {
   477         return trFnName[fnNumber];
   478     } else if(UTRACE_CONVERSION_START <= fnNumber && fnNumber < UTRACE_CONVERSION_LIMIT) {
   479         return trConvNames[fnNumber - UTRACE_CONVERSION_START];
   480     } else if(UTRACE_COLLATION_START <= fnNumber && fnNumber < UTRACE_COLLATION_LIMIT){
   481         return trCollNames[fnNumber - UTRACE_COLLATION_START];
   482     } else {
   483         return "[BOGUS Trace Function Number]";
   484     }
   485 }

mercurial