Commit 0809995e authored by Chris Müller's avatar Chris Müller

move header into its folder. Small refactorings in naming conventions

parent d6691d7d
......@@ -8,7 +8,7 @@ set(VERSION "0.1")
include(${PROJECT_SOURCE_DIR}/macros/standard.cmake)
include_directories(src)
include_directories(include)
add_subdirectory(src)
add_subdirectory(test)
......
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STRUCTURES_ARRAY_H
#define CRYSTAL_STRUCTURES_ARRAY_H
#pragma once
/**
* @file structures/array.h
......@@ -52,10 +50,10 @@ size_t cry_array_ensure(struct CryArray* array, size_t min_capa
size_t cry_array_trim(struct CryArray* array);
void cry_array_append(struct CryArray* array, const_pointer data, size_t size);
return_code cry_array_insert(struct CryArray* array, size_t index, const_pointer data, size_t size);
return_code cry_array_remove(struct CryArray* array, size_t index, size_t size);
return_code cry_array_replace(struct CryArray* array, size_t index, const_pointer data, size_t size);
void cry_array_clear(struct CryArray* array);
int cry_array_insert(struct CryArray* array, size_t index, const_pointer data, size_t size);
int cry_array_remove(struct CryArray* array, size_t index, size_t size);
int cry_array_replace(struct CryArray* array, size_t index, const_pointer data, size_t size);
void cry_array_clear(struct CryArray* array);
pointer cry_array_clone(struct CryArray* array);
pointer cry_array_get(struct CryArray* array, size_t index);
......@@ -73,14 +71,13 @@ size_t cry_ptr_array_trim(struct CryPtrArray* array);
void cry_ptr_array_append(struct CryPtrArray* array, pointer ptr);
return_code cry_ptr_array_insert(struct CryPtrArray* array, size_t index, pointer ptr);
int cry_ptr_array_insert(struct CryPtrArray* array, size_t index, pointer ptr);
pointer cry_ptr_array_remove(struct CryPtrArray* array, size_t index);
pointer cry_ptr_array_replace(struct CryPtrArray* array, size_t index, pointer ptr);
void cry_ptr_array_clear(struct CryPtrArray* array, cry_free_funptr fun);
pointer cry_ptr_array_replace(struct CryPtrArray* array, size_t index, pointer ptr);
void cry_ptr_array_clear(struct CryPtrArray* array, cry_free_funptr fun);
pointer cry_ptr_array_get(struct CryPtrArray* array, size_t index);
void cry_ptr_array_each(struct CryPtrArray* array, cry_foreach_funptr fun, pointer data);
void cry_ptr_array_each(struct CryPtrArray* array, cry_foreach_funptr fun, pointer data);
#endif // CRYSTAL_STRUCTURES_ARRAY_H
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STRUCTURES_HEAP_H
#define CRYSTAL_STRUCTURES_HEAP_H
#pragma once
#include "structures.h"
......@@ -37,4 +35,3 @@ pointer cry_heap_pop(struct CryHeap* heap);
#endif // CRYSTAL_STRUCTURES_HEAP_H
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STRUCTURES_LIST_H
#define CRYSTAL_STRUCTURES_LIST_H
#pragma once
#include "structures.h"
......@@ -28,8 +26,8 @@ struct CryList* cry_list_new(void);
void cry_list_free(struct CryList* list, cry_free_funptr handler);
size_t cry_list_size(struct CryList* list);
pointer cry_list_head(struct CryList* list);
pointer cry_list_tail(struct CryList* list);
pointer cry_list_head(struct CryList* list);
pointer cry_list_tail(struct CryList* list);
void cry_list_append(struct CryList* list, pointer data);
void cry_list_prepend(struct CryList* list, pointer data);
......@@ -49,4 +47,3 @@ pointer cry_list_remove(struct CryList* list, struct CryIndex* p
struct CryList* cry_list_concat(struct CryList* first, struct CryList* second);
#endif // CRYSTAL_STRUCTURES_LIST_H
......@@ -16,9 +16,7 @@
*
*/
#ifndef CRYSTAL_STRUCTURES_MAP_H
#define CRYSTAL_STRUCTURES_MAP_H
#pragma once
#include "structures.h"
......@@ -36,8 +34,6 @@ size_t cry_map_size(struct CryMap* map);
pointer cry_map_lookup(struct CryMap* map, const_pointer key);
int cry_map_insert(struct CryMap* map, const_pointer key, const_pointer value);
struct CryMapPair cry_map_remove(struct CryMap* map, const_pointer key);
void cry_map_clear(struct CryMap* map, cry_free_funptr fun_key, cry_free_funptr fun_data);
void cry_map_clear(struct CryMap* map, cry_free_funptr fun_key, cry_free_funptr fun_data);
#endif // CRYSTAL_STRUCTURES_MAP_H
......@@ -16,8 +16,7 @@
*
*/
#ifndef CRYSTAL_STRUCTURES_QUEUE_H
#define CRYSTAL_STRUCTURES_QUEUE_H
#pragma once
#include "structures.h"
......@@ -34,5 +33,3 @@ pointer cry_queue_nth(struct CryQueue* queue, size_t index);
pointer cry_queue_dequeue(struct CryQueue* queue);
void cry_queue_enqueue(struct CryQueue* queue, pointer data);
#endif // CRYSTAL_STRUCTURES_QUEUE_H
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STRUCTURES_REDBLACKTREE_H
#define CRYSTAL_STRUCTURES_REDBLACKTREE_H
#pragma once
#include "structures.h"
......@@ -45,7 +43,7 @@ struct CryRbTree {
struct CryRbTree* cry_rbtree_new(cry_ordering_funptr compare);
void cry_rbtree_clear(struct CryRbTree* tree, cry_free_funptr fun_entry, cry_free_funptr fun_data);
void cry_rbtree_clear(struct CryRbTree* tree, cry_free_funptr fun_entry, cry_free_funptr fun_data);
struct CryRbNode* cry_rbtree_lookup(struct CryRbTree* tree, const_pointer entry);
struct CryRbNode* cry_rbtree_insert(struct CryRbTree* tree, const_pointer entry, const_pointer data);
......@@ -58,10 +56,5 @@ struct CryRbNode* cry_rbnode_next(struct CryRbNode* node);
struct CryRbNode* cry_rbnode_prev(struct CryRbNode* node);
struct CryRbNode* cry_rbnode_new(enum CryRbNodeColor color, struct CryRbNode* parent, const_pointer entry, const_pointer data);
void cry_rbnode_free(struct CryRbNode* node, cry_free_funptr fun_entry, cry_free_funptr fun_data);
void cry_rbnode_free(struct CryRbNode* node, cry_free_funptr fun_entry, cry_free_funptr fun_data);
#endif // CRYSTAL_STRUCTURES_REDBLACKTREE_H
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STRUCTURES_STACK_H
#define CRYSTAL_STRUCTURES_STACK_H
#pragma once
#include "structures.h"
......@@ -33,4 +31,3 @@ pointer cry_stack_pop(struct CryStack* stack);
void cry_stack_push(struct CryStack* stack, pointer data);
#endif // CRYSTAL_STRUCTURES_STACK_H
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_STANDARD_H
#define CRYSTAL_STANDARD_H
#pragma once
/**
* @file standard.h
......@@ -27,46 +25,23 @@
#include <stdlib.h>
#include <stdint.h>
/**
* Convenient Macro for generating tuple types, returning error codes
* and data in a synchronous manner (without using return arguments via pointers)
* @param type Sets the type for the data field of this tuple
* @param T Sets the name for this tuple struct
*/
#define crydefine__tuple(type, T) \
struct T { \
return_code code; \
type data; \
}
/** General error code indicating all is fine */
#define CRY_OKAY 0
/** General error code indicating a failure occured */
#define CRY_FAIL -1
/** typedef to hide void* pointers for clearer interfaces */
typedef void* pointer;
/** typedef to hide void* const_pointers for clearer interfaces */
typedef const void* const_pointer;
/** General typedef for setting an error code identifier */
typedef int return_code;
crydefine__tuple(pointer, tuple_pointer);
crydefine__tuple(const char*, tuple_string);
crydefine__tuple(int, tuple_int);
crydefine__tuple(short, tuple_short);
crydefine__tuple(long, tuple_long);
crydefine__tuple(double, tuple_double);
crydefine__tuple(float, tuple_float);
/** Smaller identifier for uint8_t */
typedef uint8_t byte;
typedef uint8_t byte_t;
/** Two bytes are a word */
typedef uint16_t word_t;
/** Unicode character type */
typedef uint32_t unicode;
typedef uint32_t unicode_t;
#define FALSE 0
#define TRUE 1
/**
* Crystal's malloc macro for allocating memory based on a type
......@@ -102,4 +77,3 @@ static void (*cry_free)(pointer data) = free;
*/
#define cry_cast(Type, Var) ((Type)Var)
#endif // CRYSTAL_STANDARD_H
......@@ -16,16 +16,11 @@
*
*/
#ifndef CRYSTAL_STRUCTURES_H
#define CRYSTAL_STRUCTURES_H
#pragma once
#include "../standard.h"
#include "standard.h"
#define CRY_OUT_OF_INDEX_RANGE -1
#define CRY_ENTRY_NOT_FOUND -2
#define CRY_ENTRY_FULL -3
typedef int (*cry_ordering_funptr)(const_pointer a, const_pointer b);
typedef int (*cry_ordering_funptr)(const_pointer a, const_pointer b);
typedef void (*cry_foreach_funptr)(pointer element, pointer data);
typedef void (*cry_free_funptr)(pointer data);
......@@ -33,4 +28,3 @@ int cry_int_compare(const_pointer a, const_pointer b);
int cry_double_compare(const_pointer a, const_pointer b);
#endif // CRYSTAL_STRUCTURES_H
......@@ -15,26 +15,35 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_UTF8_H
#define CRYSTAL_UTF8_H
#include "standard.h"
int cry_utf8_validate(const byte* str);
int cry_utf8_compare(const byte* str1, const byte* str2);
byte* cry_utf8_chr(const byte* str, unicode character);
byte* cry_utf8_rchr(const byte* str, unicode character);
byte* cry_utf8_str(const byte* str1, const byte* str2);
#pragma once
size_t cry_utf8_size(const byte* str);
size_t cry_utf8_len(const byte* str);
unicode cry_utf8_get(const byte* str);
size_t cry_utf8_codepoints(const byte* str);
byte* cry_utf8_next(const byte* str);
byte* cry_utf8_prev(const byte* str);
#endif // CRYSTAL_UTF8_H
#include "standard.h"
int cry_unicode_isblank(unicode_t ch);
int cry_unicode_isspace(unicode_t ch);
int cry_unicode_isalpha(unicode_t ch);
int cry_unicode_isalnum(unicode_t ch);
int cry_unicode_isdigit(unicode_t ch);
int cry_unicode_ishex(unicode_t ch);
int cry_unicode_isoct(unicode_t ch);
int cry_unicode_isprint(unicode_t ch);
int cry_unicode_isgraph(unicode_t ch);
int cry_unicode_ispunct(unicode_t ch);
int cry_unicode_iscntrl(unicode_t ch);
int cry_utf8_validate(const byte_t* str);
int cry_utf8_compare(const byte_t* str1, const byte_t* str2);
byte_t* cry_utf8_chr(const byte_t* str, unicode_t character);
byte_t* cry_utf8_rchr(const byte_t* str, unicode_t character);
byte_t* cry_utf8_str(const byte_t* str1, const byte_t* str2);
size_t cry_utf8_size(const byte_t* str);
size_t cry_utf8_len(const byte_t* str);
unicode_t cry_utf8_get(const byte_t* str);
size_t cry_utf8_codepoints(const byte_t* str);
byte_t* cry_utf8_next(const byte_t* str);
byte_t* cry_utf8_prev(const byte_t* str);
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_UNITTEST_H
#define CRYSTAL_UNITTEST_H
#pragma once
#include "standard.h"
#include <assert.h>
......@@ -30,4 +28,3 @@ void cry_unittest_initialize(int argc, char** argv);
void cry_unittest_finalize(void);
#endif // CRYSTAL_UNITTEST_H
......@@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CRYSTAL_UNIXCOLORS_H
#define CRYSTAL_UNIXCOLORS_H
#pragma once
// Colors without bold attribute
#define CRY_NORMAL "\x1B[0m"
......@@ -60,4 +58,3 @@
#define CRY_BG_DARKCYAN "\x1B[1;46m"
#define CRY_BG_WHITE "\x1B[1;47m"
#endif // CRYSTAL_UNIXCOLORS_H
set(SOURCES
unittest.c
utf8.c
unicode.c
structures/single_linked_list.c
structures/list.c
......@@ -15,7 +14,6 @@ set(HEADER
standard.h
unix_colors.h
unittest.h
utf8.h
unicode.h
structures/structures.h
structures/array.h
......@@ -30,6 +28,6 @@ set(HEADER
add_library(${TARGET_NAME} SHARED ${SOURCES})
install(DIRECTORY . DESTINATION include/${TARGET_NAME} FILES_MATCHING PATTERN "*.h")
#install(FILES ${HEADER} DESTINATION include/${TARGET_NAME})
install(FILES ${HEADER} DESTINATION include/${TARGET_NAME})
install(TARGETS ${TARGET_NAME} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib)
/*
*******************************************************************************
*
* Copyright (C) 1999-2012, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: utf8.h
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 1999sep13
* created by: Markus W. Scherer
*/
/**
* \file
* \brief C API: 8-bit Unicode handling macros
*
* This file defines macros to deal with 8-bit Unicode (UTF-8) code units (bytes) and strings.
*
* For more information see utf.h and the ICU User Guide Strings chapter
* (http://userguide.icu-project.org/strings).
*
* <em>Usage:</em>
* ICU coding guidelines for if() statements should be followed when using these macros.
* Compound statements (curly braces {}) must be used for if-else-while...
* bodies and all macro statements should be terminated with semicolon.
*/
#ifndef CRYSTAL_ICU_H
#define CRYSTAL_ICU_H
#include "standard.h"
/**
* Counts the trail bytes for a UTF-8 lead byte.
* Returns 0 for 0..0xbf as well as for 0xfe and 0xff.
*
* This is internal since it is not meant to be called directly by external clients;
* however it is called by public macros in this file and thus must remain stable.
*
* Note: Beginning with ICU 50, the implementation uses a multi-condition expression
* which was shown in 2012 (on x86-64) to compile to fast, branch-free code.
* leadByte is evaluated multiple times.
*
* The pre-ICU 50 implementation used the exported array utf8_countTrailBytes:
* #define U8_COUNT_TRAIL_BYTES(leadByte) (utf8_countTrailBytes[leadByte])
* leadByte was evaluated exactly once.
*
* @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
* @internal
*/
#define U8_COUNT_TRAIL_BYTES(leadByte) \
((leadByte)<0xf0 ? \
((leadByte)>=0xc0)+((leadByte)>=0xe0) : \
(leadByte)<0xfe ? 3+((leadByte)>=0xf8)+((leadByte)>=0xfc) : 0)
/**
* Counts the trail bytes for a UTF-8 lead byte of a valid UTF-8 sequence.
* The maximum supported lead byte is 0xf4 corresponding to U+10FFFF.
* leadByte might be evaluated multiple times.
*
* This is internal since it is not meant to be called directly by external clients;
* however it is called by public macros in this file and thus must remain stable.
*
* @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.
* @internal
*/
#define U8_COUNT_TRAIL_BYTES_UNSAFE(leadByte) \
(((leadByte)>=0xc0)+((leadByte)>=0xe0)+((leadByte)>=0xf0))
/**
* Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value.
*
* This is internal since it is not meant to be called directly by external clients;
* however it is called by public macros in this file and thus must remain stable.
* @internal
*/
#define U8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1)
/* single-code point definitions -------------------------------------------- */
/**
* Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)?
* @param c 8-bit code unit (byte)
* @return TRUE or FALSE
* @stable ICU 2.4
*/
#define U8_IS_SINGLE(c) (((c)&0x80)==0)
/**
* Is this code unit (byte) a UTF-8 lead byte?
* @param c 8-bit code unit (byte)
* @return TRUE or FALSE
* @stable ICU 2.4
*/
#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc0)<0x3e)
/**
* Is this code unit (byte) a UTF-8 trail byte?
* @param c 8-bit code unit (byte)
* @return TRUE or FALSE
* @stable ICU 2.4
*/
#define U8_IS_TRAIL(c) (((c)&0xc0)==0x80)
/**
* How many code units (bytes) are used for the UTF-8 encoding
* of this Unicode code point?
* @param c 32-bit code point
* @return 1..4, or 0 if c is a surrogate or not a Unicode code point
* @stable ICU 2.4
*/
#define U8_LENGTH(c) \
((uint32_t)(c)<=0x7f ? 1 : \
((uint32_t)(c)<=0x7ff ? 2 : \
((uint32_t)(c)<=0xd7ff ? 3 : \
((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \
((uint32_t)(c)<=0xffff ? 3 : 4)\
) \
) \
) \
)
/**
* The maximum number of UTF-8 code units (bytes) per Unicode code point (U+0000..U+10ffff).
* @return 4
* @stable ICU 2.4
*/
#define U8_MAX_LENGTH 4
/**
* Get a code point from a string at a random-access offset,
* without changing the offset.
* The offset may point to either the lead byte or one of the trail bytes
* for a code point, in which case the macro will read all of the bytes
* for the code point.
* The result is undefined if the offset points to an illegal UTF-8
* byte sequence.
* Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT.
*
* @param s const uint8_t * string
* @param i string offset
* @param c output UChar32 variable
* @see U8_GET
* @stable ICU 2.4
*/
#define U8_GET_UNSAFE(s, i, c) { \
int32_t _u8_get_unsafe_index=(int32_t)(i); \
U8_SET_CP_START_UNSAFE(s, _u8_get_unsafe_index); \
U8_NEXT_UNSAFE(s, _u8_get_unsafe_index, c); \
}
/**
* Get a code point from a string at a random-access offset,
* without changing the offset.
* The offset may point to either the lead byte or one of the trail bytes
* for a code point, in which case the macro will read all of the bytes
* for the code point.
* If the offset points to an illegal UTF-8 byte sequence, then
* c is set to a negative value.
* Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT.
*
* @param s const uint8_t * string
* @param start starting string offset
* @param i string offset, must be start<=i<length
* @param length string length
* @param c output UChar32 variable, set to <0 in case of an error
* @see U8_GET_UNSAFE
* @stable ICU 2.4
*/
#define U8_GET(s, start, i, length, c) { \
int32_t _u8_get_index=(int32_t)(i); \
U8_SET_CP_START(s, start, _u8_get_index); \
U8_NEXT(s, _u8_get_index, length, c); \
}
/* definitions with forward iteration --------------------------------------- */
/**
* Get a code point from a string at a code point boundary offset,
* and advance the offset to the next code point boundary.
* (Post-incrementing forward iteration.)
* "Unsafe" macro, assumes well-formed UTF-8.
*
* The offset may point to the lead byte of a multi-byte sequence,
* in which case the macro will read the whole sequence.
* The result is undefined if the offset points to a trail byte
* or an illegal UTF-8 sequence.
*
* @param s const uint8_t * string
* @param i string offset
* @param c output UChar32 variable
* @see U8_NEXT
* @stable ICU 2.4
*/
#define U8_NEXT_UNSAFE(s, i, c) { \
(c)=(uint8_t)(s)[(i)++]; \
if((c)>=0x80) { \
if((c)<0xe0) { \
(c)=(((c)&0x1f)<<6)|((s)[(i)++]&0x3f); \
} else if((c)<0xf0) { \
/* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \
(c)=(UChar)(((c)<<12)|(((s)[i]&0x3f)<<6)|((s)[(i)+1]&0x3f)); \
(i)+=2; \
} else { \
(c)=(((c)&7)<<18)|(((s)[i]&0x3f)<<12)|(((s)[(i)+1]&0x3f)<<6)|((s)[(i)+2]&0x3f); \
(i)+=3; \
} \
} \
}
/**
* Get a code point from a string at a code point boundary offset,
* and advance the offset to the next code point boundary.
* (Post-incrementing forward iteration.)
* "Safe" macro, checks for illegal sequences and for string boundaries.
*
* The offset may point to the lead byte of a multi-byte sequence,
* in which case the macro will read the whole sequence.
* If the offset points to a trail byte or an illegal UTF-8 sequence, then
* c is set to a negative value.
*
* @param s const uint8_t * string
* @param i string offset, must be i<length
* @param length string length
* @param c output UChar32 variable, set to <0 in case of an error
* @see U8_NEXT_UNSAFE
* @stable ICU 2.4
*/
#define U8_NEXT(s, i, length, c) { \
(c)=(uint8_t)(s)[(i)++]; \
if((c)>=0x80) { \
uint8_t __t1, __t2; \
if( /* handle U+1000..U+CFFF inline */ \
(0xe0<(c) && (c)<=0xec) && \
(((i)+1)<(length)) && \
(__t1=(uint8_t)((s)[i]-0x80))<=0x3f && \
(__t2=(uint8_t)((s)[(i)+1]-0x80))<= 0x3f \
) { \
/* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \
(c)=(UChar)(((c)<<12)|(__t1<<6)|__t2); \
(i)+=2; \
} else if( /* handle U+0080..U+07FF inline */ \
((c)<0xe0 && (c)>=0xc2) && \
((i)<(length)) && \
(__t1=(uint8_t)((s)[i]-0x80))<=0x3f \
) { \
(c)=(UChar)((((c)&0x1f)<<6)|__t1); \
++(i); \
} else if(U8_IS_LEAD(c)) { \
/* function call for "complicated" and error cases */ \
(c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (int32_t)(length), c, -1); \
} else { \
(c)=U_SENTINEL; \
} \
} \
}
/**
* Append a code point to a string, overwriting 1 to 4 bytes.
* The offset points to the current end of the string contents
* and is advanced (post-increment).
* "Unsafe" macro, assumes a valid code point and sufficient space in the string.
* Otherwise, the result is undefined.
*
* @param s const uint8_t * string buffer
* @param i string offset
* @param c code point to append
* @see U8_APPEND
* @stable ICU 2.4
*/
#define U8_APPEND_UNSAFE(s, i, c) { \
if((uint32_t)(c)<=0x7f) { \
(s)[(i)++]=(uint8_t)(c); \
} else { \
if((uint32_t)(c)<=0x7ff) { \
(s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \
} else { \
if((uint32_t)(c)<=0xffff) { \
(s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \
} else { \
(s)[(i)++]=(uint8_t)(((c)>>18)|0xf0); \
(s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80); \
} \
(s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \
} \
(s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
} \
}
/**
* Append a code point to a string, overwriting 1 to 4 bytes.
* The offset points to the current end of the string contents
* and is advanced (post-increment).
* "Safe" macro, checks for a valid code point.
* If a non-ASCII code point is written, checks for sufficient space in the string.
* If the code point is not valid or trail bytes do not fit,
* then isError is set to TRUE.
*
* @param s const uint8_t * string buffer
* @param i string offset, must be i<capacity
* @param capacity size of the string buffer
* @param c code point to append
* @param isError output UBool set to TRUE if an error occurs, otherwise not modified
* @see U8_APPEND_UNSAFE
* @stable ICU 2.4
*/
#define U8_APPEND(s, i, capacity, c, isError) { \
if((uint32_t)(c)<=0x7f) { \
(s)[(i)++]=(uint8_t)(c); \
} else if((uint32_t)(c)<=0x7ff && (i)+1<(capacity)) { \
(s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \
(s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
} else if((uint32_t)(c)<=0xd7ff && (i)+2<(capacity)) { \
(s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \
(s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \
(s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
} else { \
(i)=utf8_appendCharSafeBody(s, (int32_t)(i), (int32_t)(capacity), c, &(isError)); \
} \