Skip to content

Commit b7c7ed0

Browse files
eaferSam Bingner
and
Sam Bingner
authored
Fix a few issues with the C generator (part 4) (#20289)
* [C] Deal with binary api parameters With this change, the bodyParameters array can also be binary, so pass its length around instead of relying on strlen(). * [C] Fix a few remaining enum issues * [C] Install headers and include any_type.h header * [C] Don't require C++ to compile C code * [C] Test binary bodies and path enums in schemas * Update samples --------- Co-authored-by: Sam Bingner <[email protected]>
1 parent 24ddb33 commit b7c7ed0

File tree

38 files changed

+820
-50
lines changed

38 files changed

+820
-50
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CLibcurlClientCodegen.java

+1
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ public void processOpts() {
347347
// root folder
348348
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", "", "CMakeLists.txt"));
349349
supportingFiles.add(new SupportingFile("Packing.cmake.mustache", "", "Packing.cmake"));
350+
supportingFiles.add(new SupportingFile("cmake-config.mustache", "", "Config.cmake.in"));
350351
supportingFiles.add(new SupportingFile("libcurl.licence.mustache", "", "libcurl.licence"));
351352
supportingFiles.add(new SupportingFile("uncrustify-rules.cfg.mustache", "", "uncrustify-rules.cfg"));
352353
supportingFiles.add(new SupportingFile("README.md.mustache", "", "README.md"));

modules/openapi-generator/src/main/resources/C-libcurl/CMakeLists.txt.mustache

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
cmake_minimum_required (VERSION 2.6...3.10.2)
2-
project (CGenerator)
2+
project (CGenerator C)
33

44
cmake_policy(SET CMP0063 NEW)
55

66
set(CMAKE_C_VISIBILITY_PRESET default)
7-
set(CMAKE_CXX_VISIBILITY_PRESET default)
87
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
98
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
109

modules/openapi-generator/src/main/resources/C-libcurl/api-body.mustache

+24-4
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ end:
107107
list_t *localVarHeaderType = {{#hasProduces}}list_createList();{{/hasProduces}}{{^hasProduces}}NULL;{{/hasProduces}}
108108
list_t *localVarContentType = {{#hasConsumes}}list_createList();{{/hasConsumes}}{{^hasConsumes}}NULL;{{/hasConsumes}}
109109
char *localVarBodyParameters = NULL;
110+
size_t localVarBodyLength = 0;
110111

111112
// clear the error code from the previous api call
112113
apiClient->response_code = 0;
@@ -121,12 +122,16 @@ end:
121122
if(!{{paramName}})
122123
goto end;
123124
{{/isString}}
125+
{{#isBinary}}
126+
if(!{{paramName}})
127+
goto end;
128+
{{/isBinary}}
124129
{{/pathParams}}
125130

126131
{{#pathParams}}
127132

128133
// Path Params
129-
long sizeOfPathParams_{{{paramName}}} = {{#pathParams}}{{#isLong}}sizeof({{paramName}})+3{{/isLong}}{{#isString}}strlen({{paramName}})+3{{/isString}}{{^-last}} + {{/-last}}{{/pathParams}} + strlen("{ {{baseName}} }");
134+
long sizeOfPathParams_{{{paramName}}} = {{#pathParams}}{{#isLong}}sizeof({{paramName}})+3{{/isLong}}{{#isString}}strlen({{^isEnum}}{{paramName}}{{/isEnum}}{{#isEnum}}{{{operationId}}}_{{enumName}}_ToString({{paramName}}){{/isEnum}})+3{{/isString}}{{^-last}} + {{/-last}}{{/pathParams}} + strlen("{ {{baseName}} }");
130135
{{#isNumeric}}
131136
if({{paramName}} == 0){
132137
goto end;
@@ -180,13 +185,13 @@ end:
180185

181186
{{/isLong}}
182187
{{#isString}}
183-
if({{paramName}} == NULL) {
188+
if({{paramName}} == {{#isEnum}}0{{/isEnum}}{{^isEnum}}NULL{{/isEnum}}) {
184189
goto end;
185190
}
186191
char* localVarToReplace_{{paramName}} = malloc(sizeOfPathParams_{{paramName}});
187192
sprintf(localVarToReplace_{{paramName}}, "{%s}", "{{baseName}}");
188193

189-
localVarPath = strReplace(localVarPath, localVarToReplace_{{paramName}}, {{paramName}});
194+
localVarPath = strReplace(localVarPath, localVarToReplace_{{paramName}}, {{^isEnum}}{{paramName}}{{/isEnum}}{{#isEnum}}{{{operationId}}}_{{enumName}}_ToString({{paramName}}){{/isEnum}});
190195
{{/isString}}
191196
{{#isUuid}}
192197
if({{paramName}} == NULL) {
@@ -331,20 +336,30 @@ end:
331336
}
332337
cJSON_AddItemToArray(localVarSingleItemJSON_{{paramName}}, localVar_{{paramName}});
333338
localVarBodyParameters = {{{cJSONPrint}}}(localVarItemJSON_{{paramName}});
339+
localVarBodyLength = strlen(localVarBodyParameters);
334340
}
335341
{{/isArray}}
336342
{{^isArray}}
337343
{{#isString}}
338344
localVarBodyParameters = strdup({{paramName}});
345+
localVarBodyLength = strlen(localVarBodyParameters);
339346
{{/isString}}
340347
{{^isString}}
348+
{{#isBinary}}
349+
localVarBodyParameters = malloc({{paramName}}->len);
350+
memcpy(localVarBodyParameters, {{paramName}}->data, {{paramName}}->len);
351+
localVarBodyLength = {{paramName}}->len;
352+
{{/isBinary}}
353+
{{^isBinary}}
341354
cJSON *localVarSingleItemJSON_{{paramName}} = NULL;
342355
if ({{paramName}} != NULL)
343356
{
344-
//string
357+
//not string, not binary
345358
localVarSingleItemJSON_{{paramName}} = {{dataType}}_convertToJSON({{paramName}});
346359
localVarBodyParameters = {{{cJSONPrint}}}(localVarSingleItemJSON_{{paramName}});
360+
localVarBodyLength = strlen(localVarBodyParameters);
347361
}
362+
{{/isBinary}}
348363
{{/isString}}
349364
{{/isArray}}
350365
{{/bodyParam}}
@@ -362,6 +377,7 @@ end:
362377
localVarHeaderType,
363378
localVarContentType,
364379
localVarBodyParameters,
380+
localVarBodyLength,
365381
"{{{httpMethod}}}");
366382

367383
{{#responses}}
@@ -503,10 +519,12 @@ end:
503519
{{/isArray}}
504520
{{^isArray}}
505521
{{^isString}}
522+
{{^isBinary}}
506523
if (localVarSingleItemJSON_{{paramName}}) {
507524
cJSON_Delete(localVarSingleItemJSON_{{paramName}});
508525
localVarSingleItemJSON_{{paramName}} = NULL;
509526
}
527+
{{/isBinary}}
510528
{{/isString}}
511529
free(localVarBodyParameters);
512530
{{/isArray}}
@@ -644,10 +662,12 @@ end:
644662
free(localVarBodyParameters);
645663
{{/isArray}}
646664
{{^isArray}}
665+
{{^isBinary}}
647666
if (localVarSingleItemJSON_{{paramName}}) {
648667
cJSON_Delete(localVarSingleItemJSON_{{paramName}});
649668
localVarSingleItemJSON_{{paramName}} = NULL;
650669
}
670+
{{/isBinary}}
651671
free(localVarBodyParameters);
652672
{{/isArray}}
653673
{{/bodyParams}}

modules/openapi-generator/src/main/resources/C-libcurl/apiClient.c.mustache

+5-4
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,10 @@ char *assembleHeaderField(char *key, char *value) {
244244
return header;
245245
}
246246

247-
void postData(CURL *handle, const char *bodyParameters) {
247+
void postData(CURL *handle, const char *bodyParameters, size_t bodyParametersLength) {
248248
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, bodyParameters);
249249
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE_LARGE,
250-
(curl_off_t)strlen(bodyParameters));
250+
(curl_off_t)bodyParametersLength);
251251
}
252252

253253
int lengthOfKeyPair(keyValuePair_t *keyPair) {
@@ -270,7 +270,8 @@ void apiClient_invoke(apiClient_t *apiClient,
270270
list_t *headerType,
271271
list_t *contentType,
272272
const char *bodyParameters,
273-
const char *requestType) {
273+
size_t bodyParametersLength,
274+
const char *requestType) {
274275
CURL *handle = curl_easy_init();
275276
CURLcode res;
276277
@@ -550,7 +551,7 @@ void apiClient_invoke(apiClient_t *apiClient,
550551
{{/hasAuthMethods}}
551552

552553
if(bodyParameters != NULL) {
553-
postData(handle, bodyParameters);
554+
postData(handle, bodyParameters, bodyParametersLength);
554555
}
555556

556557
res = curl_easy_perform(handle);

modules/openapi-generator/src/main/resources/C-libcurl/apiClient.h.mustache

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ apiClient_t* apiClient_create_with_base_path(const char *basePath
6262

6363
void apiClient_free(apiClient_t *apiClient);
6464

65-
void apiClient_invoke(apiClient_t *apiClient,const char* operationParameter, list_t *queryParameters, list_t *headerParameters, list_t *formParameters,list_t *headerType,list_t *contentType, const char *bodyParameters, const char *requestType);
65+
void apiClient_invoke(apiClient_t *apiClient,const char* operationParameter, list_t *queryParameters, list_t *headerParameters, list_t *formParameters,list_t *headerType,list_t *contentType, const char *bodyParameters, size_t bodyParametersLength, const char *requestType);
6666

6767
sslConfig_t *sslConfig_create(const char *clientCertFile, const char *clientKeyFile, const char *CACertFile, int insecureSkipTlsVerify);
6868

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@PACKAGE_INIT@
2+
3+
include(${CMAKE_CURRENT_LIST_DIR}/@[email protected])
4+
5+
check_required_components("@PROJECT_NAME@")

modules/openapi-generator/src/test/resources/2_0/c/petstore.yaml

+47
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ paths:
280280
required: true
281281
schema:
282282
type: string
283+
format: binary
283284
responses:
284285
'200':
285286
description: successful operation
@@ -348,6 +349,52 @@ paths:
348349
- petstore_auth:
349350
- 'write:pets'
350351
- 'read:pets'
352+
/store/feedback:
353+
post:
354+
tags:
355+
- store
356+
summary: Send us a feedback message
357+
description: ''
358+
operationId: sendFeedback
359+
parameters:
360+
- in: body
361+
name: feedback
362+
description: The feedback message to send
363+
required: true
364+
schema:
365+
type: string
366+
responses:
367+
'200':
368+
description: successful operation
369+
schema:
370+
type: string
371+
description: Thank you message
372+
'/store/rating/{rating}':
373+
post:
374+
tags:
375+
- store
376+
summary: How would you rate our service?
377+
description: ''
378+
operationId: sendRating
379+
parameters:
380+
- in: path
381+
name: rating
382+
description: The rating to submit
383+
required: true
384+
type: string
385+
enum:
386+
- Excellent
387+
- Great
388+
- Good
389+
- Regular
390+
- Bad
391+
- Awful
392+
responses:
393+
'200':
394+
description: successful operation
395+
schema:
396+
type: string
397+
description: Thank you message
351398
/store/daysWithoutIncident:
352399
get:
353400
tags:

samples/client/others/c/bearerAuth/.openapi-generator/FILES

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CMakeLists.txt
2+
Config.cmake.in
23
Packing.cmake
34
README.md
45
api/DefaultAPI.c

samples/client/others/c/bearerAuth/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
cmake_minimum_required (VERSION 2.6...3.10.2)
2-
project (CGenerator)
2+
project (CGenerator C)
33

44
cmake_policy(SET CMP0063 NEW)
55

66
set(CMAKE_C_VISIBILITY_PRESET default)
7-
set(CMAKE_CXX_VISIBILITY_PRESET default)
87
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
98
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
109

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@PACKAGE_INIT@
2+
3+
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake)
4+
5+
check_required_components("@PROJECT_NAME@")

samples/client/others/c/bearerAuth/api/DefaultAPI.c

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ DefaultAPI_privateGet(apiClient_t *apiClient)
2525
list_t *localVarHeaderType = list_createList();
2626
list_t *localVarContentType = NULL;
2727
char *localVarBodyParameters = NULL;
28+
size_t localVarBodyLength = 0;
2829

2930
// clear the error code from the previous api call
3031
apiClient->response_code = 0;
@@ -46,6 +47,7 @@ DefaultAPI_privateGet(apiClient_t *apiClient)
4647
localVarHeaderType,
4748
localVarContentType,
4849
localVarBodyParameters,
50+
localVarBodyLength,
4951
"GET");
5052

5153
// uncomment below to debug the error response
@@ -95,6 +97,7 @@ DefaultAPI_publicGet(apiClient_t *apiClient)
9597
list_t *localVarHeaderType = list_createList();
9698
list_t *localVarContentType = NULL;
9799
char *localVarBodyParameters = NULL;
100+
size_t localVarBodyLength = 0;
98101

99102
// clear the error code from the previous api call
100103
apiClient->response_code = 0;
@@ -116,6 +119,7 @@ DefaultAPI_publicGet(apiClient_t *apiClient)
116119
localVarHeaderType,
117120
localVarContentType,
118121
localVarBodyParameters,
122+
localVarBodyLength,
119123
"GET");
120124

121125
// uncomment below to debug the error response
@@ -165,6 +169,7 @@ DefaultAPI_usersGet(apiClient_t *apiClient)
165169
list_t *localVarHeaderType = list_createList();
166170
list_t *localVarContentType = NULL;
167171
char *localVarBodyParameters = NULL;
172+
size_t localVarBodyLength = 0;
168173

169174
// clear the error code from the previous api call
170175
apiClient->response_code = 0;
@@ -186,6 +191,7 @@ DefaultAPI_usersGet(apiClient_t *apiClient)
186191
localVarHeaderType,
187192
localVarContentType,
188193
localVarBodyParameters,
194+
localVarBodyLength,
189195
"GET");
190196

191197
// uncomment below to debug the error response

samples/client/others/c/bearerAuth/include/apiClient.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ apiClient_t* apiClient_create_with_base_path(const char *basePath
3939

4040
void apiClient_free(apiClient_t *apiClient);
4141

42-
void apiClient_invoke(apiClient_t *apiClient,const char* operationParameter, list_t *queryParameters, list_t *headerParameters, list_t *formParameters,list_t *headerType,list_t *contentType, const char *bodyParameters, const char *requestType);
42+
void apiClient_invoke(apiClient_t *apiClient,const char* operationParameter, list_t *queryParameters, list_t *headerParameters, list_t *formParameters,list_t *headerType,list_t *contentType, const char *bodyParameters, size_t bodyParametersLength, const char *requestType);
4343

4444
sslConfig_t *sslConfig_create(const char *clientCertFile, const char *clientKeyFile, const char *CACertFile, int insecureSkipTlsVerify);
4545

samples/client/others/c/bearerAuth/src/apiClient.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ char *assembleHeaderField(char *key, char *value) {
160160
return header;
161161
}
162162

163-
void postData(CURL *handle, const char *bodyParameters) {
163+
void postData(CURL *handle, const char *bodyParameters, size_t bodyParametersLength) {
164164
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, bodyParameters);
165165
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE_LARGE,
166-
(curl_off_t)strlen(bodyParameters));
166+
(curl_off_t)bodyParametersLength);
167167
}
168168

169169
int lengthOfKeyPair(keyValuePair_t *keyPair) {
@@ -186,7 +186,8 @@ void apiClient_invoke(apiClient_t *apiClient,
186186
list_t *headerType,
187187
list_t *contentType,
188188
const char *bodyParameters,
189-
const char *requestType) {
189+
size_t bodyParametersLength,
190+
const char *requestType) {
190191
CURL *handle = curl_easy_init();
191192
CURLcode res;
192193

@@ -405,7 +406,7 @@ void apiClient_invoke(apiClient_t *apiClient,
405406

406407

407408
if(bodyParameters != NULL) {
408-
postData(handle, bodyParameters);
409+
postData(handle, bodyParameters, bodyParametersLength);
409410
}
410411

411412
res = curl_easy_perform(handle);

samples/client/petstore/c-useJsonUnformatted/.openapi-generator/FILES

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CMakeLists.txt
2+
Config.cmake.in
23
Packing.cmake
34
README.md
45
api/PetAPI.c

samples/client/petstore/c-useJsonUnformatted/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
cmake_minimum_required (VERSION 2.6...3.10.2)
2-
project (CGenerator)
2+
project (CGenerator C)
33

44
cmake_policy(SET CMP0063 NEW)
55

66
set(CMAKE_C_VISIBILITY_PRESET default)
7-
set(CMAKE_CXX_VISIBILITY_PRESET default)
87
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
98
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
109

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@PACKAGE_INIT@
2+
3+
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake)
4+
5+
check_required_components("@PROJECT_NAME@")

samples/client/petstore/c-useJsonUnformatted/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ Category | Method | HTTP request | Description
8282
*StoreAPI* | [**StoreAPI_getInventory**](docs/StoreAPI.md#StoreAPI_getInventory) | **GET** /store/inventory | Returns pet inventories by status
8383
*StoreAPI* | [**StoreAPI_getOrderById**](docs/StoreAPI.md#StoreAPI_getOrderById) | **GET** /store/order/{orderId} | Find purchase order by ID
8484
*StoreAPI* | [**StoreAPI_placeOrder**](docs/StoreAPI.md#StoreAPI_placeOrder) | **POST** /store/order | Place an order for a pet
85+
*StoreAPI* | [**StoreAPI_sendFeedback**](docs/StoreAPI.md#StoreAPI_sendFeedback) | **POST** /store/feedback | Send us a feedback message
86+
*StoreAPI* | [**StoreAPI_sendRating**](docs/StoreAPI.md#StoreAPI_sendRating) | **POST** /store/rating/{rating} | How would you rate our service?
8587
*UserAPI* | [**UserAPI_createUser**](docs/UserAPI.md#UserAPI_createUser) | **POST** /user | Create user
8688
*UserAPI* | [**UserAPI_createUsersWithArrayInput**](docs/UserAPI.md#UserAPI_createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array
8789
*UserAPI* | [**UserAPI_createUsersWithListInput**](docs/UserAPI.md#UserAPI_createUsersWithListInput) | **POST** /user/createWithList | Creates list of users with given input array

0 commit comments

Comments
 (0)