Esempio n. 1
0
/*! \brief Guile callback for adding library commands.
 *  \par Function Description
 *  Callback function for the "component-library-command" Guile
 *  function, which can be used in the rc files to add a command to
 *  the component library.
 *
 *  \param [in] listcmd command to get a list of symbols
 *  \param [in] getcmd  command to get a symbol from the library
 *  \param [in] name    Optional descriptive name for component source.
 *  \return SCM_BOOL_T on success, SCM_BOOL_F otherwise.
 */
SCM g_rc_component_library_command (SCM listcmd, SCM getcmd, 
                                    SCM name)
{
  const CLibSource *src;
  gchar *lcmdstr, *gcmdstr;
  char *tmp_str, *namestr;

  SCM_ASSERT (scm_is_string (listcmd), listcmd, SCM_ARG1, 
              "component-library-command");
  SCM_ASSERT (scm_is_string (getcmd), getcmd, SCM_ARG2, 
              "component-library-command");
  SCM_ASSERT (scm_is_string (name), name, SCM_ARG3, 
              "component-library-command");

  scm_dynwind_begin(0);

  /* take care of any shell variables */
  /*! \bug this may be a security risk! */
  tmp_str = scm_to_utf8_string (listcmd);
  lcmdstr = s_expand_env_variables (tmp_str);
  scm_dynwind_unwind_handler (g_free, lcmdstr, SCM_F_WIND_EXPLICITLY);
  free (tmp_str); /* this should stay as free (allocated from guile) */

  /* take care of any shell variables */
  /*! \bug this may be a security risk! */
  tmp_str = scm_to_utf8_string (getcmd);
  gcmdstr = s_expand_env_variables (tmp_str);
  scm_dynwind_unwind_handler (g_free, gcmdstr, SCM_F_WIND_EXPLICITLY);
  free (tmp_str); /* this should stay as free (allocated from guile) */

  namestr = scm_to_utf8_string (name);

  src = s_clib_add_command (lcmdstr, gcmdstr, namestr);

  free (namestr); /* this should stay as free (allocated from guile) */

  scm_dynwind_end();

  if (src != NULL) return SCM_BOOL_T;

  return SCM_BOOL_F;
}
Esempio n. 2
0
/*! \brief
 *  \par Function Description
 *
 *  \param [in] path 
 *  \param [in] name Optional descriptive name for library directory.
 *  \return SCM_BOOL_T on success, SCM_BOOL_F otherwise.
 */
SCM g_rc_component_library(SCM path, SCM name)
{
  gchar *string;
  char *temp;
  char *namestr = NULL;

  SCM_ASSERT (scm_is_string (path), path,
              SCM_ARG1, "component-library");

  scm_dynwind_begin (0);
  if (name != SCM_UNDEFINED) {
    SCM_ASSERT (scm_is_string (name), name,
		SCM_ARG2, "component-library");
    namestr = scm_to_utf8_string (name);
    scm_dynwind_free(namestr);
  }

  /* take care of any shell variables */
  temp = scm_to_utf8_string (path);
  string = s_expand_env_variables (temp);
  scm_dynwind_unwind_handler (g_free, string, SCM_F_WIND_EXPLICITLY);
  free (temp);

  /* invalid path? */
  if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
    fprintf(stderr,
            "Invalid path [%s] passed to component-library\n",
            string);
    scm_dynwind_end();
    return SCM_BOOL_F;
  }

  if (g_path_is_absolute (string)) {
    s_clib_add_directory (string, namestr);
  } else {
    gchar *cwd = g_get_current_dir ();
    gchar *temp;
    temp = g_build_filename (cwd, string, NULL);
    s_clib_add_directory (temp, namestr);
    g_free(temp);
    g_free(cwd);
  }

  scm_dynwind_end();
  return SCM_BOOL_T;
}
Esempio n. 3
0
/*! \brief Evaluates the stroke.
 *  \par Function Description
 *  This function transforms the stroke input so far in an action.
 *
 *  It makes use of the guile procedure <B>eval-stroke</B> to evaluate
 *  the stroke sequence into a possible action. The mouse footprint is
 *  erased in this function.
 *
 *  It returns 1 if the stroke has been successfully evaluated as an
 *  action. It returns 0 if libstroke failed to transform the stroke
 *  or there is no action attached to the stroke.
 *
 *  \param [in] w_current The GschemToplevel object.
 *  \returns 1 on success, 0 otherwise.
 */
