1 /*------------- Telecommunications & Signal Processing Lab -------------
2                            McGill University
3 
4 Routine:
5   int AOdecFI (struct AO_FIpar *FI)
6 
7 Purpose:
8   Decode input audio file options for audio utilities
9 
10 Description:
11   This routine decodes an option for input audio files.  The routine AOinitOpt
12   must be called first to initialize the option arguments.  If this routine
13   fails to find an input audio file option, the argument pointer is reset to
14   allow another routine to try to decode the option.
15 
16   Options recognized:
17       -t TYPE, --type=TYPE        Input file type
18       -l LIMITS, --limits=LIMITS  Frame limits, e.g., "25:999" or ":" or ...
19       -g GAIN, --gain=GAIN        Gain, e.g. "256" or "1/256"
20       -P PAR, --parameters=PAR    Noheader file parameters
21 
22 Parameters:
23   <-  int AOdecFI
24          -1 - End of arguments/options
25           0 - Option not found
26         >=1 - Option code
27   <-> struct AO_FIpar *FI
28       Input file parameters
29 
30 Author / revision:
31   P. Kabal  Copyright (C) 2003
32   $Revision: 1.11 $  $Date: 2003/05/12 23:51:12 $
33 
34 ----------------------------------------------------------------------*/
35 
36 #include <libtsp.h>
37 #include <libtsp/nucleus.h>
38 #include <AO.h>
39 
40 #define ROUTINE		"AOdecFI"
41 #define PGM		((UTgetProg ())[0] == '\0' ? ROUTINE : UTgetProg ())
42 #define ERRSTOP(text,par)	UThalt ("%s: %s: \"%s\"", PGM, text, par)
43 
44 #define RET_ERROR	-2
45 #define RET_END		-1
46 
47 static const char *OTFI[] = {
48   "-t#", "--t*ype=",
49   "-l#", "--l*imits=",
50   "-g#", "--g*ain=",
51   "-P#", "--p*arameters=",
52   "**",
53   NULL
54 };
55 
56 static int
57 AO_decLrange (const char String[], const long int D[2], long int Lim[2]);
58 
59 
60 int
AOdecFI(struct AO_FIpar * FI)61 AOdecFI (struct AO_FIpar *FI)
62 
63 {
64   const char *OptArg;
65   int n, Sindex;
66   double Nv, Dv;
67   struct AO_CmdArg *Carg;
68   struct AF_opt *AFopt;
69   long int D[2] = {0, AO_LIM_UNDEF};
70 
71   AFopt = AFoptions ();
72 
73   /* Get the argument pointers */
74   Carg = AOArgs ();
75 
76   if (Carg->EndOptions)
77     return 0;
78 
79   /* Decode input file options */
80   Sindex = Carg->Index;
81   n = UTgetOption (&Carg->Index, Carg->Argc, Carg->Argv, OTFI, &OptArg);
82 
83   switch (n) {
84   case RET_END:
85     break;
86   case RET_ERROR:
87     UThalt ("%s: %s", PGM, AOM_BadOption);
88     break;
89   case 1:
90   case 2:
91     /* Type of input file */
92     if (AFsetFileType (OptArg))
93       ERRSTOP (AOM_BadFType, OptArg);
94     FI->Ftype = AFopt->FtypeI;
95     break;
96   case 3:
97   case 4:
98     /* Limits specification */
99     if (AO_decLrange (OptArg, D, FI->Lim)
100 	|| (FI->Lim[1] != AO_LIM_UNDEF && FI->Lim[0] > FI->Lim[1]))
101       ERRSTOP (AOM_BadLimits, OptArg);
102     break;
103   case 5:
104   case 6:
105     /* Gain for input files */
106     if (STdecDfrac (OptArg, &Nv, &Dv))
107       ERRSTOP (AOM_BadGain, OptArg);
108     FI->Gain = Nv / Dv;
109     break;
110   case 7:
111   case 8:
112     /* Headerless input parameters */
113     if (AFsetNHpar (OptArg))
114       ERRSTOP (AOM_BadNHPar, OptArg);
115     FI->NHpar = AFopt->NHpar;
116     break;
117   default:
118     Carg->Index = Sindex;		/* Reset the index */
119     n = 0;
120     break;
121   }
122 
123   return n;
124 }
125 
126 /* Decode a range value, with default values
127    "123:345"	returns (123, 345)
128    "123:"	returns (123, D[1])
129    ":345"	returns (D[0], 345)
130    "123"	returns (D[0], D[0] + 123 - 1)
131 */
132 #define DP_EMPTY		0
133 #define DP_LVAL			1
134 #define DP_DELIM		2
135 #define DP_RVAL			4
136 
137 
138 static int
AO_decLrange(const char String[],const long int D[2],long int Lim[2])139 AO_decLrange (const char String[], const long int D[2], long int Lim[2])
140 
141 {
142   int status;
143   long int L0, L1;
144 
145   /* Decode the range values */
146   status = STdecPair (String, ":", 'L', (void *) (&L0), (void *) (&L1));
147 
148   switch (status) {
149   case (DP_LVAL):
150     Lim[0] = D[0];
151     Lim[1] = D[0] + L0 - 1;
152     break;
153   case (DP_DELIM):
154     Lim[0] = D[0];
155     Lim[1] = D[1];
156     break;
157   case (DP_LVAL + DP_DELIM):
158     Lim[0] = L0;
159     Lim[1] = D[1];
160     break;
161   case (DP_DELIM + DP_RVAL):
162     Lim[0] = D[0];
163     Lim[1] = L1;
164     break;
165   case (DP_LVAL + DP_DELIM + DP_RVAL):
166     Lim[0] = L0;
167     Lim[1] = L1;
168     break;
169   }
170 
171   return (status <= 0);
172 }
173