Category: Blog

  • AceZeroProxy

    AceZeroProxy – ZeroNet’s Meta Proxy

    ZeroNet is a way to host websites in a decentralised manner, to view these sites you need to have ZeroNet installed on your PC or use a ZeroNet proxy. Many ZeroNet proxies may only run for a week or a month this is a big problem that AceZeroProxy addresses.

    This ZeroNet meta proxy is simple to use, try it out https://zero.acelewis.com and read below how it works.

    AceZeroProxy

    The Problem

    If you are using ZeroNet and want to share a link with a someone then they must have ZeroNet installed unless you use a ZeroNet Proxy. The problem with ZeroNet proxies is sometimes they go down… actually they quite often go down. This is a big headache if you want to post links to a ZeroNet proxy on a blog post or on social media because you would have to go through and update all the link when the ZeroNet proxy goes down.

    The second problem is that it may be difficult to remember the link to a working proxy, with this meta proxy you only need to remember one somewhat simple address: https://zero.acelewis.com

    How this works

    This is done 100% in client side Javascript, this means that I will not know the sites that you have visited whilst using the ZeroNet Meta Proxy (the proxies will) but more importantly it can be hosted for free on Github Pages.

    All this does is takes a ZeroNet link and redirects that link to a random ZeroNet proxy (currently I am only using ZeroNet Proxies that run on port 80/HTTP or 443/HTTPS as they bypass simple port blocking).

    How to convert a ZeroNet link into a ZeroNet Proxy link

    The easiest way is to just use the website however if you want to do it programmatically you can do the following:

    Take the ZeroNet URL for example;

    http://127.0.0.1:43110/1LennyjL5VUTvwiLtBUjMrZ85gCbVe1dj1/

    and then replace the http://127.0.0.1:43110/ with https://zero.acelewis.com#. Which gives;

    https://zero.acelewis.com#1LennyjL5VUTvwiLtBUjMrZ85gCbVe1dj1/

    Warning

    I do not recommend using a ZeroNet proxy to sign in to ZeroNet as it is technically possible for the proxy to steal your private key. Only use these ZeroNet proxies to browse ZeroNet sites. I will not know the sites you visit but the proxies obviously will.

    Visit original content creator repository https://github.com/AceLewis/AceZeroProxy
  • fastnat

    FAST NAT 全协议内网穿透

    FAST NAT是基于WeNAT的扩展版,支持HTTP、TCP、UDP、WebSocket等协议。 简单的说,就是可以给你的内网电脑分配一个公网IP和端口 例如:

    123.1.1.1:8888 -> 192.168.1.123:3306

    当外网服务器的8888端口收到数据包后,会转发给内网的3306端口,从而实现穿透。服务器做了个中转,和传统的P2P穿透不同。

    应用场景

    • 本地发布网站
    • 远程桌面
    • SSH 本地服务器
    • 访问本地mysql
    • 访问本地redis
    • 访问本地mongodb

    联系方式

    开发语言

    • 服务端、web网站:node.js
    • 客户端:nw.js + node.js

    TCP协议和流程

    流程图

    内外网代理流程

    • 内网和外网建立协议通道,用于主动连接通知
    • 外网客户端连接服务器,并且分配一个id,保存起来
    • 通知内网客户端,并且告诉id,由内网主动发起连接
    • 内网连接代理目标
    • 内网连接服务器,并且传入id,和外网进行绑定
    • 映射内外网的socket

    断线和报错处理

    • 任何一方报错,终端所有端口监听以及所有的连接
    • 由客户端再次发起连接请求,并且分配一个随机端口或者继续使用上次的外网端口

    TCP接口

    • 协议类型

      协议为JSON字符串

    • 安全性

      在第一次连接服务器的时候,需要带上用户的token,服务器进行校验合法后开放2个端口提供给后续使用。 在后续的流程中,不做任何校验。虽然有安全风险,但是常见的TCP应用:Mysql、Mongodb、Redis等,都有用户机制可以保护。

    • 协议类型

      暂定三种协议

      类型
      TCP
      UDP
      HTTP
    • 和通信服务器连接

      • 基本信息响应

        直接连接通信服务器端口8888,不用发送任何数据,成功后响应如下数据

        字段 类型 说明
        id string(8) 本次会话的id
        outId string(8) 外网socket 会话id
        intPort int(5) 内网连接的端口,5位数的端口,30000-65535
        outPort int(5) 外网连接的端口
        command string 操作命令
        protocol string 协议类型
        • 举个栗子🌰
         {
           id: 'CucfFpk7',
           intPort: 61289,
           outPort: 59918,
           command: 'start_proxy',
           outId: 'GpNYO5KW' 
         }
      • 主动连接服务器

        收到基本信息响应后,拿到内网的端口建立一个TCP连接,并且带上outId, 第一个数据包为协议包,后续的数据就是正常的转发

        字段 类型 说明
        outId string(8) 外网socket 会话id
        • 举个栗子🌰
         {
           outId: 'GpNYO5KW' 
         }
    Visit original content creator repository https://github.com/newpanjing/fastnat
  • vue3-router4-typescript

    开始

    npm install
    npm run serve
    npm run build
    

    vue3.x 结合 typescript 初体验

    一、Vue3.0 的设计目标

    • 更小\更快 – Vue 3.0 大小大概减少一半,只有 10kB
    • 加强 TypeScript 支持
    • 加强 API 设计一致性 – 易读
    • 提高自身可维护性
    • 开放更多底层功能

    vue3.x 采用 Function-based API 形式组织代码,使其更容易压缩代码且压缩效率也更高,由于 修改了组件的声明方式,以函数组合的方式完成逻辑,天然与 typescript 结合。(vue2.x 中的组件是通过声明的方式传入一系列 options 的,所以在 2.x 下使用 typeScript 需要装饰器的方式vue-class-component才行)

      // vue2.x 要想使用ts 需要这样处理,详见官方文档 https://cn.vuejs.org/v2/guide/typescript.html
    <script lang="ts">
        import Vue from 'vue'
        import Component from 'vue-class-component'
        @Component
        export default class App extends Vue {}
    </script>
    

    二、typescript 有什么优点

    1、增加代码的可读性与可维护性

    • 大部分函数看类型定义就知道是干嘛的
    • 静态类型检查,减少运行时错误

    2、社区活跃,大牛都在用

    • 在 vue3 热潮下,之后 typescript 要成为主流,快学

    三、搭建 vue3.x + typescript + vue-router 环境

    1、全局安装 vue-cli

    npm install -g @vue/cli
    

    2、初始化 vue 项目

    vue create vue-next-project
    

    这里在输入命令后,需要选择Manually select features, 至少要把 babel typescript router 选上,(vuex 看自身情况是否需要)。如下图:

    不清楚 vue-cli 的可参考文章

    3、升级为 vue3.x 项目

    https://github.com/vuejs/vue-cli-plugin-vue-next

    cd vue-next-project
    vue add vue-next
    

    这个命令会自动帮你把 vue2.x 升级到 vue3.x ,包括项目中对应的依赖进行升级与模板代码替换,像:vue-router vuex

    完成以上三步主体环境算搭建完成,看刚才创建的目录里多了个 tsconfig.json 配置文件,可以根据自身与项目需要,进行配置。

    接下来需要简单处理一下,使其支持 typescript 形式。(模板 cli 还没完善 typescript 的模板代码)

    • shims-vue.d.ts文件中的内容修改一下,这步操作应该会少了一些报错。

    // declare module "*.vue" {
    //   import Vue from 'vue';
    //   export default Vue;
    // }
    declare module "*.vue" {
        import {defineComponent} from 'vue'
        const Component: ReturnType<typeof defineComponent>;
        export default Component
    }
    
    • 组件里使用需声明 script lang="ts" ,然后用defineComponent进行包裹,即可。

    <script lang="ts">
    import {
      defineComponent,
      ref,
      onMounted,
      onUpdated,
      onUnmounted,
    } from "vue";
    
    export default defineComponent({
      name: "hello world",
      props: {},
      setup(props: any) {
        const count = ref(0);
        const increase = (): void => {
          count.value++;
        };
        function test(x: number): string {
          return props.toString();
        }
        test(1);
        // test('number');
        // 生命周期
        onMounted(() => {
          console.log("mounted vue3 typescript");
        });
        onUpdated(() => {
          console.log("updated vue3 typescript");
        });
        onUnmounted(() => {
          console.log("onUnmounted vue3 typescript");
        });
        // 暴露给模板
        return {
          count,
          increase
        };
      },
    });
    
    </script>
    

    生命周期对应

    与 2.x 版本生命周期相对应的组合式 API

    beforeCreate → 使用 setup()
    created → 使用 setup()
    beforeMount → onBeforeMount
    mounted → onMounted
    beforeUpdate → onBeforeUpdate
    updated → onUpdated
    beforeDestroy → onBeforeUnmount
    destroyed → onUnmounted
    errorCaptured → onErrorCaptured

    四、附上学习 vue-next 与 typescript 的官方秘籍

    五、不想搭建你也可以直接拉去 github demo

    vue3+typescript 环境

    Visit original content creator repository
    https://github.com/vue3/vue3-router4-typescript

  • geome

    geome

    Tests Documentation

    The repo provides a set of tools for creating PyTorch Geometric (PyG) data objects from AnnData objects, which are commonly used for storing and manipulating single-cell genomics data. In addition, the repo includes functionality for creating PyTorch Lightning (PyTorch-Lightning) DataModule objects from the PyG data objects, which can be used to create graph neural network (GNN) data pipelines. The PyG data objects represent graphs, where the nodes represent cells and the edges represent relationships between the cells, and can be used to perform GNN tasks such as node classification, graph classification, and link prediction. The repo is written in Python and utilizes the PyTorch, PyTorch Geometric, and PyTorch-Lightning libraries.

    Getting started

    Please refer to the documentation. In particular, the

    Installation

    You need to have Python 3.9 or newer installed on your system. If you don’t have Python installed, we recommend installing Mambaforge.

    There are several alternative options to install geome:

    1. Install the latest development version:

    Without GPU support:

    mamba create -n geome  python=3.10
    mamba activate geome
    pip install torch==2.1.0
    pip install torch-scatter torch-sparse torch-cluster
    pip install git+https://github.com/theislab/geome.git@main

    With GPU:

    mamba create -n geome  python=3.10
    mamba activate geome
    mamba install pytorch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 pytorch-cuda=12.1 -c pytorch -c nvidia
    pip install torch-scatter torch-sparse torch-cluster -f https://data.pyg.org/whl/torch-2.1.0+cu121.html
    pip install git+https://github.com/theislab/geome.git@main

    Release notes

    See the changelog.

    Contact

    For questions and help requests, you can reach out in the scverse discourse. If you found a bug, please use the issue tracker.

    Credits

    Some of the data for DatasetHartmann is distributed in this package. It was originally retrieved from: https://zenodo.org/record/3951613#.Y9flQS-B1qv

    This project was generated from @cjolowicz‘s Hypermodern Python Cookiecutter template.

    Citation

    t.b.a

    Visit original content creator repository https://github.com/theislab/geome
  • kreislauf

    v0.3.3

    Beat sequencing rund um den Kreis inspired very heavily by Pocket Operators and the work of Ethan Hein.

    Kreislauf UI

    Requirements

    Norns or Fates.

    Install/Update

    Kreislauf can be installed via Maiden’s project manager.

    Overview

    Patterns

    Each pattern consists of 4 concentric sequencer rings:

    • channel 1 – kick (outermost),
    • channel 2 – snare
    • channel 3 – closed hi-hat
    • channel 4 – open hi-hat (innermost).

    Beat/Notes

    When a beat is added to a ring, it fires off a Midi* note when active (60 by default) to the corresponding channel. While, this script is design with intent to create drum patterns; each beat can have its note value adjusted allowing for melody/harmony constructs as well. Go wild…

    *I’ve blindly implemented crow, but I have no idea if it works. Any crow users please let me know what bugs you find and I’ll adjust.

    Chaining

    I also like the way Pocket Operators accommodate for chaining of beats so I incorporated the ability for multiple patterns with individual loop counts to be strung together. For single pattern beats be sure to keep loop count as Inf. if you want endless looping. If multiple patterns are create, the entire sequence will always loop.

    Saving and Loading Sequences

    Patterns can be saved and later recalled (along with accompanying PSET). A number of demo patterns of some staple beats is installed within ~/dust/data/kreislauf/patterns. LOAD and SAVE patterns from the params menu.

    Controls and Params

    Controller Page Values Description
    E1 Global 1 – 3 Change page
    K2 Global Play/stop Plays or stops sequence

    Page 1

    Kreislauf page 1 screenshot

    Controller Page Values Description
    E2 P1 1 – x Cycle through patterns
    E3 P1 20 – 300 Set BPM
    E3+K1 or E4 P1 1 – 16 Step divider
    K3 P1 Add pattern
    K3+K1 P1 Remove pattern

    Page 2

    Kreislauf page 2 screenshot

    Controller Page Values Description
    E2 P2 1 – 4 Cycle through rings
    E3 P2 0 – 16 Set channel for active ring
    E3+K1 or E4 P2 Inf, 1 – 32 Loop count for active pattern
    K3 P2 Load pattern

    Page 3

    Kreislauf page 3 screenshot

    Controller Page Values Description
    E2 P3 1 – 16 Cycle through steps
    E3 P3 0 – 127 Set note value for active step
    E3+K1 or E4 P3 0 – 127 Set velocity value for active step
    K3 P3 Add beat/note to active step

    Development

    SSH into your Norns/Fates, then enter the following commands in terminal.

    $ cd ~/dust/code
    $ git clone https://github.com/frederickk/kreislauf.git

    Changelog

    • v0.3.x
      • Fixed/tidied UI
      • Fixed Midi note off
    • v0.2.x
      • Added sequencing of multiple patterns
    • v0.1.x Initial release
    Visit original content creator repository https://github.com/frederickk/kreislauf
  • app_clima_angular

    Consumir API de clima con Angular

    Proyecto con Angular para consumir API de clima dependiendo de la ubicación del usuario.
    Clima con Angular - App que consume API

    Clima con Angular – App que consume API

    Tutorial

    Aquí: https://parzibyte.me/blog/2020/06/27/angular-aplicacion-clima-api/

    Créditos

                Programado por Luis Cabrera Benito 
                ____          _____               _ _           _       
               |  _ \        |  __ \             (_) |         | |      
               | |_) |_   _  | |__) |_ _ _ __ _____| |__  _   _| |_ ___ 
               |  _ <| | | | |  ___/ _` | '__|_  / | '_ \| | | | __/ _ \
               | |_) | |_| | | |  | (_| | |   / /| | |_) | |_| | ||  __/
               |____/ \__, | |_|   \__,_|_|  /___|_|_.__/ \__, |\__\___|
                       __/ |                               __/ |        
                      |___/                               |___/         
                  
                  
                  Blog:       https://parzibyte.me/blog
                  Ayuda:      https://parzibyte.me/blog/contrataciones-ayuda/
                  Contacto:   https://parzibyte.me/blog/contacto/
    

    Imágenes

    cloudy: Icons made by Freepik from www.flaticon.com
    clear: Icons made by Good Ware from www.flaticon.com
    ishower,oshower: Icons made by Freepik from www.flaticon.com
    mcloudy: Icons made by srip from www.flaticon.com
    rain: Icons made by DinosoftLabs from www.flaticon.com
    snow: Icons made by Freepik from www.flaticon.com
    tsrain: Icons made by Freepik from www.flaticon.com
    ts: Icons made by Freepik from www.flaticon.com

    Clima

    This project was generated with Angular CLI version 9.1.6.

    Development server

    Run ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

    Code scaffolding

    Run ng generate component component-name to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module.

    Build

    Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

    Running unit tests

    Run ng test to execute the unit tests via Karma.

    Running end-to-end tests

    Run ng e2e to execute the end-to-end tests via Protractor.

    Further help

    To get more help on the Angular CLI use ng help or go check out the Angular CLI README.

    Visit original content creator repository
    https://github.com/parzibyte/app_clima_angular

  • nfXML

    nfXml

    Project developer: Marco Plaza GitHub/nfoxdev

    Basic Usage

    oVfp = nfXMLRead(cXMLstring | fileName [, cArraysList, cXpath,@cObjectMap ])
        && creates a vfp object from xml.
    
    cXml = nfXmlCreate( oVfp )
        && creates XML from a VFP empty-based object
    
    cXpaths = nfxPaths( cXml )
        && Parse XML w/o schema and show all
        && object paths - please check notes
        && below for important notes about
        && arrays in XML.
    

    IMPORTANT NOTES

    oVfp = nfXMLRead( cXMLstring , cArraysList, @cXpath)

    pass xml string, returns a vfp object. ( empty based, requires vfp9 )

    ARRAYS ( cArraysList )

    Unlike Json, XML does not identify object arrays on the XML document itself, it does it on the XML Schema.

    To gain simplicity and ease of use, nfXmlRead uses no XML Schema.

    nfXmlRead identifies arrays by counting the child nodes with identical names; so any node with more than one child node with identical name is identified as array, as no object can contain more than 2 properties with the same name.

    If you’re sure your XML contains no arrays and any contained array will have at least more than one member, you don’t need to worry.

    For any other situation, you can pass a comma separated list of all the xpaths that must be treated as arrays: a excel workbook contains the following arrays:

    “/Workbook/Styles/Style[],/Workbook/Worksheet[]/Table/Row[]/Cell[]”

    NAME PROPERTIES WITH SPECIAL CHARACTERS OR SPACES

    XML allows node names with spaces and special characters; nfXml safely converts them to valid vfp property names by replacing them on the following way:

    • ‘:’ -> ‘_’
    • ‘(‘ -> ‘_l_’
    • ‘)’ -> ‘_r_’
    • ‘-‘ -> ‘_h_’
    • ‘.’ -> ‘_d_’

    RESERVERD WORDS OR NON CHARACTER PROPERTY NAMES
    will be prepended with ‘_’
    for example, you can’t have an array called “row” since “row()” is a vfp function, then it gets renamed to _row also names starting with numbers and so on.

    NODE ATTRIBUTES
    node attributes are listed in a property called _attr_

    NAMESPACES
    Namespaces are prepended to node names, separated by “_”
    this way ss:Styles gets the vfp property name ss_styles;

    object properties with “_” should be escaped with additional “_”

    this way:

    • oxml.customer_id gets serialized as: <customer:id>

    • oxml.customer__id gets serialized as: <customer_id>

    • oxml.customer___id gets serialized as: <customer_:id>

    OPTIONAL PARAMETERS
    xpathExp: you can pass any xPath Expression for nfXMLRead to return only
    the desired node without parsing the entire document; useful for big xml files.

    ERROR MANAGEMENT
    program will throw error if you supply invalid xml; manage accordingly.

    Visit original content creator repository
    https://github.com/VFPX/nfXML

  • FusionMatting

    Visit original content creator repository
    https://github.com/gost-sniper/FusionMatting

  • taskill

    Taskill

    WIP

    The goal of this project is to create an open source independent task manager on a javascript stack that can be use locally or in web. Idea of creation inspired by redmine

    Use

    Docker must be installed

    Production

    Clone the repo, setup the env variables and run

    (cd docker/prod && docker-compose up --build -d)

    Go to the http://localhost on local machine or your domain address on server

    Env variables

    # Client
    VUE_APP_SERVER_API= # service URI API, example: http://yourdomain.com/api or http://localhost to local use
    # Server
    API_PORT= # service server port, example: 3000, if other, you must be setup proxy nginx
    DEBUG= # express debug mode
    CLIENT_URI= # service client URI for CORS, example: http://yourdomain.com, or http://localhost to local use
    MONGO_URI= # service mongo URI, exmaple mongodb://mongo:27017/taskill, (mongo - service DNS)
    SECRET_KEY= # random string as salt to generate token
    MAIL_HOST= # SMTP server email client
    MAIL_PORT= # email port
    MAIL_USER= # email login
    MAIL_PASS= # email password

    Development

    Clone the repo, setup the env variables and run

    (cd docker/dev && docker-compose up --build -d)

    Go to the http://localhost:VUE_APP_PORT on local machine

    Env example

    docker/dev/.env

    # Client
    VUE_APP_PORT= # client port, example 4000
    VUE_APP_HOST= # must be 0.0.0.0
    VUE_APP_SERVER_API= # service URI API, for dev example: http://localhost:3000/api, port must be equal API_PORT
    # Server
    API_PORT= # service server port, example: 3000
    DEBUG= # express debug mode
    CLIENT_URI= # service client URI for CORS, for dev example: http://localhost:4000, port must be equal VUE_APP_PORT
    MONGO_URI= # service mongo URI, example mongodb://mongo:27017/taskill, (mongo - service DNS)
    SECRET_KEY= # random string as salt to generate token
    MAIL_HOST= # SMTP server email client
    MAIL_PORT= # email port
    MAIL_USER= # email login
    MAIL_PASS= # email password

    Roadmap

    Client

    • Layout
    • Sing in / Sing up / Reset
    • Projects
    • Project
    • Project settings
    • Project add new
    • Tasks
    • Task
    • Task add new view
    • User profile view

    Server

    • Sing in / Sing up / Reset
    • Authorization by JWT
    • Project CRUD
    • Project add to favorite
    • Task CRUD
    • Task assignee
    • Members & transfer
    • Roles
    • Comments
    Visit original content creator repository https://github.com/taskill/taskill
  • evec

    Easy Vector (EV)

    Easy Vector is a small and simple header only C vector type.
    It’s designed for situations like options parsing where building up an unknown amount of state is required.

    It has a number of features:

    • Easy: EV is designed to make the code as easy to use a possible.
      Helps you to focus on solving your problem, not on learning yet another thing.
    • Simple: The entire code base is only a few hundered lines, contained in a single header file.
    • Cheap: EV has a pay-for-what-you-use model.
      Most “features” are optional, included only with a #define.
      This means that there’s no cost for functions that you don’t need.

    EV is licensed under a BSD 3-Clause license to make it simple and easy to integrate into any open or closed source project.
    See Licensing section for more details.

    EV should be compatible with any sensible compiler on any reasonable OS.
    It has been tested on Linux (x86) (Ubuntu 20.04) with GCC (9.3) compiler and on
    MacOS X (x86) with Clang compiler (11.0.3)

    For release notes/change log please see the Release Notes section.

    Getting Started

    Getting started with Easy Vector is … easy.
    You can use EV in just 4 simple steps

    Step 1 – Copy the header file

    Copy the evec.h header file from here and save it into your project. Include it in your code like this:

    #include "evec.h"

    EV supports a number of build time options.
    See Build Time Options for more details.

    Step 2 – Push values into vector

    EV tries to automatically allocate a new vector structure and sensibly push values into it.
    For example:

    int* a = NULL;
    evpsh(a, 1);

    There are lots of options for ways allocate and push values into EV.
    For more details see Core Functions section.

    Step 3 – Access vector values

    Once you have some values in the vector, you will eventually want to access them:

    eveach(a, ai){
        printf("%i\n", *ai);
    }

    One quick note: EV does not guarantee that values are stable (ie stored in the same location in memory).
    If you need to access values, consistently across pushes, please use the evidx() function.
    More details can be found in the Core Functions section.

    Step 4 – Free resources

    Eventually, you’ll want to clean up the mess afterwards.

    a = evfree(a);

    Done. It’s that easy!

    Core Functions

    There are 3 core functions required to use EV.

    1. Add values into the vector using evpsh() functions.
      This will automatically allocate a new vector structure if none exists.
    2. Iterate over the vector using eveach().
    3. Free the structure when done using evfree().

    For example:

    #include <stdio.h>
    #include "evec.h"
    
    
    int main(int argc, char** argv)
    {
        int* a = NULL;
        evpsh(a, 2);
        evpsh(a, 4);
        evpsh(a, 6);
    
        eveach(a,ai){
            printf("%i\n", *ai);
        }  
    
        a = evfree(a);
        return 0;
    }

    Extended Core Functions

    Beyond the basic usage, EV provides a few extra core functions for accessing the vector.

    Many operations on a vector care about only the first or the last element.
    For these operations, the evhead() and evtail() functions are provided.

    evhead() returns a pointer to the first element in the vector, but, it also resets the internal iterator state.
    After a call to evhead(), you can also call evnext() to get the next item.
    This can be used to manually implement the eveach() iteration loop above. Eg:

    #include <stdio.h>
    #include "evec.h"
    
    
    int main(int argc, char** argv)
    {
    int* a = NULL;
    evpsh(a, 2);
    evpsh(a, 4);
    evpsh(a, 6);
    
        for(int* ai = evhead(a); ai != NULL; ai = evnext(a))
            printf("%i\n", *ai);
        }  
    
        a = evfree(a);
        return 0;
    }

    To find out how many items are in the vector, use evcnt().

    If you are using a simple datatype like int or char, then you can simply access items in the vector using array/pointer notation, e.g a[i].
    Do keep in mind that this kind of access is only valid until the next EV operation which causes a memory reallocation, (eg evpsh() may do this).
    If you want to have consistent access to items, or for more complicated data types (e.g structs) you can use evidx() to obtain a pointer to the object at the given index.

    The following example has the same functionality as the previous example, but uses these extended functions.
    It has the neat property that you also have access to the iterator index value.

    #include <stdio.h>
    #include "evec.h"
    
    
    int main(int argc, char** argv)
    {
        int* a = NULL;
        evpsh(a, 2);
        evpsh(a, 4);
        evpsh(a, 6);
    
        for(int i = 0; i < evcnt(a); i++){
            printf("%i: %i\n", i, *(int*)evidx(a, i));
        }  
    
        a = evfree(a);
        return 0;
    }

    Advanced Usage

    Beyond these basic functions, EV provides more advanced options.
    These options require compile time #defines to include them.
    The simplest way is to use #define EV_FALL.
    More fine grained options are docuemented under in the build macros section.

    It’s not always possible to (or desired) for each vector slot to be sized based on the type information provided by evpsh() or evnit().
    In these situations, the evinisz() may be used to allocate specific slot sizes.
    To iterate over these custom sizes, use evidx() which is aware of the slot sizes.
    For example:

    #include <stdio.h>
    
    #define EV_FALL
    #include "evec.h"
    
    
    int main(int argc, char** argv)
    {
        void* a = evinisz(128);
        evpsh(a, "Test");
        evpsh(a, "Best");
        evpsh(a, "Rest");
    
        for(int i = 0; i < evcnt(a); i++){
            char* s = (char*)evidx(a,i);
            printf("%i: %s\n", i, s);
        }  
    
        a = evfree(a);
        return 0;   
    }

    For more advanced uses of EV, you may want to remove items from the vector, you can do this with evpop() which ejects the last item from the vector.
    Alternatively, evedel() can be used to remove an item at a given index.
    Finally, evsort() can be used to sort items.

    #include <stdio.h>
    
    #define EV_FALL
    #include "evec.h"
    
    int compare(const void* lhs, const void* rhs)
    {
        int* a = (int*)lhs;
        int* b = (int*)rhs;
    
        return *b - *a;
    }
    
    int main(int argc, char** argv)
    {
        int* a = NULL;
        evpsh(a, 2);
        evpsh(a, 4);
        evpsh(a, 6);
    
        evpsh(a, 2);
        evpsh(a, 4);
        evpsh(a, 6);
    
        evsort(a,compare);
    
        //Remove duplicates
        for(int i = 1; i < evcnt(a); i++){
            if(a[i] == a[i-1]){
                evdel(a,i);
                i--;
            }       
        }  
    
        for(int i = 0; i < evcnt(a); i++){
            printf("%i: %i\n", i, a[i]);
        }        
    
        a = evfree(a);
        return 0;
    }

    Build Time Options

    Hard Exit
    By default EV will “fail hard and early”.
    This means that exit() will be called on all errors.
    This default behavior can be overridden by defining EV_HARD_EXIT as 0 .

    Note: This must be done before the “evec.h” header is included. e.g.

    #define EV_HARD_EXIT 0
    #include "evec.h"

    Initial Slot Count
    By default EV will allocate 8 slots in the vector.
    This can be overridden by defining the EV_INIT_COUNT value.

    Note: This must be done before the “evec.h” header is included. e.g.

    #define EV_INIT_COUNT 64
    #include "evec.h"

    Growth Factor
    By default EV grow the vector by a factor of 2 each time it runs out of slots.
    For example, if there are 64 slots, EV will grow the vector to 128.
    EV can be made to grow faster by setting the EV_GROWTH_FACTOR value.

    Note: This must be done before the “evec.h” header is included. e.g.

    #define EV_GROWTH_FACTOR 3
    #include "evec.h"

    Pedantic Error Checking
    By default EV will apply reasonably pedantic error checking.
    For example, checking in most functions that the vector supplied is not null.
    You may want to avoid these checks if you trust your code.
    EV can be made to avoid pedantic by setting EV_PEDANTIC to 0.

    Note: This must be done before the “evec.h” header is included. e.g.

    #define EV_PEDANTIC 0
    #include "evec.h"

    Multiple Compilation Units (.c files)
    You may want to use EV in multiple C files across your project.
    If you do this, you may get an error something like:

    duplicate symbol '_evpush' in:
        /var/folders/sy/v5c7yz1j1mn0jhd1bcc6b1nr0000gn/T/test-6a1637.o
        /var/folders/sy/v5c7yz1j1mn0jhd1bcc6b1nr0000gn/T/test2-8b2b8d.o
    

    This is because C function definitions are global, so the compiler is seeing the EV functions defined more than once. This can easily be resolved by telling EV only to include the function declarations (but not definitions).
    You can do this with the following

    //This is test1.c
    #include "evec.h"

    //This is test2.c
    #define EV_HONLY
    #include "evec.h"

    //This is test3.c
    #define EV_HONLY
    #include "evec.h"

    Function Availability

    The following functions are included in all builds:

    • Initialisation functions – evinit(),evinisz(),evini()
    • Push functions – evpsh(),evpush()
    • Iteration and access functions – eveach(), evcnt(), evidx(), evhead(), evnext(), evtail()
    • Memory free – evfree()

    Beyond those basic functions, other advanced functions require specific inclusion in the build by defining the following:

    • EV_FPOP – Pop function to remove an item from the tail
    • EV_FEDL – Delete function to remove an item from anywhere
    • EV_FMEMSZ – Memory sizing functions including evvsz(), evvmem(), evomem(), evtmem()
    • EV_FSORT – Sort function to sort the vector contents
    • EV_FCOPY – Funciton to copy one EV vector and make a new one
    • EV_FALL – All above functions are included

    Detailed Documentation

    Initialisation

    These functions allocate a new vector and initialise it.
    Typically it is not necessary to call them directly because the various push functions will do this for you.
    But it may be that you know ahead of time how many slots you need, or that you need to be more specific about object sizes.
    In these cases the init functions will be useful.

    void* evinit(type)
    Easy allocate a new vector, based on type information.

    type A fully specified C type.
    return A pointer to the memory region, or NULL.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    void* evinisz(size_t sz)
    Easy allocate a new vector with slot sizes as given.

    slt_size The size of each slot in the vector typically the size of the type that is being stored.
    return A pointer to the memory region, or NULL.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    void* evini(size_t slt_size, size_t count)
    Allocate a new vector and initialise it.

    type The size of each slot in the vector typically the size of the type that is being stored.
    count The number of initial elements (of size slt_size) to be allocated. This should be set to the lower bound of the expected number of items (which could be zero).
    return A pointer to the memory region, or NULL.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    Push

    Functions to add a new data onto the back of the vector.

    evpsh(vec, obj)

    Easy push a new value onto the tail of a vector.
    If the vector is NULL, memory will be automatically allocated for INIT_COUNT elements, based on the object size as returned by sizeof(obj).
    If the memory backing the vector is too small, memory will be reallocated to grow the vector by the the GROWTH_FACTOR. e.g. 16B with a GROWTH_FACTOR=2 will grow to 32B.

    The reason for this wrapper macro is to make it easy to push literal values.

    vec Pointer to type of object that is (or will become) the vector, eg. int* for a vector of ints.
    obj The value to push into the vector.
    return A pointer to the memory region, or NULL.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();
    quirks This macro works fine for all literals expect string literals, for which you probably want to store the char* pointer, but this doesn’t really exist.
    For these types, you’ll need to use the explicit evpush function.


    void* evpush(void* vec, void* obj, size_t obj_size)
    Push a new value onto the vector tail.
    The if the vector is NULL, memory will be automatically allocated for INIT_COUNT elements, based on the object size supplied.

    If the memory backing the vector is too small, memory will be reallocated to grow the vector by the the GROWTH_FACTOR. e.g. 16B with a GROWTH_FACTOR=2 will grow to 32B.

    vec Pointer to type of object that is (or will become) the vector, eg. int* for a vector of ints.
    obj Pointer to the value to push into the vector.
    obj_size The size of the value to be pushed into the vector.
    return A pointer to the memory region, or NULL.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    Access and Iteration

    These functions help to navigate around the vector once created.

    eveach(var, vector){…}
    Macro to help iterate over each element of the vector, putting a pointer to the element in var.
    This macro is equivalent to

     for(typeof(vec) var = evhead(vec); var; var = evnext(vec))

    vec Pointer to the vector
    var Variable name for the iterator
    return This macro has no return value, it is desigted to help iterate over the vector.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    size_t evcnt(void* vec)
    Get the number of items in the vector.
    If the vector is NULL, or empty, return 0.

    vec Pointer to the vector
    return The number of objects in the vector.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    void* evidx(void* vec, size_t idx)
    Return a the pointer to the slot at a given index.

    Note this pointer is only valid until the next vector operation.
    A vector operation (such as a push()) may cause a memory reallocation which can make this pointer undefined.

    vec Pointer to the vector.
    idx The index value. Cannot be <0 or greater than the object count.
    return Pointer to the value at the given index
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    void* evhead(void* vec, size_t idx)
    Return a the pointer to the first slot in the vector.

    Note this pointer is only valid until the next vector operation.
    A vector operation (such as a push()) may cause a memory reallocation which can make this pointer undefined.

    vec Pointer to the vector.
    return Pointer to the value at the given index
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    void* evnext(void* vec, size_t idx)
    Return a the pointer next value after the head (if evhead() was last called ), or next value after the last call to evnext().
    It is invalid to call evnext() without first calling evhead().
    When there are no more elements in the vector, evnext() returns NULL;

    Note this pointer is only valid until the next vector operation.
    A vector operation (such as a push()) may cause a memory reallocation which can make this pointer undefined.

    vec Pointer to the vector.
    return Pointer to the next value in the vector, or NULL if there are none.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    void* evtail(void* vec, size_t idx)
    Return a the pointer to the last occupied slot in the vector.

    Note this pointer is only valid until the next vector operation.
    A vector operation (such as a push()) may cause a memory reallocation which can make this pointer undefined.

    vec Pointer to the vector.
    return Pointer to the last occupied slot in the vector
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    Free

    EV allocates memory for the underlying array, as well as accounting.
    At some point this memory should be freed.

    void* evfree(void* vec)
    Free the memory used to hold the vector and its accounting.

    vec Pointer to the vector
    obj The value to push into the vector.
    return NULL. Use `vec = evfree(vec)` to ensure there are no dangling pointers.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    Pop and Delete

    Functions to remove items from the vector.

    void evpop(void* vec)
    Remove the last value from the vector tail.

    Note: To use this function EV_FPOP or EV_FALL must be defined.

    vec Pointer to the vector
    return None.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    void* evdel(void* vec, size_t idx)
    Remove a value from the vector at the given index.

    Note: To use this function EV_FDEL or EV_FALL must be defined.

    vec Pointer to the vector.
    idx The index value. Cannot be <0 or greater than the object count.
    return None
    failure If EV_HARD_EXIT is enabled, this function may cause exit();

    Memory sizing functions

    It can be useful to know how much memory is available or in current use.

    size_t evvcnt(void* vec)
    Get the number of slots in the vector

    Note 1: This function does not return the number of used slots (ie the number of objects) in the vector.
    If you are looking for this functionality, please use evcnt() function described above.
    Note 2: To use this function EV_FMEMSZ or EV_FALL must be defined.

    vec Pointer to the vector
    return The number of slots in the vector.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    size_t size_t evvmem(void vec)*
    Get the amount of memory currently used to store the vector including unused slots.

    Note: To use this function EV_FMEMSZ or EV_FALL must be defined.

    vec Pointer to the vector
    return The amount of memory currently used to store the vector.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    size_t size_t evomem(void* vec)
    Get the amount of memory currently used to store objects in the vector

    Note: To use this function EV_FMEMSZ or EV_FALL must be defined.

    vec Pointer to the vector
    return The amount of memory currently used to store objects in the vector.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    size_t evtmem(void* vec)
    Get the total memory used by the vector including including accounting overheads.

    Note: To use this function EV_FMEMSZ or EV_FALL must be defined.

    vec Pointer to the vector
    return The total amount of memory consumed by the vector.
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    Sorting

    void evsort(void* vec, int (*compar)(const void* a, const void* b))
    Sort the elements of the vector in place

    Note: To use this function EV_FSORT or EV_FALL must be defined.

    vec Pointer to the vector
    compar Function pointer which implements the comparison function.
    This function returns +ve if a > b, -ve if a < b and 0 if a==b.
    return None. The vector will be sorted in place if this function succeeds
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    Copying

    void* evcpy(void* src)
    Create a new vector and copy the contents of the source vector into it.

    Note: To use this function EV_FCOPY or EV_FALL must be defined.

    vec Pointer to the source vector
    return A new vector with the same contents as the source
    failure If EV_HARD_EXIT is enabled, this function may cause exit();


    Release notes

    4 Jan 2021 – V1.2

    • Allow evcnt() on null vector (returns 0)
    • More pedantic header checking.
    • Code formatting cleanup

    29 Nov 2020 – V1.1

    • Improved quick start documentation with step by step guide.
    • Added release notes to documentation
    • Added multiple compilation unit support with EV_HONLY define.
    • Added test2.c to show off multiple compilation unit support.
    • Made pedantic checking optional with EV_PEDATNIC define.
    • Made debug printing optional with EV_DEBUG define.

    25 Nove 2020 – V1.0

    • Initial release of Easy Vector (EV)

    Licensing

    Copyright (c) 2020, 2021 Matthew P. Grosvenor
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
      list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.

    3. Neither the name of the copyright holder nor the names of its
      contributors may be used to endorse or promote products derived from
      this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    Visit original content creator repository
    https://github.com/mgrosvenor/evec