Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

tree.c

00001  /*
00002   * plint/prog/tree.c : code blocks tree nodes handling
00003   * 
00004   * Time-stamp: <2003-01-08 21:09:45 gseba>
00005   * 
00006   * Copyright (C) Sebastian Glita, email: gseba@users.sourceforge.net
00007   * 
00008   * This file is part of plint.
00009   * 
00010   * plint is free software; you can  redistribute it and/or modify it under the
00011   * terms of the  GNU General Public License as published  by the Free Software
00012   * Foundation; either version 2, or (at your option) any later version.
00013   *
00014   * plint  is distributed  in the  hope  that it  will be  useful, but  WITHOUT
00015   * ANY  WARRANTY; without  even  the implied  warranty  of MERCHANTABILITY  or
00016   * FITNESS FOR A  PARTICULAR PURPOSE.  See the GNU  General Public License for
00017   * more details.
00018   * 
00019   * You should  have received a  copy of the  GNU General Public  License along
00020   * with  plint; see  the file  COPYING.  If  not, write  to the  Free Software
00021   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA USA.
00022   *
00023   */
00024 
00025 #pragma GCC dependency "Makefile" maybe some command line defines have changed
00026 
00027 #include "plint.h"
00028 #include "error.h"
00029 
00030 #include "data.h"
00031 #include "parse.h"
00032 #include "proc.h"
00033 
00034 #include "misc/file.h"
00035 #include "misc/sys.h"
00036 
00037 
00038 
00039 plint_tree_t plint_tree_new()
00040 {
00041   char const * filename;
00042 
00043 #ifdef PLINT_TMP_CHECK
00044   int fd;
00045   FILE * file;
00046   plint_tree_t p = 0;
00047 
00048   do
00049     fd = open(filename = plint_temp_new(), O_CREAT | O_RDWR | O_EXCL, S_IWUSR | S_IRUSR); /* test not to overwrite */ 
00050   while (fd < 0);
00051   close(fd);
00052 
00053   if ((file = plint_file_open(filename, "wt")))
00054     {
00055       NEW(p);
00056       p->level = plint->syn.level;
00057       p->srcfile = strndup(filename, PLINT_OUT_LEN);
00058       p->file = file;
00059     }
00060   else
00061     PLINT_ERROR(PLINT_ERR_TMP);
00062 
00063 #else
00064   plint_tree_t p;
00065 
00066   filename = plint_temp_new();
00067 
00068   NEW(p);
00069   p->level = plint->syn.level;
00070   p->srcfile = strndup(filename, PLINT_OUT_LEN);
00071   p->file = plint_file_open(filename, "wt");
00072 #endif
00073 
00074   p->prnt = 0;
00075   p->user = slot_create();
00076 
00077   return p;
00078 }
00079 
00080 static int prc_two(plint_tree_t p)
00081 {
00082   plint_proc.lup.sig = p->proc;
00083   return !!plint_proc_lup_sig(plint_proc.lup.ptr);
00084 }
00085 
00086 int plint_tree_open(plint_tree_t chld)
00087 {
00088   plint_tree_t prnt;
00089   register int two = 0, old = !!chld->prnt;
00090 
00091   prnt = plint_code.tree;
00092   if (!old)
00093     PLINT_MAP_TREE(NEW, chld->blk, chld);
00094 
00095   plint_proc.lup.ptr = plint_tree_non_ins(prnt);
00096   if (PLINT_TREE_ISINS(chld))                           /* it's an insertion, */
00097     {
00098       size_t i;
00099       if (!0
00100           && !PLINT_TREE_ISPRS(chld)                    /* already parsed, */
00101           && plint->tree.ins == PLINT_INS_INSERT        /* not included, but inserted */
00102           && !plint_ins.top->count)                     /* without any insert points in the subtree */
00103         for (i = 0; i < chld->nchlds; ++i)
00104           if (PLINT_TREE_ISPRC(chld->chlds[i]))
00105             if ((two = prc_two(chld->chlds[i])))
00106               break;
00107 
00108       chld->host_id = 1;
00109       chld->host.d = plint_tree_host(prnt);
00110     }
00111   else
00112     {
00113       if (PLINT_TREE_ISPRC(chld))/* checking if there are other procedures
00114                                     with the same name & arrity, at the same level */
00115         two = prc_two(chld);
00116 
00117       /* default host: inherited */
00118       chld->host_id = prnt->host_id;
00119       chld->host = prnt->host;
00120       if (PLINT_TREE_ISPRC(prnt)) /* direct if procedure */
00121         {
00122           chld->host_id = 1;
00123           chld->host.d = prnt;
00124         }
00125       else if (PLINT_TREE_ISINS(prnt)) /* indirect if insertion */
00126         {
00127           chld->host_id = 0;
00128           chld->host.i = &prnt->host.d;
00129         }
00130     }
00131 
00132   prnt->chlds = realloc(prnt->chlds, ++prnt->nchlds*sizeof(plint_tree_t));
00133   prnt->chlds[prnt->nchlds - 1] = chld;
00134   chld->prnt = prnt;
00135 
00136   PLINT_MAP_TREE(NEW_PRNT, chld->blk, chld);
00137 
00138   plint_code.tree = chld;
00139 
00140   PLINT_MAP_TREE(NEW_CHLD, prnt->blk, prnt);
00141 
00142   if (!old)
00143     {
00144       plint_eblk_t b;
00145       for (b = _PLINT_BLK_start; ++b < _PLINT_BLK_stop ;)
00146         PLINT_MAP_TREE(NEW_USER, b, chld);
00147     }
00148 
00149   plint_trace(block, 0);
00150 
00151   return !two;
00152 }
00153 
00154 void plint_tree_close()
00155 {
00156   plint_tree_t chld = plint_code.tree, prnt = chld->prnt;
00157 
00158   plint_trace(block, 1);
00159 
00160   if (PLINT_TREE_ISPRS(chld))
00161     {
00162       fprintf(chld->file, ";\n");
00163       plint_file_close(chld->file);
00164 
00165       if (PLINT_TREE_ISINS(chld)) /* keep it as read only,
00166                                      to insert it where & when
00167                                      it is required (not only now) */
00168         chld->file = plint_file_open(chld->srcfile, "rt");
00169 
00170       chld->flag <<= 1; /* done with parsing */
00171     }
00172 
00173   if (PLINT_TREE_ISINS(chld))
00174     if (plint->tree.ins == PLINT_INS_INSERT)
00175       {
00176         plint_file_insert(prnt->file, chld->file);
00177         PLINT_MAP_TREE(INSERT, prnt->blk, prnt);
00178       }
00179     else
00180       PLINT_MAP_TREE(INCLUDE, prnt->blk, prnt);
00181   else if (!PLINT_TREE_ISPRC(chld) && (!PLINT_TREE_ISWRP(chld) || !plint->flag.hook))
00182     {
00183       fprintf(prnt->file, " \\B %p ", chld);
00184       PLINT_MAP_TREE(BLOCK, chld->blk, chld);
00185     }
00186 
00187   if (prnt)
00188     PLINT_MAP_TREE(DONE_CHLD, prnt->blk, prnt);
00189 
00190   plint_code.tree = prnt;
00191 
00192   PLINT_MAP_TREE(DONE_PRNT, chld->blk, chld);
00193 
00194   PLINT_MAP_TREE(DONE, chld->blk, chld);
00195 }
00196 
00197 void plint_tree_free(plint_tree_t r)
00198 {
00199   plint_tree_t q = 0;
00200   plint_code.tree = r;
00201   while ((r = plint_code.tree))
00202     {
00203       switch (plint->run)
00204         {
00205         case 0 OR 1: break;
00206         default:
00207           if (!q && PLINT_TREE_ISPRC(r) && r->flag < 4)
00208             {
00209               q = r;
00210 
00211 #ifdef PLINT_VERB_WARN
00212               eprintf("\n%s%s%s", PLINT_PLINT, PLINT_WARN, PLINT_NEVER);
00213               plint_proc_log(stderr, r);
00214 #endif
00215             }
00216         }
00217 
00218       while (r->nchlds)
00219         if (PLINT_TREE_ISINS(r->chlds[r->nchlds-1]))
00220           --r->nchlds;
00221         else /* don't descend into an insertion point */
00222           break;
00223 
00224       if (r->nchlds)
00225         {
00226           plint_code.tree = r->chlds[--r->nchlds];
00227           PLINT_MAP_TREE(FREE_CHLD, r->blk, r);
00228 
00229           plint_code.tree = r;
00230           r = r->chlds[r->nchlds];
00231           PLINT_MAP_TREE(FREE_PRNT, r->blk, r);
00232 
00233           plint_code.tree = r;
00234         }
00235       else
00236         {
00237           free(r->chlds);
00238 
00239           if (PLINT_TREE_ISPRS(r) || PLINT_TREE_ISINS(r))
00240             plint_file_close(r->file);
00241 
00242           unlink(r->srcfile);
00243           free(r->srcfile);
00244 
00245           if (!PLINT_TREE_ISINS(r))
00246             {
00247               plint_eblk_t b;
00248               for (b = _PLINT_BLK_start; ++b < _PLINT_BLK_stop ;)
00249                 PLINT_MAP_TREE(FREE_USER, b, r);
00250             }
00251 
00252           plint_code.tree = r->prnt;
00253 
00254           /* special case - root */
00255           if (!plint_code.tree)
00256             PLINT_MAP_TREE(FREE_PRNT, r->blk, r);
00257 
00258           if (PLINT_TREE_ISPRC(r))
00259             {
00260               hash_remstr(plint_hash.id, r->proc.name);
00261               while (r->proc.arrity)
00262                 hash_remstr(plint_hash.id, r->proc.args[--r->proc.arrity]);
00263 
00264               free(r->proc.args);
00265             }
00266 
00267           if (!PLINT_TREE_ISINS(r))
00268             {
00269               PLINT_MAP_TREE(FREE, r->blk, r);
00270               slot_delete(r->user);
00271               FREE(r);
00272             }
00273 
00274           switch (plint->run)
00275             {
00276             case 0 OR 1: break;
00277             default:
00278                 if (q == r)
00279                   q = 0;
00280             }
00281         }
00282     }
00283 }

Generated on Thu Jan 9 19:02:39 2003 for plint by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002