libgeda
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * libgeda - gEDA's library - Scheme API 00003 * Copyright (C) 2010 Peter Brett <peter@peter-b.co.uk> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA 00018 */ 00019 00025 #include <config.h> 00026 00027 #include "libgeda_priv.h" 00028 #include "libgedaguile_priv.h" 00029 00030 SCM_SYMBOL (edascm_string_format_sym , "string-format"); 00031 00041 SCM_DEFINE (active_pages, "%active-pages", 0, 0, 0, 00042 (), "Retrieve a list of currently-opened pages") 00043 { 00044 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00045 SCM lst = SCM_EOL; 00046 SCM rlst; 00047 GList *page_list = geda_list_get_glist (toplevel->pages); 00048 00049 while (page_list != NULL) { 00050 lst = scm_cons (edascm_from_page (page_list->data), lst); 00051 page_list = g_list_next (page_list); 00052 } 00053 00054 rlst = scm_reverse (lst); 00055 scm_remember_upto_here_1 (lst); 00056 return rlst; 00057 } 00058 00070 SCM_DEFINE (new_page, "%new-page", 1, 0, 0, 00071 (SCM filename_s), "Create a new page") 00072 { 00073 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00074 char *filename; 00075 PAGE *page; 00076 00077 /* Ensure that the argument is a string */ 00078 SCM_ASSERT (scm_is_string (filename_s), filename_s, 00079 SCM_ARG1, s_new_page); 00080 00081 filename = scm_to_utf8_string (filename_s); 00082 page = s_page_new (toplevel, filename); 00083 g_free (filename); 00084 00085 return edascm_from_page (page); 00086 } 00087 00101 SCM_DEFINE (close_page_x, "%close-page!", 1, 0, 0, 00102 (SCM page_s), "Close a page.") 00103 { 00104 /* Ensure that the argument is a page smob */ 00105 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00106 SCM_ARG1, s_close_page_x); 00107 00108 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00109 PAGE *page = edascm_to_page (page_s); 00110 00111 s_page_delete (toplevel, page); 00112 00113 return SCM_UNDEFINED; 00114 } 00115 00125 SCM_DEFINE (page_filename, "%page-filename", 1, 0, 0, 00126 (SCM page_s), "Get a page's associated filename") 00127 { 00128 PAGE *page; 00129 00130 /* Ensure that the argument is a page smob */ 00131 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00132 SCM_ARG1, s_page_filename); 00133 00134 00135 page = edascm_to_page (page_s); 00136 return scm_from_utf8_string (page->page_filename); 00137 } 00138 00150 SCM_DEFINE (set_page_filename_x, "%set-page-filename!", 2, 0, 0, 00151 (SCM page_s, SCM filename_s), "Set a page's associated filename") 00152 { 00153 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00154 SCM_ARG1, s_set_page_filename_x); 00155 SCM_ASSERT (scm_is_string (filename_s), filename_s, 00156 SCM_ARG2, s_set_page_filename_x); 00157 00158 PAGE *page = edascm_to_page (page_s); 00159 char *new_fn = scm_to_utf8_string (filename_s); 00160 if (page->page_filename != NULL) { 00161 g_free (page->page_filename); 00162 } 00163 page->page_filename = g_strdup (new_fn); 00164 free (new_fn); 00165 00166 return page_s; 00167 } 00168 00179 SCM_DEFINE (page_contents, "%page-contents", 1, 0, 0, 00180 (SCM page_s), "Get a page's contents.") 00181 { 00182 PAGE *page; 00183 00184 /* Ensure that the argument is a page smob */ 00185 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00186 SCM_ARG1, s_page_contents); 00187 00188 page = edascm_to_page (page_s); 00189 00190 return edascm_from_object_glist (s_page_objects (page)); 00191 } 00192 00204 SCM_DEFINE (object_page, "%object-page", 1, 0, 0, 00205 (SCM obj_s), "Get the page that an object smob belongs to") 00206 { 00207 SCM_ASSERT (EDASCM_OBJECTP (obj_s), obj_s, 00208 SCM_ARG1, s_object_page); 00209 00210 PAGE *page = o_get_page (edascm_c_current_toplevel (), 00211 edascm_to_object (obj_s)); 00212 00213 if (page != NULL) { 00214 return edascm_from_page (page); 00215 } else { 00216 return SCM_BOOL_F; 00217 } 00218 } 00219 00220 00231 SCM_DEFINE (page_append_x, "%page-append!", 2, 0, 0, 00232 (SCM page_s, SCM obj_s), "Add an object to a page.") 00233 { 00234 /* Ensure that the arguments have the correct types. */ 00235 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00236 SCM_ARG1, s_page_append_x); 00237 SCM_ASSERT (EDASCM_OBJECTP (obj_s), obj_s, 00238 SCM_ARG2, s_page_append_x); 00239 00240 PAGE *page = edascm_to_page (page_s); 00241 OBJECT *obj = edascm_to_object (obj_s); 00242 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00243 00244 /* Check that the object isn't already attached to something. */ 00245 PAGE *curr_page = o_get_page (toplevel, obj); 00246 if (((curr_page != NULL) && (curr_page != page)) 00247 || (obj->parent != NULL)) { 00248 scm_error (edascm_object_state_sym, s_page_append_x, 00249 _("Object ~A is already attached to something"), 00250 scm_list_1 (obj_s), SCM_EOL); 00251 } 00252 00253 if (curr_page == page) return obj_s; 00254 00255 /* Object cleanup now managed by C code. */ 00256 edascm_c_set_gc (obj_s, 0); 00257 o_emit_pre_change_notify (toplevel, obj); 00258 s_page_append (edascm_c_current_toplevel (), page, obj); 00259 o_emit_change_notify (toplevel, obj); 00260 page->CHANGED = 1; /* Ugh. */ 00261 00262 return page_s; 00263 } 00264 00276 SCM_DEFINE (page_remove_x, "%page-remove!", 2, 0, 0, 00277 (SCM page_s, SCM obj_s), "Remove an object from a page.") 00278 { 00279 /* Ensure that the arguments have the correct types. */ 00280 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00281 SCM_ARG1, s_page_remove_x); 00282 SCM_ASSERT (EDASCM_OBJECTP (obj_s), obj_s, 00283 SCM_ARG2, s_page_remove_x); 00284 00285 PAGE *page = edascm_to_page (page_s); 00286 OBJECT *obj = edascm_to_object (obj_s); 00287 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00288 00289 /* Check that the object is not attached to something else. */ 00290 PAGE *curr_page = o_get_page (toplevel, obj); 00291 if ((curr_page != NULL && curr_page != page) 00292 || (obj->parent != NULL)) { 00293 scm_error (edascm_object_state_sym, s_page_remove_x, 00294 _("Object ~A is attached to a complex or different page"), 00295 scm_list_1 (obj_s), SCM_EOL); 00296 } 00297 00298 /* Check that object is not attached as an attribute. */ 00299 if (obj->attached_to != NULL) { 00300 scm_error (edascm_object_state_sym, s_page_remove_x, 00301 _("Object ~A is attached as an attribute"), 00302 scm_list_1 (obj_s), SCM_EOL); 00303 } 00304 00305 /* Check that object doesn't have attributes. */ 00306 if (obj->attribs != NULL) { 00307 scm_error (edascm_object_state_sym, s_page_remove_x, 00308 _("Object ~A has attributes"), 00309 scm_list_1 (obj_s), SCM_EOL); 00310 } 00311 00312 if (curr_page == NULL) return obj_s; 00313 00314 o_emit_pre_change_notify (toplevel, obj); 00315 s_page_remove (toplevel, page, obj); 00316 page->CHANGED = 1; /* Ugh. */ 00317 /* If the object is currently selected, unselect it. */ 00318 o_selection_remove (toplevel, page->selection_list, obj); 00319 o_emit_change_notify (toplevel, obj); 00320 00321 /* Object cleanup now managed by Guile. */ 00322 edascm_c_set_gc (obj_s, 1); 00323 return page_s; 00324 } 00325 00337 SCM_DEFINE (page_dirty, "%page-dirty?", 1, 0, 0, 00338 (SCM page_s), "Check whether a page has been flagged as changed.") 00339 { 00340 /* Ensure that the argument is a page smob */ 00341 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00342 SCM_ARG1, s_page_dirty); 00343 00344 PAGE *page = edascm_to_page (page_s); 00345 return page->CHANGED ? SCM_BOOL_T : SCM_BOOL_F; 00346 } 00347 00360 SCM_DEFINE (set_page_dirty_x, "%set-page-dirty!", 2, 0, 0, 00361 (SCM page_s, SCM flag_s), 00362 "Set whether a page is flagged as changed.") 00363 { 00364 /* Ensure that the argument is a page smob */ 00365 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00366 SCM_ARG1, s_set_page_dirty_x); 00367 00368 PAGE *page = edascm_to_page (page_s); 00369 page->CHANGED = scm_is_true (flag_s); 00370 return page_s; 00371 } 00372 00383 SCM_DEFINE (page_to_string, "%page->string", 1, 0, 0, 00384 (SCM page_s), 00385 "Create a string representation of a page.") 00386 { 00387 /* Ensure that the argument is a page smob */ 00388 SCM_ASSERT (EDASCM_PAGEP (page_s), page_s, 00389 SCM_ARG1, s_page_to_string); 00390 00391 PAGE *page = edascm_to_page (page_s); 00392 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00393 00394 gchar *buf = o_save_buffer (toplevel, s_page_objects (page)); 00395 scm_dynwind_begin (0); 00396 scm_dynwind_unwind_handler (g_free, buf, SCM_F_WIND_EXPLICITLY); 00397 SCM result = scm_from_utf8_string (buf); 00398 scm_dynwind_end (); 00399 return result; 00400 } 00401 00415 SCM_DEFINE (string_to_page, "%string->page", 2, 0, 0, 00416 (SCM filename_s, SCM str_s), 00417 "Create a new page from a string.") 00418 { 00419 /* Ensure that the arguments are strings */ 00420 SCM_ASSERT (scm_is_string (filename_s), filename_s, 00421 SCM_ARG1, s_string_to_page); 00422 SCM_ASSERT (scm_is_string (str_s), str_s, 00423 SCM_ARG2, s_string_to_page); 00424 00425 TOPLEVEL *toplevel = edascm_c_current_toplevel (); 00426 char *filename = scm_to_utf8_string (filename_s); 00427 PAGE *page = s_page_new (toplevel, filename); 00428 free (filename); 00429 00430 size_t len; 00431 GError * err = NULL; 00432 char *str = scm_to_utf8_stringn (str_s, &len); 00433 GList *objects = o_read_buffer (toplevel, NULL, str, len, 00434 page->page_filename, &err); 00435 free (str); 00436 00437 if (err) { 00438 SCM error_message = scm_from_utf8_string (err->message); 00439 00440 g_error_free(err); 00441 scm_error (edascm_string_format_sym, s_string_to_page, 00442 _("Parse error: ~s"), scm_list_1 (error_message), SCM_EOL); 00443 } 00444 00445 s_page_append_list (toplevel, page, objects); 00446 00447 return edascm_from_page (page); 00448 } 00449 00456 static void 00457 init_module_geda_core_page () 00458 { 00459 /* Register the functions */ 00460 #include "scheme_page.x" 00461 00462 /* Add them to the module's public definitions. */ 00463 00464 scm_c_export (s_active_pages, s_new_page, s_close_page_x, 00465 s_page_filename, s_set_page_filename_x, s_page_contents, 00466 s_object_page, s_page_append_x, s_page_remove_x, s_page_dirty, 00467 s_set_page_dirty_x, s_page_to_string, s_string_to_page, NULL); 00468 } 00469 00476 void 00477 edascm_init_page () 00478 { 00479 /* Define the (geda core page) module */ 00480 scm_c_define_module ("geda core page", 00481 init_module_geda_core_page, 00482 NULL); 00483 }