aboutsummaryrefslogtreecommitdiff
path: root/system/kernel/pdp_type.c_old
diff options
context:
space:
mode:
Diffstat (limited to 'system/kernel/pdp_type.c_old')
-rw-r--r--system/kernel/pdp_type.c_old542
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;
-
-
-
-}