Skip to content
Permalink
Browse files

[FIX] Clang warning fixes (#1205)

* file_buffer: Fix unitialized variable usage warning

Clang warns:

In file included from src/lib_ccx/asf_functions.c:5:
src/lib_ccx/file_buffer.h:76:7: warning: variable 'result' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
                if (buffer)
                    ^~~~~~
src/lib_ccx/file_buffer.h:86:9: note: uninitialized use occurs here
        return result;
               ^~~~~~
src/lib_ccx/file_buffer.h:76:3: note: remove the 'if' if its condition is always true
                if (buffer)
                ^~~~~~~~~~~
src/lib_ccx/file_buffer.h:73:15: note: initialize the variable 'result' to silence this warning
        size_t result;
                     ^
                      = 0

* common_timing: Fix uninitialized variable usage warning

The vast majority of the code is already using fatal(), so I don't see
why this should be an exception.

Clang warns:

src/lib_ccx/ccx_common_timing.c:274:3: warning: variable 'fts' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
                default:
                ^~~~~~~
src/lib_ccx/ccx_common_timing.c:280:9: note: uninitialized use occurs here
        return fts;
               ^~~
src/lib_ccx/ccx_common_timing.c:261:11: note: initialize the variable 'fts' to silence this warning
        LLONG fts;
                 ^
                  = 0

* encoders: Fix handling of multibyte characters in UTF-8 converter

This is actually incorrect because characters longer than 1 byte will be
butchered.

Clang warns:

src/lib_ccx/ccx_encoders_common.c:178:12: warning: result of comparison of constant 256 with expression of
type 'unsigned char' is always true [-Wtautological-constant-out-of-range-compare]
                                        if (c < 256)
                                            ~ ^ ~~~
src/lib_ccx/ccx_encoders_common.c:193:12: warning: result of comparison of constant 256 with expression of
type 'unsigned char' is always true [-Wtautological-constant-out-of-range-compare]
                                        if (c < 256)
                                            ~ ^ ~~~
src/lib_ccx/ccx_encoders_common.c:209:12: warning: result of comparison of constant 256 with expression of
type 'unsigned char' is always true [-Wtautological-constant-out-of-range-compare]
                                        if (c < 256)
                                            ~ ^ ~~~
src/lib_ccx/ccx_encoders_common.c:229:12: warning: result of comparison of constant 256 with expression of type 'unsigned char' is always true [-Wtautological-constant-out-of-range-compare]
                                        if (c < 256)
                                            ~ ^ ~~~

* gxf: Fix tautological comparison warnings

Clang warns:

src/lib_ccx/ccx_gxf.c:425:17: warning: result of comparison of constant 256 with expression of type 'unsigned char' is always false [-Wtautological-constant-out-of-range-compare]
                                if (tag_len > STR_LEN)
                                    ~~~~~~~ ^ ~~~~~~~
src/lib_ccx/ccx_gxf.c:542:17: warning: result of comparison of constant 256 with expression of type 'unsigned char' is always false [-Wtautological-constant-out-of-range-compare]
                                if (tag_len > STR_LEN)
                                    ~~~~~~~ ^ ~~~~~~~
src/lib_ccx/ccx_gxf.c:617:17: warning: result of comparison of constant 256 with expression of type 'unsigned char' is always false [-Wtautological-constant-out-of-range-compare]
                                if (tag_len > STR_LEN)
                                    ~~~~~~~ ^ ~~~~~~~

* gxf: Fix uninitialized variable usage warnings

Clang warns:

src/lib_ccx/ccx_gxf.c:1449:8: warning: variable 'first_field_nb' is used uninitialized whenever switch case is taken [-Wsometimes-uninitialized]
                case TRACK_TYPE_MPEG1_525:
                     ^~~~~~~~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1475:35: note: uninitialized use occurs here
        debug("first field number %d\n", first_field_nb);
                                         ^~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:28:115: note: expanded from macro 'debug'
                                                                                                                  ^~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1450:8: warning: variable 'first_field_nb' is used uninitialized whenever switch case is taken [-Wsometimes-uninitialized]
                case TRACK_TYPE_MPEG2_525:
                     ^~~~~~~~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1475:35: note: uninitialized use occurs here
        debug("first field number %d\n", first_field_nb);
                                         ^~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:28:115: note: expanded from macro 'debug'
                                                                                                                  ^~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1456:3: warning: variable 'first_field_nb' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
                default:
                ^~~~~~~
src/lib_ccx/ccx_gxf.c:1475:35: note: uninitialized use occurs here
        debug("first field number %d\n", first_field_nb);
                                         ^~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:28:115: note: expanded from macro 'debug'
                                                                                                                  ^~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1410:30: note: initialize the variable 'first_field_nb' to silence this warning
        unsigned char first_field_nb;
                                    ^
                                     = '\0'
src/lib_ccx/ccx_gxf.c:1449:8: warning: variable 'last_field_nb' is used uninitialized whenever switch case is taken [-Wsometimes-uninitialized]
                case TRACK_TYPE_MPEG1_525:
                     ^~~~~~~~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1476:34: note: uninitialized use occurs here
        debug("last field number %d\n", last_field_nb);
                                        ^~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:28:115: note: expanded from macro 'debug'
                                                                                                                  ^~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1450:8: warning: variable 'last_field_nb' is used uninitialized whenever switch case is taken [-Wsometimes-uninitialized]
                case TRACK_TYPE_MPEG2_525:
                     ^~~~~~~~~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1476:34: note: uninitialized use occurs here
        debug("last field number %d\n", last_field_nb);
                                        ^~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:28:115: note: expanded from macro 'debug'
                                                                                                                  ^~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1456:3: warning: variable 'last_field_nb' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
                default:
                ^~~~~~~
src/lib_ccx/ccx_gxf.c:1476:34: note: uninitialized use occurs here
        debug("last field number %d\n", last_field_nb);
                                        ^~~~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:28:115: note: expanded from macro 'debug'
                                                                                                                  ^~~~~~~~~~~
src/lib_ccx/ccx_gxf.c:1411:29: note: initialize the variable 'last_field_nb' to silence this warning
        unsigned char last_field_nb;
                                   ^
                                    = '\0'

* ts_functions: Fix incorrect enumeration type in get_buffer_type

Clang warns:

src/lib_ccx/ts_functions.c:127:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_PES;
                ~~~~~~ ^~~~~~~
src/lib_ccx/ts_functions.c:131:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_H264;
                ~~~~~~ ^~~~~~~~
src/lib_ccx/ts_functions.c:135:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_DVB_SUBTITLE;
                ~~~~~~ ^~~~~~~~~~~~~~~~
src/lib_ccx/ts_functions.c:139:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_ISDB_SUBTITLE;
                ~~~~~~ ^~~~~~~~~~~~~~~~~
src/lib_ccx/ts_functions.c:143:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_HAUPPAGE;
                ~~~~~~ ^~~~~~~~~~~~
src/lib_ccx/ts_functions.c:147:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_TELETEXT;
                ~~~~~~ ^~~~~~~~~~~~
src/lib_ccx/ts_functions.c:151:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_PRIVATE_MPEG2_CC;
                ~~~~~~ ^~~~~~~~~~~~~~~~~~~~
src/lib_ccx/ts_functions.c:155:10: warning: implicit conversion from enumeration type 'enum ccx_bufferdata_type' to different enumeration type 'enum ccx_stream_type' [-Wenum-conversion]
                return CCX_PES;
                ~~~~~~ ^~~~~~~
src/lib_ccx/ts_functions.c:491:24: warning: implicit conversion from enumeration type 'enum ccx_stream_type' to different enumeration type 'enum ccx_bufferdata_type' [-Wenum-conversion]
        ptr->bufferdatatype = get_buffer_type(cinfo);
                            ~ ^~~~~~~~~~~~~~~~~~~~~~

* utility: Fix tautological comparison warnings

Clang warns:

src/lib_ccx/utility.c:605:24: warning: result of comparison of constant 65536 with expression of type 'unsigned short' is always true [-Wtautological-constant-out-of-range-compare]
        } else if (utf16_char < 0x010000) {
                   ~~~~~~~~~~ ^ ~~~~~~~~
src/lib_ccx/utility.c:610:24: warning: result of comparison of constant 1114112 with expression of type 'unsigned short' is always true [-Wtautological-constant-out-of-range-compare]
        } else if (utf16_char < 0x110000) {
                   ~~~~~~~~~~ ^ ~~~~~~~~

* ocr: Fix floating point -> integer abs() warning

Clang warns:

src/lib_ccx/ocr.c:529:8: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
                                if(abs(h-h0)>50) // Color has changed
                                   ^
src/lib_ccx/ocr.c:529:8: note: use function 'fabsf' instead
                                if(abs(h-h0)>50) // Color has changed
                                   ^~~
                                   fabsf
src/lib_ccx/ocr.c:529:8: note: include the header <math.h> or explicitly provide a declaration for 'fabsf'

* encoders: Fix incorrect string types when EIA-608 is in use

Clang warns:

src/lib_ccx/ccx_encoders_helpers.c: In function ‘clever_capitalize’:
src/lib_ccx/ccx_encoders_helpers.c:186:4: warning: case label value exceeds maximum value for type
  186 |    case 0x89: // This is a transparent space
      |    ^~~~

* ocr: Fix implicit struct declaration warning

Clang warns:

In file included from src/lib_ccx/dvd_subtitle_decoder.c:10:
src/lib_ccx/ocr.h:18:54: warning: ‘struct encoder_ctx’ declared inside parameter list will not be visible outside of this definition or declaration
   18 | char *paraof_ocrtext(struct cc_subtitle *sub, struct encoder_ctx *context);
      |                                                      ^~~~~~~~~~~
  • Loading branch information
kdrag0n committed Jan 30, 2020
1 parent 54318d0 commit 732b20aefa3dde718d5f356aea39c9762bf47792
@@ -1,3 +1,4 @@
#include "lib_ccx.h"
#include "ccx_common_timing.h"
#include "ccx_common_constants.h"
#include "ccx_common_structs.h"
@@ -272,7 +273,7 @@ LLONG get_fts(struct ccx_common_timing_ctx *ctx, int current_field)
fts = ctx->fts_now + ctx->fts_global + cb_708 * 1001 / 30;
break;
default:
ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "get_fts: unhandled branch");
fatal(CCX_COMMON_EXIT_BUG_BUG, "get_fts: unhandled branch");
}
// ccx_common_logging.debug_ftn(CCX_DMT_TIME, "[FTS] "
// "fts: %llu, fts_now: %llu, fts_global: %llu, current_field: %llu, cb_708: %llu\n",
@@ -173,10 +173,10 @@ int change_utf8_encoding(unsigned char *dest, unsigned char *src, int len, enum
{
if ((src[1] & 0x40) == 0)
{
c = utf8_to_latin1_map((((unsigned int)(src[0] & 0x1F)) << 6)
int cp = utf8_to_latin1_map((((unsigned int)(src[0] & 0x1F)) << 6)
| ((unsigned int)(src[1] & 0x3F)));
if (c < 256)
*dest++ = c;
if (cp < 256)
*dest++ = cp;
else
*dest++ = '?';
}
@@ -187,11 +187,11 @@ int change_utf8_encoding(unsigned char *dest, unsigned char *src, int len, enum
{
if ((src[1] & 0x40) == 0 && (src[2] & 0x40) == 0)
{
c = utf8_to_latin1_map((((unsigned int)(src[0] & 0x0F)) << 12)
int cp = utf8_to_latin1_map((((unsigned int)(src[0] & 0x0F)) << 12)
| (((unsigned int)(src[1] & 0x3F)) << 6)
| ((unsigned int)(src[2] & 0x3F)));
if (c < 256)
*dest++ = c;
if (cp < 256)
*dest++ = cp;
else
*dest++ = '?';
}
@@ -202,12 +202,12 @@ int change_utf8_encoding(unsigned char *dest, unsigned char *src, int len, enum
(src[2] & 0x40) == 0 &&
(src[3] & 0x40) == 0)
{
c = utf8_to_latin1_map((((unsigned int)(src[0] & 0x07)) << 18)
int cp = utf8_to_latin1_map((((unsigned int)(src[0] & 0x07)) << 18)
| (((unsigned int)(src[1] & 0x3F)) << 12)
| (((unsigned int)(src[2] & 0x3F)) << 6)
| ((unsigned int)(src[3] & 0x3F)));
if (c < 256)
*(dest++) = c;
if (cp < 256)
*(dest++) = cp;
else
*dest++ = '?';
}
@@ -221,13 +221,13 @@ int change_utf8_encoding(unsigned char *dest, unsigned char *src, int len, enum
(src[3] & 0x40) == 0 &&
(src[4] & 0x40) == 0)
{
c = utf8_to_latin1_map((((unsigned int)(src[0] & 0x03)) << 24U)
int cp = utf8_to_latin1_map((((unsigned int)(src[0] & 0x03)) << 24U)
| (((unsigned int)(src[1] & 0x3F)) << 18U)
| (((unsigned int)(src[2] & 0x3F)) << 12U)
| (((unsigned int)(src[3] & 0x3F)) << 6U)
| ((unsigned int)(src[4] & 0x3FU)));
if (c < 256)
*(dest++) = c;
if (cp < 256)
*(dest++) = cp;
else
*dest++ = '?';
}
@@ -1151,7 +1151,7 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
}

for (int i = 0; i < CCX_DECODER_608_SCREEN_ROWS; ++i)
correct_spelling_and_censor_words(context, (char *)data->characters[i], CCX_DECODER_608_SCREEN_WIDTH);
correct_spelling_and_censor_words(context, data->characters[i], CCX_DECODER_608_SCREEN_WIDTH);

#ifdef PYTHON_API
pass_cc_buffer_to_python(data, context);
@@ -1236,7 +1236,7 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
if (rect->ocr_text)
{
int len = strlen(rect->ocr_text);
correct_spelling_and_censor_words(context, rect->ocr_text, len);
correct_spelling_and_censor_words(context, (unsigned char *)rect->ocr_text, len);
for (int i = 0; i < len; ++i)
{
if ((unsigned char)rect->ocr_text[i] == 0x98) // asterisk in 608 encoding
@@ -84,19 +84,19 @@ int string_cmp(const void *p1, const void *p2)
return string_cmp_function(p1, p2, NULL);
}

void capitalize_word(size_t index, char *word)
void capitalize_word(size_t index, unsigned char *word)
{
memcpy(word, capitalization_list.words[index], strlen(capitalization_list.words[index]));
}

void censor_word(size_t index, char *word)
void censor_word(size_t index, unsigned char *word)
{
memset(word, 0x98, strlen(profane.words[index])); // 0x98 is the asterisk in EIA-608
}

void call_function_if_match(char *line, struct word_list *list, void (*modification)(size_t, char *))
void call_function_if_match(unsigned char *line, struct word_list *list, void (*modification)(size_t, unsigned char *))
{
char delim[64] = {
unsigned char delim[64] = {
' ', '\n', '\r', 0x89, 0x99,
'!', '"', '#', '%', '&',
'\'', '(', ')', ';', '<',
@@ -105,18 +105,18 @@ void call_function_if_match(char *line, struct word_list *list, void (*modificat
'.', '/', ':', '^', '_',
'{', '|', '}', '~', '\0' };

char *line_token = strdup(line);
char *c = strtok(line_token, delim);
unsigned char *line_token = strdup(line);
unsigned char *c = strtok(line_token, delim);

if (c != NULL)
{
do
{
char **index = bsearch(&c, list->words, list->len, sizeof(*list->words), string_cmp);
unsigned char **index = bsearch(&c, list->words, list->len, sizeof(*list->words), string_cmp);

if (index)
{
modification(index - list->words, line + (c - line_token));
modification(index - (unsigned char **)list->words, line + (c - line_token));
}
} while ((c = strtok(NULL, delim)) != NULL);
}
@@ -170,7 +170,7 @@ int is_all_caps(struct encoder_ctx *context, int line_num, struct eia608_screen
return (saw_upper && !saw_lower); // 1 if we've seen upper and not lower, 0 otherwise
}

int clever_capitalize(struct encoder_ctx *context, char *line, unsigned int length)
int clever_capitalize(struct encoder_ctx *context, unsigned char *line, unsigned int length)
{
// CFS: Tried doing to clever (see below) but some channels do all uppercase except for
// notes for deaf people (such as "(narrator)" which messes things up.
@@ -445,7 +445,7 @@ int add_builtin_words(const char *builtin[], struct word_list *list)
return 0;
}

void correct_spelling_and_censor_words(struct encoder_ctx *context, char *line, unsigned int length)
void correct_spelling_and_censor_words(struct encoder_ctx *context, unsigned char *line, unsigned int length)
{
if (context->sentence_cap)
{
@@ -34,7 +34,7 @@ int string_cmp_function(const void *p1, const void *p2, void *arg);
int add_word(struct word_list *list, const char *word);

int add_builtin_words(const char *builtin[], struct word_list *list);
void correct_spelling_and_censor_words(struct encoder_ctx *context, char *line, unsigned int length);
void correct_spelling_and_censor_words(struct encoder_ctx *context, unsigned char *line, unsigned int length);

unsigned encode_line (struct encoder_ctx *ctx, unsigned char *buffer, unsigned char *text);

@@ -415,15 +415,13 @@ static int parse_material_sec(struct ccx_demuxer *demux, int len)
switch (tag)
{
case MAT_NAME:
result = buffered_read(demux, (unsigned char *)ctx->media_name, MIN(tag_len, STR_LEN));
result = buffered_read(demux, (unsigned char *)ctx->media_name, tag_len);
demux->past += tag_len;
if (result != MIN(tag_len, STR_LEN))
if (result != tag_len)
{
ret = CCX_EOF;
goto error;
}
if (tag_len > STR_LEN)
buffered_skip(demux, tag_len - STR_LEN);
break;
case MAT_FIRST_FIELD:
ctx->first_field_nb = buffered_get_be32(demux);
@@ -532,15 +530,13 @@ static int parse_mpeg525_track_desc(struct ccx_demuxer *demux, int len)
switch (tag)
{
case TRACK_NAME:
result = buffered_read(demux, (unsigned char *)vid_track->track_name, MIN(tag_len, STR_LEN));
result = buffered_read(demux, (unsigned char *)vid_track->track_name, tag_len);
demux->past += tag_len;
if (result != MIN(tag_len, STR_LEN))
if (result != tag_len)
{
ret = CCX_EOF;
goto error;
}
if (tag_len > STR_LEN)
buffered_skip(demux, tag_len - STR_LEN);
break;
case TRACK_VER:
vid_track->fs_version = buffered_get_be32(demux);
@@ -607,15 +603,13 @@ static int parse_ad_track_desc(struct ccx_demuxer *demux, int len)
switch (tag)
{
case TRACK_NAME:
result = buffered_read(demux, (unsigned char *)ad_track->track_name, MIN(tag_len, STR_LEN));
result = buffered_read(demux, (unsigned char *)ad_track->track_name, tag_len);
demux->past += tag_len;
if (result != MIN(tag_len, STR_LEN))
if (result != tag_len)
{
ret = CCX_EOF;
goto error;
}
if (tag_len > STR_LEN)
buffered_skip(demux, tag_len - STR_LEN);
break;
case TRACK_AUX:
result = buffered_read(demux, (unsigned char *)auxi_info, 8);
@@ -1407,8 +1401,8 @@ static int parse_media(struct ccx_demuxer *demux, int len, struct demuxer_data *
* These values shall be sent starting with the ancillary data field from the lowest number video line continuing to
* higher video line numbers. Within each line the ancillary data fields shall not be reordered.
*/
unsigned char first_field_nb;
unsigned char last_field_nb;
unsigned char first_field_nb = 0;
unsigned char last_field_nb = 0;

/**
* see description of set_mpeg_frame_desc for details
@@ -70,7 +70,7 @@ static size_t inline buffered_read(struct ccx_demuxer *ctx, unsigned char *buffe
*/
static size_t inline buffered_read_byte(struct ccx_demuxer *ctx, unsigned char *buffer)
{
size_t result;
size_t result = 0;
if (ctx->bytesinbuffer - ctx->filebuffer_pos)
{
if (buffer)
@@ -1,3 +1,4 @@
#include <math.h>
#include "png.h"
#include "lib_ccx.h"
#ifdef ENABLE_OCR
@@ -526,7 +527,7 @@ char *ocr_bitmap(void *arg, png_color *palette, png_byte *alpha, unsigned char *
else if (max == g_avg) h = 60 * ((b_avg - r_avg) / (max - min)) + 120;
else h = 60 * ((r_avg - g_avg) / (max - min)) + 240;

if (abs(h - h0) > 50) // Color has changed
if (fabsf(h - h0) > 50) // Color has changed
{
// Write <font> tags for SRT and WebVTT
if (ccx_options.write_format == CCX_OF_SRT ||
@@ -1,6 +1,7 @@
#ifndef OCR_H
#define OCR_H
#include <png.h>
#include "ccx_encoders_common.h"

struct image_copy //A copy of the original OCR image, used for color detection
{
@@ -120,7 +120,7 @@ void pes_header_dump(uint8_t *buffer, long len)
last_pts = pts;
}
}
enum ccx_stream_type get_buffer_type(struct cap_info *cinfo)
enum ccx_bufferdata_type get_buffer_type(struct cap_info *cinfo)
{
if (cinfo->stream == CCX_STREAM_TYPE_VIDEO_MPEG2)
{
@@ -606,19 +606,13 @@ size_t utf16_to_utf8(unsigned short utf16_char, unsigned char *out)
out[1] = (unsigned char)((utf16_char >> 0 & 0x3F) | 0x80);
return 2;
}
else if (utf16_char < 0x010000) {
else
{
out[0] = (unsigned char)((utf16_char >> 12 & 0x0F) | 0xE0);
out[1] = (unsigned char)((utf16_char >> 6 & 0x3F) | 0x80);
out[2] = (unsigned char)((utf16_char >> 0 & 0x3F) | 0x80);
return 3;
}
else if (utf16_char < 0x110000) {
out[0] = (unsigned char)((utf16_char >> 18 & 0x07) | 0xF0);
out[1] = (unsigned char)((utf16_char >> 12 & 0x3F) | 0x80);
out[2] = (unsigned char)((utf16_char >> 6 & 0x3F) | 0x80);
out[3] = (unsigned char)((utf16_char >> 0 & 0x3F) | 0x80);
return 4;
}
return 0;
}

0 comments on commit 732b20a

Please sign in to comment.
You can’t perform that action at this time.