Example #1
0
static void
test_Trim(TestBatchRunner *runner) {
    String *ws_smiley = S_smiley_with_whitespace(NULL);
    String *ws_foo    = S_get_str("  foo  ");
    String *ws_only   = S_get_str("  \t  \r\n");
    String *trimmed   = S_get_str("a     b");
    String *got;

    got = Str_Trim(ws_smiley);
    TEST_TRUE(runner, Str_Equals_Utf8(got, smiley, smiley_len), "Trim");
    DECREF(got);

    got = Str_Trim_Top(ws_foo);
    TEST_TRUE(runner, Str_Equals_Utf8(got, "foo  ", 5), "Trim_Top");
    DECREF(got);

    got = Str_Trim_Tail(ws_foo);
    TEST_TRUE(runner, Str_Equals_Utf8(got, "  foo", 5), "Trim_Tail");
    DECREF(got);

    got = Str_Trim(ws_only);
    TEST_TRUE(runner, Str_Equals_Utf8(got, "", 0), "Trim with only whitespace");
    DECREF(got);

    got = Str_Trim_Top(ws_only);
    TEST_TRUE(runner, Str_Equals_Utf8(got, "", 0),
              "Trim_Top with only whitespace");
    DECREF(got);

    got = Str_Trim_Tail(ws_only);
    TEST_TRUE(runner, Str_Equals_Utf8(got, "", 0),
              "Trim_Tail with only whitespace");
    DECREF(got);

    got = Str_Trim(trimmed);
    TEST_TRUE(runner, Str_Equals(got, (Obj*)trimmed),
              "Trim doesn't change trimmed string");
    DECREF(got);

    got = Str_Trim_Top(trimmed);
    TEST_TRUE(runner, Str_Equals(got, (Obj*)trimmed),
              "Trim_Top doesn't change trimmed string");
    DECREF(got);

    got = Str_Trim_Tail(trimmed);
    TEST_TRUE(runner, Str_Equals(got, (Obj*)trimmed),
              "Trim_Tail doesn't change trimmed string");
    DECREF(got);

    DECREF(trimmed);
    DECREF(ws_only);
    DECREF(ws_foo);
    DECREF(ws_smiley);
}
Example #2
0
static void
test_numbers(TestBatchRunner *runner) {
    Integer *i64     = Int_new(33);
    String  *json    = Json_to_json((Obj*)i64);
    String  *trimmed = Str_Trim(json);
    TEST_TRUE(runner, Str_Equals_Utf8(trimmed, "33", 2), "Integer");
    DECREF(json);
    DECREF(trimmed);

    Float *f64 = Float_new(33.33);
    json = Json_to_json((Obj*)f64);
    if (json) {
        double value = Str_To_F64(json);
        double diff = 33.33 - value;
        if (diff < 0.0) { diff = 0.0 - diff; }
        TEST_TRUE(runner, diff < 0.0001, "Float");
        DECREF(json);
    }
    else {
        FAIL(runner, "Float conversion to  json  failed.");
    }

    DECREF(i64);
    DECREF(f64);
}
Example #3
0
static void
test_escapes(TestBatchRunner *runner) {
    for (int i = 0; control_escapes[i] != NULL; i++) {
        String     *string  = Str_new_from_char(i);
        const char *escaped = control_escapes[i];
        String     *json    = Json_to_json((Obj*)string);
        String     *trimmed = Str_Trim(json);
        String     *decoded = (String*)Json_from_json(json);

        String *json_wanted = Str_newf("\"%s\"", escaped);
        TEST_TRUE(runner, Str_Equals(json_wanted, (Obj*)trimmed),
                  "encode control escape: %s", escaped);

        TEST_TRUE(runner, decoded != NULL && Str_Equals(string, (Obj*)decoded),
                  "decode control escape: %s", escaped);

        DECREF(string);
        DECREF(json);
        DECREF(trimmed);
        DECREF(decoded);
        DECREF(json_wanted);
    }

    for (int i = 0; quote_escapes_source[i] != NULL; i++) {
        const char *source  = quote_escapes_source[i];
        const char *escaped = quote_escapes_json[i];
        String *string  = Str_new_from_utf8(source, strlen(source));
        String *json    = Json_to_json((Obj*)string);
        String *trimmed = Str_Trim(json);
        String *decoded = (String*)Json_from_json(json);

        String *json_wanted = Str_newf("\"%s\"", escaped);
        TEST_TRUE(runner, Str_Equals(json_wanted, (Obj*)trimmed),
                  "encode quote/backslash escapes: %s", source);

        TEST_TRUE(runner, decoded != NULL && Str_Equals(string, (Obj*)decoded),
                  "decode quote/backslash escapes: %s", source);

        DECREF(string);
        DECREF(json);
        DECREF(trimmed);
        DECREF(decoded);
        DECREF(json_wanted);
    }
}
Example #4
0
/**
 * Read a command line from the keyboard and return a pointer to the string.
 * Only string returned by this function can be given for it as argument!
 * The string will be stored into command history buffer.
 * @return	Pointer to the string which should be given back to this
 *              function or DebugUI_FreeCommand() for re-use/history.
 *              Returns NULL when error occurred.
 */
static char *DebugUI_GetCommand(char *input)
{
	/* Allow conditional parsing of the ~/.inputrc file. */
	rl_readline_name = "Hatari";
	
	/* Tell the completer that we want a crack first. */
	rl_attempted_completion_function = DebugUI_Completion;
	DebugUI_FreeCommand(input);
	return Str_Trim(readline("> "));
}
Example #5
0
/**
 * Load keyboard remap file
 */
void Keymap_LoadRemapFile(char *pszFileName)
{
	char szString[1024];
	int STScanCode, PCKeyCode;
	FILE *in;
	int idx = 0;

	/* Initialize table with default values */
	memset(LoadedKeymap, 0, sizeof(LoadedKeymap));

	if (!*pszFileName)
		return;
	
	/* Attempt to load file */
	if (!File_Exists(pszFileName))
	{
		Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: '%s' not a file\n", pszFileName);
		return;
	}
	in = fopen(pszFileName, "r");
	if (!in)
	{
		Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: failed to "
			   " open keymap file '%s'\n", pszFileName);
		return;
	}
	
	while (!feof(in) && idx < KBD_MAX_SCANCODE)
	{
		/* Read line from file */
		if (fgets(szString, sizeof(szString), in) == NULL)
			break;
		/* Remove white-space from start of line */
		Str_Trim(szString);
		if (strlen(szString)>0)
		{
			/* Is a comment? */
			if ( (szString[0]==';') || (szString[0]=='#') )
				continue;
			/* Read values */
			sscanf(szString, "%d,%d", &PCKeyCode, &STScanCode);
			/* Store into remap table, check both value within range */
			if (STScanCode >= 0 && STScanCode <= KBD_MAX_SCANCODE
			    && PCKeyCode >= 8)
			{
				LoadedKeymap[idx][0] = PCKeyCode;
				LoadedKeymap[idx][1] = STScanCode;
				idx += 1;
			}
		}
	}

	fclose(in);
}
Example #6
0
/**
 * Command: Dump or set a DSP register
 */
int DebugDsp_Register(int nArgc, char *psArgs[])
{
	char *assign;
	Uint32 value;
	char *arg;

	if (!bDspEnabled)
	{
		fprintf(stderr, "DSP isn't present or initialized.\n");
		return DEBUGGER_CMDDONE;
	}

	if (nArgc == 1)
	{
		/* No parameter - dump all registers */
		DSP_DisasmRegisters();
		return DEBUGGER_CMDDONE;
	}
	arg = psArgs[1];

	assign = strchr(arg, '=');
	if (!assign)
		goto error_msg;

	*assign++ = '\0';
	if (!Eval_Number(Str_Trim(assign), &value))
		goto error_msg;

	if (DSP_Disasm_SetRegister(Str_Trim(arg), value))
	    return DEBUGGER_CMDDONE;

error_msg:
	fprintf(stderr,"\tError, usage: dr or dr xx=yyyy\n"
		"\tWhere: xx=A0-A2, B0-B2, X0, X1, Y0, Y1, R0-R7,\n"
		"\t       N0-N7, M0-M7, LA, LC, PC, SR, SP, OMR, SSH, SSL\n");

	return DEBUGGER_CMDDONE;
}
Example #7
0
/**
 * Load keyboard remap file
 */
void Keymap_LoadRemapFile(char *pszFileName)
{
	char szString[1024];
	int STScanCode, PCKeyCode;
	FILE *in;

	/* Initialize table with default values */
	memcpy(LoadedKeyToSTScanCode, SymbolicKeyToSTScanCode, sizeof(LoadedKeyToSTScanCode));

	if (!*pszFileName)
		return;
	
	/* Attempt to load file */
	if (!File_Exists(pszFileName))
	{
		Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: '%s' not a file\n", pszFileName);
		return;
	}
	in = fopen(pszFileName, "r");
	if (!in)
	{
		Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: failed to "
			   " open keymap file '%s'\n", pszFileName);
		return;
	}
	
	while (!feof(in))
	{
		/* Read line from file */
		if (fgets(szString, sizeof(szString), in) == NULL)
			break;
		/* Remove white-space from start of line */
		Str_Trim(szString);
		if (strlen(szString)>0)
		{
			/* Is a comment? */
			if ( (szString[0]==';') || (szString[0]=='#') )
				continue;
			/* Read values */
			sscanf(szString, "%d,%d", &PCKeyCode, &STScanCode);
			/* Store into remap table, check both value within range */
			if ( (PCKeyCode>=0) && (PCKeyCode<SDLK_LAST) &&
			     (STScanCode>=0) && (STScanCode<256) )
				LoadedKeyToSTScanCode[PCKeyCode] = STScanCode;
		}
	}
	
	fclose(in);
}
Example #8
0
/**
 * Read a command line from the keyboard and return a pointer to the string.
 * Only string returned by this function can be given for it as argument!
 * @return	Pointer to the string which should be given back to this
 *              function or DebugUI_FreeCommand() for re-use/freeing.
 *              Returns NULL when error occurred.
 */
static char *DebugUI_GetCommand(char *input)
{
	fprintf(stderr, "> ");
	if (!input)
	{
		input = malloc(256);
		assert(input);
	}
	input[0] = '\0';
	if (fgets(input, 256, stdin) == NULL)
	{
		free(input);
		return NULL;
	}
	return Str_Trim(input);
}
Example #9
0
/**
 * Dump or set CPU registers
 */
