Selaa lähdekoodia

plugin-klish: INT and UINT PTYPEs use lazy range parsing.

The parsed range is stored to the ACTION's udata.
Serj Kalichev 4 kuukautta sitten
vanhempi
commit
b6f9108206
3 muutettua tiedostoa jossa 207 lisäystä ja 122 poistoa
  1. 1 1
      plugins/klish/Makefile.am
  2. 206 0
      plugins/klish/ptype_int.c
  3. 0 121
      plugins/klish/ptypes.c

+ 1 - 1
plugins/klish/Makefile.am

@@ -9,8 +9,8 @@ libklish_plugin_klish_la_SOURCES += \
 	plugins/klish/private.h \
 	plugins/klish/plugin_init.c \
 	plugins/klish/ptype_command.c \
+	plugins/klish/ptype_int.c \
 	plugins/klish/ptype_string.c \
-	plugins/klish/ptypes.c \
 	plugins/klish/misc.c \
 	plugins/klish/nav.c \
 	plugins/klish/log.c

+ 206 - 0
plugins/klish/ptype_int.c

@@ -0,0 +1,206 @@
+/*
+ * Implementation of standard PTYPEs
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <faux/str.h>
+#include <faux/list.h>
+#include <faux/conv.h>
+#include <faux/argv.h>
+#include <klish/kcontext.h>
+#include <klish/kentry.h>
+
+
+typedef struct {
+	bool_t is_range;
+	long long int min;
+	long long int max;
+} klish_ptype_INT_t;
+
+typedef struct {
+	bool_t is_range;
+	unsigned long long int min;
+	unsigned long long int max;
+} klish_ptype_UINT_t;
+
+
+klish_ptype_INT_t *klish_ptype_INT_init(kaction_t *action)
+{
+	klish_ptype_INT_t *udata = NULL;
+	const char *line = NULL;
+	faux_argv_t *argv = NULL;
+
+	udata = faux_malloc(sizeof(*udata));
+	assert(udata);
+	if (!udata)
+		return NULL;
+
+	line = kaction_script(action);
+
+	if (faux_str_is_empty(line)) {
+		udata->is_range = BOOL_FALSE;
+
+	} else {
+		const char *str = NULL;
+
+		udata->is_range = BOOL_TRUE;
+
+		argv = faux_argv_new();
+		faux_argv_parse(argv, line);
+		if (faux_argv_len(argv) < 2)
+			goto err;
+
+		// Min
+		str = faux_argv_index(argv, 0);
+		if (!faux_conv_atoll(str, &udata->min, 0))
+			goto err;
+
+		// Max
+		str = faux_argv_index(argv, 1);
+		if (!faux_conv_atoll(str, &udata->max, 0))
+			goto err;
+
+		faux_argv_free(argv);
+	}
+
+	kaction_set_udata(action, udata, faux_free);
+
+	return udata;
+
+err:
+	faux_argv_free(argv);
+	faux_free(udata);
+
+	return NULL;
+}
+
+
+/** @brief PTYPE: Signed int with optional range
+ *
+ * Use long long int for conversion from text.
+ *
+ * <ACTION sym="INT">-30 80</ACTION>
+ * Means range from "-30" to "80"
+ */
+int klish_ptype_INT(kcontext_t *context)
+{
+	kaction_t *action = NULL;
+	klish_ptype_INT_t *udata = NULL;
+	const char *value_str = NULL;
+	long long int value = 0;
+
+	value_str = kcontext_candidate_value(context);
+
+	if (!faux_conv_atoll(value_str, &value, 0))
+		return -1;
+
+	action = kcontext_action(context);
+	udata = (klish_ptype_INT_t *)kaction_udata(action);
+	if (!udata) {
+		udata = klish_ptype_INT_init(action);
+		if (!udata)
+			return -1;
+	}
+
+	if (!udata->is_range)
+		return 0;
+
+	if (value < udata->min || value > udata->max)
+		return -1;
+
+	return 0;
+}
+
+
+klish_ptype_UINT_t *klish_ptype_UINT_init(kaction_t *action)
+{
+	klish_ptype_UINT_t *udata = NULL;
+	const char *line = NULL;
+	faux_argv_t *argv = NULL;
+
+	udata = faux_malloc(sizeof(*udata));
+	assert(udata);
+	if (!udata)
+		return NULL;
+
+	line = kaction_script(action);
+
+	if (faux_str_is_empty(line)) {
+		udata->is_range = BOOL_FALSE;
+
+	} else {
+		const char *str = NULL;
+
+		udata->is_range = BOOL_TRUE;
+
+		argv = faux_argv_new();
+		faux_argv_parse(argv, line);
+		if (faux_argv_len(argv) < 2)
+			goto err;
+
+		// Min
+		str = faux_argv_index(argv, 0);
+		if (!faux_conv_atoull(str, &udata->min, 0))
+			goto err;
+
+		// Max
+		str = faux_argv_index(argv, 1);
+		if (!faux_conv_atoull(str, &udata->max, 0))
+			goto err;
+
+		faux_argv_free(argv);
+	}
+
+	kaction_set_udata(action, udata, faux_free);
+
+	return udata;
+
+err:
+	faux_argv_free(argv);
+	faux_free(udata);
+
+	return NULL;
+}
+
+
+/** @brief PTYPE: Unsigned int with optional range
+ *
+ * Use unsigned long long int for conversion from text.
+ *
+ * <ACTION sym="UINT">30 80</ACTION>
+ * Means range from "30" to "80"
+ */
+int klish_ptype_UINT(kcontext_t *context)
+{
+	kaction_t *action = NULL;
+	klish_ptype_UINT_t *udata = NULL;
+	const char *value_str = NULL;
+	unsigned long long int value = 0;
+
+	value_str = kcontext_candidate_value(context);
+
+	if (!faux_conv_atoull(value_str, &value, 0))
+		return -1;
+
+	action = kcontext_action(context);
+	udata = (klish_ptype_UINT_t *)kaction_udata(action);
+	if (!udata) {
+		udata = klish_ptype_UINT_init(action);
+		if (!udata)
+			return -1;
+	}
+
+	if (!udata->is_range)
+		return 0;
+
+	if (value < udata->min || value > udata->max)
+		return -1;
+
+	return 0;
+}