gint
x_stroke_translate_and_execute (GschemToplevel *w_current)
{
  gchar sequence[STROKE_MAX_SEQUENCE];
  StrokePoint *point;
  int min_x, min_y, max_x, max_y;
  guint i;

  g_assert (stroke_points != NULL);

  if (stroke_points->len == 0)
    return 0;

  point = &g_array_index (stroke_points, StrokePoint, 0);
  min_x = max_x = point->x;
  min_y = max_y = point->y;

  for (i = 1; i < stroke_points->len; i++) {
    point = &g_array_index (stroke_points, StrokePoint, i);
    min_x = MIN (min_x, point->x);
    min_y = MIN (min_y, point->y);
    max_x = MAX (max_x, point->x);
    max_y = MAX (max_y, point->y);
  }

  o_invalidate_rect (w_current, min_x, min_y, max_x + 1, max_y + 1);

  /* resets length of array */
  stroke_points->len = 0;

  /* try evaluating stroke */
  if (stroke_trans ((char*)&sequence)) {
    gchar *guile_string =
      g_strdup_printf("(eval-stroke \"%s\")", sequence);
    SCM ret;

    scm_dynwind_begin ((scm_t_dynwind_flags) 0);
    scm_dynwind_unwind_handler (g_free, guile_string, SCM_F_WIND_EXPLICITLY);
    ret = g_scm_c_eval_string_protected (guile_string);
    scm_dynwind_end ();

    return (SCM_NFALSEP (ret));
  }

  return 0;
}
Esempio n. 4
0
/*! \brief Print a representation of a #GschemToplevel smob.
 * \par Function Description
 * Outputs a string representing the \a smob to a Scheme output
 * \a port. The format used is "#<gschem-window b7ef65d0>".
 *
 * Used internally to Guile.
 */
static int
smob_print (SCM smob, SCM port, scm_print_state *pstate)
{
    gchar *hexstring;

    scm_puts ("#<gschem-window", port);

    scm_dynwind_begin (0);
    hexstring = g_strdup_printf (" %zx", SCM_SMOB_DATA (smob));
    scm_dynwind_unwind_handler (g_free, hexstring, SCM_F_WIND_EXPLICITLY);
    scm_puts (hexstring, port);
    scm_dynwind_end ();

    scm_puts (">", port);

    /* Non-zero means success */
    return 1;
}
Esempio n. 5
0
/*! \brief Print a representation of a gEDA smob.
 * \par Function Description
 * Outputs a string representing the gEDA \a smob to a Scheme output
 * \a port. The format used is "#<geda-TYPE b7ef65d0>", where TYPE is
 * a string describing the C structure represented by the gEDA smob.
 *
 * Used internally to Guile.
 */
