FBSTRING *fb_DrvIntlGetMonthName( int month, int short_names ) { const char *pszName; FBSTRING *result; size_t name_len; nl_item index; if( month < 1 || month > 12 ) return NULL; if( short_names ) { index = (nl_item) (ABMON_1 + month - 1); } else { index = (nl_item) (MON_1 + month - 1); } FB_LOCK(); pszName = nl_langinfo( index ); if( pszName==NULL ) { FB_UNLOCK(); return NULL; } name_len = strlen( pszName ); result = fb_hStrAllocTemp( NULL, name_len ); if( result!=NULL ) { FB_MEMCPY( result->data, pszName, name_len + 1 ); } FB_UNLOCK(); return result; }
FBSTRING *fb_DrvIntlGetWeekdayName( int weekday, int short_names ) { char *pszName = NULL; size_t name_len; LCTYPE lctype; FBSTRING *result; if( weekday < 1 || weekday > 7 ) return NULL; if( weekday==1 ) weekday = 8; if( short_names ) { lctype = (LCTYPE) (LOCALE_SABBREVDAYNAME1 + weekday - 2); } else { lctype = (LCTYPE) (LOCALE_SDAYNAME1 + weekday - 2); } pszName = fb_hGetLocaleInfo( LOCALE_USER_DEFAULT, lctype, NULL, 0 ); if( pszName==NULL ) return NULL; name_len = strlen(pszName); result = fb_hStrAllocTemp( NULL, name_len ); if( result!=NULL ) { /* !!!FIXME!!! GetCodepage() should become a hook function for console and gfx modes */ int target_cp = /*( FB_GFX_ACTIVE() ? FB_GFX_GET_CODEPAGE() : GetConsoleCP() );*/ GetConsoleCP(); if( target_cp!=-1 ) { FB_MEMCPY( result->data, pszName, name_len + 1 ); result = fb_hIntlConvertString( result, CP_ACP, target_cp ); } } free( pszName ); return result; }
/*:::::*/ FBCALL int fb_ExecEx ( FBSTRING *program, FBSTRING *args, int do_fork ) { char buffer[MAX_PATH+1], *application, *arguments; int res = 0, got_program; size_t len_arguments; #ifndef HOST_MINGW size_t len_program; #endif got_program = (program != NULL) && (program->data != NULL); if( !got_program ) { fb_hStrDelTemp( args ); fb_hStrDelTemp( program ); return -1; } application = fb_hGetShortPath( program->data, buffer, MAX_PATH ); DBG_ASSERT( application!=NULL ); if( application==program->data ) { application = buffer; FB_MEMCPY(application, program->data, FB_STRSIZE( program ) ); } #ifdef HOST_MINGW if( args==NULL ) { arguments = ""; } else { len_arguments = FB_STRSIZE( args ); arguments = alloca( len_arguments + 1 ); DBG_ASSERT( arguments!=NULL ); if( len_arguments ) FB_MEMCPY( arguments, args->data, len_arguments ); arguments[len_arguments] = 0; } #else len_program = strlen( buffer ); len_arguments = ( ( args==NULL ) ? 0 : FB_STRSIZE( args ) ); arguments = alloca( len_program + len_arguments + 2 ); DBG_ASSERT( arguments!=NULL ); FB_MEMCPY( arguments, buffer, len_program ); arguments[len_program] = ' '; if( len_arguments!=0 ) FB_MEMCPY( arguments + len_program + 1, args->data, len_arguments ); arguments[len_program + len_arguments + 1] = 0; #endif FB_STRLOCK(); fb_hStrDelTemp_NoLock( args ); fb_hStrDelTemp_NoLock( program ); FB_STRUNLOCK(); FB_CON_CORRECT_POSITION(); { #ifdef HOST_MINGW if( do_fork ) res = _spawnl( _P_WAIT, buffer, buffer, arguments, NULL ); else res = _execl( buffer, buffer, arguments, NULL ); #else STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; memset( &StartupInfo, 0, sizeof(StartupInfo) ); StartupInfo.cb = sizeof(StartupInfo); if( !CreateProcess( NULL, /* application name - correct! */ arguments, /* command line */ NULL, NULL, /* default security descriptors */ FALSE, /* don't inherit handles */ CREATE_DEFAULT_ERROR_MODE, /* do we really need this? */ NULL, /* default environment */ NULL, /* current directory */ &StartupInfo, &ProcessInfo ) ) { res = -1; } else { /* Release main thread handle - we're not interested in it */ CloseHandle( ProcessInfo.hThread ); if( do_fork ) { DWORD dwExitCode; WaitForSingleObject( ProcessInfo.hProcess, INFINITE ); if( !GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) ) { res = -1; } else { res = (int) dwExitCode; } CloseHandle( ProcessInfo.hProcess ); } else { res = (int) ProcessInfo.hProcess; } } #endif } return res; }
/*:::::*/ FBCALL int fb_ExecEx ( FBSTRING *program, FBSTRING *args, int do_fork ) { char buffer[MAX_PATH+1], *application, *arguments, **argv, *p; int i, argc = 0, res = -1, status, len_program, len_arguments; pid_t pid; if( (program == NULL) || (program->data == NULL) ) { fb_hStrDelTemp( args ); fb_hStrDelTemp( program ); return -1; } application = fb_hGetShortPath( program->data, buffer, MAX_PATH ); DBG_ASSERT( application!=NULL ); if( application==program->data ) { len_program = FB_STRSIZE( program ); application = buffer; FB_MEMCPY(application, program->data, len_program ); application[len_program] = 0; } fb_hConvertPath( application ); if( args==NULL ) { arguments = ""; } else { len_arguments = FB_STRSIZE( args ); arguments = alloca( len_arguments + 1 ); DBG_ASSERT( arguments!=NULL ); arguments[len_arguments] = 0; if( len_arguments ) argc = fb_hParseArgs( arguments, args->data, len_arguments ); } FB_STRLOCK(); fb_hStrDelTemp_NoLock( args ); fb_hStrDelTemp_NoLock( program ); FB_STRUNLOCK(); if( argc == -1 ) return -1; argc++; /* add 1 for program name */ argv = alloca( sizeof(char*) * (argc + 1 )); DBG_ASSERT( argv!=NULL ); argv[0] = application; /* scan the processed args and set pointers */ p = arguments; for( i=1 ; i<argc; i++) { argv[i] = p; /* set pointer to current argument */ while( *p++ ); /* skip to 1 char past next null char */ } argv[argc] = NULL; /* Launch */ fb_hExitConsole(); if( do_fork ) { pid = fork(); if( pid != -1 ) { if (pid == 0) { /* execvp() only returns if it failed */ execvp( application, argv ); /* HACK: execvp() failed, this must be communiated to the parent process *somehow*, so fb_ExecEx() can return -1 there */ exit( 255 ); /* FIXME: won't be able to tell the difference if the exec'ed program returned 255. Maybe a pipe could be used instead of the 255 exit code? Unless that's too slow/has side-effects */ } else if( (waitpid(pid, &status, 0) > 0) && WIFEXITED(status) ) { res = WEXITSTATUS(status); if( res == 255 ) { /* See the HACK above */ res = -1; } } } } else { res = execvp( application, argv ); } fb_hInitConsole(); return res; }
int fb_DrvIntlGetTimeFormat( char *buffer, size_t len ) { char achFormat[90], *pszFormat; char achHourZero[8], *pszHourZero; char achTimeMark[8], *pszTimeMark; char achTimeMarkPos[8], *pszTimeMarkPos; int use_timemark, timemark_prefix; size_t i; DBG_ASSERT(buffer!=NULL); /* Can I use this? The problem is that it returns the date format * with localized separators. */ pszFormat = fb_hGetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, achFormat, sizeof(achFormat) - 1 ); if( pszFormat!=NULL ) { size_t uiNameSize = strlen(pszFormat); if( uiNameSize < len ) { strcpy( buffer, pszFormat ); return TRUE; } else { return FALSE; } } /* Fall back for Win95 and WinNT < 4.0 */ pszTimeMarkPos = fb_hGetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ITIMEMARKPOSN, achTimeMarkPos, sizeof(achTimeMarkPos) ); pszTimeMark = fb_hGetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ITIME, achTimeMark, sizeof(achTimeMark) ); pszHourZero = fb_hGetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ITLZERO, achHourZero, sizeof(achHourZero) ); i = 0; use_timemark = ( pszTimeMark!=NULL && atoi( pszTimeMark )==1 ); timemark_prefix = ( pszTimeMarkPos!=NULL && atoi( pszTimeMarkPos )==1 ); if( use_timemark && timemark_prefix ) { strcpy( achFormat + i, "AM/PM " ); i += 6; } if( pszHourZero!=NULL && atoi( pszHourZero )==1 ) { if( !use_timemark ) { strcpy( achFormat + i, "HH:" ); } else { strcpy( achFormat + i, "hh:" ); } i += 3; } strcpy( achFormat + i, "mm:ss" ); i += 5; if( use_timemark && !timemark_prefix ) { strcpy( achFormat + i, " AM/PM" ); i += 6; } if( len < (i+1) ) return FALSE; FB_MEMCPY(buffer, achFormat, i); buffer[i] = 0; return TRUE; }