re-added linked lists :D; and minor aesthetic changes
parent
65ecf576d3
commit
49f3d4bdd5
|
@ -134,6 +134,15 @@
|
|||
(http://mathforum.org/library/drmath/view/52343.html)
|
||||
`(-1)%5` in python returns `4` (just like it should)
|
||||
|
||||
* [Is it safe to free `void *`?]
|
||||
(http://stackoverflow.com/a/2182522/2360353)
|
||||
Yes. The memory manager keeps track of the size of allocations - and the
|
||||
pointer you pass to `free()` is cast to `void *` before deallocation anyway.
|
||||
|
||||
* [Why do we need C Unions?]
|
||||
(http://stackoverflow.com/questions/252552/why-do-we-need-c-unions)
|
||||
Some good examples of what Unions are good for.
|
||||
|
||||
### C++ Stuff
|
||||
|
||||
* [Google C++ Style Guide]
|
||||
|
|
|
@ -34,7 +34,7 @@ void kb__layout__exec_key(bool pressed, uint8_t row, uint8_t column) {
|
|||
void (*function)(void);
|
||||
uint8_t layer;
|
||||
|
||||
for(uint8_t i = 0; i < layer_stack__size()+1+1; i++) { // i = offset+1
|
||||
for (uint8_t i=0; i < layer_stack__size()+1+1; i++) { // i = offset+1
|
||||
if (i == 0)
|
||||
if (!pressed)
|
||||
layer = pressed_layer[row][column];
|
||||
|
|
|
@ -73,17 +73,17 @@ bool kb__led__read(uint8_t led) {
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
void kb__led__all_on(void) {
|
||||
for(uint8_t i=1; i<=3; i++)
|
||||
for (uint8_t i=1; i<=3; i++)
|
||||
kb__led__on(i);
|
||||
}
|
||||
|
||||
void kb__led__all_off(void) {
|
||||
for(uint8_t i=1; i<=3; i++)
|
||||
for (uint8_t i=1; i<=3; i++)
|
||||
kb__led__off(i);
|
||||
}
|
||||
|
||||
void kb__led__all_set(float n) {
|
||||
for(uint8_t i=1; i<=3; i++)
|
||||
for (uint8_t i=1; i<=3; i++)
|
||||
kb__led__set(i, n);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ include $(CURDIR)/options.mk
|
|||
CURDIR := $(ROOTDIR)/lib/layout/layer-stack
|
||||
include $(CURDIR)/options.mk
|
||||
# -------
|
||||
CURDIR := $(ROOTDIR)/lib/data-types/list
|
||||
include $(CURDIR)/options.mk
|
||||
# -------
|
||||
CURDIR := $(firstword $(CURDIRS))
|
||||
CURDIRS := $(wordlist 2,$(words $(CURDIRS)),$(CURDIRS))
|
||||
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2013 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (see "doc/licenses/MIT.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/** description
|
||||
* An interface to a simple linked-list that can be used to implement lists,
|
||||
* queues, stacks, and things
|
||||
*
|
||||
* Prefix: `list__`
|
||||
*
|
||||
*
|
||||
* Implementation notes:
|
||||
*
|
||||
* - All functions that accept an `index` should set `index %= list->length`
|
||||
* before using it. This will make all passed indices valid. It will also
|
||||
* provide a convenient way to reference the last element of a list, by
|
||||
* passing `-1` as the index (as in Python).
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ERGODOX_FIRMWARE__FIRMWARE__LIB__DATA_TYPES__LIST__H
|
||||
#define ERGODOX_FIRMWARE__FIRMWARE__LIB__DATA_TYPES__LIST__H
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef struct list__node_t {
|
||||
struct list__node_t * next;
|
||||
} list__node_t;
|
||||
|
||||
typedef struct list__list_t {
|
||||
list__node_t * head;
|
||||
list__node_t * tail;
|
||||
uint8_t length;
|
||||
} list__list_t;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
list__list_t * list__new (void);
|
||||
void * list__insert ( list__list_t * list,
|
||||
int8_t index,
|
||||
uint8_t size );
|
||||
void * list__peek (list__list_t * list, int8_t index);
|
||||
void * list__pop__no_free (list__list_t * list, int8_t index);
|
||||
void list__free (list__list_t * list);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif // ERGODOX_FIRMWARE__FIRMWARE__LIB__DATA_TYPES__LIST__H
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// === documentation ==========================================================
|
||||
// ============================================================================
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// typedefs -------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// === list__node_t ===
|
||||
/** typedefs/list__node_t/description
|
||||
* The type of a "node", for the purposes of this library
|
||||
*
|
||||
* Full node types should be defined in the using '.c' or '.h' file, with
|
||||
* something like
|
||||
*
|
||||
* typedef struct {
|
||||
* list__node_t _private;
|
||||
* uint8_t data;
|
||||
* } node_t;
|
||||
*
|
||||
* The functions that return pointers to nodes will return `void *` pointers,
|
||||
* so functions in the using '.c' file also need to cast these return values to
|
||||
* the appropriate type before use.
|
||||
*/
|
||||
|
||||
// === list__list_t ===
|
||||
/** typedefs/list__list_t/description
|
||||
* Simple struct to define and keep track of our list
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// functions ------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// === list__new() ===
|
||||
/** functions/list__new/description
|
||||
* Allocate a new (empty) list
|
||||
*
|
||||
* Returns:
|
||||
* - success: A pointer to the new list
|
||||
* - failure: `NULL`
|
||||
*/
|
||||
|
||||
// === list__insert() ===
|
||||
/** functions/list__insert/description
|
||||
* Insert `node` at position `index % list->length`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position the new node will occupy
|
||||
* - `size`: The size of the full node type (as in `sizeof(node_t)`) defined in
|
||||
* the using '.c' or '.h' file, so we know how much memory to allocate
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the new node
|
||||
* - failure: `NULL`
|
||||
*
|
||||
* Warning:
|
||||
* - For any given list, the `size` passed to this function should always be
|
||||
* the same.
|
||||
*
|
||||
* Caution:
|
||||
* - Initialization of the data to be stored in the node is the calling
|
||||
* function's responsibility.
|
||||
*/
|
||||
|
||||
// === list__peek() ===
|
||||
/** functions/list__peek/description
|
||||
* Return a pointer to the node at position `index % list->length`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position of the node to peek at
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the node at position `index % list->length`
|
||||
* - failure: `NULL`
|
||||
*/
|
||||
|
||||
// === list__pop__no_free() ===
|
||||
/** functions/list__pop__no_free/description
|
||||
* Return a pointer to the node at position `index % list->length`, and remove
|
||||
* the node from the list
|
||||
*
|
||||
* Warning:
|
||||
* - Does not free the node's memory - this is the calling function's
|
||||
* responsibility. If you want to pop the node and free its memory without
|
||||
* looking at it, call `free( list__pop__no_free( node ) )`.
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position of the node to pop
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the node at position `index % list->length`
|
||||
* - failure: `NULL`
|
||||
*/
|
||||
|
||||
// === list__free() ===
|
||||
/** functions/list__free/description
|
||||
* Free all node pointers in `list`, then free `list`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
*/
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, 2013 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (see "doc/licenses/MIT.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/** description
|
||||
* Implements the list type in "../list.h"
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "../list.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
list__list_t * list__new(void) {
|
||||
list__list_t * list = malloc( sizeof(list__list_t) );
|
||||
if (!list) return NULL;
|
||||
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->length = 0;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void * list__insert(list__list_t * list, int8_t index, uint8_t size) {
|
||||
list__node_t * node = malloc(size);
|
||||
if (!node) return NULL;
|
||||
|
||||
list->length++;
|
||||
|
||||
if (list->length == 1) {
|
||||
// insert as only node (no others exist yet)
|
||||
list->head = node;
|
||||
list->tail = node;
|
||||
node->next = NULL;
|
||||
|
||||
} else {
|
||||
index %= list->length;
|
||||
|
||||
if (index == 0) {
|
||||
// insert as first node
|
||||
node->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
} else if (index == list->length-1) {
|
||||
// insert as last node
|
||||
list->tail->next = node;
|
||||
list->tail = node;
|
||||
node->next = NULL;
|
||||
|
||||
} else {
|
||||
// insert as other node
|
||||
list__node_t * previous = list->head;
|
||||
for (uint8_t i=1; i<index; i++)
|
||||
previous = previous->next;
|
||||
node->next = previous->next;
|
||||
previous->next = node;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void * list__peek(list__list_t * list, int8_t index) {
|
||||
// if no nodes exist
|
||||
if (list->length == 0)
|
||||
return NULL;
|
||||
|
||||
index %= list->length;
|
||||
|
||||
// if last node
|
||||
if (index == list->length-1)
|
||||
return list->tail;
|
||||
|
||||
// else
|
||||
list__node_t * node = list->head;
|
||||
for (uint8_t i=0; i<index; i++)
|
||||
node = node->next;
|
||||
return node;
|
||||
}
|
||||
|
||||
void * list__pop__no_free(list__list_t * list, int8_t index) {
|
||||
// if no nodes exist
|
||||
if (list->length == 0)
|
||||
return NULL;
|
||||
|
||||
index %= list->length;
|
||||
|
||||
list__node_t * node;
|
||||
|
||||
if (index == 0) {
|
||||
// pop first node
|
||||
node = list->head;
|
||||
list->head = node->next;
|
||||
|
||||
} else {
|
||||
// find the `index-1`th node
|
||||
list__node_t * previous = list->head;
|
||||
for (uint8_t i=1; i<index; i++)
|
||||
previous = previous->next;
|
||||
|
||||
// if last node
|
||||
if (index == list->length-1)
|
||||
list->tail = previous;
|
||||
|
||||
// pop the node at `index`
|
||||
node = previous->next;
|
||||
previous->next = node->next;
|
||||
}
|
||||
|
||||
list->length--;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void list__free(list__list_t * list) {
|
||||
list__node_t * node;
|
||||
while (list->head) {
|
||||
node = list->head;
|
||||
list->head = list->head->next;
|
||||
free(node);
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2013 Ben Blazak <benblazak.dev@gmail.com>
|
||||
# Released under The MIT License (see "doc/licenses/MIT.md")
|
||||
# Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
## description
|
||||
# list options
|
||||
#
|
||||
# This file is meant to be included by the using '.../options.mk'
|
||||
#
|
||||
|
||||
|
||||
SRC += $(wildcard $(CURDIR)/*.c)
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef ERGODOX_FIRMWARE__LIB__LAYOUT__EEPROM_MACRO__H
|
||||
#define ERGODOX_FIRMWARE__LIB__LAYOUT__EEPROM_MACRO__H
|
||||
#ifndef ERGODOX_FIRMWARE__FIRMWARE__LIB__LAYOUT__EEPROM_MACRO__H
|
||||
#define ERGODOX_FIRMWARE__FIRMWARE__LIB__LAYOUT__EEPROM_MACRO__H
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -25,5 +25,5 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif // ERGODOX_FIRMWARE__LIB__LAYOUT__EEPROM_MACRO__H
|
||||
#endif // ERGODOX_FIRMWARE__FIRMWARE__LIB__LAYOUT__EEPROM_MACRO__H
|
||||
|
||||
|
|
|
@ -14,10 +14,13 @@
|
|||
*
|
||||
* Prefixes: `keys__`, [none]
|
||||
*
|
||||
* Usage: `#define` `KEYS__DEFAULT` and `KEYS__SHIFTED` before `#include`ing.
|
||||
*
|
||||
* TODO: add media and mouse keys (after i figure out which OSs are supposed to
|
||||
* support which keys)
|
||||
* Usage:
|
||||
* - `#define` `KEYS__DEFAULT` and `KEYS__SHIFTED` before `#include`ing.
|
||||
* - These macros should probably do what their names imply (i.e. define a
|
||||
* "default" or "shifted" key, respectively, whatever that means to the
|
||||
* implementing layout), but in a practical sense they can be used however
|
||||
* one wants. They're simply a really convenient way to generate almost
|
||||
* the same bit of code for a lot of (key_name, key_code) pairs.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ static uint8_t _shift_elements(uint8_t offset, bool up) {
|
|||
uint8_t increment = (up) ? -1 : 1 ;
|
||||
uint8_t end = (up) ? _filled-1-offset : _filled-1 ;
|
||||
|
||||
for(uint8_t i=start; i!=(end+increment); i+=increment) {
|
||||
for (uint8_t i=start; i!=(end+increment); i+=increment) {
|
||||
_stack[i-increment].id = _stack[i].id;
|
||||
_stack[i-increment].number = _stack[i].number;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ uint8_t layer_stack__pop_id(uint8_t layer_id) {
|
|||
}
|
||||
|
||||
uint8_t layer_stack__find_id(uint8_t layer_id) {
|
||||
for(uint8_t i=0; i<_filled; i++)
|
||||
for (uint8_t i=0; i<_filled; i++)
|
||||
if (_stack[i].id == layer_id)
|
||||
return _filled-1-i; // offset
|
||||
return -1; // failure: return an invalid offset
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
/** description
|
||||
* Implements the timer functions defined in "../timer.h" for the ATMega32U4
|
||||
*
|
||||
* Prefix: `timer__`
|
||||
*
|
||||
* See the accompanying '.md' file for documentation.
|
||||
*/
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ uint8_t usb__kb__send_report (void);
|
|||
*/
|
||||
|
||||
// === usb__is_configured ===
|
||||
/** variables/usb__is_configured/description
|
||||
/** functions/usb__is_configured/description
|
||||
* Check whether this device has been configured by the host
|
||||
*
|
||||
* Returns:
|
||||
|
|
|
@ -82,7 +82,7 @@ int main(void) {
|
|||
time_scan_started // on the first iteration, scan immediately
|
||||
= timer__get_milliseconds() - OPT__DEBOUNCE_TIME;
|
||||
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
temp = is_pressed;
|
||||
is_pressed = was_pressed;
|
||||
was_pressed = temp;
|
||||
|
@ -96,8 +96,8 @@ int main(void) {
|
|||
kb__update_matrix(*is_pressed);
|
||||
|
||||
// "execute" keys that have changed state
|
||||
for(row=0; row<OPT__KB__ROWS; row++) {
|
||||
for(col=0; col<OPT__KB__COLUMNS; col++) {
|
||||
for (row=0; row<OPT__KB__ROWS; row++) {
|
||||
for (col=0; col<OPT__KB__COLUMNS; col++) {
|
||||
key_is_pressed = (*is_pressed)[row][col];
|
||||
key_was_pressed = (*was_pressed)[row][col];
|
||||
|
||||
|
|
Loading…
Reference in New Issue