ambrop7 14 лет назад
Родитель
Сommit
1b42ef81ac

+ 1 - 0
blog_channels.txt

@@ -23,6 +23,7 @@ ncd_runonce 4
 ncd_spawn 4
 ncd_call 4
 ncd_ref 4
+ncd_index 4
 ncd_process_manager 4
 ncd_net_backend_waitdevice 4
 ncd_net_backend_waitlink 4

+ 4 - 0
generated/blog_channel_ncd_index.h

@@ -0,0 +1,4 @@
+#ifdef BLOG_CURRENT_CHANNEL
+#undef BLOG_CURRENT_CHANNEL
+#endif
+#define BLOG_CURRENT_CHANNEL BLOG_CHANNEL_ncd_index

+ 65 - 64
generated/blog_channels_defines.h

@@ -23,67 +23,68 @@
 #define BLOG_CHANNEL_ncd_spawn 22
 #define BLOG_CHANNEL_ncd_call 23
 #define BLOG_CHANNEL_ncd_ref 24
-#define BLOG_CHANNEL_ncd_process_manager 25
-#define BLOG_CHANNEL_ncd_net_backend_waitdevice 26
-#define BLOG_CHANNEL_ncd_net_backend_waitlink 27
-#define BLOG_CHANNEL_ncd_net_backend_badvpn 28
-#define BLOG_CHANNEL_ncd_net_backend_wpa_supplicant 29
-#define BLOG_CHANNEL_ncd_net_backend_rfkill 30
-#define BLOG_CHANNEL_ncd_net_up 31
-#define BLOG_CHANNEL_ncd_net_dns 32
-#define BLOG_CHANNEL_ncd_net_iptables 33
-#define BLOG_CHANNEL_ncd_net_ipv4_addr 34
-#define BLOG_CHANNEL_ncd_net_ipv4_route 35
-#define BLOG_CHANNEL_ncd_net_ipv4_dhcp 36
-#define BLOG_CHANNEL_ncd_net_watch_interfaces 37
-#define BLOG_CHANNEL_ncd_sys_watch_input 38
-#define BLOG_CHANNEL_ncd_sys_evdev 39
-#define BLOG_CHANNEL_ncd_sys_watch_directory 40
-#define BLOG_CHANNEL_StreamPeerIO 41
-#define BLOG_CHANNEL_DatagramPeerIO 42
-#define BLOG_CHANNEL_BReactor 43
-#define BLOG_CHANNEL_BSignal 44
-#define BLOG_CHANNEL_FragmentProtoAssembler 45
-#define BLOG_CHANNEL_BPredicate 46
-#define BLOG_CHANNEL_ServerConnection 47
-#define BLOG_CHANNEL_Listener 48
-#define BLOG_CHANNEL_DataProto 49
-#define BLOG_CHANNEL_FrameDecider 50
-#define BLOG_CHANNEL_BSocksClient 51
-#define BLOG_CHANNEL_BDHCPClientCore 52
-#define BLOG_CHANNEL_BDHCPClient 53
-#define BLOG_CHANNEL_NCDIfConfig 54
-#define BLOG_CHANNEL_BUnixSignal 55
-#define BLOG_CHANNEL_BProcess 56
-#define BLOG_CHANNEL_PRStreamSink 57
-#define BLOG_CHANNEL_PRStreamSource 58
-#define BLOG_CHANNEL_PacketProtoDecoder 59
-#define BLOG_CHANNEL_DPRelay 60
-#define BLOG_CHANNEL_BThreadWork 61
-#define BLOG_CHANNEL_DPReceive 62
-#define BLOG_CHANNEL_BInputProcess 63
-#define BLOG_CHANNEL_NCDUdevMonitorParser 64
-#define BLOG_CHANNEL_NCDUdevMonitor 65
-#define BLOG_CHANNEL_NCDUdevCache 66
-#define BLOG_CHANNEL_NCDUdevManager 67
-#define BLOG_CHANNEL_BTime 68
-#define BLOG_CHANNEL_BEncryption 69
-#define BLOG_CHANNEL_SPProtoDecoder 70
-#define BLOG_CHANNEL_LineBuffer 71
-#define BLOG_CHANNEL_BTap 72
-#define BLOG_CHANNEL_lwip 73
-#define BLOG_CHANNEL_NCDConfigParser 74
-#define BLOG_CHANNEL_nsskey 75
-#define BLOG_CHANNEL_addr 76
-#define BLOG_CHANNEL_PasswordListener 77
-#define BLOG_CHANNEL_NCDInterfaceMonitor 78
-#define BLOG_CHANNEL_NCDRfkillMonitor 79
-#define BLOG_CHANNEL_udpgw 80
-#define BLOG_CHANNEL_UdpGwClient 81
-#define BLOG_CHANNEL_SocksUdpGwClient 82
-#define BLOG_CHANNEL_BNetwork 83
-#define BLOG_CHANNEL_BConnection 84
-#define BLOG_CHANNEL_BSSLConnection 85
-#define BLOG_CHANNEL_BDatagram 86
-#define BLOG_CHANNEL_PeerChat 87
-#define BLOG_NUM_CHANNELS 88
+#define BLOG_CHANNEL_ncd_index 25
+#define BLOG_CHANNEL_ncd_process_manager 26
+#define BLOG_CHANNEL_ncd_net_backend_waitdevice 27
+#define BLOG_CHANNEL_ncd_net_backend_waitlink 28
+#define BLOG_CHANNEL_ncd_net_backend_badvpn 29
+#define BLOG_CHANNEL_ncd_net_backend_wpa_supplicant 30
+#define BLOG_CHANNEL_ncd_net_backend_rfkill 31
+#define BLOG_CHANNEL_ncd_net_up 32
+#define BLOG_CHANNEL_ncd_net_dns 33
+#define BLOG_CHANNEL_ncd_net_iptables 34
+#define BLOG_CHANNEL_ncd_net_ipv4_addr 35
+#define BLOG_CHANNEL_ncd_net_ipv4_route 36
+#define BLOG_CHANNEL_ncd_net_ipv4_dhcp 37
+#define BLOG_CHANNEL_ncd_net_watch_interfaces 38
+#define BLOG_CHANNEL_ncd_sys_watch_input 39
+#define BLOG_CHANNEL_ncd_sys_evdev 40
+#define BLOG_CHANNEL_ncd_sys_watch_directory 41
+#define BLOG_CHANNEL_StreamPeerIO 42
+#define BLOG_CHANNEL_DatagramPeerIO 43
+#define BLOG_CHANNEL_BReactor 44
+#define BLOG_CHANNEL_BSignal 45
+#define BLOG_CHANNEL_FragmentProtoAssembler 46
+#define BLOG_CHANNEL_BPredicate 47
+#define BLOG_CHANNEL_ServerConnection 48
+#define BLOG_CHANNEL_Listener 49
+#define BLOG_CHANNEL_DataProto 50
+#define BLOG_CHANNEL_FrameDecider 51
+#define BLOG_CHANNEL_BSocksClient 52
+#define BLOG_CHANNEL_BDHCPClientCore 53
+#define BLOG_CHANNEL_BDHCPClient 54
+#define BLOG_CHANNEL_NCDIfConfig 55
+#define BLOG_CHANNEL_BUnixSignal 56
+#define BLOG_CHANNEL_BProcess 57
+#define BLOG_CHANNEL_PRStreamSink 58
+#define BLOG_CHANNEL_PRStreamSource 59
+#define BLOG_CHANNEL_PacketProtoDecoder 60
+#define BLOG_CHANNEL_DPRelay 61
+#define BLOG_CHANNEL_BThreadWork 62
+#define BLOG_CHANNEL_DPReceive 63
+#define BLOG_CHANNEL_BInputProcess 64
+#define BLOG_CHANNEL_NCDUdevMonitorParser 65
+#define BLOG_CHANNEL_NCDUdevMonitor 66
+#define BLOG_CHANNEL_NCDUdevCache 67
+#define BLOG_CHANNEL_NCDUdevManager 68
+#define BLOG_CHANNEL_BTime 69
+#define BLOG_CHANNEL_BEncryption 70
+#define BLOG_CHANNEL_SPProtoDecoder 71
+#define BLOG_CHANNEL_LineBuffer 72
+#define BLOG_CHANNEL_BTap 73
+#define BLOG_CHANNEL_lwip 74
+#define BLOG_CHANNEL_NCDConfigParser 75
+#define BLOG_CHANNEL_nsskey 76
+#define BLOG_CHANNEL_addr 77
+#define BLOG_CHANNEL_PasswordListener 78
+#define BLOG_CHANNEL_NCDInterfaceMonitor 79
+#define BLOG_CHANNEL_NCDRfkillMonitor 80
+#define BLOG_CHANNEL_udpgw 81
+#define BLOG_CHANNEL_UdpGwClient 82
+#define BLOG_CHANNEL_SocksUdpGwClient 83
+#define BLOG_CHANNEL_BNetwork 84
+#define BLOG_CHANNEL_BConnection 85
+#define BLOG_CHANNEL_BSSLConnection 86
+#define BLOG_CHANNEL_BDatagram 87
+#define BLOG_CHANNEL_PeerChat 88
+#define BLOG_NUM_CHANNELS 89

