diff options
author | Eli Bendersky <eliben@gmail.com> | 2012-06-23 06:25:53 +0300 |
---|---|---|
committer | Eli Bendersky <eliben@gmail.com> | 2012-06-23 06:25:53 +0300 |
commit | a291586d16a16fbd8c44ccd9e70efed36222c878 (patch) | |
tree | bdb329a893a953416618b09d48c63532f6490326 /examples | |
parent | cbcfa052b01085910bde258fc47cae8708cf936a (diff) | |
download | pycparser-a291586d16a16fbd8c44ccd9e70efed36222c878.tar.gz |
Issue 63: fix up line endings
Diffstat (limited to 'examples')
-rw-r--r-- | examples/c_files/funky.c | 40 | ||||
-rw-r--r-- | examples/c_files/hash.c | 400 | ||||
-rw-r--r-- | examples/c_files/memmgr.c | 412 | ||||
-rw-r--r-- | examples/c_files/memmgr.h | 192 | ||||
-rw-r--r-- | examples/c_files/year.c | 106 | ||||
-rw-r--r-- | examples/explore_ast.py | 332 | ||||
-rw-r--r-- | examples/func_calls.py | 100 | ||||
-rw-r--r-- | examples/func_defs.py | 100 |
8 files changed, 841 insertions, 841 deletions
diff --git a/examples/c_files/funky.c b/examples/c_files/funky.c index 252375f..5ebf7b2 100644 --- a/examples/c_files/funky.c +++ b/examples/c_files/funky.c @@ -1,20 +1,20 @@ -char foo(void)
-{
- return '1';
-}
-
-int maxout_in(int paste, char** matrix)
-{
- char o = foo();
- return (int) matrix[1][2] * 5 - paste;
-}
-
-int main()
-{
- auto char* multi = "a multi";
-
-
-}
-
-
-
+char foo(void) +{ + return '1'; +} + +int maxout_in(int paste, char** matrix) +{ + char o = foo(); + return (int) matrix[1][2] * 5 - paste; +} + +int main() +{ + auto char* multi = "a multi"; + + +} + + + diff --git a/examples/c_files/hash.c b/examples/c_files/hash.c index 7ec500e..c11fe45 100644 --- a/examples/c_files/hash.c +++ b/examples/c_files/hash.c @@ -1,200 +1,200 @@ -/*
-** C implementation of a hash table ADT
-*/
-typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
-
-
-typedef struct tagEntry
-{
- char* key;
- char* value;
-} Entry;
-
-
-
-typedef struct tagNode
-{
- Entry* entry;
-
- struct tagNode* next;
-} Node;
-
-
-typedef struct tagHash
-{
- unsigned int table_size;
-
- Node** heads;
-
-} Hash;
-
-
-static unsigned int hash_func(const char* str, unsigned int table_size)
-{
- unsigned int hash_value;
- unsigned int a = 127;
-
- for (hash_value = 0; *str != 0; ++str)
- hash_value = (a*hash_value + *str) % table_size;
-
- return hash_value;
-}
-
-
-ReturnCode HashCreate(Hash** hash, unsigned int table_size)
-{
- unsigned int i;
-
- if (table_size < 1)
- return FAIL;
-
- //
- // Allocate space for the Hash
- //
- if (((*hash) = malloc(sizeof(**hash))) == NULL)
- return FAIL;
-
- //
- // Allocate space for the array of list heads
- //
- if (((*hash)->heads = malloc(table_size*sizeof(*((*hash)->heads)))) == NULL)
- return FAIL;
-
- //
- // Initialize Hash info
- //
- for (i = 0; i < table_size; ++i)
- {
- (*hash)->heads[i] = NULL;
- }
-
- (*hash)->table_size = table_size;
-
- return SUCCESS;
-}
-
-
-ReturnCode HashInsert(Hash* hash, const Entry* entry)
-{
- unsigned int index = hash_func(entry->key, hash->table_size);
- Node* temp = hash->heads[index];
-
- HashRemove(hash, entry->key);
-
- if ((hash->heads[index] = malloc(sizeof(Node))) == NULL)
- return FAIL;
-
- hash->heads[index]->entry = malloc(sizeof(Entry));
- hash->heads[index]->entry->key = malloc(strlen(entry->key)+1);
- hash->heads[index]->entry->value = malloc(strlen(entry->value)+1);
- strcpy(hash->heads[index]->entry->key, entry->key);
- strcpy(hash->heads[index]->entry->value, entry->value);
-
- hash->heads[index]->next = temp;
-
- return SUCCESS;
-}
-
-
-
-const Entry* HashFind(const Hash* hash, const char* key)
-{
- unsigned int index = hash_func(key, hash->table_size);
- Node* temp = hash->heads[index];
-
- while (temp != NULL)
- {
- if (!strcmp(key, temp->entry->key))
- return temp->entry;
-
- temp = temp->next;
- }
-
- return NULL;
-}
-
-
-ReturnCode HashRemove(Hash* hash, const char* key)
-{
- unsigned int index = hash_func(key, hash->table_size);
- Node* temp1 = hash->heads[index];
- Node* temp2 = temp1;
-
- while (temp1 != NULL)
- {
- if (!strcmp(key, temp1->entry->key))
- {
- if (temp1 == hash->heads[index])
- hash->heads[index] = hash->heads[index]->next;
- else
- temp2->next = temp1->next;
-
- free(temp1->entry->key);
- free(temp1->entry->value);
- free(temp1->entry);
- free(temp1);
- temp1 = NULL;
-
- return SUCCESS;
- }
-
- temp2 = temp1;
- temp1 = temp1->next;
- }
-
- return FAIL;
-}
-
-
-void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
-{
- unsigned int i;
-
- if (hash == NULL || hash->heads == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- PrintFunc(temp->entry->key, temp->entry->value);
- temp = temp->next;
- }
- }
-}
-
-
-
-void HashDestroy(Hash* hash)
-{
- unsigned int i;
-
- if (hash == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- Node* temp2 = temp;
-
- free(temp->entry->key);
- free(temp->entry->value);
- free(temp->entry);
-
- temp = temp->next;
-
- free(temp2);
- }
- }
-
- free(hash->heads);
- hash->heads = NULL;
-
- free(hash);
-}
-
+/* +** C implementation of a hash table ADT +*/ +typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode; + + +typedef struct tagEntry +{ + char* key; + char* value; +} Entry; + + + +typedef struct tagNode +{ + Entry* entry; + + struct tagNode* next; +} Node; + + +typedef struct tagHash +{ + unsigned int table_size; + + Node** heads; + +} Hash; + + +static unsigned int hash_func(const char* str, unsigned int table_size) +{ + unsigned int hash_value; + unsigned int a = 127; + + for (hash_value = 0; *str != 0; ++str) + hash_value = (a*hash_value + *str) % table_size; + + return hash_value; +} + + +ReturnCode HashCreate(Hash** hash, unsigned int table_size) +{ + unsigned int i; + + if (table_size < 1) + return FAIL; + + // + // Allocate space for the Hash + // + if (((*hash) = malloc(sizeof(**hash))) == NULL) + return FAIL; + + // + // Allocate space for the array of list heads + // + if (((*hash)->heads = malloc(table_size*sizeof(*((*hash)->heads)))) == NULL) + return FAIL; + + // + // Initialize Hash info + // + for (i = 0; i < table_size; ++i) + { + (*hash)->heads[i] = NULL; + } + + (*hash)->table_size = table_size; + + return SUCCESS; +} + + +ReturnCode HashInsert(Hash* hash, const Entry* entry) +{ + unsigned int index = hash_func(entry->key, hash->table_size); + Node* temp = hash->heads[index]; + + HashRemove(hash, entry->key); + + if ((hash->heads[index] = malloc(sizeof(Node))) == NULL) + return FAIL; + + hash->heads[index]->entry = malloc(sizeof(Entry)); + hash->heads[index]->entry->key = malloc(strlen(entry->key)+1); + hash->heads[index]->entry->value = malloc(strlen(entry->value)+1); + strcpy(hash->heads[index]->entry->key, entry->key); + strcpy(hash->heads[index]->entry->value, entry->value); + + hash->heads[index]->next = temp; + + return SUCCESS; +} + + + +const Entry* HashFind(const Hash* hash, const char* key) +{ + unsigned int index = hash_func(key, hash->table_size); + Node* temp = hash->heads[index]; + + while (temp != NULL) + { + if (!strcmp(key, temp->entry->key)) + return temp->entry; + + temp = temp->next; + } + + return NULL; +} + + +ReturnCode HashRemove(Hash* hash, const char* key) +{ + unsigned int index = hash_func(key, hash->table_size); + Node* temp1 = hash->heads[index]; + Node* temp2 = temp1; + + while (temp1 != NULL) + { + if (!strcmp(key, temp1->entry->key)) + { + if (temp1 == hash->heads[index]) + hash->heads[index] = hash->heads[index]->next; + else + temp2->next = temp1->next; + + free(temp1->entry->key); + free(temp1->entry->value); + free(temp1->entry); + free(temp1); + temp1 = NULL; + + return SUCCESS; + } + + temp2 = temp1; + temp1 = temp1->next; + } + + return FAIL; +} + + +void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*)) +{ + unsigned int i; + + if (hash == NULL || hash->heads == NULL) + return; + + for (i = 0; i < hash->table_size; ++i) + { + Node* temp = hash->heads[i]; + + while (temp != NULL) + { + PrintFunc(temp->entry->key, temp->entry->value); + temp = temp->next; + } + } +} + + + +void HashDestroy(Hash* hash) +{ + unsigned int i; + + if (hash == NULL) + return; + + for (i = 0; i < hash->table_size; ++i) + { + Node* temp = hash->heads[i]; + + while (temp != NULL) + { + Node* temp2 = temp; + + free(temp->entry->key); + free(temp->entry->value); + free(temp->entry); + + temp = temp->next; + + free(temp2); + } + } + + free(hash->heads); + hash->heads = NULL; + + free(hash); +} + diff --git a/examples/c_files/memmgr.c b/examples/c_files/memmgr.c index 6036ec6..41a62c0 100644 --- a/examples/c_files/memmgr.c +++ b/examples/c_files/memmgr.c @@ -1,206 +1,206 @@ -//----------------------------------------------------------------
-// Statically-allocated memory manager
-//
-// by Eli Bendersky (eliben@gmail.com)
-//
-// This code is in the public domain.
-//----------------------------------------------------------------
-#include "memmgr.h"
-
-typedef ulong Align;
-
-union mem_header_union
-{
- struct
- {
- // Pointer to the next block in the free list
- //
- union mem_header_union* next;
-
- // Size of the block (in quantas of sizeof(mem_header_t))
- //
- ulong size;
- } s;
-
- // Used to align headers in memory to a boundary
- //
- Align align_dummy;
-};
-
-typedef union mem_header_union mem_header_t;
-
-// Initial empty list
-//
-static mem_header_t base;
-
-// Start of free list
-//
-static mem_header_t* freep = 0;
-
-// Static pool for new allocations
-//
-static byte pool[POOL_SIZE] = {0};
-static ulong pool_free_pos = 0;
-
-
-void memmgr_init()
-{
- base.s.next = 0;
- base.s.size = 0;
- freep = 0;
- pool_free_pos = 0;
-}
-
-
-static mem_header_t* get_mem_from_pool(ulong nquantas)
-{
- ulong total_req_size;
-
- mem_header_t* h;
-
- if (nquantas < MIN_POOL_ALLOC_QUANTAS)
- nquantas = MIN_POOL_ALLOC_QUANTAS;
-
- total_req_size = nquantas * sizeof(mem_header_t);
-
- if (pool_free_pos + total_req_size <= POOL_SIZE)
- {
- h = (mem_header_t*) (pool + pool_free_pos);
- h->s.size = nquantas;
- memmgr_free((void*) (h + 1));
- pool_free_pos += total_req_size;
- }
- else
- {
- return 0;
- }
-
- return freep;
-}
-
-
-// Allocations are done in 'quantas' of header size.
-// The search for a free block of adequate size begins at the point 'freep'
-// where the last block was found.
-// If a too-big block is found, it is split and the tail is returned (this
-// way the header of the original needs only to have its size adjusted).
-// The pointer returned to the user points to the free space within the block,
-// which begins one quanta after the header.
-//
-void* memmgr_alloc(ulong nbytes)
-{
- mem_header_t* p;
- mem_header_t* prevp;
-
- // Calculate how many quantas are required: we need enough to house all
- // the requested bytes, plus the header. The -1 and +1 are there to make sure
- // that if nbytes is a multiple of nquantas, we don't allocate too much
- //
- ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;
-
- // First alloc call, and no free list yet ? Use 'base' for an initial
- // denegerate block of size 0, which points to itself
- //
- if ((prevp = freep) == 0)
- {
- base.s.next = freep = prevp = &base;
- base.s.size = 0;
- }
-
- for (p = prevp->s.next; ; prevp = p, p = p->s.next)
- {
- // big enough ?
- if (p->s.size >= nquantas)
- {
- // exactly ?
- if (p->s.size == nquantas)
- {
- // just eliminate this block from the free list by pointing
- // its prev's next to its next
- //
- prevp->s.next = p->s.next;
- }
- else // too big
- {
- p->s.size -= nquantas;
- p += p->s.size;
- p->s.size = nquantas;
- }
-
- freep = prevp;
- return (void*) (p + 1);
- }
- // Reached end of free list ?
- // Try to allocate the block from the pool. If that succeeds,
- // get_mem_from_pool adds the new block to the free list and
- // it will be found in the following iterations. If the call
- // to get_mem_from_pool doesn't succeed, we've run out of
- // memory
- //
- else if (p == freep)
- {
- if ((p = get_mem_from_pool(nquantas)) == 0)
- {
- #ifdef DEBUG_MEMMGR_FATAL
- printf("!! Memory allocation failed !!\n");
- #endif
- return 0;
- }
- }
- }
-}
-
-
-// Scans the free list, starting at freep, looking the the place to insert the
-// free block. This is either between two existing blocks or at the end of the
-// list. In any case, if the block being freed is adjacent to either neighbor,
-// the adjacent blocks are combined.
-//
-void memmgr_free(void* ap)
-{
- mem_header_t* block;
- mem_header_t* p;
-
- // acquire pointer to block header
- block = ((mem_header_t*) ap) - 1;
-
- // Find the correct place to place the block in (the free list is sorted by
- // address, increasing order)
- //
- for (p = freep; !(block > p && block < p->s.next); p = p->s.next)
- {
- // Since the free list is circular, there is one link where a
- // higher-addressed block points to a lower-addressed block.
- // This condition checks if the block should be actually
- // inserted between them
- //
- if (p >= p->s.next && (block > p || block < p->s.next))
- break;
- }
-
- // Try to combine with the higher neighbor
- //
- if (block + block->s.size == p->s.next)
- {
- block->s.size += p->s.next->s.size;
- block->s.next = p->s.next->s.next;
- }
- else
- {
- block->s.next = p->s.next;
- }
-
- // Try to combine with the lower neighbor
- //
- if (p + p->s.size == block)
- {
- p->s.size += block->s.size;
- p->s.next = block->s.next;
- }
- else
- {
- p->s.next = block;
- }
-
- freep = p;
-}
+//---------------------------------------------------------------- +// Statically-allocated memory manager +// +// by Eli Bendersky (eliben@gmail.com) +// +// This code is in the public domain. +//---------------------------------------------------------------- +#include "memmgr.h" + +typedef ulong Align; + +union mem_header_union +{ + struct + { + // Pointer to the next block in the free list + // + union mem_header_union* next; + + // Size of the block (in quantas of sizeof(mem_header_t)) + // + ulong size; + } s; + + // Used to align headers in memory to a boundary + // + Align align_dummy; +}; + +typedef union mem_header_union mem_header_t; + +// Initial empty list +// +static mem_header_t base; + +// Start of free list +// +static mem_header_t* freep = 0; + +// Static pool for new allocations +// +static byte pool[POOL_SIZE] = {0}; +static ulong pool_free_pos = 0; + + +void memmgr_init() +{ + base.s.next = 0; + base.s.size = 0; + freep = 0; + pool_free_pos = 0; +} + + +static mem_header_t* get_mem_from_pool(ulong nquantas) +{ + ulong total_req_size; + + mem_header_t* h; + + if (nquantas < MIN_POOL_ALLOC_QUANTAS) + nquantas = MIN_POOL_ALLOC_QUANTAS; + + total_req_size = nquantas * sizeof(mem_header_t); + + if (pool_free_pos + total_req_size <= POOL_SIZE) + { + h = (mem_header_t*) (pool + pool_free_pos); + h->s.size = nquantas; + memmgr_free((void*) (h + 1)); + pool_free_pos += total_req_size; + } + else + { + return 0; + } + + return freep; +} + + +// Allocations are done in 'quantas' of header size. +// The search for a free block of adequate size begins at the point 'freep' +// where the last block was found. +// If a too-big block is found, it is split and the tail is returned (this +// way the header of the original needs only to have its size adjusted). +// The pointer returned to the user points to the free space within the block, +// which begins one quanta after the header. +// +void* memmgr_alloc(ulong nbytes) +{ + mem_header_t* p; + mem_header_t* prevp; + + // Calculate how many quantas are required: we need enough to house all + // the requested bytes, plus the header. The -1 and +1 are there to make sure + // that if nbytes is a multiple of nquantas, we don't allocate too much + // + ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1; + + // First alloc call, and no free list yet ? Use 'base' for an initial + // denegerate block of size 0, which points to itself + // + if ((prevp = freep) == 0) + { + base.s.next = freep = prevp = &base; + base.s.size = 0; + } + + for (p = prevp->s.next; ; prevp = p, p = p->s.next) + { + // big enough ? + if (p->s.size >= nquantas) + { + // exactly ? + if (p->s.size == nquantas) + { + // just eliminate this block from the free list by pointing + // its prev's next to its next + // + prevp->s.next = p->s.next; + } + else // too big + { + p->s.size -= nquantas; + p += p->s.size; + p->s.size = nquantas; + } + + freep = prevp; + return (void*) (p + 1); + } + // Reached end of free list ? + // Try to allocate the block from the pool. If that succeeds, + // get_mem_from_pool adds the new block to the free list and + // it will be found in the following iterations. If the call + // to get_mem_from_pool doesn't succeed, we've run out of + // memory + // + else if (p == freep) + { + if ((p = get_mem_from_pool(nquantas)) == 0) + { + #ifdef DEBUG_MEMMGR_FATAL + printf("!! Memory allocation failed !!\n"); + #endif + return 0; + } + } + } +} + + +// Scans the free list, starting at freep, looking the the place to insert the +// free block. This is either between two existing blocks or at the end of the +// list. In any case, if the block being freed is adjacent to either neighbor, +// the adjacent blocks are combined. +// +void memmgr_free(void* ap) +{ + mem_header_t* block; + mem_header_t* p; + + // acquire pointer to block header + block = ((mem_header_t*) ap) - 1; + + // Find the correct place to place the block in (the free list is sorted by + // address, increasing order) + // + for (p = freep; !(block > p && block < p->s.next); p = p->s.next) + { + // Since the free list is circular, there is one link where a + // higher-addressed block points to a lower-addressed block. + // This condition checks if the block should be actually + // inserted between them + // + if (p >= p->s.next && (block > p || block < p->s.next)) + break; + } + + // Try to combine with the higher neighbor + // + if (block + block->s.size == p->s.next) + { + block->s.size += p->s.next->s.size; + block->s.next = p->s.next->s.next; + } + else + { + block->s.next = p->s.next; + } + + // Try to combine with the lower neighbor + // + if (p + p->s.size == block) + { + p->s.size += block->s.size; + p->s.next = block->s.next; + } + else + { + p->s.next = block; + } + + freep = p; +} diff --git a/examples/c_files/memmgr.h b/examples/c_files/memmgr.h index ae8212d..47ddadb 100644 --- a/examples/c_files/memmgr.h +++ b/examples/c_files/memmgr.h @@ -1,96 +1,96 @@ -//----------------------------------------------------------------
-// Statically-allocated memory manager
-//
-// by Eli Bendersky (eliben@gmail.com)
-//
-// This code is in the public domain.
-//----------------------------------------------------------------
-#ifndef MEMMGR_H
-#define MEMMGR_H
-
-//
-// Memory manager: dynamically allocates memory from
-// a fixed pool that is allocated statically at link-time.
-//
-// Usage: after calling memmgr_init() in your
-// initialization routine, just use memmgr_alloc() instead
-// of malloc() and memmgr_free() instead of free().
-// Naturally, you can use the preprocessor to define
-// malloc() and free() as aliases to memmgr_alloc() and
-// memmgr_free(). This way the manager will be a drop-in
-// replacement for the standard C library allocators, and can
-// be useful for debugging memory allocation problems and
-// leaks.
-//
-// Preprocessor flags you can define to customize the
-// memory manager:
-//
-// DEBUG_MEMMGR_FATAL
-// Allow printing out a message when allocations fail
-//
-// DEBUG_MEMMGR_SUPPORT_STATS
-// Allow printing out of stats in function
-// memmgr_print_stats When this is disabled,
-// memmgr_print_stats does nothing.
-//
-// Note that in production code on an embedded system
-// you'll probably want to keep those undefined, because
-// they cause printf to be called.
-//
-// POOL_SIZE
-// Size of the pool for new allocations. This is
-// effectively the heap size of the application, and can
-// be changed in accordance with the available memory
-// resources.
-//
-// MIN_POOL_ALLOC_QUANTAS
-// Internally, the memory manager allocates memory in
-// quantas roughly the size of two ulong objects. To
-// minimize pool fragmentation in case of multiple allocations
-// and deallocations, it is advisable to not allocate
-// blocks that are too small.
-// This flag sets the minimal ammount of quantas for
-// an allocation. If the size of a ulong is 4 and you
-// set this flag to 16, the minimal size of an allocation
-// will be 4 * 2 * 16 = 128 bytes
-// If you have a lot of small allocations, keep this value
-// low to conserve memory. If you have mostly large
-// allocations, it is best to make it higher, to avoid
-// fragmentation.
-//
-// Notes:
-// 1. This memory manager is *not thread safe*. Use it only
-// for single thread/task applications.
-//
-
-#define DEBUG_MEMMGR_SUPPORT_STATS 1
-
-#define POOL_SIZE 8 * 1024
-#define MIN_POOL_ALLOC_QUANTAS 16
-
-
-typedef unsigned char byte;
-typedef unsigned long ulong;
-
-
-
-// Initialize the memory manager. This function should be called
-// only once in the beginning of the program.
-//
-void memmgr_init();
-
-// 'malloc' clone
-//
-void* memmgr_alloc(ulong nbytes);
-
-// 'free' clone
-//
-void memmgr_free(void* ap);
-
-// Prints statistics about the current state of the memory
-// manager
-//
-void memmgr_print_stats();
-
-
-#endif // MEMMGR_H
+//---------------------------------------------------------------- +// Statically-allocated memory manager +// +// by Eli Bendersky (eliben@gmail.com) +// +// This code is in the public domain. +//---------------------------------------------------------------- +#ifndef MEMMGR_H +#define MEMMGR_H + +// +// Memory manager: dynamically allocates memory from +// a fixed pool that is allocated statically at link-time. +// +// Usage: after calling memmgr_init() in your +// initialization routine, just use memmgr_alloc() instead +// of malloc() and memmgr_free() instead of free(). +// Naturally, you can use the preprocessor to define +// malloc() and free() as aliases to memmgr_alloc() and +// memmgr_free(). This way the manager will be a drop-in +// replacement for the standard C library allocators, and can +// be useful for debugging memory allocation problems and +// leaks. +// +// Preprocessor flags you can define to customize the +// memory manager: +// +// DEBUG_MEMMGR_FATAL +// Allow printing out a message when allocations fail +// +// DEBUG_MEMMGR_SUPPORT_STATS +// Allow printing out of stats in function +// memmgr_print_stats When this is disabled, +// memmgr_print_stats does nothing. +// +// Note that in production code on an embedded system +// you'll probably want to keep those undefined, because +// they cause printf to be called. +// +// POOL_SIZE +// Size of the pool for new allocations. This is +// effectively the heap size of the application, and can +// be changed in accordance with the available memory +// resources. +// +// MIN_POOL_ALLOC_QUANTAS +// Internally, the memory manager allocates memory in +// quantas roughly the size of two ulong objects. To +// minimize pool fragmentation in case of multiple allocations +// and deallocations, it is advisable to not allocate +// blocks that are too small. +// This flag sets the minimal ammount of quantas for +// an allocation. If the size of a ulong is 4 and you +// set this flag to 16, the minimal size of an allocation +// will be 4 * 2 * 16 = 128 bytes +// If you have a lot of small allocations, keep this value +// low to conserve memory. If you have mostly large +// allocations, it is best to make it higher, to avoid +// fragmentation. +// +// Notes: +// 1. This memory manager is *not thread safe*. Use it only +// for single thread/task applications. +// + +#define DEBUG_MEMMGR_SUPPORT_STATS 1 + +#define POOL_SIZE 8 * 1024 +#define MIN_POOL_ALLOC_QUANTAS 16 + + +typedef unsigned char byte; +typedef unsigned long ulong; + + + +// Initialize the memory manager. This function should be called +// only once in the beginning of the program. +// +void memmgr_init(); + +// 'malloc' clone +// +void* memmgr_alloc(ulong nbytes); + +// 'free' clone +// +void memmgr_free(void* ap); + +// Prints statistics about the current state of the memory +// manager +// +void memmgr_print_stats(); + + +#endif // MEMMGR_H diff --git a/examples/c_files/year.c b/examples/c_files/year.c index c0f583d..12c4a33 100644 --- a/examples/c_files/year.c +++ b/examples/c_files/year.c @@ -1,53 +1,53 @@ -#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-void convert(int thousands, int hundreds, int tens, int ones)
-{
-char *num[] = {"", "One", "Two", "Three", "Four", "Five", "Six",
- "Seven", "Eight", "Nine"};
-
-char *for_ten[] = {"", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty",
- "Seventy", "Eighty", "Ninty"};
-
-char *af_ten[] = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen",
- "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Ninteen"};
-
- printf("\nThe year in words is:\n");
-
- printf("%s thousand", num[thousands]);
- if (hundreds != 0)
- printf(" %s hundred", num[hundreds]);
-
- if (tens != 1)
- printf(" %s %s", for_ten[tens], num[ones]);
- else
- printf(" %s", af_ten[ones]);
-}
-
-
-int main()
-{
-int year;
-int n1000, n100, n10, n1;
-
- printf("\nEnter the year (4 digits): ");
- scanf("%d", &year);
-
- if (year > 9999 || year < 1000)
- {
- printf("\nError !! The year must contain 4 digits.");
- exit(EXIT_FAILURE);
- }
-
- n1000 = year/1000;
- n100 = ((year)%1000)/100;
- n10 = (year%100)/10;
- n1 = ((year%10)%10);
-
- convert(n1000, n100, n10, n1);
-
-return 0;
-}
-
-
+#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +void convert(int thousands, int hundreds, int tens, int ones) +{ +char *num[] = {"", "One", "Two", "Three", "Four", "Five", "Six", + "Seven", "Eight", "Nine"}; + +char *for_ten[] = {"", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", + "Seventy", "Eighty", "Ninty"}; + +char *af_ten[] = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", + "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Ninteen"}; + + printf("\nThe year in words is:\n"); + + printf("%s thousand", num[thousands]); + if (hundreds != 0) + printf(" %s hundred", num[hundreds]); + + if (tens != 1) + printf(" %s %s", for_ten[tens], num[ones]); + else + printf(" %s", af_ten[ones]); +} + + +int main() +{ +int year; +int n1000, n100, n10, n1; + + printf("\nEnter the year (4 digits): "); + scanf("%d", &year); + + if (year > 9999 || year < 1000) + { + printf("\nError !! The year must contain 4 digits."); + exit(EXIT_FAILURE); + } + + n1000 = year/1000; + n100 = ((year)%1000)/100; + n10 = (year%100)/10; + n1 = ((year%10)%10); + + convert(n1000, n100, n10, n1); + +return 0; +} + + diff --git a/examples/explore_ast.py b/examples/explore_ast.py index 24df79f..392e78a 100644 --- a/examples/explore_ast.py +++ b/examples/explore_ast.py @@ -1,166 +1,166 @@ -#-----------------------------------------------------------------
-# pycparser: explore_ast.py
-#
-# This example demonstrates how to "explore" the AST created by
-# pycparser to understand its structure. The AST is a n-nary tree
-# of nodes, each node having several children, each with a name.
-# Just read the code, and let the comments guide you. The lines
-# beginning with #~ can be uncommented to print out useful
-# information from the AST.
-# It helps to have the pycparser/_c_ast.cfg file in front of you.
-#
-# Copyright (C) 2008-2011, Eli Bendersky
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast
-
-# This is some C source to parse. Note that pycparser must begin
-# at the top level of the C file, i.e. with either declarations
-# or function definitions (this is called "external declarations"
-# in C grammar lingo)
-#
-# Also, a C parser must have all the types declared in order to
-# build the correct AST. It doesn't matter what they're declared
-# to, so I've inserted the dummy typedef in the code to let the
-# parser know Hash and Node are types. You don't need to do it
-# when parsing real, correct C code.
-#
-text = r"""
- typedef int Node, Hash;
-
- void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
- {
- unsigned int i;
-
- if (hash == NULL || hash->heads == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- PrintFunc(temp->entry->key, temp->entry->value);
- temp = temp->next;
- }
- }
- }
-"""
-
-# Create the parser and ask to parse the text. parse() will throw
-# a ParseError if there's an error in the code
-#
-parser = c_parser.CParser()
-ast = parser.parse(text, filename='<none>')
-
-# Uncomment the following line to see the AST in a nice, human
-# readable way. show() is the most useful tool in exploring ASTs
-# created by pycparser. See the c_ast.py file for the options you
-# can pass it.
-#
-#~ ast.show()
-
-# OK, we've seen that the top node is FileAST. This is always the
-# top node of the AST. Its children are "external declarations",
-# and are stored in a list called ext[] (see _c_ast.cfg for the
-# names and types of Nodes and their children).
-# As you see from the printout, our AST has two Typedef children
-# and one FuncDef child.
-# Let's explore FuncDef more closely. As I've mentioned, the list
-# ext[] holds the children of FileAST. Since the function
-# definition is the third child, it's ext[2]. Uncomment the
-# following line to show it:
-#
-#~ ast.ext[2].show()
-
-# A FuncDef consists of a declaration, a list of parameter
-# declarations (for K&R style function definitions), and a body.
-# First, let's examine the declaration.
-#
-function_decl = ast.ext[2].decl
-
-# function_decl, like any other declaration, is a Decl. Its type child
-# is a FuncDecl, which has a return type and arguments stored in a
-# ParamList node
-#~ function_decl.type.show()
-#~ function_decl.type.args.show()
-
-# The following displays the name and type of each argument:
-#
-#~ for param_decl in function_decl.type.args.params:
- #~ print('Arg name: %s' % param_decl.name)
- #~ print('Type:')
- #~ param_decl.type.show(offset=6)
-
-# The body is of FuncDef is a Compound, which is a placeholder for a block
-# surrounded by {} (You should be reading _c_ast.cfg parallel to this
-# explanation and seeing these things by your own eyes).
-#
-# Let's see the block's declarations:
-#
-function_body = ast.ext[2].body
-
-# The following displays the declarations and statements in the function
-# body
-#
-#~ for decl in function_body.block_items:
- #~ decl.show()
-
-# We can see a single variable declaration, i, declared to be a simple type
-# declaration of type 'unsigned int', followed by statements.
-#
-
-# block_items is a list, so the third element is the For statement:
-#
-for_stmt = function_body.block_items[2]
-#~ for_stmt.show()
-
-# As you can see in _c_ast.cfg, For's children are 'init, cond,
-# next' for the respective parts of the 'for' loop specifier,
-# and stmt, which is either a single stmt or a Compound if there's
-# a block.
-#
-# Let's dig deeper, to the while statement inside the for loop:
-#
-while_stmt = for_stmt.stmt.block_items[1]
-#~ while_stmt.show()
-
-# While is simpler, it only has a condition node and a stmt node.
-# The condition:
-#
-while_cond = while_stmt.cond
-#~ while_cond.show()
-
-# Note that it's a BinaryOp node - the basic constituent of
-# expressions in our AST. BinaryOp is the expression tree, with
-# left and right nodes as children. It also has the op attribute,
-# which is just the string representation of the operator.
-#
-#~ print while_cond.op
-#~ while_cond.left.show()
-#~ while_cond.right.show()
-
-#
-# That's if for the example. I hope you now see how easy it is to
-# explore the AST created by pycparser. Although on the surface it
-# is quite complex and has a lot of node types, this is the
-# inherent complexity of the C language every parser/compiler
-# designer has to cope with.
-# Using the tools provided by the c_ast package it's easy to
-# explore the structure of AST nodes and write code that processes
-# them.
-# Specifically, see the cdecl.py example for a non-trivial
-# demonstration of what you can do by recursively going through
-# the AST.
-#
-
-
+#----------------------------------------------------------------- +# pycparser: explore_ast.py +# +# This example demonstrates how to "explore" the AST created by +# pycparser to understand its structure. The AST is a n-nary tree +# of nodes, each node having several children, each with a name. +# Just read the code, and let the comments guide you. The lines +# beginning with #~ can be uncommented to print out useful +# information from the AST. +# It helps to have the pycparser/_c_ast.cfg file in front of you. +# +# Copyright (C) 2008-2011, Eli Bendersky +# License: BSD +#----------------------------------------------------------------- +from __future__ import print_function +import sys + +# This is not required if you've installed pycparser into +# your site-packages/ with setup.py +# +sys.path.extend(['.', '..']) + +from pycparser import c_parser, c_ast + +# This is some C source to parse. Note that pycparser must begin +# at the top level of the C file, i.e. with either declarations +# or function definitions (this is called "external declarations" +# in C grammar lingo) +# +# Also, a C parser must have all the types declared in order to +# build the correct AST. It doesn't matter what they're declared +# to, so I've inserted the dummy typedef in the code to let the +# parser know Hash and Node are types. You don't need to do it +# when parsing real, correct C code. +# +text = r""" + typedef int Node, Hash; + + void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*)) + { + unsigned int i; + + if (hash == NULL || hash->heads == NULL) + return; + + for (i = 0; i < hash->table_size; ++i) + { + Node* temp = hash->heads[i]; + + while (temp != NULL) + { + PrintFunc(temp->entry->key, temp->entry->value); + temp = temp->next; + } + } + } +""" + +# Create the parser and ask to parse the text. parse() will throw +# a ParseError if there's an error in the code +# +parser = c_parser.CParser() +ast = parser.parse(text, filename='<none>') + +# Uncomment the following line to see the AST in a nice, human +# readable way. show() is the most useful tool in exploring ASTs +# created by pycparser. See the c_ast.py file for the options you +# can pass it. +# +#~ ast.show() + +# OK, we've seen that the top node is FileAST. This is always the +# top node of the AST. Its children are "external declarations", +# and are stored in a list called ext[] (see _c_ast.cfg for the +# names and types of Nodes and their children). +# As you see from the printout, our AST has two Typedef children +# and one FuncDef child. +# Let's explore FuncDef more closely. As I've mentioned, the list +# ext[] holds the children of FileAST. Since the function +# definition is the third child, it's ext[2]. Uncomment the +# following line to show it: +# +#~ ast.ext[2].show() + +# A FuncDef consists of a declaration, a list of parameter +# declarations (for K&R style function definitions), and a body. +# First, let's examine the declaration. +# +function_decl = ast.ext[2].decl + +# function_decl, like any other declaration, is a Decl. Its type child +# is a FuncDecl, which has a return type and arguments stored in a +# ParamList node +#~ function_decl.type.show() +#~ function_decl.type.args.show() + +# The following displays the name and type of each argument: +# +#~ for param_decl in function_decl.type.args.params: + #~ print('Arg name: %s' % param_decl.name) + #~ print('Type:') + #~ param_decl.type.show(offset=6) + +# The body is of FuncDef is a Compound, which is a placeholder for a block +# surrounded by {} (You should be reading _c_ast.cfg parallel to this +# explanation and seeing these things by your own eyes). +# +# Let's see the block's declarations: +# +function_body = ast.ext[2].body + +# The following displays the declarations and statements in the function +# body +# +#~ for decl in function_body.block_items: + #~ decl.show() + +# We can see a single variable declaration, i, declared to be a simple type +# declaration of type 'unsigned int', followed by statements. +# + +# block_items is a list, so the third element is the For statement: +# +for_stmt = function_body.block_items[2] +#~ for_stmt.show() + +# As you can see in _c_ast.cfg, For's children are 'init, cond, +# next' for the respective parts of the 'for' loop specifier, +# and stmt, which is either a single stmt or a Compound if there's +# a block. +# +# Let's dig deeper, to the while statement inside the for loop: +# +while_stmt = for_stmt.stmt.block_items[1] +#~ while_stmt.show() + +# While is simpler, it only has a condition node and a stmt node. +# The condition: +# +while_cond = while_stmt.cond +#~ while_cond.show() + +# Note that it's a BinaryOp node - the basic constituent of +# expressions in our AST. BinaryOp is the expression tree, with +# left and right nodes as children. It also has the op attribute, +# which is just the string representation of the operator. +# +#~ print while_cond.op +#~ while_cond.left.show() +#~ while_cond.right.show() + +# +# That's if for the example. I hope you now see how easy it is to +# explore the AST created by pycparser. Although on the surface it +# is quite complex and has a lot of node types, this is the +# inherent complexity of the C language every parser/compiler +# designer has to cope with. +# Using the tools provided by the c_ast package it's easy to +# explore the structure of AST nodes and write code that processes +# them. +# Specifically, see the cdecl.py example for a non-trivial +# demonstration of what you can do by recursively going through +# the AST. +# + + diff --git a/examples/func_calls.py b/examples/func_calls.py index f8ff731..fe30181 100644 --- a/examples/func_calls.py +++ b/examples/func_calls.py @@ -1,51 +1,51 @@ -#-----------------------------------------------------------------
-# pycparser: func_defs.py
-#
-# Using pycparser for printing out all the calls of some function
-# in a C file.
-#
-# Copyright (C) 2008-2011, Eli Bendersky
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast, parse_file
-
-
-# A visitor with some state information (the funcname it's
-# looking for)
-#
-class FuncCallVisitor(c_ast.NodeVisitor):
+#----------------------------------------------------------------- +# pycparser: func_defs.py +# +# Using pycparser for printing out all the calls of some function +# in a C file. +# +# Copyright (C) 2008-2011, Eli Bendersky +# License: BSD +#----------------------------------------------------------------- +from __future__ import print_function +import sys + +# This is not required if you've installed pycparser into +# your site-packages/ with setup.py +# +sys.path.extend(['.', '..']) + +from pycparser import c_parser, c_ast, parse_file + + +# A visitor with some state information (the funcname it's +# looking for) +# +class FuncCallVisitor(c_ast.NodeVisitor): def __init__(self, funcname): - self.funcname = funcname
-
- def visit_FuncCall(self, node):
- if node.name.name == self.funcname:
- print('%s called at %s' % (
- self.funcname, node.name.coord))
-
-
-def show_func_calls(filename, funcname):
- ast = parse_file(filename, use_cpp=True)
- v = FuncCallVisitor(funcname)
- v.visit(ast)
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 2:
- filename = sys.argv[1]
- func = sys.argv[2]
- else:
- filename = 'c_files/hash.c'
- func = 'malloc'
-
- show_func_calls(filename, func)
-
-
-
+ self.funcname = funcname + + def visit_FuncCall(self, node): + if node.name.name == self.funcname: + print('%s called at %s' % ( + self.funcname, node.name.coord)) + + +def show_func_calls(filename, funcname): + ast = parse_file(filename, use_cpp=True) + v = FuncCallVisitor(funcname) + v.visit(ast) + + +if __name__ == "__main__": + if len(sys.argv) > 2: + filename = sys.argv[1] + func = sys.argv[2] + else: + filename = 'c_files/hash.c' + func = 'malloc' + + show_func_calls(filename, func) + + + diff --git a/examples/func_defs.py b/examples/func_defs.py index c42d5c0..5f44b4c 100644 --- a/examples/func_defs.py +++ b/examples/func_defs.py @@ -1,51 +1,51 @@ -#-----------------------------------------------------------------
-# pycparser: func_defs.py
-#
-# Using pycparser for printing out all the functions defined in a
-# C file.
-#
-# This is a simple example of traversing the AST generated by
-# pycparser.
-#
-# Copyright (C) 2008-2011, Eli Bendersky
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast, parse_file
-
-
-# A simple visitor for FuncDef nodes that prints the names and
-# locations of function definitions.
-#
-class FuncDefVisitor(c_ast.NodeVisitor):
- def visit_FuncDef(self, node):
- print('%s at %s' % (node.decl.name, node.decl.coord))
-
-
-def show_func_defs(filename):
- # Note that cpp is used. Provide a path to your own cpp or
- # make sure one exists in PATH.
+#----------------------------------------------------------------- +# pycparser: func_defs.py +# +# Using pycparser for printing out all the functions defined in a +# C file. +# +# This is a simple example of traversing the AST generated by +# pycparser. +# +# Copyright (C) 2008-2011, Eli Bendersky +# License: BSD +#----------------------------------------------------------------- +from __future__ import print_function +import sys + +# This is not required if you've installed pycparser into +# your site-packages/ with setup.py +# +sys.path.extend(['.', '..']) + +from pycparser import c_parser, c_ast, parse_file + + +# A simple visitor for FuncDef nodes that prints the names and +# locations of function definitions. +# +class FuncDefVisitor(c_ast.NodeVisitor): + def visit_FuncDef(self, node): + print('%s at %s' % (node.decl.name, node.decl.coord)) + + +def show_func_defs(filename): + # Note that cpp is used. Provide a path to your own cpp or + # make sure one exists in PATH. # - ast = parse_file(filename, use_cpp=True)
-
- v = FuncDefVisitor()
- v.visit(ast)
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 1:
- filename = sys.argv[1]
- else:
- filename = 'c_files/memmgr.c'
-
- show_func_defs(filename)
-
-
-
+ ast = parse_file(filename, use_cpp=True) + + v = FuncDefVisitor() + v.visit(ast) + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + else: + filename = 'c_files/memmgr.c' + + show_func_defs(filename) + + + |