/tzclock-3.0.1/src/ParseZone.c

# · C · 482 lines · 308 code · 41 blank · 133 comment · 74 complexity · fc197844cf345c0e6f2b7ca673817807 MD5 · raw file

  1. /*----------------------------------------------------------------------------------------------------*
  2. * *
  3. * P A R S E Z O N E . C *
  4. * ====================== *
  5. * *
  6. *----------------------------------------------------------------------------------------------------*
  7. * *
  8. * TzClock is free software; you can redistribute it and/or modify it under the terms of the GNU *
  9. * General Public License version 2 as published by the Free Software Foundation. Note that I *
  10. * am not granting permission to redistribute or modify TzClock under the terms of any later *
  11. * version of the General Public License. *
  12. * *
  13. * TzClock is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without *
  14. * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15. * GNU General Public License for more details. *
  16. * *
  17. * You should have received a copy of the GNU General Public License along with this program (in *
  18. * the file "COPYING"); if not, write to the Free Software Foundation, Inc., *
  19. * 59 Temple Place - Suite 330, Boston, MA 02111, USA. *
  20. * *
  21. *----------------------------------------------------------------------------------------------------*/
  22. /**
  23. * @file
  24. * @brief .
  25. * @version $Id: ParseZone.c 1198 2011-06-27 10:22:35Z ukchkn $
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include "TzClockDisp.h"
  32. #include "ParseZone.h"
  33. #include "list.h"
  34. typedef struct _areaInfo
  35. {
  36. char *areaName;
  37. void *cityList;
  38. void *subAreaList;
  39. }
  40. AREAINFO;
  41. int areaCount;
  42. int subAreaCount;
  43. int cityCount;
  44. extern MENU_DESC *timeZoneMenu;
  45. extern TZ_INFO *timeZones;
  46. extern int nTimeZones;
  47. static char timeNames[FIRST_CITY + 3][31] = { "Local Time", "Greenwich Mean Time", "-" };
  48. /*----------------------------------------------------------------------------------------------------*
  49. * *
  50. * G E T A R E A A N D C I T Y *
  51. * ============================== *
  52. * *
  53. *----------------------------------------------------------------------------------------------------*/
  54. /**
  55. * @brief .
  56. * @param inBuffer .
  57. * @param area .
  58. * @param subArea .
  59. * @param city .
  60. * @result .
  61. */
  62. int getAreaAndCity (char *inBuffer, char *area, char *subArea, char *city)
  63. {
  64. int i = 0, j = 0, word = 0;
  65. area[0] = subArea[0] = city[0] = 0;
  66. while (inBuffer[i] && word < 4)
  67. {
  68. if (inBuffer[i] <= ' ')
  69. {
  70. j = 0;
  71. word ++;
  72. }
  73. else
  74. {
  75. if (word == 2)
  76. {
  77. if (inBuffer[i] == '/')
  78. {
  79. j = 0;
  80. word ++;
  81. }
  82. else
  83. {
  84. area [j++] = inBuffer[i];
  85. area [j] = 0;
  86. }
  87. }
  88. else if (word == 3)
  89. {
  90. if (inBuffer[i] == '/')
  91. {
  92. strcpy (subArea, city);
  93. city[j = 0] = 0;
  94. }
  95. else
  96. {
  97. city [j++] = inBuffer[i];
  98. city [j] = 0;
  99. }
  100. }
  101. }
  102. i++;
  103. }
  104. return (area[0] != 0 && city[0] != 0);
  105. }
  106. /*----------------------------------------------------------------------------------------------------*
  107. * *
  108. * F I N D A R E A I N F O *
  109. * ========================= *
  110. * *
  111. *----------------------------------------------------------------------------------------------------*/
  112. /**
  113. * @brief .
  114. * @param areaInfoList .
  115. * @param area .
  116. * @result .
  117. */
  118. AREAINFO *findAreaInfo (void *areaInfoList, char *area)
  119. {
  120. int i = 0;
  121. AREAINFO *retnAreaInfo;
  122. while ((retnAreaInfo = (AREAINFO *)queueRead (areaInfoList, i)) != NULL)
  123. {
  124. if (strcmp (retnAreaInfo -> areaName, area) == 0)
  125. break;
  126. i++;
  127. }
  128. return retnAreaInfo;
  129. }
  130. /*----------------------------------------------------------------------------------------------------*
  131. * *
  132. * T I D Y N A M E *
  133. * ================ *
  134. * *
  135. *----------------------------------------------------------------------------------------------------*/
  136. /**
  137. * @brief .
  138. * @param name .
  139. * @result .
  140. */
  141. char *tidyName (char *name)
  142. {
  143. int i = 0;
  144. char *retnName;
  145. if ((retnName = (char *)malloc (strlen(name) + 1)) != NULL)
  146. {
  147. while (name[i])
  148. {
  149. if (name[i] == '_' || (name[i] >= 0 && name[i] < ' '))
  150. retnName[i] = ' ';
  151. else
  152. retnName[i] = name[i];
  153. retnName[++i] = 0;
  154. }
  155. }
  156. return retnName;
  157. }
  158. /*----------------------------------------------------------------------------------------------------*
  159. * *
  160. * C O M P A R E A R E A *
  161. * ====================== *
  162. * *
  163. *----------------------------------------------------------------------------------------------------*/
  164. /**
  165. * @brief .
  166. * @param item1 .
  167. * @param item2 .
  168. * @result .
  169. */
  170. int compareArea (void *item1, void *item2)
  171. {
  172. AREAINFO *areaInfo1 = (AREAINFO *)item1;
  173. AREAINFO *areaInfo2 = (AREAINFO *)item2;
  174. return (strcmp (areaInfo1 -> areaName, areaInfo2 -> areaName));
  175. }
  176. /*----------------------------------------------------------------------------------------------------*
  177. * *
  178. * C O M P A R E C I T Y *
  179. * ====================== *
  180. * *
  181. *----------------------------------------------------------------------------------------------------*/
  182. /**
  183. * @brief .
  184. * @param item1 .
  185. * @param item2 .
  186. * @result .
  187. */
  188. int compareCity (void *item1, void *item2)
  189. {
  190. return (strcmp ((char *)item1, (char *)item2));
  191. }
  192. /*----------------------------------------------------------------------------------------------------*
  193. * *
  194. * A D D A R E A A N D C I T Y *
  195. * ============================== *
  196. * *
  197. *----------------------------------------------------------------------------------------------------*/
  198. /**
  199. * @brief .
  200. * @param areaInfoList .
  201. * @param area .
  202. * @param subArea .
  203. * @param city .
  204. * @result .
  205. */
  206. int addAreaAndCity (void *areaInfoList, char *area, char *subArea, char *city)
  207. {
  208. AREAINFO *areaInfo = NULL, *subAreaInfo = NULL;
  209. char *tempArea, *tempSubArea, *tempCity;
  210. if ((areaInfo = findAreaInfo (areaInfoList, area)) == NULL)
  211. {
  212. if ((areaInfo = (AREAINFO *)malloc (sizeof (AREAINFO))) == NULL)
  213. {
  214. return 0;
  215. }
  216. if ((tempArea = (char *)malloc (strlen (area) + 1)) == NULL)
  217. {
  218. free (areaInfo);
  219. return 0;
  220. }
  221. strcpy (tempArea, area);
  222. areaInfo -> areaName = tempArea;
  223. areaInfo -> cityList = queueCreate();
  224. areaInfo -> subAreaList = queueCreate();
  225. areaCount ++;
  226. queuePutSort (areaInfoList, areaInfo, compareArea);
  227. }
  228. if (subArea[0])
  229. {
  230. if ((subAreaInfo = findAreaInfo (areaInfo -> subAreaList, subArea)) == NULL)
  231. {
  232. if ((subAreaInfo = (AREAINFO *)malloc (sizeof (AREAINFO))) == NULL)
  233. {
  234. return 0;
  235. }
  236. if ((tempSubArea = (char *)malloc (strlen (subArea) + 1)) == NULL)
  237. {
  238. free (subAreaInfo);
  239. return 0;
  240. }
  241. strcpy (tempSubArea, subArea);
  242. subAreaInfo -> areaName = tempSubArea;
  243. subAreaInfo -> cityList = queueCreate();
  244. subAreaInfo -> subAreaList = NULL;
  245. subAreaCount ++;
  246. queuePutSort (areaInfo -> subAreaList, subAreaInfo, compareArea);
  247. }
  248. }
  249. if ((tempCity = (char *)malloc (strlen (city) + 1)) == NULL)
  250. {
  251. return 0;
  252. }
  253. strcpy (tempCity, city);
  254. cityCount ++;
  255. if (subAreaInfo)
  256. {
  257. queuePutSort (subAreaInfo -> cityList, tempCity, compareCity);
  258. }
  259. else
  260. {
  261. queuePutSort (areaInfo -> cityList, tempCity, compareCity);
  262. }
  263. return 1;
  264. }
  265. /*----------------------------------------------------------------------------------------------------*
  266. * *
  267. * B U I L D A R E A I N F O *
  268. * =========================== *
  269. * *
  270. *----------------------------------------------------------------------------------------------------*/
  271. /**
  272. * @brief .
  273. * @param areaInfoList .
  274. * @param fixedMenuItems .
  275. * @result .
  276. */
  277. int buildAreaInfo (void *areaInfoList)
  278. {
  279. AREAINFO *areaInfo, *subAreaInfo;
  280. int ac = 0, zoneSize, menuSize;
  281. char tempBuff[80], *cityName;
  282. MENU_DESC *menuDesc, *menuSubDesc = NULL, *menuCityDesc = NULL;
  283. TZ_INFO *timeZone;
  284. zoneSize = areaCount + subAreaCount + cityCount + 40;
  285. if ((timeZones = (TZ_INFO *)malloc (sizeof (TZ_INFO) * zoneSize)) == NULL)
  286. {
  287. return 0;
  288. }
  289. memset (timeZones, 0, sizeof (TZ_INFO) * zoneSize);
  290. timeZone = timeZones;
  291. if ((timeZoneMenu = (MENU_DESC *)malloc (sizeof (MENU_DESC) * (areaCount + 4))) == NULL)
  292. {
  293. free (timeZoneMenu);
  294. return 0;
  295. }
  296. memset (timeZoneMenu, 0, sizeof (MENU_DESC) * (areaCount + 4));
  297. menuDesc = timeZoneMenu;
  298. /*------------------------------------------------------------------------------------------------*
  299. * Localtime menu *
  300. *------------------------------------------------------------------------------------------------*/
  301. strcpy (tempBuff, "Local/Time");
  302. if ((timeZone -> envName = (char *)malloc (strlen (tempBuff) + 1)) != NULL)
  303. {
  304. menuDesc -> menuName = timeNames[ac];
  305. menuDesc -> funcCallBack = setTimeZoneCallback;
  306. menuDesc -> param = 0;
  307. ++menuDesc;
  308. menuDesc -> menuName = timeNames[ac + 1];
  309. menuDesc -> subMenuDesc = menuSubDesc = (MENU_DESC *)malloc (sizeof (MENU_DESC) * FIRST_CITY);
  310. memset (menuSubDesc, 0, sizeof (MENU_DESC) * FIRST_CITY);
  311. menuDesc -> param = 0;
  312. ++menuDesc;
  313. menuDesc -> menuName = timeNames[ac + 2];
  314. ++menuDesc;
  315. strcpy (timeZone -> envName, tempBuff);
  316. timeZone -> value = ac++;
  317. ++timeZone;
  318. }
  319. /*------------------------------------------------------------------------------------------------*
  320. * Other GMT options *
  321. *------------------------------------------------------------------------------------------------*/
  322. for (;ac < FIRST_CITY; ac++)
  323. {
  324. if (ac == GMT_ZERO)
  325. {
  326. strcpy (tempBuff, "GMT/GMT");
  327. strcpy (timeNames[ac + 2], "GMT");
  328. }
  329. else
  330. {
  331. sprintf (tempBuff, "GMT/GMT %c %d", ac < GMT_ZERO ? '-' : '+', abs(ac - GMT_ZERO));
  332. sprintf (timeNames[ac + 2], "GMT %c %d", ac < GMT_ZERO ? '-' : '+', abs(ac - GMT_ZERO));
  333. }
  334. if ((timeZone -> envName = (char *)malloc (strlen (tempBuff) + 1)) != NULL)
  335. {
  336. menuSubDesc -> menuName = timeNames[ac + 2];
  337. menuSubDesc -> funcCallBack = setTimeZoneCallback;
  338. menuSubDesc -> param = ac;
  339. strcpy (timeZone -> envName, tempBuff);
  340. timeZone -> value = ac;
  341. ++menuSubDesc;
  342. ++timeZone;
  343. }
  344. }
  345. /*------------------------------------------------------------------------------------------------*
  346. * *
  347. *------------------------------------------------------------------------------------------------*/
  348. while ((areaInfo = (AREAINFO *)queueGet (areaInfoList)) != NULL)
  349. {
  350. menuSize = queueGetItemCount(areaInfo -> subAreaList) + queueGetItemCount(areaInfo -> cityList) + 2;
  351. menuDesc -> menuName = tidyName (areaInfo -> areaName);
  352. menuDesc -> subMenuDesc = menuSubDesc = (MENU_DESC *)malloc (menuSize * sizeof (MENU_DESC));
  353. memset (menuSubDesc, 0, menuSize * sizeof (MENU_DESC));
  354. menuDesc -> param = 0;
  355. ++menuDesc;
  356. while ((subAreaInfo = (AREAINFO *)queueGet (areaInfo -> subAreaList)) != NULL)
  357. {
  358. menuSize = queueGetItemCount(subAreaInfo -> cityList) + 2;
  359. menuSubDesc -> menuName = tidyName (subAreaInfo -> areaName);
  360. menuSubDesc -> subMenuDesc = menuCityDesc = (MENU_DESC *)malloc (menuSize * sizeof (MENU_DESC));
  361. memset (menuCityDesc, 0, menuSize * sizeof (MENU_DESC));
  362. menuSubDesc -> param = 0;
  363. ++menuSubDesc;
  364. while ((cityName = (char *)queueGet (subAreaInfo -> cityList)) != NULL)
  365. {
  366. sprintf (tempBuff, "%s/%s/%s", areaInfo -> areaName, subAreaInfo -> areaName, cityName);
  367. if ((timeZone -> envName = malloc (strlen (tempBuff) + 1)) != NULL)
  368. {
  369. menuCityDesc -> menuName = tidyName (cityName);
  370. menuCityDesc -> funcCallBack = setTimeZoneCallback;
  371. menuCityDesc -> param = ac;
  372. strcpy (timeZone -> envName, tempBuff);
  373. timeZone -> value = ac++;
  374. ++menuCityDesc;
  375. ++timeZone;
  376. }
  377. free (cityName);
  378. }
  379. free (subAreaInfo -> areaName);
  380. free (subAreaInfo);
  381. }
  382. while ((cityName = (char *)queueGet (areaInfo -> cityList)) != NULL)
  383. {
  384. sprintf (tempBuff, "%s/%s", areaInfo -> areaName, cityName);
  385. if ((timeZone -> envName = malloc (strlen (tempBuff) + 1)) != NULL)
  386. {
  387. menuSubDesc -> menuName = tidyName (cityName);
  388. menuSubDesc -> funcCallBack = setTimeZoneCallback;
  389. menuSubDesc -> param = ac;
  390. strcpy (timeZone -> envName, tempBuff);
  391. timeZone -> value = ac++;
  392. ++menuSubDesc;
  393. ++timeZone;
  394. }
  395. free (cityName);
  396. }
  397. free (areaInfo -> areaName);
  398. free (areaInfo);
  399. }
  400. nTimeZones = (timeZone - timeZones);
  401. return nTimeZones;
  402. }
  403. /*----------------------------------------------------------------------------------------------------*
  404. * *
  405. * P A R S E Z O N E *
  406. * ================== *
  407. * *
  408. *----------------------------------------------------------------------------------------------------*/
  409. /**
  410. * @brief .
  411. * @param fixedMenuItems .
  412. * @result .
  413. */
  414. int parseZone (void) // GtkItemFactoryEntry *fixedMenuItems)
  415. {
  416. FILE *inFile;
  417. int retn = 0;
  418. char inBuffer[161], area[41], subArea[41], city[41];
  419. void *areaInfoList;
  420. areaInfoList = queueCreate ();
  421. if ((inFile = fopen ("/usr/share/zoneinfo/zone.tab", "r")) == NULL)
  422. {
  423. inFile = fopen ("/usr/share/lib/zoneinfo/tab/zone_sun.tab", "r");
  424. }
  425. if (inFile != NULL)
  426. {
  427. while (fgets (inBuffer, 160, inFile))
  428. {
  429. if (inBuffer[0] == '#' || inBuffer[0] <= ' ')
  430. continue;
  431. if (getAreaAndCity (inBuffer, area, subArea, city))
  432. {
  433. addAreaAndCity (areaInfoList, area, subArea, city);
  434. }
  435. }
  436. fclose (inFile);
  437. }
  438. retn = buildAreaInfo (areaInfoList);
  439. queueDelete (areaInfoList);
  440. return retn;
  441. }