int DebugCpu_Register(int nArgc, char *psArgs[])
{
	char reg[3], *assign;
	Uint32 value;
	char *arg;

	/* If no parameter has been given, simply dump all registers */
	if (nArgc == 1)
	{
		uaecptr nextpc;
		/* use the UAE function instead */
#ifdef WINUAE_FOR_HATARI
		m68k_dumpstate_file(debugOutput, &nextpc);
#else
		m68k_dumpstate(debugOutput, &nextpc);
#endif
		fflush(debugOutput);
		return DEBUGGER_CMDDONE;
	}

	arg = psArgs[1];

	assign = strchr(arg, '=');
	if (!assign)
	{
		goto error_msg;
	}

	*assign++ = '\0';
	if (!Eval_Number(Str_Trim(assign), &value))
	{
		goto error_msg;
	}

	arg = Str_Trim(arg);
	if (strlen(arg) != 2)
	{
		goto error_msg;
	}
	reg[0] = toupper((unsigned char)arg[0]);
	reg[1] = toupper((unsigned char)arg[1]);
	reg[2] = '\0';
	
	/* set SR and update conditional flags for the UAE CPU core. */
	if (reg[0] == 'S' && reg[1] == 'R')
	{
		M68000_SetSR(value);
	}
	else if (reg[0] == 'P' && reg[1] == 'C')   /* set PC? */
	{
		M68000_SetPC(value);
	}
	else
	{
		Uint32 *regaddr;
		/* check&set data and address registers */
		if (DebugCpu_GetRegisterAddress(reg, &regaddr))
		{
			*regaddr = value;
		}
		else
		{
			goto error_msg;
		}
	}
	return DEBUGGER_CMDDONE;

error_msg:
	fprintf(stderr,"\tError, usage: r or r xx=yyyy\n\tWhere: xx=A0-A7, D0-D7, PC or SR.\n");
	return DEBUGGER_CMDDONE;
}
Example #10
0
/**
 * ---------------------------------------------------------------------/
 * /   reads from an input configuration (INI) file.
 * /---------------------------------------------------------------------
 * >>------[   input_config()   ]-------------[ 08-02-95 14:02PM ]------/
 * / return value:
 * /     int                     ; number of records read or -1 on error
 * / parameters:
 * /     char *filename          ; filename of INI style file
 * /     struct Config_Tag configs[]; Configuration structure
 * /     char *header            ; INI header name (i.e. "[TEST]")
 * /-------------------------------------------------------------------<<
 */
int input_config(const char *filename, const struct Config_Tag configs[], const char *header)
{
	const struct Config_Tag *ptr;
	int count=0, lineno=0, type;
	FILE *file;
	char *fptr,*tok;
	const char *next;
	char line[1024];

	file = fopen(filename,"r");
	if (file == NULL)
		return -1;                 /* return error designation. */

	if (header != NULL)
	{
		do
		{
			fptr = Str_Trim(fgets(line, sizeof(line), file));  /* get input line */
			if (fptr == NULL)
				break;
		}
		while (memcmp(fptr,header,strlen(header)));
	}

	if ( !feof(file) )
		do
		{
			fptr = Str_Trim(fgets(line, sizeof(line), file));   /* get input line */
			if (fptr == NULL)
				continue;
			lineno++;
			if (fptr[0] == '#')
				continue;                       /* skip comments */
			if (fptr[0] == '[')
				continue;                       /* skip next header */
			tok = Str_Trim(strtok(fptr, "="));      /* get first token */
			if (tok == NULL)
				continue;
			for (ptr = configs; ptr->buf; ++ptr)    /* scan for token */
			{
				if (!strcmp(tok, ptr->code))    /* got a match? */
				{
					type = ptr->type;
					/* get actual config value */
					next = Str_Trim(strtok(NULL, "="));
					if (next == NULL)
					{
						if (type == String_Tag)
							next = ""; /* field with empty string */
						else
							type = Error_Tag;
					}
					count++;
					switch (type)      /* check type */
					{
					case Bool_Tag:
						if (!strcasecmp(next,"FALSE"))
							*((bool *)(ptr->buf)) = false;
						else if (!strcasecmp(next,"TRUE"))
							*((bool *)(ptr->buf)) = true;
						break;
						
					case Char_Tag:
						sscanf(next, "%c", (char *)(ptr->buf));
						break;
						
					case Short_Tag:
						sscanf(next, "%hd", (short *)(ptr->buf));
						break;
						
					case Int_Tag:
						sscanf(next, "%d", (int *)(ptr->buf));
						break;
						
					case Long_Tag:
						sscanf(next, "%ld", (long *)(ptr->buf));
						break;
						
					case Float_Tag:
						sscanf(next, "%g", (float *)ptr->buf);
						break;
						
					case Double_Tag:
						sscanf(next, "%lg", (double *)ptr->buf);
						break;
						
					case String_Tag:
						strcpy((char *)ptr->buf, next);
						break;
						
					case Error_Tag:
					default:
						count--;
						printf("Error in Config file %s on line %d\n", filename, lineno);
						break;
					}
				}
			}
		}
		while (fptr != NULL && fptr[0] != '[');

	fclose(file);
	return count;
}
Example #11
0
/**
 * ---------------------------------------------------------------------/
 * /   updates an input configuration (INI) file from a structure.
 * /---------------------------------------------------------------------
 * >>------[   update_config()  ]-------------[ 08-02-95 14:02PM ]------/
 * / return value:
 * /     int                     ; Number of records read & updated
 * / parameters:
 * /     char *filename          ; filename of INI file
 * /     struct Config_Tag configs[]; Configuration structure
 * /     char *header            ; INI header name (i.e. "[TEST]")
 * /-------------------------------------------------------------------<<
 */