static int
smob_print (SCM smob, SCM port, scm_print_state *pstate)
{
  gchar *hexstring;

  scm_puts ("#<geda-", port);

  switch (EDASCM_SMOB_TYPE (smob)) {
  case GEDA_SMOB_TOPLEVEL:
    scm_puts ("toplevel", port);
    break;
  case GEDA_SMOB_PAGE:
    scm_puts ("page", port);
    break;
  case GEDA_SMOB_OBJECT:
    scm_puts ("object", port);
    break;
  case GEDA_SMOB_CONFIG:
    scm_puts ("config", port);
    break;
  case GEDA_SMOB_CLOSURE:
    scm_puts ("closure", port);
    break;
  default:
    g_critical ("%s: received bad smob flags.", __FUNCTION__);
    scm_puts ("unknown", port);
  }

  if (SCM_SMOB_DATA (smob) != 0) {
    scm_dynwind_begin (0);
    hexstring = g_strdup_printf (" %p", (void *) SCM_SMOB_DATA (smob));
    scm_dynwind_unwind_handler (g_free, hexstring, SCM_F_WIND_EXPLICITLY);
    scm_puts (hexstring, port);
    scm_dynwind_end ();
  } else {
    scm_puts (" (null)", port);
  }

  scm_puts (">", port);

  /* Non-zero means success */
  return 1;
}
Esempio n. 6
0
SCM
scm_internal_dynamic_wind (scm_t_guard before,
			   scm_t_inner inner,
			   scm_t_guard after,
			   void *inner_data,
			   void *guard_data)
{
  SCM ans;

  scm_c_issue_deprecation_warning
    ("`scm_internal_dynamic_wind' is deprecated.  "
     "Use the `scm_dynwind_begin' / `scm_dynwind_end' API instead.");

  scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
  scm_dynwind_rewind_handler (before, guard_data, SCM_F_WIND_EXPLICITLY);
  scm_dynwind_unwind_handler (after, guard_data, SCM_F_WIND_EXPLICITLY);
  ans = inner (inner_data);
  scm_dynwind_end ();
  return ans;
}
Esempio n. 7
0
static SCM g_get_duplicogram(void)
{
    SCM lst = SCM_EOL;
    uint64_t const nb_pkts = nb_nodups + nb_dups;

    scm_dynwind_begin(0);
    mutex_lock(&dup_lock);
    scm_dynwind_unwind_handler(pthread_mutex_unlock_, &dup_lock.mutex, SCM_F_WIND_EXPLICITLY);

    unsigned dt = bucket_width/2;
    for (unsigned x = 0; x < nb_buckets; x++, dt += bucket_width) {
        lst = scm_cons(
                scm_cons(scm_from_uint(dt),
                         scm_from_double(nb_pkts > 0 ? (double)dups[x] / nb_pkts : 0.)),
                lst);
    }

    dup_reset_locked();
    scm_dynwind_end();

    return lst;
}
Esempio n. 8
0
PyObject *scm2py(SCM value)
{
	if (value == NULL)
		return NULL;
	if (value == SCM_UNSPECIFIED) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	if (scm_is_exact_integer(value))
		return PyInt_FromLong(scm_to_long(value));
	if (scm_is_real(value))
		return PyFloat_FromDouble(scm_to_double(value));
	if (scm_is_bool(value)) {
		PyObject *result = scm_to_bool(value) ? Py_True : Py_False;
		Py_INCREF(result);
		return result;
	}
	if (value == SCM_EOL)
		return PyTuple_New(0);
	if (scm_is_string(value)) {
		size_t len = 0;
		char *s = scm_to_utf8_stringn(value, &len);
		PyObject *result = PyUnicode_FromStringAndSize(s, len);
		free(s);
		return result;
	}
	if (scm_is_pair(value)) {
		unsigned int len = scm_to_uint(scm_length(value));
		PyObject *result = PyTuple_New(len);
		scm_dynwind_begin(0);
		scm_dynwind_unwind_handler(
			(void (*)(void *))Py_DecRef, result, 0);
		unsigned int i;
		for (i = 0; i < len; i++) {
			PyObject *item = scm2py(scm_car(value));
			if (item == NULL) {
				scm_dynwind_end();
				Py_DECREF(result);
				return NULL;
			}
			PyTuple_SET_ITEM(result, i, item);
			value = scm_cdr(value);
		}
		scm_dynwind_end();
		return result;
	}
	if (scm_to_bool(scm_procedure_p(value))) {
		SCM ptr = scm_assq_ref(gsubr_alist, value);
		if (!scm_is_false(ptr)) {
			PyObject *result = scm_to_pointer(ptr);
			Py_INCREF(result);
			return result;
		}
		Procedure *result =
			(Procedure *)ProcedureType.tp_alloc(&ProcedureType, 0);
		if (result == NULL)
			return NULL;
		result->proc = value;
		return (PyObject *)result;
	}

	char *msg = scm_to_utf8_stringn(
		scm_simple_format(
			SCM_BOOL_F,
			scm_from_utf8_string(
				"Guile expression ~S doesn't have a "
				"corresponding Python value"),
			scm_list_1(value)), NULL);
	PyErr_SetString(PyExc_TypeError, msg);
	free(msg);
	return NULL;
}
Esempio n. 9
0
static void scm_dynwind_py_decref(PyObject *x)
{
	scm_dynwind_unwind_handler(
		(void (*)(void *))Py_DecRef, x, SCM_F_WIND_EXPLICITLY);
}