391 // the reason is that we don't want to allocate memory just for that |
391 // the reason is that we don't want to allocate memory just for that |
392 CxBuffer buf = {0}; |
392 CxBuffer buf = {0}; |
393 |
393 |
394 bool all_printable = true; |
394 bool all_printable = true; |
395 for (size_t i = 0; i < str.length; i++) { |
395 for (size_t i = 0; i < str.length; i++) { |
396 bool escape = !isprint(str.ptr[i]) |
396 unsigned char c = str.ptr[i]; |
397 || str.ptr[i] == '\\' |
397 bool escape = c < 0x20 || c == '\\' || c == '"' |
398 || str.ptr[i] == '"' |
398 || (escape_slash && c == '/'); |
399 || (escape_slash && str.ptr[i] == '/'); |
|
400 |
399 |
401 if (all_printable && escape) { |
400 if (all_printable && escape) { |
402 size_t capa = str.length + 32; |
401 size_t capa = str.length + 32; |
403 char *space = malloc(capa); |
402 char *space = malloc(capa); |
404 if (space == NULL) return cx_mutstrn(NULL, 0); |
403 if (space == NULL) return cx_mutstrn(NULL, 0); |
406 cxBufferWrite(str.ptr, 1, i, &buf); |
405 cxBufferWrite(str.ptr, 1, i, &buf); |
407 all_printable = false; |
406 all_printable = false; |
408 } |
407 } |
409 if (escape) { |
408 if (escape) { |
410 cxBufferPut(&buf, '\\'); |
409 cxBufferPut(&buf, '\\'); |
411 if (str.ptr[i] == '\"') { |
410 if (c == '\"') { |
412 cxBufferPut(&buf, '\"'); |
411 cxBufferPut(&buf, '\"'); |
413 } else if (str.ptr[i] == '\n') { |
412 } else if (c == '\n') { |
414 cxBufferPut(&buf, 'n'); |
413 cxBufferPut(&buf, 'n'); |
415 } else if (str.ptr[i] == '\t') { |
414 } else if (c == '\t') { |
416 cxBufferPut(&buf, 't'); |
415 cxBufferPut(&buf, 't'); |
417 } else if (str.ptr[i] == '\r') { |
416 } else if (c == '\r') { |
418 cxBufferPut(&buf, 'r'); |
417 cxBufferPut(&buf, 'r'); |
419 } else if (str.ptr[i] == '\\') { |
418 } else if (c == '\\') { |
420 cxBufferPut(&buf, '\\'); |
419 cxBufferPut(&buf, '\\'); |
421 } else if (str.ptr[i] == '/') { |
420 } else if (c == '/') { |
422 cxBufferPut(&buf, '/'); |
421 cxBufferPut(&buf, '/'); |
423 } else if (str.ptr[i] == '\f') { |
422 } else if (c == '\f') { |
424 cxBufferPut(&buf, 'f'); |
423 cxBufferPut(&buf, 'f'); |
425 } else if (str.ptr[i] == '\b') { |
424 } else if (c == '\b') { |
426 cxBufferPut(&buf, 'b'); |
425 cxBufferPut(&buf, 'b'); |
427 } else { |
426 } else { |
428 char code[6]; |
427 char code[6]; |
429 snprintf(code, sizeof(code), "u%04x", |
428 snprintf(code, sizeof(code), "u%04x", (unsigned int) c); |
430 (unsigned int)(0xff & str.ptr[i])); |
|
431 cxBufferPutString(&buf, code); |
429 cxBufferPutString(&buf, code); |
432 } |
430 } |
433 } else if (!all_printable) { |
431 } else if (!all_printable) { |
434 cxBufferPut(&buf, str.ptr[i]); |
432 cxBufferPut(&buf, c); |
435 } |
433 } |
436 } |
434 } |
437 if (!all_printable) { |
435 if (!all_printable) { |
438 str = cx_mutstrn(buf.space, buf.size); |
436 str = cx_mutstrn(buf.space, buf.size); |
439 } |
437 } |