Skip to content

Quick Start

Braedon edited this page Mar 17, 2019 · 5 revisions

This is a quick start guide meant for tutors!

Install

CSE

Run the following or just go to Releases and download llv.h from the latest release

curl -s https://api.github.com/repos/BraedonWooding/LLV/releases/latest \
    | grep "browser_download_url.*llv.h" \
    | cut -d '"' -f 4 \
    | wget -qi -

Mac/Linux

You can follow above if you want the single source file or you can install it like a library (it is static for ease). To install it like a library just write wget https://raw.githubusercontent.com/BraedonWooding/LLV/master/install.sh && sh install.sh && rm install.sh

Windows

TODO: Currently you can just go to releases and download the llv.h file :).

How to use

NOTE: if you are using it as a static library you have to compile it with -lLLV (like -lm)

Have a look at the examples for some specific examples (the code is under the .incl you could also look at the tests) but I'll give a few good examples here too;

Simple example (adding items to a LL and then thusly removing all odd ones)

eg1.c

// If you are on cse or did the single header route just write
#include "llv.h"

// else you have to list everything you are going to use like;
// #include <LLV/collections/ll.h>
// #include <LLV/llv.h>

int main(void) {
    LL list = ll_new("Example List");
    update(1, list); // prints out the list (which will be empty)
    for (int i = 0; i < 10; i++) {
        // NEW_NODE is a special generic macro that will create data
        // correctly with the proper type tag
        // in this case it is ll_new_node((Data){i}, INTEGER)
        ll_append(list, NEW_NODE(ll, i));
        update(1, list);
    }

    // LL and DLL have `head` and `tail`
    LL_Node cur = list->head;
    // this means that as you update cur
    // It'll display what box it currently is pointing to
    // cur can be null as well in that case it'll point to nothing
    attach_ptr(&cur, "cur");
    update(1, list);
    // sidenote: you can also call SET_PTR(cur, "cur"); and UNSET_PTR(cur);
    // if for a specific reason you don't want it to track and update
    // also remember to deattach_ptr(&cur); at the end if you care about freeing
    while (cur != NULL) {
       // read data as int
       // not typesafe so know what you are doing!!
       if (cur->data.int_data % 2 != 0) {
           // remove node
           LL_Node tmp = cur;
           cur = cur->next;
           ll_remove_node(list, tmp); // this also returns the removed node
           // sidenote: you could write this out yourself
           // by carrying around a prev ptr (or calling ll_find_prev)
           // fmt_update is a fancy printf basically
           fmt_update("%l %s %n", list, "Removed Node:", tmp);
           ll_free_node(tmp); // if you care
       } else {
           cur = cur->next;
           update(1, list);
       }
    }

    fmt_update("%s %l", "Finished Removing Odd Nodes", list);
    deattach_ptr(&cur, "cur");
    ll_free(list);
}

Run like gcc -o eg1.out eg1.c

Things to try (mainly so you can understand how things work);

  • export LLV_SLEEP_TIME=1000 before you run the program (no need to recompile)
  • update(2, list, list); (you should see the same list replicated twice!) will need to recompile of course

Getting user input

This time we will build the list till the user enters 0 then we will remove all even elements

eg2.c

// If library
// #include <LLV/collections/ll.h>
// #include <LLV/llv.h>
// Else
#include "llv.h"

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    LL list = ll_new("Example List");
    int res;
    while(true) {
        // %i for input then `i` for int
        // valid ones are: %ii (int) %il (long) %ic (char) %is (char buf - no allocation) %if (double)
        // note: they must all be at the end!!
        fmt_update("%l %ii", list, &res);
        if (res == -1) break;
        ll_append(list, NEW_NODE(ll, res));
    }

    LL_Node cur = list->head;
    attach_ptr(&cur, "cur");
    update(1, list);
    while (cur != NULL) {
       if (cur->data.int_data % 2 == 0) {
           LL_Node tmp = cur;
           cur = cur->next;
           ll_remove_node(list, tmp);
           fmt_update("%l %s %n", list, "Removed Node:", tmp);
           ll_free_node(tmp);
       } else {
           cur = cur->next;
       }
    }

    fmt_update("%s %l", "Finished Removing Even Nodes", list);
    deattach_ptr(&cur, "cur");
    ll_free(list);
}

Run like gcc -o eg2.out eg2.c

Things to try;

  • Notice how sleep time doesn't effect the insertion only when it is doing the removal this is because input overrides any sleep settings
  • Try floating point numbers!

Final Example

Get user input for an ll of floats till the user enters 0, then get an upper and lower bound and everything outside those bounds must be removed!

eg3.c

// If library
// #include <LLV/collections/ll.h>
// #include <LLV/llv.h>
// Else
#include "llv.h"

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    LL list = ll_new("Example List");
    double res;
    while(true) {
        fmt_update("%l %if", list, &res);
        // 0 has an actual proper value so epsilon isn't needed
        // here since we aren't doing arithmetic on it
        if (res == 0) break;
        // NEW_NODE picks up on it being a double and doesn't care!!! yay
        ll_append(list, NEW_NODE(ll, res));
    }

    double lower, upper;
    // no need to have lists here we just want a lower and upper bound but why not
    fmt_update("%l %s %if %if", list, "Enter lower and then upper bound", &lower, &upper);

    LL_Node cur = list->head;
    attach_ptr(&cur, "cur");
    update(1, list);
    while (cur != NULL) {
       if (cur->data.flt_data < lower || cur->data.flt_data > upper) {
           LL_Node tmp = cur;
           cur = cur->next;
           ll_remove_node(list, tmp);
           fmt_update("%l %s %n", list, "Removed Node:", tmp);
           ll_free_node(tmp);
       } else {
           cur = cur->next;
       }
    }

    fmt_update("%s %l", "Finished Removing Nodes out of bounds", list);
    deattach_ptr(&cur, "cur");
    ll_free(list);
}

Run like gcc -o eg2.out eg2.c

Things to try;

  • Remove the list in the code that grabs lower/upper bounds to show that you don't need it!