/** * 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); }
/** * 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); }
/** * 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); }