8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / audio / audioconvert / parse.cc
blobb5901b19f4f276dda97412a6e98be743bae6cfe7
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1993-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <ctype.h>
33 #include <math.h>
35 #include <Audio.h>
36 #include <AudioHdr.h>
38 #include <parse.h>
39 #include <convert.h>
41 static struct keyword_table Keywords[] = {
42 (char *)"encoding", K_ENCODING,
43 (char *)"rate", K_RATE,
44 (char *)"channels", K_CHANNELS,
45 (char *)"offset", K_OFFSET,
46 (char *)"format", K_FORMAT,
47 NULL, K_NULL,
50 // Lookup the string in a keyword table. return the token associated with it.
51 keyword_type
52 do_lookup(
53 char *s,
54 struct keyword_table *kp)
56 struct keyword_table *tkp = NULL;
58 for (; kp && kp->name; kp++) {
59 if (strncmp(s, kp->name, strlen(s)) == 0) {
60 // check if exact match
61 if (strlen(s) == strlen(kp->name)) {
62 return (kp->type);
63 } else {
64 // already have another partial match, so
65 // it's ambiguous
66 if (tkp) {
67 return (K_AMBIG);
68 } else {
69 tkp = kp;
75 // at end of list. if there was a partial match, return it, if
76 // not, there's no match....
77 if (tkp) {
78 return (tkp->type);
79 } else {
80 return (K_NULL);
84 // Parse a file format specification
85 int
86 fileformat_parse(
87 char *val,
88 format_type& format)
90 // XXX - other formats later ...
91 if (strcasecmp(val, "sun") == 0) {
92 format = F_SUN;
93 } else if (strcasecmp(val, "raw") == 0) {
94 format = F_RAW;
95 } else if (strcasecmp(val, "aiff") == 0) {
96 Err(MGET("AIFF not yet supported\n"));
97 return (-1);
98 } else {
99 return (-1);
101 return (0);
104 // Parse an audio format keyword
106 audioformat_parse(
107 char *val,
108 AudioHdr& hdr)
110 // check if it's "cd" or "dat" or "voice".
111 // these set the precision and encoding, etc.
112 if (strcasecmp(val, "dat") == 0) {
113 hdr.sample_rate = 48000;
114 hdr.channels = 2;
115 hdr.encoding = LINEAR;
116 hdr.samples_per_unit = 1;
117 hdr.bytes_per_unit = 2;
118 } else if (strcasecmp(val, "cd") == 0) {
119 hdr.sample_rate = 44100;
120 hdr.channels = 2;
121 hdr.encoding = LINEAR;
122 hdr.samples_per_unit = 1;
123 hdr.bytes_per_unit = 2;
124 } else if (strcasecmp(val, "voice") == 0) {
125 hdr.sample_rate = 8000;
126 hdr.channels = 1;
127 hdr.encoding = ULAW;
128 hdr.samples_per_unit = 1;
129 hdr.bytes_per_unit = 1;
130 } else {
131 return (-1);
133 return (0);
136 // Parse a format spec and return an audio header that describes it.
137 // Format is in the form of: [keyword=]value[,[keyword=]value ...].
139 parse_format(
140 char *s,
141 AudioHdr& hdr,
142 format_type& format,
143 off_t& offset)
145 char *cp;
146 char *buf;
147 char *key;
148 char *val;
149 char *cp2;
151 offset = 0;
152 format = F_SUN;
154 // if no string provided, just return ...
155 if (!(s && *s))
156 return (0);
158 // First off, try to parse it as a full format string
159 // (it would have to have been quoted).
160 // If this works, we're done.
161 if (hdr.FormatParse(s) == AUDIO_SUCCESS) {
162 return (0);
165 buf = strdup(s); // save a copy of the string
167 // XXX - bug alert: if someone has info="xxx,yyy", strtok will
168 // break unless we snarf properly snarf the info. punt for now,
169 // fix later (since no info supported yet)....
171 for (cp = strtok(buf, ","); cp; cp = strtok(NULL, ",")) {
172 // Check if there's a '='
173 // If so, left side is keyword, right side is value.
174 // If not, entire string is value.
175 if (cp2 = strchr(cp, '=')) {
176 *cp2++ = NULL;
177 key = cp;
178 val = cp2;
180 // Look for the keyword
181 switch (do_lookup(key, Keywords)) {
182 case K_ENCODING:
183 if (hdr.EncodingParse(val)) {
184 Err(MGET(
185 "invalid encoding option: %s\n"),
186 val);
187 goto parse_error;
189 break;
190 case K_RATE:
191 if (hdr.RateParse(val)) {
192 Err(MGET("invalid sample rate: %s\n"),
193 val);
194 goto parse_error;
196 break;
197 case K_CHANNELS:
198 if (hdr.ChannelParse(val)) {
199 Err(MGET(
200 "invalid channels option: %s\n"),
201 val);
202 goto parse_error;
204 break;
205 case K_FORMAT:
206 if (fileformat_parse(val, format) < 0) {
207 Err(MGET("unknown format: %s\n"), val);
208 goto parse_error;
210 break;
211 case K_OFFSET:
212 offset = (off_t)atoi(val);
213 break;
214 case K_AMBIG:
215 Err(MGET("ambiguous keyword: %s\n"), key);
216 goto parse_error;
217 case K_NULL:
218 Err(MGET("null keyword: =%s\n"), val);
219 goto parse_error;
220 default:
221 Err(MGET("invalid keyword: %s\n"), key);
222 goto parse_error;
224 } else {
225 // No keyword, so try to intuit the value
226 // First try encoding, audio, and file format.
227 // If they fail, try sample rate and channels.
228 val = cp;
229 if (hdr.EncodingParse(val) &&
230 (audioformat_parse(val, hdr) < 0) &&
231 (fileformat_parse(val, format) < 0)) {
232 // If this looks like sample rate, make sure
233 // it is not ambiguous with channels
234 if (!hdr.RateParse(val)) {
235 if (hdr.sample_rate < 1000) {
236 int x;
237 char y[10];
239 if (sscanf(val, " %lf %9s",
240 &x, y) != 1) {
241 Err(
242 MGET("ambiguous numeric option: %s\n"),
243 val);
244 goto parse_error;
247 } else if (hdr.ChannelParse(val)) {
248 Err(MGET("invalid option value: %s\n"),
249 val);
250 goto parse_error;
255 free(buf);
256 return (0);
258 parse_error:
259 free(buf);
260 return (-1);