k-dot-p 0.1

shapes.c++

Go to the documentation of this file.
00001 /*
00002 
00003 
00004     Copyright (C) 2009 Joseph Pingenot
00005 
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU Affero General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU Affero General Public License for more details.
00015 
00016     You should have received a copy of the GNU Affero General Public License
00017     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <glib.h>
00025 #include <libmodelxx/shapes.h++>
00026 #include <libmodelxx/key_values.h++>
00027 
00028 using namespace ::kdotp::libmodelxx::postprocessing;
00029 
00030 namespace kdotp {
00031   namespace libmodelxx {
00032     namespace grid {
00033 
00034       struct shape_block* make_block_from_shape(struct shape *s, int dim, bool abs) {
00035   shape_block* b = (struct shape_block*)malloc(sizeof(struct shape_block));
00036   b->op = LEAF;
00037   if(abs) {
00038     b->type = ABSBLOCK;
00039   }else{
00040     b->type = BLOCK;
00041   }
00042   b->generic = false;
00043   b->center = (struct function_exp*)malloc(sizeof(struct function_exp));
00044   if((b->center == NULL)) {
00045     if(abs) {
00046       fprintf(stderr, "kdotp::libmodelxx::grid::make_block_from_shape: ERROR allocating memory for first corner coordinate\n");
00047     }else{
00048       fprintf(stderr, "kdotp::libmodelxx::grid::make_block_from_shape: ERROR allocating memory for center\n");
00049     }
00050     exit(15);
00051   }
00052   b->L = (struct function_exp*)malloc(sizeof(struct function_exp));
00053   if((b->L == NULL)) {
00054     if(abs) {
00055       fprintf(stderr, "kdotp::libmodelxx::grid::make_block_from_shape: ERROR allocating memory for second corner coordinate\n");
00056     }else{
00057       fprintf(stderr, "kdotp::libmodelxx::grid::make_block_from_shape: ERROR allocating memory for L\n");
00058     }
00059     exit(16);
00060   }
00061   /*There should be two vectors: the center of the box, and the width
00062    *  of the box (vector from one corner to the other)
00063    *As a convenience, the vectors may be scalars if there is only
00064    *  one dimension
00065    */
00066   GString* str = g_string_new("");
00067   GList *l = s->descriptor;
00068   if(l == NULL) {
00069     fprintf(stderr, "kdotp::libmodelxx::grid::make_global_from_shape: ERROR: insufficient shape description was given to a \"block\" or \"absblock\" shape, which takes only two vectors. This superfluous information will be ignored.\n");
00070     exit(17);
00071   }
00072   b->center = (struct function_exp*)(l->data);
00073   function_print_tree(b->center, &str, 1);
00074   fprintf(stderr, "b->center:\n%s\n", str->str);
00075   g_string_free(str, TRUE);
00076   l = l->next;
00077   if(l == NULL) {
00078     fprintf(stderr, "kdotp::libmodelxx::grid::make_global_from_shape: ERROR: insufficient shape description was given to a \"block\" or \"absblock\" shape, which takes only two vectors. This superfluous information will be ignored.\n");    exit(18);
00079   }
00080   b->L = (struct function_exp*)(l->data);
00081   str = g_string_new("");
00082   function_print_tree(b->L, &str, 1);
00083   fprintf(stderr, "b->L:\n%s\n", str->str);
00084   g_string_free(str, TRUE);
00085   l=l->next;
00086   if(l != NULL) {
00087     fprintf(stderr, "kdotp::libmodelxx::grid::make_global_from_shape: WARNING: extra shape description was given to a \"block\" shape, which takes only two vectors. This superfluous information will be ignored.\n");
00088   }
00089   return b;
00090       }
00091       struct shape_global* make_global_from_shape(struct shape *s, int dim) {
00092   shape_global* g = (struct shape_global*)malloc(sizeof(struct shape_global));
00093   g->op = LEAF;
00094   g->type = GLOBAL;
00095   g->generic = false;
00096   if((s->descriptor) != NULL) {
00097     fprintf(stderr, "kdotp::libmodelxx::grid::make_global_from_shape: WARNING: a shape description was given to a \"global\" shape, which takes no description. This superfluous information will be ignored.\n");
00098   }
00099   return g;
00100       }
00101 
00102       /**
00103        *\note Algorithm:
00104        *1) Recurse on non-leaf nodes
00105        *2) Set l, r from recursion.
00106        *3) If leaf, set the respective type using above helper function.
00107        *\note caller MUST set the return value; you may just have a leaf node.
00108        */
00109       struct shape_tree* postprocess_shape_tree(struct shape_tree* st, int dim) {
00110   /*Simple bounce for NULL links.*/
00111   if(st == NULL) return NULL;
00112   if(st->op != LEAF) {
00113     if(st->l == NULL){
00114       fprintf(stderr, "kdotp::libmodelxx::grid::postprocess_shape_tree: left subtree of a non-LEAF shape tree node should never be NULL, but is! (op is %d)\n", st->op);
00115       return NULL;
00116     }
00117     if(((st->l) = postprocess_shape_tree(st->l, dim)) != NULL) {
00118       /*If this was already NULL, we're fine.*/
00119       if((st->r == NULL) || (((st->r) = postprocess_shape_tree(st->r, dim)) != NULL)) {
00120         return st;
00121       }else{
00122         fprintf(stderr, "kdotp::libmodelxx::grid::postprocess_shape_tree: got NULL postprocessing right subtree (op is %d)\n", st->op);
00123       }
00124     }else{
00125       fprintf(stderr, "kdotp::libmodelxx::grid::postprocess_shape_tree: got NULL postprocessing left subtree (op is %d)\n", st->op);
00126     }
00127     /*If we get to here, one or the other of the ones failed.*/
00128     return NULL;
00129   }
00130   /*This will only execute for leaf nodes.*/
00131   struct shape* s = (struct shape*)st;
00132   if(!(s->generic)) {
00133     fprintf(stderr, "kdotp::libmodelxx::grid::postprocess_shape_tree: WARNING shape is not generic, although it's expected to be!\n");
00134     /*For some reason, this shape has already been
00135      *postprocessed.  Just return it, then.
00136      */
00137     return st;
00138   }
00139   struct shape* n = NULL;
00140   switch (s->type) {
00141   case BLOCK:
00142     n = (struct shape*)make_block_from_shape(s, dim, false);
00143     break;
00144   case ABSBLOCK:
00145     n = (struct shape*)make_block_from_shape(s, dim, true);
00146     break;
00147   case GLOBAL:
00148     n = (struct shape*)make_global_from_shape(s, dim);
00149     break;
00150   default:
00151     fprintf(stderr, "kdotp::libmodelxx::grid::process_shape_tree: ERROR unrecognized shape type (numeric: %d)\n", s->type);
00152     return NULL;
00153   }
00154   shape_free(s);
00155   return (struct shape_tree*)n;
00156       }
00157 
00158       void shape_block_free(struct shape_block *b) {
00159   free_function(b->center);
00160   free_function(b->L);
00161   free(b);
00162       }
00163 
00164       void shape_global_free(struct shape_global *b) {
00165   free(b);
00166       }
00167 
00168 
00169       void shape_free(struct shape *s) {
00170   /*Free the value list.*/
00171   GList* l;
00172   if(s->generic){
00173     /*The functions are moved over to the new structure; just free the list.*/
00174     g_list_free(s->descriptor);
00175   }else{
00176     switch(s->type){
00177     case GLOBAL:
00178       shape_global_free((struct shape_global*)s);
00179       break;
00180     case BLOCK:
00181       shape_block_free((struct shape_block*)s);
00182       break;
00183     case ABSBLOCK:
00184       shape_block_free((struct shape_block*)s);
00185       break;
00186     default:
00187       fprintf(stderr, "kdotp::libmodelxx::grid::shape_free: didn't recognize non-generic shape type (numeric %d)\n", s->type);
00188     }
00189   }
00190   free(s);
00191       }
00192 
00193       void shape_tree_free(struct shape_tree *st) {
00194   if(st == NULL) return;
00195   if(st->op != LEAF) {
00196     shape_tree_free(st->l);
00197     shape_tree_free(st->r);
00198   }else{
00199     shape_free((struct shape*)st);
00200   }
00201       }
00202 
00203       enum shape_type get_shape_from_identifier(const char* identifier) {
00204   if(!g_ascii_strcasecmp(identifier, "block")){
00205     return BLOCK;
00206   }else if(!g_ascii_strcasecmp(identifier, "absblock")){
00207     return ABSBLOCK;
00208   }else if(!g_ascii_strcasecmp(identifier, "global")){
00209     return GLOBAL;
00210   }
00211   return INVALID;
00212       }
00213 
00214 
00215       void get_string_from_shape_type(char** str, enum shape_type t) {
00216         GString *s = NULL;
00217   switch(t) {
00218   case INVALID:
00219     s = g_string_new("invalid");
00220     break;
00221   case BLOCK:
00222     s = g_string_new("block");
00223     break;
00224   case ABSBLOCK:
00225     s = g_string_new("absblock");
00226     break;
00227   case GLOBAL:
00228     s = g_string_new("global");
00229     break;
00230   default:
00231     s = g_string_new("unkdnown(");
00232     g_string_append_printf(s, "%d)", t);
00233   }
00234   *str = s->str;
00235   g_string_free(s, FALSE);
00236       }
00237 
00238 
00239     }
00240   }
00241 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines