diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /support/regression/fwk/lib | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'support/regression/fwk/lib')
| -rw-r--r-- | support/regression/fwk/lib/extern1.c | 28 | ||||
| -rw-r--r-- | support/regression/fwk/lib/extern2.c | 9 | ||||
| -rw-r--r-- | support/regression/fwk/lib/fwk.lib | 3 | ||||
| -rw-r--r-- | support/regression/fwk/lib/spec.mk | 5 | ||||
| -rw-r--r-- | support/regression/fwk/lib/statics.c | 42 | ||||
| -rw-r--r-- | support/regression/fwk/lib/testfwk.c | 251 | ||||
| -rw-r--r-- | support/regression/fwk/lib/timeout.c | 286 |
7 files changed, 624 insertions, 0 deletions
diff --git a/support/regression/fwk/lib/extern1.c b/support/regression/fwk/lib/extern1.c new file mode 100644 index 0000000..c397497 --- /dev/null +++ b/support/regression/fwk/lib/extern1.c @@ -0,0 +1,28 @@ +/* needed by tests/inline.c */ + +#ifdef __SDCC +#pragma std_sdcc99 +#endif + +/*-------------- + bug 2591 + extern definition with parameters not in registers + these parameters should only be allocated here + the corresponding inline definition is in tests/inline.c +*/ +extern long bug_2591 (long a, long b, long c) +{ + return a | b | c; +} + +extern char inlined_function (void) +{ + return 2; +} + +/* needed by tests/test-p99-conformance.c */ +void +has_undefined_symbol2(void) { + /* empty */ +} + diff --git a/support/regression/fwk/lib/extern2.c b/support/regression/fwk/lib/extern2.c new file mode 100644 index 0000000..3ce738d --- /dev/null +++ b/support/regression/fwk/lib/extern2.c @@ -0,0 +1,9 @@ +/* needed by tests/inline.c */ + +#ifdef __SDCC +#pragma std_sdcc99 +#endif + +extern char inlined_function (void); + +extern char (*inlined_function_pointer) (void) = &inlined_function; diff --git a/support/regression/fwk/lib/fwk.lib b/support/regression/fwk/lib/fwk.lib new file mode 100644 index 0000000..20d6224 --- /dev/null +++ b/support/regression/fwk/lib/fwk.lib @@ -0,0 +1,3 @@ +statics.rel +extern1.rel +extern2.rel diff --git a/support/regression/fwk/lib/spec.mk b/support/regression/fwk/lib/spec.mk new file mode 100644 index 0000000..3cc9b86 --- /dev/null +++ b/support/regression/fwk/lib/spec.mk @@ -0,0 +1,5 @@ +# Regression test framework library + +FWKLIB = $(PORT_CASES_DIR)/statics$(OBJEXT) \ + $(PORT_CASES_DIR)/extern1$(OBJEXT) \ + $(PORT_CASES_DIR)/extern2$(OBJEXT) diff --git a/support/regression/fwk/lib/statics.c b/support/regression/fwk/lib/statics.c new file mode 100644 index 0000000..55ae9df --- /dev/null +++ b/support/regression/fwk/lib/statics.c @@ -0,0 +1,42 @@ +/* needed by tests/bug1477149.c */ + +static long long_1 = 1; + +static long s_get_long_1(void) +{ + long alfa = long_1; + long beta = long_1 + alfa; + long gamma = long_1 + beta; + return alfa + beta + gamma; +} + +long get_long_1(void) +{ + return s_get_long_1(); +} + +static float float_1 = 1; + +static float s_get_float_1(void) +{ + float alfa = float_1; + float beta = float_1 + alfa; + float gamma = float_1 + beta; + return alfa + beta + gamma; +} + +float get_float_1(void) +{ + return s_get_float_1(); +} + +/* for bug 3038028 */ +static char s_get_indexed(char index, char *msg) +{ + return msg[index]; +} + +char get_indexed(char index, char *msg) +{ + return s_get_indexed(index, msg); +} diff --git a/support/regression/fwk/lib/testfwk.c b/support/regression/fwk/lib/testfwk.c new file mode 100644 index 0000000..f8c7a93 --- /dev/null +++ b/support/regression/fwk/lib/testfwk.c @@ -0,0 +1,251 @@ +/** Test framework support functions. + */ +#include <testfwk.h> +#ifndef NO_VARARGS +#include <stdarg.h> +#endif + +#ifdef __SDCC_ds390 +#include <tinibios.h> /* main() must see the ISR declarations */ +#endif + +#ifdef __SDCC_mcs51 +/* until changed, isr's must have a prototype in the module containing main */ +void T2_isr (void) __interrupt 5; +#define MEMSPACE_BUF __idata +#else +#define MEMSPACE_BUF +#endif + +/** Define this if the port's div or mod functions are broken. + A slow loop based method will be substituded. +*/ +//#define BROKEN_DIV_MOD 1 + +extern void _putchar(char c); +extern void _initEmu(void); +extern void _exitEmu(void); + +int __numTests = 0; +static int __numFailures = 0; + +#if BROKEN_DIV_MOD +static int +__div(int num, int denom) +{ + int q = 0; + while (num >= denom) + { + q++; + num -= denom; + } + return q; +} + +static int +__mod (int num, int denom) +{ + while (num >= denom) + { + num -= denom; + } + return num; +} +#else +#define __div(num, denom) ((num) / (denom)) +#define __mod(num, denom) ((num) % (denom)) +#endif + +void +__prints (const char *s) +{ + char c; + + while ('\0' != (c = *s)) + { + _putchar(c); + ++s; + } +} + +void +__printd (int n) +{ + if (0 == n) + { + _putchar('0'); + } + else + { + static char MEMSPACE_BUF buf[6]; + char MEMSPACE_BUF *p = &buf[sizeof (buf) - 1]; + char neg = 0; + + buf[sizeof(buf) - 1] = '\0'; + + if (0 > n) + { + n = -n; + neg = 1; + } + + while (0 != n) + { + *--p = '0' + __mod (n, 10); + n = __div (n, 10); + } + + if (neg) + _putchar('-'); + + __prints(p); + } +} + +void +__printu (unsigned int n) +{ + if (0 == n) + { + _putchar('0'); + } + else + { + static char MEMSPACE_BUF buf[6]; + char MEMSPACE_BUF *p = &buf[sizeof (buf) - 1]; + + buf[sizeof(buf) - 1] = '\0'; + + while (0 != n) + { + *--p = '0' + __mod (n, 10); + n = __div (n, 10); + } + + __prints(p); + } +} + +#ifndef NO_VARARGS +void +__printf (const char *szFormat, ...) +{ + va_list ap; + va_start (ap, szFormat); + + while (*szFormat) + { + if (*szFormat == '%') + { + switch (*++szFormat) + { + case 's': + { + char *sz = va_arg (ap, char *); + __prints(sz); + break; + } + + case 'd': + { + int i = va_arg (ap, int); + __printd (i); + break; + } + + case 'u': + { + unsigned int i = va_arg (ap, unsigned int); + __printu (i); + break; + } + + case '%': + _putchar ('%'); + break; + + default: + break; + } + } + else + { + _putchar (*szFormat); + } + szFormat++; + } + va_end (ap); +} + +void +__fail (__code const char *szMsg, __code const char *szCond, __code const char *szFile, int line) +{ + __printf("--- FAIL: \"%s\" on %s at %s:%u\n", szMsg, szCond, szFile, line); + __numFailures++; +} + +int +main (void) +{ + _initEmu(); + + __printf("--- Running: %s\n", __getSuiteName()); + + __runSuite(); + + __printf("--- Summary: %u/%u/%u: %u failed of %u tests in %u cases.\n", + __numFailures, __numTests, __numCases, + __numFailures, __numTests, __numCases + ); + + _exitEmu(); + + return 0; +} +#else +void +__fail (__code const char *szMsg, __code const char *szCond, __code const char *szFile, int line) +{ + __prints("--- FAIL: \""); + __prints(szMsg); + __prints("\" on "); + __prints(szCond); + __prints(" at "); + __prints(szFile); + _putchar(':'); + __printd(line); + _putchar('\n'); + + __numFailures++; +} + +int +main (void) +{ + _initEmu(); + + __prints("--- Running: "); + __prints(__getSuiteName()); + _putchar('\n'); + + __runSuite(); + + __prints("--- Summary: "); + __printd(__numFailures); + _putchar('/'); + __printd(__numTests); + _putchar('/'); + __printd(__numCases); + __prints(": "); + __printd(__numFailures); + __prints(" failed of "); + __printd(__numTests); + __prints(" tests in "); + __printd(__numCases); + __prints(" cases.\n"); + + _exitEmu(); + + return 0; +} +#endif diff --git a/support/regression/fwk/lib/timeout.c b/support/regression/fwk/lib/timeout.c new file mode 100644 index 0000000..85c5600 --- /dev/null +++ b/support/regression/fwk/lib/timeout.c @@ -0,0 +1,286 @@ +/*------------------------------------------------------------------------- + timeout.c - source file for running ucSim within the regression tests + + Written By - Bernhard Held . bernhard@bernhardheld.de (2001) + Native WIN32 port by - Borut Razem . borut.razem@siol.net (2007) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! +-------------------------------------------------------------------------*/ + +#define PROGNAME "timeout" + +#define USAGE PROGNAME " : 1.10\n" \ + "Usage : " PROGNAME " timeout_in_seconds filename [arguments]\n" \ + " \"filename\" is executed, the arguments are passed to \"filename\".\n" \ + " When \"filename\" exits before the timeout expires, the\n" \ + " exit-status of \"filename\" is returned.\n" \ + " When the timeout expires before \"filename\" exits, \"filename\"\n" \ + " will be killed and an exit-status of 1 is returned.\n" + +#ifdef _WIN32 +#include <windows.h> +#include <stdio.h> +#include <malloc.h> + +/* + Native WIN32 version: + + The program creates a chile process using CreateProcess(). The waits until: + - the child exits + The exit status of the child is returned. + - the timeout elapses + The child will be killed. +*/ + +int +makeCmdLine(char *buf, int argc, const char * const *argv) +{ + int len = 0; + + argv += 2; + while (argc-- > 2) + { + int argLen = strlen(*argv); + len += argLen; + if (buf) + { + memcpy(buf, *argv, argLen); + buf += argLen; + } + if (argc > 2) + { + ++len; + if (buf) + *buf++ = ' '; + } + ++argv; + } + if (buf) + *buf = '\0'; + + return len + 1; +} + +int +main (int argc, const char * const *argv) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + char *cmdLine; + long timeout; + DWORD exitCode; + HANDLE oldStderr; + + if (argc < 3) + { + fprintf (stderr, USAGE); + return 1; + } + timeout = atol (argv[1]); + if (timeout == 0) + { + fprintf (stderr, "Error parameter " PROGNAME ": must be a non-zero dezimal value\n"); + return 1; + } + + cmdLine = alloca(makeCmdLine(NULL, argc, argv)); + makeCmdLine(cmdLine, argc, argv); + + ZeroMemory(&si, sizeof (si)); + si.cb = sizeof (si); + ZeroMemory(&pi, sizeof (pi)); + + /* We'll redirect here stderr to stdout, which will be redirected */ + /* to /dev/null by the shell. The shell could also redirect stderr */ + /* to /dev/null, but then this program doesn't have the chance to */ + /* output any real error. */ + oldStderr = GetStdHandle (STD_ERROR_HANDLE); + SetStdHandle (STD_ERROR_HANDLE, GetStdHandle (STD_OUTPUT_HANDLE)); + + /* Start the child process. */ + if(!CreateProcess (NULL, // No module name (use command line) + cmdLine, // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + TRUE, // Set handle inheritance to TRUE + 0, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) + { + printf ("CreateProcess failed (%d).\n", GetLastError ()); + return 1; + } + + /* Restore stderr */ + SetStdHandle (STD_ERROR_HANDLE, oldStderr); + + /* Wait until child process exits or timeout expires. */ + if (WaitForSingleObject (pi.hProcess, timeout * 1000) == WAIT_TIMEOUT) + { + TerminateProcess (pi.hProcess, 1); + WaitForSingleObject (pi.hProcess, INFINITE); + } + + GetExitCodeProcess (pi.hProcess, &exitCode); + + /* Close process and thread handles. */ + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + + return exitCode; +} + +#else + +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <unistd.h> + +/* First the program tries to limit the maximum CPU-time to the timeout-value. + Then the child is run with execvp(). + + It's not possible to limit the CPU-time under Cygwin (V1.3.3). If setrlimit (RLIMIT_CPU, rlp) + fails, the program will fork() and run the child with execvp(). The fork/exec pair is slow on + Cygwin, but what else can we do? The parent sleeps until: + - a signal shows the childīs exitus + The exit status of the child is returned. + - the timeout elapses + The child will be killed. +*/ + +/* Get the status from all child processes that have terminated, without ever waiting. + This function is designed to be a handler for SIGCHLD, the signal that indicates + that at least one child process has terminated. + http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC401 +*/ + +#ifndef WAIT_ANY + #define WAIT_ANY -1 +#endif + +void +sigchld_handler (int signum) +{ + int pid; + int status; + int exit_status = 0; + + while (1) + { + pid = waitpid (WAIT_ANY, &status, WNOHANG); + if (WEXITSTATUS (status)) + exit_status = 1; // WEXITSTATUS(status); + /* pid == -1: no children */ + /* pid == 0: no children to be noticed */ + if (pid <= 0) + break; + } + exit (exit_status); +} + +int +main (int argc, char * const *argv) +{ + /* if getrlimit() / setrlimit() succeed, then no fork is neeeded */ + int flagNoFork = 0; + int old_stderr; + long timeout; + pid_t pid_child; + struct rlimit rl; + + if (argc < 3) + { + fprintf (stderr, USAGE); + return 1; + } + timeout = atol (argv[1]); + if (timeout == 0) + { + fprintf (stderr, "Error parameter " PROGNAME ": must be a non-zero dezimal value\n"); + return 1; + } + + /* try to use getrlimit() / setrlimit() for RLIMIT_CPU */ + /* to limit the CPU-time */ + if (getrlimit (RLIMIT_CPU, &rl) == 0) + { + rl.rlim_cur = timeout; + if (setrlimit (RLIMIT_CPU, &rl) == 0) + flagNoFork = 1; + } + + if (flagNoFork) + { /* the CPU-time is limited: simple execvp */ + + /* s51 prints warnings on stderr: */ + /* serial input/output interface connected to a non-terminal file. */ + /* We'll redirect here stderr to stdout, which will be redirected */ + /* to /dev/null by the shell. The shell could also redirect stderr */ + /* to /dev/null, but then this program doesn't have the chance to */ + /* output any real error. */ + old_stderr = dup (STDERR_FILENO); + dup2 (STDOUT_FILENO, STDERR_FILENO); + /* shouldn't return */ + execvp (argv[2], argv + 2); + /* restore stderr */ + dup2 (old_stderr, STDERR_FILENO); + perror (argv[2]); + return 1; /* Error */ + } + else + { + /* do it the hard way: fork/exec */ + signal (SIGCHLD, sigchld_handler); + pid_child = fork(); + if (pid_child == 0) + { + /* s51 prints warnings on stderr: */ + /* serial input/output interface connected to a non-terminal file. */ + /* We'll redirect here stderr to stdout, which will be redirected */ + /* to /dev/null by the shell. The shell could also redirect stderr */ + /* to /dev/null, but then this program doesn't have the chance to */ + /* output any real error. */ + old_stderr = dup (STDERR_FILENO); + dup2 (STDOUT_FILENO, STDERR_FILENO); + /* shouldn't return */ + execvp (argv[2], argv + 2); + /* restore stderr */ + dup2 (old_stderr, STDERR_FILENO); + perror (argv[2]); + return 1; /* Error */ + } + else + { + /* this timeout is hopefully aborted by a SIGCHLD */ + sleep (timeout); + fprintf (stderr, PROGNAME ": timeout, killing child %s\n", argv[2]); + kill (pid_child, SIGTERM); + return 1; /* Error */ + } + } +} +#endif |
