GitLab wird am Montag, den 31. Januar, zwischen 08:00 und 12:00 Uhr wegen wichtigen Wartungsarbeiten nicht zur Verfügung stehen.

Commit c371ed54 authored by Jan Merle's avatar Jan Merle
Browse files

Initial commit

parents
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...
#!/bin/sh
gcc -g3 -O0 -Wall -Wextra -std=gnu99 -pedantic -o lsp_proxy src/lsp_proxy.c src/buffer.c src/cJSON.c
/*
Copyright (c) 2021 Jan Merle
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "buffer.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#ifdef NDEBUG
#define CHECK_STRING_INVARIANT(str) ((void)0)
#else
#define CHECK_STRING_INVARIANT(str) \
do { \
const string_buf *_str = (str); \
assert(_str); \
assert(_str->len >= 1); \
assert(_str->len <= _str->cap); \
assert(_str->buf); \
} while (0)
#endif
#define MAX(x, y) ((x) >= (y) ? (x) : (y))
// don't use __buf_new and __buf_grow directly, use BUF_* macros instead
__void_buf *__buf_new(__void_buf *buf, size_t initial_capacity, size_t elem_size) {
assert(buf);
buf->cap = initial_capacity;
buf->len = 0;
buf->buf = malloc(initial_capacity * elem_size);
return buf;
}
void __buf_grow(__void_buf *buf, size_t inc, size_t elem_size) {
assert(buf);
assert(buf->buf);
assert(buf->cap >= buf->len);
size_t required_cap = buf->len + inc;
if (required_cap <= buf->cap) {
return;
}
size_t new_cap = MAX(1 + 2 * buf->cap, required_cap);
assert(required_cap <= new_cap);
// TODO: overflow
size_t new_size_in_bytes = new_cap * elem_size;
buf->buf = realloc(buf->buf, new_size_in_bytes);
// TODO: this is allowed to fail, so don't just assert
assert(buf->buf != NULL);
buf->cap = new_cap;
}
// byte buffer functions
void byte_buffer_push(byte_buf *buffer, uint8_t by) { BUF_PUSH(buffer, by); }
uint8_t *byte_buffer_append(byte_buf *buffer, const uint8_t *const src, size_t n) {
uint8_t *buffer_data_append = BUF_ADD(buffer, n);
return memcpy(buffer_data_append, src, n);
}
// string buffer functions
string_buf string_new(size_t initial_capacity) {
string_buf result = {0};
if (initial_capacity < 1) {
initial_capacity = 1;
}
result = BUF_NEW(string_buf, initial_capacity);
BUF_PUSH(&result, '\0');
return result;
}
void string_clear(string_buf *str) {
CHECK_STRING_INVARIANT(str);
str->len = 1;
*str->buf = 0;
}
void string_remove_leading(string_buf *str, size_t n) {
// TODO: this might be too slow and we have to come up with something smarter
CHECK_STRING_INVARIANT(str);
assert(str->len > n); // with null character
if (n == 0) {
return;
}
str->len = str->len - n;
// TODO: what is faster, looping or memmove? (my guess is memmove, but we should still profile it)
memmove(str->buf, str->buf + n, str->len);
// for (int i = 0; i < buffer->len; ++i) {
// buffer->data[i] = buffer->data[i + n];
// }
assert(str->buf[str->len - 1] == 0);
}
// TODO: we have 4 choices: pass number of chars with \0, without \0 (current), or pass a pointer to the \0 byte or pass
// a pointer to the character right before \0
// TODO: use memmove instead of memcpy?
void string_append_cstring_n(string_buf *dest, const char *const src, size_t n) {
CHECK_STRING_INVARIANT(dest);
char *str_data_append = BUF_ADD(dest, n) - 1;
assert(str_data_append >= dest->buf);
memcpy(str_data_append, src, n);
*(dest->buf + dest->len - 1) = 0;
}
void string_append_cstring(string_buf *dest, const char *const src) { string_append_cstring_n(dest, src, strlen(src)); }
void string_append(string_buf *dest, const string_buf *const src) {
CHECK_STRING_INVARIANT(src);
string_append_cstring_n(dest, src->buf, src->len - 1);
}
void string_set_cstring_n(string_buf *dest, const char *const src, size_t n) {
string_clear(dest);
string_append_cstring_n(dest, src, n);
}
void string_set_cstring(string_buf *dest, const char *const src) { string_set_cstring_n(dest, src, strlen(src)); }
void string_set(string_buf *dest, const string_buf *const src) {
CHECK_STRING_INVARIANT(src);
string_set_cstring_n(dest, src->buf, src->len - 1);
}
void string_print_v(string_buf *output, const char *fmt, va_list args) {
va_list args_copy;
assert(output->buf != NULL && output->cap != 0);
CHECK_STRING_INVARIANT(output);
va_copy(args_copy, args);
size_t space_needed = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
char *str_data_append = BUF_ADD(output, space_needed) - 1;
assert(str_data_append >= output->buf);
// va_start(args, fmt);
vsnprintf(str_data_append, space_needed + 1, fmt, args);
// va_end(args);
assert(output->len <= output->cap);
}
void string_print(string_buf *output, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
string_print_v(output, fmt, args);
va_end(args);
}
void string_clearprint(string_buf *output, const char *fmt, ...) {
va_list args;
string_clear(output);
va_start(args, fmt);
string_print_v(output, fmt, args);
va_end(args);
}
/*
Copyright (c) 2021 Jan Merle
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __BUFFER_H_
#define __BUFFER_H_
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define DECLARE_DYN_BUF(name, type) \
typedef struct name##_s { \
size_t cap; \
size_t len; \
type *buf; \
} name
// predefined dynamic buffer types
DECLARE_DYN_BUF(string_buf, char);
DECLARE_DYN_BUF(byte_buf, uint8_t);
DECLARE_DYN_BUF(int_buf, int);
// Generic macros to create and manipulate dynamic arrays in a typesafe manner
// Use DECLARE_DYN_BUF to make your own dynamic buffer types to use with these macros or use the predefined types
// NOTE: buffer and array are sometimes used interchangeably in this file
// For byte buffers you can use the specialised functions byte_buffer_push and byte_buffer_append
// string_buf should only be used together with the specialised string_* functions. These always keep the strings
// null-terminated, so you can just use the buf member whenever you require a c string. If you have to manipulate the
// string without the string_* functions, you have to make sure that len == (strlen + 1) and cap >= len. In this case
// you can use BUF_MAYBE_GROW to manually increase the the buffer capacity.
// Pointers into a dynamic buffer may become invalid when the buffer needs to grow, so be careful if you do that
// TODO: maybe we could have a mechanism to "lock" the buffer, and have it assert if you try to grow a locked buffer
// BUF_NEW creates a new buffer of type t with an initial capacity n on the stack and returns it. This way you can
// do "int_buf b = BUF_NEW(int_buf, 10);".
// TODO: explanation why this is done like this
#define BUF_NEW(t, n) (*((t *)__buf_new((__void_buf *)&((t){0}), (n), sizeof(t))))
// BUF_PUSH takes a pointer to a buffer and an element, puts the element in the first free slot and returns the newly
// pushed element, growing the buffer when necessary. This can potentially invalidate all pointers pointing into the
// aray.
// NOTE: b gets evaluated several times, so it has to be reentrant and side effect free. x is evaluated once and
// therefore can savely be any expression, e.g. "BUF_PUSH(b, get_random_value());"
#define BUF_PUSH(b, x) (__buf_grow((__void_buf *)(b), 1, sizeof(*((b)->buf))), (b)->buf[(b)->len++] = (x))
#define BUF_ADD(b, n) \
(__buf_grow((__void_buf *)(b), (n), sizeof(*((b)->buf))), (b)->len += (n), &(b)->buf[(b)->len - (n)])
// TODO: currently this takes an increment, maybe use absolute size instead? Or maybe two macros for both?
#define BUF_MAYBE_GROW(b, inc) (__buf_grow((__void_buf *)(b), (inc), sizeof(*((b)->buf))))
// TODO: more
// byte buffer functions
void byte_buffer_push(byte_buf *buffer, uint8_t b);
uint8_t *byte_buffer_append(byte_buf *buffer, const uint8_t *const src, size_t n);
// string buffer functions
string_buf string_new(size_t initial_capacity);
void string_clear(string_buf *str);
void string_remove_leading(string_buf *str, size_t n);
void string_append_cstring_n(string_buf *dest, const char *const src, size_t n);
void string_append_cstring(string_buf *dest, const char *const src);
void string_append(string_buf *dest, const string_buf *const src);
void string_set_cstring_n(string_buf *dest, const char *const src, size_t n);
void string_set_cstring(string_buf *dest, const char *const src);
void string_set(string_buf *dest, const string_buf *const src);
void string_print_v(string_buf *output, const char *fmt, va_list args);
void string_print(string_buf *output, const char *fmt, ...);
void string_clearprint(string_buf *output, const char *fmt, ...);
// internal, don't use
DECLARE_DYN_BUF(__void_buf, void);
__void_buf *__buf_new(__void_buf *buf, size_t initial_capacity, size_t elem_size);
void __buf_grow(__void_buf *buf, size_t inc, size_t elem_size);
/*
// // NOTE: unfortunately BUF_APPEND is not typesafe, so be careful if you use it or wrap it in a function for your
// // specific buffer type, like byte_buffer_append
// // TODO: can we generate a wrapper function with a macro?
// #define BUF_APPEND(b, arr, n) (memcpy(BUF_ADD((b), (n)), (arr), (n) * sizeof(*((b)->buf))))
// // TODO: to make the following work, we need something like a BUFFER_IMPL symbol which has to be defined in only one
// // compilation unit to prevent multiple definitions of the generated wrapper functions
// #ifdef BUFFER_IMPL
// #define DECLARE_DYN_BUF_WITH_WRAPPER(name, type) \
// struct name##_s { \
// size_t cap; \
// size_t len; \
// type *buf; \
// }; \
// type *name##_append(struct name##_s *buffer, const type *const src, size_t n) { \
// return BUF_APPEND(buffer, src, n); \
// } \
// struct name##_s name##_new(size_t initial_capacity) { \
// struct name##_s result = {0}; \
// __buf_new((__void_buf *)&result, initial_capacity, sizeof(*(result.buf))); \
// return result; \
// } \
// typedef struct name##_s name
// #else
// #define DECLARE_DYN_BUF_WITH_WRAPPER(name, type)
// struct name##_s { \
// size_t cap; \
// size_t len; \
// type *buf; \
// }; \
// type *name##_append(struct name##_s *buffer, const type *const src, size_t n); \
// struct name##_s name##_new(size_t initial_capacity); \
// typedef struct name##_s name
// #endif
// DECLARE_DYN_BUF_WITH_WRAPPER(byte_buf, uint8_t);
// void byte_buffer_push(byte_buf *buffer, uint8_t b);
// // uint8_t *byte_buf_append(byte_buf *buffer, const uint8_t *const src, size_t n);
*/
#endif
This diff is collapsed.
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 14
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);