int update_config(const char *filename, const struct Config_Tag configs[], const char *header)
{
	const struct Config_Tag *ptr;
	int count=0, lineno=0, retval;
	FILE *cfgfile, *tempfile;
	char *fptr, *tok;
	char line[1024];
	bool bUseTempCfg = false;
	const char *sTempCfgName = "_temp_.cfg";

	cfgfile = fopen(filename, "r");

	/* If the cfg file does not yet exists, we can create it directly: */
	if (cfgfile == NULL)
	{
		cfgfile = fopen(filename, "w");
		if (cfgfile == NULL)
			return -1;                             /* return error designation. */
		count = write_header_tokens(cfgfile, configs, header);
		fclose(cfgfile);
		return count;
	}

	tempfile = tmpfile();                        /* Open a temporary file for output */
 	if (tempfile == NULL)
 	{
		/* tmpfile() failed, let's try a normal open */
		tempfile = fopen(sTempCfgName, "w+");
		bUseTempCfg = true;
	}
	if (tempfile == NULL)
	{
		perror("update_config");
		fclose(cfgfile);
		return -1;                         /* return error designation. */
	}

	if (header != NULL)
	{
		int headerlen = strlen(header);
		do
		{
			fptr = Str_Trim(fgets(line, sizeof(line), cfgfile));  /* get input line */
			if (fptr == NULL)
				break;
			fprintf(tempfile, "%s\n", fptr);
		}
		while(memcmp(fptr, header, headerlen));
	}

	if (feof(cfgfile))
	{
		count += write_header_tokens(tempfile, configs, header);
	}
	else
	{
		char *savedtokenflags = NULL;   /* Array to log the saved tokens */
		int numtokens = 0;              /* Total number of tokens to save */

		/* Find total number of tokens: */
		for (ptr=configs; ptr->buf; ++ptr)
		{
			numtokens += 1;
		}
		if (numtokens)
		{
			savedtokenflags = malloc(numtokens * sizeof(char));
			if (savedtokenflags)
				memset(savedtokenflags, 0, numtokens * sizeof(char));
		}

		for(;;)
		{
			fptr = Str_Trim(fgets(line, sizeof(line), cfgfile));  /* get input line */
			/* error or eof? */
			if (fptr == NULL)
				break;
			lineno++;
			if (fptr[0] == '#')
			{
				fprintf(tempfile, "%s\n", fptr);
				continue;                                 /* skip comments */
			}
			if (fptr[0] == '[')
			{
				break;
			}

			tok = Str_Trim(strtok(fptr, "="));               /* get first token */
			if (tok != NULL)
			{
				int i = 0;
				for (ptr = configs; ptr->buf; ++ptr, i++) /* scan for token */
				{
					if (!strcmp(tok, ptr->code))           /* got a match? */
					{
						if (write_token(tempfile, ptr) == 0)
						{
							if (savedtokenflags)
								savedtokenflags[i] = true;
							count += 1;
						}
					}
				}
			}
		}

		/* Write remaining (new?) tokens that were not in the configuration file, yet */
		if (count != numtokens && savedtokenflags != NULL)
		{
			int i;
			for (ptr = configs, i = 0; ptr->buf; ++ptr, i++)
			{
				if (!savedtokenflags[i])
				{
					if (write_token(tempfile, ptr) == 0)
					{
						count += 1;
						fprintf(stderr, "Wrote new token %s -> %s \n", header, ptr->code);
					}
				}
			}
		}

		if (savedtokenflags)
		{
			free(savedtokenflags);
			savedtokenflags = NULL;
		}

		if (!feof(cfgfile) && fptr != NULL)
			fprintf(tempfile, "\n%s\n", line);

		for(;;)
		{
			fptr = Str_Trim(fgets(line, sizeof(line), cfgfile));  /* get input line */
			if (fptr == NULL)
				break;
			fprintf(tempfile, "%s\n", fptr);
		}
	}


	/* Re-open the config file for writing: */
	fclose(cfgfile);
	cfgfile = fopen(filename, "wb");
	if (cfgfile == NULL || fseek(tempfile, 0, SEEK_SET) != 0)
	{
		retval = -1;
		goto cleanup;
	}

	/* Now copy the temporary file to the configuration file: */
	retval = count;
	while(!(feof(tempfile) || ferror(cfgfile)))
	{
		size_t copycount;
		copycount = fread(line, sizeof(char), sizeof(line), tempfile);
		if (copycount == 0)
			break;
		if (fwrite(line, sizeof(char), copycount, cfgfile) != copycount)
		{
			retval = -1;
			break;
		}
	}
cleanup:
	if (cfgfile)
	{
		if (ferror(cfgfile))
			perror("update_config");
		fclose(cfgfile);
	}
	if (tempfile)
	{
		/* tmpfile() is removed automatically on close */
		fclose(tempfile);
		if (bUseTempCfg)
			unlink(sTempCfgName);
	}
	return retval;
}
Example #12
0
/**
 * Read debugger commands from a file.  If 'reinit' is set
 * (as it normally should), reinitialize breakpoints etc.
 * afterwards. return false for error, true for success.
 */
