00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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 }
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 }
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 }
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
00238 attr_name = sc->vptr->pair_car(attr_car_el);
00239
00240
00241 attr_type = sc->vptr->pair_cdr (attr_car_el);
00242 attr_type = sc->vptr->pair_car (attr_type);
00243
00244
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 }
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 }
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 }
00424
00425
00426
00427
00428
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
00462
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 }