rescan.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: rescan.c /main/1 1996/04/21 19:24:17 drk $ */
  24. /*
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company
  26. * (c) Copyright 1993, 1994 International Business Machines Corp.
  27. * (c) Copyright 1993, 1994 Novell, Inc.
  28. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  29. */
  30. #include <EUSCompat.h>
  31. #include <stdio.h>
  32. #include <ctype.h>
  33. #include <string.h>
  34. #include <errno.h>
  35. #include <time.h>
  36. #include "rerule.h"
  37. #include "reparser.h"
  38. #define EOL 0
  39. #define ENDMARKERSYMBOL '$'
  40. #define DURATIONSYMBOL '#'
  41. #define FRONTWEEKSYMBOL '+'
  42. #define REARWEEKSYMBOL '-'
  43. #define MINUTESYMBOL 'M'
  44. #define DAILYSYMBOL 'D'
  45. #define WEEKLYSYMBOL 'W'
  46. #define LASTDAYSYMBOL "LD"
  47. #define MONTHPOSSYMBOL "MP"
  48. #define MONTHDAYSYMBOL "MD"
  49. #define YEARDAYSYMBOL "YD"
  50. #define YEARMONTHSYMBOL "YM"
  51. #define SUNSYMBOL "SU"
  52. #define MONSYMBOL "MO"
  53. #define TUESYMBOL "TU"
  54. #define WEDSYMBOL "WE"
  55. #define THUSYMBOL "TH"
  56. #define FRISYMBOL "FR"
  57. #define SATSYMBOL "SA"
  58. int _DtCm_yylex(void);
  59. static int scanbuf(char **inbuf, char *, int *);
  60. /* The rule that needs to be parsed is passed to yylex() through this var */
  61. char *_DtCm_rule_buf;
  62. char _DtCm_yytext[128];
  63. int
  64. _DtCm_yylex(void)
  65. {
  66. int token = 0;
  67. int yylen = 128;
  68. _DtCm_yylval.number = 0;
  69. token = scanbuf(&_DtCm_rule_buf, _DtCm_yytext, &yylen);
  70. if (token == NUMBER)
  71. sscanf(_DtCm_yytext, "%d", &_DtCm_yylval.number);
  72. if (token == DATE)
  73. strcpy(_DtCm_yylval.date, _DtCm_yytext);
  74. return (token);
  75. }
  76. static int
  77. scanbuf(
  78. char **buf,
  79. char *yytext,
  80. int *yylen)
  81. {
  82. int token = 0;
  83. int state = 0;
  84. char c = '\0';
  85. char lastchar = '\0';
  86. char *yystart = yytext;
  87. memset(yytext, '\0', *yylen);
  88. yytext[*yylen - 1] = '\0';
  89. (*yylen)--; /* Leave room for trailing '\0' */
  90. while (token == 0) {
  91. lastchar = c;
  92. c = *(*buf)++;
  93. if (*yylen > 0) {
  94. *yytext++ = c;
  95. (*yylen)--;
  96. }
  97. switch (state) {
  98. /* State 0 */
  99. case 0:
  100. if (isspace(c)) {
  101. /* Keep whitespace out of text */
  102. yytext--;
  103. (*yylen)++;
  104. /* State remains 0 */
  105. } else if (isdigit(c)) {
  106. if (**buf == '+' || **buf == '-') /* 1+ or 2- */
  107. state = 3;
  108. else
  109. state = 1;
  110. } else if (isalpha(c)) {
  111. if (isalpha(**buf))
  112. state = 2;
  113. else
  114. state = 4;
  115. } else if (c == ENDMARKERSYMBOL) {
  116. return(ENDMARKER);
  117. } else if (c == DURATIONSYMBOL) {
  118. return(DURATION);
  119. } else if (c == '\0') {
  120. return(EOL);
  121. } else
  122. return(ERROR);
  123. break;
  124. case 1:
  125. /* Get number */
  126. if (isdigit(c)) {
  127. /* Stay in state 1 and get rest of number */
  128. ;
  129. } else if (isspace(c) || c == '\0') {
  130. /* Hit a delimiter. Put it back into the
  131. * input buffer and keep it out of the token
  132. * text.
  133. */
  134. (*buf)--;
  135. yytext--; (*yylen)++;
  136. *yytext = '\0';
  137. return(NUMBER);
  138. } else
  139. state = 5;
  140. break;
  141. case 2:
  142. /* Get a command or weekday */
  143. if (strcmp(yystart, MONTHPOSSYMBOL) == 0) {
  144. return(MONTHPOSCOMMAND);
  145. } else if (strcmp(yystart, MONTHDAYSYMBOL) == 0) {
  146. return(MONTHDAYCOMMAND);
  147. } else if (strcmp(yystart, YEARDAYSYMBOL) == 0) {
  148. return(YEARDAYCOMMAND);
  149. } else if (strcmp(yystart, YEARMONTHSYMBOL) == 0) {
  150. return(YEARMONTHCOMMAND);
  151. } else if (strcmp(yystart, LASTDAYSYMBOL) == 0) {
  152. return(LASTDAY);
  153. } else if (strcmp(yystart, SUNSYMBOL) == 0) {
  154. return(SUNDAY);
  155. } else if (strcmp(yystart, MONSYMBOL) == 0) {
  156. return(MONDAY);
  157. } else if (strcmp(yystart, TUESYMBOL) == 0) {
  158. return(TUESDAY);
  159. } else if (strcmp(yystart, WEDSYMBOL) == 0) {
  160. return(WEDNESDAY);
  161. } else if (strcmp(yystart, THUSYMBOL) == 0) {
  162. return(THURSDAY);
  163. } else if (strcmp(yystart, FRISYMBOL) == 0) {
  164. return(FRIDAY);
  165. } else if (strcmp(yystart, SATSYMBOL) == 0) {
  166. return(SATURDAY);
  167. } else
  168. return(ERROR);
  169. case 3:
  170. /* Get a weeknumber */
  171. if (c == FRONTWEEKSYMBOL) {
  172. int num = lastchar - '0';
  173. switch (num) {
  174. case 1:
  175. return(FIRSTWEEK);
  176. case 2:
  177. return(SECONDWEEK);
  178. case 3:
  179. return(THIRDWEEK);
  180. case 4:
  181. return(FOURTHWEEK);
  182. case 5:
  183. return(FIFTHWEEK);
  184. default:
  185. return(ERROR);
  186. }
  187. } else if (c == REARWEEKSYMBOL) {
  188. int num = lastchar - '0';
  189. switch (num) {
  190. case 1:
  191. return(LASTWEEK);
  192. case 2:
  193. return(SECONDLAST);
  194. case 3:
  195. return(THIRDLAST);
  196. case 4:
  197. return(FOURTHLAST);
  198. case 5:
  199. return(FIFTHLAST);
  200. default:
  201. return(ERROR);
  202. }
  203. }
  204. case 4:
  205. /* Found a single letter...probably a command */
  206. /* We expect an interval to follow a command */
  207. if (isdigit(c) == 0) return(ERROR);
  208. /* Backup to before digit */
  209. (*buf)--;
  210. yytext--; (*yylen)++;
  211. *yytext = '\0';
  212. switch (lastchar) {
  213. case DAILYSYMBOL:
  214. return(DAILYCOMMAND);
  215. case MINUTESYMBOL:
  216. return(MINUTECOMMAND);
  217. case WEEKLYSYMBOL:
  218. return(WEEKLYCOMMAND);
  219. default:
  220. return(ERROR);
  221. }
  222. case 5:
  223. /* Reading an ISO 8601 date */
  224. if (isspace(c) || c == '\0') {
  225. /* Hit a delimiter. Put it back into the
  226. * input buffer and keep it out of the token
  227. * text.
  228. */
  229. (*buf)--;
  230. yytext--; (*yylen)++;
  231. *yytext = '\0';
  232. return(DATE);
  233. }
  234. break;
  235. }
  236. }
  237. /* Should never get to */
  238. return (ERROR);
  239. }