bool DebugUI_ParseFile(const char *path, bool reinit)
{
	char *olddir, *dir, *cmd, *input, *expanded, *slash;
	FILE *fp;

	fprintf(stderr, "Reading debugger commands from '%s'...\n", path);
	if (!(fp = fopen(path, "r")))
	{
		perror("ERROR");
		return false;
	}

	/* change to directory where the debugger file resides */
	olddir = NULL;
	dir = strdup(path);
	slash = strrchr(dir, PATHSEP);
	if (slash)
	{
		olddir = malloc(FILENAME_MAX);
		if (olddir)
		{
			if (!getcwd(olddir, FILENAME_MAX))
				strcpy(olddir, ".");
		}
		*slash = '\0';
		if (chdir(dir) != 0)
		{
			perror("ERROR");
			if (olddir)
				free(olddir);
			free(dir);
			fclose(fp);
			return false;
		}
		fprintf(stderr, "Changed to input file dir '%s'.\n", dir);
	}
	free(dir);

	input = NULL;
	for (;;)
	{
		if (!input)
		{
			input = malloc(256);
			assert(input);
		}
		if (!fgets(input, 256, fp))
			break;

		/* ignore empty and comment lines */
		cmd = Str_Trim(input);
		if (!*cmd || *cmd == '#')
			continue;

		/* returns new string if input needed expanding! */
		expanded = DebugUI_EvaluateExpressions(input);
		if (!expanded)
			continue;

		cmd = Str_Trim(expanded);
		fprintf(stderr, "> %s\n", cmd);
		DebugUI_ParseCommand(cmd);
		free(expanded);
	}

	free(input);
	fclose(fp);

	if (olddir)
	{
		if (chdir(olddir) != 0)
			perror("ERROR");
		else
			fprintf(stderr, "Changed back to '%s' dir.\n", olddir);
		free(olddir);
	}

	if (reinit)
	{
		DebugCpu_SetDebugging();
		DebugDsp_SetDebugging();
	}
	return true;
}