/** * Map a function by its spec. The function will be added to glapi, * and the dispatch offset will be returned. * * \param spec a '\0'-separated string array specifying a function. * It begins with the parameter signature of the function, * followed by the names of the entry points. An empty entry * point name terminates the array. * * \return the offset of the (re-)mapped function in the dispatch * table, or -1. */ static int map_function_spec(const char *spec) { const char *signature; const char *names[MAX_ENTRY_POINTS + 1]; int num_names = 0; if (!spec) return -1; signature = spec; spec += strlen(spec) + 1; /* spec is terminated by an empty string */ while (*spec) { names[num_names] = spec; num_names++; if (num_names >= MAX_ENTRY_POINTS) break; spec += strlen(spec) + 1; } if (!num_names) return -1; names[num_names] = NULL; /* add the entry points to the dispatch table */ return _glapi_add_dispatch(names, signature); }
/** * Enable and add dispatch functions for a single extension * * \param ctx Context where extension is to be enabled. * \param ext Extension that is to be enabled. * * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint * * \todo * Determine if it would be better to use \c strlen instead of the hardcoded * for-loops. */ void driInitSingleExtension( GLcontext * ctx, const struct dri_extension * ext ) { unsigned i; if ( ext->functions != NULL ) { for ( i = 0 ; ext->functions[i].strings != NULL ; i++ ) { const char * functions[16]; const char * parameter_signature; const char * str = ext->functions[i].strings; unsigned j; unsigned offset; /* Separate the parameter signature from the rest of the string. * If the parameter signature is empty (i.e., the string starts * with a NUL character), then the function has a void parameter * list. */ parameter_signature = str; while ( str[0] != '\0' ) { str++; } str++; /* Divide the string into the substrings that name each * entry-point for the function. */ for ( j = 0 ; j < 16 ; j++ ) { if ( str[0] == '\0' ) { functions[j] = NULL; break; } functions[j] = str; while ( str[0] != '\0' ) { str++; } str++; } /* Add each entry-point to the dispatch table. */ offset = _glapi_add_dispatch( functions, parameter_signature ); if (offset == -1) { #if 0 /* this causes noise with egl */ fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed " "to add %s!\n", functions[0]); #endif } else if (ext->functions[i].remap_index != -1) { driDispatchRemapTable[ ext->functions[i].remap_index ] = offset; } else if (ext->functions[i].offset != offset) { fprintf(stderr, "DISPATCH ERROR! %s -> %u != %u\n", functions[0], offset, ext->functions[i].offset); } } } if ( ctx != NULL ) { _mesa_enable_extension( ctx, ext->name ); } }