Skip to content

Instantly share code, notes, and snippets.

@v6ak
Created March 13, 2010 15:39
Show Gist options
  • Save v6ak/331375 to your computer and use it in GitHub Desktop.
Save v6ak/331375 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
typedef int boolean;
///////////// abstract CharProcessor ///////////////////////////////////
typedef struct _CP{ // abstract
/*public abstract*/ struct _CP* (*nextFunction) (struct _CP *this, char c, FILE *out);
/*public virtual*/ void (*destroyFunction) (struct _CP *this);
/*private field*/ boolean canBeFinal;
/*data*/ void *data;
} CharProcessor;
void CharProcessor_free(CharProcessor *this){
void (*destroyFunction) (struct _CP *this) = this->destroyFunction;
if(destroyFunction){
destroyFunction(this);
}
free(this);
}
CharProcessor *CharProcessor_next(CharProcessor *this, char c, FILE *out){
return this->nextFunction(this, c, out);
}
boolean CharProcessor_canBeFinal(CharProcessor *this){
return this->canBeFinal;
}
CharProcessor *newCharProcessor(struct _CP* (*nextFunction) (struct _CP *this, char c, FILE *out), boolean canBeFinal){
CharProcessor *this = malloc(sizeof(CharProcessor));
this->nextFunction = nextFunction;
this->canBeFinal = canBeFinal;
this->destroyFunction = NULL;
return this;
}
////////// final InitialCharProcessor //////////////////////////////////
typedef struct{
boolean lastIsWhite;
} InitialCharProcessor_ext;
CharProcessor *newStringCharProcessor();
CharProcessor *newCommentCharProcessor();
CharProcessor *InitialCharProcessor_next(CharProcessor* this, char c, FILE *out){
InitialCharProcessor_ext *data = this->data;
boolean newLastIsWhite = 0;
boolean copy = 0;
CharProcessor *nextCharProcessor = this;
switch(c){
case ' ':
case '\t':
case '\n':
newLastIsWhite = 1;
if(!data->lastIsWhite){
fputc(' ', out);
}
break;
case '"':
copy = 1;
nextCharProcessor = newStringCharProcessor();
break;
case '{':
nextCharProcessor = newCommentCharProcessor();
fputc(' ', out);
break;
default: // nothing interresting
copy = 1;
}
if(copy){
fputc(c, out);
}
data->lastIsWhite = newLastIsWhite;
if(nextCharProcessor != this){
CharProcessor_free(this);
}
return nextCharProcessor;
}
void InitialCharProcessor_destroy(CharProcessor *this){
free(this->data);
}
CharProcessor *newInitialCharProcessor(){
CharProcessor *this = newCharProcessor(InitialCharProcessor_next, 1);
InitialCharProcessor_ext *data = malloc(sizeof(InitialCharProcessor_ext));
data->lastIsWhite = 0;
this->data = data;
this->destroyFunction = InitialCharProcessor_destroy;
return this;
}
//////////// final StringCharProcessor /////////////////////////////////
CharProcessor *StringCharProcessor_next(CharProcessor *this, char c, FILE *out){
fputc(c, out);
if(c == '"'){
CharProcessor_free(this);
return newInitialCharProcessor();
}else{
return this;
}
}
CharProcessor *newStringCharProcessor(){
return newCharProcessor(StringCharProcessor_next, 0);
}
/////////// final CommentCharProcessor /////////////////////////////////
CharProcessor *CommentCharProcessor_next(CharProcessor *this, char c, FILE *out){
if(c == '}'){
CharProcessor_free(this);
return newInitialCharProcessor();
}else{
return this;
}
}
CharProcessor *newCommentCharProcessor(){
return newCharProcessor(CommentCharProcessor_next, 0);
}
////////////////// <main> //////////////////////////////////////////////
int main(void){
FILE *in = stdin;
FILE *out = stdout;
CharProcessor *processor = newInitialCharProcessor();
int c;
while( EOF != (c=fgetc(in)) ){
processor = CharProcessor_next(processor, c, out);
}
if(!CharProcessor_canBeFinal(processor)){
printf("Toto nemuze byt konec!\n");
}
CharProcessor_free(processor);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment