/* csurf.c by TOYODA Eizi, 2014 - licensed GPLv3 */ #include #include #include #include "cdetac.h" long tac_tR(int c) { switch (c) { case '1': return 6; case '2': return 12; case '3': return 18; case '4': return 24; case '5': return 1; case '6': return 2; case '7': return 3; case '8': return 9; case '9': return 15; case '/': return 24; default: return LONG_MIN; } } int ms_surf(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; 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 (ms_get(ms, "iw", "") > 2) { long ff = ms_get(ms, "2f", ""); ms_set(ms, "2f", NULL, knot_to_mps(ff)); } 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_Synop5; goto endfunc; } if (StringEq(token, "555")) { ms->ms_state = MSS_Synop5; goto endfunc; } /* state by position */ switch (ms->ms_state) { case MSS_DD: if (string_match(token, "[0-3][0-9][012][0-9][0134/]") && string_match(token2, "99%")) { StringCopy(ms->ms_id, "SHIP", 4); } else { StringCopy(ms->ms_id, token, 8); ms->ms_state = MSS_YYGGi; goto endfunc; } /* fall through */ case MSS_YYGGi: ms_set(ms, "2Y", NULL, tac_atoi(token, 0, 2)); ms_set(ms, "2G", NULL, tac_atoi(token, 2, 2)); ms_set(ms, "iw", NULL, tac_atoi(token, 4, 1)); if (StringEq(ms->ms_mimj, "AAXX")) { ms->ms_state = MSS_IIiii; } else { ms->ms_state = MSS_99LLL; } goto endfunc; break; case MSS_IIiii: StringCopy(ms->ms_id, token, 8); 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 (StringEq(ms->ms_mimj, "OOXX")) { 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)); ms->ms_state = MSS_hhhhi; goto endfunc; break; case MSS_hhhhi: ms_set(ms, "4h0", NULL, tac_atoi(token, 0, 4)); ms_set(ms, "im", NULL, tac_atoi(token, 4, 1)); ms->ms_state = MSS_iihVV; goto endfunc; break; case MSS_iihVV: ms_set(ms, "iR", NULL, tac_atoi(token, 0, 1)); ms_set(ms, "ix", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "h", NULL, tac_atoi(token, 2, 1)); ms_set(ms, "2V", NULL, tac_atoi(token, 3, 2)); ms->ms_state = MSS_Nddff; goto endfunc; break; case MSS_Nddff: ms_set(ms, "N", NULL, tac_atoi(token, 0, 1)); ms_set(ms, "2d", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2f", NULL, tac_atoi(token, 3, 2)); ms->ms_state = MSS_Synop1; goto endfunc; break; } /* section leader */ if (string_match(token, "222[0-9/][0-9/]")) { ms->ms_state = MSS_Synop2; goto endfunc; } else if (StringEq(token, "222")) { /* irregular */ ms->ms_state = MSS_Synop2; goto endfunc; } else if (StringEq(token, "333")) { ms->ms_state = MSS_Synop3; goto endfunc; } else if (StringEq(token, "444")) { ms->ms_state = MSS_Synop4; goto endfunc; } else if (StringEq(token, "55")) { /* irregular */ ms->ms_state = MSS_Synop5; goto endfunc; } /* main state-dependent parser */ switch (ms->ms_state) { case MSS_Synop1: if (string_match(token, "00%")) { ms_set(ms, "2f", NULL, tac_atoi(token, 2, 3)); } else if (token[0] == '1') { ms_set(ms, "3T", NULL, tac_atosi(token, token[1], 2, 3)); } else if (string_match(token, "29%")) { ms_set(ms, "3U", NULL, tac_atoi(token, 2, 3)); } else if (token[0] == '2') { ms_set(ms, "3Td", NULL, tac_atosi(token, token[1], 2, 3)); } else if (token[0] == '3') { long v = tac_atoi(token, 1, 4); if ((v >= 0L) && (v < 800L)) { v += 10000L; } else if ((v >= 800L) && (v < 900L)) { v += 9000L; } ms_set(ms, "4P0", NULL, v); } else if (string_match(token, "4[09/]%")) { long v = tac_atoi(token, 1, 4); if ((v >= 0L) && (v < 800L)) { v += 10000L; } else if ((v >= 800L) && (v < 900L)) { v += 9000L; } ms_set(ms, "4P", NULL, v); } else if (string_match(token, "4[12578]%")) { long a3 = tac_atoi(token, 1, 1); ms_set(ms, "a3", NULL, a3); long hhh = tac_atoi(token, 2, 3); switch (a3) { case 1L: ms_set(ms, "3h", "p1000", hhh); break; case 2L: ms_set(ms, "3h", "p0925", hhh); break; case 5L: ms_set(ms, "3h", "p0500", 5000L + hhh); break; case 7L: ms_set(ms, "3h", "p0700", (hhh < 500L) ? (3000L + hhh) : (2000L + hhh)); break; case 8L: ms_set(ms, "3h", "p0850", 1000L + hhh); break; } } else if (token[0] == '5') { long ppp = tac_atoi(token, 2, 3); ms_set(ms, "a", NULL, tac_atoi(token, 1, 1)); if (string_match(token, "5[5-8]%") && (ppp != LONG_MIN)) { ppp = -ppp; } ms_set(ms, "3p", NULL, ppp); } else if (token[0] == '6') { long rrr = tac_atoi(token, 1, 3); long t = tac_tR(token[4]); if (rrr >= 990L) { rrr -= 990L; } else { rrr *= 10L; } ms_set(ms, "3R", NULL, rrr); ms_set(ms, "tR", NULL, t); } else if (token[0] == '7') { ms_set(ms, "2w", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "W1", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "W2", NULL, tac_atoi(token, 4, 1)); } else if (token[0] == '8') { ms_set(ms, "Nh", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "CL", NULL, tac_atoi(token, 2, 1)); ms_set(ms, "CM", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "CH", NULL, tac_atoi(token, 4, 1)); } else if (token[0] == '9') { ms_set(ms, "GG/1", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "gg/1", NULL, tac_atoi(token, 3, 2)); } else if (StringEq(token, "/////")) { /* ignore */; } else { fprintf(stdout, "# unrecognised (%s) in Synop1\n", token); } break; /* case MSS_Synop1 */ case MSS_Synop2: if (string_match(token, "0[0246/]%")) { ms_set(ms, "2s", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "3Tw", NULL, tac_atoi(token, 2, 3)); } else if (string_match(token, "0[1357]%")) { ms_set(ms, "2s", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "3Tw", NULL, tac_atosi(token, '1', 2, 3)); } else if (token[0] == '1') { ms_set(ms, "2Pwa", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2Hwa", NULL, tac_atoi(token, 3, 2)); } else if (token[0] == '2') { ms_set(ms, "2Pw", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2Hw", NULL, tac_atoi(token, 3, 2)); } else if (token[0] == '3') { ms_set(ms, "2dw1", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2dw2", NULL, tac_atoi(token, 3, 2)); } else if (token[0] == '4') { ms_set(ms, "2Pw1", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2Hw1", NULL, tac_atoi(token, 3, 2)); } else if (token[0] == '5') { ms_set(ms, "2Pw2", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2Hw2", NULL, tac_atoi(token, 3, 2)); } else if (token[0] == '6') { ms_set(ms, "Is", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "2Es", NULL, tac_atoi(token, 2, 2)); ms_set(ms, "Rs", NULL, tac_atoi(token, 4, 1)); } else if (token[0] == '7') { ms_set(ms, "3Hwa", NULL, tac_atoi(token, 2, 3)); } else if (token[0] == '8') { ms_set(ms, "3Tb", NULL, tac_atosi(token, token[1], 2, 3)); } else if (StringEq(token, "/////")) { /* ignore */; } else if (StringEq(token, "ICING") || StringEq(token, "ICE")) { ms->ms_state = MSS_Synop2ICE; } else if (string_match(token, "ICE[0-9/][0-9/][0-9/][0-9/][0-9/]")) { ms_set(ms, "ci", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "Si", NULL, tac_atoi(token, 4, 1)); ms_set(ms, "bi", NULL, tac_atoi(token, 5, 1)); ms_set(ms, "Di", NULL, tac_atoi(token, 6, 1)); ms_set(ms, "zi", NULL, tac_atoi(token, 7, 1)); } else { fprintf(stdout, "# unrecognised (%s) in Synop2\n", token); } break; case MSS_Synop3: if (StringEq(token, "/////")) { /* ignore */; } else if (token[0] == '0') { if (string_match(token, "0E[0-9/][0-9/][0-9/]")) { ms_set(ms, "2Tg_", NULL, tac_atosi(token, token[2], 3, 2)); } else { if (string_match(ms->ms_id, "89%")) { /* Antarctica */ ms_set(ms, "2dm", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "2fm", NULL, tac_atoi(token, 3, 2)); } else { long ra = ms_get(ms, "!RA", ""); if (ra == 1) { ms_set(ms, "2Tg", NULL, tac_atoi(token, 1, 2)); ms_set(ms, "Rc", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "Rt", NULL, tac_atoi(token, 4, 1)); } else if (ra == 2) { ms_set(ms, "E/30", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "2Tg_", NULL, tac_atosi(token, token[2], 3, 2)); } else if ((ra == 4) || (ra == 3)) { ms_set(ms, "Cs", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "DL", NULL, tac_atoi(token, 2, 1)); ms_set(ms, "DM", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "DH", NULL, tac_atoi(token, 4, 1)); } else { goto BadSynop3; } } } } else if (token[0] == '1') { ms_set(ms, "3Tx", NULL, tac_atosi(token, token[1], 2, 3)); } else if (token[0] == '2') { ms_set(ms, "3Tn", NULL, tac_atosi(token, token[1], 2, 3)); } else if (token[0] == '3') { ms_set(ms, "E", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "3j", NULL, tac_atoi(token, 2, 3)); } else if (token[0] == '4') { ms_set(ms, "E_", NULL, tac_atoi(token, 1, 1)); ms_set(ms, "3s", NULL, tac_atoi(token, 2, 3)); } else if (token[0] == '5') { if (string_match(token, "5[0-3/][0-9/][0-9/][0-9/]")) { ms_set(ms, "3E", NULL, tac_atoi(token, 1, 3)); ms_set(ms, "iE", NULL, tac_atoi(token, 4, 1)); } else if (string_match(token, "55[012/][0-9/][0-9/]")) { ms_set(ms, "3S", NULL, tac_atoi(token, 2, 3)); } else if (string_match(token, "553[0-9/][0-9/]")) { ms_set(ms, "2S", NULL, tac_atoi(token, 3, 2)); } else if (token[1] == '6') { ms_set(ms, "DL", NULL, tac_atoi(token, 2, 1)); ms_set(ms, "DM", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "DH", NULL, tac_atoi(token, 4, 1)); } else if (token[1] == '7') { ms_set(ms, "C", NULL, tac_atoi(token, 2, 1)); ms_set(ms, "Da", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "ec", NULL, tac_atoi(token, 4, 1)); } else if (token[1] == '8') { ms_set(ms, "3p24", NULL, tac_atoi(token, 2, 3)); } else if (token[1] == '9') { ms_set(ms, "3p24", NULL, tac_atosi(token, '1', 2, 3)); } else { goto BadSynop3; } } else if (token[0] == '6') { long rrr = tac_atoi(token, 1, 3); long t = tac_tR(token[4]); if (rrr >= 990L) { rrr -= 990L; } else { rrr *= 10L; } ms_set(ms, "3R/3", NULL, rrr); ms_set(ms, "tR/3", NULL, t); } else if (token[0] == '7') { ms_set(ms, "4R24", NULL, tac_atoi(token, 1, 4)); } else if (token[0] == '8') { long hshs = tac_atoi(token, 3, 2); if (hshs >= 0) { char lev[8]; sprintf(lev, "hs%02u", (unsigned)hshs); ms_set(ms, "Ns", lev, tac_atoi(token, 1, 1)); ms_set(ms, "C", lev, tac_atoi(token, 2, 1)); ms_set(ms, "2hs", lev, hshs); } } else if (token[0] == '9') { if (string_match(token, "90[0-7][0-9/][0-9/]")) { char name[8]; sprintf(name, "2t/%.3s", token); ms_set(ms, name, NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "91[012][0-9/][0-9/]")) { char name[8]; sprintf(name, "2f/%.3s", token); ms_set(ms, name, NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "915[0-9/][0-9/]")) { ms_set(ms, "2d/915", NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "920[0-9/][0-9/]")) { ms_set(ms, "S/920", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "Fx/920", NULL, tac_atoi(token, 4, 1)); } else if (string_match(token, "923[0-9/][0-9/]")) { ms_set(ms, "2S/923", NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "924[0-9/][0-9/]")) { ms_set(ms, "S/924", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "Vs/924", NULL, tac_atoi(token, 4, 1)); } else if (string_match(token, "93[02-8][0-9/][0-9/]")) { char name[8]; sprintf(name, "2R/%.3s", token); ms_set(ms, name, NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "931[0-9/][0-9/]")) { ms_set(ms, "2s/931", NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "949[0-9/][0-9/]")) { ms_set(ms, "Ca/949", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "Da/949", NULL, tac_atoi(token, 4, 1)); } else if (string_match(token, "950[0-9/][0-9/]")) { ms_set(ms, "Nm/950", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "n3/950", NULL, tac_atoi(token, 4, 1)); } else if (string_match(token, "951[0-9/][0-9/]")) { ms_set(ms, "Nv/950", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "n4/950", NULL, tac_atoi(token, 4, 1)); } else if (string_match(token, "98[0-8][0-9/][0-9/]")) { char name[8]; sprintf(name, "2V/%.3s", token); ms_set(ms, name, NULL, tac_atoi(token, 3, 2)); } else if (string_match(token, "992[0-9/][0-9/]")) { ms_set(ms, "Nt/992", NULL, tac_atoi(token, 3, 1)); ms_set(ms, "tw/992", NULL, tac_atoi(token, 4, 1)); } else { goto BadSynop3; } } else { BadSynop3: fprintf(stdout, "# unrecognised (%s) in Synop3 (%.4s)\n", token, ms->ms_cccc); } break; case MSS_Synop4: fprintf(stdout, "# unrecognised (%s) in Synop4\n", token); break; case MSS_Synop5: fprintf(stdout, "# unrecognised (%s) in Synop5 (%.4s)\n", token, ms->ms_cccc); break; } endfunc: return 0; }