#include<stdio.h>                                      
#define BRACES                                         

#ifdef HTML /* FIXME: utnytt nesting av <span>...</span> */
const char grey[] = "<span style=\"color:grey;\">";        
const char grey_bg[] = "<span style=\"background-color:grey;\">";
const char red[] = "<span style=\"color:red;\">";                
const char green[] = "<span style=\"color:green;\">";            
const char blue[] = "<span style=\"color:blue;\">";              
const char pink[] = "<span style=\"color:pink;\">";              
const char purple[] = "<span style=\"color:purple;\">";          
const char cyan[] = "<span style=\"color:cyan;\">";              
const char nocolor[] = "</span>";                                
# ifdef BRACES                                                   
const char brown[] = "<span style=\"color:brown;\">";            
# endif                                                          

#else
const char grey[] = "\e[1;30m";
const char grey_bg[] = "\e[7;30m";
const char red[] = "\e[0;31m";    
const char green[] = "\e[0;32m";  
const char blue[] = "\e[1;34m";   
const char pink[] = "\e[1;35m";   
const char purple[] = "\e[0;35m"; 
const char cyan[] = "\e[0;36m";   
const char nocolor[] = "\e[0m";   
# ifdef BRACES                    
const char brown[] = "\e[0;33m";  
# endif                           
#endif /*HTML*/                   

void output(char c){
#ifdef HTML         
# define NUM 4      
        char lookup[NUM]={' ', '\n', '<', '>'};
        char *replace[NUM]={                   
                "&nbsp;", "<br/>\n", "&lt;", "&gt;"
        };                                         
        register int i = NUM-1;                    
        do{                                        
                i--;                               
                if(lookup[i] == c){                
                        printf("%s", replace[i]);  
                        return;                    
                }                                  
        }while(i);                                 
#endif                                             
        putchar(c);                                
}                                                  

void stateout(){
#ifdef HTML     
  printf("%s", nocolor);
#endif                  
}                       

/* Copyleft Andreas Nordal
 * all rights reversed    
 */                       

int main(int argc, char *argv[]){
  int i=1;                       
  while(i < argc){               
    FILE *straum = fopen(argv[i], "r");
    if(straum == NULL){                
      perror(argv[i]);                 
    }else{                             
      char A=0, B=0, C;                
      char modus=0;                    
#ifdef BRACES                          
      char togglebox=0x03;             
#endif                                 
#ifdef HTML                            
      puts("<code>");                  
#endif                                 
      while(fscanf(straum, "%c", &C) != EOF){
        if(modus){                           
          if(modus==1 && B=='"') modus=0;    
          else if(modus==2 && B=='\'') modus=0;
          else if(modus>=5 && modus<=6 && B=='\n') modus=0;
          else if(modus==7 && A=='*' && B=='/') modus=0;   
          if(!modus){                                      
            output(B);                                     
            printf("%s", nocolor);                         
            goto end_of_while;                             
          }else if(modus==11 && ((B>0 && B<'0') ||         
                  (B>'9' && B<'A') || (B>'Z' && B<'_') ||  
                  B>'z' || B=='`')){                       
            modus=0;                                       
            stateout();                                    
          }else if(modus==15 && A=='x'){                   
            modus=16;                                      
          }else if(modus==9 ||                             
          (modus==10 && ((B<'0' || B>'9') && B!='.')) ||   
          (modus==16 && (B<'0' || (B>'9' && B<'a') || B>'f'))
          || (modus==8 && (B<'0' || B>'7'))){                
            printf("%s", nocolor);                           
            modus=0;                                         
          }else if(modus==3){                                
            output(B);                                       
            stateout();                                      
            printf("%s", red);                               
            modus=1;                                         
            goto end_of_while;                               
          }else if(modus==5 && B=='/'){                      
            if(C=='/'){                                      
              stateout();                                    
              printf("%s", grey);                            
              modus=6;                                       
            }else if(C=='*'){                                
              stateout();                                    
              printf("%s", grey);                            
              modus=7;                                       
            }                                                
          }else if(modus==4){                                
            modus=2;                                         
            stateout();                                      
          }else if(B=='\\'){                                 
            if(modus==1){                                    
              stateout();                                    
              printf("%s", purple);                          
              modus=3;                                       
            }else if(modus==2){                              
              modus=4;                                       
              stateout();                                    
            }                                                
          }                                                  
#ifdef BRACES                                                
        }if(!modus){                                         
#else                                                        
        }else{                                               
#endif                                                       
          if((B>='a' && B<='z') || B=='_' ||                 
             (B>='A' && B<='Z') || B<0){                     
            modus=11;   //identifier mode                    
          }else if(B=='"'){                                  
            printf("%s", red);                               
            modus=1;                                         
          }else if(B=='\''){                                 
            printf("%s", pink);                              
            modus=2;                                         
          }else if((B>='0' && B<='9') || B=='.'){            
            if(B=='0' && (C>='0' && C<='9')){                
            printf("%s", cyan);                              
              modus=8;                                       
            }else if(B=='0' && (C=='x' || C=='X')){          
                printf("%s", cyan);                          
              modus=15;                                      
            }else{                                           
              if((B!='.' || (C>='0' && C<='9'))){            
                printf("%s", blue);                          
              }                                              
              modus=10;                                      
            }                                                
          }                                                  
#ifdef BRACES                                                
          else if(B=='{' || B=='}' || B=='(' || B==')'){     
            if(B=='{'){                                      
              if(togglebox & 0x01) printf("%s", green);      
              togglebox ^= 0x01;                             
            }else if(B=='}'){                                
              togglebox ^= 0x01;                             
              if(togglebox & 0x01) printf("%s", green);      
            }else if(B=='('){                                
              if(togglebox & 0x02) printf("%s", brown);      
              togglebox ^= 0x02;                             
            }else if(B==')'){
              togglebox ^= 0x02;
              if(togglebox & 0x02) printf("%s", brown);
            }
            output(B);
            printf("%s", nocolor);
            goto end_of_while;
          }
#endif
          else if(B=='#'){
            printf("%s", green);
            modus=5;
          }else if(B=='/' && C=='/'){
            printf("%s", grey); //grey this
            modus=6;
          }else if(B=='/' && C=='*'){
            printf("%s", grey); /*grey this*/
            modus=7;
          }else if(C=='\n' && (B==' ' || B=='\t')){
            printf("%s", grey_bg); //grey whitespace at end of line^
            modus=9;
          }
        }
        if(B) output(B);
        end_of_while:
        A = B;
        B = C;
      }
      fclose(straum);
      putchar(C);
      if(modus) printf("%s", nocolor);
      if(C!='\n') putchar('\n');
#ifdef HTML
      puts("</code>");
#endif
    }
    i++;
  }
  return 0;
}


