/* cupper.c by TOYODA Eizi, 2014 - licensed GPLv3 */ #include #include #include #include "cdetac.h" const char * state_s(enum ms_state_t m); long pppfix(int mj, long r) { if (r < 0) { return r; } if ((mj == 'B') || (mj == 'C')) { return r; } else { if (r < 100) { return (1000 + r) * 10; } else { return r * 10; } } } void atoddfff(const char *ddfff, long *dp, long *fp) { long z = tac_atoi(ddfff, 0, 5); if (z < 0) { *dp = *fp = z; } else if ((z / 100) % 10 >= 5) { *dp = z / 1000 * 10 + 5; *fp = z % 500; } else { *dp = z / 100; *fp = z % 1000; } } long hhhfix(long i, long p) { if (i < 0) { return i; } if (p == 10) { return (i < 500) ? (30000 + 10 * i) : (20000 + 10 * i); } else if ((p > 10) && (p < 50)) { return 20000 + 10 * i; } else if (p == 50) { return (i < 500) ? (20000 + 10 * i) : (10000 + 10 * i); } else if ((p > 50) && (p < 225)) { return 10000 + 10 * i; } else if ((p >= 225) && (p < 350)) { return (i < 500) ? (10000 + 10 * i) : (10 * i); } else if ((p >= 350) && (p < 500)) { return 10 * i; } else if ((p >= 500) && (p < 650)) { return (i < 500) ? (4000 + i) : (3000 + i); } else if ((p >= 650) && (p < 750)) { return (i < 500) ? (3000 + i) : (2000 + i); } else if ((p >= 750) && (p < 825)) { return (i < 500) ? (2000 + i) : (1000 + i); } else if ((p >= 825) && (p < 890)) { return 1000 + i; } else if ((p >= 890) && (p < 1000)) { return i; } else if (p == 1000) { return (i < 500) ? i : (500 - i); } else { return 30000 + 10 * i; } } long ttafix(long tta) { if (tta < 0) { return tta; } switch (tta % 10) { case 1: case 3: case 5: case 7: case 9: return -tta; default: return tta; } } long ddfix(long dd) { if (dd < 0) { return dd; } if (dd >= 50) { return (dd * 10 - 50); } else { return dd; } } int ms_upper(struct message_t *ms, enum TokenType tt, const char *token, enum TokenType tt2, const char *token2) { ms_default(ms, tt, token, tt2, token2); /* preemptive token */ switch (tt) { case TTEQ: if (ms->ms_state == MSS_EQ) { fprintf(stdout, "# duplicated TTEQ\n"); } else { /* finalizer */ long qc = ms_get(ms, "Qc", ""); long la, lo, yy; if ((qc == 3) || (qc == 5)) { la = ms_get(ms, "3La", ""); if (la != LONG_MIN) { ms_set(ms, "3La", NULL, -la); } } if ((qc == 5) || (qc == 7)) { lo = ms_get(ms, "4Lo", ""); if (lo != LONG_MIN) { ms_set(ms, "4Lo", NULL, -lo); } } if ((yy = ms_get(ms, "2Y", "")) > 50) { long ff = ms_get(ms, "2f", ""); ms_set(ms, "2f", NULL, knot_to_mps(ff)); ms_set(ms, "2f", NULL, yy - 50); } else { long ff = ms_get(ms, "2f", ""); if (ff != LONG_MIN) { ff *= 10; } ms_set(ms, "2f", NULL, ff); } } ms->ms_state = MSS_EQ; goto endfunc; case TTNIL: ms->ms_state = MSS_Temp102; goto endfunc; } /* state by position */ switch (ms->ms_state) { case MSS_DD: StringCopy(ms->ms_id, token, 8); ms->ms_state = MSS_YYGGi; goto endfunc; case MSS_YYGGi: /* here should be a china hack */ ms_set(ms, "2Y", NULL, tac_atoi(token, 0, 2)); ms_set(ms, "2G", NULL, tac_atoi(token, 2, 2)); if ((ms->ms_mimj[2] == 'B') || (ms->ms_mimj[2] == 'D')) { ms_set(ms, "a4", NULL, tac_atoi(token, 4, 1)); } else { ms_set(ms, "iw", NULL, tac_atoi(token, 4, 1)); } if (ms->ms_mimj[0] == 'T') { ms->ms_state = MSS_IIiii; } else { ms->ms_state = MSS_99LLL; } goto endfunc; break; case MSS_IIiii: StringCopy(ms->ms_id, token, 8); if (ms->ms_mimj[0] == 'T') { if ((ms->ms_mimj[2] == 'B') || (ms->ms_mimj[2] == 'D')) { ms->ms_state = MSS_Temp5ini; } else { ms->ms_state = MSS_Temp2ini; } } else { ms->ms_state = MSS_iihVV; } goto endfunc; break; case MSS_99LLL: ms_set(ms, "3La", NULL, tac_atoi(token, 2, 3)); ms->ms_state = MSS_QLLLL; goto endfunc; break; case MSS_QLLLL: ms_set(ms, "Qc", NULL, tac_atoi(token, 0, 1)); ms_set(ms, "4Lo", NULL, tac_atoi(token, 1, 4)); if (ms->ms_mimj[0] == 'U') { ms->ms_state = MSS_MMMUU; } else { ms->ms_state = MSS_iihVV; } goto endfunc; break; case MSS_MMMUU: ms_set(ms, "3M", NULL, tac_atoi(token, 0, 3)); ms_set(ms, "ULa", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "ULo", NULL, tac_atoi(token, 4, 1)); if ((ms->ms_mimj[2] == 'B') || (ms->ms_mimj[2] == 'D')) { ms->ms_state = MSS_Temp5ini; } else { ms->ms_state = MSS_Temp2ini; } goto endfunc; break; } /* section leader */ if (string_match(token, "21212")) { ms->ms_state = MSS_Temp6ini; goto endfunc; } else if (StringEq(token, "31313")) { /* irregular */ ms->ms_state = MSS_Temp7; goto endfunc; } else if (StringEq(token, "41414")) { ms->ms_state = MSS_Temp8; goto endfunc; } else if (StringEq(token, "51515")) { ms->ms_state = MSS_Temp91; goto endfunc; } else if (StringEq(token, "61616")) { ms->ms_state = MSS_Temp101; goto endfunc; } else if (StringEq(token, "62626")) { ms->ms_state = MSS_Temp102; goto endfunc; } /* main state-dependent parser */ switch (ms->ms_state) { long z, d, f; case MSS_Temp2ini: case MSS_Temp2skip: case MSS_Temp3ini: z = tac_atoi(token, 0, 2); if (z==0) { z = 1000; goto plevel; } else if (z==92) { z = 925; goto plevel; } else if ((z==85)||(z==70)||(z==50)||(z==40)||(z==30) ||(z==25)||(z==20)||(z==15)||(z==10)||(z==7)) { /* will be fixed */ z *= 10; plevel: sprintf(ms->ms_z, "p%04u", (unsigned)z); ms_set(ms, "3h", ms->ms_z, hhhfix(tac_atoi(token, 2, 3), z)); ms->ms_state = MSS_Temp2TTTDD; } else if (z == 99) { StringCopy(ms->ms_z, "SURF", 7); ms_set(ms, "3P", ms->ms_z, pppfix(ms->ms_mimj[2], tac_atoi(token, 2, 3))); ms->ms_state = MSS_Temp2TTTDD; } else { goto unrecognised; } goto endfunc; break; case MSS_Temp2TTTDD: ms_set(ms, "3Ta", ms->ms_z, ttafix(tac_atoi(token, 0, 3))); ms_set(ms, "2D", ms->ms_z, ddfix(tac_atoi(token, 3, 2))); ms->ms_state = MSS_Temp2ddfff; /* will be hack for Id */ goto endfunc; break; case MSS_Temp2ddfff: atoddfff(token, &d, &f); ms_set(ms, "2d", ms->ms_z, d); ms_set(ms, "3f", ms->ms_z, f); ms->ms_state = MSS_Temp2ini; goto endfunc; break; } unrecognised: fprintf(stdout, "# unrecognised (%s) in %s (%.4s)\n", token, state_s(ms->ms_state), ms->ms_cccc); endfunc: # if 0 printf("> %s > %s\n", token, state_s(ms->ms_state)); # endif return 0; } const char * state_s(enum ms_state_t m) { static char buf[32]; #define SRET(s) case s: return #s; break; switch (m) { SRET(MSS_ERR) SRET(MSS_EQ) SRET(MSS_DD) SRET(MSS_YYGGi) SRET(MSS_IIiii) SRET(MSS_99LLL) SRET(MSS_QLLLL) SRET(MSS_MMMUU) SRET(MSS_hhhhi) SRET(MSS_iihVV) SRET(MSS_Nddff) SRET(MSS_Synop1) SRET(MSS_Synop2) SRET(MSS_Synop2ICE) SRET(MSS_Synop3) SRET(MSS_Synop4) SRET(MSS_Synop5) SRET(MSS_YYMMJ) SRET(MSS_GGggi) SRET(MSS_QLLLLLa) SRET(MSS_LLLLLL) SRET(MSS_6QQQ) SRET(MSS_Buoy1) SRET(MSS_Buoy2) SRET(MSS_Buoy3) SRET(MSS_Buoy3TS) SRET(MSS_Buoy3dc1) SRET(MSS_Buoy3dc2) SRET(MSS_Buoy4) SRET(MSS_Buoy4_YYMMJ) SRET(MSS_Buoy4_GGgg_) SRET(MSS_Buoy4_Qc5La) SRET(MSS_Buoy4_6Lo) SRET(MSS_Buoy5) SRET(MSS_Temp2ini) SRET(MSS_Temp2skip) SRET(MSS_Temp3ini) SRET(MSS_Temp5ini) SRET(MSS_Temp6ini) SRET(MSS_Temp7) SRET(MSS_Temp8) SRET(MSS_Temp91) SRET(MSS_Temp101) SRET(MSS_Temp102) SRET(MSS_MetarMain) SRET(MSS_MetarTrend) SRET(MSS_MetarRmk) } #undef SRET sprintf(buf, "MSS%d", (int)m); return buf; }