#include <stdio.h>#include <ctype.h>#include <string.h>

Go to the source code of this file.
Defines | |
| #define | NULL (0) |
| #define | is_ascii(c) 1 |
| #define | is_space(c) (is_ascii(c) && isspace(c)) |
| #define | is_alpha(c) (is_ascii(c) && isalpha(c)) |
| #define | is_alnum(c) (is_ascii(c) && isalnum(c)) |
| #define | isidchar(ch) (is_alnum(ch) || (ch) == '_') |
| #define | isidfirstchar(ch) (is_alpha(ch) || (ch) == '_') |
| #define | bufsize 5000 |
Functions | |
| char * | malloc () |
| int | free () |
| char * | ppdirforward () |
| char * | ppdirbackward () |
| char * | skipspace () |
| char * | scanstring () |
| int | writeblanks () |
| int | test1 () |
| int | convert1 () |
| int | main (int argc, argv) |
| char * | ppdirforward (char *p) |
| char * | ppdirbackward (char *p, char *limit) |
| char * | skipspace (char *p, int dir) |
| char * | scanstring (char *p, int dir) |
| int | writeblanks (char *start, char *end) |
| int | test1 (char *buf) |
| int | convert1 (char *buf, FILE *out, int header, int convert_varargs) |
| #define bufsize 5000 |
Referenced by main().
| #define is_alnum | ( | c | ) | (is_ascii(c) && isalnum(c)) |
Definition at line 213 of file ansi2knr.c.
| #define is_alpha | ( | c | ) | (is_ascii(c) && isalpha(c)) |
Definition at line 212 of file ansi2knr.c.
| #define is_ascii | ( | c | ) | 1 |
Definition at line 206 of file ansi2knr.c.
| #define is_space | ( | c | ) | (is_ascii(c) && isspace(c)) |
| #define isidchar | ( | ch | ) | (is_alnum(ch) || (ch) == '_') |
| #define isidfirstchar | ( | ch | ) | (is_alpha(ch) || (ch) == '_') |
| #define NULL (0) |
Definition at line 193 of file ansi2knr.c.
Referenced by Triangulation::__checkAll(), Triangulation::__checkLine(), Triangulation::__colorize(), Triangulation::__elimination_tri(), Triangulation::__find_P_in_elt(), Triangulation::__findVertex(), ConnectedTriangle::__initNeighs(), Triangulation::__insertPoint(), Triangulation::__permutation(), Triangulation::__scanNeigh(), convert1(), main(), MeshReader::MeshReader(), SolverDriver::run(), Timer::start(), Timer::stop(), and MeshReader::~MeshReader().
| int convert1 | ( | char * | buf, | |
| FILE * | out, | |||
| int | header, | |||
| int | convert_varargs | |||
| ) |
Definition at line 556 of file ansi2knr.c.
References free(), isidchar, isidfirstchar, malloc(), NULL, scanstring(), skipspace(), and writeblanks().
00561 { char *endfn; 00562 char *p; 00563 /* 00564 * The breaks table contains pointers to the beginning and end 00565 * of each argument. 00566 */ 00567 char **breaks; 00568 unsigned num_breaks = 2; /* for testing */ 00569 char **btop; 00570 char **bp; 00571 char **ap; 00572 char *vararg = 0; 00573 00574 /* Pre-ANSI implementations don't agree on whether strchr */ 00575 /* is called strchr or index, so we open-code it here. */ 00576 for ( endfn = buf; *(endfn++) != '('; ) 00577 ; 00578 top: p = endfn; 00579 breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); 00580 if ( breaks == NULL ) 00581 { /* Couldn't allocate break table, give up */ 00582 fprintf(stderr, "Unable to allocate break table!\n"); 00583 fputs(buf, out); 00584 return -1; 00585 } 00586 btop = breaks + num_breaks * 2 - 2; 00587 bp = breaks; 00588 /* Parse the argument list */ 00589 do 00590 { int level = 0; 00591 char *lp = NULL; 00592 char *rp = NULL; 00593 char *end = NULL; 00594 00595 if ( bp >= btop ) 00596 { /* Filled up break table. */ 00597 /* Allocate a bigger one and start over. */ 00598 free((char *)breaks); 00599 num_breaks <<= 1; 00600 goto top; 00601 } 00602 *bp++ = p; 00603 /* Find the end of the argument */ 00604 for ( ; end == NULL; p++ ) 00605 { switch(*p) 00606 { 00607 case ',': 00608 if ( !level ) end = p; 00609 break; 00610 case '(': 00611 if ( !level ) lp = p; 00612 level++; 00613 break; 00614 case ')': 00615 if ( --level < 0 ) end = p; 00616 else rp = p; 00617 break; 00618 case '/': 00619 if (p[1] == '*') 00620 p = skipspace(p, 1) - 1; 00621 break; 00622 case '"': 00623 p = scanstring(p, 1) - 1; 00624 break; 00625 default: 00626 ; 00627 } 00628 } 00629 /* Erase any embedded prototype parameters. */ 00630 if ( lp && rp ) 00631 writeblanks(lp + 1, rp); 00632 p--; /* back up over terminator */ 00633 /* Find the name being declared. */ 00634 /* This is complicated because of procedure and */ 00635 /* array modifiers. */ 00636 for ( ; ; ) 00637 { p = skipspace(p - 1, -1); 00638 switch ( *p ) 00639 { 00640 case ']': /* skip array dimension(s) */ 00641 case ')': /* skip procedure args OR name */ 00642 { int level = 1; 00643 while ( level ) 00644 switch ( *--p ) 00645 { 00646 case ']': case ')': 00647 level++; 00648 break; 00649 case '[': case '(': 00650 level--; 00651 break; 00652 case '/': 00653 if (p > buf && p[-1] == '*') 00654 p = skipspace(p, -1) + 1; 00655 break; 00656 case '"': 00657 p = scanstring(p, -1) + 1; 00658 break; 00659 default: ; 00660 } 00661 } 00662 if ( *p == '(' && *skipspace(p + 1, 1) == '*' ) 00663 { /* We found the name being declared */ 00664 while ( !isidfirstchar(*p) ) 00665 p = skipspace(p, 1) + 1; 00666 goto found; 00667 } 00668 break; 00669 default: 00670 goto found; 00671 } 00672 } 00673 found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' ) 00674 { if ( convert_varargs ) 00675 { *bp++ = "va_alist"; 00676 vararg = p-2; 00677 } 00678 else 00679 { p++; 00680 if ( bp == breaks + 1 ) /* sole argument */ 00681 writeblanks(breaks[0], p); 00682 else 00683 writeblanks(bp[-1] - 1, p); 00684 bp--; 00685 } 00686 } 00687 else 00688 { while ( isidchar(*p) ) p--; 00689 *bp++ = p+1; 00690 } 00691 p = end; 00692 } 00693 while ( *p++ == ',' ); 00694 *bp = p; 00695 /* Make a special check for 'void' arglist */ 00696 if ( bp == breaks+2 ) 00697 { p = skipspace(breaks[0], 1); 00698 if ( !strncmp(p, "void", 4) ) 00699 { p = skipspace(p+4, 1); 00700 if ( p == breaks[2] - 1 ) 00701 { bp = breaks; /* yup, pretend arglist is empty */ 00702 writeblanks(breaks[0], p + 1); 00703 } 00704 } 00705 } 00706 /* Put out the function name and left parenthesis. */ 00707 p = buf; 00708 while ( p != endfn ) putc(*p, out), p++; 00709 /* Put out the declaration. */ 00710 if ( header ) 00711 { fputs(");", out); 00712 for ( p = breaks[0]; *p; p++ ) 00713 if ( *p == '\r' || *p == '\n' ) 00714 putc(*p, out); 00715 } 00716 else 00717 { for ( ap = breaks+1; ap < bp; ap += 2 ) 00718 { p = *ap; 00719 while ( isidchar(*p) ) 00720 putc(*p, out), p++; 00721 if ( ap < bp - 1 ) 00722 fputs(", ", out); 00723 } 00724 fputs(") ", out); 00725 /* Put out the argument declarations */ 00726 for ( ap = breaks+2; ap <= bp; ap += 2 ) 00727 (*ap)[-1] = ';'; 00728 if ( vararg != 0 ) 00729 { *vararg = 0; 00730 fputs(breaks[0], out); /* any prior args */ 00731 fputs("va_dcl", out); /* the final arg */ 00732 fputs(bp[0], out); 00733 } 00734 else 00735 fputs(breaks[0], out); 00736 } 00737 free((char *)breaks); 00738 return 0; 00739 }

| int convert1 | ( | ) |
Referenced by main().
| int free | ( | ) |
Referenced by convert1(), and main().
| int main | ( | int | argc, | |
| argv | ||||
| ) |
Definition at line 230 of file ansi2knr.c.
References bufsize, convert1(), free(), malloc(), NULL, ppdirforward(), skipspace(), and test1().
00233 { FILE *in = stdin; 00234 FILE *out = stdout; 00235 char *filename = 0; 00236 char *program_name = argv[0]; 00237 char *output_name = 0; 00238 #define bufsize 5000 /* arbitrary size */ 00239 char *buf; 00240 char *line; 00241 char *more; 00242 char *usage = 00243 "Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n"; 00244 /* 00245 * In previous versions, ansi2knr recognized a --varargs switch. 00246 * If this switch was supplied, ansi2knr would attempt to convert 00247 * a ... argument to va_alist and va_dcl; if this switch was not 00248 * supplied, ansi2knr would simply drop any such arguments. 00249 * Now, ansi2knr always does this conversion, and we only 00250 * check for this switch for backward compatibility. 00251 */ 00252 int convert_varargs = 1; 00253 int output_error; 00254 00255 while ( argc > 1 && argv[1][0] == '-' ) { 00256 if ( !strcmp(argv[1], "--varargs") ) { 00257 convert_varargs = 1; 00258 argc--; 00259 argv++; 00260 continue; 00261 } 00262 if ( !strcmp(argv[1], "--filename") && argc > 2 ) { 00263 filename = argv[2]; 00264 argc -= 2; 00265 argv += 2; 00266 continue; 00267 } 00268 fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name, 00269 argv[1]); 00270 fprintf(stderr, usage); 00271 exit(1); 00272 } 00273 switch ( argc ) 00274 { 00275 default: 00276 fprintf(stderr, usage); 00277 exit(0); 00278 case 3: 00279 output_name = argv[2]; 00280 out = fopen(output_name, "w"); 00281 if ( out == NULL ) { 00282 fprintf(stderr, "%s: Cannot open output file %s\n", 00283 program_name, output_name); 00284 exit(1); 00285 } 00286 /* falls through */ 00287 case 2: 00288 in = fopen(argv[1], "r"); 00289 if ( in == NULL ) { 00290 fprintf(stderr, "%s: Cannot open input file %s\n", 00291 program_name, argv[1]); 00292 exit(1); 00293 } 00294 if ( filename == 0 ) 00295 filename = argv[1]; 00296 /* falls through */ 00297 case 1: 00298 break; 00299 } 00300 if ( filename ) 00301 fprintf(out, "#line 1 \"%s\"\n", filename); 00302 buf = malloc(bufsize); 00303 if ( buf == NULL ) 00304 { 00305 fprintf(stderr, "Unable to allocate read buffer!\n"); 00306 exit(1); 00307 } 00308 line = buf; 00309 while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) 00310 { 00311 test: line += strlen(line); 00312 switch ( test1(buf) ) 00313 { 00314 case 2: /* a function header */ 00315 convert1(buf, out, 1, convert_varargs); 00316 break; 00317 case 1: /* a function */ 00318 /* Check for a { at the start of the next line. */ 00319 more = ++line; 00320 f: if ( line >= buf + (bufsize - 1) ) /* overflow check */ 00321 goto wl; 00322 if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL ) 00323 goto wl; 00324 switch ( *skipspace(ppdirforward(more), 1) ) 00325 { 00326 case '{': 00327 /* Definitely a function header. */ 00328 convert1(buf, out, 0, convert_varargs); 00329 fputs(more, out); 00330 break; 00331 case 0: 00332 /* The next line was blank or a comment: */ 00333 /* keep scanning for a non-comment. */ 00334 line += strlen(line); 00335 goto f; 00336 default: 00337 /* buf isn't a function header, but */ 00338 /* more might be. */ 00339 fputs(buf, out); 00340 strcpy(buf, more); 00341 line = buf; 00342 goto test; 00343 } 00344 break; 00345 case -1: /* maybe the start of a function */ 00346 if ( line != buf + (bufsize - 1) ) /* overflow check */ 00347 continue; 00348 /* falls through */ 00349 default: /* not a function */ 00350 wl: fputs(buf, out); 00351 break; 00352 } 00353 line = buf; 00354 } 00355 if ( line != buf ) 00356 fputs(buf, out); 00357 free(buf); 00358 if ( output_name ) { 00359 output_error = ferror(out); 00360 output_error |= fclose(out); 00361 } else { /* out == stdout */ 00362 fflush(out); 00363 output_error = ferror(out); 00364 } 00365 if ( output_error ) { 00366 fprintf(stderr, "%s: error writing to %s\n", program_name, 00367 (output_name ? output_name : "stdout")); 00368 exit(1); 00369 } 00370 if ( in != stdin ) 00371 fclose(in); 00372 return 0; 00373 }

| char* malloc | ( | ) |
Referenced by convert1(), and main().
| char* ppdirbackward | ( | char * | p, | |
| char * | limit | |||
| ) |
Definition at line 392 of file ansi2knr.c.
00395 { 00396 char *np = p; 00397 00398 for (;; p = --np) { 00399 if (*np == '\n' && np[-1] == '\r') 00400 --np; 00401 for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np) 00402 if (np[-1] == 0) 00403 return np; 00404 if (*np != '#') 00405 return p; 00406 } 00407 }
| char* ppdirbackward | ( | ) |
Referenced by test1().
| char* ppdirforward | ( | char * | p | ) |
Definition at line 379 of file ansi2knr.c.
00381 { 00382 for (; *p == '#'; ++p) { 00383 for (; *p != '\r' && *p != '\n'; ++p) 00384 if (*p == 0) 00385 return p; 00386 if (*p == '\r' && p[1] == '\n') 00387 ++p; 00388 } 00389 return p; 00390 }
| char* ppdirforward | ( | ) |
Referenced by main().
| char* scanstring | ( | char * | p, | |
| int | dir | |||
| ) |
Definition at line 436 of file ansi2knr.c.
00439 { 00440 for (p += dir; ; p += dir) 00441 if (*p == '"' && p[-dir] != '\\') 00442 return p + dir; 00443 }
| char* scanstring | ( | ) |
Referenced by convert1().
| char* skipspace | ( | char * | p, | |
| int | dir | |||
| ) |
Definition at line 414 of file ansi2knr.c.
References is_space.
00417 { 00418 for ( ; ; ) { 00419 while ( is_space(*p) ) 00420 p += dir; 00421 if ( !(*p == '/' && p[dir] == '*') ) 00422 break; 00423 p += dir; p += dir; 00424 while ( !(*p == '*' && p[dir] == '/') ) { 00425 if ( *p == 0 ) 00426 return p; /* multi-line comment?? */ 00427 p += dir; 00428 } 00429 p += dir; p += dir; 00430 } 00431 return p; 00432 }
| char* skipspace | ( | ) |
Referenced by convert1(), main(), and test1().
| int test1 | ( | char * | buf | ) |
Definition at line 474 of file ansi2knr.c.
References isidchar, isidfirstchar, ppdirbackward(), and skipspace().
00476 { char *p = buf; 00477 char *bend; 00478 char *endfn; 00479 int contin; 00480 00481 if ( !isidfirstchar(*p) ) 00482 return 0; /* no name at left margin */ 00483 bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1); 00484 switch ( *bend ) 00485 { 00486 case ';': contin = 0 /*2*/; break; 00487 case ')': contin = 1; break; 00488 case '{': return 0; /* not a function */ 00489 case '}': return 0; /* not a function */ 00490 default: contin = -1; 00491 } 00492 while ( isidchar(*p) ) 00493 p++; 00494 endfn = p; 00495 p = skipspace(p, 1); 00496 if ( *p++ != '(' ) 00497 return 0; /* not a function */ 00498 p = skipspace(p, 1); 00499 if ( *p == ')' ) 00500 return 0; /* no parameters */ 00501 /* Check that the apparent function name isn't a keyword. */ 00502 /* We only need to check for keywords that could be followed */ 00503 /* by a left parenthesis (which, unfortunately, is most of them). */ 00504 { static char *words[] = 00505 { "asm", "auto", "case", "char", "const", "double", 00506 "extern", "float", "for", "if", "int", "long", 00507 "register", "return", "short", "signed", "sizeof", 00508 "static", "switch", "typedef", "unsigned", 00509 "void", "volatile", "while", 0 00510 }; 00511 char **key = words; 00512 char *kp; 00513 unsigned len = endfn - buf; 00514 00515 while ( (kp = *key) != 0 ) 00516 { if ( strlen(kp) == len && !strncmp(kp, buf, len) ) 00517 return 0; /* name is a keyword */ 00518 key++; 00519 } 00520 } 00521 { 00522 char *id = p; 00523 int len; 00524 /* 00525 * Check for identifier1(identifier2) and not 00526 * identifier1(void), or identifier1(identifier2, xxxx). 00527 */ 00528 00529 while ( isidchar(*p) ) 00530 p++; 00531 len = p - id; 00532 p = skipspace(p, 1); 00533 if (*p == ',' || 00534 (*p == ')' && (len != 4 || strncmp(id, "void", 4))) 00535 ) 00536 return 0; /* not a function */ 00537 } 00538 /* 00539 * If the last significant character was a ), we need to count 00540 * parentheses, because it might be part of a formal parameter 00541 * that is a procedure. 00542 */ 00543 if (contin > 0) { 00544 int level = 0; 00545 00546 for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1)) 00547 level += (*p == '(' ? 1 : *p == ')' ? -1 : 0); 00548 if (level > 0) 00549 contin = -1; 00550 } 00551 return contin; 00552 }

| int test1 | ( | ) |
Referenced by main().
| int writeblanks | ( | char * | start, | |
| char * | end | |||
| ) |
Definition at line 450 of file ansi2knr.c.
00453 { char *p; 00454 for ( p = start; p < end; p++ ) 00455 if ( *p != '\r' && *p != '\n' ) 00456 *p = ' '; 00457 return 0; 00458 }
| int writeblanks | ( | ) |
Referenced by convert1().
1.5.6