merge
This commit is contained in:
		| @@ -587,7 +587,7 @@ Useful Parsers | ||||
|     <tr><td><code>mpc_strip(mpc_parser_t *a);</code></td><td>Matches <code>a</code> consuming any surrounding whitespace</td></tr> | ||||
|     <tr><td><code>mpc_tok(mpc_parser_t *a);</code></td><td>Matches <code>a</code> and consumes any trailing whitespace</td></tr> | ||||
|     <tr><td><code>mpc_sym(const char *s);</code></td><td>Matches string <code>s</code> and consumes any trailing whitespace</td></tr> | ||||
|     <tr><td><code>mpc_total(mpc_parser_t *a, mpc_dtor_t da);</code></td><td>Matches the whitespace consumed <code>a</code>, enclosed in the start and end of input</td></tr> | ||||
|     <tr><td><code>mpc_total(mpc_parser_t *a, mpc_dtor_t da);</code></td><td>Matches the whitespace consumed <code>a</code>, enclosed in the start and end of input</td></tr> | ||||
|     <tr><td><code>mpc_between(mpc_parser_t *a, mpc_dtor_t ad, <br /> const char *o, const char *c);</code></td><td> Matches <code>a</code> between strings <code>o</code> and <code>c</code></td></tr> | ||||
|     <tr><td><code>mpc_parens(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between <code>"("</code> and <code>")"</code></td></tr> | ||||
|     <tr><td><code>mpc_braces(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between <code>"<"</code> and <code>">"</code></td></tr> | ||||
| @@ -597,7 +597,7 @@ Useful Parsers | ||||
|     <tr><td><code>mpc_tok_parens(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between trailing whitespace consumed <code>"("</code> and <code>")"</code></td></tr> | ||||
|     <tr><td><code>mpc_tok_braces(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between trailing whitespace consumed <code>"<"</code> and <code>">"</code></td></tr> | ||||
|     <tr><td><code>mpc_tok_brackets(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between trailing whitespace consumed <code>"{"</code> and <code>"}"</code></td></tr> | ||||
|     <tr><td><code>mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between trailing whitespace consumed <code>"["</code> and <code>"]"</code></td></tr> | ||||
|     <tr><td><code>mpc_tok_squares(mpc_parser_t *a, mpc_dtor_t ad);</code></td><td>Matches <code>a</code> between trailing whitespace consumed <code>"["</code> and <code>"]"</code></td></tr> | ||||
|  | ||||
| </table> | ||||
|  | ||||
|   | ||||
							
								
								
									
										28
									
								
								examples/foobar.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								examples/foobar.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #include "../mpc.h" | ||||
|  | ||||
| int main(int argc, char** argv) { | ||||
|  | ||||
|     mpc_result_t r; | ||||
|     mpc_parser_t* Foobar; | ||||
|  | ||||
|     if (argc != 2) { | ||||
|       printf("Usage: ./foobar <foo/bar>\n"); | ||||
|       exit(0); | ||||
|     } | ||||
|  | ||||
|     Foobar = mpc_new("foobar"); | ||||
|     mpca_lang(MPCA_LANG_DEFAULT, "foobar : \"foo\" | \"bar\";", Foobar); | ||||
|      | ||||
|     if (mpc_parse("<stdin>", argv[1], Foobar, &r)) { | ||||
|         mpc_ast_print(r.output); | ||||
|         mpc_ast_delete(r.output); | ||||
|     } else { | ||||
|         mpc_err_print(r.error); | ||||
|         mpc_err_delete(r.error); | ||||
|     } | ||||
|      | ||||
|     mpc_cleanup(1, Foobar); | ||||
|      | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										61
									
								
								mpc.c
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								mpc.c
									
									
									
									
									
								
							| @@ -122,13 +122,14 @@ void mpc_err_string_cat(char *buffer, int *pos, int *max, char const *fmt, ...) | ||||
|   va_end(va); | ||||
| } | ||||
|  | ||||
| static char char_unescape_buffer[3]; | ||||
| static char char_unescape_buffer[4]; | ||||
|  | ||||
| static const char *mpc_err_char_unescape(char c) { | ||||
|    | ||||
|   char_unescape_buffer[0] = '\''; | ||||
|   char_unescape_buffer[1] = ' '; | ||||
|   char_unescape_buffer[2] = '\''; | ||||
|   char_unescape_buffer[3] = '\0'; | ||||
|    | ||||
|   switch (c) { | ||||
|      | ||||
| @@ -149,11 +150,11 @@ static const char *mpc_err_char_unescape(char c) { | ||||
| } | ||||
|  | ||||
| char *mpc_err_string(mpc_err_t *x) { | ||||
|    | ||||
|   char *buffer = calloc(1, 1024); | ||||
|   int max = 1023; | ||||
|  | ||||
|   int i;   | ||||
|   int pos = 0;  | ||||
|   int i; | ||||
|   int max = 1023; | ||||
|   char *buffer = calloc(1, 1024); | ||||
|    | ||||
|   if (x->failure) { | ||||
|     mpc_err_string_cat(buffer, &pos, &max, | ||||
| @@ -959,7 +960,7 @@ static mpc_err_t *mpc_stack_merger_err(mpc_stack_t *s, int n) { | ||||
| #define MPC_CONTINUE(st, x) mpc_stack_set_state(stk, st); mpc_stack_pushp(stk, x); continue | ||||
| #define MPC_SUCCESS(x) mpc_stack_popp(stk, &p, &st); mpc_stack_pushr(stk, mpc_result_out(x), 1); continue | ||||
| #define MPC_FAILURE(x) mpc_stack_popp(stk, &p, &st); mpc_stack_pushr(stk, mpc_result_err(x), 0); continue | ||||
| #define MPC_PRIMATIVE(x, f) if (f) { MPC_SUCCESS(x); } else { MPC_FAILURE(mpc_err_fail(i->filename, i->state, "Incorrect Input")); } | ||||
| #define MPC_PRIMITIVE(x, f) if (f) { MPC_SUCCESS(x); } else { MPC_FAILURE(mpc_err_fail(i->filename, i->state, "Incorrect Input")); } | ||||
|  | ||||
| int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) { | ||||
|    | ||||
| @@ -983,13 +984,13 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) { | ||||
|        | ||||
|       /* Basic Parsers */ | ||||
|  | ||||
|       case MPC_TYPE_ANY:       MPC_PRIMATIVE(s, mpc_input_any(i, &s)); | ||||
|       case MPC_TYPE_SINGLE:    MPC_PRIMATIVE(s, mpc_input_char(i, p->data.single.x, &s)); | ||||
|       case MPC_TYPE_RANGE:     MPC_PRIMATIVE(s, mpc_input_range(i, p->data.range.x, p->data.range.y, &s)); | ||||
|       case MPC_TYPE_ONEOF:     MPC_PRIMATIVE(s, mpc_input_oneof(i, p->data.string.x, &s)); | ||||
|       case MPC_TYPE_NONEOF:    MPC_PRIMATIVE(s, mpc_input_noneof(i, p->data.string.x, &s)); | ||||
|       case MPC_TYPE_SATISFY:   MPC_PRIMATIVE(s, mpc_input_satisfy(i, p->data.satisfy.f, &s)); | ||||
|       case MPC_TYPE_STRING:    MPC_PRIMATIVE(s, mpc_input_string(i, p->data.string.x, &s)); | ||||
|       case MPC_TYPE_ANY:       MPC_PRIMITIVE(s, mpc_input_any(i, &s)); | ||||
|       case MPC_TYPE_SINGLE:    MPC_PRIMITIVE(s, mpc_input_char(i, p->data.single.x, &s)); | ||||
|       case MPC_TYPE_RANGE:     MPC_PRIMITIVE(s, mpc_input_range(i, p->data.range.x, p->data.range.y, &s)); | ||||
|       case MPC_TYPE_ONEOF:     MPC_PRIMITIVE(s, mpc_input_oneof(i, p->data.string.x, &s)); | ||||
|       case MPC_TYPE_NONEOF:    MPC_PRIMITIVE(s, mpc_input_noneof(i, p->data.string.x, &s)); | ||||
|       case MPC_TYPE_SATISFY:   MPC_PRIMITIVE(s, mpc_input_satisfy(i, p->data.satisfy.f, &s)); | ||||
|       case MPC_TYPE_STRING:    MPC_PRIMITIVE(s, mpc_input_string(i, p->data.string.x, &s)); | ||||
|        | ||||
|       /* Other parsers */ | ||||
|        | ||||
| @@ -1147,7 +1148,7 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) { | ||||
|        | ||||
|       case MPC_TYPE_AND: | ||||
|          | ||||
|         if (p->data.or.n == 0) { MPC_SUCCESS(p->data.and.f(0, NULL)); } | ||||
|         if (p->data.and.n == 0) { MPC_SUCCESS(p->data.and.f(0, NULL)); } | ||||
|          | ||||
|         if (st == 0) { mpc_input_mark(i); MPC_CONTINUE(st+1, p->data.and.xs[st]); } | ||||
|         if (st <= p->data.and.n) { | ||||
| @@ -1176,7 +1177,7 @@ int mpc_parse_input(mpc_input_t *i, mpc_parser_t *init, mpc_result_t *final) { | ||||
| #undef MPC_CONTINUE | ||||
| #undef MPC_SUCCESS | ||||
| #undef MPC_FAILURE | ||||
| #undef MPC_PRIMATIVE | ||||
| #undef MPC_PRIMITIVE | ||||
|  | ||||
| int mpc_parse(const char *filename, const char *string, mpc_parser_t *p, mpc_result_t *r) { | ||||
|   int x; | ||||
| @@ -1945,12 +1946,12 @@ static const char *mpc_re_range_escape_char(char c) { | ||||
| static mpc_val_t *mpcf_re_range(mpc_val_t *x) { | ||||
|    | ||||
|   mpc_parser_t *out; | ||||
|   char *range = calloc(1,1); | ||||
|   size_t i, j; | ||||
|   size_t start, end; | ||||
|   const char *tmp = NULL; | ||||
|   const char *s = x; | ||||
|   int comp = s[0] == '^' ? 1 : 0; | ||||
|   size_t start, end; | ||||
|   size_t i, j; | ||||
|   char *range = calloc(1,1); | ||||
|    | ||||
|   if (s[0] == '\0') { free(x); return mpc_fail("Invalid Regex Range Expression"); }  | ||||
|   if (s[0] == '^' &&  | ||||
| @@ -2144,9 +2145,9 @@ static mpc_val_t *mpcf_escape_new(mpc_val_t *x, const char *input, const char ** | ||||
|    | ||||
|   int i; | ||||
|   int found; | ||||
|   char buff[2]; | ||||
|   char *s = x; | ||||
|   char *y = calloc(1, 1); | ||||
|   char buff[2]; | ||||
|    | ||||
|   while (*s) { | ||||
|      | ||||
| @@ -2180,10 +2181,10 @@ static mpc_val_t *mpcf_unescape_new(mpc_val_t *x, const char *input, const char | ||||
|    | ||||
|   int i; | ||||
|   int found = 0; | ||||
|   char buff[2]; | ||||
|   char *s = x; | ||||
|   char *y = calloc(1, 1); | ||||
|   char buff[2]; | ||||
|  | ||||
|    | ||||
|   while (*s) { | ||||
|      | ||||
|     i = 0; | ||||
| @@ -2201,7 +2202,7 @@ static mpc_val_t *mpcf_unescape_new(mpc_val_t *x, const char *input, const char | ||||
|       } | ||||
|       i++; | ||||
|     } | ||||
|        | ||||
|      | ||||
|     if (!found) { | ||||
|       y = realloc(y, strlen(y) + 2); | ||||
|       buff[0] = *s; buff[1] = '\0'; | ||||
| @@ -2228,6 +2229,12 @@ mpc_val_t *mpcf_unescape(mpc_val_t *x) { | ||||
|   return y; | ||||
| } | ||||
|  | ||||
| mpc_val_t *mpcf_escape_regex(mpc_val_t *x) { | ||||
|   mpc_val_t *y = mpcf_escape_new(x, mpc_escape_input_raw_re, mpc_escape_output_raw_re); | ||||
|   free(x); | ||||
|   return y;   | ||||
| } | ||||
|  | ||||
| mpc_val_t *mpcf_unescape_regex(mpc_val_t *x) { | ||||
|   mpc_val_t *y = mpcf_unescape_new(x, mpc_escape_input_raw_re, mpc_escape_output_raw_re); | ||||
|   free(x); | ||||
| @@ -2276,8 +2283,9 @@ mpc_val_t *mpcf_snd_free(int n, mpc_val_t **xs) { return mpcf_nth_free(n, xs, 1) | ||||
| mpc_val_t *mpcf_trd_free(int n, mpc_val_t **xs) { return mpcf_nth_free(n, xs, 2); } | ||||
|  | ||||
| mpc_val_t *mpcf_strfold(int n, mpc_val_t **xs) { | ||||
|   char *x = calloc(1, 1); | ||||
|   int i; | ||||
|   char *x = calloc(1, 1); | ||||
|  | ||||
|   for (i = 0; i < n; i++) { | ||||
|     x = realloc(x, strlen(x) + strlen(xs[i]) + 1); | ||||
|     strcat(x, xs[i]); | ||||
| @@ -2499,6 +2507,7 @@ void mpc_ast_delete(mpc_ast_t *a) { | ||||
|   int i; | ||||
|    | ||||
|   if (a == NULL) { return; } | ||||
|    | ||||
|   for (i = 0; i < a->children_num; i++) { | ||||
|     mpc_ast_delete(a->children[i]); | ||||
|   } | ||||
| @@ -2612,6 +2621,12 @@ mpc_ast_t *mpc_ast_state(mpc_ast_t *a, mpc_state_t s) { | ||||
| static void mpc_ast_print_depth(mpc_ast_t *a, int d, FILE *fp) { | ||||
|    | ||||
|   int i; | ||||
|    | ||||
|   if (a == NULL) { | ||||
|     fprintf(fp, "NULL\n"); | ||||
|     return; | ||||
|   } | ||||
|    | ||||
|   for (i = 0; i < d; i++) { fprintf(fp, "  "); } | ||||
|    | ||||
|   if (strlen(a->contents)) { | ||||
|   | ||||
							
								
								
									
										9
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "name": "mpc", | ||||
|   "version": "0.8.5", | ||||
|   "repo": "orangeduck/mpc", | ||||
|   "description": "A Parser Combinator library for C", | ||||
|   "keywords": ["parser", "combinator", "library", "c", "mpc"], | ||||
|   "license": "BSD", | ||||
|   "src": ["mpc.c", "mpc.h"] | ||||
| } | ||||
							
								
								
									
										186
									
								
								tests/ptest.c
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								tests/ptest.c
									
									
									
									
									
								
							| @@ -26,32 +26,47 @@ static int suite_passing = 0; | ||||
| /* Colors */ | ||||
|  | ||||
| enum { | ||||
|   BLACK   = 0x0, | ||||
|   BLUE    = 0x1, | ||||
|   GREEN   = 0x2, | ||||
|   AQUA    = 0x3, | ||||
|   RED     = 0x4, | ||||
|   PURPLE  = 0x5, | ||||
|   YELLOW  = 0x6, | ||||
|   WHITE   = 0x7, | ||||
|   GRAY    = 0x8, | ||||
|   LIGHT_BLUE    = 0x9, | ||||
|   LIGHT_GREEN   = 0xA, | ||||
|   LIGHT_AQUA    = 0xB, | ||||
|   LIGHT_RED     = 0xC, | ||||
|   LIGHT_PURPLE  = 0xD, | ||||
|   LIGHT_YELLOW  = 0xE, | ||||
|   LIGHT_WHITE   = 0xF | ||||
|   BLACK   = 0, | ||||
|   BLUE    = 1, | ||||
|   GREEN   = 2, | ||||
|   AQUA    = 3, | ||||
|   RED     = 4, | ||||
|   PURPLE  = 5, | ||||
|   YELLOW  = 6, | ||||
|   WHITE   = 7, | ||||
|   GRAY    = 8, | ||||
|    | ||||
|   LIGHT_BLUE   = 9, | ||||
|   LIGHT_GREEN  = 10, | ||||
|   LIGHT_AQUA   = 11, | ||||
|   LIGHT_RED    = 12, | ||||
|   LIGHT_PURPLE = 13, | ||||
|   LIGHT_YELLOW = 14, | ||||
|   LIGHT_WHITE  = 15, | ||||
|    | ||||
|   DEFAULT      = 16, | ||||
| }; | ||||
|  | ||||
| #ifdef _WIN32 | ||||
|  | ||||
|   #include <windows.h> | ||||
| #include <windows.h> | ||||
|  | ||||
|   static void pt_color(int color) { | ||||
|     HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|     SetConsoleTextAttribute(hCon, color); | ||||
| static WORD defaults; | ||||
| static int defaults_loaded = 0; | ||||
|  | ||||
| static void pt_color(int color) { | ||||
|    | ||||
|   HANDLE cnsl = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|    | ||||
|   if (!defaults_loaded) { | ||||
|     CONSOLE_SCREEN_BUFFER_INFO info; | ||||
|     GetConsoleScreenBufferInfo(cnsl, &info); | ||||
|     defaults = info.wAttributes; | ||||
|     defaults_loaded = 1; | ||||
|   } | ||||
|    | ||||
|   SetConsoleTextAttribute(cnsl, color == DEFAULT ? defaults : color); | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| @@ -71,14 +86,13 @@ static const char* colors[] = { | ||||
|   "\x1B[31m", | ||||
|   "\x1B[35m", | ||||
|   "\x1B[33m", | ||||
|   "\x1B[37m" | ||||
|   "\x1B[37m", | ||||
|   "\x1B[39m", | ||||
| }; | ||||
|  | ||||
|   static void pt_color(int color) { | ||||
|      | ||||
|     printf("%s", colors[color]); | ||||
|    | ||||
|   } | ||||
| static void pt_color(int color) {   | ||||
|   printf("%s", colors[color]); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @@ -92,16 +106,18 @@ static char assert_err[MAX_ERROR]; | ||||
| static char assert_err_buff[MAX_ERROR]; | ||||
| static int assert_err_num = 0; | ||||
|  | ||||
| void pt_assert_run(int result, const char* expr, const char* func, const char* file, int line) { | ||||
| void pt_assert_run( | ||||
|   int result, const char* expr, const char* func, const char* file, int line) { | ||||
|    | ||||
|   (void) func; | ||||
|   num_asserts++; | ||||
|   test_passing = test_passing && result; | ||||
|    | ||||
|   if (result) { | ||||
|     num_assert_passes++; | ||||
|   } else { | ||||
|     sprintf(assert_err_buff, "        %i. Assert [ %s ] (%s:%i)\n", assert_err_num+1, expr, file, line ); | ||||
|     sprintf(assert_err_buff,  | ||||
|       "        %i. Assert [ %s ] (%s:%i)\n",  | ||||
|       assert_err_num+1, expr, file, line ); | ||||
|     strcat(assert_err, assert_err_buff); | ||||
|     assert_err_num++; | ||||
|     num_assert_fails++; | ||||
| @@ -110,22 +126,29 @@ void pt_assert_run(int result, const char* expr, const char* func, const char* f | ||||
| } | ||||
|  | ||||
| static void ptest_signal(int sig) { | ||||
|    | ||||
|  | ||||
|   test_passing = 0; | ||||
|    | ||||
|   switch( sig ) { | ||||
|     case SIGFPE:  sprintf(assert_err_buff, "        %i. Division by Zero\n", assert_err_num+1); break; | ||||
|     case SIGILL:  sprintf(assert_err_buff, "        %i. Illegal Instruction\n", assert_err_num+1); break; | ||||
|     case SIGSEGV: sprintf(assert_err_buff, "        %i. Segmentation Fault\n", assert_err_num+1); break; | ||||
|     default: break; | ||||
|     case SIGFPE:  sprintf(assert_err_buff, | ||||
|       "        %i. Division by Zero\n", assert_err_num+1); | ||||
|     break; | ||||
|     case SIGILL:  sprintf(assert_err_buff, | ||||
|       "        %i. Illegal Instruction\n", assert_err_num+1); | ||||
|     break; | ||||
|     case SIGSEGV: sprintf(assert_err_buff, | ||||
|       "        %i. Segmentation Fault\n", assert_err_num+1); | ||||
|     break; | ||||
|   } | ||||
|    | ||||
|   assert_err_num++; | ||||
|   strcat(assert_err, assert_err_buff); | ||||
|    | ||||
|   pt_color(WHITE); pt_color(RED); printf("Failed! \n\n%s\n", assert_err); pt_color(WHITE); | ||||
|   pt_color(RED);  | ||||
|   printf("Failed! \n\n%s\n", assert_err); | ||||
|   pt_color(DEFAULT); | ||||
|    | ||||
|   printf("    | Stopping Execution.\n"); | ||||
|   puts("    | Stopping Execution."); | ||||
|   fflush(stdout); | ||||
|   exit(0); | ||||
|    | ||||
| @@ -134,14 +157,14 @@ static void ptest_signal(int sig) { | ||||
| /* Tests */ | ||||
|  | ||||
| static void pt_title_case(char* output, const char* input) { | ||||
|    | ||||
|  | ||||
|   int space = 1; | ||||
|   size_t i; | ||||
|   unsigned int i; | ||||
|    | ||||
|   strcpy(output, input); | ||||
|    | ||||
|   for(i = 0; i < strlen(output); i++) { | ||||
|      | ||||
|  | ||||
|     if (output[i] == '_' || output[i] == ' ') { | ||||
|       space = 1; | ||||
|       output[i] = ' '; | ||||
| @@ -173,19 +196,22 @@ static int num_tests_passes = 0; | ||||
| static int num_tests_fails  = 0; | ||||
|  | ||||
| void pt_add_test(void (*func)(void), const char* name, const char* suite) { | ||||
|    | ||||
|  | ||||
|   test_t test; | ||||
|  | ||||
|   if (num_tests == MAX_TESTS) { | ||||
|     printf("ERROR: Exceeded maximum test count of %i!\n", MAX_TESTS); abort(); | ||||
|     printf("ERROR: Exceeded maximum test count of %i!\n",  | ||||
|       MAX_TESTS); abort(); | ||||
|   } | ||||
|    | ||||
|   if (strlen(name) >= MAX_NAME) { | ||||
|     printf("ERROR: Test name '%s' too long (Maximum is %i characters)\n", name, MAX_NAME); abort(); | ||||
|     printf("ERROR: Test name '%s' too long (Maximum is %i characters)\n",  | ||||
|       name, MAX_NAME); abort(); | ||||
|   } | ||||
|    | ||||
|   if (strlen(suite) >= MAX_NAME) { | ||||
|     printf("ERROR: Test suite '%s' too long (Maximum is %i characters)\n", suite, MAX_NAME); abort(); | ||||
|     printf("ERROR: Test suite '%s' too long (Maximum is %i characters)\n",  | ||||
|       suite, MAX_NAME); abort(); | ||||
|   } | ||||
|    | ||||
|   test.func = func; | ||||
| @@ -194,7 +220,6 @@ void pt_add_test(void (*func)(void), const char* name, const char* suite) { | ||||
|    | ||||
|   tests[num_tests] = test; | ||||
|   num_tests++; | ||||
|    | ||||
| } | ||||
|  | ||||
| /* Suites */ | ||||
| @@ -215,17 +240,18 @@ static char current_suite[MAX_NAME]; | ||||
|  | ||||
| int pt_run(void) { | ||||
|    | ||||
|   int i; | ||||
|   unsigned int i; | ||||
|   double total; | ||||
|   test_t test; | ||||
|  | ||||
|   printf("    \n"); | ||||
|   printf("    +-------------------------------------------+\n"); | ||||
|   printf("    | ptest          MicroTesting Magic for C   |\n"); | ||||
|   printf("    |                                           |\n"); | ||||
|   printf("    | http://github.com/orangeduck/ptest        |\n"); | ||||
|   printf("    |                                           |\n"); | ||||
|   printf("    | Daniel Holden (contact@theorangeduck.com) |\n"); | ||||
|   printf("    +-------------------------------------------+\n"); | ||||
|   puts(""); | ||||
|   puts("    +-------------------------------------------+"); | ||||
|   puts("    | ptest          MicroTesting Magic for C   |"); | ||||
|   puts("    |                                           |"); | ||||
|   puts("    | http://github.com/orangeduck/ptest        |"); | ||||
|   puts("    |                                           |"); | ||||
|   puts("    | Daniel Holden (contact@theorangeduck.com) |"); | ||||
|   puts("    +-------------------------------------------+"); | ||||
|    | ||||
|   signal(SIGFPE,  ptest_signal); | ||||
|   signal(SIGILL,  ptest_signal); | ||||
| @@ -235,12 +261,12 @@ int pt_run(void) { | ||||
|   strcpy(current_suite, ""); | ||||
|    | ||||
|   for(i = 0; i < num_tests; i++) { | ||||
|      | ||||
|     test_t test = tests[i]; | ||||
|  | ||||
|     test = tests[i]; | ||||
|      | ||||
|     /* Check for transition to a new suite */ | ||||
|     if (strcmp(test.suite, current_suite)) { | ||||
|        | ||||
|  | ||||
|       /* Don't increment any counter for first entrance */ | ||||
|       if (strcmp(current_suite, "")) { | ||||
|         if (suite_passing) { | ||||
| @@ -262,6 +288,7 @@ int pt_run(void) { | ||||
|     strcpy(assert_err_buff, ""); | ||||
|     assert_err_num = 0; | ||||
|     printf("    | %s ... ", test.name); | ||||
|     fflush(stdout); | ||||
|      | ||||
|     test.func(); | ||||
|      | ||||
| @@ -269,10 +296,14 @@ int pt_run(void) { | ||||
|      | ||||
|     if (test_passing) { | ||||
|       num_tests_passes++; | ||||
|       pt_color(GREEN);  printf("Passed! \n"); pt_color(WHITE); | ||||
|       pt_color(GREEN); | ||||
|       puts("Passed!"); | ||||
|       pt_color(DEFAULT); | ||||
|     } else { | ||||
|       num_tests_fails++; | ||||
|       pt_color(RED);    printf("Failed! \n\n%s\n", assert_err); pt_color(WHITE); | ||||
|       pt_color(RED);  | ||||
|       printf("Failed! \n\n%s\n", assert_err); | ||||
|       pt_color(DEFAULT); | ||||
|     } | ||||
|      | ||||
|   } | ||||
| @@ -285,28 +316,37 @@ int pt_run(void) { | ||||
|    | ||||
|   end = clock(); | ||||
|    | ||||
|   printf("  \n"); | ||||
|   printf("  +---------------------------------------------------+\n"); | ||||
|   printf("  |                      Summary                      |\n"); | ||||
|   printf("  +---------++------------+-------------+-------------+\n"); | ||||
|   puts(""); | ||||
|   puts("  +---------------------------------------------------+"); | ||||
|   puts("  |                      Summary                      |"); | ||||
|   puts("  +---------++------------+-------------+-------------+"); | ||||
|    | ||||
|   printf("  | Suites  ||"); | ||||
|   pt_color(YELLOW); printf(" Total %4d ",  num_suites);        pt_color(WHITE); printf("|"); | ||||
|   pt_color(GREEN);  printf(" Passed %4d ", num_suites_passes); pt_color(WHITE); printf("|"); | ||||
|   pt_color(RED);    printf(" Failed %4d ", num_suites_fails);  pt_color(WHITE); printf("|\n"); | ||||
|   pt_color(YELLOW);  printf(" Total %4d ",  num_suites);         | ||||
|   pt_color(DEFAULT); putchar('|'); | ||||
|   pt_color(GREEN);   printf(" Passed %4d ", num_suites_passes);  | ||||
|   pt_color(DEFAULT); putchar('|'); | ||||
|   pt_color(RED);     printf(" Failed %4d ", num_suites_fails);   | ||||
|   pt_color(DEFAULT); puts("|"); | ||||
|    | ||||
|   printf("  | Tests   ||"); | ||||
|   pt_color(YELLOW); printf(" Total %4d ",  num_tests);         pt_color(WHITE); printf("|"); | ||||
|   pt_color(GREEN);  printf(" Passed %4d ", num_tests_passes);  pt_color(WHITE); printf("|"); | ||||
|   pt_color(RED);    printf(" Failed %4d ", num_tests_fails);   pt_color(WHITE); printf("|\n"); | ||||
|   pt_color(YELLOW);  printf(" Total %4d ",  num_tests);          | ||||
|   pt_color(DEFAULT); putchar('|'); | ||||
|   pt_color(GREEN);   printf(" Passed %4d ", num_tests_passes);   | ||||
|   pt_color(DEFAULT); putchar('|'); | ||||
|   pt_color(RED);     printf(" Failed %4d ", num_tests_fails);    | ||||
|   pt_color(DEFAULT); puts("|"); | ||||
|    | ||||
|   printf("  | Asserts ||"); | ||||
|   pt_color(YELLOW); printf(" Total %4d ",  num_asserts);       pt_color(WHITE); printf("|"); | ||||
|   pt_color(GREEN);  printf(" Passed %4d ", num_assert_passes); pt_color(WHITE); printf("|"); | ||||
|   pt_color(RED);    printf(" Failed %4d ", num_assert_fails);  pt_color(WHITE); printf("|\n"); | ||||
|   pt_color(YELLOW);  printf(" Total %4d ",  num_asserts);        | ||||
|   pt_color(DEFAULT); putchar('|'); | ||||
|   pt_color(GREEN);   printf(" Passed %4d ", num_assert_passes);  | ||||
|   pt_color(DEFAULT); putchar('|'); | ||||
|   pt_color(RED);     printf(" Failed %4d ", num_assert_fails);   | ||||
|   pt_color(DEFAULT); puts("|"); | ||||
|    | ||||
|   printf("  +---------++------------+-------------+-------------+\n"); | ||||
|   printf("  \n"); | ||||
|   puts("  +---------++------------+-------------+-------------+"); | ||||
|   puts(""); | ||||
|    | ||||
|   total = (double)(end - start) / CLOCKS_PER_SEC; | ||||
|    | ||||
|   | ||||
| @@ -18,5 +18,4 @@ void pt_add_test(void (*func)(void), const char* name, const char* suite); | ||||
| void pt_add_suite(void (*func)(void)); | ||||
| int pt_run(void); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Holden
					Daniel Holden