Example #1
0
/**
 * Adds the X-Features header to a HTTP request.
 *
 * @param xfeatures	structure holding the collected features
 * @param buf		should point to the beginning of the header.
 * @param len		no brief description.
 * @param rw		the number of bytes that were already written.
 *
 * *rw is changed too *rw + bytes written
 */
void
header_features_generate(xfeature_t xf, char *dst, size_t len, size_t *rw)
{
	static const char hdr[] = "X-Features";
	struct features *features;
	GList *cur;
	header_fmt_t *fmt;

	g_assert(len <= INT_MAX);
	g_assert(*rw <= INT_MAX);
	g_assert(len >= *rw);

	if (len - *rw < (sizeof(hdr) + sizeof(": \r\n") - 1))
		return;

	features = features_get(xf);
	g_return_if_fail(features);

	if (g_list_first(features->list) == NULL)
		return;

	fmt = header_fmt_make(hdr, ", ", 0, len - *rw);

	for (cur = g_list_first(features->list); cur; cur = g_list_next(cur)) {
		struct header_x_feature *item = cur->data;
		char buf[50];

		if (item->guard && !*item->guard)
			continue;

		if (item->guardfn && !(*item->guardfn)())
			continue;

		gm_snprintf(buf, sizeof buf, "%s/%d.%d",
			item->name, item->major, item->minor);

		header_fmt_append_value(fmt, buf);
	}

	header_fmt_end(fmt);

	if (header_fmt_length(fmt) < len - *rw) {
		*rw += clamp_strncpy(&dst[*rw], len - *rw,
				header_fmt_string(fmt), header_fmt_length(fmt));
	}

	header_fmt_free(&fmt);
}
Example #2
0
/**
 * Removes all memory used by the header_features_add.
 */
static void
header_features_cleanup(xfeature_t xf)
{
	struct features *features;
	GList *cur;

 	features = features_get(xf);
	g_return_if_fail(features);

   	cur = g_list_first(features->list);
	for (/* NOTHING */; NULL != cur; cur = g_list_next(cur)) {
		struct header_x_feature *header = cur->data;

		G_FREE_NULL(header->name);
		WFREE(header);
	}
	gm_list_free_null(&features->list);
}
Example #3
0
/**
 * Add conditional support for feature ``name'': if at run-time the value
 * returned by the ``guardfn'' function is FALSE, the feature is not emitted.
 */
void
header_features_add_guarded_function(xfeature_t xf,
	const char *name, int major, int minor, bool (*guardfn)(void))
{
	struct header_x_feature *item;
	struct features *features;

	features = features_get(xf);
	g_return_if_fail(features);

	WALLOC(item);
	item->name = g_strdup(name);
	item->major = major;
	item->minor = minor;
	item->guard = NULL;
	item->guardfn = guardfn;

	features->list = g_list_append(features->list, item);
}
void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
  char *ncdecl = 0;
  String *rdecl = 0;
  String *rname = 0;
  if (!features)
    return;

  /* MM: This removed to more tightly control feature/name matching */
  /*
     if ((decl) && (SwigType_isqualifier(decl))) {
     ncdecl = strchr(Char(decl),'.');
     ncdecl++;
     }
   */

  /* very specific hack for template constructors/destructors */
  if (name && SwigType_istemplate(name)) {
    String *nodetype = nodeType(node);
    if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
      String *nprefix = NewStringEmpty();
      String *nlast = NewStringEmpty();
      String *tprefix;
      Swig_scopename_split(name, &nprefix, &nlast);
      tprefix = SwigType_templateprefix(nlast);
      Delete(nlast);
      if (Len(nprefix)) {
	Append(nprefix, "::");
	Append(nprefix, tprefix);
	Delete(tprefix);
	rname = nprefix;
      } else {
	rname = tprefix;
	Delete(nprefix);
      }
      rdecl = Copy(decl);
      Replaceall(rdecl, name, rname);
      decl = rdecl;
      name = rname;
    }
  }

#ifdef SWIG_DEBUG
  Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl);
#endif

  /* Global features */
  features_get(features, "", 0, 0, node);
  if (name) {
    String *tname = NewStringEmpty();
    /* add features for 'root' template */
    String *dname = SwigType_istemplate_templateprefix(name);
    if (dname) {
      features_get(features, dname, decl, ncdecl, node);
    }
    /* Catch-all */
    features_get(features, name, decl, ncdecl, node);
    /* Perform a class-based lookup (if class prefix supplied) */
    if (prefix) {
      /* A class-generic feature */
      if (Len(prefix)) {
	Printf(tname, "%s::", prefix);
	features_get(features, tname, decl, ncdecl, node);
      }
      /* A wildcard-based class lookup */
      Clear(tname);
      Printf(tname, "*::%s", name);
      features_get(features, tname, decl, ncdecl, node);
      /* A specific class lookup */
      if (Len(prefix)) {
	/* A template-based class lookup */
	String *tprefix = SwigType_istemplate_templateprefix(prefix);
	if (tprefix) {
	  Clear(tname);
	  Printf(tname, "%s::%s", tprefix, name);
	  features_get(features, tname, decl, ncdecl, node);
	}
	Clear(tname);
	Printf(tname, "%s::%s", prefix, name);
	features_get(features, tname, decl, ncdecl, node);
	Delete(tprefix);
      }
    } else {
      /* Lookup in the global namespace only */
      Clear(tname);
      Printf(tname, "::%s", name);
      features_get(features, tname, decl, ncdecl, node);
    }
    Delete(tname);
    Delete(dname);
  }
  if (name && SwigType_istemplate(name)) {
    /* add features for complete template type */
    String *dname = Swig_symbol_template_deftype(name, 0);
    if (!Equal(dname, name)) {
      Swig_features_get(features, prefix, dname, decl, node);
    }
    Delete(dname);
  }

  if (rname)
    Delete(rname);
  if (rdecl)
    Delete(rdecl);
}