#ifndef WONKY_STREAM_C
#define WONKY_STREAM_C WONKY_STREAM_C
#include <wonky_stream.h>
ssize_t wonky_read(struct wonky_stream *s,void *dst,size_t num_bytes)
{
return s->read(s->state,dst,num_bytes);
}
ssize_t wonky_write(struct wonky_stream *s,void *src,size_t num_bytes)
{
return s->write(s->state,src,num_bytes);
}
ssize_t wonky_fseek(struct wonky_stream *s,size_t where,int whence)
{
return s->fseek(s->state,where,whence);
}
ssize_t wonky_eof(struct wonky_stream *s)
{
return s->eof(s->state);
}
#warning not clear what wonky_printf format is
/*
%WE pointer to struct Wonky_Error
*/
int wonky_printf(const char *format,...)
{
va_list args;
int ret;
struct wonky_stream s=wonky_stream_from_file(stdout);
va_start(args,format);
ret=wonky_vfprintf(&s,format,args);
va_end(args);
fflush(stdout);
return ret;
}
int wonky_vprintf(const char *format,va_list args)
{
struct wonky_stream s=wonky_stream_from_file(stdout);
return wonky_vfprintf(&s,format,args);
}
int wonky_fprintf(struct wonky_stream *s,const char *format,...)
{
va_list args;
int ret;
va_start(args,format);
ret=wonky_vfprintf(s,format,args);
va_end(args);
return ret;
}
int wonky_vfprintf(struct wonky_stream *s,const char *format,va_list args)
{
if(format==NULL || s==NULL)
return 0;
struct wonky__scanformat fmt;
short indentation=0;
for(size_t i=0;format[i]!='\0';)
{
if(format[i]=='%')
{
wonky__parse_scan_format(format+i,&fmt);
wonky__from_scanformat(&fmt,args,s,&indentation);
i+=fmt.forward_crawl;
}else
{
wonky_write(s,(void*)format+i,1);
++i;
}
}
}
ssize_t wonky_stream_int_to_decimal(struct wonky_stream *s,intmax_t a)
{
char hold[2]={0,0};
ssize_t ret=0;
ssize_t hret;
intmax_t d;
if(a==0)
return wonky_write(s,"0",1);
else if(a<0)
{
ret=wonky_write(s,"-",1);
a=-a;
}
for(d=1;d*10<=a;d*=10);
for(d;d>0;d/=10)
{
hold[0]=a/d+'0';
hret=wonky_write(s,hold,1);
if(hret<0)
return -ret;
else
ret+=hret;
a=a%d;
}
return ret;
}
ssize_t wonky_stream_uint_to_decimal(struct wonky_stream *s,uintmax_t a)
{
char hold[2]={0,0};
ssize_t ret=0;
ssize_t hret;
uintmax_t d;
if(a==0)
return wonky_write(s,"0",1);
for(d=1;d*10<=a;d*=10);
for(d;d>0;d/=10)
{
hold[0]=a/d+'0';
hret=wonky_write(s,hold,1);
if(hret<0)
return -ret;
else
ret+=hret;
a=a%d;
}
return ret;
}
ssize_t wonky_stream_uint_to_hexadecimal(struct wonky_stream *s,uintmax_t a)
{
char hold[2]={0,0};
ssize_t ret=0;
ssize_t hret;
uintmax_t d;
if(a==0)
return wonky_write(s,"0",1);
for(d=1;d*16<=a;d*=16);
for(d;d>0;d/=16)
{
if(a/d<10)
hold[0]=a/d+'0';
else
hold[0]=a/d-10+'A';
hret=wonky_write(s,hold,1);
if(hret<0)
return -ret;
else
ret+=hret;
a=a%d;
}
return ret;
}
ssize_t wonky_stream_uint_to_octal(struct wonky_stream *s,uintmax_t a)
{
char hold[2]={0,0};
ssize_t ret=0;
ssize_t hret;
uintmax_t d;
if(a==0)
return wonky_write(s,"0",1);
for(d=1;d*8<=a;d*=8);
for(d;d>0;d/=8)
{
hold[0]=a/d+'0';
hret=wonky_write(s,hold,1);
if(hret<0)
return -ret;
else
ret+=hret;
a=a%d;
}
return ret;
}
ssize_t wonky_stream_double_to_decimal(struct wonky_stream *s,double d)
{
int32_t exponent;
uint64_t mantissa;
ssize_t ret=0;
ssize_t hret;
exponent=wonky__double_get_exponent(d)-1023;
mantissa=wonky__double_get_mantissa(d)|0x0010000000000000;
for(mantissa;(mantissa&1)==0;mantissa>>=1,++exponent);
exponent-=52;
if(wonky__double_is_negative(d))
{
hret=wonky_write(s,"-",1);
if(hret<0)
return hret;
else
ret+=hret;
}
if(exponent<0)
{
if(-exponent<64)
{
hret=wonky_stream_from_fraction(s,mantissa,(uint64_t)1<<-exponent,10);
if(hret<0)
return hret;
}else
{
hret=wonky_stream_uint_to_decimal(s,mantissa);
if(hret<0)
return hret;
else
ret+=hret;
hret=wonky_write(s,"e",1);
if(hret<0)
return -ret;
else
ret+=hret;
hret=wonky_stream_int_to_decimal(s,exponent);
if(hret<0)
return -ret;
else
ret+=hret;
}
}else
{
hret=wonky_stream_uint_to_decimal(s,mantissa);
if(hret<0)
return hret;
else
ret+=hret;
hret=wonky_write(s,"e",1);
if(hret<0)
return -ret;
else
ret+=hret;
hret=wonky_stream_int_to_decimal(s,exponent);
if(hret<0)
return -ret;
else
ret+=hret;
}
return ret;
}
ssize_t wonky_stream_from_fraction(struct wonky_stream *s,uint64_t a,uint64_t b,int precision)
{
char hold[2]={0,0};
ssize_t ret=0;
ssize_t hret;
if(a==0)
{
return wonky_write(s,"0",1);
}else
{
hret=wonky_stream_int_to_decimal(s,a/b);
if(hret<0)
return hret;
else
ret+=hret;
hret=wonky_write(s,".",1);
if(hret<0)
return -ret;
else
ret+=hret;
a=a%b*10;
--precision;
while(precision>=0 && a!=0)
{
hold[0]=a/b+'0';
hret=wonky_write(s,hold,1);
a=(a%b)*10;
--precision;
}
}
return ret;
}
void wonky__from_scanformat(struct wonky__scanformat *fmt,va_list args,struct wonky_stream *s,short *indentation)
{
switch(fmt->conversion)
{
case WONKY__CONVERSION_PERCENT:
wonky_write(s,"%",1);
break;
case WONKY__CONVERSION_INT_DECIMAL:
{
switch(fmt->modifier)
{
case WONKY__MOD_LONG:
wonky_stream_int_to_decimal(s,va_arg(args,long int));
break;
case WONKY__MOD_LONG_LONG:
wonky_stream_int_to_decimal(s,va_arg(args,long long int));
break;
case WONKY__MOD_INTMAX:
wonky_stream_int_to_decimal(s,va_arg(args,intmax_t));
break;
case WONKY__MOD_SIZE_T:
wonky_stream_int_to_decimal(s,va_arg(args,ssize_t));
break;
case WONKY__MOD_PTRDIFF:
wonky_stream_int_to_decimal(s,va_arg(args,ptrdiff_t));
break;
default:
wonky_stream_int_to_decimal(s,va_arg(args,int));
break;
}
}
break;
case WONKY__CONVERSION_INT_OCTAL:
{
switch(fmt->modifier)
{
case WONKY__MOD_LONG:
wonky_stream_uint_to_octal(s,va_arg(args,long unsigned int));
break;
case WONKY__MOD_LONG_LONG:
wonky_stream_uint_to_octal(s,va_arg(args,long long unsigned int));
break;
case WONKY__MOD_INTMAX:
wonky_stream_uint_to_octal(s,va_arg(args,uintmax_t));
break;
case WONKY__MOD_SIZE_T:
wonky_stream_uint_to_octal(s,va_arg(args,size_t));
break;
case WONKY__MOD_PTRDIFF:
wonky_stream_uint_to_octal(s,va_arg(args,ptrdiff_t));
break;
default:
wonky_stream_uint_to_octal(s,va_arg(args,unsigned int));
break;
}
}
break;
case WONKY__CONVERSION_POINTER:
case WONKY__CONVERSION_INT_HEXADECIMAL:
{
switch(fmt->modifier)
{
case WONKY__MOD_LONG:
wonky_stream_uint_to_hexadecimal(s,va_arg(args,long unsigned int));
break;
case WONKY__MOD_LONG_LONG:
wonky_stream_uint_to_hexadecimal(s,va_arg(args,long long unsigned int));
break;
case WONKY__MOD_INTMAX:
wonky_stream_uint_to_hexadecimal(s,va_arg(args,uintmax_t));
break;
case WONKY__MOD_SIZE_T:
wonky_stream_uint_to_hexadecimal(s,va_arg(args,size_t));
break;
case WONKY__MOD_PTRDIFF:
wonky_stream_uint_to_hexadecimal(s,va_arg(args,ptrdiff_t));
break;
default:
wonky_stream_uint_to_hexadecimal(s,va_arg(args,unsigned int));
break;
}
}
break;
case WONKY__CONVERSION_INT_UNSIGNED_DECIMAL:
{
switch(fmt->modifier)
{
case WONKY__MOD_LONG:
wonky_stream_uint_to_decimal(s,va_arg(args,long unsigned int));
break;
case WONKY__MOD_LONG_LONG:
wonky_stream_uint_to_decimal(s,va_arg(args,long long unsigned int));
break;
case WONKY__MOD_INTMAX:
wonky_stream_uint_to_decimal(s,va_arg(args,uintmax_t));
break;
case WONKY__MOD_SIZE_T:
wonky_stream_uint_to_decimal(s,va_arg(args,size_t));
break;
case WONKY__MOD_PTRDIFF:
wonky_stream_uint_to_decimal(s,va_arg(args,ptrdiff_t));
break;
default:
wonky_stream_uint_to_decimal(s,va_arg(args,unsigned int));
break;
}
}
break;
case WONKY__CONVERSION_CHAR:
{
char a=va_arg(args,int);
wonky_write(s,&a,1);
}
break;
case WONKY__CONVERSION_DOUBLE_DECIMAL:
{
switch(fmt->modifier)
{
case WONKY__MOD_LONG:
case WONKY__MOD_LONG_LONG:
wonky_stream_double_to_decimal(s,va_arg(args,long double));
break;
default:
wonky_stream_double_to_decimal(s,va_arg(args,double));
break;
}
}
break;
case WONKY__CONVERSION_CSTRING:
{
char *st=va_arg(args,char*);
if(st==NULL)
{
wonky_write(s,"(null)",sizeof("(null)")-1);
}else
{
size_t l=gstrlen(st);
wonky_write(s,st,l);
}
}
break;
case WONKY__CONVERSION_WONKY_ERROR:
{
print_message(s,va_arg(args,struct Wonky_Message*));
}
break;
case WONKY__CONVERSION_WONKY_TOKEN:
{
print_token(s,va_arg(args,struct token*));
}
break;
case WONKY__CONVERSION_WONKY_INDENTATION:
*indentation=va_arg(args,int);
break;
case WONKY__CONVERSION_WONKY_AST:
print_ast(s,va_arg(args,struct AST*),*indentation);
break;
case WONKY__CONVERSION_WONKY_AST_ENUM:
print_ast_enum(s,va_arg(args,enum AST_Type));
break;
case WONKY__CONVERSION_WONKY_ID:
print_id(s,va_arg(args,struct identifier*));
break;
case WONKY__CONVERSION_WONKY_DENOTED:
print_denoted(s,va_arg(args,struct Denoted*));
break;
case WONKY__CONVERSION_WONKY_TYPE:
print_type(s,va_arg(args,struct Type*),1);
break;
case WONKY__CONVERSION_WONKY_OBJECT:
print_object(s,va_arg(args,struct Object*));
break;
case WONKY__CONVERSION_WONKY_CONSTANT:
print_constant(s,va_arg(args,struct Constant*));
break;
case WONKY__CONVERSION_WONKY_SOURCE_NAME:
{
struct Source_Name *sn=va_arg(args,struct Source_Name*);
wonky_write(s,sn->name,sn->name_size);
}
break;
case WONKY__CONVERSION_WONKY_INCLUSION_CHAIN:
{
struct Token_Pointer *tp=va_arg(args,struct Token_Pointer*);
struct Token_Pointer_Context *hold;
_Bool print_line=0;
wonky_assert(tp!=NULL);
if(tp->call_stack->size>2)
{
wonky_write(s,"\n",1);
for(struct Stack_Node *it=tp->call_stack->first;it;it=it->next)
{
hold=(struct Token_Pointer_Context*)it->data;
wonky_assert(hold);
if(hold->is_file_inclusion)
{
if(print_line)
wonky_write(s,"\n",1);
wonky_write(s,"\tIncluded in ",sizeof("\tIncluded in ")-1);
wonky_write(s,hold->filename,hold->filename_size);
wonky_fprintf(s,":%zu",hold->line+1);
print_line=1;
}
}
}
}
break;
case WONKY__CONVERSION_WONKY_TOKEN_POINTER_CALL_STACK:
{
struct Token_Pointer *tp=va_arg(args,struct Token_Pointer*);
_Bool print_line=0;
wonky_assert(tp);
wonky_fprintf(s,"%WPc\n",tp->context);
for(struct Stack_Node *it=tp->call_stack->first;it;it=it->next)
wonky_fprintf(s,"%WPc\n",it->data);
}
break;
case WONKY__CONVERSION_WONKY_TOKEN_POINTER_CONTEXT:
{
struct Token_Pointer_Context *hold=va_arg(args,struct Token_Pointer_Context*);
wonky_assert(hold);
wonky_fprintf(s,"ctx=%p",hold);
if(hold->current_token_node)
{
wonky_assert(hold->current_token_node->data!=NULL);
wonky_fprintf(s,": {\n\tcurrent_token_node = %Wt",hold->current_token_node->data);
}else
{
wonky_fprintf(s,": {\n\tcurrent_token_node = NULL");
}
wonky_fprintf(s,"\n\tnum_remain_toks = %zu\n\tline = %zu\n\tcolumn = %zu\n\tbarier=%d\n\tfilename = \"",hold->number_of_remaining_tokens,hold->line,hold->column,hold->barrier);
wonky_write(s,hold->filename,hold->filename_size);
wonky_write(s,"\"",sizeof("\"")-1);
if(hold->executed_macro_id)
{
wonky_write(s,"\n\tmacro_id = \"",sizeof(" macro_id = \"")-1);
wonky_write(s,hold->executed_macro_id->data,hold->executed_macro_id->size);
wonky_write(s,"\"",sizeof("\"")-1);
}
if(hold->has_saved_functionlike_macro_state)
{
wonky_write(s,"\n\tmacro_state : \n\t{",sizeof("\n\tmacro_state : \n\t{")-1);
for(struct Queue_Node *it=hold->functionlike_macro_arguments_save_state->first;it;it=it->prev)
wonky_fprintf(s,"\n\t\t%WMA",it->data);
wonky_write(s,"\n\t}",sizeof("\n\t}")-1);
}
wonky_write(s,"\n}\n",sizeof("\n}\n")-1);
}
break;
case WONKY__CONVERSION_WONKY_MACRO_ARGUMENT:
{
struct functionlike_define_directive_argument *arg=va_arg(args,struct functionlike_define_directive_argument*);
wonky_fprintf(s,"first_in_argument_substitution_tokens=%p number_of_substitution_tokens=%zu",arg->first_in_argument_substitution_tokens,arg->number_of_substitution_tokens);
}
break;
case WONKY__CONVERSION_WONKY_FUNCTIONLIKE_MACRO:
{
struct functionlike_define_directive *arg=va_arg(args,struct functionlike_define_directive*);
wonky_assert(arg);
wonky_fprintf(s,"\n\"%WI\" : {\n\tis_variadic=%d",arg->id,(int)arg->is_variadic);
for(struct Queue_Node *it=arg->arguments->first;it;it=it->prev)
wonky_fprintf(s,"\n\t%WMA",it->data);
wonky_fprintf(s,"\n}\n");
}
break;
case WONKY__CONVERSION_WONKY_TOKEN_LINE:
{
struct token *token=va_arg(args,struct token*);
size_t begining_of_real_line=token->delta->location->starting_byte_index;
size_t ending_of_real_line=token->delta->location->starting_byte_index;
for(begining_of_real_line ;begining_of_real_line && token->delta->location->src->src[begining_of_real_line]!='\n' ;--begining_of_real_line);
for(ending_of_real_line ;ending_of_real_line<token->delta->location->src->src_size && token->delta->location->src->src[ending_of_real_line]!='\n' ;++ending_of_real_line);
begining_of_real_line+=!!(begining_of_real_line);
wonky_assert(begining_of_real_line<ending_of_real_line);
wonky_write(s,token->delta->location->src->src+begining_of_real_line,ending_of_real_line-begining_of_real_line);
}
break;
case WONKY__CONVERSION_WONKY_SOURCE_LOCATION:
{
struct Source_Location *loc=va_arg(args,struct Source_Location*);
wonky_write(s,"[ ",2);
if(loc->src->src_name)
wonky_write(s,loc->src->src_name->name,loc->src->src_name->name_size);
else
wonky_write(s,"null",sizeof("null")-1);
wonky_fprintf(s," %zu:%zu]",loc->line+1,loc->column);
}
break;
case WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT:
{
struct token *token=va_arg(args,struct token*);
print_raw_token_text(s,token);
}
break;
}
}
ssize_t wonky__FILE_read(void *state,void *dst,size_t num_bytes)
{
return fread(dst,1,num_bytes,(FILE*)state);
}
ssize_t wonky__FILE_write(void *state,void *src,size_t num_bytes)
{
return fwrite(src,1,num_bytes,(FILE*)state);
}
_Bool wonky__FILE_fseek(void *state,size_t where,int whence)
{
return !fseek((FILE*)state,where,whence);
}
_Bool wonky__FILE_eof(void *state)
{
return feof((FILE*)state);
}
ssize_t wonky__fail_read(void *state,void *dst,size_t num_bytes)
{
return -1;
}
ssize_t wonky__fail_write(void *state,void *src,size_t num_bytes)
{
return -1;
}
_Bool wonky__fail_fseek(void *state,size_t where,int whence)
{
return 0;
}
_Bool wonky__fail_eof(void *state)
{
return 0;
}
struct wonky_stream wonky_stream_from_file(FILE *f)
{
return (struct wonky_stream) {
.read=wonky__FILE_read,
.write=wonky__FILE_write,
.fseek=wonky__FILE_fseek,
.eof=wonky__FILE_eof,
.type=WONKY_STREAM_TYPE_FILE,
.state=f
};
}
void wonky_stream_delete(struct wonky_stream *s)
{
switch(s->type)
{
case WONKY_STREAM_TYPE_STRING:
wonky_string_stream_delete(s);
break;
#warning add FILE stream deletion code here :>
}
}
/*
%WE - message
%Wt - token
%Wi - indentation (short)
%WI - id
%Wd - denoted
%WA - ast
%WT - type
%WAE - ast enum
%Wo - object
%WC - constant
%WS - source name
%WSl - source location
%WIC - inclusion chain (takes Token_Pointer )
%WPC - token pointer context call stack ( takes Token_Pointer *)
%WPc - token pointer context ( takes Token_Pointer_Context *)
%WMA - macro argument
%WMf - functionlike macro
%Wtl - print line containing token ( takes token*)
%Wtr - print raw token text ( takes token *)
*/
void wonky__parse_scan_format(const char *begining, struct wonky__scanformat *destination)
{
destination->forward_crawl=1;
destination->modifier=WONKY__MOD_END;
destination->conversion=WONKY__CONVERSION_END;
destination->alternate_form=0;
if(begining[destination->forward_crawl]=='W')
{
destination->wonky_form=1;
++destination->forward_crawl;
}else
{
destination->wonky_form=0;
}
switch(begining[destination->forward_crawl])
{
case 'h':
++destination->forward_crawl;
if(begining[destination->forward_crawl]=='h')
{
++destination->forward_crawl;
destination->modifier=WONKY__MOD_SHORT_SHORT;
}else
{
destination->modifier=WONKY__MOD_SHORT;
}
break;
case 'l':
++destination->forward_crawl;
if(begining[destination->forward_crawl]=='l')
{
++destination->forward_crawl;
destination->modifier=WONKY__MOD_LONG_LONG;
}else
{
destination->modifier=WONKY__MOD_LONG;
}
break;
case 'L':
++destination->forward_crawl;
destination->modifier=WONKY__MOD_LONG_DOUBLE;
break;
case 'j':
++destination->forward_crawl;
destination->modifier=WONKY__MOD_INTMAX;
break;
case 'z':
++destination->forward_crawl;
destination->modifier=WONKY__MOD_SIZE_T;
break;
case 't':
++destination->forward_crawl;
if(destination->wonky_form)
{
if(begining[destination->forward_crawl]=='l')
{
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_LINE;
} else if(begining[destination->forward_crawl]=='r')
{
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT;
} else
{
destination->conversion=WONKY__CONVERSION_WONKY_TOKEN;
}
/*WARNING EARLY RETURN*/
return;
}else
{
destination->modifier=WONKY__MOD_PTRDIFF;
}
break;
}
switch(begining[destination->forward_crawl])
{
case 'd':
++destination->forward_crawl;
if(destination->wonky_form)
destination->conversion=WONKY__CONVERSION_WONKY_DENOTED;
else
destination->conversion=WONKY__CONVERSION_INT_DECIMAL;
break;
case 'i':
++destination->forward_crawl;
if(destination->wonky_form)
destination->conversion=WONKY__CONVERSION_WONKY_INDENTATION;
else
destination->conversion=WONKY__CONVERSION_INT_DECIMAL;
break;
case 'I':
++destination->forward_crawl;
if(destination->wonky_form)
{
if(begining[destination->forward_crawl]=='C')
{
destination->conversion=WONKY__CONVERSION_WONKY_INCLUSION_CHAIN;
++destination->forward_crawl;
}else
{
destination->conversion=WONKY__CONVERSION_WONKY_ID;
}
}
break;
case 'o':
++destination->forward_crawl;
if(destination->wonky_form)
destination->conversion=WONKY__CONVERSION_WONKY_OBJECT;
else
destination->conversion=WONKY__CONVERSION_INT_OCTAL;
break;
case 'u':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_INT_UNSIGNED_DECIMAL;
break;
case 'x':
case 'X':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_INT_HEXADECIMAL;
break;
case 'e':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_DOUBLE_EXPONENT;
break;
case 'E':
++destination->forward_crawl;
if(destination->wonky_form)
{
destination->conversion=WONKY__CONVERSION_WONKY_ERROR;
}else
{
destination->conversion=WONKY__CONVERSION_DOUBLE_EXPONENT;
}
break;
case 'f':
case 'F':
case 'g':
case 'G':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_DOUBLE_DECIMAL;
break;
case 'a':
case 'A':
++destination->forward_crawl;
if(destination->wonky_form)
{
if(begining[destination->forward_crawl]=='E')
{
destination->conversion=WONKY__CONVERSION_WONKY_AST_ENUM;
++destination->forward_crawl;
}else
{
destination->conversion=WONKY__CONVERSION_WONKY_AST;
}
}else
{
destination->conversion=WONKY__CONVERSION_DOUBLE_HEXADECIMAL;
}
break;
case 'c':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_CHAR;
break;
case 's':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_CSTRING;
break;
case 'p':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_POINTER;
break;
case '%':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_PERCENT;
break;
case 'b':
++destination->forward_crawl;
destination->conversion=WONKY__CONVERSION_BITS;
break;
case 'T':
++destination->forward_crawl;
if(destination->wonky_form)
destination->conversion=WONKY__CONVERSION_WONKY_TYPE;
break;
case 'C':
++destination->forward_crawl;
if(destination->wonky_form)
destination->conversion=WONKY__CONVERSION_WONKY_CONSTANT;
break;
case 'S':
++destination->forward_crawl;
if(destination->wonky_form)
{
if(begining[destination->forward_crawl]=='l')
{
destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_LOCATION;
++destination->forward_crawl;
}else
{
destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_NAME;
}
}
break;
case 'P':
++destination->forward_crawl;
if(destination->wonky_form && begining[destination->forward_crawl]=='C')
{
destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_POINTER_CALL_STACK;
++destination->forward_crawl;
} else if(destination->wonky_form && begining[destination->forward_crawl]=='c')
{
destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_POINTER_CONTEXT;
++destination->forward_crawl;
}
break;
case 'M':
++destination->forward_crawl;
if(destination->wonky_form && begining[destination->forward_crawl]=='A')
{
destination->conversion=WONKY__CONVERSION_WONKY_MACRO_ARGUMENT;
++destination->forward_crawl;
} else if(destination->wonky_form && begining[destination->forward_crawl]=='f')
{
destination->conversion=WONKY__CONVERSION_WONKY_FUNCTIONLIKE_MACRO;
++destination->forward_crawl;
}
break;
}
}
/*uint32_t takes care of endianness*/
_Bool wonky__float_is_negative(float f)
{
return (*((uint32_t*)(void*)&f))&0x80000000u;
}
int16_t wonky__float_get_exponent(float f)
{
return (((*((uint32_t*)(void*)&f))&0x7F800000u)>>23);
}
uint32_t wonky__float_get_mantissa(float f)
{
return (*((uint32_t*)(void*)&f))&0x007FFFFFu;
}
float wonky__float_set_sign(float f,_Bool is_negative)
{
uint32_t *as_uint=(void*)&f;
if(is_negative)
*as_uint=((*as_uint)|0x80000000u);
else
*as_uint=((*as_uint)&0x7FFFFFFFu);
return *(float*)(void*)as_uint;
}
float wonky__float_set_exponent(float f,int16_t exponent)
{
uint32_t *as_uint=(void*)&f;
*as_uint=((*as_uint)&0x807FFFFFu)|((0xFu&(uint32_t)(exponent+0x7F))<<23);
return *(float*)(void*)as_uint;
}
float wonky__float_set_base(float f,uint32_t base)
{
uint32_t *as_uint=(void*)&f;
*as_uint=((*as_uint)&0xFF800000u)|((0x007FFFFFu)&base);
return *(float*)(void*)as_uint;
}
/*uint64_t takes care of endianness*/
_Bool wonky__double_is_negative(double d)
{
return (*((uint64_t*)(void*)&d))&0x8000000000000000ull;
}
int16_t wonky__double_get_exponent(double d)
{
return ((*((uint64_t*)(void*)&d))&0x7FF0000000000000ull)>>52;
}
uint64_t wonky__double_get_mantissa(double d)
{
return (*((uint64_t*)(void*)&d))&0x000FFFFFFFFFFFFFull;
}
double wonky__double_set_sign(double d,_Bool is_negative)
{
uint64_t *as_uint=(void*)&d;
if(is_negative)
*as_uint=((*as_uint)|0x8000000000000000ull);
else
*as_uint=((*as_uint)&0x7FFFFFFFFFFFFFFFull);
return *(double*)(void*)as_uint;
}
double wonky__double_set_exponent(double d,int16_t exponent)
{
uint64_t *as_uint=(void*)&d;
*as_uint=((*as_uint)&0x800FFFFFFFFFFFFFull)|((0x7Fu&(uint64_t)exponent)<<52);
return *(double*)(void*)as_uint;
}
double wonky__double_set_mantissa(double d,uint64_t mantissa)
{
uint64_t *as_uint=(void*)&d;
*as_uint=((*as_uint)&0xFFF0000000000000ull)|((0x000FFFFFFFFFFFFFull)&mantissa);
return *(double*)(void*)as_uint;
}
#endif