From 1264915af1cd1f47a34873360c4e88ae73a1bd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Tue, 20 Jul 2021 00:11:56 +0800 Subject: Function to get list of just the service codes --- pikul.c | 15 +++++++++++++++ pikul.h | 1 + pikul.i | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/pikul.c b/pikul.c index df1662e..2255081 100644 --- a/pikul.c +++ b/pikul.c @@ -174,6 +174,21 @@ static int servicecmp(const void *service1, const void *service2) (*(struct pikul_service * const *)service2)->code); } +char **pikul_codes(const char *origin, const char *destination, double weight) +{ + char **codes = malloc(sizeof(char *)); + codes[0] = NULL; + struct pikul_services *services = pikul_services(origin, destination, weight); + if (!services || !services->length) + return codes; + codes = realloc(codes, (services->length + 1) * sizeof(char *)); + size_t i = 0; + for (i = 0; i < services->length; i++) + codes[i] = services->list[i]->code; + codes[i] = NULL; + return codes; +} + double pikul_cost(const char *origin, const char *destination, double weight, const char *code) { struct pikul_services *services = pikul_services(origin, destination, weight); diff --git a/pikul.h b/pikul.h index fde0483..07c6880 100644 --- a/pikul.h +++ b/pikul.h @@ -24,6 +24,7 @@ extern "C" { void pikul_init(enum pikul_company company, char *provisions[]); struct pikul_services *pikul_services(const char *origin, const char *destination, double weight); void pikul_free_services(struct pikul_services *services); +char **pikul_codes(const char *origin, const char *destination, double weight); double pikul_cost(const char *origin, const char *destination, double weight, const char *service); char *pikul_order(const char *order_number, const char *service, const char *sender_name, const char *sender_phone, const char *origin, const char *sender_address, diff --git a/pikul.i b/pikul.i index 331cfcb..fca870a 100644 --- a/pikul.i +++ b/pikul.i @@ -17,6 +17,21 @@ %typemap(freearg) char *[] { free($1); } +%typemap(out) char ** { + int len = 0; + while ($1[len]) + len++; + SV **svs = malloc(len * sizeof(SV *)); + for (int i = 0; i < len; i++) { + svs[i] = sv_newmortal(); + sv_setpv((SV *)svs[i], $1[i]); + }; + AV *myav = av_make(len, svs); + free(svs); + $result = newRV_noinc((SV *)myav); + sv_2mortal($result); + argvi++; +} %typemap(in) char **[] { AV *items = (AV *)SvRV($input); @@ -43,6 +58,7 @@ %rename("%(strip:[pikul_])s") ""; void pikul_init(enum pikul_company, char *[]); +char **pikul_codes(const char *, const char *, double); double pikul_cost(const char *, const char *, double, const char *); char *pikul_order(const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, int, -- cgit v1.2.3 From d7a0867335f3aef16baad0fe138f1d09ef29d928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Tue, 20 Jul 2021 22:33:29 +0800 Subject: Function for listing services ready in HTML --- pikul.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ pikul.h | 3 +++ pikul.i | 2 ++ 3 files changed, 51 insertions(+) diff --git a/pikul.c b/pikul.c index 2255081..4a8245e 100644 --- a/pikul.c +++ b/pikul.c @@ -5,6 +5,15 @@ #include #include "private.h" +#define SELECT \ +"" +#define SELECT_NUM_PARAMS 3 +#define OPTION \ +"\t\t\t\t\t\t\t\t\t\t\t\t\n" +#define OPTION_NUM_PARAMS 4 + CURL *curl; json_tokener *tokener; struct shipping shipping; @@ -174,6 +183,43 @@ static int servicecmp(const void *service1, const void *service2) (*(struct pikul_service * const *)service2)->code); } +char *pikul_html(const char *origin, const char *destination, double weight, + const char *widget, const char *extra, const char *name, const char *value, + char *code_prefixes[], char *name_prefixes[]) +{ + struct pikul_services *services = pikul_services(origin, destination, weight); + char *html; + if (!strcmp(widget, "select")) { + char *options = NULL; + for (size_t i = 0; i < services->length; i++) { + struct pikul_service *service = services->list[i]; + char *code_prefix = code_prefixes[shipping.company]; + char *name_prefix = name_prefixes[shipping.company]; + size_t code_length = strlen(code_prefix) + strlen(service->code); + char code[code_length + 1]; + sprintf(code, "%s%s", code_prefix, service->code); + _Bool selected = !strcmp(code, value); + size_t length = strlen(OPTION) + code_length + (selected ? strlen(" selected") : 0) + + strlen(name_prefix) + strlen(service->name) + - OPTION_NUM_PARAMS * strlen("%s"); + char option[length + 1]; + sprintf(option, OPTION, code, selected ? " selected" : "", + name_prefix, service->name); + if (options) + options = realloc(options, strlen(options) + length + 1); + else { + options = malloc(length + 1); + memset(options, '\0', strlen(options)); + } + strcat(options, option); + } + html = malloc(strlen(SELECT) + strlen(name) + (extra ? strlen(extra) : 0) + strlen(options) + - SELECT_NUM_PARAMS * strlen("%s") + 1); + sprintf(html, SELECT, name, extra ? extra : "", options); + } + return html; +} + char **pikul_codes(const char *origin, const char *destination, double weight) { char **codes = malloc(sizeof(char *)); diff --git a/pikul.h b/pikul.h index 07c6880..7d46197 100644 --- a/pikul.h +++ b/pikul.h @@ -24,6 +24,9 @@ extern "C" { void pikul_init(enum pikul_company company, char *provisions[]); struct pikul_services *pikul_services(const char *origin, const char *destination, double weight); void pikul_free_services(struct pikul_services *services); +char *pikul_html(const char *origin, const char *destination, double weight, + const char *widget, const char *extra, const char *name, const char *value, + char *code_prefixes[], char *name_prefixes[]); char **pikul_codes(const char *origin, const char *destination, double weight); double pikul_cost(const char *origin, const char *destination, double weight, const char *service); char *pikul_order(const char *order_number, const char *service, const char *sender_name, diff --git a/pikul.i b/pikul.i index fca870a..d217982 100644 --- a/pikul.i +++ b/pikul.i @@ -58,6 +58,8 @@ %rename("%(strip:[pikul_])s") ""; void pikul_init(enum pikul_company, char *[]); +char *pikul_html(const char *, const char *, double, const char *, const char *, const char *, const char *, + char *[], char *[]); char **pikul_codes(const char *, const char *, double); double pikul_cost(const char *, const char *, double, const char *); char *pikul_order(const char *, const char *, const char *, const char *, const char *, const char *, -- cgit v1.2.3 From 628a1be7997f13cf7c44dc3df215557e32d4e74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Tue, 20 Jul 2021 22:52:39 +0800 Subject: Anticipate situation before there's any address info --- pikul.c | 62 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/pikul.c b/pikul.c index 4a8245e..0a170b7 100644 --- a/pikul.c +++ b/pikul.c @@ -191,27 +191,34 @@ char *pikul_html(const char *origin, const char *destination, double weight, char *html; if (!strcmp(widget, "select")) { char *options = NULL; - for (size_t i = 0; i < services->length; i++) { - struct pikul_service *service = services->list[i]; - char *code_prefix = code_prefixes[shipping.company]; - char *name_prefix = name_prefixes[shipping.company]; - size_t code_length = strlen(code_prefix) + strlen(service->code); - char code[code_length + 1]; - sprintf(code, "%s%s", code_prefix, service->code); - _Bool selected = !strcmp(code, value); - size_t length = strlen(OPTION) + code_length + (selected ? strlen(" selected") : 0) - + strlen(name_prefix) + strlen(service->name) - - OPTION_NUM_PARAMS * strlen("%s"); - char option[length + 1]; - sprintf(option, OPTION, code, selected ? " selected" : "", - name_prefix, service->name); - if (options) - options = realloc(options, strlen(options) + length + 1); - else { - options = malloc(length + 1); - memset(options, '\0', strlen(options)); - } - strcat(options, option); + if (!services || !services->length) { + static const char *empty = ""; + options = malloc(strlen(empty) + 1); + strcpy(options, empty); + } else { + for (size_t i = 0; i < services->length; i++) { + struct pikul_service *service = services->list[i]; + char *code_prefix = code_prefixes[shipping.company]; + char *name_prefix = name_prefixes[shipping.company]; + size_t code_length = strlen(code_prefix) + strlen(service->code); + char code[code_length + 1]; + sprintf(code, "%s%s", code_prefix, service->code); + _Bool selected = !strcmp(code, value); + size_t length = strlen(OPTION) + code_length + + (selected ? strlen(" selected") : 0) + + strlen(name_prefix) + strlen(service->name) + - OPTION_NUM_PARAMS * strlen("%s"); + char option[length + 1]; + sprintf(option, OPTION, code, selected ? " selected" : "", + name_prefix, service->name); + if (options) + options = realloc(options, strlen(options) + length + 1); + else { + options = malloc(length + 1); + memset(options, '\0', strlen(options)); + } + strcat(options, option); + } } html = malloc(strlen(SELECT) + strlen(name) + (extra ? strlen(extra) : 0) + strlen(options) - SELECT_NUM_PARAMS * strlen("%s") + 1); @@ -293,6 +300,19 @@ void pikul_cleanup() default: break; } + /* + if (shipping.data) + switch (shipping.mode) { + case SERVICES: + pikul_free_services(shipping.data); + break; + case ORDER: + free(shipping.data); + break; + default: + break; + } + */ free(shipping.base); json_tokener_free(tokener); curl_slist_free_all(shipping.headers); -- cgit v1.2.3 From f686ef14951df5f4c2a82bc6075bfd520e05c3de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Thu, 22 Jul 2021 17:04:07 +0800 Subject: pikul_codes shouldn't be needed --- pikul.c | 15 --------------- pikul.h | 1 - pikul.i | 16 ---------------- 3 files changed, 32 deletions(-) diff --git a/pikul.c b/pikul.c index 0a170b7..27c4cde 100644 --- a/pikul.c +++ b/pikul.c @@ -227,21 +227,6 @@ char *pikul_html(const char *origin, const char *destination, double weight, return html; } -char **pikul_codes(const char *origin, const char *destination, double weight) -{ - char **codes = malloc(sizeof(char *)); - codes[0] = NULL; - struct pikul_services *services = pikul_services(origin, destination, weight); - if (!services || !services->length) - return codes; - codes = realloc(codes, (services->length + 1) * sizeof(char *)); - size_t i = 0; - for (i = 0; i < services->length; i++) - codes[i] = services->list[i]->code; - codes[i] = NULL; - return codes; -} - double pikul_cost(const char *origin, const char *destination, double weight, const char *code) { struct pikul_services *services = pikul_services(origin, destination, weight); diff --git a/pikul.h b/pikul.h index 7d46197..3581695 100644 --- a/pikul.h +++ b/pikul.h @@ -27,7 +27,6 @@ void pikul_free_services(struct pikul_services *services); char *pikul_html(const char *origin, const char *destination, double weight, const char *widget, const char *extra, const char *name, const char *value, char *code_prefixes[], char *name_prefixes[]); -char **pikul_codes(const char *origin, const char *destination, double weight); double pikul_cost(const char *origin, const char *destination, double weight, const char *service); char *pikul_order(const char *order_number, const char *service, const char *sender_name, const char *sender_phone, const char *origin, const char *sender_address, diff --git a/pikul.i b/pikul.i index d217982..c39c6a3 100644 --- a/pikul.i +++ b/pikul.i @@ -17,21 +17,6 @@ %typemap(freearg) char *[] { free($1); } -%typemap(out) char ** { - int len = 0; - while ($1[len]) - len++; - SV **svs = malloc(len * sizeof(SV *)); - for (int i = 0; i < len; i++) { - svs[i] = sv_newmortal(); - sv_setpv((SV *)svs[i], $1[i]); - }; - AV *myav = av_make(len, svs); - free(svs); - $result = newRV_noinc((SV *)myav); - sv_2mortal($result); - argvi++; -} %typemap(in) char **[] { AV *items = (AV *)SvRV($input); @@ -60,7 +45,6 @@ void pikul_init(enum pikul_company, char *[]); char *pikul_html(const char *, const char *, double, const char *, const char *, const char *, const char *, char *[], char *[]); -char **pikul_codes(const char *, const char *, double); double pikul_cost(const char *, const char *, double, const char *); char *pikul_order(const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, int, -- cgit v1.2.3 From 66fc2d12fca46246024e567aa18cdf853e194776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Thu, 22 Jul 2021 18:48:37 +0800 Subject: Remove commented code --- pikul.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pikul.c b/pikul.c index 27c4cde..1ba8c75 100644 --- a/pikul.c +++ b/pikul.c @@ -285,19 +285,6 @@ void pikul_cleanup() default: break; } - /* - if (shipping.data) - switch (shipping.mode) { - case SERVICES: - pikul_free_services(shipping.data); - break; - case ORDER: - free(shipping.data); - break; - default: - break; - } - */ free(shipping.base); json_tokener_free(tokener); curl_slist_free_all(shipping.headers); -- cgit v1.2.3 From 2ccf1c19b5182bd99b7d717008204737d9cfccd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Thu, 22 Jul 2021 18:49:43 +0800 Subject: No special services struct --- pikul.c | 70 +++++++++++++++++++++++++++++++++++------------------------------ pikul.h | 9 ++------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/pikul.c b/pikul.c index 1ba8c75..3c93e33 100644 --- a/pikul.c +++ b/pikul.c @@ -63,15 +63,13 @@ static size_t handle(char *contents, size_t size, size_t nmemb, void *data) struct json_object *array = NULL; recurse(response, shipping.trail, &array); size_t length = json_object_array_length(array); - shipping.data = malloc(sizeof(struct pikul_services) - + sizeof(struct pikul_service *[length])); - struct pikul_services *services = (struct pikul_services *)shipping.data; - services->length = length; + shipping.data = malloc((length + 1) * sizeof(struct pikul_service *)); + struct pikul_service **services = (struct pikul_service **)shipping.data; const char **attributes = (const char **)data; enum { CODE, NAME, ETD, COST }; for (size_t i = 0; i < length; i++) { - services->list[i] = malloc(sizeof(struct pikul_service)); - struct pikul_service *service = services->list[i]; + services[i] = malloc(sizeof(struct pikul_service)); + struct pikul_service *service = services[i]; json_object *object = json_object_array_get_idx(array, i); struct json_object_iterator iterator = json_object_iter_begin(object); struct json_object_iterator iterator_end = json_object_iter_end(object); @@ -96,6 +94,7 @@ static size_t handle(char *contents, size_t size, size_t nmemb, void *data) json_object_iter_next(&iterator); } } + services[length] = NULL; break; case ORDER: ; @@ -137,7 +136,7 @@ void pikul_init(enum pikul_company company, char *provisions[]) tokener = json_tokener_new(); } -struct pikul_services *pikul_services(const char *origin, const char *destination, double weight) +struct pikul_service **pikul_services(const char *origin, const char *destination, double weight) { shipping.post = NULL; const char **attributes; @@ -157,7 +156,7 @@ struct pikul_services *pikul_services(const char *origin, const char *destinatio if (shipping.post) free(shipping.post); free(shipping.url); - return (struct pikul_services *)shipping.data; + return (struct pikul_service **)shipping.data; } static inline void free_service(struct pikul_service *service) @@ -170,10 +169,11 @@ static inline void free_service(struct pikul_service *service) free(service); } -void pikul_free_services(struct pikul_services *services) +void pikul_free_services(struct pikul_service **services) { - for (size_t i = 0; i < services->length; i++) - free_service(services->list[i]); + size_t i = 0; + while (services[i]) + free_service(services[i++]); free(services); } @@ -184,20 +184,21 @@ static int servicecmp(const void *service1, const void *service2) } char *pikul_html(const char *origin, const char *destination, double weight, - const char *widget, const char *extra, const char *name, const char *value, - char *code_prefixes[], char *name_prefixes[]) + const char *widget, const char *extra, const char *name, const char *value, + char *code_prefixes[], char *name_prefixes[]) { - struct pikul_services *services = pikul_services(origin, destination, weight); - char *html; - if (!strcmp(widget, "select")) { - char *options = NULL; - if (!services || !services->length) { + struct pikul_service **services = pikul_services(origin, destination, weight); + char *html; + if (!strcmp(widget, "select")) { + char *options = NULL; + if (!services || !services[0]) { static const char *empty = ""; options = malloc(strlen(empty) + 1); strcpy(options, empty); } else { - for (size_t i = 0; i < services->length; i++) { - struct pikul_service *service = services->list[i]; + size_t i = 0; + struct pikul_service *service; + while ((service = services[i++])) { char *code_prefix = code_prefixes[shipping.company]; char *name_prefix = name_prefixes[shipping.company]; size_t code_length = strlen(code_prefix) + strlen(service->code); @@ -219,26 +220,31 @@ char *pikul_html(const char *origin, const char *destination, double weight, } strcat(options, option); } - } - html = malloc(strlen(SELECT) + strlen(name) + (extra ? strlen(extra) : 0) + strlen(options) - - SELECT_NUM_PARAMS * strlen("%s") + 1); - sprintf(html, SELECT, name, extra ? extra : "", options); - } - return html; + } + html = malloc(strlen(SELECT) + strlen(name) + (extra ? strlen(extra) : 0) + strlen(options) + - SELECT_NUM_PARAMS * strlen("%s") + 1); + sprintf(html, SELECT, name, extra ? extra : "", options); + } + if (services) + pikul_free_services(services); + return html; } double pikul_cost(const char *origin, const char *destination, double weight, const char *code) { - struct pikul_services *services = pikul_services(origin, destination, weight); - if (!services || !services->length) + struct pikul_service **services = pikul_services(origin, destination, weight); + if (!services || !services[0]) return .0; - qsort(services->list, services->length, sizeof(struct pikul_service *), servicecmp); + size_t length = 0; + while (services[length]) + length++; + qsort(services, length, sizeof(struct pikul_service *), servicecmp); struct pikul_service *key_service = malloc(sizeof(struct pikul_service)); memset(key_service, '\0', sizeof(struct pikul_service)); key_service->code = malloc(strlen(code) + 1); strcpy(key_service->code, code); - double cost = (*(struct pikul_service **)bsearch(&key_service, services->list, - services->length, sizeof(struct pikul_service *), servicecmp))->cost; + double cost = (*(struct pikul_service **)bsearch(&key_service, services, + length, sizeof(struct pikul_service *), servicecmp))->cost; free_service(key_service); pikul_free_services(services); return cost; @@ -254,7 +260,7 @@ char *pikul_order(const char *order_number, const char *service, const char *sen switch (shipping.company) { case PIKUL_ANTERAJA: anteraja_order(order_number, service, sender_name, sender_phone, origin, - sender_address, sender_postal, receiver_name, receiver_phone, + sender_address, sender_postal, receiver_name, receiver_phone, destination, receiver_address, receiver_postal, nitems, items, subtotal); break; diff --git a/pikul.h b/pikul.h index 3581695..696b055 100644 --- a/pikul.h +++ b/pikul.h @@ -12,18 +12,13 @@ struct pikul_service { double cost; }; -struct pikul_services { - size_t length; - struct pikul_service *list[]; -}; - #ifdef __cplusplus extern "C" { #endif void pikul_init(enum pikul_company company, char *provisions[]); -struct pikul_services *pikul_services(const char *origin, const char *destination, double weight); -void pikul_free_services(struct pikul_services *services); +struct pikul_service **pikul_services(const char *origin, const char *destination, double weight); +void pikul_free_services(struct pikul_service **services); char *pikul_html(const char *origin, const char *destination, double weight, const char *widget, const char *extra, const char *name, const char *value, char *code_prefixes[], char *name_prefixes[]); -- cgit v1.2.3 From 218418f3623da5f07cf8428d1d8687b9d5fbc4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Sat, 24 Jul 2021 12:26:02 +0800 Subject: Each shipping info is retained in its own slot Slot/enum 0 is reserved for Pikul. libcurl WRITEFUNCTION callback userData parameter is now used for the shipping instance, but may also be used for something else in turns. --- anteraja.c | 31 +++++---- pikul.c | 224 ++++++++++++++++++++++++++++++++++++------------------------- pikul.h | 21 +++--- pikul.i | 10 +-- private.h | 6 +- 5 files changed, 170 insertions(+), 122 deletions(-) diff --git a/anteraja.c b/anteraja.c index a2e4562..3706f2e 100644 --- a/anteraja.c +++ b/anteraja.c @@ -57,33 +57,35 @@ static char *prefix = NULL; const char **anteraja_init(char *provisions[]) { enum { ACCESS_KEY_ID, SECRET_ACCESS_KEY, BASE_PATH, PREFIX }; - shipping.base = malloc(strlen(provisions[BASE_PATH]) + 1); - strcpy(shipping.base, provisions[BASE_PATH]); + struct shipping *shipping = shipping_list[PIKUL_ANTERAJA]; + shipping->base = malloc(strlen(provisions[BASE_PATH]) + 1); + strcpy(shipping->base, provisions[BASE_PATH]); if (provisions[PREFIX]) { prefix = malloc(strlen(provisions[PREFIX]) + 1); strcpy(prefix, provisions[PREFIX]); } - shipping.headers = curl_slist_append(shipping.headers, "Content-Type:application/json"); + shipping->headers = curl_slist_append(shipping->headers, "Content-Type:application/json"); static const char *status_trail[] = { "status", NULL }; - shipping.status_trail = status_trail; + shipping->status_trail = status_trail; static const char *fields[] = { "access-key-id", "secret-access-key", NULL }; return fields; } const char **anteraja_services(const char *origin, const char *destination, double weight) { - shipping.url = malloc(strlen(shipping.base) + strlen(SERVICES_PATH) + 1); - sprintf(shipping.url, "%s%s", shipping.base, SERVICES_PATH); - shipping.post = malloc(strlen(SERVICES_POST) + strlen(origin) + strlen(destination) + struct shipping *shipping = shipping_list[PIKUL_ANTERAJA]; + shipping->url = malloc(strlen(shipping->base) + strlen(SERVICES_PATH) + 1); + sprintf(shipping->url, "%s%s", shipping->base, SERVICES_PATH); + shipping->post = malloc(strlen(SERVICES_POST) + strlen(origin) + strlen(destination) + SERVICES_WEIGHT - 2 * strlen("%s") - strlen("%d") + 1); - sprintf(shipping.post, SERVICES_POST, origin, destination, + sprintf(shipping->post, SERVICES_POST, origin, destination, weight < 1.0 ? 1000 : (int)weight * 1000); static const char *trail[] = { "content", "services", NULL }; - shipping.trail = trail; + shipping->trail = trail; static const char *attributes[] = { "product_code", "product_name", @@ -99,8 +101,9 @@ void anteraja_order(const char *order_number, const char *service, const char *s const char *destination, const char *receiver_address, const char *receiver_postal, int nitems, char **items[], double subtotal) { - shipping.url = malloc(strlen(shipping.base) + strlen(ORDER_PATH) + 1); - sprintf(shipping.url, "%s%s", shipping.base, ORDER_PATH); + struct shipping *shipping = shipping_list[PIKUL_ANTERAJA]; + shipping->url = malloc(strlen(shipping->base) + strlen(ORDER_PATH) + 1); + sprintf(shipping->url, "%s%s", shipping->base, ORDER_PATH); enum { SKU, QUANTITY, DESCRIPTION, PRICE, WEIGHT }; char *json = NULL; double total_weight = .0; @@ -132,13 +135,13 @@ void anteraja_order(const char *order_number, const char *service, const char *s else json[strlen(json)] = '\0'; } - shipping.post = malloc(strlen(ORDER_POST) + strlen(prefix) + strlen(order_number) + strlen(service) + shipping->post = malloc(strlen(ORDER_POST) + strlen(prefix) + strlen(order_number) + strlen(service) + ORDER_WEIGHT + strlen(sender_name) + strlen(sender_phone) + strlen(origin) + strlen(sender_address) + strlen(sender_postal) + strlen(receiver_name) + strlen(receiver_phone) + strlen(destination) + strlen(receiver_address) + strlen(receiver_postal) + strlen(json) + ORDER_INSURANCE + ORDER_SUBTOTAL - 15 * strlen("%s") - 2 * strlen("%d") + 1); - sprintf(shipping.post, ORDER_POST, prefix, order_number, service, + sprintf(shipping->post, ORDER_POST, prefix, order_number, service, total_weight < 1000.0 ? 1000 : (int)total_weight, sender_name, sender_phone, origin, sender_address, sender_postal, receiver_name, receiver_phone, destination, receiver_address, receiver_postal, json, total_weight < 1000.0 ? "true" : "false", @@ -148,7 +151,7 @@ void anteraja_order(const char *order_number, const char *service, const char *s "waybill_no", NULL }; - shipping.trail = trail; + shipping->trail = trail; } void anteraja_cleanup() diff --git a/pikul.c b/pikul.c index 3c93e33..8ba0cd1 100644 --- a/pikul.c +++ b/pikul.c @@ -2,7 +2,7 @@ #include #endif #include -#include +#include #include "private.h" #define SELECT \ @@ -14,9 +14,7 @@ "\t\t\t\t\t\t\t\t\t\t\t\t\n" #define OPTION_NUM_PARAMS 4 -CURL *curl; -json_tokener *tokener; -struct shipping shipping; +struct shipping *shipping_list[PIKUL_END]; const char **anteraja_init(char *[]); const char **anteraja_services(const char *, const char *, double); @@ -35,13 +33,14 @@ static void recurse(struct json_object *outer, const char *trail[], struct json_ *last = inner; } -static size_t handle(char *contents, size_t size, size_t nmemb, void *data) +static size_t handle(char *contents, size_t size, size_t nmemb, struct shipping *shipping) { size_t realsize = size * nmemb; #ifdef DEBUG contents[realsize] = '\0'; fprintf(stderr, "%s\n", contents); #endif + json_tokener *tokener = shipping->tokener; json_object *response = json_tokener_parse_ex(tokener, contents, realsize); enum json_tokener_error error = json_tokener_get_error(tokener); if (!response) { @@ -54,18 +53,20 @@ static size_t handle(char *contents, size_t size, size_t nmemb, void *data) } else if (!json_object_is_type(response, json_type_object) || error != json_tokener_success) return realsize; struct json_object *status = NULL; - recurse(response, shipping.status_trail, &status); - if (json_object_get_int(status) != 200) + recurse(response, shipping->status_trail, &status); + if (json_object_get_int(status) != 200) { + shipping->data = NULL; return realsize; - switch (shipping.mode) { + } + switch (shipping->mode) { case SERVICES: ; struct json_object *array = NULL; - recurse(response, shipping.trail, &array); + recurse(response, shipping->trail, &array); size_t length = json_object_array_length(array); - shipping.data = malloc((length + 1) * sizeof(struct pikul_service *)); - struct pikul_service **services = (struct pikul_service **)shipping.data; - const char **attributes = (const char **)data; + struct pikul_service **services = malloc(sizeof(struct pikul_service *) + * (length + 1)); + const char **attributes = (const char **)shipping->data; enum { CODE, NAME, ETD, COST }; for (size_t i = 0; i < length; i++) { services[i] = malloc(sizeof(struct pikul_service)); @@ -95,13 +96,14 @@ static size_t handle(char *contents, size_t size, size_t nmemb, void *data) } } services[length] = NULL; + shipping->data = services; break; case ORDER: ; struct json_object *string = NULL; - recurse(response, shipping.trail, &string); - shipping.data = malloc(json_object_get_string_len(string) + 1); - strcpy(shipping.data, json_object_get_string(string)); + recurse(response, shipping->trail, &string); + shipping->data = malloc(json_object_get_string_len(string) + 1); + strcpy(shipping->data, json_object_get_string(string)); break; default: break; @@ -111,15 +113,17 @@ static size_t handle(char *contents, size_t size, size_t nmemb, void *data) void pikul_init(enum pikul_company company, char *provisions[]) { - curl_global_init(CURL_GLOBAL_SSL); - curl = curl_easy_init(); + curl_global_init(CURL_GLOBAL_DEFAULT); + struct shipping *shipping = malloc(sizeof(struct shipping)); + CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, shipping); #ifdef DEBUG curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); #endif - shipping.company = company; - shipping.headers = NULL; + shipping->headers = NULL; const char **fields; + shipping_list[company] = shipping; switch (company) { case PIKUL_ANTERAJA: fields = anteraja_init(provisions); @@ -130,33 +134,39 @@ void pikul_init(enum pikul_company company, char *provisions[]) while (*fields) { char header[strlen(*fields) + strlen(":") + strlen(*provisions) + 1]; sprintf(header, "%s:%s", *fields++, *provisions++); - shipping.headers = curl_slist_append(shipping.headers, header); + shipping->headers = curl_slist_append(shipping->headers, header); } - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, shipping.headers); - tokener = json_tokener_new(); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, shipping->headers); + shipping->handle = curl; + shipping->tokener = json_tokener_new(); } -struct pikul_service **pikul_services(const char *origin, const char *destination, double weight) +struct pikul_service **pikul_services(enum pikul_company company, + const char *origin, const char *destination, double weight) { - shipping.post = NULL; - const char **attributes; - switch (shipping.company) { + struct shipping *shipping = shipping_list[company]; + shipping->post = NULL; + switch (company) { case PIKUL_ANTERAJA: - attributes = anteraja_services(origin, destination, weight); + shipping->data = anteraja_services(origin, destination, weight); break; default: break; } - curl_easy_setopt(curl, CURLOPT_URL, shipping.url); - if (shipping.post) - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, shipping.post); - shipping.mode = SERVICES; - curl_easy_setopt(curl, CURLOPT_WRITEDATA, attributes); + CURL *curl = shipping->handle; + curl_easy_setopt(curl, CURLOPT_URL, shipping->url); + if (shipping->post) { + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, shipping->post); +#ifdef DEBUG + fprintf(stderr, "POST: %s\n", shipping->post); +#endif + } + shipping->mode = SERVICES; curl_easy_perform(curl); - if (shipping.post) - free(shipping.post); - free(shipping.url); - return (struct pikul_service **)shipping.data; + if (shipping->post) + free(shipping->post); + free(shipping->url); + return (struct pikul_service **)shipping->data; } static inline void free_service(struct pikul_service *service) @@ -183,58 +193,78 @@ static int servicecmp(const void *service1, const void *service2) (*(struct pikul_service * const *)service2)->code); } -char *pikul_html(const char *origin, const char *destination, double weight, +char *pikul_html(char *origins[], char *destinations[], double weight, const char *widget, const char *extra, const char *name, const char *value, char *code_prefixes[], char *name_prefixes[]) { - struct pikul_service **services = pikul_services(origin, destination, weight); char *html; + struct pikul_service **services[PIKUL_END]; + bool no_service = true; + for (enum pikul_company company = PIKUL; company < PIKUL_END; company++) { + if (!shipping_list[company]) + continue; + services[company] = pikul_services(company, + origins[company], destinations[company], weight); + if (services[company] && services[company][0]) + no_service = false; + } if (!strcmp(widget, "select")) { char *options = NULL; - if (!services || !services[0]) { + if (no_service) { static const char *empty = ""; options = malloc(strlen(empty) + 1); strcpy(options, empty); - } else { - size_t i = 0; - struct pikul_service *service; - while ((service = services[i++])) { - char *code_prefix = code_prefixes[shipping.company]; - char *name_prefix = name_prefixes[shipping.company]; - size_t code_length = strlen(code_prefix) + strlen(service->code); - char code[code_length + 1]; - sprintf(code, "%s%s", code_prefix, service->code); - _Bool selected = !strcmp(code, value); - size_t length = strlen(OPTION) + code_length - + (selected ? strlen(" selected") : 0) - + strlen(name_prefix) + strlen(service->name) - - OPTION_NUM_PARAMS * strlen("%s"); - char option[length + 1]; - sprintf(option, OPTION, code, selected ? " selected" : "", - name_prefix, service->name); - if (options) - options = realloc(options, strlen(options) + length + 1); - else { - options = malloc(length + 1); - memset(options, '\0', strlen(options)); + } else + for (enum pikul_company company = PIKUL; company < PIKUL_END; company++) { + if (!services[company]) + continue; + if (!services[company][0]) { + free(services[company]); + continue; + } + size_t i = 0; + struct pikul_service *service; + while ((service = services[company][i++])) { + char *code_prefix = code_prefixes[company]; + char *name_prefix = name_prefixes[company]; + size_t code_length = strlen(code_prefix) + strlen(service->code); + char code[code_length + 1]; + sprintf(code, "%s%s", code_prefix, service->code); + _Bool selected = !strcmp(code, value); + size_t length = strlen(OPTION) + code_length + + (selected ? strlen(" selected") : 0) + + strlen(name_prefix) + strlen(service->name) + - OPTION_NUM_PARAMS * strlen("%s"); + char option[length + 1]; + sprintf(option, OPTION, code, selected ? " selected" : "", + name_prefix, service->name); + if (options) + options = realloc(options, strlen(options) + length + 1); + else { + options = malloc(length + 1); + memset(options, '\0', strlen(options)); + } + strcat(options, option); } - strcat(options, option); + pikul_free_services(services[company]); } - } html = malloc(strlen(SELECT) + strlen(name) + (extra ? strlen(extra) : 0) + strlen(options) - SELECT_NUM_PARAMS * strlen("%s") + 1); sprintf(html, SELECT, name, extra ? extra : "", options); } - if (services) - pikul_free_services(services); return html; } -double pikul_cost(const char *origin, const char *destination, double weight, const char *code) +double pikul_cost(enum pikul_company company, const char *code, + const char *origin, const char *destination, double weight) { - struct pikul_service **services = pikul_services(origin, destination, weight); - if (!services || !services[0]) + struct pikul_service **services = pikul_services(company, origin, destination, weight); + if (!services) + return .0; + if (!services[0]) { + free(services); return .0; + } size_t length = 0; while (services[length]) length++; @@ -250,14 +280,16 @@ double pikul_cost(const char *origin, const char *destination, double weight, co return cost; } -char *pikul_order(const char *order_number, const char *service, const char *sender_name, - const char *sender_phone, const char *origin, const char *sender_address, - const char *sender_postal, const char *receiver_name, const char *receiver_phone, - const char *destination, const char *receiver_address, const char *receiver_postal, +char *pikul_order(enum pikul_company company, const char *order_number, const char *service, + const char *sender_name, const char *sender_phone, const char *origin, + const char *sender_address, const char *sender_postal, + const char *receiver_name, const char *receiver_phone, const char *destination, + const char *receiver_address, const char *receiver_postal, int nitems, char **items[], double subtotal) { - shipping.post = NULL; - switch (shipping.company) { + struct shipping *shipping = shipping_list[company]; + shipping->post = NULL; + switch (company) { case PIKUL_ANTERAJA: anteraja_order(order_number, service, sender_name, sender_phone, origin, sender_address, sender_postal, receiver_name, receiver_phone, @@ -267,33 +299,39 @@ char *pikul_order(const char *order_number, const char *service, const char *sen default: break; } - curl_easy_setopt(curl, CURLOPT_URL, shipping.url); - if (shipping.post) { - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, shipping.post); + CURL *curl = shipping->handle; + curl_easy_setopt(curl, CURLOPT_URL, shipping->url); + if (shipping->post) { + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, shipping->post); #ifdef DEBUG - fprintf(stderr, "POST: %s\n", shipping.post); + fprintf(stderr, "POST: %s\n", shipping->post); #endif } - shipping.mode = ORDER; + shipping->mode = ORDER; curl_easy_perform(curl); - if (shipping.post) - free(shipping.post); - free(shipping.url); - return (char *)shipping.data; + if (shipping->post) + free(shipping->post); + free(shipping->url); + return (char *)shipping->data; } void pikul_cleanup() { - switch (shipping.company) { - case PIKUL_ANTERAJA: - anteraja_cleanup(); - break; - default: - break; + for (enum pikul_company company = PIKUL; company < PIKUL_END; company++) { + if (!shipping_list[company]) + continue; + switch (company) { + case PIKUL_ANTERAJA: + anteraja_cleanup(); + break; + default: + break; + } + struct shipping *shipping = shipping_list[company]; + free(shipping->base); + json_tokener_free(shipping->tokener); + curl_slist_free_all(shipping->headers); + curl_easy_cleanup(shipping->handle); } - free(shipping.base); - json_tokener_free(tokener); - curl_slist_free_all(shipping.headers); - curl_easy_cleanup(curl); curl_global_cleanup(); } diff --git a/pikul.h b/pikul.h index 696b055..8e41762 100644 --- a/pikul.h +++ b/pikul.h @@ -2,7 +2,9 @@ #define PIKUL_H enum pikul_company { - PIKUL_ANTERAJA + PIKUL, + PIKUL_ANTERAJA, + PIKUL_END }; struct pikul_service { @@ -17,16 +19,19 @@ extern "C" { #endif void pikul_init(enum pikul_company company, char *provisions[]); -struct pikul_service **pikul_services(const char *origin, const char *destination, double weight); +struct pikul_service **pikul_services(enum pikul_company company, + const char *origin, const char *destination, double weight); void pikul_free_services(struct pikul_service **services); -char *pikul_html(const char *origin, const char *destination, double weight, +char *pikul_html(char *origins[], char *destinations[], double weight, const char *widget, const char *extra, const char *name, const char *value, char *code_prefixes[], char *name_prefixes[]); -double pikul_cost(const char *origin, const char *destination, double weight, const char *service); -char *pikul_order(const char *order_number, const char *service, const char *sender_name, - const char *sender_phone, const char *origin, const char *sender_address, - const char *sender_postal, const char *receiver_name, const char *receiver_phone, - const char *destination, const char *receiver_address, const char *receiver_postal, +double pikul_cost(enum pikul_company company, const char *service, + const char *origin, const char *destination, double weight); +char *pikul_order(enum pikul_company company, const char *order_number, const char *service, + const char *sender_name, const char *sender_phone, const char *origin, + const char *sender_address, const char *sender_postal, + const char *receiver_name, const char *receiver_phone, const char *destination, + const char *receiver_address, const char *receiver_postal, int nitems, char **items[], double subtotal); void pikul_cleanup(); diff --git a/pikul.i b/pikul.i index c39c6a3..ae59146 100644 --- a/pikul.i +++ b/pikul.i @@ -43,10 +43,10 @@ %rename("%(strip:[pikul_])s") ""; void pikul_init(enum pikul_company, char *[]); -char *pikul_html(const char *, const char *, double, const char *, const char *, const char *, const char *, +char *pikul_html(char *[], char *[], double, const char *, const char *, const char *, const char *, char *[], char *[]); -double pikul_cost(const char *, const char *, double, const char *); -char *pikul_order(const char *, const char *, const char *, const char *, const char *, const char *, - const char *, const char *, const char *, const char *, const char *, const char *, int, - char **[], double); +double pikul_cost(enum pikul_company, const char *, const char *, const char *, double); +char *pikul_order(enum pikul_company, const char *, const char *, const char *, const char *, const char *, + const char *, const char *, const char *, const char *, const char *, const char *, + const char *, int, char **[], double); void pikul_cleanup(); diff --git a/private.h b/private.h index 6df3e91..954d29e 100644 --- a/private.h +++ b/private.h @@ -1,17 +1,19 @@ #include +#include #include "pikul.h" extern struct shipping { - enum pikul_company company; + CURL *handle; char *base; struct curl_slist *headers; const char **status_trail; char *url; char *post; + json_tokener *tokener; enum { SERVICES, ORDER } mode; const char **trail; void *data; -} shipping; +} *shipping_list[]; -- cgit v1.2.3 From b960919d909c75dc9c483846c2acec5315a0b7db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A6=8C=EA=A6=AB=EA=A6=B6=EA=A6=8F=EA=A7=80=EA=A6=A6?= =?UTF-8?q?=EA=A6=BF=EA=A6=A7=EA=A6=AE=EA=A6=91=EA=A6=A9=EA=A6=AD=EA=A7=80?= Date: Sat, 24 Jul 2021 13:09:19 +0800 Subject: Make sure services is filled with NULL --- pikul.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pikul.c b/pikul.c index 8ba0cd1..c9d9eda 100644 --- a/pikul.c +++ b/pikul.c @@ -201,8 +201,10 @@ char *pikul_html(char *origins[], char *destinations[], double weight, struct pikul_service **services[PIKUL_END]; bool no_service = true; for (enum pikul_company company = PIKUL; company < PIKUL_END; company++) { - if (!shipping_list[company]) + if (!shipping_list[company]) { + services[company] = NULL; continue; + } services[company] = pikul_services(company, origins[company], destinations[company], weight); if (services[company] && services[company][0]) -- cgit v1.2.3