Blame view

app/app-prime-modbus/lib/common/strparsing.c 13.2 KB
8c2952457   김태훈   응용 프로그램 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  /**
      @file   strparsing.c
      @date   2009-06-01
      @author 장길석 jwjwmx@gmail.com
      @brief  Ver 0.0.4
              문자열을 분석하여 tstrlist로 생성한다.
      @todo
      @bug
      @remark
      @warning
          - 저작권    에프에이리눅스(주)
          - 외부공개 금지
      @section ModifyInfo 수정 정보
          - 2009-07-06
              -# Doxygen을 위한 주석 수정
          - 2009-06-01
              -# 기본 기능을 추가
  */
  //------------------------------------------------------------------------------
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
  
  #include <tlist.h>
  #include <tstrlist.h>
  #include <strparsing.h>
  
  #define MAX_BUFFSIZE        1024
  #define MAX_IDENTIFY        128
  
  int     strp_error_code;                                                        // 에러코드
  
  static char buff_parse[1024];
  static char buff_identify[1024];
  
  static char *read_string( tstrlist *strplist, char *str_identify)
  //설명: 구별자의 문자열 데이터를 구한다.
  //인수: tstrlist *strplist  : tstrlist 객체 포인터
  //      char *str_identify  : 구별자 문자열
  //반환: 섹션과 구별자의 문자열 데이터
  //주의: 섹션과 구별자가 없다면 NULL을 반환
  //      반환된 문자열 포인터로 메모리 소멸을 해서는 안 된다.
  {
      int     index;
      
      index   = tstrlist_indexof( strplist, str_identify);
      if ( 0 > index) return NULL;
  
      return (char *)tstrlist_get_object( strplist, index);
  }
                                                        
  static char *get_inner( char *str, char branch)
  // 설명: " 또는 ' 으로 묶인 문자열 값을 구한다.
  // 참고: 인용 부호 안에는 공백 문자 이상의 모든 문자를 포함한다.
  // 반환: 인수로 받은 문자열 포인터에서 다음 처리할 문자 위치
  {                   
      char   *pbuff;                                                              // 버퍼 사용을 위한 포인터
      char    ch_data;                                                            // 검색 대상 문자
  
      pbuff   = buff_parse;
      
      while( '\0' != *str)
      {
          ch_data = *str++;
          if ( branch == ch_data)                                                 // 구별자 문자를 만났다면
          {  
              break;                                                              // break
          }
          else
          {
             *pbuff++ = ch_data;                                                  // 문자열 복사
          }
      }
     *pbuff = '\0';                                                               // 데이터 구성 완료
      return str;
  }
  
  static char *get_string( char *str)
  // 설명: 문자열 끝이나 '=' 문자를 만나기 까지 공백없는 문자열을 구한다.
  // 반환: 인수로 받은 문자열 포인터에서 다음 처리할 문자 위치
  {
      char   *pbuff;                                                              // 버퍼 사용을 위한 포인터
      char    ch_data;                                                            // 검색 대상 문자         
  
      pbuff   = buff_parse;
      
      while( '\0' != *str)
      {
          
          ch_data = *str;
          if ( ( ' ' == ch_data) || ( '=' == ch_data))
          {  
              break;
          }
          else
          {
             *pbuff++ = ch_data;
          }
          str++;                                                                  // 이 함수 호출 후에 '='문자가 있는지를 확인해야 하므로, 여기서 포인터 증가
      }
     *pbuff = '\0';
      return str;
  }
  
  static char *get_parse( char *str)
  // 설명: 인수로 받은 문자열을 인용부호와 인용부호가 없는 문자열에 따라 파싱한다.
  // 반환: 인수로 받은 문자열 포인터에서 다음 처리할 문자 위치
  {
      buff_parse[0] = '\0';
  
      while( '\0' != *str)
      {
          switch( *str++)
          {                     
              case '\''   :                                                       // 인용부호 ' 문자 사이의 문자열을 구한다.
              {
                  str = get_inner( str, '\'');
                  return str;
              }
              case '"'    :                                                       // 인용부호 " 문자 사이의 문자열을 구한다.
              {
                  str = get_inner( str, '\"');
                  return str;
              }
              case ' '    :                                                       // 공백이나
              case '='    :                                                       // 분리자 이면 다음 문자를 계속 검색
                      break;
              default     :
              {
                  str = get_string( str-1);                                       // 공백이나 분리자를 만날 때까지의 문자열을 구한다.    
                  return str;
              }
          }
      }
      return str;
  }
  
  static int is_identify( char *str)
  // 설명: 방금 구한 문자열이 구별자인지를 확인한다.
  // 참고: 문자열 뒤에 공백이나 분리자만 있다면 구별자로 인정
  // 반환: 구별자 여부
  {
      while( '\0' != *str)
      {
          switch( *str++)
          {
              case ' '    :   break;                                              // 공백 문자이면 다음 문자를 계속 검색
              case '='    :   return 1;                                           // '=' 문자가 있으면 OK
              default     :   return 0;                                           // 공백이나 '=' 문자가 아니면 FALSE
          }
      }        
      return 0;
  }
  
  static void parse_string( tstrlist *lst_parse, char *str)
  // 설명: 구별자와 구별자에 대한 데이터를 구한다.
  // 반환: 구별자 개수
  {
      char   *pdata;
      
      while ( '\0' != *str)
      {
          str = get_parse( str);
          if ( '\0' == buff_parse[0])
          {
              break;
          }
          if ( !is_identify( str))
          {
              continue;
          }
          memcpy( buff_identify, buff_parse, strlen( buff_parse)+1);              // NULL까지 포함하기 위해 +1
          
          str     = get_parse( str);
          pdata   = ( char *)malloc( strlen( buff_parse)+1);
          if ( NULL == pdata)
          {         
              strp_error_code = STRPERR_OUT_OF_MEMORY;
              break;
          }
          else
          {
              memcpy( pdata, buff_parse, strlen( buff_parse)+1);                  // NULL까지 포함하기 위해 +1
              tstrlist_add_object( lst_parse, buff_identify, pdata);
          }            
      }
  }
  
  int strp_read_bool( tstrlist *strplist, char *str_identify, int default_value)
  /**
      @brief  구별자가 지정하는 Boolean 데이터를 구한다.
      @param  strplist : 파싱 자료를 가지고 있는 tstlist
      @param  str_identify : 구별자 문자열
      @param  default_value : 값이 없다면 대신 반환될 기본값
      @warning    구별자의 문자열이 0 이면 FALSE로 반환하며
  
                  이외는 무조건 TRUE로 반환한다.
  
                  즉, 구별자가 가지고 있는 문자열 정보가
  
                  '0' 인지 아닌지의 여부를 반환한다.
  */
  {
      char   *data;
      int     int_data;
  
      data    = read_string( strplist, str_identify);                             // 먼저 구별자로 데이터를 구한다.    
      if      ( NULL == data)                             return default_value;   // 찾는 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == strlen( data) )                      return default_value;   // 문자열 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == sscanf( data, "%d", &int_data))      return default_value;   // 정수로 변환된 값이 없다면 기본값을 반환
      else                                                return 0 != int_data;   // 정수 값이 0이면 FALSE로 반환한다.
  }
  
  double strp_read_real( tstrlist *strplist, char *str_identify, double default_value)
  /**
      @brief  구별자가 지정하는 정수 데이터를 구한다.
      @param  strplist : 파싱 자료를 가지고 있는 tstlist
      @param  str_identify : 구별자 문자열
      @param  default_value : 값이 없다면 대신 반환될 기본값
      @return
              - 구별자에 해당하는 실수 값
              - 저정한 섹션이나 구별자에 대한 실수 값이 없다면 기본값을 반환
  */
  {
      char       *data;
      double      float_data;
  
  
      data    = read_string( strplist, str_identify);                             // 먼저 구별자로 데이터를 구한다.    
      if      ( NULL == data)                             return default_value;   // 찾는 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == strlen( data) )                      return default_value;   // 문자열 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == sscanf( data, "%lf", &float_data))   return default_value;   // 실수로 변환된 값이 없다면 기본값을 반환
      else                                                return float_data;      // 실수 값을 반환한다.
  }
  
  int strp_read_integer( tstrlist *strplist, char *str_identify, int default_value)
  /**
      @brief  구별자가 지정하는 정수 데이터를 구한다.
      @param  strplist : 파싱 자료를 가지고 있는 tstlist
      @param  str_identify : 구별자 문자열
      @param  default_value : 값이 없다면 대신 반환될 기본값
      @return
              - 구별자에 해당하는 정수 값
              - 저정한 섹션이나 구별자에 대한 정수 값이 없다면 기본값을 반환
  */
  {
      char   *data;
      int     int_data;
  
      data    = read_string( strplist, str_identify);                             // 먼저 구별자로 데이터를 구한다.    
      if      ( NULL == data)                             return default_value;   // 찾아진 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == strlen( data) )                      return default_value;   // 문자열 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == sscanf( data, "%d", &int_data))      return default_value;   // 정수로 변환된 값이 없다면 기본값을 반환
      else                                                return int_data;        // 정수값을 반환한다.
  }
  
  char *strp_read_string( tstrlist *strplist, char *str_identify, char *default_value)
  /**
      @brief  섹션과 구별자가 지정하는 문자열 데이터를 구한다.
      @param  strplist : 파싱 자료를 가지고 있는 tstlist
      @param  str_identify : 구별자 문자열
      @param  default_value : 값이 없다면 대신 반환될 기본값
      @return
  
          구별자의 문자열 정보
  
          저정한 섹션이나 구별자에 대한 문자열이 없다면 기본값을 반환
      @warning 절대 반환 받은 문자열을 소멸 시켜서는 안 된다!!
  */
  {
      char    *data;
  
      data    = read_string( strplist, str_identify);                             // 먼저 구별자로 데이터를 구한다.    
      if ( NULL == data)                                  return default_value;   // 찾아진 데이터가 없다면 기본값을 반환한다.
      else if ( 0 == strlen( data) )                      return default_value;   // 문자열 데이터가 없다면 기본값을 반환한다.
      else                                                return data;
  }
  
  char  *strp_error_string( void)
  /**
      @brief  strp_error_code에 대한 에러 설명 문자열을 반환
      @return 에러 코드에 대한 에러 설명 문자열 포인터
      @warning 절대 반환 받은 문자열을 소멸 시켜서는 안 된다!!
  */
  {
     char *error_string[] ={ "에러 없음",                                         //  INIERR_NONE
                             "메모리 부족",                                       //  INIERR_OUT_OF_MEMORY
                             "파일 이름 지정 오류",                               //  INIERR_FILENAME_FAIL
                             "자료 없음",                                         //  INIERR_NO_DATA
                             "IniFile 없음",                                      //  INIERR_NO_FILE
                             "IniFile을 읽을 수 없음",                            //  INIERR_ACCESS_FAIL
                             "섹션 리스트 생성 실패",                             //  INIERR_CREATE_SECTION_FAIL
                             "구별자 생성 실패",                                  //  INIERR_CREATE_IDENTIFY_FAIL
                             "인수의 객체가 NULL"                                 //  INIERR_NULL_POINTER
                          };
     return( error_string[strp_error_code]);
  }
  
  int strp_print_error( char *remark)
  /**
      @brief  ini_error_code에 대한 에러 설명 문자열을 화면에 출력
      @param  remark : 에러 설명 문자열 끝에 첨부하여 출력할 문자열
      @return
  
          에러 코드
  */
  {
     printf( "[str parsing error:%d]%s %s
  ", strp_error_code, strp_error_string(), remark);
     return strp_error_code;
  }
  
  void strp_free( tstrlist *strplist)
  /**
      @brief  strparsing 객체를 소멸한다.
      @param  strplist : strparsing 객체
  */
  {
      int     ndx;
      char   *pdata;
      
      for ( ndx = 0; ndx < tstrlist_getcount( strplist); ndx++)
      {
          pdata   = ( char *)tstrlist_get_object( strplist, ndx);                 // 객체로 등록한 문자열 제거
          free( pdata);
      }
      tstrlist_free( strplist);                                                   // 리스트 소멸
  }
  tstrlist *strp_parsing( char *data)
  /**
      @brief  data 문자열을 분석해서 구별자와 데이터로 구성된 아이템 목록을 만든다.
  
      @param  data : 문자열 데이터
      @return
  
          구별자와 데이터로 구성된 아이템의 tstrlist *
  
          읽기에 실패했다면 NULL을 반환
  */
  {
      tstrlist   *lst_parse;
  
      strp_error_code  = STRPERR_NONE;                                            //  에러코드: 에러 없음
  
      lst_parse = tstrlist_create();                                              //  tstrlist 객체 생성
      if ( NULL == lst_parse)                                                     //  tstrlist 객체를 생성하지 못했다면
      {
          strp_error_code  = STRPERR_CREATE_LIST_FAIL;                            //  에러코드: 루트 섹션 리스트 생성
          return  NULL;
      }
      parse_string( lst_parse, data);
      return lst_parse;
  }