TEST(stdio, snprintf_utf8_15439554) { locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0); locale_t old_locale = uselocale(cloc); // http://b/15439554 char buf[BUFSIZ]; // 1-byte character. snprintf(buf, sizeof(buf), "%dx%d", 1, 2); EXPECT_STREQ("1x2", buf); // 2-byte character. snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2); EXPECT_STREQ("1¢2", buf); // 3-byte character. snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2); EXPECT_STREQ("1€2", buf); // 4-byte character. snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2); EXPECT_STREQ("1𤭢2", buf); uselocale(old_locale); freelocale(cloc); }
/* * Translate @str according to the locale defined by LC_TIME; unlike * dcgettext(), the translation is still taken from the LC_MESSAGES * catalogue and not the LC_TIME one. */ static const char * translate_time_format_string (const char *str) { const char *locale = g_getenv ("LC_TIME"); const char *res; char *sep; locale_t old_loc; locale_t loc = (locale_t)0; if (locale) loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t)0); old_loc = uselocale (loc); sep = strchr (str, '\004'); res = g_dpgettext (GETTEXT_PACKAGE, str, sep ? sep - str + 1 : 0); uselocale (old_loc); if (loc != (locale_t)0) freelocale (loc); return res; }
/** * Print error message and quit application * @arg err Error code. * @arg fmt Error message. * * Prints the formatted error message to stderr and quits the application * using the provided error code. */ void nl_cli_fatal(int err, const char *fmt, ...) { va_list ap; fprintf(stderr, "Error: "); if (fmt) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); } else { char *buf; #ifdef HAVE_STRERROR_L locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0); if (loc == (locale_t)0) { if (errno == ENOENT) loc = newlocale(LC_MESSAGES_MASK, "POSIX", (locale_t)0); if (loc == (locale_t)0) buf = "newlocale() failed"; } if (loc != (locale_t)0) buf = strerror_l(err, loc); #else buf = strerror(err); #endif fprintf(stderr, "%s\n", buf); #ifdef HAVE_STRERROR_L if (loc != (locale_t)0) freelocale(loc); #endif } exit(abs(err)); }
static int scan(FILE *fp, const char *name, bool quiet) { int c; bool hasid = false; bool subversion = false; analyzer_states state = INIT; struct sbuf *id = sbuf_new_auto(); locale_t l; l = newlocale(LC_ALL_MASK, "C", NULL); if (name != NULL) printf("%s:\n", name); while ((c = fgetc(fp)) != EOF) { switch (state) { case INIT: if (c == '$') { /* Transit to DELIM_SEEN if we see $ */ state = DELIM_SEEN; } else { /* Otherwise, stay in INIT state */ continue; } break; case DELIM_SEEN: if (isalpha_l(c, l)) { /* Transit to KEYWORD if we see letter */ sbuf_clear(id); sbuf_putc(id, '$'); sbuf_putc(id, c); state = KEYWORD; continue; } else if (c == '$') { /* Or, stay in DELIM_SEEN if more $ */ continue; } else { /* Otherwise, transit back to INIT */ state = INIT; } break; case KEYWORD: sbuf_putc(id, c); if (isalpha_l(c, l)) { /* * Stay in KEYWORD if additional letter is seen */ continue; } else if (c == ':') { /* * See ':' for the first time, transit to * PUNC_SEEN. */ state = PUNC_SEEN; subversion = false; } else if (c == '$') { /* * Incomplete ident. Go back to DELIM_SEEN * state because we see a '$' which could be * the beginning of a keyword. */ state = DELIM_SEEN; } else { /* * Go back to INIT state otherwise. */ state = INIT; } break; case PUNC_SEEN: case PUNC_SEEN_SVN: sbuf_putc(id, c); switch (c) { case ':': /* * If we see '::' (seen : in PUNC_SEEN), * activate subversion treatment and transit * to PUNC_SEEN_SVN state. * * If more than two :'s were seen, the ident * is invalid and we would therefore go back * to INIT state. */ if (state == PUNC_SEEN) { state = PUNC_SEEN_SVN; subversion = true; } else { state = INIT; } break; case ' ': /* * A space after ':' or '::' indicates we are at the * last component of potential ident. */ state = TEXT; break; default: /* All other characters are invalid */ state = INIT; break; } break; case TEXT: sbuf_putc(id, c); if (iscntrl_l(c, l)) { /* Control characters are not allowed in this state */ state = INIT; } else if (c == '$') { sbuf_finish(id); /* * valid ident should end with a space. * * subversion extension uses '#' to indicate that * the keyword expansion have exceeded the fixed * width, so it is also permitted if we are in * subversion mode. No length check is enforced * because GNU RCS ident(1) does not do it either. */ c = sbuf_data(id)[sbuf_len(id) - 2]; if (c == ' ' || (subversion && c == '#')) { printf(" %s\n", sbuf_data(id)); hasid = true; } state = INIT; } /* Other characters: stay in the state */ break; } } sbuf_delete(id); freelocale(l); if (!hasid) { if (!quiet) fprintf(stderr, "%s warning: no id keywords in %s\n", getprogname(), name ? name : "standard input"); return (EXIT_FAILURE); } return (EXIT_SUCCESS); }
void _Locale_numeric_destroy( struct _Locale_numeric *__loc ) { freelocale((locale_t)__loc); }
/***************************************************************************** * config_SaveConfigFile: Save a module's config options. ***************************************************************************** * This will save the specified module's config options to the config file. * If psz_module_name is NULL then we save all the modules config options. * It's no use to save the config options that kept their default values, so * we'll try to be a bit clever here. * * When we save we mustn't delete the config options of the modules that * haven't been loaded. So we cannot just create a new config file with the * config structures we've got in memory. * I don't really know how to deal with this nicely, so I will use a completly * dumb method ;-) * I will load the config file in memory, but skipping all the sections of the * modules we want to save. Then I will create a brand new file, dump the file * loaded in memory and then append the sections of the modules we want to * save. * Really stupid no ? *****************************************************************************/ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, bool b_autosave ) { module_t *p_parser; char *permanent = NULL, *temporary = NULL; if( config_PrepareDir( p_this ) ) { msg_Err( p_this, "no configuration directory" ); return -1; } /* List all available modules */ module_t **list = module_list_get (NULL); char *bigbuf = NULL; size_t bigsize = 0; FILE *file = config_OpenConfigFile (p_this); if (file != NULL) { struct stat st; /* Some users make vlcrc read-only to prevent changes. * The atomic replacement scheme breaks this "feature", * so we check for read-only by hand. */ if (fstat (fileno (file), &st) || !(st.st_mode & S_IWUSR)) { msg_Err (p_this, "configuration file is read-only"); goto error; } bigsize = (st.st_size < LONG_MAX) ? st.st_size : 0; bigbuf = malloc (bigsize + 1); if (bigbuf == NULL) goto error; /* backup file into memory, we only need to backup the sections we * won't save later on */ char *p_index = bigbuf; char *line = NULL; size_t bufsize; ssize_t linelen; bool backup = false; while ((linelen = getline (&line, &bufsize, file)) != -1) { char *p_index2; if ((line[0] == '[') && (p_index2 = strchr(line,']'))) { /* we found a new section, check if we need to do a backup */ backup = true; for (int i = 0; (p_parser = list[i]) != NULL; i++) { if (!strncmp (line + 1, p_parser->psz_object_name, strlen (p_parser->psz_object_name)) && ((psz_module_name == NULL) || !strcmp (psz_module_name, p_parser->psz_object_name))) { backup = false; /* no, we will rewrite it! */ break; } } } /* save line if requested and line is valid (doesn't begin with a * space, tab, or eol) */ if (backup && !memchr ("\n\t ", line[0], 3)) { memcpy (p_index, line, linelen); p_index += linelen; } } fclose (file); file = NULL; free (line); *p_index = '\0'; bigsize = p_index - bigbuf; } /* * Save module config in file */ permanent = config_GetConfigFile (p_this); if (!permanent) { module_list_free (list); goto error; } if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1) { temporary = NULL; module_list_free (list); goto error; } /* Configuration lock must be taken before vlcrc serializer below. */ vlc_rwlock_rdlock (&config_lock); /* The temporary configuration file is per-PID. Therefore SaveConfigFile() * should be serialized against itself within a given process. */ static vlc_mutex_t lock = VLC_STATIC_MUTEX; vlc_mutex_lock (&lock); int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (fd == -1) { vlc_rwlock_unlock (&config_lock); vlc_mutex_unlock (&lock); module_list_free (list); goto error; } file = fdopen (fd, "wt"); if (file == NULL) { msg_Err (p_this, "cannot create configuration file: %m"); vlc_rwlock_unlock (&config_lock); close (fd); vlc_mutex_unlock (&lock); module_list_free (list); goto error; } fprintf( file, "\xEF\xBB\xBF###\n" "### "PACKAGE_NAME" "PACKAGE_VERSION"\n" "###\n" "\n" "###\n" "### lines beginning with a '#' character are comments\n" "###\n" "\n" ); /* Ensure consistent number formatting... */ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t baseloc = uselocale (loc); /* We would take the config lock here. But this would cause a lock * inversion with the serializer above and config_AutoSaveConfigFile(). vlc_rwlock_rdlock (&config_lock);*/ /* Look for the selected module, if NULL then save everything */ for (int i = 0; (p_parser = list[i]) != NULL; i++) { module_config_t *p_item, *p_end; if( psz_module_name && strcmp( psz_module_name, p_parser->psz_object_name ) ) continue; if( !p_parser->i_config_items ) continue; if( psz_module_name ) msg_Dbg( p_this, "saving config for module \"%s\"", p_parser->psz_object_name ); fprintf( file, "[%s]", p_parser->psz_object_name ); if( p_parser->psz_longname ) fprintf( file, " # %s\n\n", p_parser->psz_longname ); else fprintf( file, "\n\n" ); for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize; p_item < p_end; p_item++ ) { if ((p_item->i_type & CONFIG_HINT) /* ignore hint */ || p_item->b_removed /* ignore deprecated option */ || p_item->b_unsaveable) /* ignore volatile option */ continue; /* Do not save the new value in the configuration file * if doing an autosave, and the item is not an "autosaved" one. */ bool b_retain = b_autosave && !p_item->b_autosave; if (IsConfigIntegerType (p_item->i_type)) { int64_t val = b_retain ? p_item->saved.i : p_item->value.i; config_Write (file, p_item->psz_text, (p_item->i_type == CONFIG_ITEM_BOOL) ? N_("boolean") : N_("integer"), val == p_item->orig.i, p_item->psz_name, "%"PRId64, val); p_item->saved.i = val; } else if (IsConfigFloatType (p_item->i_type)) { float val = b_retain ? p_item->saved.f : p_item->value.f; config_Write (file, p_item->psz_text, N_("float"), val == p_item->orig.f, p_item->psz_name, "%f", val); p_item->saved.f = val; } else { const char *psz_value = b_retain ? p_item->saved.psz : p_item->value.psz; bool modified; assert (IsConfigStringType (p_item->i_type)); if (b_retain && (psz_value == NULL)) /* FIXME: hack */ psz_value = p_item->orig.psz; modified = (psz_value != NULL) ? ((p_item->orig.psz != NULL) ? (strcmp (psz_value, p_item->orig.psz) != 0) : true) : (p_item->orig.psz != NULL); config_Write (file, p_item->psz_text, N_("string"), !modified, p_item->psz_name, "%s", psz_value ? psz_value : ""); if ( !b_retain ) { free ((char *)p_item->saved.psz); if( (psz_value && p_item->orig.psz && strcmp( psz_value, p_item->orig.psz )) || !psz_value || !p_item->orig.psz) p_item->saved.psz = strdupnull (psz_value); else p_item->saved.psz = NULL; } } if (!b_retain) p_item->b_dirty = false; } } vlc_rwlock_unlock (&config_lock); module_list_free (list); if (loc != (locale_t)0) { uselocale (baseloc); freelocale (loc); } /* * Restore old settings from the config in file */ if (bigsize) fwrite (bigbuf, 1, bigsize, file); /* * Flush to disk and replace atomically */ fflush (file); /* Flush from run-time */ if (ferror (file)) { vlc_unlink (temporary); vlc_mutex_unlock (&lock); msg_Err (p_this, "cannot write configuration file"); clearerr (file); goto error; } #ifndef WIN32 #ifdef __APPLE__ fsync (fd); /* Flush from OS */ #else fdatasync (fd); /* Flush from OS */ #endif /* Atomically replace the file... */ if (vlc_rename (temporary, permanent)) vlc_unlink (temporary); /* (...then synchronize the directory, err, TODO...) */ /* ...and finally close the file */ vlc_mutex_unlock (&lock); #endif fclose (file); #ifdef WIN32 /* Windows cannot remove open files nor overwrite existing ones */ vlc_unlink (permanent); if (vlc_rename (temporary, permanent)) vlc_unlink (temporary); vlc_mutex_unlock (&lock); #endif free (temporary); free (permanent); free (bigbuf); return 0; error: if( file ) fclose( file ); free (temporary); free (permanent); free (bigbuf); return -1; }
static void clear_c_locale(void) { freelocale(c_locale); c_locale = NULL; }
static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) vertex_shader_uid_data dummy_data; vertex_shader_uid_data* uid_data = out.template GetUidData<vertex_shader_uid_data>(); if (uid_data == nullptr) uid_data = &dummy_data; out.SetBuffer(text); const bool is_writing_shadercode = (out.GetBuffer() != nullptr); #ifndef ANDROID locale_t locale; locale_t old_locale; if (is_writing_shadercode) { locale = newlocale(LC_NUMERIC_MASK, "C", nullptr); // New locale for compilation old_locale = uselocale(locale); // Apply the locale for this thread } #endif if (is_writing_shadercode) text[sizeof(text) - 1] = 0x7C; // canary _assert_(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens); _assert_(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans); out.Write("%s", s_lighting_struct); // uniforms if (api_type == API_OPENGL) out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); else out.Write("cbuffer VSBlock {\n"); out.Write( "\tfloat4 " I_POSNORMALMATRIX"[6];\n" "\tfloat4 " I_PROJECTION"[4];\n" "\tint4 " I_MATERIALS"[4];\n" "\tLight " I_LIGHTS"[8];\n" "\tfloat4 " I_TEXMATRICES"[24];\n" "\tfloat4 " I_TRANSFORMMATRICES"[64];\n" "\tfloat4 " I_NORMALMATRICES"[32];\n" "\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n" "\tfloat4 " I_DEPTHPARAMS";\n" "};\n"); GenerateVSOutputStruct(out, api_type); uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->components = components; uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; if (api_type == API_OPENGL) { out.Write("in float4 rawpos; // ATTR%d,\n", SHADER_POSITION_ATTRIB); if (components & VB_HAS_POSMTXIDX) out.Write("in int posmtx; // ATTR%d,\n", SHADER_POSMTX_ATTRIB); if (components & VB_HAS_NRM0) out.Write("in float3 rawnorm0; // ATTR%d,\n", SHADER_NORM0_ATTRIB); if (components & VB_HAS_NRM1) out.Write("in float3 rawnorm1; // ATTR%d,\n", SHADER_NORM1_ATTRIB); if (components & VB_HAS_NRM2) out.Write("in float3 rawnorm2; // ATTR%d,\n", SHADER_NORM2_ATTRIB); if (components & VB_HAS_COL0) out.Write("in float4 color0; // ATTR%d,\n", SHADER_COLOR0_ATTRIB); if (components & VB_HAS_COL1) out.Write("in float4 color1; // ATTR%d,\n", SHADER_COLOR1_ATTRIB); for (int i = 0; i < 8; ++i) { u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i)); if ((components & (VB_HAS_UV0<<i)) || hastexmtx) out.Write("in float%d tex%d; // ATTR%d,\n", hastexmtx ? 3 : 2, i, SHADER_TEXTURE0_ATTRIB + i); } // Let's set up attributes for (size_t i = 0; i < 8; ++i) { if (i < xfmem.numTexGen.numTexGens) { out.Write("centroid out float3 uv%d;\n", i); } } out.Write("centroid out float4 clipPos;\n"); if (g_ActiveConfig.bEnablePixelLighting) out.Write("centroid out float4 Normal;\n"); out.Write("centroid out float4 colors_02;\n"); out.Write("centroid out float4 colors_12;\n"); out.Write("void main()\n{\n"); } else // D3D { out.Write("VS_OUTPUT main(\n"); // inputs if (components & VB_HAS_NRM0) out.Write(" float3 rawnorm0 : NORMAL0,\n"); if (components & VB_HAS_NRM1) out.Write(" float3 rawnorm1 : NORMAL1,\n"); if (components & VB_HAS_NRM2) out.Write(" float3 rawnorm2 : NORMAL2,\n"); if (components & VB_HAS_COL0) out.Write(" float4 color0 : COLOR0,\n"); if (components & VB_HAS_COL1) out.Write(" float4 color1 : COLOR1,\n"); for (int i = 0; i < 8; ++i) { u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i)); if ((components & (VB_HAS_UV0<<i)) || hastexmtx) out.Write(" float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i); } if (components & VB_HAS_POSMTXIDX) out.Write(" int posmtx : BLENDINDICES,\n"); out.Write(" float4 rawpos : POSITION) {\n"); } out.Write("VS_OUTPUT o;\n"); // transforms if (components & VB_HAS_POSMTXIDX) { if (is_writing_shadercode && (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS) && !DriverDetails::HasBug(DriverDetails::BUG_ANNIHILATEDUBOS)) ) { // This'll cause issues, but it can't be helped out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[0], rawpos), dot(" I_TRANSFORMMATRICES"[1], rawpos), dot(" I_TRANSFORMMATRICES"[2], rawpos), 1);\n"); if (components & VB_HAS_NRMALL) out.Write("float3 N0 = " I_NORMALMATRICES"[0].xyz, N1 = " I_NORMALMATRICES"[1].xyz, N2 = " I_NORMALMATRICES"[2].xyz;\n"); } else { out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[posmtx], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+1], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+2], rawpos), 1);\n"); if (components & VB_HAS_NRMALL) { out.Write("int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n"); out.Write("float3 N0 = " I_NORMALMATRICES"[normidx].xyz, N1 = " I_NORMALMATRICES"[normidx+1].xyz, N2 = " I_NORMALMATRICES"[normidx+2].xyz;\n"); } } if (components & VB_HAS_NRM0) out.Write("float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n"); if (components & VB_HAS_NRM1) out.Write("float3 _norm1 = float3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n"); if (components & VB_HAS_NRM2) out.Write("float3 _norm2 = float3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n"); } else { out.Write("float4 pos = float4(dot(" I_POSNORMALMATRIX"[0], rawpos), dot(" I_POSNORMALMATRIX"[1], rawpos), dot(" I_POSNORMALMATRIX"[2], rawpos), 1.0);\n"); if (components & VB_HAS_NRM0) out.Write("float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX"[3].xyz, rawnorm0), dot(" I_POSNORMALMATRIX"[4].xyz, rawnorm0), dot(" I_POSNORMALMATRIX"[5].xyz, rawnorm0)));\n"); if (components & VB_HAS_NRM1) out.Write("float3 _norm1 = float3(dot(" I_POSNORMALMATRIX"[3].xyz, rawnorm1), dot(" I_POSNORMALMATRIX"[4].xyz, rawnorm1), dot(" I_POSNORMALMATRIX"[5].xyz, rawnorm1));\n"); if (components & VB_HAS_NRM2) out.Write("float3 _norm2 = float3(dot(" I_POSNORMALMATRIX"[3].xyz, rawnorm2), dot(" I_POSNORMALMATRIX"[4].xyz, rawnorm2), dot(" I_POSNORMALMATRIX"[5].xyz, rawnorm2));\n"); } if (!(components & VB_HAS_NRM0)) out.Write("float3 _norm0 = float3(0.0, 0.0, 0.0);\n"); out.Write("o.pos = float4(dot(" I_PROJECTION"[0], pos), dot(" I_PROJECTION"[1], pos), dot(" I_PROJECTION"[2], pos), dot(" I_PROJECTION"[3], pos));\n"); out.Write("int4 lacc;\n" "float3 ldir, h;\n" "float dist, dist2, attn;\n"); uid_data->numColorChans = xfmem.numChan.numColorChans; if (xfmem.numChan.numColorChans == 0) { if (components & VB_HAS_COL0) out.Write("o.colors_0 = color0;\n"); else out.Write("o.colors_0 = float4(1.0, 1.0, 1.0, 1.0);\n"); } GenerateLightingShader<T>(out, uid_data->lighting, components, "color", "o.colors_"); if (xfmem.numChan.numColorChans < 2) { if (components & VB_HAS_COL1) out.Write("o.colors_1 = color1;\n"); else out.Write("o.colors_1 = o.colors_0;\n"); } // special case if only pos and tex coord 0 and tex coord input is AB11 // donko - this has caused problems in some games. removed for now. bool texGenSpecialCase = false; /*bool texGenSpecialCase = ((g_main_cp_state.vtx_desc.Hex & 0x60600L) == g_main_cp_state.vtx_desc.Hex) && // only pos and tex coord 0 (g_main_cp_state.vtx_desc.Tex0Coord != NOT_PRESENT) && (xfmem.texcoords[0].texmtxinfo.inputform == XF_TEXINPUT_AB11); */ // transform texcoords out.Write("float4 coord = float4(0.0, 0.0, 1.0, 1.0);\n"); for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) { TexMtxInfo& texinfo = xfmem.texMtxInfo[i]; out.Write("{\n"); out.Write("coord = float4(0.0, 0.0, 1.0, 1.0);\n"); uid_data->texMtxInfo[i].sourcerow = xfmem.texMtxInfo[i].sourcerow; switch (texinfo.sourcerow) { case XF_SRCGEOM_INROW: _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); out.Write("coord = rawpos;\n"); // pos.w is 1 break; case XF_SRCNORMAL_INROW: if (components & VB_HAS_NRM0) { _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); out.Write("coord = float4(rawnorm0.xyz, 1.0);\n"); } break; case XF_SRCCOLORS_INROW: _assert_( texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC0 || texinfo.texgentype == XF_TEXGEN_COLOR_STRGBC1 ); break; case XF_SRCBINORMAL_T_INROW: if (components & VB_HAS_NRM1) { _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); out.Write("coord = float4(rawnorm1.xyz, 1.0);\n"); } break; case XF_SRCBINORMAL_B_INROW: if (components & VB_HAS_NRM2) { _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); out.Write("coord = float4(rawnorm2.xyz, 1.0);\n"); } break; default: _assert_(texinfo.sourcerow <= XF_SRCTEX7_INROW); if (components & (VB_HAS_UV0<<(texinfo.sourcerow - XF_SRCTEX0_INROW)) ) out.Write("coord = float4(tex%d.x, tex%d.y, 1.0, 1.0);\n", texinfo.sourcerow - XF_SRCTEX0_INROW, texinfo.sourcerow - XF_SRCTEX0_INROW); break; } // first transformation uid_data->texMtxInfo[i].texgentype = xfmem.texMtxInfo[i].texgentype; switch (texinfo.texgentype) { case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) { // transform the light dir into tangent space uid_data->texMtxInfo[i].embosslightshift = xfmem.texMtxInfo[i].embosslightshift; uid_data->texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift; out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(texinfo.embosslightshift)); out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0);\n", i, texinfo.embosssourceshift); } else { _assert_(0); // should have normals uid_data->texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift; out.Write("o.tex%d.xyz = o.tex%d.xyz;\n", i, texinfo.embosssourceshift); } break; case XF_TEXGEN_COLOR_STRGBC0: _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); out.Write("o.tex%d.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i); break; case XF_TEXGEN_COLOR_STRGBC1: _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW); out.Write("o.tex%d.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i); break; case XF_TEXGEN_REGULAR: default: uid_data->texMtxInfo_n_projection |= xfmem.texMtxInfo[i].projection << i; if (components & (VB_HAS_TEXMTXIDX0<<i)) { out.Write("int tmp = int(tex%d.z);\n", i); if (texinfo.projection == XF_TEXPROJ_STQ) out.Write("o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), dot(coord, " I_TRANSFORMMATRICES"[tmp+2]));\n", i); else out.Write("o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), 1);\n", i); } else { if (texinfo.projection == XF_TEXPROJ_STQ) out.Write("o.tex%d.xyz = float3(dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]));\n", i, 3*i, 3*i+1, 3*i+2); else out.Write("o.tex%d.xyz = float3(dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]), 1);\n", i, 3*i, 3*i+1); } break; } uid_data->dualTexTrans_enabled = xfmem.dualTexTrans.enabled; // CHECKME: does this only work for regular tex gen types? if (xfmem.dualTexTrans.enabled && texinfo.texgentype == XF_TEXGEN_REGULAR) { const PostMtxInfo& postInfo = xfmem.postMtxInfo[i]; uid_data->postMtxInfo[i].index = xfmem.postMtxInfo[i].index; int postidx = postInfo.index; out.Write("float4 P0 = " I_POSTTRANSFORMMATRICES"[%d];\n" "float4 P1 = " I_POSTTRANSFORMMATRICES"[%d];\n" "float4 P2 = " I_POSTTRANSFORMMATRICES"[%d];\n", postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f); if (texGenSpecialCase) { // no normalization // q of input is 1 // q of output is unknown // multiply by postmatrix out.Write("o.tex%d.xyz = float3(dot(P0.xy, o.tex%d.xy) + P0.z + P0.w, dot(P1.xy, o.tex%d.xy) + P1.z + P1.w, 0.0);\n", i, i, i); } else { uid_data->postMtxInfo[i].normalize = xfmem.postMtxInfo[i].normalize; if (postInfo.normalize) out.Write("o.tex%d.xyz = normalize(o.tex%d.xyz);\n", i, i); // multiply by postmatrix out.Write("o.tex%d.xyz = float3(dot(P0.xyz, o.tex%d.xyz) + P0.w, dot(P1.xyz, o.tex%d.xyz) + P1.w, dot(P2.xyz, o.tex%d.xyz) + P2.w);\n", i, i, i, i); } } out.Write("}\n"); } // clipPos/w needs to be done in pixel shader, not here out.Write("o.clipPos = float4(pos.x,pos.y,o.pos.z,o.pos.w);\n"); if (g_ActiveConfig.bEnablePixelLighting) { out.Write("o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n"); if (components & VB_HAS_COL0) out.Write("o.colors_0 = color0;\n"); if (components & VB_HAS_COL1) out.Write("o.colors_1 = color1;\n"); } //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed if (api_type == API_D3D) { out.Write("o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); } else // OGL { // this results in a scale from -1..0 to -1..1 after perspective // divide out.Write("o.pos.z = o.pos.w + o.pos.z * 2.0;\n"); // the next steps of the OGL pipeline are: // (x_c,y_c,z_c,w_c) = o.pos //switch to OGL spec terminology // clipping to -w_c <= (x_c,y_c,z_c) <= w_c // (x_d,y_d,z_d) = (x_c,y_c,z_c)/w_c//perspective divide // z_w = (f-n)/2*z_d + (n+f)/2 // z_w now contains the value to go to the 0..1 depth buffer //trying to get the correct semantic while not using glDepthRange //seems to get rather complicated } // The console GPU places the pixel center at 7/12 in screen space unless // antialiasing is enabled, while D3D and OpenGL place it at 0.5. This results // in some primitives being placed one pixel too far to the bottom-right, // which in turn can be critical if it happens for clear quads. // Hence, we compensate for this pixel center difference so that primitives // get rasterized correctly. out.Write("o.pos.xy = o.pos.xy - " I_DEPTHPARAMS".zw;\n"); if (api_type == API_OPENGL) { // Bit ugly here // TODO: Make pretty // Will look better when we bind uniforms in GLSL 1.3 // clipPos/w needs to be done in pixel shader, not here for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) out.Write(" uv%d.xyz = o.tex%d;\n", i, i); out.Write(" clipPos = o.clipPos;\n"); if (g_ActiveConfig.bEnablePixelLighting) out.Write(" Normal = o.Normal;\n"); out.Write("colors_02 = o.colors_0;\n"); out.Write("colors_12 = o.colors_1;\n"); out.Write("gl_Position = o.pos;\n"); out.Write("}\n"); } else // D3D { out.Write("return o;\n}\n"); } if (is_writing_shadercode) { if (text[sizeof(text) - 1] != 0x7C) PanicAlert("VertexShader generator - buffer too small, canary has been eaten!"); #ifndef ANDROID uselocale(old_locale); // restore locale freelocale(locale); #endif } }
void *RPCThread::Entry() { int retval = 0; CRPCFinishedEvent RPC_done_event( wxEVT_RPC_FINISHED ); ASYNC_RPC_REQUEST *current_request; double startTime = 0; wxMutexError mutexErr = wxMUTEX_NO_ERROR; wxCondError condErr = wxCOND_NO_ERROR; #ifndef NO_PER_THREAD_LOCALE #ifdef __WXMSW__ // On Windows, set all locales for this thread on a per-thread basis _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); setlocale(LC_ALL, "C"); #else // We initialize RPC_Thread_Locale to fix a compiler warning locale_t RPC_Thread_Locale = LC_GLOBAL_LOCALE; #if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) if (uselocale) // uselocale() is not available in Mac OS 10.3.9 #endif { // On Mac / Unix / Linux, set "C" locale for this thread only RPC_Thread_Locale = newlocale(LC_ALL_MASK, "C", NULL); uselocale(RPC_Thread_Locale); } #endif // ifndef __WXMSW__ #endif // ifndef NO_PER_THREAD_LOCALE m_pRPC_Thread_Mutex->Lock(); m_pDoc->m_bRPCThreadIsReady = true; while(true) { // Wait for main thread to wake us // This does the following: // (1) Unlocks the Mutex and puts the RPC thread to sleep as an atomic operation. // (2) On Signal from main thread: locks Mutex again and wakes the RPC thread. condErr = m_pRPC_Thread_Condition->Wait(); wxASSERT(condErr == wxCOND_NO_ERROR); if (m_pDoc->m_bShutDownRPCThread) { #if !defined(NO_PER_THREAD_LOCALE) && !defined(__WXMSW__) #if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4) if (uselocale) // uselocale() is not available in Mac OS 10.3.9 #endif { uselocale(LC_GLOBAL_LOCALE); freelocale(RPC_Thread_Locale); } #endif m_pRPC_Thread_Mutex->Unlock(); // Just for safety - not really needed // Tell CMainDocument that thread has gracefully ended // We do this here because OnExit() is not called on Windows m_pDoc->m_RPCThread = NULL; return 0; } current_request = m_pDoc->GetCurrentRPCRequest(); if (!current_request->isActive) continue; // Should never happen if (current_request->RPCExecutionTime) { startTime = dtime(); } retval = ProcessRPCRequest(); if (current_request->RPCExecutionTime) { *(current_request->RPCExecutionTime) = dtime() - startTime; } current_request->retval = retval; mutexErr = m_pRPC_Request_Mutex->Lock(); wxASSERT(mutexErr == wxMUTEX_NO_ERROR); current_request->isActive = false; wxPostEvent( wxTheApp, RPC_done_event ); // Signal() is ignored / discarded unless the main thread is // currently blocked by m_pRPC_Request_Condition->Wait[Timeout]() m_pRPC_Request_Condition->Signal(); mutexErr = m_pRPC_Request_Mutex->Unlock(); wxASSERT(mutexErr == wxMUTEX_NO_ERROR); } return NULL; }
void wxXLocale::Free() { if ( m_locale ) freelocale(m_locale); }
static void free_locale_by_ptr(locale_t *lc) { freelocale(*lc); delete lc; }
void _Locale_messages_destroy( struct _Locale_messages* __loc ) { freelocale((locale_t)__loc); }
static int run_test (const char *locname) { struct lconv *lc; const char *str; const wchar_t *wstr; int result = 0; locale_t loc; /* ISO C stuff. */ lc = localeconv (); if (lc == NULL) { printf ("localeconv failed for locale %s\n", locname); result = 1; } else { #define STRTEST(name, exp) \ do \ if (strcmp (lc->name, exp) != 0) \ { \ printf (#name " in locale %s wrong (is \"%s\", should be \"%s\")\n",\ locname, lc->name, exp); \ result = 1; \ } \ while (0) STRTEST (decimal_point, "."); STRTEST (thousands_sep, ""); STRTEST (grouping, ""); STRTEST (mon_decimal_point, ""); STRTEST (mon_thousands_sep, ""); STRTEST (mon_grouping, ""); STRTEST (positive_sign, ""); STRTEST (negative_sign, ""); STRTEST (currency_symbol, ""); STRTEST (int_curr_symbol, ""); #define CHARTEST(name, exp) \ do \ if (lc->name != exp) \ { \ printf (#name " in locale %s wrong (is %d, should be %d)\n", \ locname, lc->name, CHAR_MAX); \ result = 1; \ } \ while (0) CHARTEST (frac_digits, CHAR_MAX); CHARTEST (p_cs_precedes, CHAR_MAX); CHARTEST (n_cs_precedes, CHAR_MAX); CHARTEST (p_sep_by_space, CHAR_MAX); CHARTEST (n_sep_by_space, CHAR_MAX); CHARTEST (p_sign_posn, CHAR_MAX); CHARTEST (n_sign_posn, CHAR_MAX); CHARTEST (int_frac_digits, CHAR_MAX); CHARTEST (int_p_cs_precedes, CHAR_MAX); CHARTEST (int_n_cs_precedes, CHAR_MAX); CHARTEST (int_p_sep_by_space, CHAR_MAX); CHARTEST (int_n_sep_by_space, CHAR_MAX); CHARTEST (int_p_sign_posn, CHAR_MAX); CHARTEST (int_n_sign_posn, CHAR_MAX); } #undef STRTEST #define STRTEST(name, exp) \ str = nl_langinfo (name); \ if (strcmp (str, exp) != 0) \ { \ printf ("nl_langinfo(" #name ") in locale %s wrong " \ "(is \"%s\", should be \"%s\")\n", locname, str, exp); \ result = 1; \ } #define WSTRTEST(name, exp) \ wstr = (wchar_t *) nl_langinfo (name); \ if (wcscmp (wstr, exp) != 0) \ { \ printf ("nl_langinfo(" #name ") in locale %s wrong " \ "(is \"%S\", should be \"%S\")\n", locname, wstr, exp); \ result = 1; \ } /* Unix stuff. */ STRTEST (ABDAY_1, "Sun"); STRTEST (ABDAY_2, "Mon"); STRTEST (ABDAY_3, "Tue"); STRTEST (ABDAY_4, "Wed"); STRTEST (ABDAY_5, "Thu"); STRTEST (ABDAY_6, "Fri"); STRTEST (ABDAY_7, "Sat"); STRTEST (DAY_1, "Sunday"); STRTEST (DAY_2, "Monday"); STRTEST (DAY_3, "Tuesday"); STRTEST (DAY_4, "Wednesday"); STRTEST (DAY_5, "Thursday"); STRTEST (DAY_6, "Friday"); STRTEST (DAY_7, "Saturday"); STRTEST (ABMON_1, "Jan"); STRTEST (ABMON_2, "Feb"); STRTEST (ABMON_3, "Mar"); STRTEST (ABMON_4, "Apr"); STRTEST (ABMON_5, "May"); STRTEST (ABMON_6, "Jun"); STRTEST (ABMON_7, "Jul"); STRTEST (ABMON_8, "Aug"); STRTEST (ABMON_9, "Sep"); STRTEST (ABMON_10, "Oct"); STRTEST (ABMON_11, "Nov"); STRTEST (ABMON_12, "Dec"); STRTEST (MON_1, "January"); STRTEST (MON_2, "February"); STRTEST (MON_3, "March"); STRTEST (MON_4, "April"); STRTEST (MON_5, "May"); STRTEST (MON_6, "June"); STRTEST (MON_7, "July"); STRTEST (MON_8, "August"); STRTEST (MON_9, "September"); STRTEST (MON_10, "October"); STRTEST (MON_11, "November"); STRTEST (MON_12, "December"); STRTEST (AM_STR, "AM"); STRTEST (PM_STR, "PM"); STRTEST (D_T_FMT, "%a %b %e %H:%M:%S %Y"); STRTEST (D_FMT, "%m/%d/%y"); STRTEST (T_FMT, "%H:%M:%S"); STRTEST (T_FMT_AMPM, "%I:%M:%S %p"); STRTEST (ERA, ""); STRTEST (ERA_D_FMT, ""); STRTEST (ERA_T_FMT, ""); STRTEST (ERA_D_T_FMT, ""); STRTEST (ALT_DIGITS, ""); STRTEST (RADIXCHAR, "."); STRTEST (THOUSEP, ""); STRTEST (YESEXPR, "^[yY]"); STRTEST (NOEXPR, "^[nN]"); /* Extensions. */ WSTRTEST (_NL_WABDAY_1, L"Sun"); WSTRTEST (_NL_WABDAY_2, L"Mon"); WSTRTEST (_NL_WABDAY_3, L"Tue"); WSTRTEST (_NL_WABDAY_4, L"Wed"); WSTRTEST (_NL_WABDAY_5, L"Thu"); WSTRTEST (_NL_WABDAY_6, L"Fri"); WSTRTEST (_NL_WABDAY_7, L"Sat"); WSTRTEST (_NL_WDAY_1, L"Sunday"); WSTRTEST (_NL_WDAY_2, L"Monday"); WSTRTEST (_NL_WDAY_3, L"Tuesday"); WSTRTEST (_NL_WDAY_4, L"Wednesday"); WSTRTEST (_NL_WDAY_5, L"Thursday"); WSTRTEST (_NL_WDAY_6, L"Friday"); WSTRTEST (_NL_WDAY_7, L"Saturday"); WSTRTEST (_NL_WABMON_1, L"Jan"); WSTRTEST (_NL_WABMON_2, L"Feb"); WSTRTEST (_NL_WABMON_3, L"Mar"); WSTRTEST (_NL_WABMON_4, L"Apr"); WSTRTEST (_NL_WABMON_5, L"May"); WSTRTEST (_NL_WABMON_6, L"Jun"); WSTRTEST (_NL_WABMON_7, L"Jul"); WSTRTEST (_NL_WABMON_8, L"Aug"); WSTRTEST (_NL_WABMON_9, L"Sep"); WSTRTEST (_NL_WABMON_10, L"Oct"); WSTRTEST (_NL_WABMON_11, L"Nov"); WSTRTEST (_NL_WABMON_12, L"Dec"); WSTRTEST (_NL_WMON_1, L"January"); WSTRTEST (_NL_WMON_2, L"February"); WSTRTEST (_NL_WMON_3, L"March"); WSTRTEST (_NL_WMON_4, L"April"); WSTRTEST (_NL_WMON_5, L"May"); WSTRTEST (_NL_WMON_6, L"June"); WSTRTEST (_NL_WMON_7, L"July"); WSTRTEST (_NL_WMON_8, L"August"); WSTRTEST (_NL_WMON_9, L"September"); WSTRTEST (_NL_WMON_10, L"October"); WSTRTEST (_NL_WMON_11, L"November"); WSTRTEST (_NL_WMON_12, L"December"); WSTRTEST (_NL_WAM_STR, L"AM"); WSTRTEST (_NL_WPM_STR, L"PM"); WSTRTEST (_NL_WD_T_FMT, L"%a %b %e %H:%M:%S %Y"); WSTRTEST (_NL_WD_FMT, L"%m/%d/%y"); WSTRTEST (_NL_WT_FMT, L"%H:%M:%S"); WSTRTEST (_NL_WT_FMT_AMPM, L"%I:%M:%S %p"); WSTRTEST (_NL_WERA_D_FMT, L""); WSTRTEST (_NL_WERA_T_FMT, L""); WSTRTEST (_NL_WERA_D_T_FMT, L""); WSTRTEST (_NL_WALT_DIGITS, L""); STRTEST (_DATE_FMT, "%a %b %e %H:%M:%S %Z %Y"); WSTRTEST (_NL_W_DATE_FMT, L"%a %b %e %H:%M:%S %Z %Y"); STRTEST (INT_CURR_SYMBOL, ""); STRTEST (CURRENCY_SYMBOL, ""); STRTEST (MON_DECIMAL_POINT, ""); STRTEST (MON_THOUSANDS_SEP, ""); STRTEST (MON_GROUPING, ""); STRTEST (POSITIVE_SIGN, ""); STRTEST (NEGATIVE_SIGN, ""); STRTEST (GROUPING, ""); STRTEST (YESSTR, ""); STRTEST (NOSTR, ""); /* Test the new locale mechanisms. */ loc = newlocale (LC_ALL_MASK, locname, NULL); if (loc == NULL) { printf ("cannot create locale object for locale %s\n", locname); result = 1; } else { int c; #undef STRTEST #define STRTEST(name, exp) \ str = nl_langinfo_l (name, loc); \ if (strcmp (str, exp) != 0) \ { \ printf ("nl_langinfo_l(" #name ") in locale %s wrong " \ "(is \"%s\", should be \"%s\")\n", locname, str, exp); \ result = 1; \ } #undef WSTRTEST #define WSTRTEST(name, exp) \ wstr = (wchar_t *) nl_langinfo_l (name, loc); \ if (wcscmp (wstr, exp) != 0) \ { \ printf ("nl_langinfo_l(" #name ") in locale %s wrong " \ "(is \"%S\", should be \"%S\")\n", locname, wstr, exp); \ result = 1; \ } /* Unix stuff. */ STRTEST (ABDAY_1, "Sun"); STRTEST (ABDAY_2, "Mon"); STRTEST (ABDAY_3, "Tue"); STRTEST (ABDAY_4, "Wed"); STRTEST (ABDAY_5, "Thu"); STRTEST (ABDAY_6, "Fri"); STRTEST (ABDAY_7, "Sat"); STRTEST (DAY_1, "Sunday"); STRTEST (DAY_2, "Monday"); STRTEST (DAY_3, "Tuesday"); STRTEST (DAY_4, "Wednesday"); STRTEST (DAY_5, "Thursday"); STRTEST (DAY_6, "Friday"); STRTEST (DAY_7, "Saturday"); STRTEST (ABMON_1, "Jan"); STRTEST (ABMON_2, "Feb"); STRTEST (ABMON_3, "Mar"); STRTEST (ABMON_4, "Apr"); STRTEST (ABMON_5, "May"); STRTEST (ABMON_6, "Jun"); STRTEST (ABMON_7, "Jul"); STRTEST (ABMON_8, "Aug"); STRTEST (ABMON_9, "Sep"); STRTEST (ABMON_10, "Oct"); STRTEST (ABMON_11, "Nov"); STRTEST (ABMON_12, "Dec"); STRTEST (MON_1, "January"); STRTEST (MON_2, "February"); STRTEST (MON_3, "March"); STRTEST (MON_4, "April"); STRTEST (MON_5, "May"); STRTEST (MON_6, "June"); STRTEST (MON_7, "July"); STRTEST (MON_8, "August"); STRTEST (MON_9, "September"); STRTEST (MON_10, "October"); STRTEST (MON_11, "November"); STRTEST (MON_12, "December"); STRTEST (AM_STR, "AM"); STRTEST (PM_STR, "PM"); STRTEST (D_T_FMT, "%a %b %e %H:%M:%S %Y"); STRTEST (D_FMT, "%m/%d/%y"); STRTEST (T_FMT, "%H:%M:%S"); STRTEST (T_FMT_AMPM, "%I:%M:%S %p"); STRTEST (ERA, ""); STRTEST (ERA_D_FMT, ""); STRTEST (ERA_T_FMT, ""); STRTEST (ERA_D_T_FMT, ""); STRTEST (ALT_DIGITS, ""); STRTEST (RADIXCHAR, "."); STRTEST (THOUSEP, ""); STRTEST (YESEXPR, "^[yY]"); STRTEST (NOEXPR, "^[nN]"); /* Extensions. */ WSTRTEST (_NL_WABDAY_1, L"Sun"); WSTRTEST (_NL_WABDAY_2, L"Mon"); WSTRTEST (_NL_WABDAY_3, L"Tue"); WSTRTEST (_NL_WABDAY_4, L"Wed"); WSTRTEST (_NL_WABDAY_5, L"Thu"); WSTRTEST (_NL_WABDAY_6, L"Fri"); WSTRTEST (_NL_WABDAY_7, L"Sat"); WSTRTEST (_NL_WDAY_1, L"Sunday"); WSTRTEST (_NL_WDAY_2, L"Monday"); WSTRTEST (_NL_WDAY_3, L"Tuesday"); WSTRTEST (_NL_WDAY_4, L"Wednesday"); WSTRTEST (_NL_WDAY_5, L"Thursday"); WSTRTEST (_NL_WDAY_6, L"Friday"); WSTRTEST (_NL_WDAY_7, L"Saturday"); WSTRTEST (_NL_WABMON_1, L"Jan"); WSTRTEST (_NL_WABMON_2, L"Feb"); WSTRTEST (_NL_WABMON_3, L"Mar"); WSTRTEST (_NL_WABMON_4, L"Apr"); WSTRTEST (_NL_WABMON_5, L"May"); WSTRTEST (_NL_WABMON_6, L"Jun"); WSTRTEST (_NL_WABMON_7, L"Jul"); WSTRTEST (_NL_WABMON_8, L"Aug"); WSTRTEST (_NL_WABMON_9, L"Sep"); WSTRTEST (_NL_WABMON_10, L"Oct"); WSTRTEST (_NL_WABMON_11, L"Nov"); WSTRTEST (_NL_WABMON_12, L"Dec"); WSTRTEST (_NL_WMON_1, L"January"); WSTRTEST (_NL_WMON_2, L"February"); WSTRTEST (_NL_WMON_3, L"March"); WSTRTEST (_NL_WMON_4, L"April"); WSTRTEST (_NL_WMON_5, L"May"); WSTRTEST (_NL_WMON_6, L"June"); WSTRTEST (_NL_WMON_7, L"July"); WSTRTEST (_NL_WMON_8, L"August"); WSTRTEST (_NL_WMON_9, L"September"); WSTRTEST (_NL_WMON_10, L"October"); WSTRTEST (_NL_WMON_11, L"November"); WSTRTEST (_NL_WMON_12, L"December"); WSTRTEST (_NL_WAM_STR, L"AM"); WSTRTEST (_NL_WPM_STR, L"PM"); WSTRTEST (_NL_WD_T_FMT, L"%a %b %e %H:%M:%S %Y"); WSTRTEST (_NL_WD_FMT, L"%m/%d/%y"); WSTRTEST (_NL_WT_FMT, L"%H:%M:%S"); WSTRTEST (_NL_WT_FMT_AMPM, L"%I:%M:%S %p"); WSTRTEST (_NL_WERA_D_FMT, L""); WSTRTEST (_NL_WERA_T_FMT, L""); WSTRTEST (_NL_WERA_D_T_FMT, L""); WSTRTEST (_NL_WALT_DIGITS, L""); STRTEST (_DATE_FMT, "%a %b %e %H:%M:%S %Z %Y"); WSTRTEST (_NL_W_DATE_FMT, L"%a %b %e %H:%M:%S %Z %Y"); STRTEST (INT_CURR_SYMBOL, ""); STRTEST (CURRENCY_SYMBOL, ""); STRTEST (MON_DECIMAL_POINT, ""); STRTEST (MON_THOUSANDS_SEP, ""); STRTEST (MON_GROUPING, ""); STRTEST (POSITIVE_SIGN, ""); STRTEST (NEGATIVE_SIGN, ""); STRTEST (GROUPING, ""); STRTEST (YESSTR, ""); STRTEST (NOSTR, ""); /* Character class tests. */ for (c = 0; c < 128; ++c) { #define CLASSTEST(name) \ if (is##name (c) != is##name##_l (c, loc)) \ { \ printf ("is%s('\\%o') != is%s_l('\\%o')\n", \ #name, c, #name, c); \ result = 1; \ } CLASSTEST (alnum); CLASSTEST (alpha); CLASSTEST (blank); CLASSTEST (cntrl); CLASSTEST (digit); CLASSTEST (lower); CLASSTEST (graph); CLASSTEST (print); CLASSTEST (punct); CLASSTEST (space); CLASSTEST (upper); CLASSTEST (xdigit); /* Character mapping tests. */ #define MAPTEST(name) \ if (to##name (c) != to##name##_l (c, loc)) \ { \ printf ("to%s('\\%o') != to%s_l('\\%o'): '\\%o' vs '\\%o'\n", \ #name, c, #name, c, \ to##name (c), to##name##_l (c, loc)); \ result = 1; \ } MAPTEST (lower); MAPTEST (upper); } /* Character class tests, this time for wide characters. Note that this only works because we know that the internal encoding is UCS4. */ for (c = 0; c < 128; ++c) { #undef CLASSTEST #define CLASSTEST(name) \ if (isw##name (c) != isw##name##_l (c, loc)) \ { \ printf ("isw%s('\\%o') != isw%s_l('\\%o')\n", \ #name, c, #name, c); \ result = 1; \ } CLASSTEST (alnum); CLASSTEST (alpha); CLASSTEST (blank); CLASSTEST (cntrl); CLASSTEST (digit); CLASSTEST (lower); CLASSTEST (graph); CLASSTEST (print); CLASSTEST (punct); CLASSTEST (space); CLASSTEST (upper); CLASSTEST (xdigit); /* Character mapping tests. Note that this only works because we know that the internal encoding is UCS4. */ #undef MAPTEST #define MAPTEST(name) \ if (tow##name (c) != tow##name##_l (c, loc)) \ { \ printf ("tow%s('\\%o') != tow%s_l('\\%o'): '\\%o' vs '\\%o'\n",\ #name, c, #name, c, \ tow##name (c), tow##name##_l (c, loc)); \ result = 1; \ } MAPTEST (lower); MAPTEST (upper); } freelocale (loc); } return result; }
void _Locale_monetary_destroy( struct _Locale_monetary *__loc ) { freelocale((locale_t)__loc); }
void _Locale_collate_destroy( struct _Locale_collate *__loc ) { freelocale((locale_t)__loc); }
void _Locale_time_destroy( struct _Locale_time *__loc ) { freelocale((locale_t)__loc); }
/** * Emit a log message. This function is the variable argument list equivalent * to vlc_Log(). */ void vlc_vaLog (vlc_object_t *obj, int type, const char *module, const char *format, va_list args) { if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET) return; /* C locale to get error messages in English in the logs */ locale_t c = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); locale_t locale = uselocale (c); #ifndef __GLIBC__ /* Expand %m to strerror(errno) - only once */ char buf[strlen(format) + 2001], *ptr; strcpy (buf, format); ptr = (char*)buf; format = (const char*) buf; for( ;; ) { ptr = strchr( ptr, '%' ); if( ptr == NULL ) break; if( ptr[1] == 'm' ) { char errbuf[2001]; size_t errlen; #ifndef WIN32 strerror_r( errno, errbuf, 1001 ); #else int sockerr = WSAGetLastError( ); if( sockerr ) { strncpy( errbuf, net_strerror( sockerr ), 1001 ); WSASetLastError( sockerr ); } if ((sockerr == 0) || (strcmp ("Unknown network stack error", errbuf) == 0)) strncpy( errbuf, strerror( errno ), 1001 ); #endif errbuf[1000] = 0; /* Escape '%' from the error string */ for( char *percent = strchr( errbuf, '%' ); percent != NULL; percent = strchr( percent + 2, '%' ) ) { memmove( percent + 1, percent, strlen( percent ) + 1 ); } errlen = strlen( errbuf ); memmove( ptr + errlen, ptr + 2, strlen( ptr + 2 ) + 1 ); memcpy( ptr, errbuf, errlen ); break; /* Only once, so we don't overflow */ } /* Looks for conversion specifier... */ do ptr++; while( *ptr && ( strchr( "diouxXeEfFgGaAcspn%", *ptr ) == NULL ) ); if( *ptr ) ptr++; /* ...and skip it */ } #endif /* Fill message information fields */ msg_item_t msg; msg.i_object_id = (uintptr_t)obj; msg.psz_object_type = (obj != NULL) ? obj->psz_object_type : "generic"; msg.psz_module = module; msg.psz_header = NULL; for (vlc_object_t *o = obj; o != NULL; o = o->p_parent) if (o->psz_header != NULL) { msg.psz_header = o->psz_header; break; } /* Pass message to subscribers */ libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc); va_list ap; va_copy (ap, args); if (priv->b_color) PrintColorMsg (&priv->i_verbose, type, &msg, format, ap); else PrintMsg (&priv->i_verbose, type, &msg, format, ap); va_end (ap); vlc_rwlock_rdlock (&msg_lock); for (msg_subscription_t *sub = msg_head; sub != NULL; sub = sub->next) { va_copy (ap, args); sub->func (sub->opaque, type, &msg, format, ap); va_end (ap); } vlc_rwlock_unlock (&msg_lock); uselocale (locale); freelocale (c); }
TEST(locale, newlocale) { locale_t l = newlocale(LC_ALL, "C", 0); ASSERT_TRUE(l != NULL); freelocale(l); }
const char *GenerateEncodingShader(u32 format,API_TYPE ApiType) { #ifndef ANDROID locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation locale_t old_locale = uselocale(locale); // Apply the locale for this thread #endif text[sizeof(text) - 1] = 0x7C; // canary char *p = text; switch (format) { case GX_TF_I4: WriteI4Encoder(p, ApiType); break; case GX_TF_I8: WriteI8Encoder(p, ApiType); break; case GX_TF_IA4: WriteIA4Encoder(p, ApiType); break; case GX_TF_IA8: WriteIA8Encoder(p, ApiType); break; case GX_TF_RGB565: WriteRGB565Encoder(p, ApiType); break; case GX_TF_RGB5A3: WriteRGB5A3Encoder(p, ApiType); break; case GX_TF_RGBA8: WriteRGBA8Encoder(p, ApiType); break; case GX_CTF_R4: WriteC4Encoder(p, "r", ApiType); break; case GX_CTF_RA4: WriteCC4Encoder(p, "ar", ApiType); break; case GX_CTF_RA8: WriteCC8Encoder(p, "ar", ApiType); break; case GX_CTF_A8: WriteC8Encoder(p, "a", ApiType); break; case GX_CTF_R8: WriteC8Encoder(p, "r", ApiType); break; case GX_CTF_G8: WriteC8Encoder(p, "g", ApiType); break; case GX_CTF_B8: WriteC8Encoder(p, "b", ApiType); break; case GX_CTF_RG8: WriteCC8Encoder(p, "rg", ApiType); break; case GX_CTF_GB8: WriteCC8Encoder(p, "gb", ApiType); break; case GX_TF_Z8: WriteC8Encoder(p, "b", ApiType); break; case GX_TF_Z16: WriteZ16Encoder(p, ApiType); break; case GX_TF_Z24X8: WriteZ24Encoder(p, ApiType); break; case GX_CTF_Z4: WriteC4Encoder(p, "b", ApiType); break; case GX_CTF_Z8M: WriteZ8Encoder(p, "256.0", ApiType); break; case GX_CTF_Z8L: WriteZ8Encoder(p, "65536.0" , ApiType); break; case GX_CTF_Z16L: WriteZ16LEncoder(p, ApiType); break; default: PanicAlert("Unknown texture copy format: 0x%x\n", format); break; } if (text[sizeof(text) - 1] != 0x7C) PanicAlert("TextureConversionShader generator - buffer too small, canary has been eaten!"); #ifndef ANDROID uselocale(old_locale); // restore locale freelocale(locale); #endif return text; }
TEST(locale, duplocale) { locale_t cloned_global = duplocale(LC_GLOBAL_LOCALE); ASSERT_TRUE(cloned_global != NULL); freelocale(cloned_global); }
/** * ProjectM update thread which do the rendering * @param p_this: the p_thread object */ static void *Thread( void *p_data ) { filter_t *p_filter = (filter_t*)p_data; filter_sys_t *p_sys = p_filter->p_sys; video_format_t fmt; vlc_gl_t *gl; unsigned int i_last_width = 0; unsigned int i_last_height = 0; locale_t loc; locale_t oldloc; projectM *p_projectm; #ifndef HAVE_PROJECTM2 char *psz_config; #else char *psz_preset_path; char *psz_title_font; char *psz_menu_font; projectM::Settings settings; #endif vlc_savecancel(); /* Create the openGL provider */ p_sys->p_vout = (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) ); if( !p_sys->p_vout ) goto error; /* */ video_format_Init( &fmt, 0 ); video_format_Setup( &fmt, VLC_CODEC_RGB32, p_sys->i_width, p_sys->i_height, 0, 1 ); fmt.i_sar_num = 1; fmt.i_sar_den = 1; vout_display_state_t state; memset( &state, 0, sizeof(state) ); state.cfg.display.sar.num = 1; state.cfg.display.sar.den = 1; state.cfg.is_display_filled = true; state.cfg.zoom.num = 1; state.cfg.zoom.den = 1; state.sar.num = 1; state.sar.den = 1; p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl", 300000, 1000000 ); if( !p_sys->p_vd ) { vlc_object_release( p_sys->p_vout ); goto error; } var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL ); var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd ); gl = vout_GetDisplayOpengl( p_sys->p_vd ); if( !gl ) { vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); goto error; } /* Work-around the projectM locale bug */ loc = newlocale (LC_NUMERIC_MASK, "C", NULL); oldloc = uselocale (loc); /* Create the projectM object */ #ifndef HAVE_PROJECTM2 psz_config = var_InheritString( p_filter, "projectm-config" ); p_projectm = new projectM( psz_config ); free( psz_config ); #else psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" ); #ifdef WIN32 if ( psz_preset_path == NULL ) { char *psz_data_path = config_GetDataDir( p_filter ); asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path ); free( psz_data_path ); } #endif psz_title_font = var_InheritString( p_filter, "projectm-title-font" ); psz_menu_font = var_InheritString( p_filter, "projectm-menu-font" ); settings.meshX = var_InheritInteger( p_filter, "projectm-meshx" ); settings.meshY = var_InheritInteger( p_filter, "projectm-meshy" ); settings.fps = 35; settings.textureSize = var_InheritInteger( p_filter, "projectm-texture-size" ); settings.windowWidth = p_sys->i_width; settings.windowHeight = p_sys->i_height; settings.presetURL = psz_preset_path; settings.titleFontURL = psz_title_font; settings.menuFontURL = psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; p_projectm = new projectM( settings ); free( psz_menu_font ); free( psz_title_font ); free( psz_preset_path ); #endif /* HAVE_PROJECTM2 */ p_sys->i_buffer_size = p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); vlc_sem_post( &p_sys->ready ); /* Choose a preset randomly or projectM will always show the first one */ if ( p_projectm->getPlaylistSize() > 0 ) p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() ); /* */ for( ;; ) { const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */ /* Manage the events */ vout_ManageDisplay( p_sys->p_vd, true ); if( p_sys->p_vd->cfg->display.width != i_last_width || p_sys->p_vd->cfg->display.height != i_last_height ) { /* FIXME it is not perfect as we will have black bands */ vout_display_place_t place; vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false ); p_projectm->projectM_resetGL( place.width, place.height ); i_last_width = p_sys->p_vd->cfg->display.width; i_last_height = p_sys->p_vd->cfg->display.height; } /* Render the image and swap the buffers */ vlc_mutex_lock( &p_sys->lock ); if( p_sys->i_nb_samples > 0 ) { p_projectm->pcm()->addPCMfloat( p_sys->p_buffer, p_sys->i_nb_samples ); p_sys->i_nb_samples = 0; } if( p_sys->b_quit ) { vlc_mutex_unlock( &p_sys->lock ); delete p_projectm; vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); if (loc != (locale_t)0) { uselocale (oldloc); freelocale (loc); } return NULL; } vlc_mutex_unlock( &p_sys->lock ); p_projectm->renderFrame(); /* */ mwait( i_deadline ); if( !vlc_gl_Lock(gl) ) { vlc_gl_Swap( gl ); vlc_gl_Unlock( gl ); } } abort(); error: p_sys->b_error = true; vlc_sem_post( &p_sys->ready ); return NULL; }
/***************************************************************************** * config_LoadConfigFile: loads the configuration file. ***************************************************************************** * This function is called to load the config options stored in the config * file. *****************************************************************************/ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name ) { FILE *file; file = config_OpenConfigFile (p_this); if (file == NULL) return VLC_EGENERIC; /* Look for the selected module, if NULL then save everything */ module_t **list = module_list_get (NULL); /* Look for UTF-8 Byte Order Mark */ char * (*convert) (const char *) = strdupnull; char bom[3]; if ((fread (bom, 1, 3, file) != 3) || memcmp (bom, "\xEF\xBB\xBF", 3)) { convert = FromLocaleDup; rewind (file); /* no BOM, rewind */ } module_t *module = NULL; char line[1024], section[1022]; section[0] = '\0'; /* Ensure consistent number formatting... */ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t baseloc = uselocale (loc); while (fgets (line, 1024, file) != NULL) { /* Ignore comments and empty lines */ switch (line[0]) { case '#': case '\n': case '\0': continue; } if (line[0] == '[') { char *ptr = strchr (line, ']'); if (ptr == NULL) continue; /* syntax error; */ *ptr = '\0'; /* New section ( = a given module) */ strcpy (section, line + 1); module = NULL; if ((psz_module_name == NULL) || (strcmp (psz_module_name, section) == 0)) { for (int i = 0; list[i]; i++) { module_t *m = list[i]; if ((strcmp (section, m->psz_object_name) == 0) && (m->i_config_items > 0)) /* ignore config-less modules */ { module = m; if (psz_module_name != NULL) msg_Dbg (p_this, "loading config for module \"%s\"", section); break; } } } continue; } if (module == NULL) continue; /* no need to parse if there is no matching module */ char *ptr = strchr (line, '\n'); if (ptr != NULL) *ptr = '\0'; /* look for option name */ const char *psz_option_name = line; ptr = strchr (line, '='); if (ptr == NULL) continue; /* syntax error */ *ptr = '\0'; const char *psz_option_value = ptr + 1; /* try to match this option with one of the module's options */ for (size_t i = 0; i < module->confsize; i++) { module_config_t *p_item = module->p_config + i; if ((p_item->i_type & CONFIG_HINT) || strcmp (p_item->psz_name, psz_option_name)) continue; /* We found it */ errno = 0; vlc_mutex_lock( p_item->p_lock ); switch( p_item->i_type ) { case CONFIG_ITEM_BOOL: case CONFIG_ITEM_INTEGER: { long l = strtoi (psz_option_value); if (errno) msg_Warn (p_this, "Integer value (%s) for %s: %m", psz_option_value, psz_option_name); else p_item->saved.i = p_item->value.i = (int)l; break; } case CONFIG_ITEM_FLOAT: if( !*psz_option_value ) break; /* ignore empty option */ p_item->value.f = (float)atof (psz_option_value); p_item->saved.f = p_item->value.f; break; case CONFIG_ITEM_KEY: if( !*psz_option_value ) break; /* ignore empty option */ p_item->value.i = ConfigStringToKey(psz_option_value); p_item->saved.i = p_item->value.i; break; default: /* free old string */ free( (char*) p_item->value.psz ); free( (char*) p_item->saved.psz ); p_item->value.psz = convert (psz_option_value); p_item->saved.psz = strdupnull (p_item->value.psz); break; } vlc_mutex_unlock( p_item->p_lock ); break; } } if (ferror (file)) { msg_Err (p_this, "error reading configuration: %m"); clearerr (file); } fclose (file); module_list_free (list); if (loc != (locale_t)0) { uselocale (baseloc); freelocale (loc); } return 0; }
/* Test the gl_locale_name_thread() function. */ static void test_locale_name_thread (void) { /* Get into a defined state, */ setlocale (LC_ALL, "en_US.UTF-8"); #if HAVE_NEWLOCALE /* Check that gl_locale_name_thread returns NULL when no thread locale is set. */ uselocale (LC_GLOBAL_LOCALE); ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL); ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL); /* Check that gl_locale_name_thread considers the thread locale. */ { locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL); if (locale != NULL) { const char *name; uselocale (locale); name = gl_locale_name_thread (LC_CTYPE, "LC_CTYPE"); ASSERT (strcmp (name, "fr_FR.UTF-8") == 0); name = gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES"); ASSERT (strcmp (name, "fr_FR.UTF-8") == 0); } } /* Check that gl_locale_name_thread distinguishes different categories of the thread locale, and that the name is the right one for each. */ { unsigned int i; for (i = 0; i < SIZEOF (categories); i++) { int category_mask = categories[i].mask; locale_t locale = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", NULL); if (locale != NULL) { locale = newlocale (category_mask, "de_DE.UTF-8", locale); if (locale != NULL) { unsigned int j; uselocale (locale); for (j = 0; j < SIZEOF (categories); j++) { const char *name_j = gl_locale_name_thread (categories[j].cat, categories[j].string); if (j == i) ASSERT (strcmp (name_j, "de_DE.UTF-8") == 0); else ASSERT (strcmp (name_j, "fr_FR.UTF-8") == 0); } } } } } /* Check that gl_locale_name_thread returns a string that is allocated with indefinite extent. */ { /* Try many locale names in turn, in order to defeat possible caches. */ static const char * const choices[] = { "C", "POSIX", "af_ZA", "af_ZA.UTF-8", "am_ET", "am_ET.UTF-8", "be_BY", "be_BY.UTF-8", "bg_BG", "bg_BG.UTF-8", "ca_ES", "ca_ES.UTF-8", "cs_CZ", "cs_CZ.UTF-8", "da_DK", "da_DK.UTF-8", "de_AT", "de_AT.UTF-8", "de_CH", "de_CH.UTF-8", "de_DE", "de_DE.UTF-8", "el_GR", "el_GR.UTF-8", "en_AU", "en_AU.UTF-8", "en_CA", "en_CA.UTF-8", "en_GB", "en_GB.UTF-8", "en_IE", "en_IE.UTF-8", "en_NZ", "en_NZ.UTF-8", "en_US", "en_US.UTF-8", "es_ES", "es_ES.UTF-8", "et_EE", "et_EE.UTF-8", "eu_ES", "eu_ES.UTF-8", "fi_FI", "fi_FI.UTF-8", "fr_BE", "fr_BE.UTF-8", "fr_CA", "fr_CA.UTF-8", "fr_CH", "fr_CH.UTF-8", "fr_FR", "fr_FR.UTF-8", "he_IL", "he_IL.UTF-8", "hr_HR", "hr_HR.UTF-8", "hu_HU", "hu_HU.UTF-8", "hy_AM", "is_IS", "is_IS.UTF-8", "it_CH", "it_CH.UTF-8", "it_IT", "it_IT.UTF-8", "ja_JP.UTF-8", "kk_KZ", "kk_KZ.UTF-8", "ko_KR.UTF-8", "lt_LT", "lt_LT.UTF-8", "nl_BE", "nl_BE.UTF-8", "nl_NL", "nl_NL.UTF-8", "no_NO", "no_NO.UTF-8", "pl_PL", "pl_PL.UTF-8", "pt_BR", "pt_BR.UTF-8", "pt_PT", "pt_PT.UTF-8", "ro_RO", "ro_RO.UTF-8", "ru_RU", "ru_RU.UTF-8", "sk_SK", "sk_SK.UTF-8", "sl_SI", "sl_SI.UTF-8", "sv_SE", "sv_SE.UTF-8", "tr_TR", "tr_TR.UTF-8", "uk_UA", "uk_UA.UTF-8", "zh_CN", "zh_CN.UTF-8", "zh_HK", "zh_HK.UTF-8", "zh_TW", "zh_TW.UTF-8" }; /* Remember which locales are available. */ unsigned char /* bool */ available[SIZEOF (choices)]; /* Array of remembered results of gl_locale_name_thread. */ const char *unsaved_names[SIZEOF (choices)][SIZEOF (categories)]; /* Array of remembered results of gl_locale_name_thread, stored in safe memory. */ char *saved_names[SIZEOF (choices)][SIZEOF (categories)]; unsigned int j; for (j = 0; j < SIZEOF (choices); j++) { locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL); available[j] = (locale != NULL); if (locale != NULL) { unsigned int i; uselocale (locale); for (i = 0; i < SIZEOF (categories); i++) { unsaved_names[j][i] = gl_locale_name_thread (categories[i].cat, categories[i].string); saved_names[j][i] = strdup (unsaved_names[j][i]); } uselocale (LC_GLOBAL_LOCALE); freelocale (locale); } } /* Verify the unsaved_names are still valid. */ for (j = 0; j < SIZEOF (choices); j++) if (available[j]) { unsigned int i; for (i = 0; i < SIZEOF (categories); i++) ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0); } /* Allocate many locales, without freeing them. This is an attempt at overwriting as much of the previously allocated memory as possible. */ for (j = SIZEOF (choices); j > 0; ) { j--; if (available[j]) { locale_t locale = newlocale (LC_ALL_MASK, choices[j], NULL); unsigned int i; ASSERT (locale != NULL); uselocale (locale); for (i = 0; i < SIZEOF (categories); i++) { const char *name = gl_locale_name_thread (categories[i].cat, categories[i].string); ASSERT (strcmp (unsaved_names[j][i], name) == 0); } uselocale (LC_GLOBAL_LOCALE); } } /* Verify the unsaved_names are still valid. */ for (j = 0; j < SIZEOF (choices); j++) if (available[j]) { unsigned int i; for (i = 0; i < SIZEOF (categories); i++) ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0); } } #else /* Check that gl_locale_name_thread always returns NULL. */ ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL); ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL); #endif }
/***************************************************************************** * config_SaveConfigFile: Save a module's config options. ***************************************************************************** * This will save the specified module's config options to the config file. * If psz_module_name is NULL then we save all the modules config options. * It's no use to save the config options that kept their default values, so * we'll try to be a bit clever here. * * When we save we mustn't delete the config options of the modules that * haven't been loaded. So we cannot just create a new config file with the * config structures we've got in memory. * I don't really know how to deal with this nicely, so I will use a completly * dumb method ;-) * I will load the config file in memory, but skipping all the sections of the * modules we want to save. Then I will create a brand new file, dump the file * loaded in memory and then append the sections of the modules we want to * save. * Really stupid no ? *****************************************************************************/ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, bool b_autosave ) { module_t *p_parser; FILE *file = NULL; char *permanent = NULL, *temporary = NULL; char p_line[1024], *p_index2; unsigned long i_sizebuf = 0; char *p_bigbuffer = NULL, *p_index; bool b_backup; int i_index; if( config_PrepareDir( p_this ) ) { msg_Err( p_this, "no configuration directory" ); goto error; } file = config_OpenConfigFile( p_this ); if( file != NULL ) { struct stat st; /* Some users make vlcrc read-only to prevent changes. * The atomic replacement scheme breaks this "feature", * so we check for read-only by hand. */ if (fstat (fileno (file), &st) || !(st.st_mode & S_IWUSR)) { msg_Err (p_this, "configuration file is read-only"); goto error; } i_sizebuf = ( st.st_size < LONG_MAX ) ? st.st_size : 0; } p_bigbuffer = p_index = malloc( i_sizebuf+1 ); if( !p_bigbuffer ) goto error; p_bigbuffer[0] = 0; /* List all available modules */ module_t **list = module_list_get (NULL); /* backup file into memory, we only need to backup the sections we won't * save later on */ b_backup = false; while( file && fgets( p_line, 1024, file ) ) { if( (p_line[0] == '[') && (p_index2 = strchr(p_line,']'))) { /* we found a section, check if we need to do a backup */ for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ ) { if( ((p_index2 - &p_line[1]) == (int)strlen(p_parser->psz_object_name) ) && !memcmp( &p_line[1], p_parser->psz_object_name, strlen(p_parser->psz_object_name) ) ) { if( !psz_module_name ) break; else if( !strcmp( psz_module_name, p_parser->psz_object_name ) ) break; } } if( list[i_index] == NULL ) { /* we don't have this section in our list so we need to back * it up */ *p_index2 = 0; #if 0 msg_Dbg( p_this, "backing up config for unknown module \"%s\"", &p_line[1] ); #endif *p_index2 = ']'; b_backup = true; } else { b_backup = false; } } /* save line if requested and line is valid (doesn't begin with a * space, tab, or eol) */ if( b_backup && (p_line[0] != '\n') && (p_line[0] != ' ') && (p_line[0] != '\t') ) { strcpy( p_index, p_line ); p_index += strlen( p_line ); } } if( file ) fclose( file ); file = NULL; /* * Save module config in file */ permanent = config_GetConfigFile (p_this); if (!permanent) { module_list_free (list); goto error; } if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1) { temporary = NULL; module_list_free (list); goto error; } /* The temporary configuration file is per-PID. Therefore SaveConfigFile() * should be serialized against itself within a given process. */ static vlc_mutex_t lock = VLC_STATIC_MUTEX; vlc_mutex_lock (&lock); int fd = utf8_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (fd == -1) { vlc_mutex_unlock (&lock); module_list_free (list); goto error; } file = fdopen (fd, "wt"); if (file == NULL) { close (fd); vlc_mutex_unlock (&lock); module_list_free (list); goto error; } fprintf( file, "\xEF\xBB\xBF###\n### " COPYRIGHT_MESSAGE "\n###\n\n" "###\n### lines beginning with a '#' character are comments\n###\n\n" ); /* Ensure consistent number formatting... */ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t baseloc = uselocale (loc); /* Look for the selected module, if NULL then save everything */ for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ ) { module_config_t *p_item, *p_end; if( psz_module_name && strcmp( psz_module_name, p_parser->psz_object_name ) ) continue; if( !p_parser->i_config_items ) continue; if( psz_module_name ) msg_Dbg( p_this, "saving config for module \"%s\"", p_parser->psz_object_name ); fprintf( file, "[%s]", p_parser->psz_object_name ); if( p_parser->psz_longname ) fprintf( file, " # %s\n\n", p_parser->psz_longname ); else fprintf( file, "\n\n" ); for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize; p_item < p_end; p_item++ ) { if ((p_item->i_type & CONFIG_HINT) /* ignore hint */ || p_item->b_removed /* ignore deprecated option */ || p_item->b_unsaveable) /* ignore volatile option */ continue; vlc_mutex_lock (p_item->p_lock); /* Do not save the new value in the configuration file * if doing an autosave, and the item is not an "autosaved" one. */ bool b_retain = b_autosave && !p_item->b_autosave; if (IsConfigIntegerType (p_item->i_type)) { int val = b_retain ? p_item->saved.i : p_item->value.i; if (p_item->i_type == CONFIG_ITEM_KEY) { char *psz_key = ConfigKeyToString (val); config_Write (file, p_item->psz_text, N_("key"), val == p_item->orig.i, p_item->psz_name, "%s", psz_key ? psz_key : ""); free (psz_key); } else config_Write (file, p_item->psz_text, (p_item->i_type == CONFIG_ITEM_BOOL) ? N_("boolean") : N_("integer"), val == p_item->orig.i, p_item->psz_name, "%d", val); p_item->saved.i = val; } else if (IsConfigFloatType (p_item->i_type)) { float val = b_retain ? p_item->saved.f : p_item->value.f; config_Write (file, p_item->psz_text, N_("float"), val == p_item->orig.f, p_item->psz_name, "%f", val); p_item->saved.f = val; } else { const char *psz_value = b_retain ? p_item->saved.psz : p_item->value.psz; bool modified; assert (IsConfigStringType (p_item->i_type)); if (b_retain && (psz_value == NULL)) /* FIXME: hack */ psz_value = p_item->orig.psz; modified = (psz_value != NULL) ? ((p_item->orig.psz != NULL) ? (strcmp (psz_value, p_item->orig.psz) != 0) : true) : (p_item->orig.psz != NULL); config_Write (file, p_item->psz_text, N_("string"), !modified, p_item->psz_name, "%s", psz_value ? psz_value : ""); if ( !b_retain ) { free ((char *)p_item->saved.psz); if( (psz_value && p_item->orig.psz && strcmp( psz_value, p_item->orig.psz )) || !psz_value || !p_item->orig.psz) p_item->saved.psz = strdupnull (psz_value); else p_item->saved.psz = NULL; } } if (!b_retain) p_item->b_dirty = false; vlc_mutex_unlock (p_item->p_lock); } } module_list_free (list); if (loc != (locale_t)0) { uselocale (baseloc); freelocale (loc); } /* * Restore old settings from the config in file */ fputs( p_bigbuffer, file ); free( p_bigbuffer ); /* * Flush to disk and replace atomically */ fflush (file); /* Flush from run-time */ #ifndef WIN32 fdatasync (fd); /* Flush from OS */ /* Atomically replace the file... */ if (utf8_rename (temporary, permanent)) utf8_unlink (temporary); /* (...then synchronize the directory, err, TODO...) */ /* ...and finally close the file */ vlc_mutex_unlock (&lock); #endif fclose (file); #ifdef WIN32 /* Windows cannot remove open files nor overwrite existing ones */ utf8_unlink (permanent); if (utf8_rename (temporary, permanent)) utf8_unlink (temporary); vlc_mutex_unlock (&lock); #endif free (temporary); free (permanent); return 0; error: if( file ) fclose( file ); free (temporary); free (permanent); free( p_bigbuffer ); return -1; }
inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, u32 components) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) pixel_shader_uid_data dummy_data; pixel_shader_uid_data& uid_data = (&out.template GetUidData<pixel_shader_uid_data>() != NULL) ? out.template GetUidData<pixel_shader_uid_data>() : dummy_data; #ifndef ANDROID locale_t locale; locale_t old_locale; #endif if (Write_Code) { out.SetBuffer(text); #ifndef ANDROID locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation old_locale = uselocale(locale); // Apply the locale for this thread #endif text[sizeof(text) - 1] = 0x7C; // canary } unsigned int numStages = bpmem.genMode.numtevstages + 1; unsigned int numTexgen = bpmem.genMode.numtexgens; const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest(); const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z && dstAlphaMode != DSTALPHA_NULL); bool lightingEnabled = xfregs.numChan.numColorChans > 0; bool enable_pl = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting && lightingEnabled; uid_data.pixel_lighting = enable_pl; uid_data.dstAlphaMode = dstAlphaMode; uid_data.genMode_numindstages = bpmem.genMode.numindstages; uid_data.genMode_numtevstages = bpmem.genMode.numtevstages; uid_data.genMode_numtexgens = bpmem.genMode.numtexgens; if (ApiType == API_D3D11) { uid_data.tex_pcformat.samp0 = TextureCache::getStagePCelementCount(0); uid_data.tex_pcformat.samp1 = TextureCache::getStagePCelementCount(1); uid_data.tex_pcformat.samp2 = TextureCache::getStagePCelementCount(2); uid_data.tex_pcformat.samp3 = TextureCache::getStagePCelementCount(3); uid_data.tex_pcformat.samp4 = TextureCache::getStagePCelementCount(4); uid_data.tex_pcformat.samp5 = TextureCache::getStagePCelementCount(5); uid_data.tex_pcformat.samp6 = TextureCache::getStagePCelementCount(6); uid_data.tex_pcformat.samp7 = TextureCache::getStagePCelementCount(7); } if (Write_Code) { InitializeRegisterState(); out.Write("//Pixel Shader for TEV stages\n"); out.Write("//%i TEV stages, %i texgens, %i IND stages\n", numStages, numTexgen, bpmem.genMode.numindstages); out.Write(headerUtil); if (ApiType == API_OPENGL) { // Declare samplers for (u32 i = 0; i < 8; ++i) out.Write("uniform sampler2D samp%d;\n", i); } else { // Declare samplers for (u32 i = 0; i < 8; ++i) out.Write("%s samp%d : register(s%d);\n", (ApiType == API_D3D11) ? "sampler" : "uniform sampler2D", i, i); if (ApiType == API_D3D11) { out.Write("\n"); for (u32 i = 0; i < 8; ++i) { out.Write("Texture2D Tex%d : register(t%d);\n", i, i); } } } out.Write("\n"); if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("layout(std140) uniform PSBlock {\n"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_COLORS, "float4", I_COLORS "[4]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_KCOLORS, "float4", I_KCOLORS "[4]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_ALPHA, "float4", I_ALPHA); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_TEXDIMS, "float4", I_TEXDIMS "[8]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_ZBIAS, "float4", I_ZBIAS "[2]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_INDTEXSCALE, "float4", I_INDTEXSCALE "[2]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_INDTEXMTX, "float4", I_INDTEXMTX "[6]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_FOG, "float4", I_FOG "[3]"); if (enable_pl) { DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_PLIGHTS, "float4", I_PLIGHTS "[40]"); DeclareUniform<T, ApiType>(out, g_ActiveConfig.backend_info.bSupportsGLSLUBO, C_PMATERIALS, "float4", I_PMATERIALS "[4]"); } if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) out.Write("};\n"); if (ApiType == API_OPENGL) { out.Write("out vec4 ocol0;\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) out.Write("out vec4 ocol1;\n"); if (per_pixel_depth) out.Write("#define depth gl_FragDepth\n"); out.Write("VARYIN float4 colors_02;\n"); out.Write("VARYIN float4 colors_12;\n"); // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes if (numTexgen < 7) { for (u32 i = 0; i < numTexgen; ++i) { out.Write("VARYIN float3 uv%d_2;\n", i); } out.Write("VARYIN float4 clipPos_2;\n"); if (enable_pl) { out.Write("VARYIN float4 Normal_2;\n"); } } else { // wpos is in w of first 4 texcoords if (enable_pl) { for (u32 i = 0; i < 8; ++i) { out.Write("VARYIN float4 uv%d_2;\n", i); } } else { for (u32 i = 0; i < numTexgen; ++i) { out.Write("VARYIN float%d uv%d_2;\n", i < 4 ? 4 : 3, i); } } out.Write("float4 clipPos;\n"); } if (forced_early_z) { // HACK: This doesn't force the driver to write to depth buffer if alpha test fails. // It just allows it, but it seems that all drivers do. out.Write("layout(early_fragment_tests) in;\n"); } out.Write("void main()\n{\n"); } else { if (forced_early_z) { out.Write("[earlydepthstencil]\n"); } out.Write("void main(\n"); if (ApiType != API_D3D11) { out.Write(" out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", per_pixel_depth ? "\n out float depth : DEPTH," : "", ApiType == API_D3D9_SM20 ? "POSITION" : "VPOS"); } else { out.Write(" out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", per_pixel_depth ? "\n out float depth : SV_Depth," : ""); } // "centroid" attribute is only supported by D3D11 const char* optCentroid = (ApiType == API_D3D11 ? "centroid" : ""); out.Write(" in %s float4 colors_0 : COLOR0,\n", optCentroid); out.Write(" in %s float4 colors_1 : COLOR1", optCentroid); // compute window position if needed because binding semantic WPOS is not widely supported if (numTexgen < 7) { for (unsigned int i = 0; i < numTexgen; ++i) out.Write(",\n in %s float3 uv%d : TEXCOORD%d", optCentroid, i, i); out.Write(",\n in %s float4 clipPos : TEXCOORD%d", optCentroid, numTexgen); if (enable_pl) out.Write(",\n in %s float4 Normal : TEXCOORD%d", optCentroid, numTexgen + 1); out.Write(" ) {\n"); } else { // wpos is in w of first 4 texcoords if (enable_pl) { for (u32 i = 0; i < 8; ++i) out.Write(",\n in float4 uv%d : TEXCOORD%d", i, i); } else { for (u32 i = 0; i < numTexgen; ++i) out.Write(",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3, i, i); } out.Write(" ) {\n"); out.Write("float4 clipPos = float4(0.0,0.0,0.0,0.0);"); } } if (dstAlphaMode == DSTALPHA_NULL) { out.Write("ocol0 = float4(0.0,0.0,0.0,0.0);\n"); out.Write("}\n"); if (text[sizeof(text) - 1] != 0x7C) PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); #ifndef ANDROID uselocale(old_locale); // restore locale freelocale(locale); #endif return; } out.Write("float4 c0 = " I_COLORS "[1], c1 = " I_COLORS "[2], c2 = " I_COLORS "[3], prev = " I_COLORS "[0];\n" "float4 tex_t = float4(0.0,0.0,0.0,0.0), ras_t = float4(0.0,0.0,0.0,0.0), konst_t = float4(0.0,0.0,0.0,0.0);\n" "float3 c16 = float3(1.0,256.0,0.0), c24 = float3(1.0,256.0,256.0*256.0);\n" "float a_bump=0.0;\n" "float3 tevcoord=float3(0.0,0.0,0.0);\n" "float2 wrappedcoord=float2(0.0,0.0), t_coord=float2(0.0,0.0),ittmpexp=float2(0.0,0.0);\n" "float4 tin_a = float4(0.0,0.0,0.0,0.0), tin_b = float4(0.0,0.0,0.0,0.0), tin_c = float4(0.0,0.0,0.0,0.0), tin_d = float4(0.0,0.0,0.0,0.0);\n\n"); if (ApiType == API_OPENGL) { // On Mali, global variables must be initialized as constants. // This is why we initialize these variables locally instead. out.Write("float4 rawpos = gl_FragCoord;\n"); out.Write("float4 colors_0 = colors_02;\n"); out.Write("float4 colors_1 = colors_12;\n"); // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes if (numTexgen < 7) { if (numTexgen) { for (u32 i = 0; i < numTexgen; ++i) { out.Write("float3 uv%d = uv%d_2;\n", i, i); } } out.Write("float4 clipPos = clipPos_2;\n"); if (enable_pl) { out.Write("float4 Normal = Normal_2;\n"); } } else { // wpos is in w of first 4 texcoords if (enable_pl) { for (u32 i = 0; i < 8; ++i) { out.Write("float4 uv%d = uv%d_2;\n", i, i); } } else { for (u32 i = 0; i < numTexgen; ++i) { out.Write("float%d uv%d = uv%d_2;\n", i < 4 ? 4 : 3, i, i); } } } } } if (enable_pl) { if (Write_Code) { if (xfregs.numChan.numColorChans > 0) { if (numTexgen < 7) { out.Write("float3 _norm0 = normalize(Normal.xyz);\n\n"); out.Write("float3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n"); } else { out.Write("float3 _norm0 = normalize(float3(uv4.w,uv5.w,uv6.w));\n\n"); out.Write("float3 pos = float3(uv0.w,uv1.w,uv7.w);\n"); } out.Write("float4 mat, lacc;\n" "float3 ldir, h;\n" "float dist, dist2, attn;\n"); } } uid_data.components = components; GenerateLightingShader<T, Write_Code>(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); } if (Write_Code) { if (numTexgen < 7) out.Write("clipPos = float4(rawpos.x, rawpos.y, clipPos.z, clipPos.w);\n"); else out.Write("clipPos = float4(rawpos.x, rawpos.y, uv2.w, uv3.w);\n"); } // HACK to handle cases where the tex gen is not enabled if (numTexgen == 0) { if (Write_Code) out.Write("float3 uv0 = float3(0.0,0.0,0.0);\n"); } else { for (unsigned int i = 0; i < numTexgen; ++i) { // optional perspective divides uid_data.texMtxInfo_n_projection |= xfregs.texMtxInfo[i].projection << i; if (Write_Code) { if (xfregs.texMtxInfo[i].projection == XF_TEXPROJ_STQ) { out.Write("if (uv%d.z != 0.0)", i); out.Write("\tuv%d.xy = uv%d.xy / uv%d.z;\n", i, i, i); } out.Write("uv%d.xy = round(128.0 * uv%d.xy * " I_TEXDIMS"[%d].zw);\n", i, i, i); } } } // indirect texture map lookup int nIndirectStagesUsed = 0; if (bpmem.genMode.numindstages > 0) { for (unsigned int i = 0; i < numStages; ++i) { if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; } } uid_data.nIndirectStagesUsed = nIndirectStagesUsed; for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) { if (nIndirectStagesUsed & (1 << i)) { unsigned int texcoord = bpmem.tevindref.getTexCoord(i); unsigned int texmap = bpmem.tevindref.getTexMap(i); uid_data.SetTevindrefValues(i, texcoord, texmap); if (Write_Code) { if (texcoord < numTexgen) { out.Write("t_coord = BSH(uv%d.xy , " I_INDTEXSCALE"[%d].%s);\n", texcoord, i / 2, (i & 1) ? "zw" : "xy"); } else { out.Write("t_coord = float2(0.0,0.0);\n"); } out.Write("float3 indtex%d = ", i); SampleTexture<T, Write_Code, ApiType>(out, "(t_coord/128.0)", "abg", texmap); } } } // Uid fields for BuildSwapModeTable are set in WriteStage char swapModeTable[4][5]; const char* swapColors = "rgba"; for (int i = 0; i < 4; i++) { swapModeTable[i][0] = swapColors[bpmem.tevksel[i * 2].swap1]; swapModeTable[i][1] = swapColors[bpmem.tevksel[i * 2].swap2]; swapModeTable[i][2] = swapColors[bpmem.tevksel[i * 2 + 1].swap1]; swapModeTable[i][3] = swapColors[bpmem.tevksel[i * 2 + 1].swap2]; swapModeTable[i][4] = '\0'; } for (unsigned int i = 0; i < numStages; i++) WriteStage<T, Write_Code, ApiType>(out, uid_data, i, swapModeTable); // build the equation for this stage if (Write_Code) { u32 colorCdest = bpmem.combiners[numStages - 1].colorC.dest; u32 alphaCdest = bpmem.combiners[numStages - 1].alphaC.dest; if (numStages) { // The results of the last texenv stage are put onto the screen, // regardless of the used destination register if (colorCdest != 0) { out.Write("prev.rgb = %s;\n", tevCOutputTable[colorCdest]); } if (alphaCdest != 0) { out.Write("prev.a = %s;\n", tevAOutputTable[alphaCdest]); } } // emulation of unsigned 8 overflow if (TevOverflowState[tevCOutputSourceMap[colorCdest]] || TevOverflowState[tevAOutputSourceMap[alphaCdest]]) out.Write("prev = CHK_O_U8(prev);\n"); } AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); uid_data.Pretest = Pretest; // NOTE: Fragment may not be discarded if alpha test always fails and early depth test is enabled // (in this case we need to write a depth value if depth test passes regardless of the alpha testing result) if (Pretest != AlphaTest::PASS) WriteAlphaTest<T, Write_Code, ApiType>(out, uid_data, dstAlphaMode, per_pixel_depth); // D3D9 doesn't support readback of depth in pixel shader, so we always have to calculate it again. // This shouldn't be a performance issue as the written depth is usually still from perspective division // but this isn't true for z-textures, so there will be depth issues between enabled and disabled z-textures fragments if ((ApiType == API_OPENGL || ApiType == API_D3D11) && g_ActiveConfig.bFastDepthCalc) { if (Write_Code) { out.Write("float zCoord = rawpos.z;\n"); } } else { // the screen space depth value = far z + (clip z / clip w) * z range if (Write_Code) { out.Write("float zCoord = " I_ZBIAS "[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS "[1].y;\n"); } } // depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either const bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel; uid_data.ztex_op = bpmem.ztex2.op; uid_data.per_pixel_depth = per_pixel_depth; uid_data.forced_early_z = forced_early_z; uid_data.fast_depth_calc = g_ActiveConfig.bFastDepthCalc; uid_data.early_ztest = bpmem.UseEarlyDepthTest(); uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel; // Note: z-textures are not written to depth buffer if early depth test is used if (per_pixel_depth && bpmem.UseEarlyDepthTest() && Write_Code) out.Write("depth = zCoord;\n"); // Note: depth texture output is only written to depth buffer if late depth test is used // theoretical final depth value is used for fog calculation, though, so we have to emulate ztextures anyway if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !skip_ztexture) { // use the texture input of the last texture stage (tex_t), hopefully this has been read and is in correct format... if (Write_Code) { out.Write("zCoord = dot(" I_ZBIAS"[0].xyzw, tex_t.xyzw * (1.0/255.0)) + " I_ZBIAS "[1].w %s;\n", (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : ""); // U24 overflow emulation disabled because problems caused by float rounding //out.Write("zCoord = CHK_O_U24(zCoord);\n"); } } if (per_pixel_depth && bpmem.UseLateDepthTest() && Write_Code) out.Write("depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) { if (Write_Code) out.Write("ocol0 = float4(prev.rgb," I_ALPHA ".a) * (1.0/255.0);\n"); } else { WriteFog<T, Write_Code>(out, uid_data); if (Write_Code) out.Write("ocol0 = prev * (1.0/255.0);\n"); } // Use dual-source color blending to perform dst alpha in a single pass if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { if (Write_Code) { if (ApiType & API_D3D9) { // alpha component must be 0 or the shader will not compile (Direct3D 9Ex restriction) // Colors will be blended against the color from ocol1 in D3D 9... out.Write("ocol1 = float4(prev.a, prev.a, prev.a, 0.0) * (1.0/255.0);\n"); } else { // Colors will be blended against the alpha from ocol1... out.Write("ocol1 = prev * (1.0/255.0);\n"); } // ...and the alpha from ocol0 will be written to the framebuffer. out.Write("ocol0.a = " I_ALPHA ".a*(1.0/255.0);\n"); } } if (Write_Code) { out.Write("}\n"); if (text[sizeof(text) - 1] != 0x7C) PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); #ifndef ANDROID uselocale(old_locale); // restore locale freelocale(locale); #endif } }
JSonScanner::~JSonScanner() { freelocale(m_C_locale); }
/***************************************************************************** * config_LoadConfigFile: loads the configuration file. ***************************************************************************** * This function is called to load the config options stored in the config * file. *****************************************************************************/ int config_LoadConfigFile( vlc_object_t *p_this ) { FILE *file; file = config_OpenConfigFile (p_this); if (file == NULL) return VLC_EGENERIC; /* Look for UTF-8 Byte Order Mark */ char * (*convert) (const char *) = strdupnull; char bom[3]; if ((fread (bom, 1, 3, file) != 3) || memcmp (bom, "\xEF\xBB\xBF", 3)) { convert = FromLocaleDup; rewind (file); /* no BOM, rewind */ } char *line = NULL; size_t bufsize; ssize_t linelen; /* Ensure consistent number formatting... */ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t baseloc = uselocale (loc); vlc_rwlock_wrlock (&config_lock); while ((linelen = getline (&line, &bufsize, file)) != -1) { line[linelen - 1] = '\0'; /* trim newline */ /* Ignore comments, section and empty lines */ if (memchr ("#[", line[0], 3) != NULL) continue; /* look for option name */ const char *psz_option_name = line; char *ptr = strchr (line, '='); if (ptr == NULL) continue; /* syntax error */ *ptr = '\0'; module_config_t *item = config_FindConfig (p_this, psz_option_name); if (item == NULL) continue; const char *psz_option_value = ptr + 1; switch (item->i_type) { case CONFIG_ITEM_BOOL: case CONFIG_ITEM_INTEGER: { int64_t l; errno = 0; l = strtoi (psz_option_value); if ((l > item->max.i) || (l < item->min.i)) errno = ERANGE; if (errno) msg_Warn (p_this, "Integer value (%s) for %s: %m", psz_option_value, psz_option_name); else item->saved.i = item->value.i = l; break; } case CONFIG_ITEM_FLOAT: if (!*psz_option_value) break; /* ignore empty option */ item->value.f = (float)atof (psz_option_value); item->saved.f = item->value.f; break; default: free ((char *)item->value.psz); free ((char *)item->saved.psz); item->value.psz = convert (psz_option_value); item->saved.psz = strdupnull (item->value.psz); break; } } vlc_rwlock_unlock (&config_lock); free (line); if (ferror (file)) { msg_Err (p_this, "error reading configuration: %m"); clearerr (file); } fclose (file); if (loc != (locale_t)0) { uselocale (baseloc); freelocale (loc); } return 0; }
/** * Saves the in-memory configuration into a file. * @return 0 on success, -1 on error. */ int config_SaveConfigFile (vlc_object_t *p_this) { if( config_PrepareDir( p_this ) ) { msg_Err( p_this, "no configuration directory" ); return -1; } /* * Save module config in file */ char *temporary; char *permanent = config_GetConfigFile (p_this); if (permanent == NULL) return -1; if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1) { free (permanent); return -1; } else { struct stat st; /* Some users make vlcrc read-only to prevent changes. * The atomic replacement scheme breaks this "feature", * so we check for read-only by hand. */ if (stat (permanent, &st) == 0 && !(st.st_mode & S_IWUSR)) { msg_Err (p_this, "configuration file is read-only"); goto error; } } /* Configuration lock must be taken before vlcrc serializer below. */ vlc_rwlock_rdlock (&config_lock); /* The temporary configuration file is per-PID. Therefore this function * should be serialized against itself within a given process. */ static vlc_mutex_t lock = VLC_STATIC_MUTEX; vlc_mutex_lock (&lock); int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (fd == -1) { vlc_rwlock_unlock (&config_lock); vlc_mutex_unlock (&lock); goto error; } FILE *file = fdopen (fd, "wt"); if (file == NULL) { msg_Err (p_this, "cannot create configuration file: %s", vlc_strerror_c(errno)); vlc_rwlock_unlock (&config_lock); close (fd); vlc_mutex_unlock (&lock); goto error; } fprintf( file, "\xEF\xBB\xBF###\n" "### "PACKAGE_NAME" "PACKAGE_VERSION"\n" "###\n" "\n" "###\n" "### lines beginning with a '#' character are comments\n" "###\n" "\n" ); /* Ensure consistent number formatting... */ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t baseloc = uselocale (loc); /* We would take the config lock here. But this would cause a lock * inversion with the serializer above and config_AutoSaveConfigFile(). vlc_rwlock_rdlock (&config_lock);*/ /* Look for the selected module, if NULL then save everything */ size_t count; module_t **list = module_list_get (&count); for (size_t i = 0; i < count; i++) { module_t *p_parser = list[i]; module_config_t *p_item, *p_end; if( !p_parser->i_config_items ) continue; fprintf( file, "[%s]", module_get_object (p_parser) ); if( p_parser->psz_longname ) fprintf( file, " # %s\n\n", p_parser->psz_longname ); else fprintf( file, "\n\n" ); for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize; p_item < p_end; p_item++ ) { if (!CONFIG_ITEM(p_item->i_type) /* ignore hint */ || p_item->b_removed /* ignore deprecated option */ || p_item->b_unsaveable) /* ignore volatile option */ continue; if (IsConfigIntegerType (p_item->i_type)) { int64_t val = p_item->value.i; config_Write (file, p_item->psz_text, (CONFIG_CLASS(p_item->i_type) == CONFIG_ITEM_BOOL) ? N_("boolean") : N_("integer"), val == p_item->orig.i, p_item->psz_name, "%"PRId64, val); } else if (IsConfigFloatType (p_item->i_type)) { float val = p_item->value.f; config_Write (file, p_item->psz_text, N_("float"), val == p_item->orig.f, p_item->psz_name, "%f", val); } else { const char *psz_value = p_item->value.psz; bool modified; assert (IsConfigStringType (p_item->i_type)); modified = !!strcmp (psz_value ? psz_value : "", p_item->orig.psz ? p_item->orig.psz : ""); config_Write (file, p_item->psz_text, N_("string"), !modified, p_item->psz_name, "%s", psz_value ? psz_value : ""); } } } vlc_rwlock_unlock (&config_lock); module_list_free (list); if (loc != (locale_t)0) { uselocale (baseloc); freelocale (loc); } /* * Flush to disk and replace atomically */ fflush (file); /* Flush from run-time */ if (ferror (file)) { vlc_unlink (temporary); vlc_mutex_unlock (&lock); msg_Err (p_this, "cannot write configuration file"); fclose (file); goto error; } #if defined(__APPLE__) || defined(__ANDROID__) fsync (fd); /* Flush from OS */ #else fdatasync (fd); /* Flush from OS */ #endif #if defined (_WIN32) || defined (__OS2__) /* Windows cannot (re)move open files nor overwrite existing ones */ fclose (file); vlc_unlink (permanent); #endif /* Atomically replace the file... */ if (vlc_rename (temporary, permanent)) vlc_unlink (temporary); /* (...then synchronize the directory, err, TODO...) */ /* ...and finally close the file */ vlc_mutex_unlock (&lock); #if !defined (_WIN32) && !defined (__OS2__) fclose (file); #endif free (temporary); free (permanent); return 0; error: free (temporary); free (permanent); return -1; }
void utf_done(void) { freelocale(l); l = NULL; }
/** * Emit a log message. This function is the variable argument list equivalent * to vlc_Log(). */ void vlc_vaLog (vlc_object_t *obj, int type, const char *module, const char *format, va_list args) { if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET) return; /* Get basename from the module filename */ char *p = strrchr(module, '/'); if (p != NULL) module = p; p = strchr(module, '.'); size_t modlen = (p != NULL) ? (p - module) : 1; char modulebuf[modlen]; if (p != NULL) { memcpy(modulebuf, module, modlen); modulebuf[modlen] = '\0'; module = modulebuf; } /* C locale to get error messages in English in the logs */ locale_t c = newlocale (LC_MESSAGES_MASK, "C", (locale_t)0); locale_t locale = uselocale (c); #ifndef __GLIBC__ /* Expand %m to strerror(errno) - only once */ char buf[strlen(format) + 2001], *ptr; strcpy (buf, format); ptr = (char*)buf; format = (const char*) buf; for( ;; ) { ptr = strchr( ptr, '%' ); if( ptr == NULL ) break; if( ptr[1] == 'm' ) { char errbuf[2001]; size_t errlen; #ifndef _WIN32 strerror_r( errno, errbuf, 1001 ); #else int sockerr = WSAGetLastError( ); if( sockerr ) { strncpy( errbuf, net_strerror( sockerr ), 1001 ); WSASetLastError( sockerr ); } if ((sockerr == 0) || (strcmp ("Unknown network stack error", errbuf) == 0)) strncpy( errbuf, strerror( errno ), 1001 ); #endif errbuf[1000] = 0; /* Escape '%' from the error string */ for( char *percent = strchr( errbuf, '%' ); percent != NULL; percent = strchr( percent + 2, '%' ) ) { memmove( percent + 1, percent, strlen( percent ) + 1 ); } errlen = strlen( errbuf ); memmove( ptr + errlen, ptr + 2, strlen( ptr + 2 ) + 1 ); memcpy( ptr, errbuf, errlen ); break; /* Only once, so we don't overflow */ } /* Looks for conversion specifier... */ do ptr++; while( *ptr && ( strchr( "diouxXeEfFgGaAcspn%", *ptr ) == NULL ) ); if( *ptr ) ptr++; /* ...and skip it */ } #endif /* Fill message information fields */ vlc_log_t msg; msg.i_object_id = (uintptr_t)obj; msg.psz_object_type = (obj != NULL) ? obj->psz_object_type : "generic"; msg.psz_module = module; msg.psz_header = NULL; for (vlc_object_t *o = obj; o != NULL; o = o->p_parent) if (o->psz_header != NULL) { msg.psz_header = o->psz_header; break; } /* Pass message to the callback */ libvlc_priv_t *priv = obj ? libvlc_priv (obj->p_libvlc) : NULL; #ifdef _WIN32 va_list ap; va_copy (ap, args); Win32DebugOutputMsg (priv ? &priv->log.verbose : NULL, type, &msg, format, ap); va_end (ap); #endif if (priv) { vlc_rwlock_rdlock (&priv->log.lock); priv->log.cb (priv->log.opaque, type, &msg, format, args); vlc_rwlock_unlock (&priv->log.lock); } uselocale (locale); freelocale (c); }