summaryrefslogtreecommitdiff
path: root/Build/source/texk/chktex/FindErrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/chktex/FindErrs.c')
-rw-r--r--Build/source/texk/chktex/FindErrs.c1485
1 files changed, 0 insertions, 1485 deletions
diff --git a/Build/source/texk/chktex/FindErrs.c b/Build/source/texk/chktex/FindErrs.c
deleted file mode 100644
index 2014e3923cc..00000000000
--- a/Build/source/texk/chktex/FindErrs.c
+++ /dev/null
@@ -1,1485 +0,0 @@
-/*
- * ChkTeX v1.5, error searching & report routines.
- * Copyright (C) 1995-96 Jens T. Berger Thielemann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Contact the author at:
- * Jens Berger
- * Spektrumvn. 4
- * N-0666 Oslo
- * Norway
- * E-mail: <jensthi@ifi.uio.no>
- *
- *
- */
-
-
-#include "ChkTeX.h"
-#include "FindErrs.h"
-#include "OpSys.h"
-#include "Utility.h"
-#include "Resource.h"
-
-/***************************** ERROR MESSAGES ***************************/
-
-#undef MSG
-#define MSG(num, type, inuse, ctxt, text) {num, type, inuse, ctxt, text},
-
-struct ErrMsg LaTeXMsgs [emMaxFault + 1] =
-{
- ERRMSGS
- {emMaxFault, etErr, iuOK, 0, INTERNFAULT}
-};
-
-#define istex(c) (isalpha(c) || (AtLetter && (c == '@')))
-#define CTYPE(func) \
-static int my_##func(int c) \
-{ \
- return(func(c)); \
-}
-
-#define INUSE(c) (LaTeXMsgs[(enum ErrNum) c].InUse == iuOK)
-
-#define PSERR2(pos,len,err,a,b) \
- PrintError(CurStkName(&InputStack), RealBuf, pos, len, Line, err, a, b)
-
-#define PSERRA(pos,len,err,a) \
- PrintError(CurStkName(&InputStack), RealBuf, pos, len, Line, err, a)
-
-#define HEREA(len, err, a) PSERRA(BufPtr - Buf - 1, len, err, a)
-#define PSERR(pos,len,err) PSERRA(pos,len,err,"")
-
-#define HERE(len, err) HEREA(len, err, "")
-
-#define SKIP_BACK(ptr, c, check) \
- while((c = *ptr--)) \
- { \
- ifn(check) break; \
- } \
- ptr++;
-
-#define SKIP_AHEAD(ptr, c, check) \
- while((c = *ptr++)) \
- { \
- ifn(check) \
- break; \
- } \
- ptr--;
-
-
-/* -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- -=><=- */
-
-static ULONG Line;
-
-static STRPTR RealBuf, LineCpy, BufPtr;
-
-static int ItFlag = efNone;
-
-NEWBUF(Buf, BUFSIZ);
-NEWBUF(CmdBuffer, BUFSIZ);
-NEWBUF(ArgBuffer, BUFSIZ);
-
-static enum ErrNum PerformCommand(const STRPTR Cmd, STRPTR Arg);
-
-#ifdef isdigit
-CTYPE(isdigit)
-#else
-# define my_isdigit isdigit
-#endif
-
-#ifdef isalpha
-CTYPE(isalpha)
-#else
-# define my_isalpha isalpha
-#endif
-
-/*
- * Reads in a TeX token from Src and puts it in Dest.
- *
- */
-
-
-static STRPTR GetLTXToken(STRPTR Src, STRPTR Dest)
-{
- int Char;
-
- if(Src && *Src)
- {
- if(*Src == '\\')
- {
- *Dest++ = *Src++;
- Char = *Dest++ = *Src++;
-
- if(istex(Char))
- {
- while(istex(Char))
- Char = *Dest++ = *Src++;
-
- Src--;
- Dest--;
- }
-
- }
- else
- *Dest++ = *Src++;
- *Dest = 0;
- }
- else
- Src = NULL;
-
- return(Src);
-}
-
-
-/*
- * Scans the `SrcBuf' for a LaTeX arg, and puts that arg into `Dest'.
- * `Until' specifies what we'll copy. Assume the text is
- * "{foo}bar! qux} baz".
- * GET_TOKEN => "{foo}"
- * GET_STRIP_TOKEN => "foo"
- * '!' => "{foo}bar!" (i.e. till the first "!")
- * Returns NULL if we can't find the argument, ptr to the first character
- * after the argument in other cases.
- *
- * If one of the tokens found is in the wl wordlist, and we're in the
- * outer most paren, and Until isn't a single character, we'll stop.
- * You may pass NULL as wl.
- *
- * We assume that you've previously skipped over leading spaces.
- *
- */
-
-#define GET_TOKEN 256
-#define GET_STRIP_TOKEN 257
-
-static STRPTR GetLTXArg(STRPTR SrcBuf,
- const STRPTR OrigDest,
- const int Until,
- struct WordList *wl)
-
-{
- STRPTR Retval, TmpPtr, Dest = OrigDest;
- ULONG DeliCnt = 0;
-
- *Dest = 0;
- TmpPtr = SrcBuf;
-
- switch(Until)
- {
- case GET_STRIP_TOKEN:
- case GET_TOKEN:
- while((Retval = GetLTXToken(TmpPtr, Dest)))
- {
- switch(*Dest)
- {
- case '{':
- DeliCnt++;
- break;
- case '}':
- DeliCnt--;
- }
- Dest += Retval - TmpPtr;
- TmpPtr = Retval;
-
- if(!DeliCnt || ((DeliCnt == 1) && wl && HasWord(Dest, wl)))
- break;
- }
-
- if(Retval && (*OrigDest == '{') && (Until == GET_STRIP_TOKEN))
- {
- strcpy(OrigDest, OrigDest + 1);
- OrigDest[strlen(OrigDest) - 1] = 0;
- }
- break;
- default:
- DeliCnt = TRUE;
- while((Retval = GetLTXArg(TmpPtr, Dest, GET_TOKEN, NULL)))
- {
- if(*Dest == Until)
- DeliCnt = FALSE;
-
- Dest += Retval - TmpPtr;
- TmpPtr = Retval;
-
- if(!DeliCnt)
- break;
- }
- break;
- }
- *Dest = 0;
-
- return(Retval);
-}
-
-
-static STRPTR MakeCpy(void)
-{
- if(!LineCpy)
- LineCpy = strdup(RealBuf);
-
- if(!LineCpy)
- PrintPrgErr(pmStrDupErr);
-
- return(LineCpy);
-}
-
-static STRPTR PreProcess(void)
-{
- /* First, kill comments. */
-
- STRPTR TmpPtr;
-
- strcpy(Buf, RealBuf);
-
- TmpPtr = Buf;
-
- while((TmpPtr = strchr(TmpPtr, '%')))
- {
- if(TmpPtr[-1] != '\\')
- {
- PSERR(TmpPtr - Buf, 1, emComment);
- *TmpPtr = 0;
- break;
- }
- TmpPtr++;
- }
- return(Buf);
-}
-
-/*
- * Interpret environments
- */
-
-static void PerformEnv(STRPTR Env, BOOL Begin)
-{
-static
- TEXT VBStr [BUFSIZ] = "";
-
- if(HasWord(Env, &MathEnvir))
- {
- MathMode += Begin ? 1 : -1;
- MathMode = max(MathMode, 0);
- }
-
- if(Begin && HasWord(Env, &VerbEnvir))
- {
- VerbMode = TRUE;
- strcpy(VBStr, "\\end{");
- strcat(VBStr, Env);
- strcat(VBStr, "}");
- VerbStr = VBStr;
- }
-}
-
-static STRPTR SkipVerb(void)
-{
- STRPTR TmpPtr = BufPtr;
- int TmpC;
-
- if(VerbMode && BufPtr)
- {
- ifn(TmpPtr = strstr(BufPtr, VerbStr))
- BufPtr = &BufPtr[strlen(BufPtr)];
- else
- {
- VerbMode = FALSE;
- BufPtr = &TmpPtr[strlen(VerbStr)];
- SKIP_AHEAD(BufPtr, TmpC, LATEX_SPACE(TmpC));
- if(*BufPtr)
- PSERR(BufPtr - Buf, strlen(BufPtr) - 2, emIgnoreText);
- }
- }
- return(TmpPtr);
-}
-
-#define CHECKDOTS(wordlist, dtval) \
-for(i = 0; (i < wordlist.Stack.Used) && !(Back && Front); i++) \
- { if(!strafter(PstPtr, wordlist.Stack.Data[i])) \
- Back = dtval; \
- if(!strinfront(PrePtr, wordlist.Stack.Data[i])) \
- Front = dtval; }
-
-
-
-/*
- * Checks that the dots are correct
- */
-
-static enum DotLevel CheckDots(STRPTR PrePtr, STRPTR PstPtr)
-{
- ULONG i;
- int TmpC;
- enum DotLevel Front = dtUnknown, Back = dtUnknown;
-
- if(MathMode)
- {
- PrePtr--;
-#define SKIP_EMPTIES(macro, ptr) macro(ptr, TmpC, \
-(LATEX_SPACE(TmpC) || (TmpC == '{') || (TmpC == '}')))
-
- SKIP_EMPTIES(SKIP_BACK, PrePtr);
- SKIP_EMPTIES(SKIP_AHEAD, PstPtr);
-
- CHECKDOTS(CenterDots, dtCDots);
-
- ifn(Front && Back)
- {
- CHECKDOTS(LowDots, dtLDots);
- }
- return(Front & Back);
- }
- else
- return(dtLDots);
-
-}
-
-static STRPTR Dot2Str(enum DotLevel dl)
-{
- STRPTR Retval = INTERNFAULT;
- switch(dl)
- {
- case dtUnknown:
- Retval = "\\cdots or \\ldots";
- break;
- case dtDots:
- Retval = "\\dots";
- break;
- case dtCDots:
- Retval = "\\cdots";
- break;
- case dtLDots:
- Retval = "\\ldots";
- break;
- }
- return Retval;
-}
-
-/*
- * Wipes a command, according to the definition in WIPEARG
- */
-
-static void WipeArgument(STRPTR Cmd, STRPTR CmdPtr)
-{
- ULONG CmdLen = strlen(Cmd);
- STRPTR Format, TmpPtr;
- int c, TmpC;
-
- if(Cmd && *Cmd)
- {
- TmpPtr = &CmdPtr[CmdLen];
- Format = &Cmd[CmdLen + 1];
-
- while(TmpPtr && *TmpPtr && *Format)
- {
- switch(c = *Format++)
- {
- case '*':
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
- if(*TmpPtr == '*')
- TmpPtr++;
- break;
- case '[':
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
- if(*TmpPtr == '[')
- TmpPtr = GetLTXArg(TmpPtr, ArgBuffer, ']', NULL);
- break;
- case '{':
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
- TmpPtr = GetLTXArg(TmpPtr, ArgBuffer, GET_TOKEN, NULL);
- case '}':
- case ']':
- break;
- default:
- PrintPrgErr(pmWrongWipeTemp, &Cmd[strlen(Cmd) + 1]);
- break;
- }
- }
-
- if(TmpPtr)
- strwrite(CmdPtr, VerbClear, TmpPtr - CmdPtr);
- else
- strxrep(CmdPtr, "()[]{}", *VerbClear);
- }
-}
-
-/*
- * Checks italic.
- *
- */
-
-static void CheckItal(const STRPTR Cmd)
-{
- int TmpC;
- STRPTR TmpPtr;
- if(HasWord(Cmd, &NonItalic))
- ItState = itOff;
- elif(HasWord(Cmd, &Italic))
- ItState = itOn;
- elif(HasWord(Cmd, &ItalCmd))
- {
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
- if(*TmpPtr == '{')
- {
- ItFlag = ItState? efItal : efNoItal;
- ItState = itOn;
- }
- }
-}
-
-/*
- * Interpret isolated commands.
- *
- */
-
-static void PerformBigCmd(STRPTR CmdPtr)
-{
- STRPTR TmpPtr,
- ArgEndPtr;
- ULONG CmdLen = strlen(CmdBuffer);
- int TmpC;
- enum ErrNum
- ErrNum;
- struct ErrInfo *ei;
-
- enum DotLevel dotlev, realdl = dtUnknown;
-
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
-
- ArgEndPtr = GetLTXArg(TmpPtr, ArgBuffer, GET_STRIP_TOKEN, NULL);
-
- /* Kill `\verb' commands */
-
- if(WipeVerb)
- {
- if(!strcmp(CmdBuffer, "\\verb"))
- {
- if(*BufPtr)
- {
- if((TmpPtr = strchr(&BufPtr[1], *BufPtr)))
- strwrite(CmdPtr, VerbClear, (TmpPtr - CmdPtr) + 1);
- else
- PSERR(CmdPtr - Buf, 5, emNoArgFound);
- }
- }
- }
-
- if(HasWord(CmdBuffer, &IJAccent))
- {
- if(ArgEndPtr)
- {
- TmpPtr = ArgBuffer;
- SKIP_AHEAD(TmpPtr, TmpC, TmpC == '{'); /* } */
-
- if((*TmpPtr == 'i') || (*TmpPtr == 'j'))
- PrintError(CurStkName(&InputStack), RealBuf,
- CmdPtr - Buf,
- (LONG) strlen(CmdBuffer), Line,
- emAccent, CmdBuffer,
- *TmpPtr, MathMode? "math" : "");
- }
- else
- PSERR(CmdPtr - Buf, CmdLen, emNoArgFound);
- }
-
- if(HasWord(CmdBuffer, &NotPreSpaced) &&
- isspace(CmdPtr[-1]))
- PSERRA(CmdPtr - Buf - 1, 1, emRemPSSpace, CmdBuffer);
-
- if((TmpPtr = HasWord(CmdBuffer, &NoCharNext)))
- {
- STRPTR BPtr = BufPtr;
-
- TmpPtr += strlen(TmpPtr) + 1;
- SKIP_AHEAD(BPtr, TmpC, LATEX_SPACE(TmpC));
-
- if(strchr(TmpPtr, *BPtr))
- {
- PSERR2(CmdPtr - Buf, CmdLen, emNoCharMean,
- CmdBuffer, *BPtr);
- }
- }
-
- if(!strcmp(CmdBuffer, "\\begin") ||
- !strcmp(CmdBuffer, "\\end"))
- {
- if(ArgEndPtr)
- {
- if(!strcmp(ArgBuffer, "document"))
- InHeader = FALSE;
-
- if(CmdBuffer[1] == 'b')
- {
- ifn(PushErr(ArgBuffer, Line, CmdPtr - Buf,
- CmdLen, MakeCpy(),
- &EnvStack))
- PrintPrgErr(pmNoStackMem);
- }
- else
- {
- if((ei = PopErr(&EnvStack)))
- {
- if(strcmp(ei->Data, ArgBuffer))
- PrintError(CurStkName(&InputStack), RealBuf,
- CmdPtr - Buf,
- (LONG) strlen(CmdBuffer),
- Line, emExpectC, ei->Data, ArgBuffer);
-
- FreeErrInfo(ei);
- }
- else
- PrintError(CurStkName(&InputStack), RealBuf,
- CmdPtr - Buf,
- (LONG) strlen(CmdBuffer),
- Line, emSoloC, ArgBuffer);
- }
-
- PerformEnv(ArgBuffer, (BOOL) CmdBuffer[1] == 'b');
- } else
- PSERR(CmdPtr - Buf, CmdLen, emNoArgFound);
- }
-
- CheckItal(CmdBuffer);
-
- if((ErrNum = PerformCommand(CmdBuffer, BufPtr)))
- PSERR(CmdPtr - Buf, CmdLen, ErrNum);
-
- if(!strcmp(CmdBuffer, "\\cdots"))
- realdl = dtCDots;
-
- if(!strcmp(CmdBuffer, "\\ldots"))
- realdl = dtLDots;
-
- if(!strcmp(CmdBuffer, "\\dots"))
- realdl = dtLDots;
-
- if(realdl != dtUnknown)
- {
- dotlev = CheckDots(CmdPtr, BufPtr);
- if(dotlev && (dotlev != realdl))
- {
- TmpPtr = Dot2Str(dotlev);
- PSERRA(CmdPtr - Buf, CmdLen, emEllipsis, TmpPtr);
- }
- }
-
- if((TmpPtr = HasWord(CmdBuffer, &WipeArg)))
- WipeArgument(TmpPtr, CmdPtr);
-}
-
-/*
- * Check user abbreviations. Pass a pointer to the `.';
- * also ensure that it's followed by spaces, etc.
- *
- * Note: We assume that all abbrevs have been transferred from
- * AbbrevCase into Abbrev.
- */
-
-static void CheckAbbrevs(const STRPTR Buffer)
-{
- LONG i;
- STRPTR TmpPtr, AbbPtr;
-
- if(INUSE(emInterWord))
- {
- TmpPtr = TmpBuffer + Abbrev.MaxLen + 2;
- *TmpPtr = 0;
- AbbPtr = Buffer;
-
- for(i = Abbrev.MaxLen;
- i >= 0;
- i--)
- {
- *--TmpPtr = *AbbPtr--;
- if(!isalpha(*AbbPtr) && HasWord(TmpPtr, &Abbrev))
- PSERR(Buffer - Buf + 1, 1, emInterWord);
- if(!*AbbPtr)
- break;
- }
- }
-}
-
-
-/*
- * Check misc. things which can't be included in the main loop.
- *
- */
-
-static void CheckRest(void)
-{
- ULONG Count;
- LONG CmdLen;
- STRPTR UsrPtr;
-
- /* Search for user-specified warnings */
-
- if(INUSE(emUserWarn))
- {
- strcpy(TmpBuffer, Buf);
- FORWL(Count, UserWarn)
- {
- for(UsrPtr = TmpBuffer;
- (UsrPtr = strstr(UsrPtr, UserWarn.Stack.Data[Count]));
- UsrPtr++)
- {
- CmdLen = strlen(UserWarn.Stack.Data[Count]);
- PSERR(UsrPtr - TmpBuffer, CmdLen, emUserWarn);
- }
- }
-
-
- strlwr(TmpBuffer);
-
- FORWL(Count, UserWarnCase)
- {
- for(UsrPtr = TmpBuffer;
- (UsrPtr = strstr(UsrPtr, UserWarnCase.Stack.Data[Count]));
- UsrPtr++)
- {
- CmdLen = strlen(UserWarnCase.Stack.Data[Count]);
- PSERR(UsrPtr - TmpBuffer, CmdLen, emUserWarn);
- }
- }
- }
-}
-
-
-/*
- * Checks that the dash-len is correct.
- */
-
-static void CheckDash(void)
-{
- STRPTR TmpPtr;
- int TmpC;
- LONG TmpCount, Len;
- struct WordList *wl = NULL;
- ULONG i;
- BOOL Errored;
- STRPTR PrePtr = &BufPtr[-2];
-
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, TmpC == '-');
- TmpCount = TmpPtr - BufPtr + 1;
-
- if(MathMode)
- {
- if(TmpCount > 1)
- HERE(TmpCount, emWrongDash);
- }
- else
- {
- if(LATEX_SPACE(*PrePtr) && LATEX_SPACE(*TmpPtr))
- wl = &WordDash;
- if(isdigit(*PrePtr) && isdigit(*TmpPtr))
- wl = &NumDash;
- if(isalpha(*PrePtr) && isalpha(*TmpPtr))
- wl = &HyphDash;
-
- if(wl)
- {
- Errored = TRUE;
- FORWL(i, *wl)
- {
- Len = strtol(wl->Stack.Data[i], NULL, 0);
- if(TmpCount == Len)
- {
- Errored = FALSE;
- break;
- }
- }
- if(Errored)
- HERE(TmpCount, emWrongDash);
- }
- }
-}
-
-/*
- * Pushes and pops nesting characters.
- *
- */
-
-static void HandleBracket(int Char)
-{
- ULONG BrOffset; /* Offset into BrOrder array */
- struct ErrInfo *ei;
- int TmpC, Match;
- TEXT ABuf[2], BBuf[2];
- STRPTR TmpPtr;
-
- AddBracket(Char);
-
- if((BrOffset = BrackIndex(Char)) != ~0UL)
- {
- if(BrOffset & 1) /* Closing bracket of some sort */
- {
- if((ei = PopErr(&CharStack)))
- {
- Match = MatchBracket(*(ei->Data));
- if(ei->Flags & efNoItal)
- {
- if(ItState == itOn)
- {
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, TmpC == '}');
-
- if(!strchr(LTX_SmallPunc, *TmpPtr))
- HERE(1, emNoItFound);
- }
-
- ItState = FALSE;
- }
- elif(ei->Flags & efItal)
- ItState = TRUE;
- FreeErrInfo(ei);
- }
- else
- Match = 0;
-
- if(Match != Char)
- {
- ABuf[0] = Match;
- BBuf[0] = Char;
- ABuf[1] = BBuf[1] = 0;
- if(Match)
- PrintError(CurStkName(&InputStack), RealBuf,
- BufPtr - Buf - 1, 1, Line,
- emExpectC,
- ABuf, BBuf);
- else
- HEREA(1, emSoloC, BBuf);
- }
-
- }
- else /* Opening bracket of some sort */
- {
- if((ei = PushChar(Char, Line, BufPtr - Buf - 1,
- &CharStack, MakeCpy())))
- {
- if(Char == '{')
- {
- switch(ItFlag)
- {
- default:
- ei->Flags = ItFlag;
- ItFlag = efNone;
- break;
- case efNone:
- ei->Flags |= ItState?
- efItal : efNoItal;
- }
- }
- }
-
- else
- PrintPrgErr(pmNoStackMem);
- }
- }
-}
-
-
-
-/*
- * Searches the `Buf' for possible errors, and prints the errors. `Line'
- * is supplied for error printing.
- */
-
-BOOL FindErr(const STRPTR _RealBuf, const ULONG _Line)
-{
- STRPTR
- CmdPtr, /* We'll have to copy each command out. */
- PrePtr, /* Ptr to char in front of command, NULL if
- * the cmd appears as the first character */
- TmpPtr, /* Temporary pointer */
- ErrPtr; /* Ptr to where an error started */
-
- int
- TmpC, /* Just a temp var used throughout the proc.*/
- MatchC,
- Char; /* Char. currently processed */
- ULONG CmdLen; /* Length of misc. things */
- BOOL MixingQuotes;
-
-#if defined(_MSC_VER) && (_MSC_VER < 1300)
- int (* pstcb)(int c);
-#else
- int (CDECL * pstcb)(int c);
-#endif
-
- enum DotLevel dotlev;
-
- LineCpy = NULL;
-
- if(_RealBuf)
- {
- RealBuf = _RealBuf;
- Line = _Line;
-
- BufPtr = PreProcess();
-
- BufPtr = SkipVerb();
-
- while(BufPtr && *BufPtr)
- {
- PrePtr = BufPtr - 1;
- Char = *BufPtr++;
- if(isspace(Char))
- Char = ' ';
-
- switch(Char)
- {
- case '~':
- TmpPtr = NULL;
- if(isspace(*PrePtr))
- TmpPtr = PrePtr;
- elif(isspace(*BufPtr))
- TmpPtr = BufPtr;
-
- if(TmpPtr)
- PSERR(TmpPtr - Buf, 1, emDblSpace);
- break;
-
- case 'X':
- case 'x':
- TmpPtr = PrePtr;
-
- SKIP_BACK(TmpPtr, TmpC,
- (LATEX_SPACE(TmpC) || strchr("{}$", TmpC)));
-
- if(isdigit(*TmpPtr))
- {
- TmpPtr = BufPtr;
-
- SKIP_AHEAD(TmpPtr, TmpC,
- (LATEX_SPACE(TmpC) || strchr("{}$", TmpC)));
-
- if(isdigit(*TmpPtr))
- HERE(1, emUseTimes);
- }
- /* FALLTHRU */
- /* CTYPE: isalpha() */
- case 'a': case 'b': case 'c': case 'd':
- case 'e': case 'f': case 'g': case 'h':
- case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p':
- case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': /* case 'x': */
- case 'y': case 'z':
-
- case 'A': case 'B': case 'C': case 'D':
- case 'E': case 'F': case 'G': case 'H':
- case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P':
- case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': /* case 'X': */
- case 'Y': case 'Z':
- if(!isalpha(*PrePtr) && (*PrePtr != '\\') && MathMode)
- {
- TmpPtr = BufPtr;
- CmdPtr = CmdBuffer;
- do
- {
- *CmdPtr++ = Char;
- Char = *TmpPtr++;
- } while(isalpha(Char));
-
- *CmdPtr = 0;
-
- if(HasWord(CmdBuffer, &MathRoman))
- HEREA(strlen(CmdBuffer), emWordCommand, CmdBuffer);
- }
-
- break;
- case ' ':
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
-
- if(*TmpPtr && *PrePtr)
- {
- if((TmpPtr - BufPtr) > 0)
- {
- HERE(TmpPtr - BufPtr + 1, emMultiSpace);
- strwrite(BufPtr, VerbClear, TmpPtr - BufPtr - 1);
- }
- }
- break;
-
- case '.':
- if((Char == *BufPtr) && (Char == BufPtr[1]))
- {
- dotlev = CheckDots(&PrePtr[1], &BufPtr[2]);
- TmpPtr = Dot2Str(dotlev);
- HEREA(3, emEllipsis, TmpPtr);
- }
-
- /* Regexp: "([^A-Z@.])\.[.!?:;]*\s+[a-z]" */
-
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, strchr(LTX_GenPunc, TmpC));
- if(LATEX_SPACE(*TmpPtr))
- {
- if(!isupper(*PrePtr) && (*PrePtr != '@') &&
- (*PrePtr != '.'))
- {
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
- if(islower(*TmpPtr))
- PSERR(BufPtr - Buf, 1, emInterWord);
- else
- CheckAbbrevs(&BufPtr[-1]);
- }
- }
-
- /* FALLTHRU */
- case ':': case '?': case '!': case ';':
- /* Regexp: "[A-Z][A-Z][.!?:;]\s+" */
-
- if(isspace(*BufPtr) && isupper(*PrePtr) &&
- (isupper(PrePtr[-1]) || (Char != '.')))
- HERE(1, emInterSent);
-
- /* FALLTHRU */
- case ',':
- if(isspace(*PrePtr) &&
- !(isdigit(*BufPtr) &&
- ((BufPtr[-1] == '.') || (BufPtr[-1] == ','))))
- PSERR(PrePtr - Buf, 1, emSpacePunct);
-
- if(MathMode &&
- (((*BufPtr == '$') && (BufPtr[1] != '$')) ||
- (!strafter(BufPtr, "\\)"))))
- HEREA(1, emPunctMath, "outside inner");
-
- if(!MathMode &&
- (((*PrePtr == '$') && (PrePtr[-1] == '$')) ||
- (!strinfront(PrePtr, "\\]"))))
- HEREA(1, emPunctMath, "inside display");
-
- break;
- case '\'':
- case '`':
- if((Char == *BufPtr) && (Char == BufPtr[1]))
- {
- PrintError(CurStkName(&InputStack), RealBuf,
- BufPtr - Buf - 1, 3, Line,
- emThreeQuotes,
- Char, Char, Char,
- Char, Char, Char);
- }
-
- if(Char == '\'')
- MatchC = '`';
- else
- MatchC = '\'';
-
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, TmpC == Char);
-
- MixingQuotes = FALSE;
-
- if((*TmpPtr == MatchC) || (*TmpPtr == '\"') ||
- (*TmpPtr == '´'))
- MixingQuotes = TRUE;
-
- SKIP_AHEAD(TmpPtr, TmpC, strchr("`\'\"´", TmpC));
-
- if(MixingQuotes)
- HERE(TmpPtr - BufPtr + 1, emQuoteMix);
-
- switch(Char)
- {
- case '\'':
- if(isalpha(*TmpPtr) &&
- (strchr(LTX_GenPunc, *PrePtr) || isspace(*PrePtr)))
- HERE(TmpPtr - BufPtr + 1, emBeginQ);
-
- /* Now check quote style */
-#define ISPUNCT(ptr) (strchr(LTX_GenPunc, *ptr) && (ptr[-1] != '\\'))
-
- /* We ignore all single words/abbreviations in quotes */
-
- {
- STRPTR WordPtr = PrePtr;
- SKIP_BACK(WordPtr, TmpC, (isalnum(TmpC) ||
- strchr(LTX_GenPunc, TmpC)));
-
- if(*WordPtr != '`')
- {
- if(*PrePtr && (Quote != quTrad) && ISPUNCT(PrePtr))
- PSERRA(PrePtr - Buf, 1, emQuoteStyle,
- "in front of");
-
- if(*TmpPtr && (Quote != quLogic) &&
- ISPUNCT(TmpPtr))
- PSERRA(TmpPtr - Buf, 1, emQuoteStyle, "after");
- }
- }
-
- break;
- case '`':
- if(isalpha(*PrePtr) &&
- (strchr(LTX_GenPunc, *TmpPtr) || isspace(*TmpPtr)))
- HERE(TmpPtr - BufPtr + 1, emEndQ);
- break;
- }
- BufPtr = TmpPtr;
- break;
- case '"':
- HERE(1, emUseQuoteLiga);
- break;
-
- /* One of these are unnecessary, but what the heck... */
- case 180: /* ´. NOTE: '\xb4' gets converted to - something*/
- case ~(0xff &(~180)): /* This yields 0xff...fb4 in */
- /* arbitrary precision. */
-
- HERE(1, emUseOtherQuote);
- break;
-
- case '_':
- case '^':
- if(*PrePtr != '\\')
- {
- TmpPtr = PrePtr;
- SKIP_BACK(TmpPtr, TmpC, LATEX_SPACE(TmpC));
-
- CmdLen = 1;
-
- switch(*TmpPtr)
- {
- /*{*/
- case '}':
- if(PrePtr[-1] != '\\')
- break;
-
- CmdLen++;
- PrePtr--;
- /* FALLTHRU */
- /*[(*/
- case ')':
- case ']':
- PSERR(PrePtr - Buf, CmdLen, emEnclosePar);
- }
-
- TmpPtr = BufPtr;
- SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
-
- ErrPtr = TmpPtr;
-
- if(isalpha(*TmpPtr))
- pstcb = &my_isalpha;
- elif(isdigit(*TmpPtr))
- pstcb = &my_isdigit;
- else
- break;
-
- while((*pstcb)(*TmpPtr++))
- ;
- TmpPtr--;
-
- if((TmpPtr - ErrPtr) > 1)
- PSERR(ErrPtr - Buf, TmpPtr - ErrPtr, emEmbrace);
- }
- break;
- case '-':
- CheckDash();
- break;
- case '\\': /* Command encountered */
- BufPtr = GetLTXToken(--BufPtr, CmdBuffer);
-
- if(LATEX_SPACE(*PrePtr))
- {
- if(HasWord(CmdBuffer, &Linker))
- PSERR(PrePtr - Buf, 1, emNBSpace);
- if(HasWord(CmdBuffer, &PostLink))
- PSERR(PrePtr - Buf, 1, emFalsePage);
- }
-
- if(LATEX_SPACE(*BufPtr) && !MathMode &&
- (!HasWord(CmdBuffer, &Silent)) &&
- (strlen(CmdBuffer) != 2))
- {
- PSERR(BufPtr - Buf, 1, emSpaceTerm);
- }
- elif((*BufPtr == '\\') && (!isalpha(BufPtr[1])) &&
- (!LATEX_SPACE(BufPtr[1])))
- PSERR(BufPtr - Buf, 2, emNotIntended);
-
- PerformBigCmd(PrePtr + 1);
- BufPtr = SkipVerb();
-
- break;
-
- LOOP(bracket,
- case '(':
- ifn(!*PrePtr || LATEX_SPACE(*PrePtr) || isdigit(*PrePtr) ||
- strchr("([{`~", *PrePtr))
- {
- if(PrePtr[-1] != '\\') /* Short cmds */
- {
- TmpPtr = PrePtr;
- SKIP_BACK(TmpPtr, TmpC, istex(TmpC));
- if(*TmpPtr != '\\') /* Long cmds */
- PSERRA(BufPtr - Buf - 1, 1, emSpaceParen,
- "in front of");
- }
- }
- if(isspace(*BufPtr))
- PSERRA(BufPtr - Buf, 1, emNoSpaceParen, "after");
-
- LAST(bracket);
- case ')':
- if(isspace(*PrePtr))
- PSERRA(BufPtr - Buf - 1, 1, emNoSpaceParen,
- "in front of");
- if(isalpha(*BufPtr))
- PSERRA(BufPtr - Buf, 1, emSpaceParen, "after");
-
- LAST(bracket);
- )
-
- case '}':
- case '{':
- case '[':
- case ']':
- HandleBracket(Char);
- break;
- case '$':
- if(*PrePtr != '\\')
- {
- if(*BufPtr == '$')
- BufPtr++;
- MathMode ^= TRUE;
- }
-
- break;
- }
- }
-
- if(!VerbMode)
- {
- CheckRest();
- }
- }
-
- return(TRUE);
-}
-
-/*
- * Tries to create plural forms for words. Put a '%s' where a
- * suffix should be put, e.g. "warning%s". Watch your %'s!
- */
-
-static void Transit(FILE *fh, ULONG Cnt, STRPTR Str)
-{
- switch(Cnt)
- {
- case 0:
- fputs("No ", fh);
- fprintf(fh, Str, "s");
- break;
- case 1:
- fputs("One ", fh);
- fprintf(fh, Str, "");
- break;
- default:
- fprintf(fh, "%ld ", Cnt);
- fprintf(fh, Str, "s");
- break;
- }
-}
-
-/*
- * Prints the status/conclusion after doing all the testing, including
- * bracket stack status, math mode, etc.
- */
-
-void PrintStatus(ULONG Lines)
-{
- ULONG Cnt;
- struct ErrInfo *ei;
-
-
- while((ei = PopErr(&CharStack)))
- {
- PrintError(ei->File, ei->LineBuf, ei->Column,
- ei->ErrLen, ei->Line, emNoMatchC,
- (STRPTR) ei->Data);
- FreeErrInfo(ei);
- }
-
- while((ei = PopErr(&EnvStack)))
- {
- PrintError(ei->File, ei->LineBuf, ei->Column,
- ei->ErrLen, ei->Line, emNoMatchC,
- (STRPTR) ei->Data);
- FreeErrInfo(ei);
- }
-
- if(MathMode)
- {
- PrintError(CurStkName(&InputStack), "", 0L, 0L, Lines,
- emMathStillOn);
- }
-
- for(Cnt = 0L; Cnt < (NUMBRACKETS>>1); Cnt++)
- {
- if(Brackets[Cnt << 1] != Brackets[(Cnt << 1) + 1])
- {
- PrintError(CurStkName(&InputStack), "", 0L, 0L, Lines,
- emNoMatchCC,
- BrOrder[Cnt<<1], BrOrder[(Cnt<<1) + 1]);
- }
- }
-
- if(!Quiet)
- {
- Transit(stderr, ErrPrint, "error%s printed; ");
- Transit(stderr, WarnPrint, "warning%s printed; ");
- Transit(stderr, UserSupp, "user suppressed warning%s printed.\n");
- }
-}
-
-
-
-/*
- * Uses OutputFormat. Be sure that `String'
- * does not contain tabs, newlines, etc.
- * Prints a formatted string. Formatting codes understood:
- * %b - string to print Between fields (from -s option)
- * %c - Column position of error
- * %d - lenght of error (Digit)
- * %f - current Filename
- * %i - Turn on inverse printing mode.
- * %I - Turn off inverse printing mode.
- * %k - Kind of error (warning, error, message)
- * %l - Line number of error
- * %m - warning Message
- * %n - warning Number
- * %u - an Underlining line (like the one which appears when using -v1)
- * %r - part of line in front of error ('S' - 1)
- * %s - part of line which contains error (String) * %t - part of line after error ('S' + 1)
- */
-
-
-void PrintError(const STRPTR File, const STRPTR String,
- const LONG Position, const LONG Len,
- const LONG LineNo, const enum ErrNum Error, ...)
-{
- static /* Just to reduce stack usage... */
- TEXT PrintBuffer[BUFSIZ];
- va_list MsgArgs;
-
- STRPTR LastNorm = OutputFormat, of;
- int c;
-
- enum Context Context;
-
- if(betw(emMinFault, Error, emMaxFault))
- {
- switch(LaTeXMsgs[Error].InUse)
- {
- case iuOK:
- do
- {
- Context = LaTeXMsgs[Error].Context;
-
- if(!HeadErrOut)
- Context |= ctOutHead;
-
-#define RGTCTXT(Ctxt, Var) if((Context & Ctxt) && !(Var)) break;
-
- RGTCTXT(ctInMath, MathMode);
- RGTCTXT(ctOutMath, !MathMode);
- RGTCTXT(ctInHead, InHeader);
- RGTCTXT(ctOutHead, !InHeader);
-
- switch(LaTeXMsgs[Error].Type)
- {
- case etWarn:
- WarnPrint++;
- break;
- case etErr:
- ErrPrint++;
- break;
- case etMsg:
- break;
- }
-
- while((of = strchr(LastNorm, '%')))
- {
- c = *of;
- *of = 0;
-
- fputs(LastNorm, OutputFile);
-
- *of++ = c;
-
- switch(c = *of++)
- {
- case 'b':
- fputs(Delimit, OutputFile);
- break;
- case 'c':
- fprintf(OutputFile, "%ld", Position + 1);
- break;
- case 'd':
- fprintf(OutputFile, "%ld", Len);
- break;
- case 'f':
- fputs(File, OutputFile);
- break;
- case 'i':
- fputs(ReverseOn, OutputFile);
- break;
- case 'I':
- fputs(ReverseOff, OutputFile);
- break;
- case 'k':
- switch(LaTeXMsgs[Error].Type)
- {
- case etWarn:
- fprintf(OutputFile, "Warning");
- break;
- case etErr:
- fprintf(OutputFile, "Error");
- break;
- case etMsg:
- fprintf(OutputFile, "Message");
- break;
- }
- break;
- case 'l':
- fprintf(OutputFile, "%ld", LineNo);
- break;
- case 'm':
- va_start(MsgArgs, Error);
- vfprintf(OutputFile, LaTeXMsgs[Error].Message,
- MsgArgs);
- va_end(MsgArgs);
- break;
- case 'n':
- fprintf(OutputFile, "%d", Error);
- break;
- case 'u':
- sfmemset(PrintBuffer, ' ', (LONG) Position);
-
- sfmemset(&PrintBuffer[Position], '^', Len);
- PrintBuffer[Position + Len] = 0;
- fputs(PrintBuffer, OutputFile);
- break;
- case 'r':
- substring(String, PrintBuffer, 0L, Position);
- fputs(PrintBuffer, OutputFile);
- break;
- case 's':
- substring(String, PrintBuffer, Position, Len);
- fputs(PrintBuffer, OutputFile);
- break;
- case 't':
- substring(String, PrintBuffer, Position + Len, LONG_MAX);
- fputs(PrintBuffer, OutputFile);
- break;
- default:
- fputc(c, OutputFile);
- break;
- }
- LastNorm = of;
- }
- fputs(LastNorm, OutputFile);
- } while(FALSE);
- break;
- case iuNotUser:
- UserSupp++;
- break;
- case iuNotSys:
- break;
- }
- }
-}
-
-/*
- * All commands isolated is routed through this command, so we can
- * update global statuses like math mode and whether @ is a letter
- * or not.
- */
-
-static enum ErrNum PerformCommand(const STRPTR Cmd, STRPTR Arg)
-{
- STRPTR Argument = "";
- enum ErrNum
- en = emMinFault;
- int TmpC;
-
- if(!strcmp(Cmd, "\\makeatletter"))
- AtLetter = TRUE;
- elif(!strcmp(Cmd, "\\makeatother"))
- AtLetter = FALSE;
- elif(InputFiles &&
- !(strcmp(Cmd, "\\input") && strcmp(Cmd, "\\include")))
- {
- SKIP_AHEAD(Arg, TmpC, LATEX_SPACE(TmpC));
- if(*Arg == '{') /* } */
- {
- if(GetLTXArg(Arg, TmpBuffer, GET_STRIP_TOKEN, NULL))
- Argument = TmpBuffer;
- }
- else
- Argument = strip(Arg, STRP_BTH);
-
- ifn(Argument && PushFileName(Argument, &InputStack))
- en = emNoCmdExec;
- }
- elif(HasWord(Cmd, &Primitives))
- en = emTeXPrim;
- elif(*Cmd == '\\')
- {
- /* Quicker check of single lettered commands. */
- switch(Cmd[1])
- {
- case '(':
- case '[':
- MathMode = TRUE;
- break;
- case ']':
- case ')':
- MathMode = FALSE;
- break;
- case '/':
- switch(ItState)
- {
- case itOn:
- ItState = itCorrected;
- Argument = Arg;
-
- SKIP_AHEAD(Argument, TmpC, TmpC == '{' || TmpC == '}');
-
- if(strchr(".,", *Argument))
- en = emItPunct;
-
- break;
- case itCorrected:
- en = emItDup;
- break;
- case itOff:
- en = emItInNoIt;
- }
- break;
- }
- }
-
- return(en);
-}