project.c

Go to the documentation of this file.
00001 /*
00002  * gEDA - GNU Electronic Design Automation
00003  * This file is a part of gerbv.
00004  *
00005  *   Copyright (C) 2000-2003 Stefan Petersen (spe@stacken.kth.se)
00006  *
00007  * $Id$
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
00022  */
00023 
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #ifdef HAVE_STDLIB_H
00035 #include <stdlib.h>
00036 #endif
00037 
00038 #include <stdio.h>
00039 
00040 #ifdef HAVE_STRING_H
00041 #include <string.h>
00042 #endif
00043 
00044 #ifdef HAVE_SYS_TYPES_H
00045 #include <sys/types.h>
00046 #endif
00047 
00048 #ifdef HAVE_SYS_STAT_H
00049 #include <sys/stat.h>
00050 #endif
00051 
00052 #ifdef HAVE_UNISTD_H
00053 #include <unistd.h>
00054 #endif
00055 
00056 #include <errno.h>
00057 
00058 #include "gerbv.h"
00059 #include "gerb_file.h"
00060 #include "project.h"
00061 #include "scheme-private.h"
00062 #include "main.h"
00063 #include "interface.h"
00064 #include "render.h"
00065 
00066 /* DEBUG printing.  #define DEBUG 1 in config.h to use this fcn. */
00067 #define dprintf if(DEBUG) printf
00068 
00069 static project_list_t *plist_top = NULL;
00070 
00071 static void
00072 get_color(scheme *sc, pointer value, int *color)
00073 {
00074     int i;
00075     pointer elem;
00076 
00077     if (!sc->vptr->is_vector(value)) {
00078        GERB_MESSAGE("Color parameter not a vector\n");
00079        return;
00080     }
00081     if (sc->vptr->vector_length(value) != 3) {
00082        GERB_MESSAGE("Color vector of incorrect length\n");
00083        return;
00084     }
00085     
00086     for (i = 0; i < 3; i++) {
00087        elem = sc->vptr->vector_elem(value, i);
00088        if (sc->vptr->is_integer(elem) && sc->vptr->is_number(elem))
00089            color[i] = sc->vptr->ivalue(elem);
00090        else { 
00091            color[i] = -1;
00092            GERB_MESSAGE("Illegal color in projectfile\n");
00093        }
00094     }
00095     
00096     return;
00097 } /* get_color */
00098 
00099 
00100 static char *
00101 get_value_string(scheme *sc, pointer value)
00102 {
00103     if (!sc->vptr->is_string(value))
00104        return NULL;
00105 
00106     return sc->vptr->string_value(value);
00107 } /* get_value_string */
00108 
00109 
00112 static char *
00113 convert_path_separators(char* path, int conv_flag)
00114 {
00115 #if defined (__MINGW32__)        
00116     char     *hit_in_path;
00117 
00118     switch (conv_flag) {
00119        
00120     case MINGW_UNIX:
00121         while ((hit_in_path = strchr(path, '\\'))) {
00122             *hit_in_path = '/';
00123         }
00124         break;
00125     case UNIX_MINGW:
00126        while ((hit_in_path = strchr(path, '/'))) {
00127             *hit_in_path = '\\';
00128         }
00129         break;
00130     }    
00131 #endif
00132 
00133     return path;
00134 }/* convert_path_separators */
00135 
00136 
00137 static pointer
00138 define_layer(scheme *sc, pointer args)
00139 {
00140     pointer car_el, cdr_el, name, value;
00141     int layerno;
00142     project_list_t *plist_tmp = NULL;
00143 
00144     dprintf("--> entering project.c:define_layer\n");
00145 
00146     if (!sc->vptr->is_pair(args)){
00147        GERB_MESSAGE("define-layer!: Too few arguments\n");
00148        return sc->F;
00149     }
00150 
00151     car_el = sc->vptr->pair_car(args);
00152     cdr_el = sc->vptr->pair_cdr(args);
00153 
00154     if (!sc->vptr->is_integer(car_el) || !sc->vptr->is_number(car_el)) {
00155        GERB_MESSAGE("define-layer!: Layer number missing/incorrect\n");
00156        return sc->F;
00157     }
00158 
00159     layerno = sc->vptr->ivalue(car_el);
00160     dprintf("    layerno = %d\n", layerno);
00161     if (mainProject->last_loaded <= layerno) {
00162        mainProject->last_loaded = layerno;
00163     }
00164     
00165     car_el = sc->vptr->pair_car(cdr_el);
00166     cdr_el = sc->vptr->pair_cdr(cdr_el);
00167     
00168     plist_tmp = (project_list_t *)g_malloc(sizeof(project_list_t));
00169     memset(plist_tmp, 0, sizeof(project_list_t));
00170     plist_tmp->next = plist_top;
00171     plist_top = plist_tmp;
00172     plist_top->layerno = layerno;
00173     plist_top->visible = 1;
00174     plist_top->n_attr = 0;
00175     plist_top->attr_list = NULL;
00176 
00177     while (sc->vptr->is_pair(car_el)) {
00178        
00179        name = sc->vptr->pair_car(car_el);
00180        value =  sc->vptr->pair_cdr(car_el);
00181        
00182        if (!sc->vptr->is_symbol(name)) {
00183            GERB_MESSAGE("define-layer!:non-symbol found, ignoring\n");
00184            goto end_name_value_parse;
00185        }
00186        
00187        if (strcmp(sc->vptr->symname(name), "color") == 0) {
00188            get_color(sc, value, plist_top->rgb);
00189        } else if (strcmp(sc->vptr->symname(name), "filename") == 0) {
00190            
00191             plist_top->filename = strdup(get_value_string(sc, value));
00192            plist_top->filename = convert_path_separators(plist_top->filename, 
00193                                                    UNIX_MINGW);
00194             plist_top->is_pnp = 0;
00195        } else if (strcmp(sc->vptr->symname(name), "pick_and_place") == 0) {
00196 
00197            plist_top->filename = strdup(get_value_string(sc, value));
00198            plist_top->filename = convert_path_separators(plist_top->filename, 
00199                                                    UNIX_MINGW);
00200            plist_top->is_pnp = 1;
00201        } else if (strcmp(sc->vptr->symname(name), "inverted") == 0) {
00202            if (value == sc->F) {
00203               plist_top->inverted = 0;
00204            } else if (value == sc->T) {
00205               plist_top->inverted = 1;
00206            } else {
00207               GERB_MESSAGE("Argument to inverted must be #t or #f\n");
00208            }
00209        } else if (strcmp(sc->vptr->symname(name), "visible") == 0) {
00210            if (value == sc->F) {
00211               plist_top->visible = 0;
00212            } else if (value == sc->T) {
00213               plist_top->visible = 1;
00214            } else {
00215               GERB_MESSAGE("Argument to visible must be #t or #f\n");
00216            }
00217               } else if (strcmp(sc->vptr->symname(name), "attribs") == 0) {
00218            pointer attr_car_el, attr_cdr_el;
00219            pointer attr_name, attr_type, attr_value;
00220            char *type;
00221 
00222            dprintf ("Parsing file attributes\n");
00223 
00224            attr_car_el = sc->vptr->pair_car (value);
00225            attr_cdr_el = sc->vptr->pair_cdr (value);
00226            while (sc->vptr->is_pair(attr_car_el)) {
00227               int p = plist_top->n_attr;
00228               plist_top->n_attr++;
00229               plist_top->attr_list = (gerbv_HID_Attribute *) 
00230                   realloc (plist_top->attr_list, 
00231                           plist_top->n_attr * sizeof (gerbv_HID_Attribute));
00232               if (plist_top->attr_list == NULL ) {
00233                   fprintf (stderr, "%s():  realloc failed\n", __FUNCTION__);
00234                   exit (1);
00235               }                                                         
00236 
00237               /* car */
00238               attr_name = sc->vptr->pair_car(attr_car_el);
00239 
00240               /* cadr */
00241               attr_type =  sc->vptr->pair_cdr (attr_car_el);
00242               attr_type =  sc->vptr->pair_car (attr_type);
00243 
00244               /* caddr */
00245               attr_value =  sc->vptr->pair_cdr (attr_car_el);
00246               attr_value =  sc->vptr->pair_cdr (attr_value);
00247               attr_value =  sc->vptr->pair_car (attr_value);
00248 
00249               dprintf ("  attribute %s, type is %s, value is ", 
00250                       sc->vptr->symname(attr_name),
00251                       sc->vptr->symname(attr_type));
00252 
00253               plist_top->attr_list[p].name = strdup (sc->vptr->symname (attr_name));
00254 
00255               type = sc->vptr->symname (attr_type);
00256 
00257               if (strcmp (type, "label") == 0) {
00258                   dprintf ("%s", sc->vptr->string_value (attr_value));
00259                   plist_top->attr_list[p].type = HID_Label;
00260                   plist_top->attr_list[p].default_val.str_value = 
00261                      strdup (sc->vptr->string_value (attr_value));
00262 
00263               } else if (strcmp (type, "integer") == 0) {
00264                   dprintf ("%ld", sc->vptr->ivalue (attr_value));
00265                   plist_top->attr_list[p].type = HID_Integer;
00266                   plist_top->attr_list[p].default_val.int_value = 
00267                      sc->vptr->ivalue (attr_value);
00268 
00269               } else if (strcmp (type, "real") == 0) {
00270                   dprintf ("%g", sc->vptr->rvalue (attr_value));
00271                   plist_top->attr_list[p].type = HID_Real;
00272                   plist_top->attr_list[p].default_val.real_value = 
00273                      sc->vptr->rvalue (attr_value);
00274 
00275               } else if (strcmp (type, "string") == 0) {
00276                   dprintf ("%s", sc->vptr->string_value (attr_value));
00277                   plist_top->attr_list[p].type = HID_String;
00278                   plist_top->attr_list[p].default_val.str_value = 
00279                      strdup (sc->vptr->string_value (attr_value));
00280 
00281               } else if (strcmp (type, "boolean") == 0) {
00282                   dprintf ("%ld", sc->vptr->ivalue (attr_value));
00283                   plist_top->attr_list[p].type = HID_Boolean;
00284                   plist_top->attr_list[p].default_val.int_value = 
00285                      sc->vptr->ivalue (attr_value);
00286 
00287               } else if (strcmp (type, "enum") == 0) {
00288                   dprintf ("%ld", sc->vptr->ivalue (attr_value));
00289                   plist_top->attr_list[p].type = HID_Enum;
00290                   plist_top->attr_list[p].default_val.int_value = 
00291                      sc->vptr->ivalue (attr_value);
00292 
00293               } else if (strcmp (type, "mixed") == 0) {
00294                   plist_top->attr_list[p].type = HID_Mixed;
00295                   plist_top->attr_list[p].default_val.str_value = NULL;
00296                   fprintf (stderr, "%s():  WARNING:  HID_Mixed is not yet supported\n",
00297                           __FUNCTION__);
00298 
00299               } else if (strcmp (type, "path") == 0) {
00300                   dprintf ("%s", sc->vptr->string_value (attr_value));
00301                   plist_top->attr_list[p].type = HID_Path;
00302                   plist_top->attr_list[p].default_val.str_value = 
00303                      strdup (sc->vptr->string_value (attr_value));
00304               } else {
00305                   fprintf (stderr, "%s():  Unknown attribute type: \"%s\"\n",
00306                           __FUNCTION__, type);
00307               }
00308               dprintf ("\n");
00309 
00310               attr_car_el = sc->vptr->pair_car(attr_cdr_el);
00311               attr_cdr_el = sc->vptr->pair_cdr(attr_cdr_el);
00312            }
00313 
00314        }
00315        
00316     end_name_value_parse:
00317        car_el = sc->vptr->pair_car(cdr_el);
00318        cdr_el = sc->vptr->pair_cdr(cdr_el);
00319     }
00320     
00321     return sc->NIL;
00322 } /* define_layer */
00323 
00324 static pointer
00325 set_render_type(scheme *sc, pointer args)
00326 {
00327     pointer car_el, cdr_el;
00328     int r;
00329 
00330     dprintf("--> entering project.c:%s()\n", __FUNCTION__);
00331 
00332     if (!sc->vptr->is_pair(args)){
00333        GERB_MESSAGE("set-render-type!: Too few arguments\n");
00334        return sc->F;
00335     }
00336 
00337     car_el = sc->vptr->pair_car(args);
00338     cdr_el = sc->vptr->pair_cdr(args);
00339 
00340     r = sc->vptr->ivalue (car_el);
00341     dprintf ("%s():  Setting render type to %d\n", __FUNCTION__, r);
00342     interface_set_render_type (r);
00343 
00344     return sc->NIL;
00345 } /* set_render_type */
00346 
00347 
00357 project_list_t *
00358 read_project_file(char const* filename)
00359 {
00360     struct stat stat_info;
00361     scheme *sc;
00362     FILE *fd;
00363     char *initdirs[] = {BACKEND_DIR, mainProject->execpath, ".", 
00364                      "$GERBV_SCHEMEINIT", NULL};
00365     char *initfile;
00366 
00367     if (stat(filename, &stat_info)) {
00368        GERB_MESSAGE("Failed to read %s\n", filename);
00369        return NULL;
00370     }
00371 
00372     if (!S_ISREG(stat_info.st_mode)) {
00373        GERB_MESSAGE("Failed to read %s\n", filename);
00374        return NULL;
00375     }
00376 
00377     sc = scheme_init_new();
00378     scheme_set_output_port_file(sc, stdout);
00379 
00380     if(!sc){
00381        GERB_FATAL_ERROR("Couldn't init scheme\n");
00382        exit(1);
00383     }
00384 
00385     errno = 0;
00386     initfile = gerb_find_file("init.scm", initdirs);
00387     if (initfile == NULL) {
00388        scheme_deinit(sc);
00389        GERB_MESSAGE("Problem loading init.scm (%s)\n", strerror(errno));
00390        return NULL;
00391     }
00392     if ((fd = fopen(initfile, "r")) == NULL) {
00393        scheme_deinit(sc);
00394        GERB_MESSAGE("Couldn't open %s (%s)\n", initfile, strerror(errno));
00395        return NULL;
00396     }
00397     sc->vptr->load_file(sc, fd);
00398     fclose(fd);
00399 
00400     sc->vptr->scheme_define(sc, sc->global_env, 
00401                          sc->vptr->mk_symbol(sc, "define-layer!"),
00402                          sc->vptr->mk_foreign_func(sc, define_layer));
00403 
00404     sc->vptr->scheme_define(sc, sc->global_env, 
00405                          sc->vptr->mk_symbol(sc, "set-render-type!"),
00406                          sc->vptr->mk_foreign_func(sc, set_render_type));
00407 
00408     if ((fd = fopen(filename, "r")) == NULL) {
00409        scheme_deinit(sc);
00410        GERB_MESSAGE("Couldn't open project file %s (%s)\n", filename,
00411                    strerror(errno));
00412        return NULL;
00413     }
00414 
00415     plist_top = NULL;
00416 
00417     scheme_load_file(sc, fd);
00418     fclose(fd);
00419 
00420     scheme_deinit(sc);
00421 
00422     return plist_top;
00423 } /* read_project */
00424 
00425 
00426 /*
00427  * Writes a description of a project to a file 
00428  * that can be parsed by read_project above
00429  */
00430 int 
00431 write_project_file(gerbv_project_t *gerbvProject, char const* filename, project_list_t *project)
00432 {
00433     FILE *fd;
00434     project_list_t *p = project, *tmp;
00435     int n_attr = 0;
00436     gerbv_HID_Attribute *attr_list = NULL;
00437     int i;
00438 
00439     if ((fd = fopen(filename, "w")) == NULL) {
00440            GERB_MESSAGE("Couldn't save project %s\n", filename);
00441            return(-1);
00442     }
00443     while (p) {
00444        fprintf(fd, "(define-layer! %d ", p->layerno);
00445        
00446 #if defined (__MINGW32__)
00447        fprintf(fd, "(cons 'filename \"%s\")", convert_path_separators(p->filename, MINGW_UNIX));    
00448 #else
00449        fprintf(fd, "(cons 'filename \"%s\")", p->filename);    
00450 #endif
00451     
00452        if (p->inverted)
00453            fprintf(fd, "(cons 'inverted #t)");
00454        if (p->visible)
00455            fprintf(fd, "(cons 'visible #t)");
00456        else
00457            fprintf(fd, "(cons 'visible #f)");
00458 
00459        fprintf(fd, "(cons 'color #(%d %d %d))", p->rgb[0], p->rgb[1], p->rgb[2]);
00460 
00461        /* now write out the attribute list which specifies the
00462         * file format 
00463         */
00464        if (p->layerno < 0) {
00465            attr_list = NULL;
00466            n_attr = 0;
00467        } else {
00468            attr_list = gerbvProject->file[p->layerno]->image->info->attr_list;
00469            n_attr =  gerbvProject->file[p->layerno]->image->info->n_attr;
00470        }
00471 
00472        if (n_attr > 0) {
00473            fprintf (fd, "(cons 'attribs (list");
00474        }
00475        for (i = 0; i < n_attr ; i++) {
00476            switch (attr_list[i].type) {
00477            case HID_Label:
00478                 fprintf(fd, " (list '%s 'Label \"%s\")", attr_list[i].name,
00479                        attr_list[i].default_val.str_value);
00480                 break;
00481                 
00482              case HID_Integer:
00483                 fprintf(fd, " (list '%s 'Integer %d)", attr_list[i].name,
00484                        attr_list[i].default_val.int_value);
00485                 break;
00486                 
00487              case HID_Real:
00488                 fprintf(fd, " (list '%s 'Real %g)", attr_list[i].name,
00489                        attr_list[i].default_val.real_value);
00490                 break;
00491                 
00492              case HID_String:
00493                 fprintf(fd, " (list '%s 'String \"%s\")", attr_list[i].name,
00494                        attr_list[i].default_val.str_value);
00495                 break;
00496                 
00497              case HID_Boolean:
00498                 fprintf(fd, " (list '%s 'Boolean %d)", attr_list[i].name,
00499                        attr_list[i].default_val.int_value);
00500                 break;
00501                 
00502              case HID_Enum:
00503                 fprintf(fd, " (list '%s 'Enum %d)", attr_list[i].name,
00504                        attr_list[i].default_val.int_value);
00505                 break;
00506 
00507              case HID_Mixed:
00508                 dprintf ("HID_Mixed\n");
00509                 fprintf (stderr, "%s():  WARNING:  HID_Mixed is not yet supported.\n",
00510                         __FUNCTION__);
00511                 break;
00512 
00513              case HID_Path:
00514                 fprintf(fd, " (list '%s 'Path \"%s\")", attr_list[i].name,
00515                        attr_list[i].default_val.str_value);
00516                 break;
00517 
00518              default:
00519                 fprintf (stderr, "%s: unknown type of HID attribute (%d)\n", 
00520                         __FUNCTION__, attr_list[i].type);
00521                 break;
00522              }
00523        }
00524        if (n_attr > 0) {
00525            fprintf (fd, "))");
00526        }
00527 
00528        fprintf(fd, ")\n");
00529        tmp = p;
00530        p = p->next;
00531        g_free(tmp);
00532        tmp = NULL;
00533     }
00534 
00535     fprintf (fd, "(set-render-type! %d)\n", screenRenderInfo.renderType);
00536             
00537     fclose(fd);
00538 
00539     return(0);
00540 } /* write_project */

Generated on Tue Aug 19 00:14:49 2008 for gerbv by  doxygen 1.5.6