aboutsummaryrefslogtreecommitdiffstats
path: root/l4arg.c
diff options
context:
space:
mode:
Diffstat (limited to 'l4arg.c')
-rw-r--r--l4arg.c399
1 files changed, 200 insertions, 199 deletions
diff --git a/l4arg.c b/l4arg.c
index 5e9f8b1..d8180f4 100644
--- a/l4arg.c
+++ b/l4arg.c
@@ -1,3 +1,4 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
#include "l4arg.h"
#include "l4array.h"
@@ -5,237 +6,237 @@
#include <string.h>
LbsStrv* lbs_arg_parse (const char* str, const char* delim,
- const char* esc, const LbsArgQuote* q, LbsArray** detail_ptr) {
+ const char* esc, const LbsArgQuote* q, LbsArray** detail_ptr) {
- LbsStrv* strv = lbs_strv_new ();
- if (strv == NULL) {
- return NULL;
- }
- /* goto label => free_strv */
+ LbsStrv* strv = lbs_strv_new ();
+ if (strv == NULL) {
+ return NULL;
+ }
+ /* goto label => free_strv */
- // string length cache
- int qlen; // user-supplied quoting string table length
- for (qlen = 0; q[qlen].left != NULL && q[qlen].right != NULL; qlen++);
+ // string length cache
+ int qlen; // user-supplied quoting string table length
+ for (qlen = 0; q[qlen].left != NULL && q[qlen].right != NULL; qlen++);
- // qlen will not be too long, so we can use VLA
- int qlen_p = qlen <= 0 ? 1 : qlen;
+ // qlen will not be too long, so we can use VLA
+ int qlen_p = qlen <= 0 ? 1 : qlen;
#if __STDC_NO_VLA__
- int* qllen = malloc (sizeof (int) * qlen_p);
- if (qllen == NULL) {
- lbs_strv_unref (strv);
- return NULL;
- }
- int* qrlen = malloc (sizeof (int) * qlen_p);
- if (qrlen == NULL) {
- lbs_strv_unref (strv);
- return NULL;
- }
+ int* qllen = malloc (sizeof (int) * qlen_p);
+ if (qllen == NULL) {
+ lbs_strv_unref (strv);
+ return NULL;
+ }
+ int* qrlen = malloc (sizeof (int) * qlen_p);
+ if (qrlen == NULL) {
+ lbs_strv_unref (strv);
+ return NULL;
+ }
#else
- int qllen[qlen_p]; // left quoting string length
- int qrlen[qlen_p]; // right quoting string length
+ int qllen[qlen_p]; // left quoting string length
+ int qrlen[qlen_p]; // right quoting string length
#endif
- for (int i = 0; i < qlen; i++) {
- // empty strings are not allowed
- qllen[i] = strlen (q[i].left);
- if (qllen[i] <= 0) {
- goto free_strv;
- }
- qrlen[i] = strlen (q[i].right);
- if (qrlen[i] <= 0) {
- goto free_strv;
- }
- }
-
- LbsArray* detail;
- if (detail_ptr != NULL) {
- detail = lbs_array_new (sizeof (int));
- if (detail == NULL) {
- goto free_strv;
- }
- if (lbs_array_push_back (detail, &(int){-1}) < 0) {
- goto free_detail;
- }
- } else {
- detail = NULL;
- }
- /* goto label => free_detail */
-
- bool is_delimed = true;
- bool is_escaped = false;
- bool is_quoted = false;
- bool ignore_esc = false;
- int stri = 0; // strv index
- int qi; // quoting string index currently used
-
- const char* p = str;
- for (; *p != '\0'; p++) {
+ for (int i = 0; i < qlen; i++) {
+ // empty strings are not allowed
+ qllen[i] = strlen (q[i].left);
+ if (qllen[i] <= 0) {
+ goto free_strv;
+ }
+ qrlen[i] = strlen (q[i].right);
+ if (qrlen[i] <= 0) {
+ goto free_strv;
+ }
+ }
+
+ LbsArray* detail;
+ if (detail_ptr != NULL) {
+ detail = lbs_array_new (sizeof (int));
+ if (detail == NULL) {
+ goto free_strv;
+ }
+ if (lbs_array_push_back (detail, &(int){-1}) < 0) {
+ goto free_detail;
+ }
+ } else {
+ detail = NULL;
+ }
+ /* goto label => free_detail */
+
+ bool is_delimed = true;
+ bool is_escaped = false;
+ bool is_quoted = false;
+ bool ignore_esc = false;
+ int stri = 0; // strv index
+ int qi; // quoting string index currently used
+
+ const char* p = str;
+ for (; *p != '\0'; p++) {
loop_start:
- if (is_escaped) {
- if (lbs_strv_append_char (strv, stri, *p) < 0) {
- goto free_detail;
- }
- is_escaped = false;
- continue;
- }
-
- if (is_quoted) {
- if (strncmp (p, q[qi].right, qrlen[qi]) == 0) {
- is_quoted = false;
- is_escaped = false;
- ignore_esc = false;
- p += qrlen[qi] - 1;
- } else {
- if (!ignore_esc && strchr (esc, *p)) {
- is_escaped = true;
- } else {
- if (lbs_strv_append_char (strv, stri, *p) < 0) {
- goto free_detail;
- }
- }
- }
- continue;
- }
-
- if (strchr (delim, *p)) {
- if (is_delimed) {
- continue;
- }
- if (lbs_strv_append_str_empty (strv) < 0) {
- goto free_detail;
- }
- if (detail != NULL && lbs_array_push_back (detail, &(int){-1}) < 0) {
- goto free_detail;
- }
- stri++;
- is_delimed = true;
- continue;
- }
- if (strchr (esc, *p)) {
- is_escaped = true;
- continue;
- }
-
- is_delimed = false;
-
- for (int i = 0; i < qlen; i++) {
- if (strncmp (p, q[i].left, qllen[i]) == 0) {
- is_quoted = true;
- ignore_esc = q[i].super;
- qi = i;
- p += qllen[qi]; // p++ will be skipped, so do not minus 1 here
- if (detail != NULL) {
- lbs_array_v (detail, int, stri) = qi;
- }
- goto loop_start; // restart the loop
- }
- }
-
- if (lbs_strv_append_char (strv, stri, *p) < 0) {
- goto free_detail;
- }
- }
-
- if (is_delimed && lbs_strv_get_str_len (strv, stri) == 0) {
- lbs_strv_remove_str (strv);
- lbs_array_pop_back (detail);
- }
-
- if (detail_ptr != NULL) {
- *detail_ptr = detail;
- }
+ if (is_escaped) {
+ if (lbs_strv_append_char (strv, stri, *p) < 0) {
+ goto free_detail;
+ }
+ is_escaped = false;
+ continue;
+ }
+
+ if (is_quoted) {
+ if (strncmp (p, q[qi].right, qrlen[qi]) == 0) {
+ is_quoted = false;
+ is_escaped = false;
+ ignore_esc = false;
+ p += qrlen[qi] - 1;
+ } else {
+ if (!ignore_esc && strchr (esc, *p)) {
+ is_escaped = true;
+ } else {
+ if (lbs_strv_append_char (strv, stri, *p) < 0) {
+ goto free_detail;
+ }
+ }
+ }
+ continue;
+ }
+
+ if (strchr (delim, *p)) {
+ if (is_delimed) {
+ continue;
+ }
+ if (lbs_strv_append_str_empty (strv) < 0) {
+ goto free_detail;
+ }
+ if (detail != NULL && lbs_array_push_back (detail, &(int){-1}) < 0) {
+ goto free_detail;
+ }
+ stri++;
+ is_delimed = true;
+ continue;
+ }
+ if (strchr (esc, *p)) {
+ is_escaped = true;
+ continue;
+ }
+
+ is_delimed = false;
+
+ for (int i = 0; i < qlen; i++) {
+ if (strncmp (p, q[i].left, qllen[i]) == 0) {
+ is_quoted = true;
+ ignore_esc = q[i].super;
+ qi = i;
+ p += qllen[qi]; // p++ will be skipped, so do not minus 1 here
+ if (detail != NULL) {
+ lbs_array_v (detail, int, stri) = qi;
+ }
+ goto loop_start; // restart the loop
+ }
+ }
+
+ if (lbs_strv_append_char (strv, stri, *p) < 0) {
+ goto free_detail;
+ }
+ }
+
+ if (is_delimed && lbs_strv_get_str_len (strv, stri) == 0) {
+ lbs_strv_remove_str (strv);
+ lbs_array_pop_back (detail);
+ }
+
+ if (detail_ptr != NULL) {
+ *detail_ptr = detail;
+ }
#if __STDC_NO_VLA__
- free (qllen);
- free (qrlen);
+ free (qllen);
+ free (qrlen);
#endif
- return strv;
+ return strv;
- /* Error-handling goto label */
+ /* Error-handling goto label */
free_detail:
- if (detail != NULL) {
- lbs_array_unref (detail);
- }
+ if (detail != NULL) {
+ lbs_array_unref (detail);
+ }
free_strv:
#if __STDC_NO_VLA__
- free (qllen);
- free (qrlen);
+ free (qllen);
+ free (qrlen);
#endif
- lbs_strv_unref (strv);
- return NULL;
+ lbs_strv_unref (strv);
+ return NULL;
}
LbsArgQopt* lbs_arg_qopt_new (const char* str) {
- LbsStrv* strv;
- LbsArray* detail;
-
- strv = lbs_arg_parse (str, ",", "\\", (LbsArgQuote[]) {
- { "\"", "\"", false }, { "\'", "\'", true }, { NULL, NULL, false}},
- &detail);
-
- if (strv == NULL || detail == NULL) {
- return NULL;
- }
- /* goto label => free_detail_and_strv */
-
- size_t strv_len = lbs_strv_get_len (strv);
- LbsArgQopt* qopt = malloc (sizeof (LbsArgQopt) +
- sizeof (LbsArgQoptItem) * (strv_len + 1));
- if (qopt == NULL) {
- goto free_detail_and_strv;
- }
-
- qopt->len = strv_len;
- qopt->strv = NULL;
- qopt->detail = NULL;
- qopt->opts[strv_len] = (LbsArgQoptItem) { NULL, NULL };
-
- for (size_t i = 0; i < strv_len; i++) {
- qopt->opts[i].name = lbs_strv_dup_str (strv, i);
- if (qopt->opts[i].name == NULL) {
- goto free_qopt;
- }
-
- char* pos = strchr (qopt->opts[i].name, '=');
- if (pos == NULL) {
- qopt->opts[i].value = NULL;
- } else {
- *pos = '\0';
- qopt->opts[i].value = pos + 1;
- }
-
- }
-
- qopt->strv = strv;
- qopt->detail = detail;
- return qopt;
+ LbsStrv* strv;
+ LbsArray* detail;
+
+ strv = lbs_arg_parse (str, ",", "\\", (LbsArgQuote[]) {
+ { "\"", "\"", false }, { "\'", "\'", true }, { NULL, NULL, false}},
+ &detail);
+
+ if (strv == NULL || detail == NULL) {
+ return NULL;
+ }
+ /* goto label => free_detail_and_strv */
+
+ size_t strv_len = lbs_strv_get_len (strv);
+ LbsArgQopt* qopt = malloc (sizeof (LbsArgQopt) +
+ sizeof (LbsArgQoptItem) * (strv_len + 1));
+ if (qopt == NULL) {
+ goto free_detail_and_strv;
+ }
+
+ qopt->len = strv_len;
+ qopt->strv = NULL;
+ qopt->detail = NULL;
+ qopt->opts[strv_len] = (LbsArgQoptItem) { NULL, NULL };
+
+ for (size_t i = 0; i < strv_len; i++) {
+ qopt->opts[i].name = lbs_strv_dup_str (strv, i);
+ if (qopt->opts[i].name == NULL) {
+ goto free_qopt;
+ }
+
+ char* pos = strchr (qopt->opts[i].name, '=');
+ if (pos == NULL) {
+ qopt->opts[i].value = NULL;
+ } else {
+ *pos = '\0';
+ qopt->opts[i].value = pos + 1;
+ }
+
+ }
+
+ qopt->strv = strv;
+ qopt->detail = detail;
+ return qopt;
free_qopt:
- lbs_arg_qopt_free (qopt);
+ lbs_arg_qopt_free (qopt);
free_detail_and_strv:
- lbs_strv_unref (strv);
- lbs_array_unref (detail);
- return NULL;
+ lbs_strv_unref (strv);
+ lbs_array_unref (detail);
+ return NULL;
}
void lbs_arg_qopt_free_generic (void* qopt_generic) {
- if (qopt_generic == NULL) {
- return;
- }
+ if (qopt_generic == NULL) {
+ return;
+ }
- LbsArgQopt* qopt = qopt_generic;
- lbs_strv_unref (qopt->strv);
- lbs_array_unref (qopt->detail);
+ LbsArgQopt* qopt = qopt_generic;
+ lbs_strv_unref (qopt->strv);
+ lbs_array_unref (qopt->detail);
- for (int i = 0; qopt->opts[i].name != NULL; i++) {
- free (qopt->opts[i].name);
- }
+ for (int i = 0; qopt->opts[i].name != NULL; i++) {
+ free (qopt->opts[i].name);
+ }
- free (qopt);
+ free (qopt);
}