implement preprocessor for tsf format
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
/* TLLY ver=77 */
|
/* TLLY ver=77 */
|
||||||
/* *=* Copyright 1996, 1997 WebTV Networks, Inc. All rights reserved. */
|
/* *=* Copyright 1996, 1997 WebTV Networks, Inc. All rights reserved. */
|
||||||
|
#ifndef FIJI
|
||||||
/*
|
/*
|
||||||
* This is the "base" TellyScript Fragment. It is suppressed for FIJI
|
* This is the "base" TellyScript Fragment. It is suppressed for FIJI
|
||||||
* (see comments below).
|
* (see comments below).
|
||||||
@@ -164,11 +165,12 @@ char* gPAPPassword; /* box's PAP password, embedded in script by the
|
|||||||
int gEnable56K; /* if set, allow 56K connections; if not, don't */
|
int gEnable56K; /* if set, allow 56K connections; if not, don't */
|
||||||
int gDisguiseRate; /* if set, reverse the DTE and DCE rates */
|
int gDisguiseRate; /* if set, reverse the DTE and DCE rates */
|
||||||
int gFlexKnob=5; /* 56k knob for Rockwell, 5=most aggressive (default) */
|
int gFlexKnob=5; /* 56k knob for Rockwell, 5=most aggressive (default) */
|
||||||
|
#endif /*!FIJI*/
|
||||||
/* FIJI doesn't have these built-in */
|
/* FIJI doesn't have these built-in */
|
||||||
int gBlock911=1; /* This flag is now set for all services. */
|
int gBlock911=1; /* This flag is now set for all services. */
|
||||||
int gWantsVideoAd; /* if set, user wants to download Video Ads */
|
int gWantsVideoAd; /* if set, user wants to download Video Ads */
|
||||||
/* This flag is not needed anymore, left here for future use */
|
/* This flag is not needed anymore, left here for future use */
|
||||||
|
#ifndef FIJI
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
@@ -431,6 +433,97 @@ GetPhoneSettings(int* pSettingsVersion)
|
|||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef CLASSIC
|
||||||
|
/*
|
||||||
|
* GetHardwareInfo - figure out some things about the platform we're
|
||||||
|
* running on.
|
||||||
|
*
|
||||||
|
* "*pIsEarlyK56" is set if we're using Rockwell's v1.0 K56 firmware.
|
||||||
|
* "*pAcceptsS220" is set if the modem recognizes S220 as a valid S-register.
|
||||||
|
*
|
||||||
|
* Assumes that the modem is happy and in V1E0 (verbose result code, no
|
||||||
|
* echo) mode.
|
||||||
|
*
|
||||||
|
* NOTE: we don't really check for and try to handle the case where the
|
||||||
|
* modem goes out to lunch and we're hitting the getline() timeouts. Since
|
||||||
|
* we've already talked to the modem a little before getting here, I think
|
||||||
|
* it's safe to assume that we won't fail here and then succeed later. If
|
||||||
|
* the information we get from this function is more critical than what we
|
||||||
|
* have now, we should be more careful.
|
||||||
|
*
|
||||||
|
* Returns 0 if all went well, nonzero on error.
|
||||||
|
*/
|
||||||
|
GetHardwareInfo(int* pIsEarlyK56, int* pAcceptsS220, int* pIsRockwell,
|
||||||
|
int* pAcceptsAmpP, int* pAcceptsPlusMR)
|
||||||
|
{
|
||||||
|
char resultBuf[64];
|
||||||
|
|
||||||
|
/* look for v1.0 Rockwell K56 firmware... if found, limit to <= V.34 */
|
||||||
|
flush();
|
||||||
|
sendstr("ATI3\r"); /* modem firmware query */
|
||||||
|
printf("TS: SENT ATI3");
|
||||||
|
getline(resultBuf, 63, 300); /* throw out the first one */
|
||||||
|
if (!getline(resultBuf, 63, 300)) /* keep 2nd; note it has leading '\r' */
|
||||||
|
return 1;
|
||||||
|
printf("TS: fw query got '%s'", resultBuf+1);
|
||||||
|
setfirmwareversion(resultBuf+1);
|
||||||
|
resultBuf[21] = '\0'; /* me falta strncmp in 1.0 */
|
||||||
|
*pIsEarlyK56 = 0;
|
||||||
|
if (strcmp(resultBuf+1, "V1.001_WEBTV-K56_DLP") == 0)
|
||||||
|
*pIsEarlyK56 = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Softmodem can't handle AT+MS, so try to detect Rockwell. Sadly,
|
||||||
|
* there doesn't seem to be a simple way to do this.
|
||||||
|
*/
|
||||||
|
*pIsRockwell = 0;
|
||||||
|
if (strcmp(resultBuf+11, "TV-K56_DLP") == 0)
|
||||||
|
*pIsRockwell = 1;
|
||||||
|
resultBuf[15] = '\0'; /* do we have strncmp in 2.0? */
|
||||||
|
if (strcmp(resultBuf+8, "K56_DLP") == 0) /* V2.200-K56_DLP_RAM */
|
||||||
|
*pIsRockwell = 1;
|
||||||
|
printf("TS: isRockwell=%d", *pIsRockwell);
|
||||||
|
|
||||||
|
/* see if it's a Rockwell that supports +MR */
|
||||||
|
*pAcceptsPlusMR = 0;
|
||||||
|
if (*pIsRockwell) {
|
||||||
|
flush();
|
||||||
|
sendstr("AT+MR=0\r");
|
||||||
|
getline(resultBuf, 63, 300); /* throw out 1st */
|
||||||
|
if (!getline(resultBuf, 63, 300)) /* keep 2nd */
|
||||||
|
return 1;
|
||||||
|
printf("TS: +MR=0 test returned '%s'", resultBuf+1);
|
||||||
|
if (strcmp(resultBuf+1, "OK") == 0)
|
||||||
|
*pAcceptsPlusMR = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if it will take an S220 command */
|
||||||
|
flush();
|
||||||
|
sendstr("ATS220=0\r"); /* JP CW --> extremely insensitive */
|
||||||
|
printf("TS: SENT ATS220=0");
|
||||||
|
getline(resultBuf, 63, 300); /* throw out 1st */
|
||||||
|
if (!getline(resultBuf, 63, 300)) /* keep 2nd */
|
||||||
|
return 1;
|
||||||
|
printf("TS: S220 test returned '%s'", resultBuf+1);
|
||||||
|
*pAcceptsS220 = 0;
|
||||||
|
if (strcmp(resultBuf+1, "OK") == 0)
|
||||||
|
*pAcceptsS220 = 1;
|
||||||
|
|
||||||
|
/* see if it will take an &Pn command -- desktop Supras won't */
|
||||||
|
flush();
|
||||||
|
sendstr("AT&P0\r");
|
||||||
|
printf("TS: SENT AT&P0");
|
||||||
|
getline(resultBuf, 63, 300); /* throw out 1st */
|
||||||
|
if (!getline(resultBuf, 63, 300)) /* keep 2nd */
|
||||||
|
return 1;
|
||||||
|
printf("TS: AT&P0 test returned '%s'", resultBuf+1);
|
||||||
|
*pAcceptsAmpP = 0;
|
||||||
|
if (strcmp(resultBuf+1, "OK") == 0)
|
||||||
|
*pAcceptsAmpP = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize - set up the modem configuration and dialing commands, and
|
* Initialize - set up the modem configuration and dialing commands, and
|
||||||
@@ -454,6 +547,11 @@ Initialize(char* staticConfigBuf, char* dynamicConfigBuf)
|
|||||||
char dialSpeed = settings[104];
|
char dialSpeed = settings[104];
|
||||||
char cwSensitivity = extendedSettings[105]; /* version >= 7 */
|
char cwSensitivity = extendedSettings[105]; /* version >= 7 */
|
||||||
char *cwValue = "14";
|
char *cwValue = "14";
|
||||||
|
#ifndef CLASSIC
|
||||||
|
char *s220Value;
|
||||||
|
int isEarlyK56, acceptsS220, isRockwell, acceptsAmpP, acceptsPlusMR;
|
||||||
|
char *flexKnobStr; /* sairam testing */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Talk to the modem.
|
* Talk to the modem.
|
||||||
@@ -466,7 +564,40 @@ Initialize(char* staticConfigBuf, char* dynamicConfigBuf)
|
|||||||
if (SendAndWaitForOK("AT&D2V1E0\r", "OK"))
|
if (SendAndWaitForOK("AT&D2V1E0\r", "OK"))
|
||||||
return 3; /* kTellyConfigurationError */
|
return 3; /* kTellyConfigurationError */
|
||||||
|
|
||||||
|
#ifndef CLASSIC
|
||||||
|
/* figure out what we got? */
|
||||||
|
if (GetHardwareInfo(&isEarlyK56, &acceptsS220, &isRockwell, &acceptsAmpP,
|
||||||
|
&acceptsPlusMR))
|
||||||
|
return 3; /* kTellyConfigurationError */
|
||||||
|
if (isEarlyK56)
|
||||||
|
printf("TS: found v1.0 K56 fw, disabling 56K");
|
||||||
|
|
||||||
|
strcpy(staticConfigBuf, "AT");
|
||||||
|
if (isRockwell) {
|
||||||
|
if (isEarlyK56 || !gEnable56K) {
|
||||||
|
strcat(staticConfigBuf, "+MS=11,1"); /* disable 56K */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else {
|
||||||
|
/+ Rockwell 56k Aggressiveness knob - sairam testing +/
|
||||||
|
if (isRockwell) {
|
||||||
|
sprintf(staticConfigBuf+2, "!0049=0%d", gFlexKnob);
|
||||||
|
printf("TS: setting 56k knob to %d", gFlexKnob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
/* assume softmodem */
|
||||||
|
if (!gEnable56K) {
|
||||||
|
strcat(staticConfigBuf, "S51=31"); /* disable 56K */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acceptsPlusMR) /* suppress extended result codes we don't parse */
|
||||||
|
strcat(staticConfigBuf, "+MR=0");
|
||||||
|
#else
|
||||||
strcpy(staticConfigBuf, "AT"); /* CLASSIC doesn't support 56K */
|
strcpy(staticConfigBuf, "AT"); /* CLASSIC doesn't support 56K */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modem configuration. This sets things so we connect with V.34 only,
|
* Modem configuration. This sets things so we connect with V.34 only,
|
||||||
@@ -528,6 +659,26 @@ Initialize(char* staticConfigBuf, char* dynamicConfigBuf)
|
|||||||
strcat(dynamicConfigBuf, "S10=");
|
strcat(dynamicConfigBuf, "S10=");
|
||||||
strcat(dynamicConfigBuf, cwValue);
|
strcat(dynamicConfigBuf, cwValue);
|
||||||
|
|
||||||
|
#ifndef CLASSIC
|
||||||
|
/* set the JP "catch-phone" sensitivity; this is *in addition* to S10 */
|
||||||
|
if (acceptsS220) {
|
||||||
|
if (cwSensitivity == 1) /* most likely to hang up */
|
||||||
|
s220Value = "32";
|
||||||
|
else if (cwSensitivity == 2)
|
||||||
|
s220Value = "21";
|
||||||
|
else if (cwSensitivity == 3)
|
||||||
|
s220Value = "11";
|
||||||
|
else /* == 4 or bogus */ /* most likely to ignore calls */
|
||||||
|
s220Value = "1";
|
||||||
|
|
||||||
|
printf("TS: setting S220=%s", s220Value);
|
||||||
|
strcat(dynamicConfigBuf, "S220=");
|
||||||
|
strcat(dynamicConfigBuf, s220Value);
|
||||||
|
} else {
|
||||||
|
printf("TS: not setting S220"); /* CLASSIC boxes; others? */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the dial speed.
|
* Set the dial speed.
|
||||||
*/
|
*/
|
||||||
@@ -541,6 +692,22 @@ Initialize(char* staticConfigBuf, char* dynamicConfigBuf)
|
|||||||
strcat(dynamicConfigBuf, "S11=1"); /* blazing (not in UI) */
|
strcat(dynamicConfigBuf, "S11=1"); /* blazing (not in UI) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CLASSIC
|
||||||
|
/*
|
||||||
|
* Set the pulse speed. &P0 is default for US, but we use JP pulse
|
||||||
|
* values for now since they seem to work anyway. Some desktop Supra
|
||||||
|
* modems don't understand "&Pn", and will fail to configure, so we
|
||||||
|
* use the "acceptsAmpP" auto-detect value.
|
||||||
|
*/
|
||||||
|
if (acceptsAmpP) {
|
||||||
|
if (dialSpeed == 0 || dialSpeed == 1) {
|
||||||
|
strcat(dynamicConfigBuf, "&P1"); /* 10PPS 33% */
|
||||||
|
} else if (dialSpeed == 2 || dialSpeed == 3) {
|
||||||
|
strcat(dynamicConfigBuf, "&P3"); /* 20PPS 33% */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* put a carriage return on the end */
|
/* put a carriage return on the end */
|
||||||
strcat(dynamicConfigBuf, "\r");
|
strcat(dynamicConfigBuf, "\r");
|
||||||
@@ -699,6 +866,18 @@ ParseResult(int result)
|
|||||||
int retcode;
|
int retcode;
|
||||||
char* comment = "";
|
char* comment = "";
|
||||||
|
|
||||||
|
#ifndef CLASSIC /* no CLASSIC box supports modem_parsersult() */
|
||||||
|
retcode = modem_parseresult(&result, &gDTERate, &gDCERate, &gCompression,
|
||||||
|
&gProtocol, &gConnected, &comment);
|
||||||
|
if (retcode != 0x42554646) {
|
||||||
|
printf("TS: parseresult -- %d %s (retcode=%d)", result,
|
||||||
|
comment, retcode);
|
||||||
|
if (gDCERate && gDCERate < 14400) {
|
||||||
|
retcode = 14; /* kTellyVerySlowConnect */
|
||||||
|
}
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
retcode = 0;
|
retcode = 0;
|
||||||
|
|
||||||
if (result == 0) /* OK */
|
if (result == 0) /* OK */
|
||||||
@@ -1285,11 +1464,34 @@ DialByIndex(char* staticConfig, char* dynamicConfig, char* sequence)
|
|||||||
return err;
|
return err;
|
||||||
} else {
|
} else {
|
||||||
dialerror(err);
|
dialerror(err);
|
||||||
|
#ifndef CLASSIC
|
||||||
|
/* 101223/093628
|
||||||
|
* Make sure that MsgWatch calls are
|
||||||
|
* limited to the primary POP only,
|
||||||
|
* and to the first trial!
|
||||||
|
*/
|
||||||
|
if (idx == nextNumber) {
|
||||||
|
if (getconnectreason() == 1) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else if (status == 2 || idx == sequenceLen-1) {
|
} else if (status == 2 || idx == sequenceLen-1) {
|
||||||
return err;
|
return err;
|
||||||
} else /*status==1*/ {
|
} else /*status==1*/ {
|
||||||
dialerror(err);
|
dialerror(err);
|
||||||
|
#ifndef CLASSIC
|
||||||
|
/* 101223/093628
|
||||||
|
* Make sure that MsgWatch calls are
|
||||||
|
* limited to the primary POP only
|
||||||
|
*/
|
||||||
|
if (idx == nextNumber) {
|
||||||
|
if (getconnectreason() == 1) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1369,6 +1571,9 @@ main()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* !FIJI */
|
||||||
|
|
||||||
|
/* --- base.tsf END --- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locale-specific stuff for USA.
|
* Locale-specific stuff for USA.
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
var minisrv_service_file = true;
|
var minisrv_service_file = true;
|
||||||
var template_path = "";
|
var template = "";
|
||||||
|
var template_preprocessor = {};
|
||||||
|
|
||||||
var gourl = "wtv-head-waiter:/login?";
|
var gourl = "wtv-head-waiter:/login?";
|
||||||
|
|
||||||
@@ -109,7 +110,8 @@ if (session_data.data_store.wtvsec_login) {
|
|||||||
case "bf0app":
|
case "bf0app":
|
||||||
prereg_contype = "text/tellyscript";
|
prereg_contype = "text/tellyscript";
|
||||||
// if wtv-open-access: true then client expects OpenISP
|
// if wtv-open-access: true then client expects OpenISP
|
||||||
template = wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app.base.template.txt")
|
template = wtvshared.getServiceDep("/wtv-1800/tellyscripts/base.template.txt")
|
||||||
|
template_preprocessor = { 'CLASSIC': true }
|
||||||
if (session_data.get("wtv-open-access")) template += wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app.openisp.template.txt");
|
if (session_data.get("wtv-open-access")) template += wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app.openisp.template.txt");
|
||||||
else template += wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app.normal.template.txt");
|
else template += wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app.normal.template.txt");
|
||||||
//else file_path = wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app_WTV_18006138199.tok", true);
|
//else file_path = wtvshared.getServiceDep("/wtv-1800/tellyscripts/bf0app/bf0app_WTV_18006138199.tok", true);
|
||||||
@@ -119,6 +121,7 @@ if (session_data.data_store.wtvsec_login) {
|
|||||||
|
|
||||||
case "JP-Fiji":
|
case "JP-Fiji":
|
||||||
prereg_contype = "text/tellyscript";
|
prereg_contype = "text/tellyscript";
|
||||||
|
template_preprocessor = { 'FIJI': true }
|
||||||
// if wtv-open-access: true then client expects OpenISP
|
// if wtv-open-access: true then client expects OpenISP
|
||||||
if (session_data.get("wtv-open-access")) var file_path = wtvshared.getServiceDep("/wtv-1800/tellyscripts/FIJI/dc_production_normal.tok", true);
|
if (session_data.get("wtv-open-access")) var file_path = wtvshared.getServiceDep("/wtv-1800/tellyscripts/FIJI/dc_production_normal.tok", true);
|
||||||
else var file_path = wtvshared.getServiceDep("/wtv-1800/tellyscripts/FIJI/dc_production_normal.tok", true);
|
else var file_path = wtvshared.getServiceDep("/wtv-1800/tellyscripts/FIJI/dc_production_normal.tok", true);
|
||||||
@@ -201,11 +204,11 @@ if (session_data.data_store.wtvsec_login) {
|
|||||||
});
|
});
|
||||||
} else if (template) {
|
} else if (template) {
|
||||||
request_is_async = true;
|
request_is_async = true;
|
||||||
telly = new WTVTellyScript(template, 2); // 2 = Untokenized
|
telly = new WTVTellyScript(template, 2, template_preprocessor, session_data.get("wtv-open-access") ? 3 : 1); // dataState 2 = Untokenized
|
||||||
telly.setTemplateVars(minisrv_config.config.service_name, minisrv_config.services[service_name].dialin_number, minisrv_config.services[service_name].dns1ip, minisrv_config.services[service_name].dns2ip);
|
telly.setTemplateVars(minisrv_config.config.service_name, minisrv_config.services[service_name].dialin_number, minisrv_config.services[service_name].dns1ip, minisrv_config.services[service_name].dns2ip);
|
||||||
telly.minify();
|
telly.minify();
|
||||||
telly.tokenize();
|
telly.tokenize();
|
||||||
telly.pack((session_data.get("wtv-open-access")) ? 3 : 1);
|
telly.pack();
|
||||||
sendToClient(socket, headers, telly.packed_data);
|
sendToClient(socket, headers, telly.packed_data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1053,17 +1053,93 @@ class WTVTellyScript {
|
|||||||
* @param {Uint8Array|string} data - The TellyScript data (either packed, tokenized, or raw).
|
* @param {Uint8Array|string} data - The TellyScript data (either packed, tokenized, or raw).
|
||||||
* @param {number} dataState - One of TellyScriptState (default: PACKED).
|
* @param {number} dataState - One of TellyScriptState (default: PACKED).
|
||||||
* @param {number} tellyscriptType - One of TellyScriptType (default: ORIGINAL).
|
* @param {number} tellyscriptType - One of TellyScriptType (default: ORIGINAL).
|
||||||
|
* @param {object} preprocessor_definitions - A dictionary of preprocessor definitions.
|
||||||
|
* @param {number} version_minor - The minor version number (default: 1).
|
||||||
*/
|
*/
|
||||||
constructor(data, dataState = TellyScriptState.PACKED, tellyscriptType = TellyScriptType.ORIGINAL) {
|
constructor(data, dataState = TellyScriptState.PACKED, preprocessor_definitions = {}, version_minor = 1, tellyscriptType = TellyScriptType.ORIGINAL) {
|
||||||
this.tellyscript_type = tellyscriptType;
|
this.tellyscript_type = tellyscriptType;
|
||||||
this.packed_data = null;
|
this.packed_data = null;
|
||||||
this.packed_header = null;
|
this.packed_header = null;
|
||||||
this.tokenized_data = null;
|
this.tokenized_data = null;
|
||||||
this.raw_data = null;
|
this.raw_data = null;
|
||||||
|
this.preprocessor_definitions = preprocessor_definitions;
|
||||||
|
this.version_minor = version_minor;
|
||||||
|
|
||||||
this.process(data, dataState);
|
this.process(data, dataState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preprocess() {
|
||||||
|
var definitions = this.preprocessor_definitions || {};
|
||||||
|
// Split input into lines (handling CRLF and LF)
|
||||||
|
const lines = this.raw_data.split(/\r?\n/);
|
||||||
|
const output = [];
|
||||||
|
// A stack to track whether the current block is active.
|
||||||
|
// Start with "true" so that top-level lines are output.
|
||||||
|
const stateStack = [true];
|
||||||
|
|
||||||
|
// Process each line one by one.
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i];
|
||||||
|
|
||||||
|
// Only process directives if they are left-aligned.
|
||||||
|
if (line.startsWith("#")) {
|
||||||
|
if (/^#ifdef\b/.test(line)) {
|
||||||
|
// Get the label immediately after "#ifdef"
|
||||||
|
const token = line.slice(6).split(/\s/)[0];
|
||||||
|
const condition = !!definitions[token];
|
||||||
|
// The block is active only if the parent block is active and condition is true.
|
||||||
|
const active = stateStack[stateStack.length - 1] && condition;
|
||||||
|
stateStack.push(active);
|
||||||
|
continue; // Do not output this directive line.
|
||||||
|
} else if (/^#ifndef\b/.test(line)) {
|
||||||
|
const token = line.slice(7).split(/\s/)[0];
|
||||||
|
const condition = !definitions[token];
|
||||||
|
const active = stateStack[stateStack.length - 1] && condition;
|
||||||
|
stateStack.push(active);
|
||||||
|
continue;
|
||||||
|
} else if (/^#if\b/.test(line)) {
|
||||||
|
// Expect exactly "#if 1" or "#if 0" (no extra spaces allowed).
|
||||||
|
const token = line.slice(3).split(/\s/)[0];
|
||||||
|
if (token !== "1" && token !== "0") {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid #if condition at line ${i + 1}: "${line}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const condition = token === "1";
|
||||||
|
const active = stateStack[stateStack.length - 1] && condition;
|
||||||
|
stateStack.push(active);
|
||||||
|
continue;
|
||||||
|
} else if (/^#else\b/.test(line)) {
|
||||||
|
if (stateStack.length <= 1) {
|
||||||
|
throw new Error(`#else without matching #if at line ${i + 1}`);
|
||||||
|
}
|
||||||
|
// Flip the state of the current block while considering the parent's state.
|
||||||
|
const previous = stateStack.pop();
|
||||||
|
const newState = stateStack[stateStack.length - 1] && !previous;
|
||||||
|
stateStack.push(newState);
|
||||||
|
continue;
|
||||||
|
} else if (/^#endif\b/.test(line)) {
|
||||||
|
if (stateStack.length <= 1) {
|
||||||
|
throw new Error(`#endif without matching #if at line ${i + 1}`);
|
||||||
|
}
|
||||||
|
stateStack.pop();
|
||||||
|
continue;
|
||||||
|
} else if (/^#include\b/.test(line)) {
|
||||||
|
// Silently remove #include directives.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For non-directive lines (or lines with unrecognized directives),
|
||||||
|
// output them only if the current block is active.
|
||||||
|
if (stateStack[stateStack.length - 1]) {
|
||||||
|
output.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.raw_data = output.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
minify() {
|
minify() {
|
||||||
let minifier = new WTVTellyScriptMinifier();
|
let minifier = new WTVTellyScriptMinifier();
|
||||||
this.raw_data = minifier.minify(this);
|
this.raw_data = minifier.minify(this);
|
||||||
@@ -1218,12 +1294,13 @@ class WTVTellyScript {
|
|||||||
this.pack();
|
this.pack();
|
||||||
this.detokenize();
|
this.detokenize();
|
||||||
} else if (dataState === TellyScriptState.RAW) {
|
} else if (dataState === TellyScriptState.RAW) {
|
||||||
// For RAW byte data, convert to string (assuming UTF-8)
|
// For RAW byte data, convert to string (assuming UTF-8)
|
||||||
this.process(new TextDecoder().decode(data), dataState);
|
this.process(new TextDecoder().decode(data), dataState);
|
||||||
}
|
}
|
||||||
} else if (typeof data === "string") {
|
} else if (typeof data === "string") {
|
||||||
if (dataState === TellyScriptState.RAW) {
|
if (dataState === TellyScriptState.RAW) {
|
||||||
this.raw_data = data;
|
this.raw_data = data;
|
||||||
|
this.preprocess()
|
||||||
this.tokenize();
|
this.tokenize();
|
||||||
this.pack();
|
this.pack();
|
||||||
} else if (dataState === TellyScriptState.PACKED || dataState === TellyScriptState.TOKENIZED) {
|
} else if (dataState === TellyScriptState.PACKED || dataState === TellyScriptState.TOKENIZED) {
|
||||||
@@ -1275,7 +1352,7 @@ class WTVTellyScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Packing ---
|
// --- Packing ---
|
||||||
pack(version_minor = 1) {
|
pack() {
|
||||||
// Compress tokenized data using LZSS.
|
// Compress tokenized data using LZSS.
|
||||||
const comp = new LZSS();
|
const comp = new LZSS();
|
||||||
const compressed_data = comp.compress(this.tokenized_data);
|
const compressed_data = comp.compress(this.tokenized_data);
|
||||||
@@ -1295,7 +1372,7 @@ class WTVTellyScript {
|
|||||||
this.packed_header = {
|
this.packed_header = {
|
||||||
magic: (this.tellyscript_type === TellyScriptType.DIALSCRIPT) ? "VKAT" : "ANDY",
|
magic: (this.tellyscript_type === TellyScriptType.DIALSCRIPT) ? "VKAT" : "ANDY",
|
||||||
version_major: (this.packed_header && this.packed_header.version_major) ? this.packed_header.version_major : 1,
|
version_major: (this.packed_header && this.packed_header.version_major) ? this.packed_header.version_major : 1,
|
||||||
version_minor: (this.packed_header && this.packed_header.version_minor) ? this.packed_header.version_minor : version_minor,
|
version_minor: (this.packed_header && this.packed_header.version_minor) ? this.packed_header.version_minor : this.version_minor,
|
||||||
script_id: script_id,
|
script_id: script_id,
|
||||||
script_mod: Math.floor(Date.now() / 1000),
|
script_mod: Math.floor(Date.now() / 1000),
|
||||||
compressed_data_length: compressed_data.length,
|
compressed_data_length: compressed_data.length,
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ wtv-system-version: 7181
|
|||||||
wtv-capability-flags: 10935ffc8f
|
wtv-capability-flags: 10935ffc8f
|
||||||
wtv-client-bootrom-version: 2046
|
wtv-client-bootrom-version: 2046
|
||||||
wtv-client-rom-type: bf0app
|
wtv-client-rom-type: bf0app
|
||||||
wtv-open-access: true
|
|
||||||
wtv-system-chipversion: 51511296
|
wtv-system-chipversion: 51511296
|
||||||
User-Agent: Mozilla/4.0 WebTV/2.2.6.1 (compatible; MSIE 4.0)
|
User-Agent: Mozilla/4.0 WebTV/2.2.6.1 (compatible; MSIE 4.0)
|
||||||
wtv-encryption: true
|
wtv-encryption: true
|
||||||
@@ -30,6 +29,7 @@ wtv-script-id: 0
|
|||||||
wtv-script-mod: 0
|
wtv-script-mod: 0
|
||||||
|
|
||||||
`
|
`
|
||||||
|
//wtv-open-access: true
|
||||||
|
|
||||||
|
|
||||||
//wtv-client-rom-type: US-LC2-disk-0MB-8MB
|
//wtv-client-rom-type: US-LC2-disk-0MB-8MB
|
||||||
@@ -62,7 +62,7 @@ client.on('data', (chunk) => {
|
|||||||
|
|
||||||
telly = new WTVTellyScript(accumulatedBuffer)
|
telly = new WTVTellyScript(accumulatedBuffer)
|
||||||
console.log(telly.packed_header)
|
console.log(telly.packed_header)
|
||||||
console.log(telly.raw_data)
|
// console.log(telly.raw_data)
|
||||||
// Optionally, close the connection after receiving data
|
// Optionally, close the connection after receiving data
|
||||||
client.end();
|
client.end();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user