+ 0 - 121
plugins/klish/ptypes.c

@@ -1,121 +0,0 @@
-/*
- * Implementation of standard PTYPEs
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <faux/str.h>
-#include <faux/list.h>
-#include <faux/conv.h>
-#include <faux/argv.h>
-#include <klish/kcontext.h>
-#include <klish/kentry.h>
-
-
-/** @brief PTYPE: Signed int with optional range
- *
- * Use long long int for conversion from text.
- *
- * <ACTION sym="INT">-30 80</ACTION>
- * Means range from "-30" to "80"
- */
-int klish_ptype_INT(kcontext_t *context)
-{
-	const char *script = NULL;
-	const char *value_str = NULL;
-	long long int value = 0;
-
-	script = kcontext_script(context);
-	value_str = kcontext_candidate_value(context);
-
-	if (!faux_conv_atoll(value_str, &value, 0))
-		return -1;
-
-	// Range is specified
-	if (!faux_str_is_empty(script)) {
-		faux_argv_t *argv = faux_argv_new();
-		const char *str = NULL;
-		faux_argv_parse(argv, script);
-
-		// Min
-		str = faux_argv_index(argv, 0);
-		if (str) {
-			long long int min = 0;
-			if (!faux_conv_atoll(str, &min, 0) || (value < min)) {
-				faux_argv_free(argv);
-				return -1;
-			}
-		}
-
-		// Max
-		str = faux_argv_index(argv, 1);
-		if (str) {
-			long long int max = 0;
-			if (!faux_conv_atoll(str, &max, 0) || (value > max)) {
-				faux_argv_free(argv);
-				return -1;
-			}
-		}
-
-		faux_argv_free(argv);
-	}
-
-	return 0;
-}
-
-
-/** @brief PTYPE: Unsigned int with optional range
- *
- * Use unsigned long long int for conversion from text.
- *
- * <ACTION sym="UINT">30 80</ACTION>
- * Means range from "30" to "80"
- */
-int klish_ptype_UINT(kcontext_t *context)
-{
-	const char *script = NULL;
-	const char *value_str = NULL;
-	unsigned long long int value = 0;
-
-	script = kcontext_script(context);
-	value_str = kcontext_candidate_value(context);
-
-	if (!faux_conv_atoull(value_str, &value, 0))
-		return -1;
-
-	// Range is specified
-	if (!faux_str_is_empty(script)) {
-		faux_argv_t *argv = faux_argv_new();
-		const char *str = NULL;
-		faux_argv_parse(argv, script);
-
-		// Min
-		str = faux_argv_index(argv, 0);
-		if (str) {
-			unsigned long long int min = 0;
-			if (!faux_conv_atoull(str, &min, 0) || (value < min)) {
-				faux_argv_free(argv);
-				return -1;
-			}
-		}
-
-		// Max
-		str = faux_argv_index(argv, 1);
-		if (str) {
-			unsigned long long int max = 0;
-			if (!faux_conv_atoull(str, &max, 0) || (value > max)) {
-				faux_argv_free(argv);
-				return -1;
-			}
-		}
-
-		faux_argv_free(argv);
-	}
-
-	return 0;
-}