OSDN Git Service

691034fed610a43e29f3cfdbd258b3f1f82eaa5e
[kozos-expbrd/kozos_expbrd.git] / firm / sample / simple_mp3_player / os / ntopt.c
1 /**
2  * @file ntopt.c
3  * @author Shinichiro Nakamura
4  * @brief NT-Shell用オプション解析モジュールの実装。
5  */
6
7 /*
8  * ===============================================================
9  *  Natural Tiny Shell (NT-Shell)
10  *  Version 0.0.8
11  * ===============================================================
12  * Copyright (c) 2010-2011 Shinichiro Nakamura
13  *
14  * Permission is hereby granted, free of charge, to any person
15  * obtaining a copy of this software and associated documentation
16  * files (the "Software"), to deal in the Software without
17  * restriction, including without limitation the rights to use,
18  * copy, modify, merge, publish, distribute, sublicense, and/or
19  * sell copies of the Software, and to permit persons to whom the
20  * Software is furnished to do so, subject to the following
21  * conditions:
22  *
23  * The above copyright notice and this permission notice shall be
24  * included in all copies or substantial portions of the Software.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
28  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
30  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
31  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33  * OTHER DEALINGS IN THE SOFTWARE.
34  * ===============================================================
35  */
36
37 #include "ntopt.h"
38
39 /**
40  * @brief 与えられた文字がデリミタであるかどうかを判定する。
41  * @param c 文字。
42  * @retval true デリミタである。
43  * @retval false デリミタでない。
44  */
45 #define IS_DELIM(c) \
46     (((c) == '\r') || ((c) == '\n') || ((c) == '\t') || ((c) == '\0') || ((c) == ' '))
47
48 static int ntopt_get_count(const char *str);
49 static char *ntopt_get_text(
50         const char *str, const int n, char *buf, int siz, int *len);
51
52 /**
53  * @brief 与えられた文字列のセンテンス数を取得する。
54  * @param str 文字列。
55  * @return センテンス数。
56  */
57 static int ntopt_get_count(const char *str)
58 {
59     int cnt = 0;
60     int wc = 0;
61     char *p = (char *)str;
62     while (*p) {
63         if (!IS_DELIM(*p)) {
64             wc++;
65             if (wc == 1) {
66                 cnt++;
67             }
68         } else {
69             wc = 0;
70         }
71         p++;
72     }
73     return cnt;
74 }
75
76 /**
77  * @brief 与えられた文字列のセンテンスを取得する。
78  * @param str 文字列。
79  * @param n センテンス。(0からntopt-get_count(str) - 1までの値。)
80  * @param buf 格納バッファ。
81  * @param siz 格納バッファのサイズ。
82  * @param len 格納した文字列のサイズ。
83  * @retval !NULL 取得成功。格納バッファへのポインタ。
84  * @retval NULL 取得失敗。
85  */
86 static char *ntopt_get_text(
87         const char *str, const int n, char *buf, int siz, int *len)
88 {
89     int cnt = 0;
90     int wc = 0;
91     char *p = (char *)str;
92     *len = 0;
93     while (*p) {
94         if (!IS_DELIM(*p)) {
95             wc++;
96             if ((wc == 1)) {
97                 if (cnt == n) {
98                     char *des = buf;
99                     int cc = 0;
100                     while (!IS_DELIM(*p)) {
101                         cc++;
102                         if (siz <= cc) {
103                             break;
104                         }
105                         *des = *p;
106                         des++;
107                         p++;
108                     }
109                     *des = '\0';
110                     *len = cc;
111                     return buf;
112                 }
113                 cnt++;
114             }
115         } else {
116             wc = 0;
117         }
118         p++;
119     }
120     return '\0';
121 }
122
123 /**
124  * @brief 与えられた文字列をデリミタで分割する。
125  * @param str 文字列。
126  * @param func コールバック関数。
127  * @param extobj 拡張オブジェクト。
128  * @return コールバック関数が返した値。
129  */
130 int ntopt_parse(
131         const char *str,
132         int (*func)(int argc, char **argv, void *extobj),
133         void *extobj)
134 {
135     int argc;
136     char argv[NTOPT_TEXT_MAXLEN];
137     char *argvp[NTOPT_TEXT_MAXARGS];
138     int i;
139     int total;
140     char *p;
141
142     argc = ntopt_get_count(str);
143     if (NTOPT_TEXT_MAXARGS <= argc) {
144         argc = NTOPT_TEXT_MAXARGS;
145     }
146
147     total = 0;
148     p = &argv[0];
149     for (i = 0; i < argc; i++) {
150         int len;
151         argvp[i] = ntopt_get_text(
152                 str, i, p, NTOPT_TEXT_MAXLEN - total, &len);
153         if (total + len + 1 < NTOPT_TEXT_MAXLEN) {
154             p += len + 1;
155             total += len + 1;
156         } else {
157             break;
158         }
159     }
160
161     return func(argc, &argvp[0], extobj);
162 }
163