Skip to content

Instantly share code, notes, and snippets.

@lindenb
Created September 9, 2011 20:31
Customizing C printf to print a fasta sequence
/**
* Author:
* Pierre Lindenbaum PhD
* Contact:
* plindenbaum@yahoo.fr
* Date:
* 2011-09-09
* WWW:
* http://plindenbaum.blogspot.com
* Reference:
* http://www.gnu.org/s/hello/manual/libc/Customizing-Printf.html
* Motivation:
* Customizing printf to print a fasta sequence
* Usage:
* g++ -Wall source.c
* ./a.out < file.fasta
*/
#include <stdio.h>
#include <stdlib.h>
#include <printf.h>
#include <ctype.h>
typedef struct fasta_t
{
char* name;
char* sequence;
}Fasta;
#define FPUTC(C) ret+=(fputc(C,stream)==EOF?0:1)
/** handler for printf called by register_printf_function */
static int printf_fasta_handler(
FILE *stream, /* stream output */
const struct printf_info *info, /* information about the various options */
const void *const *args /* arguments */
)
{
int n=0;
int ret=0;
char* p;
/* return the number of character writtern */
int lline =(info->prec<1?60:info->prec);
const Fasta* fasta=*((const Fasta**)(args[0]));
if(fasta->name!=NULL)
{
FPUTC('>');
ret+=fputs(fasta->name,stream);
}
else
{
FPUTC('>');
}
if(fasta->sequence!=NULL)
{
p=(char*)fasta->sequence;
while(p[n]!=0 && (info->width<1 || n< info->width))
{
if(n%lline==0)
{
FPUTC('\n');
}
FPUTC(p[n]);
++n;
}
}
FPUTC('\n');
return ret;
}
static int printf_fasta_arginfo(
const struct printf_info *info,
size_t n,
int *argtypes,
int *size)
{
/* We always take exactly one argument and this is a pointer to the
structure.. */
if (n > 0) argtypes[0] = PA_POINTER;
return 1;
}
#define APPEND(ptr,len,c) {ptr=realloc(ptr,sizeof(char)*((len)+2));\
if(ptr==NULL)\
{\
fputs("Out of memory\n",stderr);\
exit(EXIT_FAILURE);\
}\
ptr[(len)]=c;\
ptr[(len)+1]=0;\
len++;\
}
int main(int argc,char** argv)
{
size_t len_name=0;
size_t len_seq=0;
Fasta record;
int c;
/* register a new output conversion */
if(register_printf_specifier('W',
/* handler function */
printf_fasta_handler,
/* arginfo function */
printf_fasta_arginfo
)!=0)
{
fputs("Cannot register print function",stderr);
return EXIT_FAILURE;
}
record.name=NULL;
record.sequence=NULL;
for(;;)
{
c=fgetc(stdin);
if(c==EOF || c=='>')
{
if(len_seq>0)
{
printf("%80W\n",&record);
printf("%200.90W\n",&record);
printf("%200W\n",&record);
printf("%.80W\n",&record);
}
if(c==EOF) break;
len_seq=0;
len_name=0;
while((c=fgetc(stdin))!=EOF && c!='\n')
{
APPEND(record.name,len_name,c);
}
}
else if(!isspace(c))
{
APPEND(record.sequence,len_seq,c);
}
}
free(record.name);
free(record.sequence);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment