#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <libgen.h> #include <sys/param.h> #define FIELDS 23 /* dimensions: inter_p, qindex, plane, mode[4], bsize, txsize */ typedef struct { char *name; int ext; int pos; int posval; } argument; static argument arguments[] = { { "inter", 0, 0, 1}, { "intra", 0, 0, 0}, { "frametype", 2, 0, -1}, { "Y", 0, 1, 0}, { "U", 0, 1, 1}, { "V", 0, 1, 2}, { "plane", 3, 1, -1}, { "qi", 0, 2, -1}, { "dcq", 0, 3, -1}, { "acq", 0, 4, -1}, { "dcthresh", 0, 5, -1}, { "acthresh", 0, 6, -1}, { "mode", 0, 7, -1}, { "modeB", 0, 8, -1}, { "modeC", 0, 9, -1}, { "modeD", -0, 10, -1}, { "blockshape", 0, 11, -1}, { "pixels", 0, 12, -1}, { "N", 1, 12, -1}, { "txtype", 0, 13, -1}, { "txsize", 0, 14, -1}, { "L", 1, 15, -1}, { "eobcount", 0, 15, -1}, { NULL } }; static argument *a = arguments; static char *base = NULL; FILE *sfopen(char *mode, int posval){ char buf[MAXPATHLEN]; int range = a->ext; if (range > 1) { if(posval >= range){ fprintf(stderr,"Position value out of expected range in data:\n"); fprintf(stderr," argument name: %s\n possible range: %d\n " " value: %d\n",a->name, range, posval); return NULL; } if(a->posval >= 0){ fprintf(stderr,"Invalid argument entry in list:\n"); fprintf(stderr," argument name: %s\n possible range: %d\n " " value: %d\n",a->name, range, a->posval); return NULL; } snprintf(buf,MAXPATHLEN,"%s%s%s.m", base, *base?"-":"", (a - range + posval)->name); }else{ if(a->posval < 0){ snprintf(buf,MAXPATHLEN,"%s%s%s%d.m", base, *base?"-":"", (a - range)->name,posval); }else{ if(a->posval == posval){ snprintf(buf,MAXPATHLEN,"%s%s%s.m", base, *base?"-":"", (a - range)->name); } } } FILE *f = fopen(buf,mode); if(f==NULL){ fprintf(stderr,"Could not open output file %s.\n", buf); exit(1);; } return f; } FILE **out=NULL; int out_active = 0; int out_min = 0; int out_max = 0; int out_size = 0; int sfwrite(char *buf, int n, int stream){ if(out == NULL){ /* No output files actually opened, structures not allocated */ out_max = stream + 128; out = calloc(out_max, sizeof(*out)); } if(out_size < stream+1){ /* reallocate to larger output structure */ int new = stream + 128; out = realloc(out, new*sizeof(*out)); memset(out+out_size, 0, (new-out_size)*sizeof(*out)); out_size = new; } if(!out[stream]){ /* Do not currently have an output stream for this position index */ while(out_active >= 128){ /* Have too many output streams open... cull one*/ if(stream < out_min){ /* Cull one off the top */ out_max--; if(out[out_max]){ fclose(out[out_max]); out[out_max] = 0; out_active--; } continue; } if(out[out_min]){ /* cull one off the bottom */ fclose(out[out_min]); out[out_min] = 0; out_active--; } out_min++; } out[stream] = sfopen("a",stream); if(!out[stream]) return -1; if(stream < out_min) out_min = stream; if(stream >= out_max) out_max = stream+1; out_active++; } return fwrite(buf, 1, n, out[stream]); } void sfclose(void){ int i; if(out){ for(i=out_min; i<out_max; i++){ if(out[i])fclose(out[i]); } free(out); out=NULL; out_min=0; out_max=0; out_size=0; } } int main(int argc, char **argv){ int i; FILE *in; if(argc < 2) { fprintf(stderr,"Partition type is a required argument.\n"); return 1; } int pos = -1; int posval = -1; while(a->name){ if(!strcmp(a->name,argv[1]))break; a++; } if(!a->name){ fprintf(stderr,"Unknown partition request: %s\n",argv[1]); return 1; } pos = a->pos; posval = a->posval; for(i=2; i==2 || i<argc; i++){ if(argc < 3) { in = stdin; base = strdup(""); }else{ char *dot; in = fopen(argv[i],"r"); if(in==NULL){ fprintf(stderr,"Could not open input file %s.\n",argv[i]); return 1; } if(argc == 3){ base = strdup(basename(argv[i])); dot = strrchr(base, '.'); if (dot) *dot=0; }else{ base = strdup(""); } } char *bufp = NULL; char *tokp = NULL; size_t bn = 0; size_t tn = 0; ssize_t l; int toklength=0; while((l=getline(&bufp,&bn,in))>0){ size_t ret; if(bufp[0]=='#'){ char *tmpbuf = bufp; ssize_t tempn = bn; bufp = tokp; tokp = tmpbuf; bn = tn; tn = tempn; toklength = l; } else { long long x; char *lptr=bufp; char *rptr=bufp; int j; for(j=0;j<a->pos;j++){ strtoll(lptr,&rptr,10); if(lptr == rptr) break; lptr=rptr; } x=strtoll(lptr,&rptr,10); if(lptr == rptr) continue; if(posval == -1 || (int)x == posval){ if(toklength) ret=sfwrite(tokp,toklength,x); ret=sfwrite(bufp,l,x); if(ret!=l){ fprintf(stderr,"Write failed (%d != %d)\n",ret,l); return 1; } } toklength = 0; } } fclose(in); } sfclose(); }