diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2005-12-15 07:26:47 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2005-12-15 07:26:47 +0000 |
commit | 37b6643df2df7d784a31ca73f7bb90dc109c2401 (patch) | |
tree | a8664e5adcfcb60cae136063d627549ecb76619b /system/kernel/pdp_type.c_old | |
parent | c50ce0e0217ea07e2d450add2ab29cecea66fa96 (diff) |
removing PDP source (except debian files) before import of PDP 0.12.4
svn path=/trunk/externals/pdp/; revision=4217
Diffstat (limited to 'system/kernel/pdp_type.c_old')
-rw-r--r-- | system/kernel/pdp_type.c_old | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/system/kernel/pdp_type.c_old b/system/kernel/pdp_type.c_old deleted file mode 100644 index 4e42d53..0000000 --- a/system/kernel/pdp_type.c_old +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Pure Data Packet system implementation. : code for handling different packet types - * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* this file contains type handling routines - note: pd symbols are used for type identification - for porting to other hosts, i suggest reimplementing t_pdp_symbol */ - -// debug - -#include <fnmatch.h> -#include <stdarg.h> -#include <string.h> -#include <pthread.h> -#include "pdp.h" - -/* - - - -*/ - - -#define D if (0) - - -static t_pdp_conversion *conversion_list; - -#define CACHE_SIZE 32 -static t_pdp_conversion *cached_conversion_list_start; -static t_pdp_conversion cached_conversion_array[CACHE_SIZE]; - -/* mutex */ -static pthread_mutex_t pdp_hash_mutex; -static pthread_mutex_t pdp_conversion_mutex; -static pthread_mutex_t pdp_cache_mutex; - -#define HASHSIZE 1024 -static t_pdp_symbol *pdp_symhash[HASHSIZE]; - - -/* shamelessly copied from pd src and made thread safe */ -t_pdp_symbol *_pdp_dogensym(char *s, t_pdp_symbol *oldsym) -{ - t_pdp_symbol **sym1, *sym2; - unsigned int hash1 = 0, hash2 = 0; - int length = 0; - char *s2 = s; - while (*s2) - { - hash1 += *s2; - hash2 += hash1; - length++; - s2++; - } - sym1 = pdp_symhash + (hash2 & (HASHSIZE-1)); - - /* lock hash */ - pthread_mutex_lock(&pdp_hash_mutex); - - while (sym2 = *sym1) - { - if (!strcmp(sym2->s_name, s)) goto gotit; - sym1 = &sym2->s_next; - } - if (oldsym) sym2 = oldsym; - else - { - sym2 = (t_pdp_symbol *)pdp_alloc(sizeof(*sym2)); - sym2->s_name = pdp_alloc(length+1); - _pdp_symbol_clear_namespaces(sym2); - sym2->s_next = 0; - strcpy(sym2->s_name, s); - } - *sym1 = sym2; - - gotit: - - /* unlock hash */ - pthread_mutex_unlock(&pdp_hash_mutex); - return (sym2); -} - -t_pdp_symbol *pdp_gensym(char *s) -{ - return(_pdp_dogensym(s, 0)); -} - -/* convert a type to a list */ -t_pdp_list *pdp_type_to_list(t_pdp_symbol *type) -{ - char *c = type->s_name; - char *lastname = c; - char tmp[100]; - int n = 0; - t_pdp_list *l = pdp_list_new(0); - - while(*c){ - if (*c == '/'){ - strncpy(tmp, lastname, n); - tmp[n] = 0; - pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(tmp)); - c++; - lastname = c; - n = 0; - } - else{ - c++; - n++; - } - } - pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(lastname)); - - return l; -} - - -/* get the description symbol. this includes some compat transition stuff with a warning */ -t_pdp_symbol *pdp_packet_get_description(int packet) -{ - t_pdp *header = pdp_packet_header(packet); - - if (!header) return pdp_gensym("invalid"); - else if (!header->desc){ - /* if description is not defined, try to reconstruct it (for backwards compat) */ - if (header->type == PDP_IMAGE){ - post("FIXME: pdp_type_get_description: packet %d has no description. using workaround.", packet); - return pdp_packet_image_get_description(packet); - } - else - return pdp_gensym("unknown"); - } - else return header->desc; -} - - - -/* this runs a conversion program */ -int _pdp_type_run_conversion_program(t_pdp_conversion_program *program, - int packet, t_pdp_symbol *dest_template) -{ - /* run a conversion program: - treat the source packet as readonly, and cleanup intermediates, such - that the net result is the production of a new packet, with the - source packet intact. */ - - int p, tmp; - - D post("DEBUG: _pdp_type_run_conversion_program: program = %x", program); - - // run the first line of the program - D post("DEBUG: _pdp_type_run_conversion_program: method = %x", *program); - p = (*program->method)(packet, dest_template); - D post("DEBUG: _pdp_type_run_conversion_program: packet returned = %d, type = %s", p, pdp_packet_get_description(p)->s_name); - - // run the remaining lines + cleanup intermediates - for (program = program->next; program ; program = program->next){ - D post("DEBUG: _pdp_type_run_conversion_program: next method ptr = %x", *program->method); - tmp = (*program->method)(p, dest_template); - pdp_packet_mark_unused(p); - p = tmp; - } - return p; -} - - -/* find a conversion program */ -t_pdp_conversion_program * -_pdp_type_find_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern) -{ - t_pdp_conversion *c; - t_pdp_conversion_program *retval = 0; - - /* lock conversion list */ - pthread_mutex_lock(&pdp_conversion_mutex); - - for (c = conversion_list; c; c=c->next){ - /* can be a wildcard match */ - if (pdp_type_description_match(src_pattern, c->src_pattern) && - pdp_type_description_match(dst_pattern, c->dst_pattern)) { - /* found a program */ - D post("DEBUG: _pdp_type_find_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name); - retval = c->program; - goto gotit; - } - } - - /* no conversion program was found */ - retval = 0; - gotit: - - /* lock conversion list */ - pthread_mutex_unlock(&pdp_conversion_mutex); - return retval; -} - -/* find a cached conversion program */ -t_pdp_conversion_program * -_pdp_type_find_cached_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern) -{ - t_pdp_conversion *c; - t_pdp_conversion_program *retval = 0; - - /* lock cached list */ - pthread_mutex_lock(&pdp_cache_mutex); - - for (c = cached_conversion_list_start; c; c=c->next){ - /* must be exact match */ - if ((src_pattern == c->src_pattern) && - (dst_pattern == c->dst_pattern)) { - /* found a program */ - D post("DEBUG: _pdp_type_find_cached_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name); - retval = c->program; - goto gotit; - } - } - - retval = 0; - - gotit: - - /* un lock cached list */ - pthread_mutex_unlock(&pdp_cache_mutex); - - /* no conversion program was found */ - return retval; -} - - -/* conversion program manipulations */ -void pdp_conversion_program_free(t_pdp_conversion_program *program) -{ - t_pdp_conversion_program *p = 0; - while (program) { - p = program; - program = program->next; - pdp_dealloc (p); - } -} - -/* debug print */ -void _pdp_conversion_program_print(t_pdp_conversion_program *program) -{ - D post("DEBUG: conversion program: %x", program); - while(program){ - D post("DEBUG: method: %x", program->method); - program = program->next; - } -} - -t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...) -{ - t_pdp_conversion_program head; - t_pdp_conversion_program *p = &head; - t_pdp_conversion_method m = method; - va_list ap; - - D post("DEBUG: pdp_conversion_program_new:BEGIN"); - - p = p->next = (t_pdp_conversion_program *)pdp_alloc(sizeof(*p)); - p->method = m; - va_start(ap, method); - while (m = va_arg(ap, t_pdp_conversion_method)){ - p = p->next = (t_pdp_conversion_program *)pdp_alloc(sizeof(*p)); - p->method = m; - } - p->next = 0; // terminate list - va_end(ap); - - D post("DEBUG: pdp_conversion_program_new:END"); - D _pdp_conversion_program_print(head.next); - - return head.next; -} - -t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program) -{ - t_pdp_conversion_program head; - t_pdp_conversion_program *p = &head; - - for(;program; program=program->next){ - p = p->next = (t_pdp_conversion_program *)pdp_alloc(sizeof(*p)); - p->method = program->method; - } - p->next = 0; - return head.next; -} - -void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail) -{ - t_pdp_conversion_program *p = program; - - //D post("DEBUG: pdp_conversion_program_add:BEGIN"); - - - while (p->next) p = p->next; - p->next = pdp_conversion_program_copy(tail); - - //D post("DEBUG: pdp_conversion_program_add:END"); - -} - -/* conversion registration */ -void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program) -{ - t_pdp_conversion head; - t_pdp_conversion *c = &head; - - /* lock conversion list */ - pthread_mutex_lock(&pdp_conversion_mutex); - - head.next = conversion_list; - - while (c->next) c=c->next; // add a new one to the end - c = c->next = (t_pdp_conversion *)pdp_alloc(sizeof(*c)); - c->src_pattern = src_pattern; - c->dst_pattern = dst_pattern; - c->program = program; - c->next = 0; - - conversion_list = head.next; - - /* unlock conversion list */ - pthread_mutex_unlock(&pdp_conversion_mutex); - -} - -/* register a cached conversion */ -void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program) -{ - - t_pdp_conversion *save, *c, *c2; - - /* unlock cahed conversion list */ - pthread_mutex_lock(&pdp_cache_mutex); - - c2 = save = cached_conversion_list_start; - while (c2->next->next) c2 = c2->next; - c = c2->next; - c2->next = 0; - if (c->program) pdp_conversion_program_free(c->program); - c->src_pattern = src_pattern; - c->dst_pattern = dst_pattern; - c->program = program; - c->next = save; - cached_conversion_list_start = c; - - /* unlock cached conversion list */ - pthread_mutex_unlock(&pdp_cache_mutex); -} - -/* convert a given packet to a certain type (template) */ -int _pdp_packet_convert(int packet, t_pdp_symbol *dest_template) -{ - t_pdp_symbol *type = pdp_packet_get_description(packet); - t_pdp_symbol *tmp_type = 0; - int tmp_packet = -1; - - t_pdp_conversion_program *program = 0; - t_pdp_conversion_program *program_last = 0; - t_pdp_conversion_program *program_tail = 0; - - /* check if there is a program in the cached list, if so run it */ - if (program = _pdp_type_find_cached_conversion_program(type, dest_template)) - return _pdp_type_run_conversion_program(program, packet, dest_template); - - /* if it is not cached, iteratively convert - and save program on top of cache list if a conversion path (program) was found */ - - // run first conversion that matches - program = pdp_conversion_program_copy(_pdp_type_find_conversion_program(type, dest_template)); - program_last = program; - if (!program){ - D post("DEBUG: pdp_type_convert: (1) can't convert %s to %s", type->s_name, dest_template->s_name); - return -1; - } - tmp_packet = _pdp_type_run_conversion_program(program, packet, dest_template); - tmp_type = pdp_packet_get_description(tmp_packet); - - // run more conversions if necessary, deleting intermediate packets - while (!pdp_type_description_match(tmp_type, dest_template)){ - int new_packet; - program_tail = _pdp_type_find_conversion_program(tmp_type, dest_template); - if (!program_tail){ - D post("DEBUG: pdp_type_convert: (2) can't convert %s to %s", tmp_type->s_name, dest_template->s_name); - pdp_packet_mark_unused(tmp_packet); - pdp_conversion_program_free(program); - return -1; - } - if (program_last == program_tail){ - post("ERROR: pdp_packet_convert: conversion loop detected"); - } - program_last = program_tail; - - pdp_conversion_program_add(program, program_tail); - new_packet = _pdp_type_run_conversion_program(program_tail, tmp_packet, dest_template); - pdp_packet_mark_unused(tmp_packet); - tmp_packet = new_packet; - tmp_type = pdp_packet_get_description(tmp_packet); - } - - // save the conversion program - pdp_type_register_cached_conversion(type, dest_template, program); - - // return resulting packet - return tmp_packet; - -} - -/* convert or copy ro */ -int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_template) -{ - t_pdp_symbol *type = pdp_packet_get_description(packet); - - /* if it is compatible, return a ro copy */ - if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_ro(packet); - - /* if not, convert to a new type */ - else return _pdp_packet_convert(packet, dest_template); -} - -/* convert or copy rw */ -int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_template) -{ - t_pdp_symbol *type = pdp_packet_get_description(packet); - - /* if it is compatible, just return a rw copy */ - if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_rw(packet); - - /* if not, convert to a new type */ - else return _pdp_packet_convert(packet, dest_template); -} - - -static void _setup_type_cache(t_pdp_symbol *s) -{ - t_pdp_list *l = pdp_type_to_list(s); - pthread_mutex_lock(&pdp_hash_mutex); //lock to prevent re-entry - if (!s->s_type){ - s->s_type = l; - l = 0; - } - pthread_mutex_unlock(&pdp_hash_mutex); - if (l) pdp_list_free(l); -} - -/* check if a type description fits a template - this function is symmetric */ -int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern) -{ - - -#if 1 - t_pdp_atom *ad, *ap; - t_pdp_symbol *wildcard = pdp_gensym("*"); - - /* same type -> match */ - if (description == pattern) return 1; - - /* use the description list stored in the symbol for comparison */ - if (!(description->s_type)) _setup_type_cache(description); - if (!(pattern->s_type)) _setup_type_cache(pattern); - - /* check size */ - if (description->s_type->elements != pattern->s_type->elements) return 0; - - /* compare symbols of type list */ - for(ad=description->s_type->first, ap=pattern->s_type->first; ad; ad=ad->next, ap=ap->next){ - if (ad->w.w_symbol == wildcard) continue; - if (ap->w.w_symbol == wildcard) continue; - if (ad->w.w_symbol != ap->w.w_symbol) return 0; /* difference and not a wildcard */ - } - - /* type templates match */ - return 1; - - -#else - int retval = 0; - if (description == pattern) retval = 1; - //else retval = (!fnmatch(pattern->s_name, description->s_name, FNM_FILE_NAME)); - - //hack: make a symmetric match symmetric by calling fnmatch a second time with reversed attributes - else retval = ((!fnmatch(pattern->s_name, description->s_name, FNM_FILE_NAME)) - ||(!fnmatch(description->s_name, pattern->s_name, FNM_FILE_NAME))); - - - D post("DEBUG: testing match between %s and %s: %s", description->s_name, pattern->s_name, retval ? "match" : "no match"); - - return retval; -#endif -} - - - - - -/* setup method */ -void pdp_type_setup(void) -{ - int i; - - // create mutexes - pthread_mutex_init(&pdp_hash_mutex, NULL); - pthread_mutex_init(&pdp_conversion_mutex, NULL); - pthread_mutex_init(&pdp_cache_mutex, NULL); - - // init hash - memset(pdp_symhash, 0, HASHSIZE * sizeof(t_pdp_symbol *)); - - // init conversion lists - conversion_list = 0; - for(i=0; i<CACHE_SIZE; i++){ - t_pdp_conversion *c = cached_conversion_array + i; - c->src_pattern = 0; - c->dst_pattern = 0; - c->program = 0; - c->next = c + 1; - } - cached_conversion_list_start = cached_conversion_array; - cached_conversion_array[CACHE_SIZE-1].next = 0; - - - -} |