+static int FuncStrAt (void)
+/* Handle the .STRAT function */
+{
+ char Str [sizeof(SVal)];
+ long Index;
+
+ /* String constant expected */
+ if (Tok != TOK_STRCON) {
+ Error (ERR_STRCON_EXPECTED);
+ NextTok ();
+ return 0;
+
+ }
+
+ /* Remember the string and skip it */
+ strcpy (Str, SVal);
+ NextTok ();
+
+ /* Comma must follow */
+ ConsumeComma ();
+
+ /* Expression expected */
+ Index = ConstExpression ();
+
+ /* Must be a valid index */
+ if (Index >= (long) strlen (Str)) {
+ Error (ERR_RANGE);
+ return 0;
+ }
+
+ /* Return the char, handle as unsigned. Be sure to translate it into
+ * the target character set.
+ */
+ return (unsigned char) TgtTranslateChar (Str [(size_t)Index]);
+}
+
+
+
+static int FuncStrLen (void)
+/* Handle the .STRLEN function */
+{
+ /* String constant expected */
+ if (Tok != TOK_STRCON) {
+
+ Error (ERR_STRCON_EXPECTED);
+ /* Smart error recovery */
+ if (Tok != TOK_RPAREN) {
+ NextTok ();
+ }
+ return 0;
+
+ } else {
+
+ /* Get the length of the string */
+ int Len = strlen (SVal);
+
+ /* Skip the string */
+ NextTok ();
+
+ /* Return the length */
+ return Len;
+
+ }
+}
+
+
+
+static int FuncTCount (void)
+/* Handle the .TCOUNT function */
+{
+ /* We have a list of tokens that ends with the closing paren. Skip
+ * the tokens, handling nested braces and count them.
+ */
+ int Count = 0;
+ unsigned Parens = 0;
+ while (Parens != 0 || Tok != TOK_RPAREN) {
+
+ /* Check for end of line or end of input. Since the calling function
+ * will check for the closing paren, we don't need to print an error
+ * here, just bail out.
+ */
+ if (Tok == TOK_SEP || Tok == TOK_EOF) {
+ break;
+ }
+
+ /* One more token */
+ ++Count;
+
+ /* Keep track of the nesting level */
+ switch (Tok) {
+ case TOK_LPAREN: ++Parens; break;
+ case TOK_RPAREN: --Parens; break;
+ default: break;
+ }
+
+ /* Skip the token */
+ NextTok ();
+ }
+
+ /* Return the number of tokens */
+ return Count;
+}
+
+
+