text: #include <stdio.h>
  #include <stdlib.h>
  
  #define LINELEN 8192
  #define STRINGLEN 1024
  int drop_comment( char *);
  int change_to_lower( char *, int );
  
  int
  main( int argc , char *argv[] )
  {
    FILE *fp ;
    char linei[LINELEN] ;
    char lineo[8*LINELEN] ;
    char wrf_error_fatal_str[STRINGLEN] ;
    char surface_driver_str[STRINGLEN] ;
    char radiation_driver_str[STRINGLEN] ;
    char cumulus_driver_str[STRINGLEN] ;
    char pbl_driver_str[STRINGLEN] ;
    char *p, *q, *r ;
    char firstp ;
    int state, ns, ns2 ;
    int inparen ;
    int inacall ;
    int col ;
  
    if ( argc != 2 ) {
       fprintf(stderr,"usage: %s file\n",argv[0]) ;
    }
    if ((fp = fopen(argv[1],"r"))==NULL) {
      fprintf(stderr,"cannot open %s for reading\n",argv[1]) ;
      exit(2) ;
    }
    while ( fgets( linei, LINELEN, fp ) != NULL ) {
      lineo[0] = '\0' ;
      if ( linei[0] != '#' ) drop_comment( linei ) ;
      inacall = 0 ;
      for ( p = linei, q = lineo , firstp = *p ; *p ; p++ ) {
        if ( !inacall && (*(p+0) == 'c' || *(p+0) == 'C' ) && 
             (*(p+1) == 'a' || *(p+1) == 'A' ) &&
             (*(p+2) == 'l' || *(p+2) == 'L' ) &&
             (*(p+3) == 'l' || *(p+3) == 'L' ) && firstp != '#' )
        {
          inacall = 1 ;
          strncpy(q,p,4) ; q+=4 ;
          ns = 1 ; while (  *(p+3+ns) && *(p+3+ns) != '\n' &&
                           (*(p+3+ns) == ' ' || 
                            *(p+3+ns) == '\t' )) { *q++ = *(p+3+ns) ; ns++ ; }
  
          strncpy(wrf_error_fatal_str,  p+3+ns,15+1) ; change_to_lower(wrf_error_fatal_str,15+1 ) ; /* 15, but add one to check for '3' */
          strncpy(surface_driver_str,   p+3+ns,14)   ; change_to_lower(surface_driver_str,14) ;
          strncpy(radiation_driver_str, p+3+ns,16)   ; change_to_lower(radiation_driver_str,16) ;
          strncpy(cumulus_driver_str,   p+3+ns,14)   ; change_to_lower(cumulus_driver_str,14) ;
          strncpy(pbl_driver_str,       p+3+ns,10)   ; change_to_lower(pbl_driver_str,10) ;
  
          if ( !strncmp( wrf_error_fatal_str, "wrf_error_fatal", 15 ) && wrf_error_fatal_str[15] != '3' )
          {
            ns2 = 1 ; while ( *(p+3+ns+14+ns2) && *(p+3+ns+14+ns2) != '\n' &&
                             (*(p+3+ns+14+ns2) == ' ' ) ) ns2++ ;
            if ( *(p+3+ns+14+ns2) == '(' ) {
               *q='\0';
               printf("%s",lineo) ;
               printf("wrf_error_fatal3(__FILE__,__LINE__,&\n") ;
               ns2 = 1 ; while ( *(p+3+ns+14+ns2) && *(p+3+ns+14+ns2) != '\n' &&
                                (*(p+3+ns+14+ns2) == ' ' || 
                                 *(p+3+ns+14+ns2) == '(' ||
                                 *(p+3+ns+14+ns2) == '\t' ||
                                 *(p+3+ns+14+ns2) == '&' )) ns2++ ;
               if( *(p+3+ns+14+ns2) != '\n') printf("%s",(p+3+ns+14+ns2)) ;
               goto next_line ;
            } else {
               printf("%s",linei) ;
               goto next_line ;
            }
          } else if ( !strncmp ( surface_driver_str,   "surface_driver", 14 )  ||
                      !strncmp ( radiation_driver_str, "radiation_driver", 16) ||
                      !strncmp ( cumulus_driver_str,   "cumulus_driver", 14)   ||
                      !strncmp ( pbl_driver_str,       "pbl_driver", 10)
                    ) {
            strcpy(lineo,p+3+ns) ;
            inparen = 1 ;
            while ( fgets( linei, LINELEN, fp ) != NULL ) {
              for ( q = linei ; *q ; q++ ) {
                if (*q=='!') { *q = '\n' ; *(q+1) = '\0' ; break ; }
              }
              for ( q = linei ; *q ; q++ ) {
                if      ( *q == '(' ) inparen++ ;
                else if ( *q == ')' ) inparen-- ;
              }
              strcat(lineo,linei) ;
              if ( inparen == 0 ) {
                break ;
              }
            }
            for(q=lineo,r=lineo;*q;q++) {
              if (*q == '#' && *(q-1) == '\n') { /* CPP def. copy as is*/
                *r++ = '&' ;
                *r++ = '\n' ;
                for (; *q; q++) {
                   *r++ = *q; 
                   if ( *q == '\n' ) break ;
                }
              }
              if ( *q == ' ' || *q == '\n' || *q == '&' ) continue ;
              *r++ = *q ;
            }
            *r = '\0' ;
            printf("CALL ") ;
            for(q=lineo,col=130-5;*q;q++) {
              putchar(*q) ;
              if ( *q == '\n' ) { if (*(q+1) != '#') { putchar('&') ; } ; col = 131 ; }
              col-- ;
              if ( col <= 0 ) {
                col = 130 ;
                if (*q!=')' || *(q+1) ) {  putchar('&') ; putchar('\n') ; putchar('&') ; }
              }
            }
            putchar('\n') ;
            goto next_line ;
          } else {
            p += 3+ns ;
            *q++ = *p ;
          }
        } else {
          *q++ = *p ;
        }
      }
      *q='\0';
      printf("%s",lineo) ;
  next_line:
      state = 0 ;
    }
    fclose(fp) ;
    exit(0) ;
  }
  
  int
  drop_comment( char * linei )
  {
    char *p, *q ;
    char inquote = '\0' ;
  
    for ( p = linei ; *p ; p++ )
    {
      if ( *p == '\'' ) { if ( inquote == *p ) { inquote = '\0' ; } else { inquote = *p ; } }
      if ( *p == '"' )  { if ( inquote == *p ) { inquote = '\0' ; } else { inquote = *p ; } }
      if ( !inquote && *p == '!' ) { 
         /* let us make sure this is not an OMP directive shall we? */
         for ( q = p ; *q ; q++ ) {
           if ((*q == '$') && 
              (*(q+1) == 'o' || *(q+1) == 'O') &&
              (*(q+2) == 'm' || *(q+2) == 'M') &&
              (*(q+3) == 'p' || *(q+3) == 'P') )  return(0) ;
         /* nor an intel compiler directive, what? */
           if ((*(q+3) == '$') &&
              (*(q)   == 'd' || *(q)   == 'D') &&
              (*(q+1) == 'e' || *(q+1) == 'E') &&
              (*(q+2) == 'c' || *(q+2) == 'C') )  return(0) ;
         /* nor an intel compiler directive, just so. quite. */
           if ((*(q+3) == '$') &&
              (*(q)   == 'd' || *(q)   == 'D') &&
              (*(q+1) == 'i' || *(q+1) == 'I') &&
              (*(q+2) == 'r' || *(q+2) == 'R') )  return(0) ;
         /* nor a pgi accelerator directive */
           if ((*q == '$') &&
              (*(q+1) == 'a' || *(q+1) == 'A') &&
              (*(q+2) == 'c' || *(q+2) == 'C') &&
              (*(q+3) == 'c' || *(q+3) == 'C') )  return(0) ;
         /* nor a fujitsu compiler directive */
           if ((*(q+1) == 'o' || *(q+1) == 'O') &&
              (*(q+2) == 'c' || *(q+2) == 'C') &&
              (*(q+3) == 'l' || *(q+3) == 'L') )  return(0) ;
         }
         *p = '\n' ; *(p+1) = '\0' ; return(0) ; 
      }
    }
    return 0; /* SamT: bug fix: return a value */
  }
  
  int 
  change_to_lower( char * s , int n ) 
  {
    int i ;
    for ( i = 0 ; i < n ; i++ )
    {
      if ( s[i] >= 'A' && s[i] <= 'Z' ) s[i] = s[i] - 'A' + 'a' ;
    }
    return 0; /* SamT: bug fix: return a value */
  }
  
  