+ 1 - 0
generated/blog_channels_list.h

@@ -23,6 +23,7 @@
 {.name = "ncd_spawn", .loglevel = 4},
 {.name = "ncd_call", .loglevel = 4},
 {.name = "ncd_ref", .loglevel = 4},
+{.name = "ncd_index", .loglevel = 4},
 {.name = "ncd_process_manager", .loglevel = 4},
 {.name = "ncd_net_backend_waitdevice", .loglevel = 4},
 {.name = "ncd_net_backend_waitlink", .loglevel = 4},

+ 1 - 0
ncd/CMakeLists.txt

@@ -57,6 +57,7 @@ add_executable(badvpn-ncd
     modules/spawn.c
     modules/call.c
     modules/ref.c
+    modules/index.c
     modules/process_manager.c
     modules/net_backend_waitdevice.c
     modules/net_backend_waitlink.c

+ 180 - 0
ncd/modules/index.c

@@ -0,0 +1,180 @@
+/**
+ * @file index.c
+ * @author Ambroz Bizjak <ambrop7@gmail.com>
+ * 
+ * @section LICENSE
+ * 
+ * This file is part of BadVPN.
+ * 
+ * BadVPN is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ * 
+ * BadVPN is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * @section DESCRIPTION
+ * 
+ * Synopsis:
+ *   index index(string value)
+ *   index index::next()
+ * 
+ * Description:
+ *   Non-negative integer with range of a size_t.
+ *   The first form creates an index from the given decimal string.
+ *   The second form cretes an index with value one more than an existing
+ *   index.
+ * 
+ * Variables:
+ *   string (empty) - the index value. Note this may be different from
+ *     than the value given to index() if it was not in normal form.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <misc/parse_number.h>
+#include <ncd/NCDModule.h>
+
+#include <generated/blog_channel_ncd_index.h>
+
+#define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
+
+struct instance {
+    NCDModuleInst *i;
+    size_t value;
+};
+
+static void func_new_templ (NCDModuleInst *i, size_t value)
+{
+    // allocate instance
+    struct instance *o = malloc(sizeof(*o));
+    if (!o) {
+        ModuleLog(i, BLOG_ERROR, "failed to allocate instance");
+        goto fail0;
+    }
+    NCDModuleInst_Backend_SetUser(i, o);
+    
+    // init arguments
+    o->i = i;
+    o->value = value;
+    
+    // signal up
+    NCDModuleInst_Backend_Up(o->i);
+    return;
+    
+fail0:
+    NCDModuleInst_Backend_SetError(i);
+    NCDModuleInst_Backend_Dead(i);
+}
+
+static void func_new_from_value (NCDModuleInst *i)
+{
+    // read arguments
+    NCDValue *arg_value;
+    if (!NCDValue_ListRead(i->args, 1, &arg_value)) {
+        ModuleLog(i, BLOG_ERROR, "wrong arity");
+        goto fail0;
+    }
+    if (NCDValue_Type(arg_value) != NCDVALUE_STRING) {
+        ModuleLog(i, BLOG_ERROR, "wrong type");
+        goto fail0;
+    }
+    
+    // parse value
+    uintmax_t value;
+    if (!parse_unsigned_integer(NCDValue_StringValue(arg_value), &value)) {
+        ModuleLog(i, BLOG_ERROR, "wrong value");
+        goto fail0;
+    }
+    
+    // check overflow
+    if (value > SIZE_MAX) {
+        ModuleLog(i, BLOG_ERROR, "value too large");
+        goto fail0;
+    }
+    
+    func_new_templ(i, value);
+    return;
+    
+fail0:
+    NCDModuleInst_Backend_SetError(i);
+    NCDModuleInst_Backend_Dead(i);
+}
+
+static void func_new_from_index (NCDModuleInst *i)
+{
+    struct instance *index = i->method_object->inst_user;
+    
+    // check overflow
+    if (index->value == SIZE_MAX) {
+        ModuleLog(i, BLOG_ERROR, "overflow");
+        goto fail0;
+    }
+    
+    func_new_templ(i, index->value + 1);
+    return;
+    
+fail0:
+    NCDModuleInst_Backend_SetError(i);
+    NCDModuleInst_Backend_Dead(i);
+}
+
+static void func_die (void *vo)
+{
+    struct instance *o = vo;
+    NCDModuleInst *i = o->i;
+    
+    // free instance
+    free(o);
+    
+    NCDModuleInst_Backend_Dead(i);
+}
+
+static int func_getvar (void *vo, const char *name, NCDValue *out)
+{
+    struct instance *o = vo;
+    
+    if (!strcmp(name, "")) {
+        char str[64];
+        snprintf(str, sizeof(str), "%zu", o->value);
+        
+        if (!NCDValue_InitString(out, str)) {
+            ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitString failed");
+            return 0;
+        }
+        
+        return 1;
+    }
+    
+    return 0;
+}
+
+static const struct NCDModule modules[] = {
+    {
+        .type = "index",
+        .func_new = func_new_from_value,
+        .func_die = func_die,
+        .func_getvar = func_getvar
+    }, {
+        .type = "index::next",
+        .base_type = "index",
+        .func_new = func_new_from_index,
+        .func_die = func_die,
+        .func_getvar = func_getvar
+    }, {
+        .type = NULL
+    }
+};
+
+const struct NCDModuleGroup ncdmodule_index = {
+    .modules = modules
+};

+ 2 - 0
ncd/modules/modules.h

@@ -47,6 +47,7 @@ extern const struct NCDModuleGroup ncdmodule_runonce;
 extern const struct NCDModuleGroup ncdmodule_spawn;
 extern const struct NCDModuleGroup ncdmodule_call;
 extern const struct NCDModuleGroup ncdmodule_ref;
+extern const struct NCDModuleGroup ncdmodule_index;
 extern const struct NCDModuleGroup ncdmodule_process_manager;
 extern const struct NCDModuleGroup ncdmodule_net_backend_waitdevice;
 extern const struct NCDModuleGroup ncdmodule_net_backend_waitlink;
@@ -91,6 +92,7 @@ static const struct NCDModuleGroup *ncd_modules[] = {
     &ncdmodule_spawn,
     &ncdmodule_call,
     &ncdmodule_ref,
+    &ncdmodule_index,
     &ncdmodule_process_manager,
     &ncdmodule_net_backend_waitdevice,
     &ncdmodule_net_backend_waitlink,