/* * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd * http://www.trevorwishart.co.uk * http://www.composersdesktop.com * This file is part of the CDP System. The CDP System is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The CDP System is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the CDP System; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* Manipulate or Generate columns of numbers */ #include #include #include #define STACK_WITH_OVERLAP 1111 void usage(void), logo(void); static void read_flags(char *,char *); static void do_string_params(char *argv[],int pcnt); static void read_data(char *startarg,char *endarg,int *ro); static void do_help(char *str); static int option_takes_NO_data_but_has_extra_params(char *agv); static int option_takes_data_and_has_extra_params(char *agv); static void check_exceptional_processes(int ro,int argc); static void handle_multifile_processes_and_the_output_file(int argc,char flag,int ro,char **argv); static void cant_read_numeric_value(char flag,int ro); static void cant_read_numeric_value_with_flag_only(char flag); static void unknown_flag_only(char flag); static void unknown_flag(char flag,int ro); static void cannot_read_flags(char *flagstr); static void flag_takes_no_params(char flag,int ro); static void flag_only_takes_no_params(char flag); static void unknown_flag_or_bad_param(void); static void no_value_with_flag(char flag,int ro); static void no_value_with_flag_only(char flag); static void no_value_required_with_flag(char flag,int ro); static void no_value_required_with_flag_only(char flag); static void read_flags_data_error(char *str); static void unknown_flag_string(char *flagstr); static void check_for_columnextract(char *argv1,int *argc,char *argv[]); static int valid_call_for_multicol_input(char flag,int ro); static int noro(int ro); static void output_multicol_data(); int cnt = 0, firstcnt, arraysize = BIGARRAY, infilecnt, outfilecnt, colcnt, thecol, allcols = 1; double *number, *permm, *permmm, factor, scatter, *pos, *outcoldata; int outcoldatacnt = 0; FILE **fp; char temp[20000], flag, *filename, *thisfilename, string[200]; int ro = 0, ifactor = 0, len, condit = 0; double thresh; int *file_cnt; int sloom = 0; int sloombatch = 0; char errstr[400]; char srcfile[2000],goalfile[2000]; #define TOO_BIG_ARRAY (100000) void reorganise_extra_params(char *agv,int argc,char *argv[]); const char* cdp_version = "7.1.0"; int main(int argc,char *argv[]) { int extra_params = 0, k = 0, *perm = (int *)0; char *agv = (char *)0; char *p; goalfile[0] = ENDOFSTR; if(argc==2 && (strcmp(argv[1],"--version") == 0)) { fprintf(stdout,"%s\n",cdp_version); fflush(stdout); return 0; } if(argc < 2) usage(); if(!strcmp(argv[1],"#")) { sloom = 1; argv++; argc--; } else if (!strcmp(argv[1],"##")) { p = argv[0]; argc--; argv++; argv[0] = p; sloombatch = 1; } initrand48(); number = (double *)exmalloc(arraysize * sizeof(double)); fp = (FILE **)exmalloc(2 * sizeof(FILE *)); fp[1] = stderr; if(!sloom && !sloombatch) { if(argc==2) do_help(argv[1]); } if(argc<3) usage(); check_for_columnextract(argv[1],&argc,argv); check_for_conditional(&argc,argv); agv = argv[argc-1]; if(!sloom) { if(allcols > 1) read_data("__temp.txt",argv[argc-1],&ro); else read_data(argv[1],argv[argc-1],&ro); read_flags(agv,argv[2]); } else { if(option_takes_NO_data_but_has_extra_params(agv)) extra_params = 1; else { if(allcols > 1) read_data("__temp.txt",argv[argc-1],&ro); else read_data(argv[1],argv[argc-1],&ro); } if(option_takes_data_and_has_extra_params(agv)) { extra_params = 1; read_flags(agv,argv[2]); } if(!extra_params) read_flags(agv,argv[2]); } check_exceptional_processes(ro,argc); if(!sloom) { if(argc>=4) handle_multifile_processes_and_the_output_file(argc,flag,ro,argv); if((number=(double *)exrealloc((char *)number,(cnt+1)*sizeof(double)))==NULL) { fprintf(stdout, "ERROR: Out of memory\n"); fflush(stdout); exit(1); /* EXTRA ONE IS TEMPORARY FOR QIKSORT INDEXING PROBLEM !! */ } } else { if(argc>=4 && !extra_params) handle_multifile_processes_and_the_output_file(argc,flag,ro,argv); else if(flag =='K' && ro == 'b') { handle_multifile_processes_and_the_output_file(argc,flag,ro,argv); } if(extra_params) reorganise_extra_params(agv,argc,argv); else if((number=(double *)exrealloc((char *)number,(cnt+1)*sizeof(double)))==NULL) { fprintf(stdout, "ERROR: Out of memory\n"); fflush(stdout); exit(1); /* EXTRA ONE IS TEMPORARY FOR QIKSORT INDEXING PROBLEM !! */ } } switch(flag) { case('A'): switch(ro) { case('d'): accel_durations(); break; /* Ad */ case('e'): abutt(); break; /* Ae */ case('s'): alphabetic_sort(); break; /* As */ case('t'): accel_time_seq(); break; /* At */ default: approx_vals(); break; /* A */ } break; case('a'): switch(ro) { case(0): add(); break; /* a */ case('o'): ascending_order(); break; /* ao */ case('T'): append_text(0); break; /* aT */ case('X'): append_text(1); break; /* aX */ } break; case('B'): plain_bob(); break; /* B */ case('b'): switch(ro) { case('b'): band_cut(); break; /* bb */ case('g'): reduce_to_bound(); print_numbers(); break; /* bg */ case('l'): increase_to_bound(); print_numbers(); break; /* bl */ } break; case('C'): switch(ro) { case(ENDOFSTR): concatenate_files(argv[1]); break; /* C */ case('c'): concatenate_files_cyclically(argv[1]); break; /* Cc */ case('a'): cyclic_select('a'); break; /* Ca */ case('m'): cyclic_select('m'); break; /* Cm */ } break; case('c'): switch(ro) { case(ENDOFSTR): count_items(argv[1]); break; /* c */ case('c'): columnate(); break; /* cc */ case('l'): count_items(argv[1]); break; /* cl */ case('s'): cosin_spline(); break; /* cs */ case('t'): cut_table_at_time(); break; /* ct */ } break; case('D'): switch(ro) { case('B'): db_to_level(0); break; /* DB */ case('s'): db_to_level(1); break; /* Ds */ } break; case('d'): switch(ro) { case(ENDOFSTR): divide_list(); break; /* d */ case('b'): level_to_db(0); break; /* db */ case('d'): duplicate_values_stepped(); break; /* dd */ case('g'): distance_from_grid(); break; /* dg */ case('h'): delay_to_pitch(0); break; /* dh */ case('i'): delete_small_intervals(); break; /* di */ case('l'): duplicate_list(); break; /* dl */ case('L'): duplicate_list_at_step(); break; /* dL */ case('M'): delay_to_pitch(1); break; /* dM */ case('o'): duplicate_octaves(); break; /* do */ case('O'): duplicate_octfrq(); break; /* dO */ case('v'): duplicate_values(); break; /* dv */ } break; case('E'): vals_end_to_end_in_2_cols(); break; /* E */ case('e'): switch(ro) { case(ENDOFSTR): eliminate_equivalents(); print_numbers(); break; /* e */ case('a'): env_append(); break; /* ea */ case('b'): eliminate_dupltext(); break; /* eb */ case('d'): eliminate_duplicates(); print_numbers(); break; /* ed */ case('e'): eliminate_even_items(); print_numbers(); break; /* ee */ case('f'): expand_table_dur_by_factor(); break; /* ef */ case('g'): eliminate_greater_than(); print_numbers(); break; /* eg */ case('i'): env_superimpos(INVERT,MULT); break; /* ei */ case('l'): eliminate_less_than(); print_numbers(); break; /* el */ case('L'): list_warp(); break; /* eL */ case('m'): env_superimpos(0,ENVMAX); break; /* em */ case('Q'): seqtime_warp(); break; /* eQ */ case('s'): env_superimpos(0,MULT); break; /* es */ case('t'): expand_table_to_dur(); break; /* et */ case('v'): expand_table_vals_by_factor(); break; /* ev */ case('w'): time_warp(); break; /* ew */ case('W'): brktime_warp(); break; /* eW */ case('x'): extend_table_to_dur(); break; /* ex */ case('X'): brkval_warp(); break; /* eX */ case('Y'): brktime_owarp(); break; /* eY */ case('A'): env_superimpos(0,ADD); break; /* eA */ case('D'): env_del_inv(); break; /* eD */ case('P'): env_plateau(); break; /* eP */ case('S'): env_superimpos(0,SUBTRACT); break; /* eS */ } break; case('F'): switch(ro) { case(ENDOFSTR): format_vals(); break; /* F */ /* RWD */ case('r'): column_format_vals(); break; /* Fr */ case('f'): format_strs(); break; /* Ff */ case('R'): column_format_strs(); break; /* FR */ } break; case('f'): switch(ro) { case('r'): remove_frq_pitchclass_duplicates(); break; /* fr */ case('l'): floor_vals(); break; /* fl */ case('t'): pitchtotext(0); break; /* ft */ } break; case('G'): group(); break; /* G */ case('g'): switch(ro) { case(ENDOFSTR): greatest(); break; /* g */ case('s'): multiply(1); break; /* gs */ case('a'): cumuladd(); break; /* ga */ } break; case('H'): switch(ro) { case(ENDOFSTR): generate_harmonics(); break; /* H */ case('g'): group_harmonics(); break; /* Hg */ case('r'): get_harmonic_roots(); break; /* Hr */ } break; case('h'): switch(ro) { case('d'): pitch_to_delay(0); break; /* hd */ case('M'): hz_to_midi(); break; /* hM */ } break; case('I'): switch(ro) { case(ENDOFSTR): print_numbers(); break; /* I */ case('r'): interval_to_ratio(1,0); break; /* Ir */ case('v'): invert_normd_env(); break; /* Iv */ case('V'): interp_n_vals(); break; /* IV */ } break; case('i'): switch(ro) { case(ENDOFSTR): get_intervals(); break; /* i */ case('r'): repeat_intervals(); break; /* ir */ case('='): make_equal_intevals_btwn_given_vals(); break; /* i= */ case('e'): create_equal_vals(); break; /* ie */ case('c'): create_intervals(); break; /* ic */ case('C'): create_intervals_from_base(); break; /* iC */ case('R'): create_ratios_from_base(); break; /* iR */ case('p'): insert_intermediate_valp(); break; /* ip */ case('Q'): create_equal_steps(); break; /* iQ */ case('a'): change_value_of_intervals(); break; /* ia */ case('m'): change_value_of_intervals(); break; /* im */ case('v'): get_intermediate_values(); break; /* iv */ case('V'): insert_intermediate_values(); break; /* iV */ case('M'): motivically_invert_midi(); break; /* iM */ case('h'): motivically_invert_hz(); break; /* ih */ case('l'): /* il */ case('L'): interval_limit(); break; /* iL */ } break; case('J'): switch(ro) { case(0): join_many_files_as_columns(argv[1],0); break; /* J */ case('j'): join_many_files_as_columns(argv[1],1); break; /* Jj */ } break; case('j'): switch(ro) { case(0): join_files_as_rows(); break; /* j */ case('j'): join_many_files_as_rows(); break; /* jj */ } break; case('k'): switch(ro) { case('A'): kill_path(); break; /* kA */ case('B'): kill_extension(); break; /* kB */ case('C'): kill_path_and_extension(); break; /* kC */ case('T'): kill_text(0); break; /* kT */ case('X'): kill_text(1); break; /* kX */ case('Y'): kill_text(2); break; /* kY */ } break; case('K'): switch(ro) { case('a'): ta_reverse_sequence(1); break; /* Ka */ case('A'): a_reverse_sequence(1); break; /* KA */ case('b'): abut_sequences(1); break; /* Kb */ case('c'): compress_sequence(1); break; /* Kc */ case('E'): p_expandset_sequence(1); break; /* KE */ case('I'): p_invertset_sequence(1); break; /* KI */ case('i'): p_invert_sequence(1); break; /* Ki */ case('l'): loop_sequence(1); break; /* Kl */ case('m'): uptempo_sequence(1); break; /* Km */ case('M'): accel_sequence(1); break; /* KM */ case('P'): p_reverse_sequence(1); break; /* KP */ case('r'): t_reverse_sequence(1); break; /* Kr */ case('R'): pa_reverse_sequence(1); break; /* KR */ case('t'): transpose_sequence(1); break; /* Kt */ case('T'): tp_reverse_sequence(1); break; /* KT */ case('Z'): tpa_reverse_sequence(1); break; /* KZ */ } break; case('L'): log_equal_divisions(); break; /* L */ case('l'): switch(ro) { case(ENDOFSTR): least(); break; /* l */ case('i'): limit_vals(); break; /* li */ case('v'): limit_table_val_range(); break; /* lv */ } break; case('M'): switch(ro) { case(ENDOFSTR): find_mean(); break; /* M */ case('d'): pitch_to_delay(1); break; /* Md */ case('h'): midi_to_hz(); break; /* Mh */ case('m'): major_to_minor(); break; /* Mm */ case('r'): remove_midi_pitchclass_duplicates(); break; /* Mr */ case('t'): pitchtotext(1); break; /* Mt */ } break; case('m'): switch(ro) { case(0): multiply(0); break; /* m */ case('g'): mark_greater_than(); break; /* mg */ case('l'): mark_less_than(); break; /* ml */ case('m'): mark_multiples(); break; /* mm */ case('M'): minor_to_major(); break; /* mM */ case('e'): mark_event_groups(); break; /* me */ case('i'): min_interval(0); break; /* mi */ case('I'): min_interval(1); break; /* mI */ } break; case('N'): switch(ro) { case('r'): rotate_partition_values_to_files(); break; /* Nr */ default: partition_values_to_files(); break; /* N */ } break; case('n'): switch(ro) { case('F'): note_to_midi(2); break; /* nF */ case('M'): note_to_midi(0); break; /* nM */ case('T'): note_to_midi(1); break; /* nT */ } break; case('O'): switch(ro) { case('s'): multiply(0); break; /* Os */ case('T'): interval_to_ratio(0,1); break; /* OT */ } break; case('o'): switch(ro) { case(ENDOFSTR): qiksort(); print_numbers(); break; /* o */ case('r'): interval_to_ratio(0,0); break; /* or */ } break; case('p'): switch(ro) { case(ENDOFSTR): product(); break; /* p */ case('p'): tw_psuedopan(); break; /* pp */ } break; case('P'): take_power(); break; /* P */ case('Q'): quadratic_curve_steps(); break; /* Q */ case('q'): switch(ro) { case(ENDOFSTR): quantise(); break; /* q */ case('t'): quantise_time(); break; /* qt */ case('v'): quantise_val(); break; /* qv */ case('z'): rand_zigs(); break; /* qz */ } break; case('R'): switch(ro) { case(ENDOFSTR): reciprocals(0); break; /* R */ case('o'): case('x'): if((perm=(int *)malloc(stringscnt * sizeof(int)))==NULL) { fprintf(stdout, "ERROR: Out of memory\n"); fflush(stdout); exit(1); } for(k=0;k 1.0) { if(number[0] < .001) { fprintf(stdout, "ERROR: Quantisation too small for scatter > 1.0\n"); fflush(stdout); exit(1); } k = (int)floor(number[1]/number[0]) + 1; k = (int)ceil(k/(cnt-1)); k *= round(number[2]); if(k > TOO_BIG_ARRAY) { fprintf(stdout, "ERROR: Combination of scatter > 1 with small quantisation: requires too much memory\n"); fflush(stdout); exit(1); } if((perm=(int *)malloc(k * sizeof(int)))==NULL) { fprintf(stdout, "ERROR: Out of memory\n"); fflush(stdout); exit(1); } } quantised_scatter(perm,k); break; /* za */ case('X'): alt0101(); break; /* zX */ case('Y'): alt0011(); break; /* zY */ case('Z'): alt01100(); break; /* zZ */ case('A'): alt0r0r(); break; /* zA */ case('B'): altr0r0(); break; /* zB */ case('C'): alt00rr(); break; /* zC */ case('D'): altrr00(); break; /* zD */ case('e'): tw_pseudo_exp(); break; /* ze */ case('E'): alt0rr00r(); break; /* zE */ case('F'): altr00rr0(); break; /* zF */ case('G'): alt00RR(); break; /* zG */ case('H'): altrr00(); break; /* zH */ case('I'): alt0RR00R(); break; /* zI */ case('J'): altR00RR0(); break; /* zJ */ } break; case('Z'): switch(ro) { case('h'): just_intonation_Hz(); break; /* Zh */ case('M'): just_intonation_midi(); break; /* ZM */ case('H'): create_just_intonation_Hz(); break; /* ZH */ case('m'): create_just_intonation_midi(); break; /* Zm */ case('s'): random_warp(); break; /* Zs */ } break; } if(allcols > 1) output_multicol_data(); return 0; } /****************************** USAGE ****************************/ void usage(void) { if(!sloom) { logo(); fprintf(stderr, "USAGE: columns infile [outfile] -flag[@] [{threshold|}threshold] [--cCOLCNT]\n\n"); fprintf(stderr, " { = less than: } = greater than THRESHOLD is numeric value.\n"); fprintf(stderr, " threshold can only be used with R,a,m,d,P,c.\n"); fprintf(stderr, " and specified operation then applies ONLY to vals > OR < threshold value.\n\n"); fprintf(stderr, " If multicolumn data is being processed\n"); fprintf(stderr, " COLCNT is the column of the input data to which process is applied.\n"); fprintf(stderr, " Not all processes work with multicolumn data.\n"); fprintf(stderr, "FOR MORE INFORMATION:\n"); fprintf(stderr, " columns -f to see all available flags.\n"); fprintf(stderr, " columns -g for generative operations.\n"); fprintf(stderr, " columns -l for list manipulation and editing.\n"); fprintf(stderr, " columns -m for mathematical operations.\n"); fprintf(stderr, " columns -M for musical operations.\n"); fprintf(stderr, " columns -R for random operations.\n"); fprintf(stderr, "ALSO\n"); fprintf(stderr, "columns inoutfile1 infile2 [infile3....] -J to juxtapose cols in one file\n"); fprintf(stderr, "columns infile1 outfiles -SX to separate cols to X distinct files.\n"); fprintf(stderr, "columns infile1 outfiles -NX to separate vals to X distinct files, in blocks.\n"); fprintf(stderr, "columns infile1 outfiles -NrX to separate vals to X distinct files, in rotation\n"); } exit(1); } /********************************** READ_FLAGS *************************/ void read_flags(char *argv,char *argv2) { char *p, *q; double qtone = 0.0; int maxpos; if(*argv++!='-') cannot_read_flags(argv-1); if(sscanf(argv++,"%c",&flag)!=1) cannot_read_flags(argv-2); if(allcols > 1) { ro = *argv; if(!valid_call_for_multicol_input(flag,ro)) { fprintf(stdout,"ERROR: Operation invalid with multicolumn input.\n"); fflush(stdout); exit(1); } } switch(flag) { case('A'): ro = *argv++; switch(ro) { case('b'): /* Ab */ case('e'): /* Ae */ case('s'): /* As */ if(strlen(argv)) no_value_required_with_flag(flag,ro); break; case('d'): /* Ad */ case('t'): /* At */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; default: if(sscanf(--argv,"%lf",&factor)!=1) /* A */ unknown_flag(flag,ro); } break; case('a'): /* a */ ro = *argv++; switch(ro) { case('o'): /* ao */ break; case('T'): /* aT */ case('X'): /* aX */ if(sscanf(argv,"%s",temp)!=1) { fprintf(stdout,"ERROR: Cannot read string text parameter.\n"); fflush(stdout); exit(1); } break; default: /* a */ if(sscanf(--argv,"%lf",&factor)!=1) { cant_read_numeric_value_with_flag_only(flag); } ro = 0; ifactor = round(factor); break; } break; case('B'): /* B */ if((cnt & 1)) read_flags_data_error("Must have even number of 'bells' for bell-ringing, at present."); if(cnt > 32) read_flags_data_error("Too many bells (max 32, at present)."); if(*argv!=ENDOFSTR) flag_only_takes_no_params(flag); break; case('b'): ro = (int)*argv++; switch(ro) { case('b'): /* bb */ break; case('g'): /* bg */ case('l'): /* bl */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; default: unknown_flag_string(argv-2); } break; case('C'): /* C */ ro =*argv++; switch(ro) { case(ENDOFSTR): case('a'): case('m'): case('c'): break; } break; case('c'): ro = *argv++; switch(ro) { case(ENDOFSTR): break; /* c */ case('l'): /* cl */ case('c'): /* cc */ if(*argv!=ENDOFSTR) flag_takes_no_params(flag,ro); break; case('s'): /* cs */ case('t'): /* ct */ if(sscanf(argv,"%lf",&factor)!=1) no_value_with_flag(flag,ro); break; default: if(isdigit(ro) || ro=='.' || ro=='-') { --argv; if(sscanf(argv,"%lf",&thresh)!=1) cant_read_numeric_value(flag,ro); else { ro = 0; condit = '>'; } break; } unknown_flag(flag,ro); } break; case('D'): ro = (int)*argv++; switch(ro) { case('B'): /* DB */ case('s'): /* Ds */ break; default: unknown_flag(flag,ro); } break; case('d'): ro = (int)*argv++; switch(ro) { case('v'): /* dv */ case('l'): /* dl */ case('o'): /* do */ case('O'): /* dO */ if(sscanf(argv,"%d",&ifactor)!=1) cant_read_numeric_value(flag,ro); break; case('i'): /* di */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; case('b'): /* db */ case('d'): /* dd */ case('g'): /* dg */ case('h'): /* dh */ case('L'): /* dL */ case('M'): /* dM */ break; default: if(isalpha(ro)) unknown_flag(flag,ro); else { if(sscanf(argv-1,"%lf",&factor)!=1) cant_read_numeric_value_with_flag_only(flag); ro = ENDOFSTR; /* d */ } break; } break; case('E'): /* E */ if(sscanf(argv,"%lf",&factor)!=1) factor = 0.0; break; case('e'): ro = (int)*argv; if(ro==ENDOFSTR) no_value_with_flag_only(flag); if(isdigit(ro) || ro=='.' || ro=='-') { if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value_with_flag_only(flag); ro = ENDOFSTR; /* e */ break; } argv++; switch(ro) { case('e'): /* ee */ case('b'): /* eb */ case('Q'): /* eQ */ case('L'): /* eL */ case('w'): /* ew */ case('W'): /* eW */ case('X'): /* eX */ case('Y'): /* eY */ if(*argv!=ENDOFSTR) read_flags_data_error("No parameter required with this option."); break; case('a'): /* ea */ case('d'): /* ed */ case('g'): /* eg */ case('l'): /* el */ case('f'): /* ef */ case('t'): /* et */ case('x'): /* ex */ case('v'): /* ev */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; case('i'): /* ei */ case('m'): /* em */ case('s'): /* es */ case('A'): /* eA */ case('S'): /* eS */ if(*argv == ENDOFSTR) factor = 0.0; else { if(sscanf(argv,"%lf",&factor)!=1) { fprintf(stdout,"ERROR: Cannot read numerical value.\n"); fflush(stdout); exit(1); } if(factor < 0.0) { fprintf(stdout,"ERROR: Cannot insert at a time before zero.\n"); fflush(stdout); exit(1); } } break; case('D'): /* eD */ if(sscanf(argv,"%lf",&factor)!=1) { fprintf(stdout,"ERROR: Cannot read numerical value.\n"); fflush(stdout); exit(1); } if(factor < 0.0) { fprintf(stdout,"ERROR: Cannot delay to a time before zero.\n"); fflush(stdout); exit(1); } break; case('P'): /* eP */ if(sscanf(argv,"%d",&ifactor)!=1) { fprintf(stdout,"ERROR: Cannot read line number.\n"); fflush(stdout); exit(1); } if(ifactor < 1 || ifactor > cnt) { fprintf(stdout,"ERROR: Line %d does not exist.\n",ifactor); fflush(stdout); exit(1); } if(ifactor == 1) { fprintf(stdout,"ERROR: Cannot plateau at line 1 (No change to file).\n"); fflush(stdout); exit(1); } break; default: unknown_flag_string(argv-2); } break; /*RWD new Format option */ case('F'): ro = (int)*argv; if(ro=='r' || ro == 'f' || ro == 'R') argv++; else ro = ENDOFSTR; if(((int)*argv) == ENDOFSTR) no_value_with_flag_only(flag); if(sscanf(argv,"%d",&ifactor)!=1) cant_read_numeric_value_with_flag_only(flag); if(ifactor <= 0) read_flags_data_error("Value must be > zero."); if(!sloom) { if(ifactor > 8) read_flags_data_error("Maximum of 8 values possible on a line."); } break; case('f'): ro = *argv++; switch(ro) { case('t'): /* ft */ break; case('r'): /* fr */ if(sscanf(argv,"%d",&ifactor)!=1) ifactor = 1; break; case('l'): /* fl */ if(sscanf(argv,"%lf",&factor)!=1) no_value_with_flag(flag,ro); break; default: unknown_flag(flag,ro); } break; case('G'): /* G */ if(sscanf(argv,"%d",&ifactor)!=1) no_value_with_flag_only(flag); if(ifactor >= stringscnt) { sprintf(errstr,"ERROR: regrouping value (%d) is too big for list of numbers (only %d in list).\n",ifactor,cnt); do_error(); } break; case('g'): ro = *argv++; switch(ro) { case(ENDOFSTR): /* g */ case('a'): /* ga */ break; case('s'): /* gs */ factor = (double)MAXSAMP; break; default: unknown_flag_or_bad_param(); } break; case('H'): if((ro = (int)*argv++)!='g' && ro !='r') { if(isalpha(ro)) unknown_flag(flag,ro); if(sscanf(--argv,"%d",&ifactor)!=1) no_value_with_flag_only(flag); ro = ENDOFSTR; } else { switch(ro) { case('r'): if(sscanf(argv,"%d",&ifactor)!=1) no_value_with_flag(flag,ro); break; case('g'): if(sscanf(argv,"%lf",&factor)!=1) factor = HARMONIC_TUNING_TOLERANCE; break; default: unknown_flag(flag,ro); } } break; case('h'): ro = *argv++; switch(ro) { case('d'): /* hd */ case('M'): /* hM */ break; default: unknown_flag_string(argv-1); } if(*argv!=ENDOFSTR) read_flags_data_error("No parameter required with this flag."); break; case('I'): ro =*argv++; switch(ro) { case(ENDOFSTR): break; /* I */ case('r'): break; /* Ir */ case('v'): break; /* Iv */ case('V'): /* IV */ if(sscanf(argv,"%d",&ifactor)!=1) cant_read_numeric_value(flag,ro); break; } break; case('i'): ro = (int)*argv++; switch(ro) { case(ENDOFSTR): /* i */ break; case('M'): /* iM */ case('p'): /* ip */ case('v'): /* iv */ case('V'): /* iV */ case('h'): /* ih */ if(*argv!=ENDOFSTR) no_value_required_with_flag(flag,ro); break; case('='): /* i= */ if(cnt!=2) { if(!sloom) read_flags_data_error("Must have two values in infile with flag i=."); exit(1); } if(flteq(number[0],number[1])) { if(!sloom) read_flags_data_error("Two values in infile must be different."); exit(1); } if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); if(flteq(factor,0.0)) read_flags_data_error("Parameter cannot be zero."); break; case('r'): /* ir */ case('c'): /* ic */ if(sscanf(argv,"%d",&ifactor)!=1) cant_read_numeric_value(flag,ro); if(flag=='c' && cnt!=1) read_flags_data_error("Must have only one value in infile."); break; case('a'): /* ia */ case('m'): /* im */ case('l'): /* il */ case('L'): /* iL */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; default: if(isdigit(ro) || ro=='.' || ro=='-') flag_only_takes_no_params(flag); unknown_flag_string(argv-2); } break; case('J'): ro = *argv; if(ro=='j') { /*Jj */ if(sscanf(++argv,"%d",&ifactor)!=1) no_value_with_flag_only(flag); } else if(*argv!=ENDOFSTR) /* J */ flag_only_takes_no_params(flag); break; case('j'): ro = *argv; if(ro == 'j') /* jj */ break; else { /* j */ ro = 0; maxpos = (cnt/colcnt) + 1; if(sscanf(argv,"%d",&ifactor)!=1) no_value_with_flag_only(flag); else if(ifactor > maxpos) { fprintf(stdout,"ERROR: Insertion point is beyond end of file: reverting to end of file.\n"); fflush(stdout); ifactor = maxpos; } } break; case('L'): /* L */ if(cnt!=2) read_flags_data_error("Must have two values in infile."); if(flteq(number[0],number[1])) read_flags_data_error("Two values in infile must be different."); if(number[0]<=0 || number[1]<=0) read_flags_data_error("This option only works on values >0.\n"); if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value_with_flag_only(flag); if(flteq(factor,0.0)) read_flags_data_error("Parameter cannot be zero."); break; case('l'): ro =*argv++; switch(ro) { case(ENDOFSTR): break; /* l */ case('i'): /* li */ case('v'): /* lv */ if(sscanf(argv,"%lf",&factor)!=1) no_value_with_flag(flag,ro); break; default: unknown_flag(flag,ro); } break; case('k'): ro =*argv++; switch(ro) { case('A'): /* kA */ case('B'): /* kB */ case('C'): /* kC */ case('T'): /* kT */ case('X'): /* kX */ case('Y'): /* kY */ break; default: unknown_flag(flag,ro); } break; case('K'): ro =*argv++; switch(ro) { case('c'): case('t'): case('E'): case('l'): case('b'): case('m'): case('M'): if(sscanf(argv,"%lf",&factor)!=1) read_flags_data_error("Cannot read parameter value."); break; case('I'): case('i'): case('P'): case('A'): case('R'): case('r'): case('Z'): case('T'): case('a'): break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; case('M'): ro = *argv++; switch(ro) { case(ENDOFSTR): /* M */ case('d'): /* Md */ break; case('h'): /* Mh */ if(*argv!=ENDOFSTR) no_value_required_with_flag(flag,ro); break; case('m'): /* Mm */ if((p=get_pitchclass(argv,&ifactor,0))==(char *)0) { sprintf(errstr,"key not specified, or unknown (%s)\n",argv); do_error(); } break; case('t'): /* Mt */ break; case('r'): /* Mr */ if(sscanf(argv,"%d",&ifactor)!=1) ifactor = 1; break; default: if(isdigit(ro) || ro=='.' || ro=='-') no_value_required_with_flag_only(flag); unknown_flag(flag,ro); } break; case('m'): ro = *argv++; switch(ro) { case('i'): /* mi */ case('I'): /* mI */ break; case('M'): /* mM */ if((p=get_pitchclass(argv,&ifactor,0))==(char *)0) { sprintf(errstr,"key not specified, or unknown (%s)\n",argv); do_error(); } break; case('g'): /* mg */ case('l'): /* ml */ case('e'): /* me */ case('m'): /* mm */ if(sscanf(argv,"%lf",&factor)!=1) { cant_read_numeric_value(flag,ro); } if(ro == 'm' && flteq(factor,0.0)) { fprintf(stdout,"ERROR: Mutiples of numbers very close to zero cannot be handled.\n"); fflush(stdout); exit(1); } ifactor = round(factor); break; default: /* m */ if(sscanf(--argv,"%lf",&factor)!=1) { cant_read_numeric_value_with_flag_only(flag); } ro = 0; break; } break; case('N'): /* N */ ro = *argv; if(ro == 'r') /* Nr */ argv++; if(*argv==ENDOFSTR) { if(ro=='r') cant_read_numeric_value(flag,ro); else cant_read_numeric_value_with_flag_only(flag); } if(ro!='r' && !isdigit(ro)) unknown_flag(flag,ro); if(sscanf(argv,"%d",&outfilecnt)!=1) { if(ro=='r') cant_read_numeric_value(flag,ro); else cant_read_numeric_value_with_flag_only(flag); } if(outfilecnt<2) read_flags_data_error("Number of partitioning sets must be >1."); if(outfilecnt > 99) read_flags_data_error("You can't have more than 99 outfiles (at present)."); len = strlen(argv2); filename = (char *)exmalloc(len+1); *filename = ENDOFSTR; strcpy(filename,argv2); len+=2; if(factor>9) len++; thisfilename = (char *)exmalloc(len+1); break; case('n'): /* n */ ro = *argv++; switch(ro) { case('F'): /* nF */ case('M'): /* nM */ break; case('T'): /* nT */ switch(*argv++) { case('c'): case('C'): factor = 60.0; break; case('d'): case('D'): factor = 62.0; break; case('e'): case('E'): factor = 64.0; break; case('f'): case('F'): factor = 65.0; break; case('g'): case('G'): factor = 67.0; break; case('a'): case('A'): factor = 69.0; break; case('b'): case('B'): factor = 71.0; break; default: fprintf(stdout,"ERROR: Cannot read note parameter.\n"); fflush(stdout); exit(1); } switch(*argv) { case('b'): factor -= 1.0; argv++; break; case('#'): factor += 1.0; argv++; break; case(ENDOFSTR): break; } ifactor = 0; switch(*argv) { case(ENDOFSTR): break; default: qtone = 0.0; q = argv + strlen(argv) - 1; if(*q == '-') { qtone = -.5; *q = ENDOFSTR; } else if(*q == '+') { qtone = .5; *q = ENDOFSTR; } if(sscanf(argv,"%d",&ifactor)!=1) { fprintf(stdout,"ERROR: Invalid octave data in note parameter.\n"); fflush(stdout); exit(1); } break; } factor += (double)(12 * ifactor); factor += qtone; break; default: unknown_flag_string(argv-1); } break; case('O'): ro = *argv++; switch(ro) { case('s'): /* Os */ factor = 12; break; case('T'): /* OT */ break; default: unknown_flag(flag,ro); } break; case('o'): ro = *argv++; switch(ro) { case(ENDOFSTR): /* o */ case('r'): /* or */ break; default: unknown_flag_or_bad_param(); } break; case('p'): /* p */ ro = *argv++; switch(ro) { case(ENDOFSTR): /* p */ case('p'): /* pp */ break; default: unknown_flag_string(argv-1); } break; case('P'): /* P */ case('q'): /* q */ ro = (int)*argv; if(ro==ENDOFSTR) no_value_with_flag_only(flag); if(isdigit(ro) || ro=='.' || ro=='-') { if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value_with_flag_only(flag); ro = ENDOFSTR; /* q */ break; } switch(ro) { case('t'): case('v'): argv++; if(sscanf(argv,"%lf",&factor)!=1) { cant_read_numeric_value(flag,ro); exit(1); } break; default: unknown_flag_string(argv-1); break; } break; case('Q'): /* Q */ if(cnt!=3) read_flags_data_error("Must have three values in infile."); if(flteq(number[0],number[1])) read_flags_data_error("First two values in infile must be different."); if(number[2]<=0.0) read_flags_data_error("Curvature (third value in infile) must be >0.0."); if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value_with_flag_only(flag); if(flteq(factor,0.0)) read_flags_data_error("Parameter cannot be zero."); break; case('R'): ro = (int)*argv++; switch(ro) { case(ENDOFSTR): /* R */ factor = 1.0; break; case('g'): /* Rg */ case('G'): /* RG */ if(*argv!=ENDOFSTR) read_flags_data_error("No parameter required with this option."); break; case('o'): /* Ro */ case('i'): /* Ri */ case('I'): /* RI */ case('r'): /* Rr */ if(*argv!=ENDOFSTR) { fprintf(stdout,"ERROR: No parameter required with this option\n"); fflush(stdout); exit(1); } break; case('e'): /* Re */ if(sscanf(argv,"%d",&ifactor)!=1) no_value_with_flag(flag,ro); break; case('a'): /* Ra */ case('A'): /* RA */ case('c'): /* Rc */ case('m'): /* Rm */ case('s'): /* Rs */ case('v'): /* Rv */ case('x'): /* Rx */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); if(ro=='s' && (factor > 1.0 || factor < 0.0)) read_flags_data_error("Numerical value out of range [0-1]."); else if(ro == 'x') { ifactor = round(factor); if(ifactor < 1) read_flags_data_error("Numerical value out of range [must be >= 1]."); } break; default: if(sscanf(argv-1,"%lf",&factor)!=1) unknown_flag_string(argv-2); ro = ENDOFSTR; } break; case('r'): ro = *argv++; switch(ro) { case(ENDOFSTR): /* r */ break; case('m'): /* rm */ if(sscanf(argv,"%d",&ifactor)!=1) no_value_with_flag(flag,ro); break; case('T'): /* rT */ factor = 1.0; /* fall thro */ case('a'): /* ra */ case('G'): /* rG */ case('I'): /* rI */ case('J'): /* rJ */ case('o'): /* ro */ case('p'): /* rp */ case('r'): /* rr */ case('R'): /* rR */ case('X'): /* rX */ case('z'): /* rz */ if(*argv!=ENDOFSTR) no_value_required_with_flag(flag,ro); break; default: unknown_flag(flag,ro); } break; case('S'): /* S */ ro = *argv; switch(ro) { case('M'): /* SM */ argv++; /* NB need to do this here if there are more 'S' flags!! */ if(*argv!=ENDOFSTR) no_value_required_with_flag(flag,ro); break; default: if(*argv==ENDOFSTR) { cant_read_numeric_value_with_flag_only(flag); exit(1); } if(sscanf(argv,"%d",&outfilecnt)!=1) { cant_read_numeric_value_with_flag_only(flag); exit(1); } if(outfilecnt<2) read_flags_data_error("Number of partitioning sets must be >1."); if(outfilecnt > 99) read_flags_data_error("You can't have more than 99 outfiles (at present)."); len = strlen(argv2); filename = (char *)exmalloc(len+1); *filename = ENDOFSTR; strcpy(filename,argv2); len+=2; if(factor>9) len++; thisfilename = (char *)exmalloc(len+1); ro = ENDOFSTR; break; } break; case('s'): ro = *argv++; switch(ro) { case('R'): /* sR */ case('T'): /* sT */ case('F'): /* sF */ case('X'): /* sX */ case('a'): /* sa */ case('b'): /* sb */ case('f'): /* sf */ break; case('O'): /* sO */ factor = .083333333333; /* i.e. 1/12 */ break; case('g'): /* sg */ factor = 1.0/MAXSAMP; break; case('d'): /* sd */ if(*argv == ENDOFSTR) { factor = 0.0; break; } /* fall thro */ /* sd with param */ case('A'): /* sA */ if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; case('t'): /* st */ if(*argv == ENDOFSTR) no_value_with_flag(flag,ro); else if(sscanf(argv,"%d",&ifactor)!=1) cant_read_numeric_value(flag,ro); else if(BAD_SR(ifactor)) read_flags_data_error("Invalid sampling rate."); break; case('P'): /* sP */ case('p'): /* sp */ case('o'): /* so */ case('u'): /* su */ case('k'): /* sk */ case('l'): /* sl */ case('K'): /* sK */ case('n'): /* sn */ case('E'): /* sE */ if(*argv == ENDOFSTR) no_value_with_flag(flag,ro); else if(sscanf(argv,"%lf",&factor)!=1) cant_read_numeric_value(flag,ro); break; case('U'): /* sn */ if(*argv == ENDOFSTR) no_value_with_flag(flag,ro); else if(sscanf(argv,"%s",string)!=1) { fprintf(stdout,"ERROR: Cannot read string text parameter.\n"); fflush(stdout); exit(1); } break; case('z'): /* sz */ ifactor = *argv; if(ifactor == ENDOFSTR) factor = 0.0; else { if(sscanf(argv,"%lf",&factor)!=1) { cant_read_numeric_value(flag,ro); exit(1); } } break; case(ENDOFSTR): /* s */ factor = 0.0; break; default: /* s with parameter */ if(isdigit(ro) || ro=='.' || ro=='-') { argv--; if(sscanf(argv,"%lf",&factor)!=1) { cant_read_numeric_value(flag,ro); exit(1); } ro = ENDOFSTR; } else unknown_flag(flag,ro); } break; case('T'): if((ro = *argv++)==ENDOFSTR) unknown_flag_only(flag); switch(ro) { case('M'): /* TM */ case('h'): /* Th */ if(sscanf(argv,"%lf",&factor)!=1) factor = TWELVE; /* Normal tempering */ break; case('c'): /* Tc */ case('l'): /* Tl */ if(sscanf(argv,"%lf",&factor)!=1) read_flags_data_error("Cannot read tempo value."); break; case('p'): /* Tp */ case('P'): /* TP */ if(sscanf(argv,"%lf",&factor)!=1) read_flags_data_error("Cannot read beat duration."); break; case('r'): /* Tr */ factor = 1.0; /* fall thro */ case('b'): /* Tb */ case('B'): /* TB */ case('O'): /* TO */ case('s'): /* Ts */ break; default: unknown_flag(flag,ro); } break; case('t'): ro = *argv++; switch(ro) { case(ENDOFSTR): /* t */ break; case('s'): /* ts */ if(*argv == ENDOFSTR) no_value_with_flag(flag,ro); else if(sscanf(argv,"%d",&ifactor)!=1) { cant_read_numeric_value(flag,ro); } else if(BAD_SR(ifactor)) read_flags_data_error("Invalid sampling rate."); break; case('e'): /* te */ case('M'): /* tM */ case('h'): /* th */ case('r'): /* tr */ case('R'): /* tR */ if(*argv!=ENDOFSTR) no_value_required_with_flag(flag,ro); break; case('d'): if(sscanf(argv,"%d",&ifactor)!=1) read_flags_data_error("Cannot read density value."); break; case('B'): /* tB */ case('c'): /* tc */ case('C'): /* tC */ if(sscanf(argv,"%lf",&factor)!=1) read_flags_data_error("Cannot read parameter value."); break; default: if(isdigit(ro) || ro=='.' || ro=='-') no_value_required_with_flag_only(flag); unknown_flag(flag,ro); } break; case('V'): if(sscanf(argv,"%lf",&factor)!=1) no_value_with_flag_only(flag); break; case('v'): if(sscanf(argv,"%lf",&factor)!=1) factor = 0.0; break; case('w'): ro =*argv++; switch(ro) { case('t'): case('o'): break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; case('W'): ro =*argv++; switch(ro) { case('c'): case('t'): case('E'): case('l'): case('b'): case('m'): case('M'): if(sscanf(argv,"%lf",&factor)!=1) read_flags_data_error("Cannot read parameter value."); break; case('I'): case('i'): case('P'): case('A'): case('R'): case('r'): case('Z'): case('T'): case('a'): break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; case('y'): ro =*argv++; switch(ro) { case('a'): case('A'): case('b'): case('B'): case('c'): case('C'): case('d'): case('e'): case('E'): case('g'): case('i'): case('I'): case('l'): case('o'): case('p'): case('q'): case('Q'): case('r'): case('R'): case('P'): case('s'): case('S'): case('x'): break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; case('Y'): ro =*argv++; switch(ro) { case('s'): case('S'): break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; case('z'): ro =*argv++; switch(ro) { case('A'): case('B'): case('C'): case('D'): case('e'): case('E'): case('F'): case('G'): case('H'): case('I'): case('J'): case('X'): case('Y'): case('Z'): case('q'): break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; case('Z'): ro =*argv++; switch(ro) { case('h'): case('M'): if(sscanf(argv,"%lf",&factor)!=1) read_flags_data_error("Cannot read parameter value."); break; case('s'): if(sscanf(argv,"%s",string)!=1) read_flags_data_error("Cannot read parameter value."); break; default: fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); exit(1); } break; default: unknown_flag_string(argv-1); } if(condit) { if(!(flag=='s' && (ro=='p' || ro=='P' || ro=='F' || ro=='R' || ro=='u' || ro=='X')) && !(flag=='W' && (ro=='l' || ro=='M')) && !(flag=='K' && (ro=='l' || ro=='M')) && !(flag == 'm' && ro == 'm') && !(flag =='T' && ro == 'P') && !(flag == 'l' && ro == 'v') && !(flag == 'd' && ro == 'L') && !(flag == 'T' && (ro == 'M' || ro == 'h')) && !(flag == 'c' && ro == 0) && (ro!=0 || !(flag=='R'||flag=='a'||flag=='m'||flag=='P'||flag=='c'||flag=='d'))) read_flags_data_error("Threshold cannot be used with this option."); } } /***************************** GET_EXTRA_PARAMS *********************************/ void get_extra_params(int no,int argc,char *argv[]) { int n, m; cnt = no; number=(double *)exrealloc((char *)number,(cnt+1)*sizeof(double)); for(n=2,m=0;n < argc-1;n++,m++) { if(sscanf(argv[n],"%lf",&number[m])!=1) { fprintf(stdout,"ERROR: Insufficient parameters for this process.\n"); fflush(stdout); exit(1); } } } /***************************** GET_FUNNY_PARAMS *********************************/ void get_funny_params(int no,int argc,char *argv[]) { int n, m; number=(double *)exrealloc((char *)number,(cnt+no)*sizeof(double)); for(n=2,m=cnt;n < argc-1;n++,m++) { if(sscanf(argv[n],"%lf",&number[m])!=1) { fprintf(stdout,"ERROR: Insufficient parameters for this process.\n"); fflush(stdout); exit(1); } } } /***************************** REORGANISE_EXTRA_PARAMS *********************************/ void reorganise_extra_params(char *agv,int argc,char *argv[]) { double range, step, scat, quantisation, dur; int tq, ql; agv++; flag = *agv; agv++; ro = *agv; switch(flag) { case('A'): switch(ro) { case('d'): case('t'): get_extra_params(3,argc,argv); factor = number[0]; number[0] = number[1]; number[1] = number[2]; cnt--; if(factor <= 0.0) { fprintf(stdout,"ERROR: Total duration must be greater than zero.\n"); fflush(stdout); exit(1); } if((number[0]<=0) || (number[1]<=0)) { fprintf(stdout,"ERROR: Time steps must be greater than zero.\n"); fflush(stdout); exit(1); } if(factor < number[0] + number[1]) { fprintf(stdout,"ERROR: Total duration too small to divide thus.\n"); fflush(stdout); exit(1); } break; case('T'): get_extra_params(4,argc,argv); factor = number[0]; number[0] = number[1]; number[1] = number[2]; number[2] = number[3]; cnt--; if((number[0]<=0) || (number[1]<=0)) { fprintf(stdout,"ERROR: Time steps must be greater than zero.\n"); fflush(stdout); exit(1); } if(factor <= 0.0) { fprintf(stdout,"ERROR: Total duration must be greater than zero.\n"); fflush(stdout); exit(1); } if(factor < number[0] + number[1]) { fprintf(stdout,"ERROR: Total duration too small to divide thus.\n"); fflush(stdout); exit(1); } ro = 't'; break; default: fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } break; case('b'): switch(ro) { case('b'): get_funny_params(2,argc,argv); break; } break; case('C'): switch(ro) { case('a'): case('m'): get_funny_params(3,argc,argv); break; } break; case('c'): switch(ro) { case('s'): get_extra_params(4,argc,argv); cnt = round(number[0]); if(cnt < 2) { fprintf(stdout,"ERROR: Number of output values must be more than 1.\n"); fflush(stdout); exit(1); } if(number[3] < FLTERR) { fprintf(stdout,"ERROR: skew value must be greater than 0 (1.0 == NO skew).\n"); fflush(stdout); exit(1); } break; } break; case('d'): switch(ro) { case('d'): case('L'): get_funny_params(2,argc,argv); break; } break; case('g'): switch(ro) { case('a'): get_funny_params(1,argc,argv); break; } break; case('i'): switch(ro) { case('e'): case('c'): get_extra_params(2,argc,argv); ifactor = round(number[0]); number[0] = number[1]; cnt--; if(ifactor <= 1) { fprintf(stdout,"ERROR: Number of values must be more than 1.\n"); fflush(stdout); exit(1); } break; case('R'): case('Q'): case('C'): get_extra_params(3,argc,argv); ifactor = round(number[0]); number[0] = number[1]; number[1] = number[2]; cnt--; if(ifactor <= 1) { fprintf(stdout,"ERROR: Number of values must be more than 1.\n"); fflush(stdout); exit(1); } break; case('='): get_extra_params(3,argc,argv); factor = number[0]; number[0] = number[1]; number[1] = number[2]; cnt--; range = fabs(number[1] - number[0]); step = fabs(factor); if(step > range) { fprintf(stdout,"ERROR: Range not large enough to accomodate the steps.\n"); fflush(stdout); exit(1); } if(flteq(step,0.0)) { fprintf(stdout,"ERROR: Steps are too small to work with.\n"); fflush(stdout); exit(1); } if(range/step >= 10000.0) { fprintf(stdout,"ERROR: More than 10000 steps: can't handle this.\n"); fflush(stdout); exit(1); } break; default: fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } break; case('L'): if(ro != ENDOFSTR) { fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } get_extra_params(3,argc,argv); factor = (double)round(number[0]); if(factor <= 0.0) { fprintf(stdout,"ERROR: Number of divisions must be greater than zero.\n"); fflush(stdout); exit(1); } number[0] = number[1]; number[1] = number[2]; if(flteq(number[0],number[1])) { fprintf(stdout,"ERROR: The range to divide up is too small.\n"); fflush(stdout); exit(1); } if(number[0] <= 0.0 || number[1] <= 0.0) { fprintf(stdout,"ERROR: The range must be between two positive numbers.\n"); fflush(stdout); exit(1); } cnt--; break; case('K'): tq = 2; if(ro == 'b') tq = 3; if(sscanf(argv[tq],"%d",&ifactor)!=1) { fprintf(stdout,"ERROR: Failed to get number of soundfiles in sequence data.\n"); fflush(stdout); exit(1); } break; case('p'): if (ro == 'p') { get_extra_params(7,argc,argv); break; } break; case('q'): if (ro == 'z') { get_extra_params(4,argc,argv); break; } break; case('Q'): if(ro != ENDOFSTR) { fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } get_extra_params(4,argc,argv); factor = (double)round(number[0]); number[0] = number[1]; number[1] = number[2]; number[2] = number[3]; cnt--; if(flteq(number[0],number[1])) { fprintf(stdout,"ERROR: Parameters 2 and 3 must be different.\n"); fflush(stdout); exit(1); } if(number[2]<=0.0) { fprintf(stdout,"ERROR: Curvature (4th parameter) must be > 0.0.\n"); fflush(stdout); exit(1); } if(factor <= 0.0) { fprintf(stdout,"ERROR: Number of steps cannot be zero\n"); fflush(stdout); exit(1); } break; case('R'): switch(ro) { case('g'): get_extra_params(1,argc,argv); if(round(number[0])<=0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } break; case('G'): get_extra_params(1,argc,argv); if(round(number[0]) <= 0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } if(round(number[1]) <= 1) { fprintf(stdout,"ERROR: Number of consecutive repeats must be 2 or more.\n"); fflush(stdout); exit(1); } break; case('i'): get_extra_params(2,argc,argv); if(round(number[0])<=0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } if(round(number[1])==1) { fprintf(stdout,"ERROR: All numbers will be the same (1).\n"); fflush(stdout); exit(1); } break; case('I'): get_extra_params(3,argc,argv); if(round(number[0])<=0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } if(round(number[1])==1) { fprintf(stdout,"ERROR: All numbers will be the same (1).\n"); fflush(stdout); exit(1); } if(round(number[2])<1) { fprintf(stdout,"ERROR: Number of allowable repetitions must be 1 or more.\n"); fflush(stdout); exit(1); } break; case('r'): get_extra_params(3,argc,argv); if(round(number[0])<=0) { fprintf(stdout,"ERROR: TOtal duratihn must be > 0.\n"); fflush(stdout); exit(1); } if(round(number[1])<1) { fprintf(stdout,"ERROR: Must be more than one number to generate.\n"); fflush(stdout); exit(1); } if(round(number[2])<=0) { fprintf(stdout,"ERROR: Randomisation value must be > 0.\n"); fflush(stdout); exit(1); } if(round(number[2])>round(number[1])) { fprintf(stdout,"ERROR: Randomisation Value cannot be greater than number of values to generate.\n"); fflush(stdout); exit(1); } break; case('c'): case('v'): get_extra_params(3,argc,argv); factor = number[0]; number[0] = number[1]; number[1] = number[2]; cnt--; if(ro == 'v') { if(round(factor) < 1.0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } } else { /* case 'c' */ if (number[0] <= 0.0 || number[1] <= 0.0) { fprintf(stdout,"ERROR: Chunk sizes must all be larger than zero.\n"); fflush(stdout); exit(1); } if (number[1] < number[0]) { number[2] = number[0]; number[0] = number[1]; number[1] = number[2]; } if(factor <= 0.0) { fprintf(stdout,"ERROR: Item to cut must be greater than zero.\n"); fflush(stdout); exit(1); } if(factor < number[0]) { fprintf(stdout,"ERROR: Chunk sizes are too large.\n"); fflush(stdout); exit(1); } if(factor < number[1]) { number[1] = factor; } } break; default: fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } break; case('r'): switch(ro) { case('G'): get_extra_params(3,argc,argv); if(round(number[0]) <= 0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } if((int)round(number[1]) == (int)round(number[2])) { fprintf(stdout,"ERROR: Two numbers to randomise must be different from each other.\n"); fflush(stdout); exit(1); } break; case('J'): get_extra_params(4,argc,argv); if(round(number[0]) <= 0) { fprintf(stdout,"ERROR: Number of items to generate must be 1 or more.\n"); fflush(stdout); exit(1); } if((int)round(number[1]) == (int)round(number[2])) { fprintf(stdout,"ERROR: Two numbers to randomise must be different from each other.\n"); fflush(stdout); exit(1); } break; case('z'): get_extra_params(6,argc,argv); if(round(number[0])<3) { fprintf(stdout,"ERROR: Number of items to generate must be 3 or more.\n"); fflush(stdout); exit(1); } if(round(number[1]) == round(number[2])) { fprintf(stdout,"ERROR: All 'random' numbers will be the same (%d).\n",(int) round(number[1])); fflush(stdout); exit(1); } if(round(number[5])<1) { fprintf(stdout,"ERROR: Number of allowable repetitions must be 1 or more.\n"); fflush(stdout); exit(1); } break; default: fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } break; case('s'): switch(ro) { case('a'): case('b'): case('f'): get_funny_params(2,argc,argv); break; case('s'): get_extra_params(5,argc,argv); if(flteq(number[0],number[1])) { fprintf(stdout,"WARNING: Maximum and minimum vals are equal: no sinusoidal movement.\n"); fflush(stdout); } if(number[3] <= 0.0) { fprintf(stdout,"ERROR: No of periods is <= 0. Cannot proceed\n"); fflush(stdout); exit(1); } if(number[4] <= 2.0) { fprintf(stdout,"ERROR: No of values per period is <= 2. No sinusoid will be produced\n"); fflush(stdout); exit(1); } if (number[3] * number[4] < 1.0) { fprintf(stdout,"ERROR: No of cycles too short to produce any output with this no. of vals per cycle.\n"); fflush(stdout); exit(1); } break; case('c'): case('v'): case('x'): get_extra_params(5,argc,argv); if(flteq(number[0],number[1])) { fprintf(stdout,"ERROR: Maximum and minimum vals are equal: no sinusoidal movement.\n"); fflush(stdout); exit(1); } if(flteq(number[2],number[3])) { fprintf(stdout,"ERROR: Start and end times equal .. no sinusoidal movement.\n"); fflush(stdout); exit(1); } if(number[2] > number[3]) { dur = number[2]; number[2] = number[3]; number[3] = dur; } if(number[2] < 0.0) { fprintf(stdout,"ERROR: Time value less than zero.\n"); fflush(stdout); exit(1); } if (ro == 'c') { if(number[4] <= 3) { fprintf(stdout,"ERROR: No of points < 3. Cannot define sinusoidal motion.\n"); fflush(stdout); exit(1); } } else { if(number[4] <= 5) { fprintf(stdout,"ERROR: No of points < 5. Cannot define cosinusoidal motion.\n"); fflush(stdout); exit(1); } } break; } break; case('S'): switch(ro) { case('M'): get_funny_params(4,argc,argv); break; } break; case('T'): switch(ro) { case('b'): do_string_params(argv,2); break; case('B'): do_string_params(argv,3); break; } break; case('y'): switch(ro) { case('o'): case('p'): case('s'): case('B'): case('E'): case('S'): get_funny_params(1,argc,argv); break; case('e'): case('l'): case('g'): case('I'): case('A'): case('C'): case('x'): get_funny_params(2,argc,argv); break; case('R'): case('a'): case('b'): case('c'): get_funny_params(3,argc,argv); break; case('q'): case('Q'): get_funny_params(4,argc,argv); break; case('P'): get_funny_params(5,argc,argv); break; case('i'): get_funny_params(2,argc,argv); ifactor = (int)round(number[cnt]); factor = number[cnt+1]; if(ifactor < 1 || ifactor > cnt+1) { fprintf(stdout,"ERROR: Position must be within or at end of the column (1 to %d).\n",cnt+1); fflush(stdout); exit(1); } break; case('d'): get_funny_params(2,argc,argv); ifactor = (int)round(number[cnt]); factor = round(number[cnt+1]); if((ifactor < 1) || (factor < 1.0)) { fprintf(stdout,"ERROR: Positions must be 1 or greater.\n"); fflush(stdout); exit(1); } if((ifactor > cnt) && (factor > (double)cnt)) { fprintf(stdout,"ERROR: Positions must be inside the list you are editing.\n"); fflush(stdout); exit(1); } if(((ifactor >= cnt) && (factor <= 1.0)) || ((ifactor == 1) && (factor >= (double)cnt))) { fprintf(stdout,"ERROR: Entire column will be deleted.\n"); fflush(stdout); exit(1); } break; case('r'): get_funny_params(2,argc,argv); ifactor = (int)round(number[cnt]); factor = number[cnt+1]; if(ifactor < 1 || ifactor > cnt) { fprintf(stdout,"ERROR: Position must be within the column (1 to %d).\n",cnt); fflush(stdout); exit(1); } break; } break; case('z'): switch(ro) { case('X'): case('Y'): case('Z'): get_extra_params(3,argc,argv); cnt = round(number[0]); number[0] = number[1]; number[1] = number[2]; break; case('e'): get_extra_params(5,argc,argv); ifactor = round(number[0]); number[0] = number[1]; number[1] = number[2]; number[2] = number[3]; number[3] = number[4]; break; case('A'): case('B'): case('C'): case('D'): case('E'): case('F'): case('G'): case('H'): case('I'): case('J'): get_extra_params(4,argc,argv); cnt = round(number[0]); number[0] = number[1]; number[1] = number[2]; number[2] = number[3]; if(cnt <= 0) { fprintf(stdout,"ERROR: Number of steps cannot be less than 1.\n"); fflush(stdout); exit(1); } break; case('q'): get_extra_params(4,argc,argv); cnt = round(number[0]); number[0] = number[1]; number[1] = number[2]; number[2] = number[3]; if(cnt<=1) { fprintf(stdout,"ERROR: Can't randomise less than 2 elements.\n"); fflush(stdout); exit(1); } quantisation = number[0]; dur = number[1]; scat = number[2]; tq = (int)floor(dur/quantisation) + 1; /* total quantised positions */ ql = (int)ceil(tq/(cnt-1)); /* average number of quanta per placed item */ if(ql <= 1) { fprintf(stdout,"ERROR: Quantisation is too coarse to accomodate all these elements.\n"); fflush(stdout); exit(1); } if(scat <= 1.0) { /* for scatter less than 1 */ ql = (int)round(ql * scat); if(ql <= 1) { fprintf(stdout,"ERROR: Scatter is too small to achieve randomisation of position.\n"); fflush(stdout); exit(1); } } if((cnt+1 > 4) && (number = (double *)realloc((char *)number,(cnt+1) * sizeof(double)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } break; } break; case('Z'): switch(ro) { case('H'): case('m'): get_extra_params(3,argc,argv); break; } break; default: fprintf(stdout,"ERROR: Unknown process mode.\n"); fflush(stdout); exit(1); } } /************************* DO_STRING_PARAMS *************************** * * Reads parameters which are strings * * NB stringscnt will then include count of these parameters, * hence count of any strings values read from file gets remembered as 'cnt'. */ void do_string_params(char *argv[],int pcnt) { int strspace, n, k, nn; int space_step = 200, old_stringstoresize, startstringscnt = stringscnt; char temp2[200], *p; int total_space = space_step; cnt = stringscnt; /* remember count of any existing strings */ if(stringstoresize == 0) { if((stringstore = (char *)exmalloc(total_space))==NULL) { sprintf(errstr,"Out of Memory\n"); do_error(); } } for(n=2,k=0;k= total_space) { while(stringstoresize >= total_space) total_space += space_step; if((stringstore = (char *)exrealloc((char *)stringstore,total_space))==NULL) { sprintf(errstr,"Out of Memory\n"); do_error(); } } strcpy(stringstore + stringstart,temp2); stringstart += strspace; stringscnt++; } if(stringscnt <= cnt) { fprintf(stdout,"ERROR: Invalid or missing data.\n"); fflush(stdout); exit(1); } if(strings == 0) { if((strings = (char **)malloc(stringscnt * sizeof(char *)))==NULL) { sprintf(errstr,"Out of Memory\n"); do_error(); } } else { if((strings = (char **)realloc((char *)strings,stringscnt * sizeof(char *)))==NULL) { sprintf(errstr,"Out of Memory\n"); do_error(); } } p = stringstore; nn = 0; while(nn < startstringscnt) { while(*p != ENDOFSTR) p++; p++; nn++; } while(nn < stringscnt) { strings[nn] = p; while(*p != ENDOFSTR) p++; p++; nn++; } fclose(fp[0]); } /********************************* READ_DATA *********************************/ void read_data(char *startarg,char *endarg,int *ro) { /* READ THE (FIRST) FILE DATA */ if(!strncmp(endarg,"-th",3) || !strncmp(endarg,"-tM",3)) do_pitchtext_infile(startarg); /* PITCH-REPRESENTING TEXTS in file */ else if(!strncmp(endarg,"-As",3) || !strncmp(endarg,"-dl",3) || !strncmp(endarg,"-rr",3) || !strncmp(endarg,"-rR",3) || !strncmp(endarg,"-rX",3) || !strncmp(endarg,"-dv",3) || !strncmp(endarg,"-G",2) || !strncmp(endarg,"-sK",3) || !strncmp(endarg,"-sk",3) || !strncmp(endarg,"-Ro",3) || !strncmp(endarg,"-Ff",3) || !strncmp(endarg,"-FR",3) || !strncmp(endarg,"-Tb",3) || !strncmp(endarg,"-TB",3) || !strncmp(endarg,"-nM",3) || !strcmp(endarg,"-kT") || !strcmp(endarg,"-kX") || !strcmp(endarg,"-kA") || !strcmp(endarg,"-kB") || !strcmp(endarg,"-kC") || !strcmp(endarg,"-kY") || !strncmp(endarg,"-aT",3) || !strncmp(endarg,"-aX",3) || !strncmp(endarg,"-nT",3) || !strncmp(endarg,"-sU",3) || !strncmp(endarg,"-Rx",3) || !strncmp(endarg,"-eb",3) || !strncmp(endarg,"-nF",3)) { do_string_infile(startarg); /* STRINGS in file */ } else if(!strncmp(endarg,"-J",2) || !strncmp(endarg,"-j",2) || !strncmp(endarg,"-jj",3) || !strncmp(endarg,"-Jj",3) || !strncmp(endarg,"-Wb",3) ) { colcnt = do_stringline_infile(startarg,0); /* LINES OF STRINGS in file */ if(!strncmp(endarg,"-Wb",3) && (colcnt != 3)) { fprintf(stdout,"ERROR: THis process only works with sequence files\n"); fflush(stdout); exit(1); } cnt = stringscnt; } else if(!strncmp(endarg,"-DB",3)) do_DB_infile(startarg); /* DB info in file */ else if(!strcmp(endarg,"-c")) *ro = ENDOFSTR; /* COUNT only, option */ else if(!strcmp(endarg,"-cl")) *ro = 'l'; /* COUNT lines, option */ else do_infile(startarg); /* read numeric values */ } /********************************* DO_HELP *********************************/ void do_help(char *str) { if(!strcmp(str,"-f")) help(); if(!strcmp(str,"-m")) helpm(); if(!strcmp(str,"-M")) helpM(); if(!strcmp(str,"-R")) helpr(); if(!strcmp(str,"-l")) helpl(); if(!strcmp(str,"-g")) helpg(); } /********************************* OPTION_TAKES_NO_DATA_BUT_HAS_EXTRA_PARAMS *********************************/ int option_takes_NO_data_but_has_extra_params(char *agv) { if(!strcmp(agv,"-Rg") || !strcmp(agv,"-Rv") || !strcmp(agv,"-Rc") || !strcmp(agv,"-Ri") || !strcmp(agv,"-RI") || !strcmp(agv,"-At") || !strcmp(agv,"-AT") || !strcmp(agv,"-Ad") || !strcmp(agv,"-ic") || !strcmp(agv,"-i=") || !strcmp(agv,"-L") || !strcmp(agv,"-Q") || !strcmp(agv,"-iC") || !strcmp(agv,"-ie") || !strcmp(agv,"-rz") || !strcmp(agv,"-qz") || !strcmp(agv,"-Rr") || !strcmp(agv,"-iR") || !strcmp(agv,"-iQ") || !strcmp(agv,"-cs") || !strcmp(agv,"-ss") || !strcmp(agv,"-sc") || !strcmp(agv,"-sv") || !strcmp(agv,"-sx") || !strncmp(agv,"-Zm",3) || !strncmp(agv,"-ZH",3) || !strncmp(agv,"-z",2) || !strcmp(agv,"-RG") || !strcmp(agv,"-rG") || !strcmp(agv,"-rJ") || !strcmp(agv,"-pp")) return 1; /* all flags starting with 'z', don't read data, but have extra-params */ return 0; } /********************************* OPTION_TAKES_DATA_AND_HAS_EXTRA_PARAMS *********************************/ int option_takes_data_and_has_extra_params(char *agv) { if(!strncmp(agv,"-y",2) /* all flags starting with 'y', read data, and have extra-params */ || !strncmp(agv,"-Tb",3) || !strncmp(agv,"-TB",3) || !strncmp(agv,"-Ca",3) || !strncmp(agv,"-Cm",3) || !strcmp(agv,"-sa") || !strcmp(agv,"-sb") || !strcmp(agv,"-sf") || !strncmp(agv,"-bb",3) || !strcmp(agv,"-dd") || !strcmp(agv,"-dL") || !strcmp(agv,"-SM") || !strcmp(agv,"-ga") || !strncmp(agv,"-K",2)) /* all flags starting with 'K', read data, and have extra-params */ return 1; return 0; } /********************************* CHECK_EXCEPTIONAL_PROCESSES ********************************/ void check_exceptional_processes(int ro,int argc) { if(!sloom && !sloombatch) { if(flag=='H' && (ro==ENDOFSTR || ro=='r') && cnt>1) { fprintf(stderr,"Too many values in file for H"); if(ro=='r') fprintf(stderr,"r"); fprintf(stderr," flag.\n"); exit(1); } if((flag=='J' || (flag=='C' && (ro == ENDOFSTR || ro == 'c'))) && argc<4) { fprintf(stderr,"Flags J & C need at least 2 input files.\n"); exit(1); } if(((flag=='S' && ro==ENDOFSTR) || flag=='N') && argc!=4) { fprintf(stderr,"flags S & N or Nr need 1 infilename & 1 generic outfilename.\n"); exit(1); } } else { if(flag=='H' && (ro==ENDOFSTR || ro=='r') && cnt>1) { fprintf(stdout,"ERROR: Too many values in file this option.\n"); fflush(stdout); exit(1); } if((flag=='J' || flag=='j' || (flag == 'W' && ro == 'b') || (flag=='e' && (ro == 's' || ro == 'i' || ro == 'A' || ro == 'S' || ro == 'w' || ro == 'W' || ro == 'L' || ro == 'Q' || ro == 'X' || ro == 'Y')) || (flag == 'A' && ro == 'e')) && argc<4) { fprintf(stdout,"ERROR: This option needs at least 2 input files.\n"); fflush(stdout); exit(1); } if(((flag=='S' && ro==ENDOFSTR) || flag=='N') && argc!=4) { fprintf(stdout,"ERROR: These options need 1 infilename & 1 generic outfilename.\n"); fflush(stdout); exit(1); } } } /********************************* HANDLE_MULTIFILE_PROCESSES_AND_THE_OUTPUT_FILE ********************************/ void handle_multifile_processes_and_the_output_file(int argc, char flag,int ro,char **argv) { int joico = 0, colcnt2 = 0; if(!sloom) { if(flag=='J') { joico = 1; firstcnt = cnt; infilecnt = argc-2; do_other_stringline_infiles(argv,'J'); } else if(flag=='C' && (ro == ENDOFSTR || ro == 'c')) { joico = 1; firstcnt = cnt; infilecnt = argc-2; do_other_infiles(argv); } else if(flag =='j') { if(ro == 0) { infilecnt = 2; colcnt2 = do_other_stringline_infile(argv[2]); if(colcnt != colcnt2) { fprintf(stdout,"ERROR: Incompatible column counts (%d and %d) in these two files.\n",colcnt,colcnt2); fflush(stdout); exit(1); } } else if(ro =='j') { infilecnt = argc-2; do_other_stringline_infiles(argv,'j'); } } else if(flag =='W' && ro == 'b') { infilecnt = argc-2; do_other_stringline_infiles(argv,'W'); } else if(flag =='K' && ro == 'b') { infilecnt = argc-3; do_other_infiles(argv); } else { if(argc>4 && !joico) { fprintf(stdout,"Too many arguments.\n"); fflush(stdout); exit(1); } if(flag!='S' && flag!='N') { /*RWD*/ if(!strcmp(argv[2],"con") || !strcmp(argv[2],"CON")) fp[1]=stdout; else if(allcols == 1) do_outfile(argv[2]); else strcpy(goalfile,argv[2]); } } } else { if(flag=='A' && ro == 'e') { joico = 1; infilecnt = argc-2; if((file_cnt = (int *)malloc(infilecnt * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } file_cnt[0] = cnt; do_other_infiles(argv); } else if(flag=='J') { joico = 1; firstcnt = cnt; infilecnt = argc-2; do_other_stringline_infiles(argv,'J'); } else if(flag=='C' && (ro == ENDOFSTR || ro == 'c')) { joico = 1; firstcnt = cnt; infilecnt = argc-2; do_other_infiles(argv); } else if(flag =='e' && (ro == 's' || ro == 'i' || ro == 'a' || ro == 'A' || ro == 'S' || ro == 'w' || ro == 'W' || ro == 'L' || ro == 'Q' || ro == 'X' || ro == 'm' || ro =='Y')) { firstcnt = cnt; infilecnt = 2; do_other_infiles(argv); } else if(flag =='w' && (ro == 't' || ro == 'o')) { firstcnt = cnt; infilecnt = 2; do_other_infiles(argv); } else if(flag =='j') { if(ro == 0) { infilecnt = 2; colcnt2 = do_other_stringline_infile(argv[2]); if(colcnt != colcnt2) { fprintf(stdout,"ERROR: Incompatible column counts (%d and %d) in these two files.\n",colcnt,colcnt2); fflush(stdout); exit(1); } } else if(ro =='j') { infilecnt = argc-2; do_other_stringline_infiles(argv,'j'); } } else if(flag =='W' && ro == 'b') { infilecnt = argc-2; do_other_stringline_infiles(argv,'W'); } else if(flag =='K' && ro == 'b') { infilecnt = argc-3; do_other_infiles(argv); } else if(!joico) { if(argc>4) { fprintf(stdout,"ERROR: Too many arguments.\n"); fflush(stdout); exit(1); } if(flag!='S' && flag!='N') { if(allcols == 1) do_outfile(argv[2]); else strcpy(goalfile,argv[2]); } } } } /********************************* ERROR_REPORTING ********************************/ void cant_read_numeric_value(char flag,int ro) { if(!sloom && !sloombatch) fprintf(stderr,"Cannot read numerical value with flag %c%c\n",flag,ro); else { fprintf(stdout,"ERROR: Cannot read numerical value.\n"); fflush(stdout); } exit(1); } void cant_read_numeric_value_with_flag_only(char flag) { if(!sloom && !sloombatch) fprintf(stderr,"Cannot read numerical value with flag %c\n",flag); else { fprintf(stdout,"ERROR: Cannot read numerical value.\n"); fflush(stdout); } exit(1); } void unknown_flag_only(char flag) { if(!sloom && !sloombatch) fprintf(stderr,"Unknown flag -%c\n",flag); else { fprintf(stdout,"ERROR: Unknown option.\n"); fflush(stdout); } exit(1); } void unknown_flag(char flag,int ro) { if(!sloom && !sloombatch) fprintf(stderr,"Unknown flag -%c%c\n",flag,ro); else { fprintf(stdout,"ERROR: Unknown option.\n"); fflush(stdout); } exit(1); } void cannot_read_flags(char *flagstr) { if(!sloom && !sloombatch) fprintf(stderr,"Cannot read flag %s.\n",flagstr); else { fprintf(stdout,"ERROR: Cannot read the option type\n"); fflush(stdout); } exit(1); } void flag_takes_no_params(char flag,int ro) { if(!sloom && !sloombatch) fprintf(stderr,"flag -%c%c does not take a parameter\n",flag,ro); else { fprintf(stdout,"ERROR: This option does not take a parameter\n"); fflush(stdout); } exit(1); } void flag_only_takes_no_params(char flag) { if(!sloom && !sloombatch) fprintf(stderr,"flag -%c does not take a parameter\n",flag); else { fprintf(stdout,"ERROR: This option does not take a parameter\n"); fflush(stdout); } exit(1); } void unknown_flag_or_bad_param(void) { if(!sloom && !sloombatch) fprintf(stderr,"Unknown flag or inappropriate use of parameter.\n"); else { fprintf(stdout,"ERROR: Unknown flag or inappropriate use of parameter.\n"); fflush(stdout); } exit(1); } void no_value_with_flag(char flag,int ro) { if(!sloom && !sloombatch) fprintf(stderr,"No value supplied with flag -%c%c\n",flag,ro); else { fprintf(stdout,"ERROR: No value supplied with this option\n"); fflush(stdout); } exit(1); } void no_value_with_flag_only(char flag) { if(!sloom && !sloombatch) fprintf(stderr,"No value supplied with flag -%c\n",flag); else { fprintf(stdout,"ERROR: No value supplied with this option\n"); fflush(stdout); } exit(1); } void no_value_required_with_flag(char flag,int ro) { if(!sloom && !sloombatch) fprintf(stderr,"No parameter required with flag %c%c.\n",flag,ro); else { fprintf(stdout,"ERROR: No parameter required with this option.\n"); fflush(stdout); } exit(1); } void no_value_required_with_flag_only(char flag) { if(!sloom && !sloombatch) fprintf(stderr,"No parameter required with flag %c\n",flag); else { fprintf(stdout,"ERROR: No parameter required with this option.\n"); fflush(stdout); } exit(1); } void read_flags_data_error(char *str) { if(!sloom && !sloombatch) fprintf(stderr,"%s\n",str); else { fprintf(stdout,"ERROR: %s\n",str); fflush(stdout); } exit(1); } void unknown_flag_string(char *flagstr) { if(!sloom && !sloombatch) fprintf(stderr,"Unknown flag %s.\n",flagstr); else { fprintf(stdout,"ERROR: Unknown option\n"); fflush(stdout); } exit(1); } void do_error(void) { if(!sloom && !sloombatch) fprintf(stderr,"%s\n",errstr); else { fprintf(stdout,"ERROR: %s\n",errstr); fflush(stdout); } exit(1); } void do_valout(double val) { if(!sloom && !sloombatch) { if(allcols > 1) outcoldata[outcoldatacnt++] = val; else fprintf(fp[1],"%lf\n",val); } else fprintf(stdout,"INFO: %lf\n",val); } void do_valout_as_message(double val) { if(!sloom && !sloombatch) fprintf(fp[1],"%lf\n",val); else fprintf(stdout,"WARNING: %lf\n",val); } void do_valout_flush(double val) { if(!sloom && !sloombatch) { if(allcols > 1) outcoldata[outcoldatacnt++] = val; else fprintf(fp[1],"%lf\n",val); } else { fprintf(stdout,"INFO: %lf\n",val); fflush(stdout); } } void do_stringout(char *str) { if(!sloom && !sloombatch) { if(allcols > 1) outcoldata[outcoldatacnt++] = atof(str); else fprintf(fp[1],"%s\n",str); } else fprintf(stdout,"INFO: %s\n",str); } void do_valpair_out(double val0,double val1) { if(!sloom && !sloombatch) fprintf(fp[1],"%lf %lf\n",val0,val1); else fprintf(stdout,"INFO: %lf %lf\n",val0,val1); } /************************* CHECK_FOR_COLUMNEXTRACT ************************/ void check_for_columnextract(char *argv1,int *argc,char *argv[]) { int this_column, linecnt; double dummy; char temp2[200], *p = argv[*argc-1]; if(*p != '-') return; p++; if(*p != '-') return; p++; if(*p != 'c') return; p++; if(sscanf(p,"%d",&thecol)!=1) return; thecol--; strcpy(srcfile,argv1); (*argc)--; if((fp[0] = fopen(argv1,"r"))==NULL) { sprintf(errstr,"Cannot open infile %s\n",argv1); do_error(); } if((fp[2] = fopen("__temp.txt","w"))==NULL) { sprintf(errstr,"Cannot open temporary file (__temp.txt) to store extracted column\n"); do_error(); } this_column = 0; linecnt = 0; while(fgets(temp,200,fp[0])!=NULL) { this_column = 0; p = temp; while(strgetstr(&p,temp2)) { if(this_column == thecol) { if(sscanf(temp2,"%lf",&dummy) != 1) { sprintf(errstr,"Numeric values only for multicolumn data.\n"); do_error(); } fprintf(fp[2],"%s\n",temp2); } this_column++; } if(linecnt == 0) { if(this_column <= thecol) { sprintf(errstr,"There is no column %d in the input data.\n",thecol+1); do_error(); } allcols = this_column; } else if(allcols != this_column) { sprintf(errstr,"Inconsistent number of columns in data.\n"); do_error(); } linecnt++; } fclose(fp[0]); fclose(fp[2]); if((outcoldata = (double *)malloc(linecnt * sizeof(double))) == NULL) { sprintf(errstr,"Failed to allocate memory to store column data.\n"); do_error(); } } /********************************** VALID_CALL_FOR_MULTICOL_INPUT **********************************/ int valid_call_for_multicol_input(char flag,int ro) { switch(flag) { case('A'): if(ro == 's') return 1; if(noro(ro)) return 1; break; case('D'): if(ro == 'B') return 1; break; case('I'): if(ro == 'r') return 1; break; case('M'): if(ro == 'h') return 1; if(ro == 'm') return 1; if(ro == 't') return 1; break; case('P'): if(noro(ro)) return 1; break; case('R'): if(noro(ro)) return 1; if(ro == 'A' || ro == 'a' || ro == 'm' || ro == 'o' || ro == 's') return 1; break; case('S'): if(ro == 'L') return 1; break; case('T'): if(ro == 'c' || ro == 'h' || ro == 'M' || ro == 'l') return 1; break; case('a'): if(noro(ro)) return 1; break; case('b'): if(ro == 'g' || ro == 'l') return 1; break; case('d'): if(noro(ro)) return 1; if(ro == 'b') return 1; break; case('f'): if(ro == 'l') return 1; break; case('h'): if(ro == 'M') return 1; break; case('i'): if(ro == 'L' || ro == 'M' || ro == 'a' || ro == 'h' || ro == 'm' || ro == 'l') return 1; break; case('l'): if(ro == 'i') return 1; break; case('m'): if(noro(ro)) return 1; if(ro == 'M' || ro == 'g' || ro == 'l') return 1; break; case('o'): case('q'): if(noro(ro)) return 1; break; case('r'): if(ro == 'S' || ro == 'm' || ro == 'r') return 1; break; case('s'): if(ro == 'l' || ro == 't') return 1; break; case('t'): if(ro == 'M' || ro == 'h') return 1; break; } return 0; } int noro(int ro) { if(ro == ENDOFSTR || ro == '.' || ro == '-' || isdigit(ro)) return 1; return 0; } void output_multicol_data() { int xcnt; int this_column; char *p, temp2[200]; if(strlen(goalfile) > 0) { if((fp[0] = fopen(srcfile,"r"))==NULL) { sprintf(errstr,"Cannot reopen source file %s\n",srcfile); do_error(); } do_outfile(goalfile); xcnt = 0; while(fgets(temp,200,fp[0])!=NULL) { this_column = 0; p = temp; while(strgetstr(&p,temp2)) { if(this_column == thecol) fprintf(fp[1],"%lf",outcoldata[xcnt++]); else fprintf(fp[1],"%s",temp2); fprintf(fp[1],"\t"); this_column++; } fprintf(fp[1],"\n"); } fclose(fp[0]); fclose(fp[1]); } else { for(xcnt = 0;xcnt < outcoldatacnt;xcnt++) fprintf(stdout,"%lf\n",outcoldata[xcnt]); fflush(stdout); } }