Example #1
0
static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	mlt_filter filter = (mlt_filter)mlt_frame_pop_service( frame );
	mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
	uint8_t* vs_image = NULL;
	VSPixelFormat vs_format = PF_NONE;

	// VS only works on progressive frames
	mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "consumer_deinterlace", 1 );

	*format = validate_format( *format );

	int error = mlt_frame_get_image( frame, image, format, width, height, 1 );

	// Convert the received image to a format vid.stab can handle
	if ( !error )
	{
		vs_format = mltimage_to_vsimage( *format, *width, *height, *image, &vs_image );
	}

	if( vs_image )
	{
		mlt_service_lock( MLT_FILTER_SERVICE(filter) );

		char* results = mlt_properties_get( properties, "results" );
		if( results && strcmp( results, "" ) )
		{
			apply_results( filter, frame, vs_image, vs_format, *width, *height );
			vsimage_to_mltimage( vs_image, *image, *format, *width, *height );
		}
		else
		{
			analyze_image( filter, frame, vs_image, vs_format, *width, *height );
			if( mlt_properties_get_int( properties, "show" ) == 1 )
			{
				vsimage_to_mltimage( vs_image, *image, *format, *width, *height );
			}
		}

		mlt_service_unlock( MLT_FILTER_SERVICE(filter) );

		free_vsimage( vs_image, vs_format );
	}

	return error;
}
Example #2
0
void read_frame(
        xyuv::frame * frame,
        std::istream & istream
) {
    std::vector<file_format_loader> file_format_loaders {
            fileformat_version_0::read_header,
            fileformat_version_1::read_header
    };

    io_file_header file_header;
    read_file_header(istream, file_header);

    uint16_t version = be_to_host(file_header.version);
    XYUV_ASSERT(version < file_format_loaders.size() && "ERROR: File format too new for this library.");

    file_format_loaders[version](istream, frame->format, file_header);

    validate_format(frame->format);
    frame->data.reset( new uint8_t[frame->format.size]);
    read_large_buffer(istream, reinterpret_cast<char*>(frame->data.get()), frame->format.size);
}
Example #3
0
	void validate_format(const CharT* fmt, size_t nargs) { validate_format(basic_string_view<CharT>{fmt}, nargs); }
Example #4
0
	void validate_format(basic_string_view<CharT, Traits> fmt) { validate_format(fmt, sizeof...(Args)); }
Example #5
0
bool std::experimental::validate_format(basic_string_view<CharT, Traits> fmt, size_t nargs, nothrow_t) noexcept
{
	try { validate_format(fmt, nargs); }
	catch(...) { return false; }
	return true;
}
Example #6
0
	bool validate_format(const CharT* fmt, size_t nargs, nothrow_t) noexcept { return validate_format(basic_string_view<CharT>{fmt}, nargs, nothrow); }
Example #7
0
	bool validate_format(basic_string_view<CharT, Traits> fmt, nothrow_t) noexcept { return validate_format(fmt, sizeof...(Args), nothrow); }
Example #8
0
static SQInteger _string_format( HSQUIRRELVM v ) {
	const SQChar *format;
	SQChar *dest;
	SQChar fmt[MAX_FORMAT_LEN];
	sq_getstring( v, 2, &format );
	SQInteger allocated = ( sq_getsize( v, 2 ) + 1 ) * sizeof( SQChar );
	dest = sq_getscratchpad( v, allocated );
	SQInteger n = 0, i = 0, nparam = 3, w = 0;
	while ( format[n] != '\0' ) {
		if ( format[n] != '%' ) {
			assert( i < allocated );
			dest[i++] = format[n];
			n++;
		} else if ( format[n+1] == '%' ) { //handles %%
			dest[i++] = '%';
			n += 2;
		} else {
			n++;
			if ( nparam > sq_gettop( v ) )
				return sq_throwerror( v, _SC( "not enough paramters for the given format string" ) );
			n = validate_format( v, fmt, format, n, w );
			if ( n < 0 ) return -1;
			SQInteger addlen = 0;
			SQInteger valtype = 0;
			const SQChar *ts;
			SQInteger ti;
			SQFloat tf;
			switch ( format[n] ) {
			case 's':
				if ( SQ_FAILED( sq_getstring( v, nparam, &ts ) ) )
					return sq_throwerror( v, _SC( "string expected for the specified format" ) );
				addlen = ( sq_getsize( v, nparam ) * sizeof( SQChar ) ) + ( ( w + 1 ) * sizeof( SQChar ) );
				valtype = 's';
				break;
case 'i': case 'd': case 'c': case 'o':  case 'u':  case 'x':  case 'X':
				if ( SQ_FAILED( sq_getinteger( v, nparam, &ti ) ) )
					return sq_throwerror( v, _SC( "integer expected for the specified format" ) );
				addlen = ( ADDITIONAL_FORMAT_SPACE ) + ( ( w + 1 ) * sizeof( SQChar ) );
				valtype = 'i';
				break;
case 'f': case 'g': case 'G': case 'e':  case 'E':
				if ( SQ_FAILED( sq_getfloat( v, nparam, &tf ) ) )
					return sq_throwerror( v, _SC( "float expected for the specified format" ) );
				addlen = ( ADDITIONAL_FORMAT_SPACE ) + ( ( w + 1 ) * sizeof( SQChar ) );
				valtype = 'f';
				break;
			default:
				return sq_throwerror( v, _SC( "invalid format" ) );
			}
			n++;
			//if((allocated-i) < addlen)
			allocated += addlen;
			dest = sq_getscratchpad( v, allocated );
			switch ( valtype ) {
			case 's': i += scsprintf( &dest[i], fmt, ts ); break;
			case 'i': i += scsprintf( &dest[i], fmt, ti ); break;
			case 'f': i += scsprintf( &dest[i], fmt, tf ); break;
			};
			nparam ++;
		}
	}
	sq_pushstring( v, dest, i );
	return 1;
}
Example #9
0
cheat_script::script_entry::script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &entrynode, bool isaction)
	: m_next(NULL),
		m_condition(&symbols),
		m_expression(&symbols)
{
	const char *expression = NULL;
	try
	{
		// read the condition if present
		expression = xml_get_attribute_string(&entrynode, "condition", NULL);
		if (expression != NULL)
			m_condition.parse(expression);

		// if this is an action, parse the expression
		if (isaction)
		{
			expression = entrynode.value;
			if (expression == NULL || expression[0] == 0)
				throw emu_fatalerror("%s.xml(%d): missing expression in action tag\n", filename, entrynode.line);
			m_expression.parse(expression);
		}

		// otherwise, parse the attributes and arguments
		else
		{
			// extract format
			const char *format = xml_get_attribute_string(&entrynode, "format", NULL);
			if (format == NULL || format[0] == 0)
				throw emu_fatalerror("%s.xml(%d): missing format in output tag\n", filename, entrynode.line);
			m_format.cpy(format);

			// extract other attributes
			m_line = xml_get_attribute_int(&entrynode, "line", 0);
			m_justify = JUSTIFY_LEFT;
			const char *align = xml_get_attribute_string(&entrynode, "align", "left");
			if (strcmp(align, "center") == 0)
				m_justify = JUSTIFY_CENTER;
			else if (strcmp(align, "right") == 0)
				m_justify = JUSTIFY_RIGHT;
			else if (strcmp(align, "left") != 0)
				throw emu_fatalerror("%s.xml(%d): invalid alignment '%s' specified\n", filename, entrynode.line, align);

			// then parse arguments
			int totalargs = 0;
			for (xml_data_node *argnode = xml_get_sibling(entrynode.child, "argument"); argnode != NULL; argnode = xml_get_sibling(argnode->next, "argument"))
			{
				output_argument &curarg = m_arglist.append(*global_alloc(output_argument(manager, symbols, filename, *argnode)));

				// verify we didn't overrun the argument count
				totalargs += curarg.count();
				if (totalargs > MAX_ARGUMENTS)
					throw emu_fatalerror("%s.xml(%d): too many arguments (found %d, max is %d)\n", filename, argnode->line, totalargs, MAX_ARGUMENTS);
			}

			// validate the format against the arguments
			validate_format(filename, entrynode.line);
		}
	}
	catch (expression_error &err)
	{
		throw emu_fatalerror("%s.xml(%d): error parsing cheat expression \"%s\" (%s)\n", filename, entrynode.line, expression, err.code_string());
	}
}
Example #10
0
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{
	const SQChar *format;
	SQChar *dest;
	SQChar fmt[MAX_FORMAT_LEN];
	sq_getstring(v,nformatstringidx,&format);
	SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
	dest = sq_getscratchpad(v,allocated);
	SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
	while(format[n] != '\0') {
		if(format[n] != '%') {
			assert(i < allocated);
			dest[i++] = format[n];
			n++;
		}
		else if(format[n+1] == '%') { //handles %%
				dest[i++] = '%';
				n += 2;
		}
		else {
			n++;
			if( nparam > sq_gettop(v) )
                // C::B patch: Correct misspelled "parameters"
				return sq_throwerror(v,_SC("not enough parameters for the given format string"));
			n = validate_format(v,fmt,format,n,w);
			if(n < 0) return -1;
			SQInteger addlen = 0;
			SQInteger valtype = 0;
			const SQChar *ts;
			SQInteger ti;
			SQFloat tf;
			switch(format[n]) {
			case 's':
				if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
					return sq_throwerror(v,_SC("string expected for the specified format"));
				addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
				valtype = 's';
				break;
			case 'i': case 'd': case 'c':case 'o':  case 'u':  case 'x':  case 'X':
				if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
					return sq_throwerror(v,_SC("integer expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'i';
				break;
			case 'f': case 'g': case 'G': case 'e':  case 'E':
				if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
					return sq_throwerror(v,_SC("float expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'f';
				break;
			default:
				return sq_throwerror(v,_SC("invalid format"));
			}
			n++;
			allocated += addlen + sizeof(SQChar);
			dest = sq_getscratchpad(v,allocated);
			switch(valtype) {
			case 's': i += scsprintf(&dest[i],fmt,ts); break;
			case 'i': i += scsprintf(&dest[i],fmt,ti); break;
			case 'f': i += scsprintf(&dest[i],fmt,tf); break;
			};
			nparam ++;
		}
	}
	*outlen = i;
	dest[i] = '\0';
	*output = dest;
	return SQ_OK;
}
Example #11
0
int main(int argc, char ** argv)
{
	int events = 0;
        int orig_events;
	bool monitor = false;
	int quiet = 0;
	unsigned long int timeout = 0;
	int recursive = 0;
	bool csv = false;
	bool daemon = false;
	bool syslog = false;
	char * format = NULL;
	char * timefmt = NULL;
	char * fromfile = NULL;
	char * outfile = NULL;
	char * regex = NULL;
	char * iregex = NULL;
	pid_t pid;
    int fd;

	// Parse commandline options, aborting if something goes wrong
	if ( !parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout,
	                 &recursive, &csv, &daemon, &syslog, &format, &timefmt,
                         &fromfile, &outfile, &regex, &iregex) ) {
		return EXIT_FAILURE;
	}

	if ( !inotifytools_initialize() ) {
		fprintf(stderr, "Couldn't initialize inotify.  Are you running Linux "
		                "2.6.13 or later, and was the\n"
		                "CONFIG_INOTIFY option enabled when your kernel was "
		                "compiled?  If so, \n"
		                "something mysterious has gone wrong.  Please e-mail "
		                PACKAGE_BUGREPORT "\n"
		                " and mention that you saw this message.\n");
		return EXIT_FAILURE;
	}

	if ( timefmt ) inotifytools_set_printf_timefmt( timefmt );
	if (
		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) ||
		(iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED|
		                                                        REG_ICASE))
	) {
		fprintf(stderr, "Error in `exclude' regular expression.\n");
		return EXIT_FAILURE;
	}


	if ( format ) validate_format(format);

	// Attempt to watch file
	// If events is still 0, make it all events.
	if (events == 0)
		events = IN_ALL_EVENTS;
        orig_events = events;
        if ( monitor && recursive ) {
                events = events | IN_CREATE | IN_MOVED_TO | IN_MOVED_FROM;
        }

	FileList list = construct_path_list( argc, argv, fromfile );

	if (0 == list.watch_files[0]) {
		fprintf(stderr, "No files specified to watch!\n");
		return EXIT_FAILURE;
	}


    // Daemonize - BSD double-fork approach
	if ( daemon ) {

		pid = fork();
	        if (pid < 0) {
			fprintf(stderr, "Failed to fork1 whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
	        if (pid > 0) {
			_exit(0);
	        }
		if (setsid() < 0) {
			fprintf(stderr, "Failed to setsid whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
		signal(SIGHUP,SIG_IGN);
	        pid = fork();
	        if (pid < 0) {
	                fprintf(stderr, "Failed to fork2 whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }
	        if (pid > 0) {
	                _exit(0);
	        }
		if (chdir("/") < 0) {
			fprintf(stderr, "Failed to chdir whilst daemonizing!\n");
	                return EXIT_FAILURE;
	        }

		// Redirect stdin from /dev/null
	        fd = open("/dev/null", O_RDONLY);
		if (fd != fileno(stdin)) {
			dup2(fd, fileno(stdin));
			close(fd);
		}

		// Redirect stdout to a file
	        fd = open(outfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
		if (fd < 0) {
                        fprintf( stderr, "Failed to open output file %s\n", outfile );
                        return EXIT_FAILURE;
                }
		if (fd != fileno(stdout)) {
			dup2(fd, fileno(stdout));
			close(fd);
		}

        // Redirect stderr to /dev/null
		fd = open("/dev/null", O_WRONLY);
	        if (fd != fileno(stderr)) {
	                dup2(fd, fileno(stderr));
	                close(fd);
	        }

        } else if (outfile != NULL) { // Redirect stdout to a file if specified
		fd = open(outfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
		if (fd < 0) {
			fprintf( stderr, "Failed to open output file %s\n", outfile );
			return EXIT_FAILURE;
		}
		if (fd != fileno(stdout)) {
			dup2(fd, fileno(stdout));
			close(fd);
		}
        }

        if ( syslog ) {
		openlog ("inotifywait", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON);
        }

	if ( !quiet ) {
		if ( recursive ) {
			output_error( syslog, "Setting up watches.  Beware: since -r "
				"was given, this may take a while!\n" );
		} else {
			output_error( syslog, "Setting up watches.\n" );
		}
	}

	// now watch files
	for ( int i = 0; list.watch_files[i]; ++i ) {
		char const *this_file = list.watch_files[i];
		if ( (recursive && !inotifytools_watch_recursively_with_exclude(
		                        this_file,
		                        events,
		                        list.exclude_files ))
		     || (!recursive && !inotifytools_watch_file( this_file, events )) ){
			if ( inotifytools_error() == ENOSPC ) {
				output_error( syslog, "Failed to watch %s; upper limit on inotify "
				                "watches reached!\n", this_file );
				output_error( syslog, "Please increase the amount of inotify watches "
				        "allowed per user via `/proc/sys/fs/inotify/"
				        "max_user_watches'.\n");
			}
			else {
				output_error( syslog, "Couldn't watch %s: %s\n", this_file,
				        strerror( inotifytools_error() ) );
			}
			return EXIT_FAILURE;
		}
	}

	if ( !quiet ) {
		output_error( syslog, "Watches established.\n" );
	}

	// Now wait till we get event
	struct inotify_event * event;
	char * moved_from = 0;

	do {
		event = inotifytools_next_event( timeout );
		if ( !event ) {
			if ( !inotifytools_error() ) {
				return EXIT_TIMEOUT;
			}
			else {
				output_error( syslog, "%s\n", strerror( inotifytools_error() ) );
				return EXIT_FAILURE;
			}
		}

		if ( quiet < 2 && (event->mask & orig_events) ) {
			if ( csv ) {
				output_event_csv( event );
			}
			else if ( format ) {
				inotifytools_printf( event, format );
			}
			else {
				inotifytools_printf( event, "%w %,e %f\n" );
			}
		}

		// if we last had MOVED_FROM and don't currently have MOVED_TO,
		// moved_from file must have been moved outside of tree - so unwatch it.
		if ( moved_from && !(event->mask & IN_MOVED_TO) ) {
			if ( !inotifytools_remove_watch_by_filename( moved_from ) ) {
				output_error( syslog, "Error removing watch on %s: %s\n",
				         moved_from, strerror(inotifytools_error()) );
			}
			free( moved_from );
			moved_from = 0;
		}

		if ( monitor && recursive ) {
			if ((event->mask & IN_CREATE) ||
			    (!moved_from && (event->mask & IN_MOVED_TO))) {
				// New file - if it is a directory, watch it
				static char * new_file;

				nasprintf( &new_file, "%s%s",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );

				if ( isdir(new_file) &&
				    !inotifytools_watch_recursively( new_file, events ) ) {
					output_error( syslog, "Couldn't watch new directory %s: %s\n",
					         new_file, strerror( inotifytools_error() ) );
				}
				free( new_file );
			} // IN_CREATE
			else if (event->mask & IN_MOVED_FROM) {
				nasprintf( &moved_from, "%s%s/",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );
				// if not watched...
				if ( inotifytools_wd_from_filename(moved_from) == -1 ) {
					free( moved_from );
					moved_from = 0;
				}
			} // IN_MOVED_FROM
			else if (event->mask & IN_MOVED_TO) {
				if ( moved_from ) {
					static char * new_name;
					nasprintf( &new_name, "%s%s/",
					           inotifytools_filename_from_wd( event->wd ),
					           event->name );
					inotifytools_replace_filename( moved_from, new_name );
					free( moved_from );
					moved_from = 0;
				} // moved_from
			}
		}

		fflush( NULL );

	} while ( monitor );

	// If we weren't trying to listen for this event...
	if ( (events & event->mask) == 0 ) {
		// ...then most likely something bad happened, like IGNORE etc.
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Example #12
0
/* -------------------------------------------------------------
 * MAIN:
 * Check all parameters passed on the command line, calculate
 * the date to be displayed, and display it.
 * ------------------------------------------------------------- */
int main( int argc, char **argv, char **envp ) {
   struct tm *time_var;
   time_t time_number;
   signed long time_offset;
   char *ptr;
   int i, date_override;
   char saved_command[MAX_PARM_LEN+1];
   char saved_format[MAX_MASK_LEN+1];
   char saved_startdate_override[13]; /* YYYYMMDDHHMM_ */

   /*
    * Check to see what command line parameters we have
    */
   if (argc < 2) {
      printf( "%s: (c)Mark Dickinson, 2001\n", argv[0] );
      show_syntax();
      exit( 1 );
   }

   time_offset = 0;     /* default, and start point for adjustments */
   date_override = 0;   /* use current system date and time */
   strcpy(saved_format,"YYYYMMDD"); /* default */
   i = 1;
   /* use a while loop instead of a for loop as we may
    * increment the counter ourselves */
   while ( i < argc ) {
      ptr = argv[i];
      i++;
	  if (i >= argc) {
		 printf( "Missing value for %s\n", ptr );
		 exit( 1 );
      }
      strncpy( saved_command, ptr, MAX_PARM_LEN ); 
      ptr = argv[i];
      if (strncmp("-format",saved_command,7) == 0) {
         validate_format( ptr, saved_format );
      }
	  else if (strncmp("-workingdate",saved_command,12) == 0) {
         date_override = 1;
		 strncpy( saved_startdate_override, ptr, 12 ); /* YYYYMMDDHHMM */
      }
      else {
         time_offset = time_offset + check_parameter( saved_command, ptr );
      }
      i++;
   }
    
   /*
    * Work out the new time and print the result.
    */
   if (date_override == 1) {
      /* have to get the dst flag setting for this */
      time_number = time(0);
      time_var = localtime( &time_number );
	  /* then workout the callers passed time */
      time_number = make_time( (char *)&saved_startdate_override, time_var->tm_isdst );
   }
   else {
      time_number = time(0);     /* time now in seconds from 00:00, Jan 1 1970 */
   }
   time_number = time_number + time_offset;
   if (strcmp("CTIME",saved_format) == 0) {
      printf( "%s", ctime( &time_number ) );
   }
   else {
     time_var = localtime( &time_number );   
     print_time( time_var, saved_format ); 
   }
   exit( 0 );
} /* end main */
Example #13
0
cheat_script::script_entry::script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node const &entrynode, bool isaction)
	: m_condition(&symbols),
		m_expression(&symbols)
{
	const char *expression = nullptr;
	try
	{
		// read the condition if present
		expression = entrynode.get_attribute_string("condition", nullptr);
		if (expression != nullptr)
			m_condition.parse(expression);

		// if this is an action, parse the expression
		if (isaction)
		{
			expression = entrynode.get_value();
			if (expression == nullptr || expression[0] == 0)
				throw emu_fatalerror("%s.xml(%d): missing expression in action tag\n", filename, entrynode.line);
			m_expression.parse(expression);
		}

		// otherwise, parse the attributes and arguments
		else
		{
			// extract format
			const char *format = entrynode.get_attribute_string("format", nullptr);
			if (format == nullptr || format[0] == 0)
				throw emu_fatalerror("%s.xml(%d): missing format in output tag\n", filename, entrynode.line);
			m_format.assign(format);

			// extract other attributes
			m_line = entrynode.get_attribute_int("line", 0);
			m_justify = ui::text_layout::LEFT;
			const char *align = entrynode.get_attribute_string("align", "left");
			if (strcmp(align, "center") == 0)
				m_justify = ui::text_layout::CENTER;
			else if (strcmp(align, "right") == 0)
				m_justify = ui::text_layout::RIGHT;
			else if (strcmp(align, "left") != 0)
				throw emu_fatalerror("%s.xml(%d): invalid alignment '%s' specified\n", filename, entrynode.line, align);

			// then parse arguments
			int totalargs = 0;
			for (xml_data_node const *argnode = entrynode.get_child("argument"); argnode != nullptr; argnode = argnode->get_next_sibling("argument"))
			{
				auto curarg = std::make_unique<output_argument>(manager, symbols, filename, *argnode);
				// verify we didn't overrun the argument count
				totalargs += curarg->count();

				m_arglist.push_back(std::move(curarg));

				if (totalargs > MAX_ARGUMENTS)
					throw emu_fatalerror("%s.xml(%d): too many arguments (found %d, max is %d)\n", filename, argnode->line, totalargs, MAX_ARGUMENTS);
			}

			// validate the format against the arguments
			validate_format(filename, entrynode.line);
		}
	}
	catch (expression_error &err)
	{
		throw emu_fatalerror("%s.xml(%d): error parsing cheat expression \"%s\" (%s)\n", filename, entrynode.line, expression, err.code_string());
	}
}
Example #14
0
SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
{
	const SQChar *format;
	SQChar *dest;
	SQChar fmt[MAX_FORMAT_LEN];
	sq_getstring(v,nformatstringidx,&format);
	SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
	dest = sq_getscratchpad(v,allocated);
	SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
	while(format[n] != '\0') {
		if(format[n] != '%') {
			assert(i < allocated);
			dest[i++] = format[n];
			n++;
		}
		else if(format[n+1] == '%') { //handles %%
				dest[i++] = '%';
				n += 2; 
		}
		else {
			n++;
			if( nparam > sq_gettop(v) )
				return sq_throwerror(v,_SC("not enough paramters for the given format string"));
			n = validate_format(v,fmt,format,n,w);
			if(n < 0) return -1;
			SQInteger addlen = 0;
			SQInteger valtype = 0;
			const SQChar *ts;
			SQInteger ti;
			SQFloat tf;
			switch(format[n]) {
			case 's':
				if(SQ_FAILED(sq_getstring(v,nparam,&ts))) 
					return sq_throwerror(v,_SC("string expected for the specified format"));
				addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
				valtype = 's';
				break;
			case 'i': case 'd': case 'o': case 'u':  case 'x':  case 'X':
#ifdef _SQ64
				{
				size_t flen = scstrlen(fmt);
				SQInteger fpos = flen - 1;
				SQChar f = fmt[fpos];
				SQChar *prec = (SQChar *)_PRINT_INT_PREC;
				while(*prec != _SC('\0')) {
					fmt[fpos++] = *prec++;
				}
				fmt[fpos++] = f;
				fmt[fpos++] = _SC('\0');
				}
#endif
			case 'c':
				if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) 
					return sq_throwerror(v,_SC("integer expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'i';
				break;
			case 'f': case 'g': case 'G': case 'e':  case 'E':
				if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) 
					return sq_throwerror(v,_SC("float expected for the specified format"));
				addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
				valtype = 'f';
				break;
			default:
				return sq_throwerror(v,_SC("invalid format"));
			}
			n++;
			allocated += addlen + sizeof(SQChar);
			dest = sq_getscratchpad(v,allocated);
			switch(valtype) {
#pragma warning(push)  
#pragma warning(disable : 4996)  
			case 's': i += scsprintf(&dest[i],fmt,ts); break;
			case 'i': i += scsprintf(&dest[i],fmt,ti); break;
			case 'f': i += scsprintf(&dest[i],fmt,tf); break;
#pragma warning(pop)
			};
			nparam ++;
		}
	}
	*outlen = i;
	dest[i] = '\0';
	*output = dest;
	return SQ_OK;
}