/* * * (c) COPYRIGHT INRIA, Grif, 1996. * Please first read the full copyright statement in file COPYRIGHT. * */ /* * Warning: * This module is part of the Thot library, which was originally * developed in French. That's why some comments are still in * French, but their translation is in progress and the full module * will be available in English in the next release. * */ /* * Ce programme compile un schema de presentation contenu dans un fichier * de type .P * Il est dirige par la grammaire du langage de presentation * contenue, sous forme codee, dans le fichier PRESEN.GRM. * Il produit un fichier de type .PRS qui sera ensuite utilise par Thot * * Authors: V. Quint (INRIA) * C. Roisin (INRIA) - Columns and pages * */ #include "thot_sys.h" #include "constgrm.h" #include "constmedia.h" #include "compilmsg.h" #include "prsmsg.h" #include "message.h" #include "typemedia.h" #include "typegrm.h" #include "fileaccess.h" #include "prsdef.h" #include "thotpattern.h" #include "fileaccess.h" #include "thotdir.h" #define THOT_EXPORT #include "compil_tv.h" #include "thotcolor.h" #include "thotcolor_tv.h" #include "thotpalette_tv.h" #undef THOT_EXPORT #define THOT_EXPORT extern #include "analsynt_tv.h" #include "compil_tv.h" int LineNum; /* compteur de lignes dans le fichier source */ static PtrPSchema pPSchema; /* Schema de presentation genere */ static PtrSSchema pSSchema; /* Schema de structure */ static int CurView; /* numero de la vue courante */ static PtrPRule FirstRule; /* pointeur sur la premiere regle de la suite de regles courante */ static PtrPRule CurRule; /* pointeur sur la regle de present. courante */ static PtrPRule NextRule; /* pointeur sur la regle de present. suivante */ static int CurAttrNum; /* numero de l'attribut en cours */ static int CurAttrVal; /* numero de la valeur d'attribut en cours */ static int CurComparAttr; /* numero de l'attribut de comparaison */ static int CurElemHeritAttr; /* numero de l'element heritant de cet attribut */ static int CurAttrLowerBound; /* borne inferieure de comparaison */ static int CurAttrUpperBound; /* borne superieure de comparaison */ static Name CurTextEqual; /* valeur d'attribut textuel */ static int CurType; /* numero de la regle de structure definissant le type dont on analyse les regles de presentation */ static int CurPresBox; /* numero de la boite de presentation courante */ static boolean ViewDef; /* on est dans la definition des vues du doc. */ static boolean CounterDef; /* on est dans la definition des compteurs */ static boolean ConstantDef; /* on est dans la definition des constantes */ static boolean VariableDef; /* on est dans la definition des variables */ static CounterValue CurMinMax; /* SyntacticType de la valeur du compteur */ static boolean PresBoxDef; /* on est dans la definition des boites */ static boolean DefaultRuleDef; /* on est dans la definition des regles par defaut */ static boolean RuleDef; /* on est dans la definition des regles */ static boolean AttributeDef; /* on est dans la definition des attributs */ static boolean NewAttributeDef; /* definition d'un nouveau paquet de regles de presentation d'un attribut */ static int TransmittedCounter; /* numero du compteur dont on traite la regle de transmission */ static int TransmittedElem; /* type de l'element dont on traite la regle de transmission */ static boolean InBreakRule; /* on est dans une regle 'Break' */ static boolean InPageBreakRule; /* on est dans une regle 'PageBreak' */ static boolean InLineBreakRule; /* on est dans une regle 'LineBreak' */ static boolean InGatherRule; /* on est dans une regle 'Gather' */ static boolean InInLineRule; /* on est dans une regle 'InLine' */ static boolean IncludedColumn; static boolean InRule; /* on est dans une regle */ static boolean InWithinCond; /* on est dans une condition 'Within' */ static boolean AxisDef; /* le prochain repere boite rencontre est une definition de repere */ static boolean Forward; /* on est dans une reference en avant pour une boite */ static boolean CondBlock; /* on est dans un bloc de condition */ static boolean ViewBlock; /* on est dans un bloc de vues */ static boolean RuleBlock; /* on est dans un bloc de regles */ static boolean RulesForView; /* on est dans les regles d'une vue */ static boolean NewVariableDef; /* on definit une nouvelle variable */ static int LatestNumber; /* valeur absolue du dernier nombre recontre */ static boolean LatestNumberAttr; /* LatestNumber est un numero d'attribut numerique */ static int PrevSign; /* signe du dernier nombre rencontre */ static int AncestorSign; /* signe du dernier niveau d'ancetre rencontre' dans un compteur */ static enum { Centimeter, Millimeter, Point, Pica, Inch, ScreenPixel, FontHeight, XHeight, Percent } CurUnit; static int AttrValSign; /* signe (+1 ou -1) de la derniere valeur d'attribut rencontree (AttrRelat) */ static PtrCondition Conditions; /* les conditions du IF */ static boolean Immediately; /* Pour les conditions avec Immediately Within */ static boolean SignGreaterOrLess; /* il y a un signe > ou < dans la condition Within en cours de traitement */ static int CurCondCntSign; /* signe dans une condition */ static Name CopyType; /* nom du type qui apparait dans la regle Copy */ static int BeginCopyType; /* indice dans la ligne du debut de ce nom */ static PtrSSchema pExternalSS; /* pointeur sur le schema de structure externe */ static boolean InCondPage; /* on est dans une condition Even, Odd ou One */ static boolean InclusionRefName; /* le nom de type qui suit doit etre interprete comme le nom d'une reference d'inclusion sans expansion */ static boolean VCondLess; /* on est dans une condition 'Less' */ static boolean VCondGreater; /* on est dans une condition 'Greater' */ static boolean CondEqual; /* on est dans une condition 'Equal' */ static boolean FirstInPair; /* on a rencontre' "First" */ static boolean SecondInPair; /* on a rencontre' "Second" */ static boolean AttrInitCounter; /* on a rencontre' "Init" dans une definition de compteur */ #include "compilmsg_f.h" #include "fileaccess_f.h" #include "parser_f.h" #include "platform_f.h" #include "prs_f.h" #include "memory_f.h" #include "message_f.h" #include "readstr_f.h" #include "registry_f.h" #include "writeprs_f.h" /*---------------------------------------------------------------------- Initialize ----------------------------------------------------------------------*/ #ifdef __STDC__ static void Initialize () #else /* __STDC__ */ static void Initialize () #endif /* __STDC__ */ { int i; /* acquiert un schema de presentation */ GetSchPres (&pPSchema); if (pPSchema == NULL) /* memoire insuffisante */ CompilerMessage (0, PRS, FATAL, NO_MORE_MEM_LEFT, inputLine, LineNum); else { /* acquiert un schema de structure pour les structures externes */ GetSchStruct (&pExternalSS); if (pExternalSS == NULL) TtaDisplaySimpleMessage (FATAL, PRS, NO_MORE_MEM_LEFT); else { CurMinMax = CntCurVal; /* initialise les regles de presentation des elements */ for (i = 0; i < MAX_RULES_SSCHEMA; i++) { pPSchema->PsAcceptPageBreak[i] = True; pPSchema->PsAcceptLineBreak[i] = True; } /* initialise les boites de presentation */ for (i = 0; i < MAX_PRES_BOX; i++) { pPSchema->PsPresentBox[i].PbAcceptPageBreak = True; pPSchema->PsPresentBox[i].PbAcceptLineBreak = True; } /* initialise les indicateurs du compilateur */ ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = False; PresBoxDef = False; DefaultRuleDef = False; RuleDef = False; AttributeDef = False; NewAttributeDef = False; InBreakRule = False; InPageBreakRule = False; InLineBreakRule = False; InGatherRule = False; InInLineRule = False; IncludedColumn = False; InRule = False; InWithinCond = False; AxisDef = False; Forward = False; CondBlock = False; ViewBlock = False; RuleBlock = False; RulesForView = False; NewVariableDef = False; LatestNumber = 0; LatestNumberAttr = False; PrevSign = 1; CurUnit = FontHeight; AttrValSign = 1; CurView = 1; CurRule = NULL; FirstRule = NULL; CurType = 1; GetPresentRule (&NextRule); if (NextRule == NULL) /* memoire insuffisante */ CompilerMessage (0, PRS, FATAL, NO_MORE_MEM_LEFT, inputLine, LineNum); Conditions = NULL; InclusionRefName = False; CopyType[0] = '\0'; BeginCopyType = 0; FirstInPair = False; SecondInPair = False; } } } /*---------------------------------------------------------------------- CopyName copy the word of length wl startig at position wi in buffer inputLine into string n. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CopyName (Name n, indLine wi, indLine wl) #else /* __STDC__ */ static void CopyName (n, wi, wl) Name n; indLine wi; indLine wl; #endif /* __STDC__ */ { if (wl > MAX_NAME_LENGTH - 1) CompilerMessage (wi, PRS, FATAL, WORD_SIZE_OVERFLOW, inputLine, LineNum); else { strncpy (n, &inputLine[wi - 1], MAX_NAME_LENGTH); n[wl] = '\0'; } } /*---------------------------------------------------------------------- CheckConditions verifie qu'il n'y a aucune condition courante ou qu'il n'y a que des conditions Within. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CheckConditions (indLine wi) #else /* __STDC__ */ static void CheckConditions (wi) indLine wi; #endif /* __STDC__ */ { PtrCondition pCond; pCond = Conditions; while (pCond != NULL) if (pCond->CoCondition != PcWithin && pCond->CoCondition != PcDefaultCond && pCond->CoCondition != PcElemType) { CompilerMessage (wi, PRS, FATAL, ONLY_CONDITION_WITHIN, inputLine, LineNum); pCond = NULL; } else pCond = pCond->CoNextCondition; } /*---------------------------------------------------------------------- ConditionEnd ----------------------------------------------------------------------*/ static void ConditionEnd () { InWithinCond = False; if (CopyType[0] != '\0') /* on n'a pas encore traite' le nom de type suppose' externe */ /* ce nom de type est donc erronne' */ { CompilerMessage (BeginCopyType, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); CopyType[0] = '\0'; BeginCopyType = 0; } } /*---------------------------------------------------------------------- CreatePRule cree une nouvelle regle de type t ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CreatePRule (PRuleType t, indLine wi) #else /* __STDC__ */ static void CreatePRule (t, wi) PRuleType t; indLine wi; #endif /* __STDC__ */ { PtrPRule pPRuleV; ConditionEnd (); if (t != PtFunction) /* ce n'est pas une regle fonction. Verifie qu'il n'y a que des conditions Within parmi les conditions courantes */ CheckConditions (wi); CurRule = NextRule; GetPresentRule (&NextRule); if (NextRule == NULL) /*memoire insuffisante */ CompilerMessage (0, PRS, FATAL, NO_MORE_MEM_LEFT, inputLine, LineNum); CurRule->PrType = t; CurRule->PrCond = Conditions; CurRule->PrNextPRule = NextRule; CurRule->PrViewNum = CurView; CurRule->PrPresMode = PresImmediate; switch (t) { case PtVisibility: case PtDepth: case PtFillPattern: case PtBackground: case PtForeground: CurRule->PrAttrValue = False; CurRule->PrIntValue = 0; break; case PtFont: CurRule->PrChrValue = 'T'; /* Times par defaut */ break; case PtStyle: CurRule->PrChrValue = 'R'; /* Romain par defaut */ break; case PtUnderline: CurRule->PrChrValue = 'N'; /* Pas de souligne par defaut */ break; case PtThickness: CurRule->PrChrValue = 'N'; /* souligne mince par defaut */ break; case PtLineStyle: CurRule->PrChrValue = 'S'; /* trait continu par defaut */ break; case PtBreak1: case PtBreak2: case PtIndent: case PtSize: case PtLineSpacing: case PtLineWeight: CurRule->PrMinUnit = UnRelative; CurRule->PrMinAttr = False; CurRule->PrMinValue = 0; CurRule->PrInhMinOrMax = 0; CurRule->PrInhDelta = 0; CurRule->PrMinMaxAttr = False; break; case PtAdjust: CurRule->PrAdjust = AlignLeft; break; case PtVertRef: case PtHorizRef: case PtVertPos: case PtHorizPos: CurRule->PrPosRule.PoPosDef = NoEdge; CurRule->PrPosRule.PoPosRef = NoEdge; CurRule->PrPosRule.PoDistUnit = UnRelative; CurRule->PrPosRule.PoDistAttr = False; CurRule->PrPosRule.PoDistance = 0; CurRule->PrPosRule.PoRelation = RlSameLevel; CurRule->PrPosRule.PoNotRel = False; CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoUserSpecified = False; CurRule->PrPosRule.PoRefPresBox = 0; break; case PtHeight: case PtWidth: CurRule->PrDimRule.DrPosition = False; CurRule->PrDimRule.DrAbsolute = True; CurRule->PrDimRule.DrUnit = UnRelative; CurRule->PrDimRule.DrAttr = False; CurRule->PrDimRule.DrValue = 0; CurRule->PrDimRule.DrRelation = RlSameLevel; CurRule->PrDimRule.DrNotRelat = False; CurRule->PrDimRule.DrRefElement = True; CurRule->PrDimRule.DrMin = False; CurRule->PrDimRule.DrUserSpecified = False; CurRule->PrDimRule.DrTypeRefElem = 0; break; default: break; } /* verifie que cette regle n'est pas deja presente pour cette vue */ pPRuleV = FirstRule; while (pPRuleV != NULL && pPRuleV != CurRule) { if (pPRuleV->PrViewNum == CurView) if (pPRuleV->PrType == t) if (t != PtFunction) /* seules les fonctions peuvent etre en plusieurs exemplaires */ if (pPRuleV->PrCond == NULL) /* les regles sans condition ne peuvent pas figurer en plusieurs exemplaires */ CompilerMessage (wi, PRS, FATAL, RULE_ALREADY_DEFINED, inputLine, LineNum); pPRuleV = pPRuleV->PrNextPRule; } } /*---------------------------------------------------------------------- SetLevel ----------------------------------------------------------------------*/ #ifdef __STDC__ static void SetLevel (Level lev, indLine wi) #else /* __STDC__ */ static void SetLevel (lev, wi) Level lev; indLine wi; #endif /* __STDC__ */ { if ((CurRule->PrType == PtVertRef || CurRule->PrType == PtHorizRef) && !(lev == RlEnclosed || lev == RlSelf)) CompilerMessage (wi, PRS, FATAL, ONLY_ENCLOSED_AND_ARE_ALLOWED, inputLine, LineNum); else if (lev == RlEnclosed && (CurRule->PrType == PtVertPos || CurRule->PrType == PtHorizPos)) /* position par rapport au contenu, erreur */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_A_POSITION, inputLine, LineNum); else switch (CurRule->PrType) { case PtVertRef: case PtHorizRef: case PtVertPos: case PtHorizPos: CurRule->PrPosRule.PoRelation = lev; break; case PtHeight: case PtWidth: if (CurRule->PrDimRule.DrPosition) CurRule->PrDimRule.DrPosRule.PoRelation = lev; else CurRule->PrDimRule.DrRelation = lev; break; default: break; } } /*---------------------------------------------------------------------- CheckBoxEnd ----------------------------------------------------------------------*/ static void CheckBoxEnd () { if (PresBoxDef) /* fin des regles de presentation d'une boite */ { if (pPSchema->PsPresentBox[CurPresBox - 1].PbFirstPRule == NextRule) /* aucune regle (seulement 'Content') */ pPSchema->PsPresentBox[CurPresBox - 1].PbFirstPRule = NULL; } if (CurRule != NULL) CurRule->PrNextPRule = NULL; } /*---------------------------------------------------------------------- EndOfRulesForType fin des regles de presentation associees a un type d'element structure' ou a une valeur d'attribut. On verifie si au moins une regle a ete definie pour ce type ou cet attribut. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void EndOfRulesForType () #else /* __STDC__ */ static void EndOfRulesForType () #endif /* __STDC__ */ { AttributePres *pPRuleA; NumAttrCase *pAttrCase; int l; if (RuleDef) if (pPSchema->PsElemPRule[CurType - 1] == NextRule) /* aucune regle de presentation pour ce type d'element */ pPSchema->PsElemPRule[CurType - 1] = NULL; if (AttributeDef) { pPRuleA = pPSchema->PsAttrPRule[CurAttrNum - 1]; for (l = pPSchema->PsNAttrPRule[CurAttrNum - 1]; --l > 0; pPRuleA = pPRuleA->ApNextAttrPres) if (pPRuleA->ApElemType == CurElemHeritAttr) break; if (pPRuleA) { /* selon le type de l'attribut */ switch (pSSchema->SsAttribute[CurAttrNum - 1].AttrType) { case AtNumAttr: pAttrCase = &pPRuleA->ApCase[pPRuleA->ApNCases - 1]; if (pAttrCase->CaFirstPRule == NextRule) pAttrCase->CaFirstPRule = NULL; break; case AtTextAttr: if (pPRuleA->ApTextFirstPRule == NextRule) pPRuleA->ApTextFirstPRule = NULL; break; case AtReferenceAttr: if (pPRuleA->ApRefFirstPRule == NextRule) pPRuleA->ApRefFirstPRule = NULL; break; case AtEnumAttr: if (pPRuleA->ApEnumFirstPRule[CurAttrVal] == NextRule) pPRuleA->ApEnumFirstPRule[CurAttrVal] = NULL; break; default: break; } } } } /*---------------------------------------------------------------------- NewVarListItem alloue une nouvelle entree dans la table des items constituant une variable de presentation. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewVarListItem (PresVariable * pVar, indLine wi) #else /* __STDC__ */ static void NewVarListItem (pVar, wi) PresVariable *pVar; indLine wi; #endif /* __STDC__ */ { if (pVar->PvNItems > 0) /* ce n'est pas le premier element de la variable */ /* si le 1er element n'est pas du texte, on n'accepte pas le */ /* nouvel element */ if (pVar->PvItem[0].ViType == VarText) if (pPSchema->PsConstant[pVar->PvItem[0].ViConstant - 1].PdType != CharString) CompilerMessage (wi, PRS, FATAL, MAX_FUNCTIONS_IN_A_VARIABLE_OVERFLOW, inputLine, LineNum); if (pVar->PvNItems >= MAX_PRES_VAR_ITEM) CompilerMessage (wi, PRS, FATAL, MAX_FUNCTIONS_IN_A_VARIABLE_OVERFLOW, inputLine, LineNum); else pVar->PvNItems++; } /*---------------------------------------------------------------------- NewCondition alloue une nouvelle condition ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewCondition (indLine wi) #else /* __STDC__ */ static void NewCondition (wi) indLine wi; #endif /* __STDC__ */ { PtrCondition newCond; /* acquiert un bloc memoire pour une nouvelle condition */ GetPresentRuleCond (&newCond); if (newCond == NULL) /*memoire insuffisante */ CompilerMessage (0, PRS, FATAL, NO_MORE_MEM_LEFT, inputLine, LineNum); else { Immediately = False; /* chaine la nouvelle condition en tete */ newCond->CoNextCondition = Conditions; Conditions = newCond; /* initialise la nouvelle condition */ newCond->CoNotNegative = True; newCond->CoTarget = False; CurCondCntSign = 1; InCondPage = False; } } /*---------------------------------------------------------------------- NewConst alloue une nouvelle entree dans la table des constantes du schema de presentation ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewConst (indLine wi) #else /* __STDC__ */ static void NewConst (wi) indLine wi; #endif /* __STDC__ */ { if (pPSchema->PsNConstants >= MAX_PRES_CONST) CompilerMessage (wi, PRS, FATAL, MAX_CONSTANTS_OVERFLOW, inputLine, LineNum); else { pPSchema->PsConstant[pPSchema->PsNConstants].PdAlphabet = 'L'; pPSchema->PsConstant[pPSchema->PsNConstants].PdType = CharString; pPSchema->PsNConstants++; } } /*---------------------------------------------------------------------- NewVar alloue une nouvelle entree dans la table des variables variables du schema de presentation ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewVar (indLine wi) #else /* __STDC__ */ static void NewVar (wi) indLine wi; #endif /* __STDC__ */ { if (pPSchema->PsNVariables >= MAX_PRES_VARIABLE) CompilerMessage (wi, PRS, FATAL, MAX_VARIABLES_OVERFLOW, inputLine, LineNum); else pPSchema->PsVariable[pPSchema->PsNVariables++].PvNItems = 0; } /*---------------------------------------------------------------------- Round arrondit un float en un int. ----------------------------------------------------------------------*/ #ifdef __STDC__ static int Round (float e) #else /* __STDC__ */ static int Round (e) float e; #endif /* __STDC__ */ { register int result; if (e < 0.0) result = e - 0.5; else result = e + 0.5; return result; } /*---------------------------------------------------------------------- EndOfNumber ----------------------------------------------------------------------*/ #ifdef __STDC__ static void EndOfNumber () #else /* __STDC__ */ static void EndOfNumber () #endif /* __STDC__ */ { TypeUnit unit; unit = UnRelative; if (LatestNumber != 0) { if (LatestNumberAttr) /* on ne convertit pas les numeros d'attribut */ switch (CurUnit) { case Centimeter: case Millimeter: case Point: case Pica: case Inch: unit = UnPoint; break; case ScreenPixel: unit = UnPixel; break; case FontHeight: unit = UnRelative; break; case XHeight: unit = UnXHeight; break; case Percent: unit = UnPercent; break; default: fprintf (stderr, "Invalid distance unit %X\n", CurUnit); break; } else /* convertit les unite's de longueur */ switch (CurUnit) { case Centimeter: /* convertit les centimetres en points typo */ LatestNumber = Round ((float) (LatestNumber * 72) / 2540); unit = UnPoint; break; case Millimeter: /* convertit les millimetres en points typo */ LatestNumber = Round ((float) (LatestNumber * 72) / 25400); unit = UnPoint; break; case Point: /* arrondit en points typo */ LatestNumber = Round ((float) LatestNumber / 1000); unit = UnPoint; break; case Pica: /* convertit les picas en points typo */ LatestNumber = Round ((float) (LatestNumber * 12) / 1000); unit = UnPoint; break; case Inch: /* convertit les pouces en points typo */ LatestNumber = Round ((float) (LatestNumber * 72) / 1000); unit = UnPoint; break; case ScreenPixel: /* arrondit en pixels */ LatestNumber = Round ((float) LatestNumber / 1000); unit = UnPixel; break; case FontHeight: /* convertit en 1/10 */ LatestNumber = Round ((float) LatestNumber / 100); unit = UnRelative; break; case XHeight: /* convertit en 1/10 */ LatestNumber = Round ((float) LatestNumber / 100); unit = UnXHeight; break; case Percent: LatestNumber = Round ((float) LatestNumber / 1000); unit = UnPercent; break; default: fprintf (stderr, "Invalid distance unit %X\n", CurUnit); break; } LatestNumber = LatestNumber * PrevSign; if (CurRule->PrPresMode == PresInherit) { if (CurRule->PrType == PtIndent || CurRule->PrType == PtLineSpacing || CurRule->PrType == PtLineWeight) { CurRule->PrInhDelta = LatestNumber; CurRule->PrInhAttr = LatestNumberAttr; CurRule->PrInhUnit = unit; } } else switch (CurRule->PrType) { case PtBreak1: case PtBreak2: case PtIndent: case PtLineSpacing: case PtLineWeight: CurRule->PrMinUnit = unit; CurRule->PrMinAttr = LatestNumberAttr; CurRule->PrMinValue = LatestNumber; break; case PtVertRef: case PtHorizRef: case PtVertPos: case PtHorizPos: CurRule->PrPosRule.PoDistUnit = unit; CurRule->PrPosRule.PoDistAttr = LatestNumberAttr; CurRule->PrPosRule.PoDistance = LatestNumber; break; case PtHeight: case PtWidth: if (CurRule->PrDimRule.DrPosition) { CurRule->PrDimRule.DrPosRule.PoDistUnit = unit; CurRule->PrDimRule.DrPosRule.PoDistAttr = LatestNumberAttr; CurRule->PrDimRule.DrPosRule.PoDistance = LatestNumber; } else { CurRule->PrDimRule.DrUnit = unit; CurRule->PrDimRule.DrAttr = LatestNumberAttr; CurRule->PrDimRule.DrValue = LatestNumber; } break; default: break; } } LatestNumber = 0; LatestNumberAttr = False; PrevSign = 1; CurUnit = FontHeight; } /*---------------------------------------------------------------------- NewAttrPRule allocation et initialisation d'une structure AttributePres en fonction de l'attribut de numero att ----------------------------------------------------------------------*/ #ifdef __STDC__ static AttributePres *NewAttrPRule (int att) #else /* __STDC__ */ static AttributePres *NewAttrPRule (att) int att; #endif /* __STDC__ */ { AttributePres *pPRuleA; NumAttrCase *pAttrCase; int j; GetAttributePres (&pPRuleA, 1); if (pPRuleA) { /* selon le type de l'attribut */ switch (pSSchema->SsAttribute[att - 1].AttrType) { case AtNumAttr: pPRuleA->ApNCases = 0; for (j = 0; j < MAX_PRES_ATTR_CASE; j++) { pAttrCase = &pPRuleA->ApCase[j]; pAttrCase->CaComparType = ComparConstant; pAttrCase->CaLowerBound = -MAX_INT_ATTR_VAL - 1; pAttrCase->CaUpperBound = MAX_INT_ATTR_VAL + 1; pAttrCase->CaFirstPRule = NULL; } break; case AtTextAttr: pPRuleA->ApString[0] = '\0'; pPRuleA->ApTextFirstPRule = NULL; break; case AtReferenceAttr: pPRuleA->ApRefFirstPRule = NULL; break; case AtEnumAttr: for (j = 0; j <= MAX_ATTR_VAL; j++) pPRuleA->ApEnumFirstPRule[j] = NULL; break; default: break; } } else /* memoire insuffisante */ CompilerMessage (0, PRS, FATAL, NO_MORE_MEM_LEFT, inputLine, LineNum); pPSchema->PsNAttrPRule[att - 1] += 1; return (pPRuleA); } /*---------------------------------------------------------------------- GenerateRPresAttribut alloue eventuellement une nouvelle structure AttributePres et initialise la regle concernee ----------------------------------------------------------------------*/ #ifdef __STDC__ static void GenerateRPresAttribut (indLine wi) #else /* __STDC__ */ static void GenerateRPresAttribut (wi) indLine wi; #endif /* __STDC__ */ { AttributePres *pPRuleA; NumAttrCase *pAttrCase; int l; /* s'il n'y a pas de structure AttributePres, on en alloue une */ if (pPSchema->PsNAttrPRule[CurAttrNum - 1] == 0) { pPRuleA = pPSchema->PsAttrPRule[CurAttrNum - 1] = NewAttrPRule (CurAttrNum); if (CurElemHeritAttr) { pPSchema->PsNInheritedAttrs[CurElemHeritAttr - 1] += 1; pPSchema->PsNHeirElems[CurAttrNum - 1] += 1; } } else /* sinon on cherche s'il y en a une qui traite deja certaines regles de l'element CurElemHeritAttr */ { pPRuleA = pPSchema->PsAttrPRule[CurAttrNum - 1]; for (l = pPSchema->PsNAttrPRule[CurAttrNum - 1]; --l > 0; pPRuleA = pPRuleA->ApNextAttrPres) if (CurTextEqual[0] == '\0') if (pPRuleA->ApElemType == CurElemHeritAttr) break; /* si on n'a pas touve, on alloue un paquet suivant */ if (pPRuleA->ApElemType != CurElemHeritAttr || CurTextEqual[0] != '\0') { pPRuleA->ApNextAttrPres = NewAttrPRule (CurAttrNum); pPRuleA = pPRuleA->ApNextAttrPres; if (CurElemHeritAttr) { pPSchema->PsNInheritedAttrs[CurElemHeritAttr - 1] += 1; pPSchema->PsNHeirElems[CurAttrNum - 1] += 1; } } } /* maintenant on remplit les champs dans pPRuleA */ pPRuleA->ApElemType = CurElemHeritAttr; switch (pSSchema->SsAttribute[CurAttrNum - 1].AttrType) { case AtNumAttr: /* c'est un attribut a valeur numerique */ if (pPRuleA->ApNCases >= MAX_PRES_ATTR_CASE) /* trop de cas pour cet attribut */ CompilerMessage (wi, PRS, FATAL, MAX_CASES_IN_ATTR_OVERFLOW, inputLine, LineNum); else { pAttrCase = &pPRuleA->ApCase[pPRuleA->ApNCases++]; if (CurComparAttr == 0) /* on utilise des constantes pour comparer */ { pAttrCase->CaComparType = ComparConstant; pAttrCase->CaLowerBound = CurAttrLowerBound; pAttrCase->CaUpperBound = CurAttrUpperBound; } else /* on utilise un numero d'attribut */ { if (CurElemHeritAttr == 0) pPSchema->PsNComparAttrs[CurComparAttr - 1] += 1; /* ATTENTION ce n'est donc pas le vrai nombre d'attributs se comparant a CurComparAttr puisqu'on fait +1 a chaque fois */ pAttrCase->CaComparType = ComparAttr; if (VCondGreater) /* attr GREATER MinValAttrName */ { pAttrCase->CaLowerBound = CurComparAttr; pAttrCase->CaUpperBound = -1; } else if (VCondLess) /* attr LESS MaxValAttrName */ { pAttrCase->CaLowerBound = -1; pAttrCase->CaUpperBound = CurComparAttr; } else /* attr EQUAL EqValAttrName */ { pAttrCase->CaLowerBound = CurComparAttr; pAttrCase->CaUpperBound = CurComparAttr; } } pAttrCase->CaFirstPRule = NextRule; FirstRule = NextRule; } break; case AtTextAttr: strcpy (pPRuleA->ApString, CurTextEqual); CurTextEqual[0] = '\0'; pPRuleA->ApTextFirstPRule = NextRule; FirstRule = NextRule; break; case AtReferenceAttr: if (pPRuleA->ApRefFirstPRule != NULL) /* attribut deja rencontre' */ CompilerMessage (wi, PRS, FATAL, CANT_REDEFINE, inputLine, LineNum); else { pPRuleA->ApRefFirstPRule = NextRule; FirstRule = NextRule; } break; case AtEnumAttr: if (pPRuleA->ApEnumFirstPRule[CurAttrVal] != NULL) /* attribut deja rencontre' */ CompilerMessage (wi, PRS, FATAL, CANT_REDEFINE, inputLine, LineNum); else { pPRuleA->ApEnumFirstPRule[CurAttrVal] = NextRule; FirstRule = NextRule; } break; default: break; } NewAttributeDef = False; } /*---------------------------------------------------------------------- PageCounterChangeBox Cherche les compteurs de page pour la vue pageView et indique dans ces compteurs que la boite de numero boxNum peut etre modifiee par ces compteurs. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void PageCounterChangeBox (int boxNum, int pageView) #else /* __STDC__ */ static void PageCounterChangeBox (boxNum, pageView) int boxNum; int pageView; #endif /* __STDC__ */ { int counter; int item; Counter *pCntr; /* parcourt tous les compteurs du schema de presentation */ for (counter = 0; counter < pPSchema->PsNCounters; counter++) { pCntr = &pPSchema->PsCounter[counter]; for (item = 0; item < pCntr->CnNItems; item++) if (pCntr->CnItem[item].CiElemType == PageBreak + 1) if (pCntr->CnItem[item].CiViewNum == pageView) /* C'est un compteur de pages pour la vue voulue */ if (pCntr->CnNPresBoxes < MAX_PRES_COUNT_USER) { pCntr->CnNPresBoxes++; pCntr->CnPresBox[pCntr->CnNPresBoxes - 1] = boxNum; } } } /*---------------------------------------------------------------------- ProcessShortKeyWord ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessShortKeyWord (int x, indLine wi, SyntacticCode gCode) #else /* __STDC__ */ static void ProcessShortKeyWord (x, wi, gCode) int x; indLine wi; SyntacticCode gCode; #endif /* __STDC__ */ { PresVariable *pPresVar; switch (x) { /* traitement selon le code du mot-cle court */ case CHR_59: /* ; */ if (gCode == RULE_Rule) /* fin d'une regle */ { if (CurRule != NULL) if (CurRule->PrType == PtBreak1 || CurRule->PrType == PtBreak2 || CurRule->PrType == PtIndent || CurRule->PrType == PtVertRef || CurRule-> PrType == PtHorizRef || CurRule->PrType == PtVertPos || CurRule->PrType == PtHorizPos || CurRule->PrType == PtHeight || CurRule->PrType == PtWidth || CurRule->PrType == PtLineSpacing || CurRule->PrType == PtLineWeight) EndOfNumber (); InBreakRule = False; InPageBreakRule = False; InLineBreakRule = False; InGatherRule = False; InInLineRule = False; /* verifie la validite des regles de dimensionnement relatif */ /* au contenu */ if (CurRule != NULL) if (CurRule->PrType == PtHeight || CurRule->PrType == PtWidth) if (!CurRule->PrDimRule.DrPosition) if (!CurRule->PrDimRule.DrAbsolute) if (CurRule->PrDimRule.DrRelation == RlEnclosed) if (CurRule->PrDimRule.DrTypeRefElem != 0 || CurRule->PrDimRule.DrValue != 0) CompilerMessage (wi, PRS, FATAL, BAD_DIM_RULE, inputLine, LineNum); InRule = False; if (RulesForView && !RuleBlock && !CondBlock) { RulesForView = False; CurView = 1; } if (!ViewBlock) CheckBoxEnd (); if (!RuleBlock) Conditions = NULL; } else if (gCode == RULE_Transmit) /* fin d'une regle transmit */ { TransmittedCounter = 0; TransmittedElem = 0; } break; case CHR_44: /* , */ if (gCode == RULE_Function) { pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; if (pPresVar->PvItem[pPresVar->PvNItems - 1].ViType == VarPageNumber) /* c'est la fin d'un PageNumber dans une variable. On connait */ /* la vue concernee */ { if (NewVariableDef) /* definition de variable dans une regle Content */ /* Cherche les compteurs de page pour la vue concernee */ /* et indique dans ces compteurs que la boite courante */ /* peut etre modifiee par ces compteurs */ PageCounterChangeBox (CurPresBox, pPresVar->PvItem[pPresVar->PvNItems - 1].ViView); } } break; case CHR_58: /* : */ if (gCode == RULE_Rule1 || gCode == RULE_Rule2 || gCode == RULE_Rule3 || gCode == RULE_Rule4) InRule = True; if (gCode == RULE_Attr && NewAttributeDef) GenerateRPresAttribut (wi); break; case CHR_40: /* ( */ if (gCode == RULE_VarConst) /* dans une regle VarConst */ if (PresBoxDef) /* dans la regle Content d'une boite de presentation */ { NewVar (wi); /* cree une nouvelle variable */ pPSchema->PsPresentBox[CurPresBox - 1].PbContent = ContVariable; pPSchema->PsPresentBox[CurPresBox - 1].PbContVariable = pPSchema->PsNVariables; NewVariableDef = True; } else /* dans une regle Content d'une paire ou d'une reference, on refuse: seules les constantes sont acceptees dans cette regle */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_A_REF, inputLine, LineNum); else if (gCode == RULE_Rule3) /* dans Rule3 */ InRule = True; else if (gCode == RULE_ElemCondition && !InCondPage) /* on s'occupe de la construction ``if (compteur < cste)'' (resp >, =, IN [*..*] et pas des construction ``if One (compteur)'' (resp Even, Odd) */ { Conditions->CoCondition = PcInterval; Conditions->CoCounter = 0; Conditions->CoMinCounter = MIN_COUNTER_VAL; Conditions->CoMaxCounter = MAX_COUNTER_VAL; Conditions->CoValCounter = CntCurVal; } break; case CHR_41: /* ) */ if (gCode == RULE_VarConst) /* dans une regle VarConst */ NewVariableDef = False; /* fin de definition de variable */ if (gCode == RULE_Rule3) if (CurRule->PrType == PtFunction && CurRule->PrPresFunction == FnCopy) /* fin d'une regle Copy */ if (CopyType[0] != '\0') /* on n'a pas encore traite' le nom de type a copier */ /* ce nom de type est donc erronne' */ { CompilerMessage (BeginCopyType, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); CopyType[0] = '\0'; BeginCopyType = 0; } break; case CHR_61: /* = */ if (gCode == RULE_InheritVal || gCode == RULE_NameInherit || gCode == RULE_BoolInherit || gCode == RULE_InheritDist || gCode == RULE_InheritSize || gCode == RULE_AdjustInherit || gCode == RULE_LineStyleInherit) /* PresInherit */ { CurRule->PrInhDelta = 0; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = False; } if (gCode == RULE_InheritDist) { PrevSign = 1; LatestNumberAttr = False; LatestNumber = 0; CurUnit = FontHeight; } break; case CHR_46: /* . */ if (gCode == RULE_Dimension) /* dimension relative */ { if (!CurRule->PrDimRule.DrPosition) CurRule->PrDimRule.DrAbsolute = False; } else if (gCode == RULE_AbsDist) /* introduit une partie decimale */ if (LatestNumberAttr) /* interdit apres un attribut */ CompilerMessage (wi, PRS, FATAL, NO_DECIMAL_PART_AFTER_AN_ATTR, inputLine, LineNum); break; case CHR_42: /* * */ if (gCode == RULE_TypeOrPage || gCode == RULE_RefVPosition || gCode == RULE_RefHPosition || gCode == RULE_Present || gCode == RULE_BoxType) InclusionRefName = True; else if (gCode == RULE_Reference) SetLevel (RlSelf, wi); break; case CHR_43: /* + */ if (gCode == RULE_Sign || gCode == RULE_InheritDist) /* dans une distance */ PrevSign = 1; break; case CHR_45: /* - */ if (gCode == RULE_Sign || gCode == RULE_InheritDist) /* dans une distance */ PrevSign = -1; else if (gCode == RULE_AttrRelat || gCode == RULE_AttrValue) /* devant une valeur d'attribut numerique, dans une condition */ /* d'application de regles associees a un attribut */ AttrValSign = -1; else if (gCode == RULE_ElemCondition) CurCondCntSign = -1; else if (gCode == RULE_RelAncestorLevel) AncestorSign = -1; break; case CHR_62: /* > */ if (gCode == RULE_GreaterLess) { Conditions->CoAncestorRel = CondGreater; SignGreaterOrLess = True; } break; case CHR_60: /* < */ if (gCode == RULE_GreaterLess) { Conditions->CoAncestorRel = CondLess; SignGreaterOrLess = True; } break; case CHR_37: /* % */ if (gCode == RULE_Unit) CurUnit = Percent; break; default: break; } } /*---------------------------------------------------------------------- ProcessAxis ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessAxis (BoxEdge axis, indLine wi) #else /* __STDC__ */ static void ProcessAxis (axis, wi) BoxEdge axis; indLine wi; #endif /* __STDC__ */ { switch (CurRule->PrType) { case PtVertRef: case PtHorizRef: CurRule->PrPosRule.PoPosRef = axis; break; case PtVertPos: case PtHorizPos: if (AxisDef) { AxisDef = False; CurRule->PrPosRule.PoPosDef = axis; } else CurRule->PrPosRule.PoPosRef = axis; break; case PtHeight: case PtWidth: if (!CurRule->PrDimRule.DrPosition) if ((CurRule->PrType == PtHeight && !(axis == Top || axis == Bottom)) || (CurRule->PrType == PtWidth && !(axis == Left || axis == Right))) CompilerMessage (wi, PRS, FATAL, BROKEN_RULE, inputLine, LineNum); else { CurRule->PrDimRule.DrPosition = True; CurRule->PrDimRule.DrPosRule.PoPosDef = axis; CurRule->PrDimRule.DrPosRule.PoPosRef = NoEdge; CurRule->PrDimRule.DrPosRule.PoDistUnit = UnRelative; CurRule->PrDimRule.DrPosRule.PoDistAttr = False; CurRule->PrDimRule.DrPosRule.PoDistance = 0; CurRule->PrDimRule.DrPosRule.PoRelation = RlSameLevel; CurRule->PrDimRule.DrPosRule.PoNotRel = False; CurRule->PrDimRule.DrPosRule.PoRefElem = False; CurRule->PrDimRule.DrPosRule.PoRefPresBox = 0; AxisDef = False; } else /* 2eme repere d'un dimensionnement elastique */ CurRule->PrDimRule.DrPosRule.PoPosRef = axis; break; default: break; } } /*---------------------------------------------------------------------- CreateConstant ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CreateConstant (BasicType constType, indLine wi) #else /* __STDC__ */ static void CreateConstant (constType, wi) BasicType constType; indLine wi; #endif /* __STDC__ */ { PresVariable *pPresVar; if (!ConstantDef) { NewConst (wi); if (NewVariableDef || VariableDef) /* dans une definition de variable */ { pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarText; pPresVar->PvItem[pPresVar->PvNItems - 1].ViConstant = pPSchema->PsNConstants; } else /* on ne peut etre que dans une regle 'Content' */ if (PresBoxDef) /* definition dans une regle Content d'une boite de presentation */ { pPSchema->PsPresentBox[CurPresBox - 1].PbContent = ContConst; pPSchema->PsPresentBox[CurPresBox - 1].PbContConstant = pPSchema->PsNConstants; } else if (RuleDef && CurRule->PrPresMode == PresFunction && CurRule->PrPresFunction == FnContentRef) /* dans une regle Content d'un element reference ou paire */ { CurRule->PrNPresBoxes = 1; CurRule->PrPresBox[0] = pPSchema->PsNConstants; } } pPSchema->PsConstant[pPSchema->PsNConstants - 1].PdType = constType; } /*---------------------------------------------------------------------- NewCounterOper ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewCounterOper (CounterOp oper, indLine wi) #else /* __STDC__ */ static void NewCounterOper (oper, wi) CounterOp oper; indLine wi; #endif /* __STDC__ */ { Counter *pCntr; pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; if (pCntr->CnNItems >= MAX_PRES_COUNT_ITEM) CompilerMessage (wi, PRS, FATAL, MAX_OPS_ON_A_COUNTER_OVERFLOW, inputLine, LineNum); else { pCntr->CnItem[pCntr->CnNItems].CiCntrOp = oper; pCntr->CnItem[pCntr->CnNItems].CiElemType = 0; pCntr->CnItem[pCntr->CnNItems].CiAscendLevel = 0; pCntr->CnItem[pCntr->CnNItems].CiViewNum = 0; pCntr->CnItem[pCntr->CnNItems].CiParamValue = 0; pCntr->CnItem[pCntr->CnNItems].CiInitAttr = 0; pCntr->CnItem[pCntr->CnNItems].CiReinitAttr = 0; pCntr->CnItem[pCntr->CnNItems].CiCondAttr = 0; pCntr->CnItem[pCntr->CnNItems].CiCondAttrPresent = FALSE; pCntr->CnNItems++; } } /*---------------------------------------------------------------------- GetTypedRule cherche la regle de type ruleType dans la liste de regles qui commence par la regle firstR. ----------------------------------------------------------------------*/ #ifdef __STDC__ static PtrPRule GetTypedRule (PRuleType ruleType, PtrPRule firstR) #else /* __STDC__ */ static PtrPRule GetTypedRule (ruleType, firstR) PRuleType ruleType; PtrPRule firstR; #endif /* __STDC__ */ { PtrPRule pRule; boolean stop; pRule = firstR; stop = False; do if (pRule == NULL) stop = True; else if (pRule->PrType == ruleType) stop = True; else pRule = pRule->PrNextPRule; while (!stop); return pRule; } /*---------------------------------------------------------------------- CreateDefaultRule cree une nouvelle regle de presentation par defaut. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CreateDefaultRule () #else /* __STDC__ */ static void CreateDefaultRule () #endif /* __STDC__ */ { if (CurRule != NULL) CurRule->PrNextPRule = NextRule; CurRule = NextRule; GetPresentRule (&NextRule); if (NextRule == NULL) /* memoire insuffisante */ CompilerMessage (0, PRS, FATAL, NO_MORE_MEM_LEFT, inputLine, LineNum); if (pPSchema->PsFirstDefaultPRule == NULL) pPSchema->PsFirstDefaultPRule = CurRule; CurRule->PrNextPRule = NULL; CurRule->PrCond = NULL; CurRule->PrViewNum = 1; CurRule->PrPresMode = PresImmediate; } /*---------------------------------------------------------------------- InheritRule transforme la regle de presentation courante en une regle d'heritage de type inheritType. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void InheritRule (InheritMode inheritType) #else /* __STDC__ */ static void InheritRule (inheritType) InheritMode inheritType; #endif /* __STDC__ */ { CurRule->PrPresMode = PresInherit; CurRule->PrInheritMode = inheritType; CurRule->PrInhAttr = False; CurRule->PrInhDelta = 0; CurRule->PrMinMaxAttr = False; CurRule->PrInhMinOrMax = 0; CurRule->PrInhUnit = UnRelative; } /*---------------------------------------------------------------------- CheckDefaultRules verifie que toutes les regles par defaut sont presentes pour la vue 1 et si certaines sont absentes, on les ajoute. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CheckDefaultRules () #else /* __STDC__ */ static void CheckDefaultRules () indLine wi; #endif /* __STDC__ */ { if (pPSchema->PsFirstDefaultPRule == NextRule) pPSchema->PsFirstDefaultPRule = NULL; if (GetTypedRule (PtVisibility, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Visibility par defaut, on en cree une : */ /* Visibility: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtVisibility; InheritRule (InheritParent); } if (GetTypedRule (PtVertRef, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle VertRef par defaut, on en cree une : */ /* VertRef: * . Left; */ { CreateDefaultRule (); CurRule->PrType = PtVertRef; CurRule->PrPosRule.PoPosDef = VertRef; CurRule->PrPosRule.PoPosRef = Left; CurRule->PrPosRule.PoDistUnit = UnRelative; CurRule->PrPosRule.PoDistAttr = False; CurRule->PrPosRule.PoDistance = 0; CurRule->PrPosRule.PoRelation = RlSelf; CurRule->PrPosRule.PoNotRel = False; CurRule->PrPosRule.PoUserSpecified = False; CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoRefPresBox = 0; } if (GetTypedRule (PtHorizRef, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle HorizRef par defaut, on en cree une : */ /* HorizRef: Enclosed . HRef; */ { CreateDefaultRule (); CurRule->PrType = PtHorizRef; CurRule->PrPosRule.PoPosDef = HorizRef; CurRule->PrPosRule.PoPosRef = HorizRef; CurRule->PrPosRule.PoDistUnit = UnRelative; CurRule->PrPosRule.PoDistAttr = False; CurRule->PrPosRule.PoDistance = 0; CurRule->PrPosRule.PoRelation = RlEnclosed; CurRule->PrPosRule.PoNotRel = False; CurRule->PrPosRule.PoUserSpecified = False; CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoRefPresBox = 0; } if (GetTypedRule (PtVertPos, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle VertPos par defaut, on en cree une : */ /* VertPos: Top = Previous . Bottom; */ { CreateDefaultRule (); CurRule->PrType = PtVertPos; CurRule->PrPosRule.PoPosDef = Top; CurRule->PrPosRule.PoPosRef = Bottom; CurRule->PrPosRule.PoDistUnit = UnRelative; CurRule->PrPosRule.PoDistAttr = False; CurRule->PrPosRule.PoDistance = 0; CurRule->PrPosRule.PoRelation = RlPrevious; CurRule->PrPosRule.PoNotRel = False; CurRule->PrPosRule.PoUserSpecified = False; CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoRefPresBox = 0; } if (GetTypedRule (PtHorizPos, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle HorizPos par defaut, on en cree une : */ /* HorizPos: Left = Enclosing . Left; */ { CreateDefaultRule (); CurRule->PrType = PtHorizPos; CurRule->PrPosRule.PoPosDef = Left; CurRule->PrPosRule.PoPosRef = Left; CurRule->PrPosRule.PoDistUnit = UnRelative; CurRule->PrPosRule.PoDistAttr = False; CurRule->PrPosRule.PoDistance = 0; CurRule->PrPosRule.PoRelation = RlEnclosing; CurRule->PrPosRule.PoNotRel = False; CurRule->PrPosRule.PoUserSpecified = False; CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoRefPresBox = 0; } if (GetTypedRule (PtHeight, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Height par defaut, on en cree une : */ /* Height: Enclosed . Height; */ { CreateDefaultRule (); CurRule->PrType = PtHeight; CurRule->PrDimRule.DrPosition = False; CurRule->PrDimRule.DrAbsolute = False; CurRule->PrDimRule.DrSameDimens = True; CurRule->PrDimRule.DrUnit = UnRelative; CurRule->PrDimRule.DrAttr = False; CurRule->PrDimRule.DrMin = False; CurRule->PrDimRule.DrUserSpecified = False; CurRule->PrDimRule.DrValue = 0; CurRule->PrDimRule.DrRelation = RlEnclosed; CurRule->PrDimRule.DrNotRelat = False; CurRule->PrDimRule.DrRefElement = True; CurRule->PrDimRule.DrTypeRefElem = 0; } if (GetTypedRule (PtWidth, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Width par defaut, on en cree une : */ /* Width: Enclosed . Width; */ { CreateDefaultRule (); CurRule->PrType = PtWidth; CurRule->PrDimRule.DrPosition = False; CurRule->PrDimRule.DrAbsolute = False; CurRule->PrDimRule.DrSameDimens = True; CurRule->PrDimRule.DrUnit = UnRelative; CurRule->PrDimRule.DrAttr = False; CurRule->PrDimRule.DrMin = False; CurRule->PrDimRule.DrUserSpecified = False; CurRule->PrDimRule.DrValue = 0; CurRule->PrDimRule.DrRelation = RlEnclosed; CurRule->PrDimRule.DrNotRelat = False; CurRule->PrDimRule.DrRefElement = True; CurRule->PrDimRule.DrTypeRefElem = 0; } if (GetTypedRule (PtSize, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Size par defaut, on en cree une : */ /* Size: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtSize; InheritRule (InheritParent); } if (GetTypedRule (PtStyle, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Style par defaut, on en cree une : */ /* Style: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtStyle; InheritRule (InheritParent); } if (GetTypedRule (PtFont, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Font par defaut, on en cree une : */ /* Font: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtFont; InheritRule (InheritParent); } if (GetTypedRule (PtUnderline, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Underline par defaut, on en cree une : */ /* Underline: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtUnderline; InheritRule (InheritParent); } if (GetTypedRule (PtThickness, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Thickness par defaut, on en cree une : */ /* Thickness: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtThickness; InheritRule (InheritParent); } if (GetTypedRule (PtIndent, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Indent par defaut, on en cree une : */ /* Indent: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtIndent; InheritRule (InheritParent); } if (GetTypedRule (PtLineSpacing, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle LineSpacing par defaut, on en cree une : */ /* LineSpacing: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtLineSpacing; InheritRule (InheritParent); } if (GetTypedRule (PtDepth, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Depth par defaut, on en cree une : */ /* Depth: 0; */ { CreateDefaultRule (); CurRule->PrType = PtDepth; CurRule->PrPresMode = PresImmediate; CurRule->PrAttrValue = False; CurRule->PrIntValue = 0; } if (GetTypedRule (PtAdjust, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Adjust par defaut, on en cree une : */ /* Adjust: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtAdjust; InheritRule (InheritParent); } if (GetTypedRule (PtJustify, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Justify par defaut, on en cree une : */ /* Justify: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtJustify; InheritRule (InheritParent); } if (GetTypedRule (PtLineStyle, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle LineStyle par defaut, on en cree une : */ /* LineStyle: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtLineStyle; InheritRule (InheritParent); } if (GetTypedRule (PtLineWeight, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle LineWeight par defaut, on en cree une : */ /* LineWeight: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtLineWeight; InheritRule (InheritParent); } if (GetTypedRule (PtFillPattern, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle FillPattern par defaut, on en cree une : */ /* FillPattern: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtFillPattern; InheritRule (InheritParent); } if (GetTypedRule (PtBackground, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Background par defaut, on en cree une : */ /* Background: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtBackground; InheritRule (InheritParent); } if (GetTypedRule (PtForeground, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Foreground par defaut, on en cree une : */ /* Foreground: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtForeground; InheritRule (InheritParent); } if (GetTypedRule (PtHyphenate, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle Hyphenate par defaut, on en cree une : */ /* Hyphenate: Enclosing =; */ { CreateDefaultRule (); CurRule->PrType = PtHyphenate; InheritRule (InheritParent); } if (GetTypedRule (PtVertOverflow, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle VertOverflow par defaut, on en cree une : */ /* VertOverflow: False; */ { CreateDefaultRule (); CurRule->PrType = PtVertOverflow; CurRule->PrPresMode = PresImmediate; CurRule->PrJustify = FALSE; } if (GetTypedRule (PtHorizOverflow, pPSchema->PsFirstDefaultPRule) == NULL) /* pas de regle HorizOverflow par defaut, on en cree une : */ /* HorizOverflow: False; */ { CreateDefaultRule (); CurRule->PrType = PtHorizOverflow; CurRule->PrPresMode = PresImmediate; CurRule->PrJustify = FALSE; } CurRule->PrNextPRule = NULL; } /*---------------------------------------------------------------------- CheckForwardRef verifie que toutes les references de boites en avant sont resolues. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CheckForwardRef (indLine wi) #else /* __STDC__ */ static void CheckForwardRef (wi) indLine wi; #endif /* __STDC__ */ { int box; int i, j; boolean stop; for (box = 0; box < pPSchema->PsNPresentBoxes; box++) if (pPSchema->PsPresentBox[box].PbName[0] == ' ') { i = 0; stop = False; do { if (i + 1 > MAX_IDENTIFIERS) stop = True; else if (Identifier[i].SrcIdentCode == RULE_ViewName) /* identificateur de boite */ if (Identifier[i].SrcIdentDefRule == box + 1) { stop = True; /* affiche le nom de l'identificateur */ printf ("\n"); for (j = 0; j < Identifier[i].SrcIdentLen; j++) putchar (Identifier[i].SrcIdentifier[j]); printf ("\n"); } i++; } while (!stop); if (i > MAX_IDENTIFIERS) /*erreur dans la declaration FORWARD */ CompilerMessage (wi, PRS, FATAL, BAD_USE_OF_KEYWORD_FORWARD, inputLine, LineNum); } } /*---------------------------------------------------------------------- LayoutRule ----------------------------------------------------------------------*/ #ifdef __STDC__ static void LayoutRule (FunctionType layoutFonct, indLine wi) #else /* __STDC__ */ static void LayoutRule (layoutFonct, wi) FunctionType layoutFonct; indLine wi; #endif /* __STDC__ */ { PtrPRule pPRule; ConditionEnd (); if (DefaultRuleDef) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); else if (RuleDef && CurType <= MAX_BASIC_TYPE) CompilerMessage (wi, PRS, FATAL, BAD_RULE_FOR_A_TERMINAL_ELEM, inputLine, LineNum); else if (layoutFonct != FnLine && layoutFonct != FnNoLine && layoutFonct != FnShowBox && pSSchema->SsRule[CurType - 1].SrConstruct == CsChoice) CompilerMessage (wi, PRS, FATAL, CANT_USE_RULE_FOR_A_CHOICE, inputLine, LineNum); else { /* verifie qu'il n'y a que des conditions Within parmi les conditions courantes */ CheckConditions (wi); CreatePRule (PtFunction, wi); CurRule->PrPresMode = PresFunction; CurRule->PrPresFunction = layoutFonct; CurRule->PrPresBoxRepeat = False; CurRule->PrElement = False; CurRule->PrExternal = False; CurRule->PrNPresBoxes = 0; CurRule->PrPresBoxName[0] = '\0'; /* verifie que cette regle n'est pas deja presente pour cette */ /* vue uniquement pour layoutFonct = FnLine ou FnPage ou FnColumn */ if (layoutFonct == FnLine || layoutFonct == FnPage || layoutFonct == FnColumn || layoutFonct == FnSubColumn || layoutFonct == FnNoLine) { pPRule = FirstRule; while (pPRule != CurRule) { if (pPRule->PrViewNum == CurView) if (pPRule->PrType == PtFunction) if (pPRule->PrPresFunction == FnLine || pPRule->PrPresFunction == FnNoLine || pPRule->PrPresFunction == FnPage || pPRule->PrPresFunction == FnColumn || pPRule->PrPresFunction == FnSubColumn) #ifdef __COLPAGE__ /* on autorise quand meme Page suivi de Column */ if (!((layoutFonct == FnColumn && pPRule->PrPresFunction == FnPage) || (layoutFonct == FnSubColumn && pPRule->PrPresFunction == FnColumn))) #endif /* __COLPAGE__ */ CompilerMessage (wi, PRS, FATAL, ONLY_ONE_PAGE_RULE, inputLine, LineNum); pPRule = pPRule->PrNextPRule; } } } } /*---------------------------------------------------------------------- BooleanValue affecte la valeur bool au parametre de presentation courant (indique' par InBreakRule, InLineBreakRule, InPageBreakRule, InGatherRule ou InInLineRule) de la boite courante ou des regles par defaut. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void BooleanValue (boolean bool, indLine wi) #else /* __STDC__ */ static void BooleanValue (bool, wi) boolean bool; indLine wi; #endif /* __STDC__ */ { int k; if (InBreakRule) /* on est dans une regle 'Break' */ { if (DefaultRuleDef) /* on est dans les regles par defaut */ /* initialise la secabilite dans toutes les boites de */ /* presentation et de tous les elements */ { for (k = 0; k < MAX_PRES_BOX; k++) { pPSchema->PsPresentBox[k].PbAcceptPageBreak = bool; pPSchema->PsPresentBox[k].PbAcceptLineBreak = bool; } for (k = 0; k < MAX_RULES_SSCHEMA; k++) { pPSchema->PsAcceptPageBreak[k] = bool; pPSchema->PsAcceptLineBreak[k] = bool; } } else /* dans une regle specifique */ if (PresBoxDef) /* pour une boite de presentation */ { pPSchema->PsPresentBox[CurPresBox - 1].PbAcceptPageBreak = bool; pPSchema->PsPresentBox[CurPresBox - 1].PbAcceptLineBreak = bool; } else /* pour la boite d'un type d'element */ { pPSchema->PsAcceptPageBreak[CurType - 1] = bool; pPSchema->PsAcceptLineBreak[CurType - 1] = bool; } } else if (InPageBreakRule) /* on est dans une regle 'PageBreak' */ { if (DefaultRuleDef) /* on est dans les regles par defaut */ /* initialise la secabilite dans toutes les boites de */ /* presentation et de tous les elements */ { for (k = 0; k < MAX_PRES_BOX; k++) pPSchema->PsPresentBox[k].PbAcceptPageBreak = bool; for (k = 0; k < MAX_RULES_SSCHEMA; k++) pPSchema->PsAcceptPageBreak[k] = bool; } else /* dans une regle specifique */ if (PresBoxDef) /* pour une boite de presentation */ pPSchema->PsPresentBox[CurPresBox - 1].PbAcceptPageBreak = bool; else /* pour la boite d'un type d'element */ pPSchema->PsAcceptPageBreak[CurType - 1] = bool; } else if (InLineBreakRule) /* on est dans une regle 'LineBreak' */ { if (DefaultRuleDef) /* on est dans les regles par defaut */ /* initialise la secabilite dans toutes les boites de */ /* presentation et de tous les elements */ { for (k = 0; k < MAX_PRES_BOX; k++) pPSchema->PsPresentBox[k].PbAcceptLineBreak = bool; for (k = 0; k < MAX_RULES_SSCHEMA; k++) pPSchema->PsAcceptLineBreak[k] = bool; } else /* dans une regle specifique */ if (PresBoxDef) /* pour une boite de presentation */ pPSchema->PsPresentBox[CurPresBox - 1].PbAcceptLineBreak = bool; else /* pour la boite d'un type d'element */ pPSchema->PsAcceptLineBreak[CurType - 1] = bool; } else if (InGatherRule) /* on est dans une regle Gather */ if (PresBoxDef) /* pour une boite de presentation */ pPSchema->PsPresentBox[CurPresBox - 1].PbBuildAll = bool; else /* pour la boite d'un type d'element */ pPSchema->PsBuildAll[CurType - 1] = bool; else if (InInLineRule) /* on est dans une regle InLine */ { if (!bool) LayoutRule (FnNotInLine, wi); } else /* on est dans une regle Justify, Hyphenate, VertOverflow ou HorizOverflow */ { CurRule->PrPresMode = PresImmediate; CurRule->PrJustify = bool; } } /*---------------------------------------------------------------------- CreationRule ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CreationRule (FunctionType creatFonct, indLine wi) #else /* __STDC__ */ static void CreationRule (creatFonct, wi) FunctionType creatFonct; indLine wi; #endif /* __STDC__ */ { if (DefaultRuleDef) /* pas de creation dans les regles par defaut */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); else if (CurView != 1) /* regles de creation seulement dans la vue principale */ CompilerMessage (wi, PRS, FATAL, RULE_FORBIDDEN_IN_A_VIEW, inputLine, LineNum); else if ((creatFonct == FnCreateBefore || creatFonct == FnCreateAfter || creatFonct == FnCreateWith || creatFonct == FnCreateEnclosing) && CurType == pSSchema->SsRootElem) /* pas de creation avant, apres ou au-dessus de la racine */ CompilerMessage (wi, PRS, FATAL, PRS_INVALID_RULE_FOR_ROOT_ELEM, inputLine, LineNum); else { CreatePRule (PtFunction, wi); CurRule->PrPresMode = PresFunction; CurRule->PrPresFunction = creatFonct; CurRule->PrPresBoxRepeat = False; CurRule->PrElement = False; CurRule->PrExternal = False; CurRule->PrNPresBoxes = 0; CurRule->PrPresBoxName[0] = '\0'; } } /*---------------------------------------------------------------------- GenerateCopyRule ----------------------------------------------------------------------*/ #ifdef __STDC__ static void GenerateCopyRule (FunctionType fonctType, indLine wi) #else /* __STDC__ */ static void GenerateCopyRule (fonctType, wi) FunctionType fonctType; indLine wi; #endif /* __STDC__ */ { PtrPRule R; /* verifie qu'il n'y a que des conditions Within parmi les conditions courantes */ CheckConditions (wi); CreatePRule (PtFunction, wi); CurRule->PrPresMode = PresFunction; CurRule->PrPresFunction = fonctType; CurRule->PrPresBoxRepeat = False; CurRule->PrElement = False; CurRule->PrExternal = False; CurRule->PrNPresBoxes = 0; CurRule->PrPresBoxName[0] = '\0'; /* S'il n'y a pas de condition courante, verifie qu'il n'y a pas */ /* deja une regle Copy ou Content sans condition pour cette vue */ if (Conditions != NULL) { R = FirstRule; while (R != CurRule) { if (R->PrViewNum == CurView) if (R->PrType == PtFunction) if (R->PrPresFunction == FnContentRef || R->PrPresFunction == FnCopy) if (R->PrCond == NULL) CompilerMessage (wi, PRS, FATAL, ONLY_ONE_COPY_CONTENT_RULE, inputLine, LineNum); R = R->PrNextPRule; } } } /*---------------------------------------------------------------------- SameConditions compare deux chaines de conditions et retourne True si elles sont egales. ----------------------------------------------------------------------*/ #ifdef __STDC__ static boolean SameConditions (PtrCondition pCond1, PtrCondition pCond2) #else /* __STDC__ */ static boolean SameConditions (pCond1, pCond2) PtrCondition pCond1; PtrCondition pCond2; #endif /* __STDC__ */ { boolean different, sameRules, oneRule; PtrCondition curCond1; PtrCondition curCond2; curCond1 = pCond1; curCond2 = pCond2; different = False; /* les deux chaines de conditions ont-elles la meme longueur ? */ while (curCond1 != NULL && curCond2 != NULL) { curCond1 = curCond1->CoNextCondition; curCond2 = curCond2->CoNextCondition; } if (curCond1 != NULL || curCond2 != NULL) /* une chaine est plus longue que l'autre */ different = True; else /* les deux chaines de conditions ont la meme longueur */ /* on compare chaque regle d'une chaine avec toutes celles */ /* de l'autre, jusqu'a trouver une regle de la 1ere chaine qui */ /* n'aie pas d'egale dans le deuxieme */ { curCond1 = pCond1; while (curCond1 != NULL && !different) { curCond2 = pCond2; oneRule = False; while (curCond2 != NULL && !oneRule) { sameRules = True; if (curCond1->CoNotNegative != curCond2->CoNotNegative) sameRules = False; else if (curCond1->CoCondition != curCond2->CoCondition) sameRules = False; else if (curCond1->CoTarget != curCond2->CoTarget) sameRules = False; else if (curCond1->CoCondition == PcInterval || curCond1->CoCondition == PcEven || curCond1->CoCondition == PcOdd || curCond1->CoCondition == PcOne) { if (curCond1->CoCounter != curCond2->CoCounter) sameRules = False; else if (curCond1->CoCondition == PcInterval) if (curCond1->CoMinCounter != curCond2->CoMinCounter) sameRules = False; else if (curCond1->CoMaxCounter != curCond2->CoMaxCounter) sameRules = False; } else if (curCond1->CoCondition == PcElemType) { if (curCond1->CoTypeElAttr != curCond2->CoTypeElAttr) sameRules = False; } else if (curCond1->CoCondition == PcWithin) if (curCond1->CoRelation != curCond2->CoRelation) sameRules = False; else if (curCond1->CoTypeAncestor != curCond2->CoTypeAncestor) sameRules = False; else if (curCond1->CoImmediate != curCond2->CoImmediate) sameRules = False; else if (curCond1->CoAncestorRel != curCond2->CoAncestorRel) sameRules = False; else if (strcmp (curCond1->CoAncestorName, curCond2->CoAncestorName) != 0) sameRules = False; else if (strcmp (curCond1->CoSSchemaName, curCond2->CoSSchemaName) != 0) sameRules = False; if (sameRules) oneRule = True; else curCond2 = curCond2->CoNextCondition; } if (!oneRule) different = True; else curCond1 = curCond1->CoNextCondition; } } return !different; } /*---------------------------------------------------------------------- ProcessLongKeyWord ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessLongKeyWord (int x, SyntacticCode gCode, indLine wi) #else /* __STDC__ */ static void ProcessLongKeyWord (x, gCode, wi) int x; SyntacticCode gCode; indLine wi; #endif /* __STDC__ */ { int i; boolean assoc; Counter *pCntr; PresVariable *pPresVar; switch (x) { /* traitement selon le code du mot-cle */ case KWD_PRESENTATION: /* PRESENTATION */ break; case KWD_VIEWS: /* VIEWS */ ViewDef = True; break; case KWD_PRINT: /* PRINT */ ViewDef = False; break; case KWD_COUNTERS: /* COUNTERS */ ViewDef = False; CounterDef = True; break; case KWD_CONST: /* CONST */ ViewDef = False; CounterDef = False; ConstantDef = True; break; case KWD_VAR: /* VAR */ ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = True; break; case KWD_DEFAULT: /* DEFAULT */ ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = False; DefaultRuleDef = True; pPSchema->PsFirstDefaultPRule = NextRule; FirstRule = NextRule; break; case KWD_BOXES: /* BOXES */ /* verifie que toutes les regles par defaut sont presentes pour la */ /* vue 1. */ CheckDefaultRules (); ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = False; DefaultRuleDef = False; PresBoxDef = True; break; case KWD_RULES: /* RULES */ ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = False; DefaultRuleDef = False; CheckForwardRef (wi); if (PresBoxDef) { CheckForwardRef (wi); /* verifie les references en avant de boites */ PresBoxDef = False; } else /* verifie que toutes les regles par defaut sont presentes pour */ /* la vue 1 */ CheckDefaultRules (); CurRule->PrNextPRule = NULL; RuleDef = True; break; case KWD_ATTRIBUTES: /* ATTRIBUTES */ CheckDefaultRules (); ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = False; DefaultRuleDef = False; PresBoxDef = False; RuleDef = False; AttributeDef = True; break; case KWD_TRANSMIT: /* TRANSMIT */ CheckDefaultRules (); ViewDef = False; CounterDef = False; ConstantDef = False; VariableDef = False; DefaultRuleDef = False; PresBoxDef = False; RuleDef = False; AttributeDef = False; TransmittedCounter = 0; TransmittedElem = 0; EndOfRulesForType (); CurRule->PrNextPRule = NULL; if (NextRule != NULL) free (NextRule); NextRule = NULL; break; case KWD_END: /* END */ switch (gCode) { /* r= numero de la regle ou apparait END */ case RULE_PresentModel: /* fin du progamme */ EndOfRulesForType (); CurRule->PrNextPRule = NULL; if (NextRule != NULL) free (NextRule); NextRule = NULL; break; case RULE_ViewRuleList: /* fin ViewRuleList */ ViewBlock = False; CheckBoxEnd (); EndOfRulesForType (); break; case RULE_CondRuleList: /* fin CondRuleList */ CurView = 1; /* la vue par defaut est la premiere */ RulesForView = False; CondBlock = False; if (!ViewBlock) { CheckBoxEnd (); EndOfRulesForType (); } break; case RULE_RuleList: RuleBlock = False; Conditions = NULL; if (!ViewBlock && !CondBlock) { CheckBoxEnd (); EndOfRulesForType (); } break; } break; case KWD_EXPORT /* THOT_EXPORT */ : /* verifie qu'il n'y a pas deja une vue THOT_EXPORT */ i = 1; while (i < pPSchema->PsNViews && !pPSchema->PsExportView[i - 1]) i++; if (pPSchema->PsExportView[i - 1]) CompilerMessage (wi, PRS, FATAL, ONLY_ONE_EXPORT_VIEW_ALLOWED, inputLine, LineNum); /* deja une vue THOT_EXPORT */ else pPSchema->PsExportView[pPSchema->PsNViews - 1] = True; break; case KWD_RANK: /* RANK */ NewCounterOper (CntrRank, wi); AncestorSign = 1; AttrInitCounter = False; break; case KWD_RLevel: /* CntrRLevel */ NewCounterOper (CntrRLevel, wi); break; case KWD_INIT /* INIT */ : AttrInitCounter = True; break; case KWD_REINIT /* REINIT */ : AttrInitCounter = False; break; case KWD_SET: /* SET */ NewCounterOper (CntrSet, wi); break; case KWD_ADD: /* ADD */ NewCounterOper (CntrAdd, wi); break; case KWD_Page: if (gCode == RULE_TypeOrPage) /* dans un compteur */ { pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiElemType = PageBreak + 1; pCntr->CnItem[pCntr->CnNItems - 1].CiViewNum = 0; } else /* regle de mise en pages */ { if (x == KWD_Page) LayoutRule (FnPage, wi); /* la regle Page s'applique-t-elle a une vue d'elements associes? */ assoc = False; if (pSSchema->SsRule[CurType - 1].SrConstruct == CsList) /* la regle s'applique a un element liste */ { i = pSSchema->SsRule[CurType - 1].SrListItem; /* les elements de la liste sont-ils des elements associes ? */ assoc = pSSchema->SsRule[i - 1].SrAssocElem; } if (assoc) pPSchema->PsAssocPaginated[CurType - 1] = True; else pPSchema->PsPaginatedView[CurView - 1] = True; } break; case KWD_With: /* With */ pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiCondAttrPresent = TRUE; break; case KWD_Without: /* Without */ pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiCondAttrPresent = FALSE; break; case KWD_TEXT: /* TEXT */ CreateConstant (CharString, wi); break; case KWD_SYMBOL: /* SYMBOL */ CreateConstant (Symbol, wi); break; case KWD_GRAPHICS: /* GRAPHICS */ CreateConstant (GraphicElem, wi); break; case KWD_PICTURE: /* PICTURE */ CreateConstant (Picture, wi); break; case KWD_DATE: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarDate; break; case KWD_FDATE: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarFDate; break; case KWD_DocName: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarDocName; break; case KWD_DirName: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarDirName; break; case KWD_ElemName: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarElemName; break; case KWD_AttributeName: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarAttrName; break; case KWD_VALUE: break; case KWD_PageNumber: pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarPageNumber; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntArabic; pPresVar->PvItem[pPresVar->PvNItems - 1].ViView = 1; break; case KWD_ARABIC /* ARABIC */ : pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntArabic; break; case KWD_UROMAN /* UROMAN */ : pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntURoman; break; case KWD_LROMAN /* LROMAN */ : pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntLRoman; break; case KWD_UPPERCASE /* UPPERCASE */ : pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntUppercase; break; case KWD_LOWERCASE /* LOWERCASE */ : pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntLowercase; break; case KWD_FORWARD: /* forward */ Forward = True; break; case KWD_BEGIN /* BEGIN */ : if (gCode == RULE_ViewRuleList) ViewBlock = True; if (gCode == RULE_RuleList) { RuleBlock = True; ConditionEnd (); } if (gCode == RULE_CondRuleList) CondBlock = True; break; case KWD_Otherwise: /* Otherwise */ Conditions = NULL; NewCondition (wi); Conditions->CoCondition = PcDefaultCond; break; case KWD_VertRef: /* VertRef */ CreatePRule (PtVertRef, wi); CurRule->PrPosRule.PoPosDef = VertRef; break; case KWD_HorizRef: /* HorizRef */ CreatePRule (PtHorizRef, wi); CurRule->PrPosRule.PoPosDef = HorizRef; break; case KWD_Height /* Height */ : if (InRule) if (CurRule->PrType == PtHeight) CurRule->PrDimRule.DrSameDimens = True; else CurRule->PrDimRule.DrSameDimens = False; else CreatePRule (PtHeight, wi); break; case KWD_Width /* Width */ : if (InRule) if (CurRule->PrType == PtWidth) CurRule->PrDimRule.DrSameDimens = True; else CurRule->PrDimRule.DrSameDimens = False; else CreatePRule (PtWidth, wi); break; case KWD_VertPos: /* VertPos */ CreatePRule (PtVertPos, wi); AxisDef = True; /* le prochain repere boite est une definition */ break; case KWD_HorizPos: /* HorizPos */ CreatePRule (PtHorizPos, wi); AxisDef = True; /* le prochain repere boite est une definition */ break; case KWD_Justify: /* Justify */ CreatePRule (PtJustify, wi); break; case KWD_Hyphenate: /* Hyphenate */ CreatePRule (PtHyphenate, wi); break; case KWD_VertOverflow: /* VertOverflow */ CreatePRule (PtVertOverflow, wi); break; case KWD_HorizOverflow: /* HorizOverflow */ CreatePRule (PtHorizOverflow, wi); break; case KWD_LineSpacing: /* LineSpacing */ CreatePRule (PtLineSpacing, wi); break; case KWD_Break /* Break */ : CompilerMessage (wi, PRS, INFO, USE_PAGEBREAK, inputLine, LineNum); if (Conditions != NULL) /* un IF precede la regle Break. Erreur */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_CONDITION, inputLine, LineNum); else if (CurView != 1) /* interdit dans une vue non-principale */ CompilerMessage (wi, PRS, FATAL, RULE_FORBIDDEN_IN_A_VIEW, inputLine, LineNum); else { InBreakRule = True; ConditionEnd (); } break; case KWD_PageBreak /* PageBreak */ : if (Conditions != NULL) /* un IF precede la regle Break. Erreur */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_CONDITION, inputLine, LineNum); else if (CurView != 1) CompilerMessage (wi, PRS, FATAL, RULE_FORBIDDEN_IN_A_VIEW, inputLine, LineNum); else { InPageBreakRule = True; ConditionEnd (); } break; case KWD_LineBreak /* LineBreak */ : if (Conditions != NULL) /* un IF precede la regle Break. Erreur */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_CONDITION, inputLine, LineNum); else if (CurView != 1) CompilerMessage (wi, PRS, FATAL, RULE_FORBIDDEN_IN_A_VIEW, inputLine, LineNum); else { InLineBreakRule = True; ConditionEnd (); } break; case KWD_InLine: if (DefaultRuleDef) /* pas de regle InLine dans les regles par defaut */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); else InInLineRule = True; break; case KWD_Size: /* Size */ CreatePRule (PtSize, wi); break; case KWD_Visibility: /* Visibility */ CreatePRule (PtVisibility, wi); break; case KWD_Font: /* Font */ CreatePRule (PtFont, wi); break; case KWD_Roman: /* Style roman */ CurRule->PrChrValue = 'R'; break; case KWD_Bold: /* Style Bold */ CurRule->PrChrValue = 'B'; break; case KWD_Italics: /* Style Italics */ CurRule->PrChrValue = 'I'; break; case KWD_BoldItalics: /* Style BoldItalics */ CurRule->PrChrValue = 'G'; break; case KWD_BoldOblique: /* Style BoldOblique */ CurRule->PrChrValue = 'Q'; break; case KWD_Oblique: /* Style Oblique */ CurRule->PrChrValue = 'O'; break; case KWD_Underline: /* Souligne */ CreatePRule (PtUnderline, wi); break; case KWD_NoUnderline: /* pas de soulignement */ CurRule->PrChrValue = 'N'; break; case KWD_Underlined: /* soulignement */ CurRule->PrChrValue = 'U'; break; case KWD_Overlined: /* surlignement */ CurRule->PrChrValue = 'O'; break; case KWD_CrossedOut: CurRule->PrChrValue = 'C'; break; case KWD_Thickness: /* epaisseur du soulignement */ CreatePRule (PtThickness, wi); break; case KWD_Thin: /* soulignement fin */ CurRule->PrChrValue = 'N'; break; case KWD_Thick: /* soulignement epais */ CurRule->PrChrValue = 'T'; break; case KWD_Style: /* Style */ CreatePRule (PtStyle, wi); break; case KWD_Indent: /* Indent */ CreatePRule (PtIndent, wi); break; case KWD_Adjust: /* Adjust */ CreatePRule (PtAdjust, wi); break; case KWD_NoBreak1 /* NoBreak1 */ : if (DefaultRuleDef) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); /* pas de regle NoBreak1 * dans les regles par * defaut */ else CreatePRule (PtBreak1, wi); break; case KWD_NoBreak2 /* NoBreak2 */ : if (DefaultRuleDef) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); /* pas de regle NoBreak2 * dans les regles par * defaut */ else CreatePRule (PtBreak2, wi); break; case KWD_Content /* Content */ : /* autorise' seulement pour les boites de presentation et les */ /* elements reference ou paire */ if (PresBoxDef) { if (Conditions != NULL) /* un IF precede la regle Content d'une boite de presentation */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_CONDITION, inputLine, LineNum); } else /* on n'est pas dans une boite de presentation */ if (!(RuleDef && (pSSchema->SsRule[CurType - 1].SrConstruct == CsReference || pSSchema->SsRule[CurType - 1].SrConstruct == CsPairedElement))) /* on n'est pas dans les regles d'un element reference */ /* ni dans celles d'un element CsPairedElement */ CompilerMessage (wi, PRS, FATAL, AUTHORIZED_ONLY_FOR_BOXES_AND_REFS, inputLine, LineNum); else /* cree une regle "Content" pour le type courant */ { GenerateCopyRule (FnContentRef, wi); ConditionEnd (); } break; case KWD_Gather /* Gather */ : if (DefaultRuleDef) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); /* pas de regle Gather * dans les regles par defaut */ else if (Conditions != NULL) /* un IF precede la regle Break. Erreur */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_CONDITION, inputLine, LineNum); else if (CurView != 1) /* interdit dans une vue non-principale */ CompilerMessage (wi, PRS, FATAL, RULE_FORBIDDEN_IN_A_VIEW, inputLine, LineNum); else { InGatherRule = True; ConditionEnd (); } break; case KWD_Line: /* Line */ LayoutRule (FnLine, wi); break; case KWD_NoLine: /* NoLine */ LayoutRule (FnNoLine, wi); break; case KWD_Included: IncludedColumn = True; break; case KWD_Column: /* Column */ if (IncludedColumn) LayoutRule (FnSubColumn, wi); else LayoutRule (FnColumn, wi); IncludedColumn = False; #ifdef __COLPAGE__ /* la regle Colonne s'applique-t-elle a une vue d'elements associes? */ assoc = False; if (pSSchema->SsRule[CurType - 1].SrConstruct == CsList) /* la regle s'applique a un element liste */ { i = pSSchema->SsRule[CurType - 1].SrListItem; /* les elements de la liste sont-ils des elements associes ? */ assoc = pSSchema->SsRule[i - 1].SrAssocElem; } if (assoc) ; /* pPSchema->SPVueAssocAvecCol[CurType - 1] = True; */ else pPSchema->PsColumnView[CurView - 1] = True; #endif /* __COLPAGE__ */ break; case KWD_Copy /* Copy */ : if (DefaultRuleDef) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); else if (CurView != 1) /* regle autorisee seulement dans la vue principale */ CompilerMessage (wi, PRS, FATAL, RULE_FORBIDDEN_IN_A_VIEW, inputLine, LineNum); else if (RuleDef && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) /* reserve' aux references */ CompilerMessage (wi, PRS, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else { GenerateCopyRule (FnCopy, wi); ConditionEnd (); } break; case KWD_Depth: /* Depth */ CreatePRule (PtDepth, wi); break; case KWD_LineStyle: CreatePRule (PtLineStyle, wi); break; case KWD_LineWeight: CreatePRule (PtLineWeight, wi); break; case KWD_FillPattern: CreatePRule (PtFillPattern, wi); break; case KWD_Background: CreatePRule (PtBackground, wi); break; case KWD_Foreground: CreatePRule (PtForeground, wi); break; case KWD_ShowBox: LayoutRule (FnShowBox, wi); break; case KWD_BackgroundPicture: /* create a new constant */ NewConst (wi); LayoutRule (FnBackgroundPicture, wi); CurRule->PrNPresBoxes = 1; CurRule->PrPresBox[0] = pPSchema->PsNConstants; break; case KWD_PictureMode: LayoutRule (FnPictureMode, wi); CurRule->PrNPresBoxes = 1; CurRule->PrPresBox[0] = RealSize; break; case KWD_NormalSize: CurRule->PrPresBox[0] = RealSize; break; case KWD_Scale: CurRule->PrPresBox[0] = ReScale; break; case KWD_RepeatXY: CurRule->PrPresBox[0] = FillFrame; break; case KWD_RepeatX: CurRule->PrPresBox[0] = XRepeat; break; case KWD_RepeatY: CurRule->PrPresBox[0] = YRepeat; break; case KWD_Solid: CurRule->PrChrValue = 'S'; break; case KWD_Dashed: CurRule->PrChrValue = '-'; break; case KWD_Dotted: CurRule->PrChrValue = '.'; break; case KWD_nil /* NULL */ : if (CurRule->PrType == PtHeight || CurRule->PrType == PtWidth) CompilerMessage (wi, PRS, FATAL, FORDBIDDEN_IN_HEIGHT_AND_WIDTH, inputLine, LineNum); else { CurRule->PrPosRule.PoPosDef = NoEdge; AxisDef = True; } break; case KWD_UserSpecified: if (!(RuleDef || AttributeDef)) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_A_PRES_BOX, inputLine, LineNum); /* interdit pour les boites de presentation */ else if (CurRule->PrType == PtHeight || CurRule->PrType == PtWidth) CurRule->PrDimRule.DrUserSpecified = True; else if (CurRule->PrType == PtVertPos || CurRule->PrType == PtHorizPos) CurRule->PrPosRule.PoUserSpecified = True; break; case KWD_Refering: /* Refering */ SetLevel (RlContainsRef, wi); break; case KWD_Enclosing /* Enclosing */ : if (gCode == RULE_Reference) SetLevel (RlEnclosing, wi); else InheritRule (InheritParent); break; case KWD_Enclosed /* Enclosed */ : if (gCode == RULE_Reference) SetLevel (RlEnclosed, wi); else if (CurRule->PrType == PtVisibility) CompilerMessage (wi, PRS, FATAL, CANT_INHERIT_FROM_ENCLOSED, inputLine, LineNum); else InheritRule (InheritChild); break; case KWD_Creator: if (!PresBoxDef) /* on n'est pas dans une boite de presentation, erreur */ CompilerMessage (BeginCopyType, PRS, FATAL, VALID_ONLY_FOR_PRES_BOX, inputLine, LineNum); else if (gCode == RULE_Reference) SetLevel (RlCreator, wi); else InheritRule (InheritCreator); break; case KWD_Previous /* Previous */ : if (gCode == RULE_Reference) SetLevel (RlPrevious, wi); else if (CurRule->PrType == PtVisibility) CompilerMessage (wi, PRS, FATAL, CANT_INHERIT_FROM_PREVIOUS, inputLine, LineNum); else InheritRule (InheritPrevious); break; case KWD_GrandFather: InheritRule (InheritGrandFather); break; case KWD_Next: /* Next */ SetLevel (RlNext, wi); break; case KWD_Root: /* Root */ SetLevel (RlRoot, wi); break; case KWD_Refered /* Refered */ : case KWD_Referred /* Referred */ : if (gCode == RULE_ElemCondition) /* dans une condition "IF Referred" */ Conditions->CoCondition = PcReferred; else if (!AttributeDef && !PresBoxDef) /* autorise' seulement pour les attributs */ CompilerMessage (wi, PRS, FATAL, CANT_USE_IF_NOT_A_REF_ATTR, inputLine, LineNum); else if (AttributeDef && pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtReferenceAttr) /* seulement pour les attributs reference */ CompilerMessage (wi, PRS, FATAL, CANT_USE_IF_NOT_A_REF_ATTR, inputLine, LineNum); else SetLevel (RlReferred, wi); break; case KWD_AnyElem: CurRule->PrPosRule.PoRefElem = True; CurRule->PrPosRule.PoTypeRefElem = MAX_PRES_VARIABLE + 1; break; case KWD_AnyBox: CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoRefPresBox = MAX_PRES_BOX + 1; break; case KWD_NOT /* NOT */ : if (gCode == RULE_Condition) /* dans une Condition */ Conditions->CoNotNegative = False; else /* Not dans NBoxType */ { switch (CurRule->PrType) { case PtVertRef: case PtHorizRef: case PtVertPos: case PtHorizPos: CurRule->PrPosRule.PoNotRel = True; break; case PtHeight: case PtWidth: if (CurRule->PrDimRule.DrPosition) CurRule->PrDimRule.DrPosRule.PoNotRel = True; else CurRule->PrDimRule.DrNotRelat = True; break; default: break; } } break; case KWD_Left /* Left */ : if (gCode == RULE_Adjustment) /* mode d'alignement des lignes */ CurRule->PrAdjust = AlignLeft; else ProcessAxis (Left, wi); break; case KWD_VMiddle /* VMiddle */ : if (gCode == RULE_Adjustment) /* mode d'alignement des lignes */ CurRule->PrAdjust = AlignCenter; else ProcessAxis (VertMiddle, wi); break; case KWD_VRef: /* VRef */ ProcessAxis (VertRef, wi); break; case KWD_Right /* Right */ : if (gCode == RULE_Adjustment) /* mode d'alignement des lignes */ CurRule->PrAdjust = AlignRight; else ProcessAxis (Right, wi); break; case KWD_Top: /* Top */ ProcessAxis (Top, wi); break; case KWD_HMiddle: /* HMiddle */ ProcessAxis (HorizMiddle, wi); break; case KWD_HRef: /* HRef */ ProcessAxis (HorizRef, wi); break; case KWD_Bottom: /* Bottom */ ProcessAxis (Bottom, wi); break; case KWD_CM /* cm */ : if (LatestNumberAttr) CompilerMessage (wi, PRS, FATAL, BAD_UNIT_FOR_AN_ATTR, inputLine, LineNum); else CurUnit = Centimeter; break; case KWD_MM /* mm */ : if (LatestNumberAttr) CompilerMessage (wi, PRS, FATAL, BAD_UNIT_FOR_AN_ATTR, inputLine, LineNum); else CurUnit = Millimeter; break; case KWD_PT /* pt */ : if (gCode == RULE_Unit) CurUnit = Point; else if (gCode == RULE_SizeInherit) CurRule->PrMinUnit = UnPoint; else if (gCode == RULE_InheritSize) CurRule->PrInhUnit = UnPoint; break; case KWD_PC /* pc */ : if (LatestNumberAttr) CompilerMessage (wi, PRS, FATAL, BAD_UNIT_FOR_AN_ATTR, inputLine, LineNum); else CurUnit = Pica; break; case KWD_IN /* in */ : if (gCode == RULE_Unit) if (LatestNumberAttr) CompilerMessage (wi, PRS, FATAL, BAD_UNIT_FOR_AN_ATTR, inputLine, LineNum); else CurUnit = Inch; break; case KWD_PX /* px */ : CurUnit = ScreenPixel; break; case KWD_EM /* em */ : CurUnit = FontHeight; break; case KWD_EX /* ex */ : CurUnit = XHeight; break; case KWD_Min: if (gCode == RULE_Dimension) CurRule->PrDimRule.DrMin = True; break; case KWD_Yes: /* Yes */ BooleanValue (True, wi); break; case KWD_No: /* No */ BooleanValue (False, wi); break; case KWD_LeftWithDots: /* LeftWithDots */ CurRule->PrAdjust = AlignLeftDots; break; case KWD_IF: /* IF */ if (DefaultRuleDef) /* pas de condition dans les regles par defaut */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_DEFAULT_RULES, inputLine, LineNum); else { Conditions = NULL; NewCondition (wi); } break; case KWD_AND /* AND */ : ConditionEnd (); NewCondition (wi); break; case KWD_Target: /* Target */ if (RuleDef && pSSchema->SsRule[CurType - 1].SrConstruct != CsReference) /* reserve' aux elements references */ CompilerMessage (wi, PRS, FATAL, VALID_ONLY_FOR_REFS, inputLine, LineNum); else if (AttributeDef && pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtReferenceAttr) /* seulement pour les attributs reference */ CompilerMessage (wi, PRS, FATAL, CANT_USE_IF_NOT_A_REF_ATTR, inputLine, LineNum); else Conditions->CoTarget = True; break; case KWD_First: /* First */ if (gCode == RULE_FirstSec) FirstInPair = True; else Conditions->CoCondition = PcFirst; break; case KWD_Second: /* Second */ SecondInPair = True; break; case KWD_Last: /* Last */ Conditions->CoCondition = PcLast; break; case KWD_FirstRef: /* FirstRef */ Conditions->CoCondition = PcFirstRef; break; case KWD_LastRef: /* LastRef */ Conditions->CoCondition = PcLastRef; break; case KWD_ExternalRef: /* ExternalRef */ Conditions->CoCondition = PcExternalRef; break; case KWD_InternalRef: /* InternalRef */ Conditions->CoCondition = PcInternalRef; break; case KWD_CopyRef: /* PcCopyRef */ Conditions->CoCondition = PcCopyRef; break; case KWD_AnyAttributes: /* AnyAttributs */ Conditions->CoCondition = PcAnyAttributes; break; case KWD_FirstAttr: /* FirstAttr */ Conditions->CoCondition = PcFirstAttr; break; case KWD_LastAttr: /* LastAttr */ Conditions->CoCondition = PcLastAttr; break; case KWD_UserPage: /* UserPage */ Conditions->CoCondition = PcUserPage; break; case KWD_StartPage: /* StartPage */ Conditions->CoCondition = PcStartPage; break; case KWD_ComputedPage: /* ComputedPage */ Conditions->CoCondition = PcComputedPage; break; case KWD_Empty: /* PcEmpty */ Conditions->CoCondition = PcEmpty; break; case KWD_MaxRangeVal: /* MaxRangeVal */ if (Conditions != NULL) Conditions->CoValCounter = CntMaxVal; CurMinMax = CntMaxVal; break; case KWD_MinRangeVal: /* MinRangeVal */ if (Conditions != NULL) Conditions->CoValCounter = CntMinVal; CurMinMax = CntMinVal; break; case KWD_Even: /* Even */ Conditions->CoCondition = PcEven; Conditions->CoCounter = 0; InCondPage = True; break; case KWD_Odd: /* Odd */ Conditions->CoCondition = PcOdd; Conditions->CoCounter = 0; InCondPage = True; break; case KWD_One: /* One */ Conditions->CoCondition = PcOne; Conditions->CoCounter = 0; InCondPage = True; break; case KWD_Immediately: Immediately = True; break; case KWD_Within: Conditions->CoCondition = PcWithin; Conditions->CoImmediate = Immediately; SignGreaterOrLess = False; /* a priori, il n'y a pas de nombre d'ancetres indique' */ /* On considere "If Within Type" comme "If Within >0 Type" */ Conditions->CoAncestorRel = CondGreater; Conditions->CoRelation = 0; Conditions->CoTypeAncestor = 0; Conditions->CoAncestorName[0] = '\0'; Conditions->CoSSchemaName[0] = '\0'; InWithinCond = True; break; case KWD_Create: /* Create */ CreationRule (FnCreateFirst, wi); CompilerMessage (wi, PRS, INFO, USE_CREATEFIRST, inputLine, LineNum); break; case KWD_CreateBefore: /* CreateBefore */ CreationRule (FnCreateBefore, wi); break; case KWD_CreateAfter: /* CreateAfter */ CreationRule (FnCreateAfter, wi); break; case KWD_CreateLast: /* CreateLast */ CreationRule (FnCreateLast, wi); break; case KWD_CreateFirst: /* CreateFirst */ CreationRule (FnCreateFirst, wi); break; case KWD_CreateWith: /* CreateWith */ CreationRule (FnCreateWith, wi); break; case KWD_CreateEnclosing: /* CreateEnclosing */ CreationRule (FnCreateEnclosing, wi); break; case KWD_Repeated: /* Repeated */ CurRule->PrPresBoxRepeat = True; break; case KWD_LESS: VCondLess = True; break; case KWD_GREATER: VCondGreater = True; break; case KWD_EQUAL: CondEqual = True; break; default: break; } } /*---------------------------------------------------------------------- GetTypeNumber retourne le numero du type d'element dont le nom est typeName. ----------------------------------------------------------------------*/ #ifdef __STDC__ static int GetTypeNumber (indLine wl, indLine wi, Name typeName) #else /* __STDC__ */ static int GetTypeNumber (wl, wi, typeName) indLine wl; indLine wi; Name typeName; #endif /* __STDC__ */ { int i; CopyName (typeName, wi, wl); /* verifie si le type est declare' dans le schema de structure */ i = 1; while (strcmp (typeName, pSSchema->SsRule[i - 1].SrName) && i < pSSchema->SsNRules) i++; if (strcmp (typeName, pSSchema->SsRule[i - 1].SrName)) i = 0; else if (InclusionRefName) /* on cherche une reference a un document importe' */ { while (i <= pSSchema->SsNRules && (pSSchema->SsRule[i - 1].SrConstruct != CsReference || !pSSchema->SsRule[i - 1].SrRefImportedDoc)) /* ce n'est pas ce que l'on cherche, on continue */ { i++; while (strcmp (typeName, pSSchema->SsRule[i - 1].SrName) && i < pSSchema->SsNRules) i++; } if (i > pSSchema->SsNRules) i = 0; } return i; } /*---------------------------------------------------------------------- ProcessTypeName traite un nom de type d'element ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessTypeName (SyntacticCode prevRule, Name typeName, indLine wi, indLine wl) #else /* __STDC__ */ static void ProcessTypeName (prevRule, typeName, wi, wl) SyntacticCode prevRule; Name typeName; indLine wi; indLine wl; #endif /* __STDC__ */ { int i; boolean found; SRule *pSRule; Counter *pCntr; i = GetTypeNumber (wl, wi, typeName); if (i == 0) CompilerMessage (wi, PRS, FATAL, UNKNOWN_TYPE, inputLine, LineNum); /* type inconnu */ else { if (pSSchema->SsRule[i - 1].SrConstruct == CsPairedElement) /* c'est un element CsPairedElement */ { if (!SecondInPair && !FirstInPair) /* le nom du type n'etait pas precede' de First ou Second */ CompilerMessage (wi, PRS, FATAL, MISSING_FIRST_SECOND, inputLine, LineNum); else if (SecondInPair) /* il s'agit du type suivant */ i++; } else /* ce n'est pas un element CsPairedElement */ if (SecondInPair || FirstInPair) /* le nom du type etait precede' de First ou Second, erreur */ CompilerMessage (wi, PRS, FATAL, NOT_A_PAIR, inputLine, LineNum); if (prevRule == RULE_FSTypeName) /* un nom de type d'element, avant les regles */ /* de presentation d'un attribut */ CurElemHeritAttr = i; else if (prevRule == RULE_PrintView) /* dans la liste des vues a imprimer */ { pSRule = &pSSchema->SsRule[i - 1]; /* on n'accepte que les listes d'elements associes */ if (pSRule->SrConstruct != CsList) CompilerMessage (wi, PRS, FATAL, ASSOC_ELEMS_ONLY, inputLine, LineNum); /* ce n'est pas une liste, erreur */ else if (!pSSchema->SsRule[pSRule->SrListItem - 1].SrAssocElem) CompilerMessage (wi, PRS, FATAL, ASSOC_ELEMS_ONLY, inputLine, LineNum); /* les constituants de la liste ne sont */ /* pas des elements associes */ else { if (pPSchema->PsNPrintedViews >= MAX_PRINT_VIEW) CompilerMessage (wi, PRS, FATAL, MAX_VIEWS_TO_BE_PRINTED_OVERFLOW, inputLine, LineNum); /* table des vues a imprimee saturee */ else { pPSchema->PsPrintedView[pPSchema->PsNPrintedViews].VpAssoc = True; pPSchema->PsPrintedView[pPSchema->PsNPrintedViews].VpNumber = i; pPSchema->PsNPrintedViews++; } } } else if (prevRule == RULE_TypeOrCounter) /* un nom de type au debut d'une regle Transmit */ { TransmittedElem = i; if (pPSchema->PsNTransmElems >= MAX_TRANSM_ELEM) CompilerMessage (wi, PRS, FATAL, MAX_MANY_TRANSMIT_RULES_FOR_ELEMS_OVERFLOW, inputLine, LineNum); /* table PsTransmElem saturee */ else if (pPSchema->PsElemTransmit[i - 1] > 0) CompilerMessage (wi, PRS, FATAL, ELEM_HAS_A_TRANSMIT_RULE, inputLine, LineNum); /* deja une regle transmit pout l'element */ else { pPSchema->PsNTransmElems++; pPSchema->PsElemTransmit[i - 1] = pPSchema->PsNTransmElems; } } else if (prevRule == RULE_Transmit) { /* un nom de type a la fin d'une regle Transmit */ if (!pSSchema->SsRule[i - 1].SrRefImportedDoc) CompilerMessage (wi, PRS, FATAL, NOT_AN_INCLUDED_DOC, inputLine, LineNum); /* ce n'est pas un document inclus */ else if (TransmittedCounter > 0) /* c'est une regle Transmit pour un compteur */ { pCntr = &pPSchema->PsCounter[TransmittedCounter - 1]; pCntr->CnTransmSSchemaAttr[pCntr->CnNTransmAttrs - 1] = i; } else if (TransmittedElem > 0) /* un nom de type a la fin d'une regle Transmit pour un */ /* contenu d'element */ pPSchema->PsTransmElem[pPSchema->PsNTransmElems - 1].TeTargetDoc = i; } else if (prevRule == RULE_VarConst) /* dans une regle "Content" */ if (!PresBoxDef) /* on est dans une regle Content d'un element reference ou paire */ /* refus: seules les constantes sont acceptees dans cette regle */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_A_REF, inputLine, LineNum); else /* contenu d'une boite de presentation */ if (!pSSchema->SsRule[i - 1].SrAssocElem) /* ce n'est pas un element associe, erreur */ CompilerMessage (wi, PRS, FATAL, NOT_AN_ASSOC_ELEM, inputLine, LineNum); else { pPSchema->PsPresentBox[CurPresBox - 1].PbContent = ContElement; pPSchema->PsPresentBox[CurPresBox - 1].PbContElem = i; /* ces elements associes sont affiches dans des boites de */ /* haut ou bas de page */ pPSchema->PsInPageHeaderOrFooter[i - 1] = True; /* cherche dans le schema de structure le type d'element */ /* qui reference ce type d'element associe */ i = MAX_BASIC_TYPE; found = False; do { pSRule = &pSSchema->SsRule[i++]; if (pSRule->SrConstruct == CsReference) if (pSRule->SrReferredType == pPSchema->PsPresentBox[CurPresBox - 1].PbContElem) found = True; } while (!found && i < pSSchema->SsNRules); if (found) pPSchema->PsPresentBox[CurPresBox - 1].PbContRefElem = i; else CompilerMessage (wi, PRS, FATAL, MISSING_REF_TO_ELEM, inputLine, LineNum); /* pas de reference dans le schema, erreur */ } else if (CounterDef) /* dans une definition de compteur */ { pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiElemType = i; pCntr->CnItem[pCntr->CnNItems - 1].CiViewNum = 0; } else if (!InRule) /* debut des regles d'un type */ { if (pPSchema->PsElemPRule[i - 1] != NULL) CompilerMessage (wi, PRS, FATAL, CANT_REDEFINE, inputLine, LineNum); /* deja traite' */ else { pPSchema->PsElemPRule[i - 1] = NextRule; FirstRule = NextRule; CurType = i; } } else /* utilisation d'un type dans un positionnement, un */ /* dimensionnement, une copie ou un contenu de boite */ { if ((CurRule->PrType == PtVertRef || CurRule->PrType == PtHorizRef) && CurRule->PrPosRule.PoRelation != RlEnclosed) CompilerMessage (wi, PRS, FATAL, ONLY_ENCLOSED_AND_ARE_ALLOWED, inputLine, LineNum); else switch (CurRule->PrType) { case PtVertRef: case PtHorizRef: case PtVertPos: case PtHorizPos: CurRule->PrPosRule.PoRefElem = True; CurRule->PrPosRule.PoTypeRefElem = i; break; case PtHeight: case PtWidth: if (CurRule->PrDimRule.DrPosition) { CurRule->PrDimRule.DrPosRule.PoRefElem = True; CurRule->PrDimRule.DrPosRule.PoTypeRefElem = i; } else { CurRule->PrDimRule.DrRefElement = True; CurRule->PrDimRule.DrTypeRefElem = i; } break; case PtFunction: if (CurRule->PrPresFunction == FnCopy) { CurRule->PrElement = True; CurRule->PrExternal = False; CurRule->PrNPresBoxes = 1; CurRule->PrPresBox[0] = i; } break; default: break; } } } FirstInPair = False; SecondInPair = False; InclusionRefName = False; } /*---------------------------------------------------------------------- NewBoxName traite un nouveau nom de boite de presentation ----------------------------------------------------------------------*/ #ifdef __STDC__ static void NewBoxName (indLine wl, indLine wi, int identnum) #else /* __STDC__ */ static void NewBoxName (wl, wi, identnum) indLine wl; indLine wi; int identnum; #endif /* __STDC__ */ { PresentationBox *pPresBox; pPresBox = &pPSchema->PsPresentBox[pPSchema->PsNPresentBoxes]; pPSchema->PsNPresentBoxes++; Identifier[identnum].SrcIdentDefRule = pPSchema->PsNPresentBoxes; if (Forward) { pPresBox->PbName[0] = ' '; Forward = False; } else { CopyName (pPresBox->PbName, wi, wl); pPresBox->PbFirstPRule = NextRule; FirstRule = NextRule; CurPresBox = pPSchema->PsNPresentBoxes; } /* a priori la boite a un contenu libre */ pPresBox->PbContent = FreeContent; } /*---------------------------------------------------------------------- IntAttribute traite un nom d'attribut qui apparait a la place d'une valeur numerique entiere. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void IntAttribute (int attr, SyntacticCode prevRule, indLine wi) #else /* __STDC__ */ static void IntAttribute (attr, prevRule, wi) int attr; SyntacticCode prevRule; indLine wi; #endif /* __STDC__ */ { if (pSSchema->SsAttribute[attr - 1].AttrType != AtNumAttr) /* not an attribute of type Integer, error */ CompilerMessage (wi, PRS, FATAL, BAD_ATTR_TYPE, inputLine, LineNum); else switch (prevRule) /* prevRule = number of the rule where the attribute name appears*/ { case RULE_NbInherit: /* Integer */ CurRule->PrIntValue = attr; CurRule->PrAttrValue = True; break; case RULE_DimRatioA: /* DimRatioA */ CurUnit = Percent; LatestNumber = attr; LatestNumberAttr = True; PrevSign = 1; /* sign = "+" */ CurRule->PrDimRule.DrUnit = UnPercent; break; case RULE_IntPartA: /* IntPartA */ LatestNumber = attr; LatestNumberAttr = True; break; case RULE_PosIntegerA: /* PosIntegerA */ CurRule->PrInhDelta = attr; CurRule->PrInhAttr = True; CurRule->PrInhUnit = UnRelative; break; case RULE_maximumA: /* maximumA */ CurRule->PrInhMinOrMax = attr; CurRule->PrMinMaxAttr = True; break; case RULE_NegIntegerA: /* NegIntegerA */ CurRule->PrInhDelta = -attr; CurRule->PrInhAttr = True; CurRule->PrInhUnit = UnRelative; break; case RULE_minimumA: /* minimumA */ CurRule->PrInhMinOrMax = attr; CurRule->PrMinMaxAttr = True; break; case RULE_SizeA: /* SizeA */ CurRule->PrMinValue = attr; CurRule->PrMinUnit = UnRelative; CurRule->PrMinAttr = True; break; case RULE_PosSizeA: /* PosSizeA */ CurRule->PrInhDelta = attr; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = True; break; case RULE_MaxSizeA: /* MaxSizeA */ CurRule->PrInhMinOrMax = attr; CurRule->PrMinMaxAttr = True; break; case RULE_NegSizeA: /* NegSizeA */ CurRule->PrInhDelta = -attr; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = True; break; case RULE_MinSizeA: /* MinSizeA */ CurRule->PrInhMinOrMax = attr; CurRule->PrMinMaxAttr = True; break; default: break; } } /*---------------------------------------------------------------------- ProcessName traite un nom. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessName (SyntacticCode gCode, int identnum, SyntacticCode prevRule, indLine wl, indLine wi) #else /* __STDC__ */ static void ProcessName (gCode, identnum, prevRule, wl, wi) SyntacticCode gCode; int identnum; SyntacticCode prevRule; indLine wl; indLine wi; #endif /* __STDC__ */ { Name n; int i, j; boolean ok, new; Counter *pCntr; PresVariable *pPresVar; PresentationBox *pPresBox; PresVarItem *pVarElem; PtrPRule pPRule; PtrCondition pCond; TtAttribute *pAttr; switch (gCode) { /* gCode = numero de la regle ou apparait le nom */ case RULE_TypeName /* TypeName */ : if (prevRule == RULE_PresentModel) /* nom de la structure generique */ { CopyName (n, wi, wl); /* lit le schema de structure compile' */ GetSchStruct (&pSSchema); if (pSSchema == NULL) TtaDisplaySimpleMessage (FATAL, PRS, NO_MORE_MEM_LEFT); /* memoire insuffisante */ if (!ReadStructureSchema (n, pSSchema)) TtaDisplaySimpleMessage (FATAL, PRS, MISSING_STRUCT_SCHEM); /* echec lecture du schema de structure */ else if (strcmp (n, pSSchema->SsName)) CompilerMessage (wi, PRS, FATAL, STRUCT_SCHEM_DOES_NOT_MATCH, inputLine, LineNum); else { Initialize (); strncpy (pPSchema->PsStructName, n, MAX_NAME_LENGTH); } } else if (prevRule == RULE_ExtStruct) { /* verifier que ce schema de structure externe existe et qu'il */ /* contient bien le type CopyType */ CopyName (n, wi, wl); if (!ReadStructureSchema (n, pExternalSS)) /* echec lecture du schema de structure */ CompilerMessage (wi, PRS, FATAL, CANT_LOAD_SCHEMA, inputLine, LineNum); else /* le schema de structure externe a ete charge' */ { i = 1; while (strcmp (CopyType, pExternalSS->SsRule[i - 1].SrName) != 0 && i < pExternalSS->SsNRules) i++; if (strcmp (CopyType, pExternalSS->SsRule[i - 1].SrName) != 0) /* type inconnu */ if (PresBoxDef || InWithinCond) /* on est dans une boite de presentation, erreur */ CompilerMessage (BeginCopyType, PRS, FATAL, NOT_FOR_PRES_BOX, inputLine, LineNum); else { /* on suppose que c'est un nom de boite de presentation */ /* definie dans un autre schema de presentation (pour */ /* la presentation des references externes) */ if ((RuleDef && pSSchema->SsRule[CurType - 1].SrRefTypeNat[0] == '\0') || (AttributeDef && pSSchema->SsAttribute[CurAttrNum - 1].AttrTypeRefNature[0] == '\0')) /* la regle ne s'applique pas a` une reference externe */ CompilerMessage (BeginCopyType, PRS, FATAL, AUTHORIZED_ONLY_FOR_EXT_REFS, inputLine, LineNum); else /* la regle s'applique a` une reference externe */ if (CurRule->PrNPresBoxes != 0) /* deja une boite dans la regle, on refuse */ CompilerMessage (wi, PRS, FATAL, REDEFINITION_OF_CONTENT, inputLine, LineNum); else { strncpy (CurRule->PrPresBoxName, CopyType, MAX_NAME_LENGTH); /* indique qu'on copie une boite de presentation et non un element */ CurRule->PrElement = False; } } else if (InWithinCond) { strncpy (Conditions->CoAncestorName, CopyType, MAX_NAME_LENGTH); CopyName (Conditions->CoSSchemaName, wi, wl); Conditions->CoTypeAncestor = 0; } else /* le type a copier existe, il a le numero i */ { /* indique qu'on copie un element et non une boite de presentation */ CurRule->PrElement = True; /* nom du type d'element a copier */ strncpy (CurRule->PrPresBoxName, CopyType, MAX_NAME_LENGTH); /* indique que PrPresBoxName est un nom de type defini */ /* dans un autre schema */ CurRule->PrExternal = True; } /* marque que ce nom externe est traite' */ CopyType[0] = '\0'; BeginCopyType = 0; } } else if (prevRule == RULE_ElemCondition) { /* On est dans une condition */ CopyName (n, wi, wl); /* verifie si le type existe dans le schema de structure */ i = 1; while (strcmp (n, pSSchema->SsRule[i - 1].SrName) && i < pSSchema->SsNRules) i++; if (InWithinCond) /* un nom de type d'element dans une condition Within */ { if (strcmp (n, pSSchema->SsRule[i - 1].SrName)) /* type inconnu */ { /* c'est peut-etre un type defini dans un autre schema */ CopyName (CopyType, wi, wl); BeginCopyType = wi; } else /* le type existe, il a le numero i */ Conditions->CoTypeAncestor = i; /* On remet Immediately a faux seulement ici */ Immediately = False; } else /* on est dans une condition, mais pas apres Within */ { if (!strcmp (n, pSSchema->SsRule[i - 1].SrName)) /* c'est bien un nom de type d'element */ { /* la regle est-elle bien pour un attribut ? */ if (!AttributeDef) CompilerMessage (wi, PRS, FATAL, VALID_ONLY_FOR_ATTRIBUTES, inputLine, LineNum); else { Conditions->CoCondition = PcElemType; Conditions->CoTypeElAttr = i; } } else /* peut-etre est-ce un nom d'attribut */ { /* cherche ce nom parmi les attributs du schema de structure */ i = 1; while (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName) && i < pSSchema->SsNAttributes) i++; if (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName)) /* on ne l'a pas trouve, erreur */ CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); else /* c'est un nom d'attribut dans une condition */ { /* change le type de ce nom qui devient un nom d'attribut */ Identifier[identnum].SrcIdentCode = RULE_AttrName; /* traite ce nom d'attribut */ Conditions->CoCondition = PcAttribute; Conditions->CoTypeElAttr = i; } } } } else if (prevRule == RULE_CountFunction) { /* On est dans un CntrRLevel */ pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; CopyName (n, wi, wl); /* verifie si le type existe dans le schema de structure */ i = 1; while (strcmp (n, pSSchema->SsRule[i - 1].SrName) && i < pSSchema->SsNRules) i++; if (strcmp (n, pSSchema->SsRule[i - 1].SrName)) /* type inconnu */ CompilerMessage (wi, PRS, FATAL, UNKNOWN_TYPE, inputLine, LineNum); else /* le type existe, il a le numero i */ pCntr->CnItem[0].CiElemType = i; } else ProcessTypeName (prevRule, n, wi, wl); break; case RULE_ViewName: /* ViewName */ if (ViewDef) /* declaration de vue */ { if (pPSchema->PsNViews >= MAX_VIEW) CompilerMessage (wi, PRS, FATAL, MAX_VIEWS_OVERFLOW, inputLine, LineNum); /* Trop de vues */ else if (Identifier[identnum].SrcIdentDefRule != 0) CompilerMessage (wi, PRS, FATAL, CANT_REDECLARE_NAME, inputLine, LineNum); /* Vue deja declaree */ else /* ajoute une vue dans la table des vues */ { CopyName (pPSchema->PsView[pPSchema->PsNViews], wi, wl); pPSchema->PsNViews++; Identifier[identnum].SrcIdentDefRule = pPSchema->PsNViews; } } else if (prevRule == RULE_PrintView) /* dans la liste des vues a imprimer */ if (Identifier[identnum].SrcIdentDefRule == 0) /* ce nom n'a pas ete declare comme nom de vue, voyons si */ /* ce n'est pas un identificateur de type */ { ProcessTypeName (prevRule, n, wi, wl); Identifier[identnum].SrcIdentCode = RULE_TypeName; /* changement de type, c'est */ /* maintenant un identificateur de type structure */ } else /* ce nom a ete declare comme nom de vue */ { if (pPSchema->PsNPrintedViews >= MAX_PRINT_VIEW) CompilerMessage (wi, PRS, FATAL, MAX_VIEWS_TO_BE_PRINTED_OVERFLOW, inputLine, LineNum); /* table des vues a imprimee saturee */ else { pPSchema->PsPrintedView[pPSchema->PsNPrintedViews].VpAssoc = False; pPSchema->PsPrintedView[pPSchema->PsNPrintedViews].VpNumber = Identifier[identnum].SrcIdentDefRule; pPSchema->PsNPrintedViews++; } } else if (CounterDef) { pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiViewNum = Identifier[identnum].SrcIdentDefRule; } else if (prevRule == RULE_CounterAttrPage) if (Identifier[identnum].SrcIdentDefRule == 0) CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); /* Vue non declaree */ else { pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems - 1].ViView = Identifier[identnum].SrcIdentDefRule; } else if (prevRule == RULE_ViewRules) /* dans une instruction 'in ViewName ...' */ if (Identifier[identnum].SrcIdentDefRule == 0) /* Vue non declaree */ CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); else if (Identifier[identnum].SrcIdentDefRule == 1) /* C'est la vue* principale, erreur */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_THE_MAIN_VIEW, inputLine, LineNum); else { CurView = Identifier[identnum].SrcIdentDefRule; RulesForView = True; } break; case RULE_CounterName: /* CounterName */ if (CounterDef) /* declaration de compteur */ { if (pPSchema->PsNCounters >= MAX_PRES_COUNTER) CompilerMessage (wi, PRS, FATAL, MAX_COUNTERS_OVERFLOW, inputLine, LineNum); else if (Identifier[identnum].SrcIdentDefRule != 0) CompilerMessage (wi, PRS, FATAL, CANT_REDECLARE_NAME, inputLine, LineNum); else { pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters]; pPSchema->PsNCounters++; pCntr->CnNItems = 0; pCntr->CnNTransmAttrs = 0; pCntr->CnNPresBoxes = 0; pCntr->CnNCreators = 0; pCntr->CnNCreatedBoxes = 0; Identifier[identnum].SrcIdentDefRule = pPSchema->PsNCounters; } } else if (Identifier[identnum].SrcIdentDefRule == 0) /* on n'a pas encore rencontre' ce nom */ if (prevRule != RULE_CounterAttrPage) CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); /* compteur non declare' */ else /* on vient de la regle CounterAttrPage; peut-etre est-ce un */ /* nom d'attribut */ { /* cherche ce nom parmi les attributs du schema de structure */ CopyName (n, wi, wl); i = 1; while (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName) && i < pSSchema->SsNAttributes) i++; if (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName)) CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); /* on ne l'a pas trouve, erreur */ else /* c'est un nom d'attribut apres VALUE */ { /* change le type de ce nom qui devient un nom d'attribut */ Identifier[identnum].SrcIdentCode = RULE_AttrName; /* traite ce nom d'attribut */ pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarAttrValue; pPresVar->PvItem[pPresVar->PvNItems - 1].ViStyle = CntArabic; pPresVar->PvItem[pPresVar->PvNItems - 1].ViAttr = i; } } else if (prevRule == RULE_CounterAttrPage) /* un compteur dans une definition de variable */ { pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; pPresVar->PvItem[pPresVar->PvNItems].ViType = VarCounter; pPresVar->PvItem[pPresVar->PvNItems].ViCounter = Identifier[identnum].SrcIdentDefRule; pPresVar->PvItem[pPresVar->PvNItems].ViCounterVal = CurMinMax; pPresVar->PvNItems++; if (NewVariableDef) /* definition de var. dans une regle Content */ { pCntr = &pPSchema->PsCounter[Identifier[identnum].SrcIdentDefRule - 1]; /* ce compteur est utilise' dans la boite de presentation */ if (pCntr->CnNPresBoxes < MAX_PRES_COUNT_USER) { pCntr->CnPresBox[pCntr->CnNPresBoxes] = CurPresBox; if (CurMinMax == CntMaxVal || CurMinMax == CntMinVal) pCntr->CnMinMaxPresBox[pCntr->CnNPresBoxes] = True; else pCntr->CnMinMaxPresBox[pCntr->CnNPresBoxes] = False; pCntr->CnNPresBoxes++; } } CurMinMax = CntCurVal; } else if (prevRule == RULE_ElemCondition) /* dans une condition */ { Conditions->CoCounter = Identifier[identnum].SrcIdentDefRule; pCntr = &pPSchema->PsCounter[Identifier[identnum].SrcIdentDefRule - 1]; /* ce compteur est-il deja utilise' par la boite courante */ /* comme condition de creation ? */ if (PresBoxDef) j = CurPresBox; else j = CurType; new = True; for (i = 0; i < pCntr->CnNCreators; i++) if (pCntr->CnCreator[i] == j && pCntr->CnPresBoxCreator[i] == PresBoxDef) new = False; if (new) /* ce compteur n'est pas encore utilise' par la boite */ /* courante dans ses regles de creation, on le marque. */ { pCntr->CnCreator[pCntr->CnNCreators] = j; pCntr->CnPresBoxCreator[pCntr->CnNCreators] = PresBoxDef; if (CurMinMax == CntMaxVal || CurMinMax == CntMinVal) pCntr->CnMinMaxCreator[pCntr->CnNCreators] = True; else pCntr->CnMinMaxCreator[pCntr->CnNCreators] = False; CurMinMax = CntCurVal; pCntr->CnNCreators++; } } else if (prevRule == RULE_TypeOrCounter) /* un compteur au debut d'une regle Transmit */ { TransmittedCounter = Identifier[identnum].SrcIdentDefRule; pCntr = &pPSchema->PsCounter[TransmittedCounter - 1]; if (pCntr->CnNTransmAttrs >= MAX_TRANSM_ATTR) { CompilerMessage (wi, PRS, FATAL, MAX_TRANSMIT_RULES_FOR_COUNTER_OVERFLOW, inputLine, LineNum); /* trop de regles transmit pour ce compteur */ TransmittedCounter = 0; } else pCntr->CnNTransmAttrs++; } break; case RULE_AttrName: /* AttrName */ /* cherche ce nom d'attribut dans le schema de structure */ CopyName (n, wi, wl); i = 1; while (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName) && i < pSSchema->SsNAttributes) i++; if (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName)) CompilerMessage (wi, PRS, FATAL, NO_SUCH__ATTR, inputLine, LineNum); /* on ne l'a pas trouve, erreur */ else if (!(prevRule == RULE_Attr || prevRule == RULE_CountFunction || prevRule == RULE_CondAttr || prevRule == RULE_Function || prevRule == RULE_AttrValue || prevRule == RULE_AttrRelat || prevRule == RULE_ElemCondition || prevRule == RULE_CounterAttrPage)) /* c'est un nom d'attribut a la place d'une valeur numerique */ IntAttribute (i, prevRule, wi); else if (prevRule == RULE_Function || prevRule == RULE_CounterAttrPage) /* c'est un nom d'attribut dans une variable */ { pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; if (pPresVar->PvNItems > 0) /* ce n'est pas le premier element de la variable */ /* si le 1er element n'est pas du texte, on n'accepte pas */ /* le nouvel element */ if (pPresVar->PvItem[0].ViType == VarText) if (pPSchema->PsConstant[pPresVar->PvItem[0].ViConstant - 1].PdType != CharString) CompilerMessage (wi, PRS, FATAL, MAX_FUNCTIONS_IN_A_VARIABLE_OVERFLOW, inputLine, LineNum); if (pPresVar->PvNItems >= MAX_PRES_VAR_ITEM) CompilerMessage (wi, PRS, FATAL, MAX_FUNCTIONS_IN_A_VARIABLE_OVERFLOW, inputLine, LineNum); /* variable trop longue */ else { pPresVar->PvItem[pPresVar->PvNItems].ViType = VarAttrValue; pPresVar->PvItem[pPresVar->PvNItems].ViStyle = CntArabic; pPresVar->PvItem[pPresVar->PvNItems].ViAttr = i; pPresVar->PvNItems++; } } else if (prevRule == RULE_Attr) /* c'est un nom d'attribut auquel on va associer des regles de */ /* presentation */ { CurAttrNum = i; /* on se souvient de son numero */ /* on effectue un certain nombre d'initialisations */ NewAttributeDef = True; VCondLess = False; VCondGreater = False; CondEqual = False; CurAttrVal = 0; /* on n'a pas encore rencontre' de valeur */ CurComparAttr = 0; /* a priori on ne compare pas avec un attribut */ CurElemHeritAttr = 0; /* a priori ce n'est pas de l'heritage */ CurAttrLowerBound = -MAX_INT_ATTR_VAL - 1; /* - infini */ CurAttrUpperBound = MAX_INT_ATTR_VAL + 1; /* + infini */ CurTextEqual[0] = '\0'; /* string vide */ } else if (prevRule == RULE_CountFunction) { /* c'est un nom d'attribut apres le mot INIT ou REINIT dans */ /* une definition de compteur */ /* seuls les attributs numeriques sont accepte's */ if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr) /* ce n'est pas un attribut numerique, erreur */ CompilerMessage (wi, PRS, FATAL, BAD_ATTR_TYPE, inputLine, LineNum); else { pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; if (AttrInitCounter) /* le compteur courant prendra cet attribut comme */ /* valeur initiale */ pCntr->CnItem[0].CiInitAttr = i; else pCntr->CnItem[0].CiReinitAttr = i; } } else if (prevRule == RULE_CondAttr) { /* c'est un nom d'attribut apres le mot WITH ou WITHOUT dans une definition de compteur */ pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiCondAttr = i; } else if (prevRule == RULE_AttrRelat) { /* c'est un nom d'attribut a la place d'une valeur numerique */ /* pour comparer la valeur de l'attribut a un attribut pose */ /* sur un element englobant */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtNumAttr) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_FOR_THIS_TYPE_OF_ATTR, inputLine, LineNum); /* interdit pour un attribut non numerique */ else if (pSSchema->SsAttribute[i - 1].AttrType != AtNumAttr) CompilerMessage (wi, PRS, FATAL, FORBIDDEN_FOR_THIS_TYPE_OF_ATTR, inputLine, LineNum); /* l'attribut n'est pas un attribut numerique */ else CurComparAttr = i; } else if (prevRule == RULE_ElemCondition) /* c'est un nom d'attribut dans une condition */ { Conditions->CoCondition = PcAttribute; Conditions->CoTypeElAttr = i; } break; case RULE_ConstName: /* ConstName */ if (ConstantDef) /* definition de constante */ if (Identifier[identnum].SrcIdentDefRule != 0) CompilerMessage (wi, PRS, FATAL, CANT_REDECLARE_NAME, inputLine, LineNum); else { NewConst (wi); Identifier[identnum].SrcIdentDefRule = pPSchema->PsNConstants; } else if (Identifier[identnum].SrcIdentDefRule == 0) /* utilisation d'une constante */ /* on n'a pas encore rencontre' ce nom */ if (prevRule == RULE_Function) /* peut-etre est-ce un nom d'attribut */ /* cherche ce nom parmi les attributs du schema de structure */ { CopyName (n, wi, wl); i = 1; while (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName) && i < pSSchema->SsNAttributes) i++; if (strcmp (n, pSSchema->SsAttribute[i - 1].AttrName)) CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); /* on ne l'a pas trouve, erreur */ else /* c'est un nom d'attribut dans une variable */ /* change le type de ce nom qui devient un nom d'attribut */ { Identifier[identnum].SrcIdentCode = RULE_AttrName; /* r=19 */ /* traite ce nom d'attribut */ pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarAttrValue; pPresVar->PvItem[pPresVar->PvNItems - 1].ViAttr = i; } } else CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); /* nom de constante inconnu */ else { if (PresBoxDef && !NewVariableDef) /* dans une regle 'Content : Nom_Constante;' d'une boite de presentation */ { pPresBox = &pPSchema->PsPresentBox[CurPresBox - 1]; pPresBox->PbContent = ContConst; pPresBox->PbContConstant = Identifier[identnum].SrcIdentDefRule; } if (VariableDef || NewVariableDef) /* dans une definition de variable */ { pPresVar = &pPSchema->PsVariable[pPSchema->PsNVariables - 1]; NewVarListItem (pPresVar, wi); pPresVar->PvItem[pPresVar->PvNItems - 1].ViType = VarText; pPresVar->PvItem[pPresVar->PvNItems - 1].ViConstant = Identifier[identnum].SrcIdentDefRule; } if (RuleDef) if (CurRule->PrPresMode == PresFunction && CurRule->PrPresFunction == FnContentRef) /* un nom de constante dans une regle Content d'un element reference ou paire */ { CurRule->PrNPresBoxes = 1; CurRule->PrPresBox[0] = Identifier[identnum].SrcIdentDefRule; } } break; case RULE_AlphabetName: /* AlphabetName */ /* c'est l'alphabet d'une constante, on ne garde que le premier */ /* caractere */ pPSchema->PsConstant[pPSchema->PsNConstants - 1].PdAlphabet = inputLine[wi - 1]; break; case RULE_VarName /* VarName */ : if (VariableDef) /* definition de variable */ if (Identifier[identnum].SrcIdentDefRule != 0) CompilerMessage (wi, PRS, FATAL, CANT_REDECLARE_NAME, inputLine, LineNum); else { NewVar (wi); Identifier[identnum].SrcIdentDefRule = pPSchema->PsNVariables; } else if (Identifier[identnum].SrcIdentDefRule == 0) /* utilisation d'une variable */ /* ce nom n'a pas ete declare comme identificateur de variable */ if (prevRule == RULE_VarConst) /* s'il vient de la regle VarConst, voyons */ /* si ce n'est pas un identificateur de type */ { ProcessTypeName (prevRule, n, wi, wl); Identifier[identnum].SrcIdentCode = RULE_TypeName; /* changement de type, c'est */ /* maintenant un identificateur de type structure' */ } else CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); else { if (PresBoxDef) { pPresBox = &pPSchema->PsPresentBox[CurPresBox - 1]; pPresBox->PbContent = ContVariable; pPresBox->PbContVariable = Identifier[identnum].SrcIdentDefRule; /* cherche tous les compteurs reference's par cette variable */ /* et marque que la boite de presentation courante les utilise */ pPresVar = &pPSchema->PsVariable[Identifier[identnum].SrcIdentDefRule - 1]; for (i = 0; i < pPresVar->PvNItems; i++) { pVarElem = &pPresVar->PvItem[i]; if (pVarElem->ViType == VarCounter) { pCntr = &pPSchema->PsCounter[pVarElem->ViCounter - 1]; if (pCntr->CnNPresBoxes < MAX_PRES_COUNT_USER) { pCntr->CnPresBox[pCntr->CnNPresBoxes] = CurPresBox; if (pPresVar->PvItem[pPresVar->PvNItems - 1].ViCounterVal == CntMinVal || pPresVar->PvItem[pPresVar->PvNItems - 1].ViCounterVal == CntMaxVal) pCntr->CnMinMaxPresBox[pCntr->CnNPresBoxes] = True; pCntr->CnNPresBoxes++; } } else if (pVarElem->ViType == VarPageNumber) PageCounterChangeBox (CurPresBox, pVarElem->ViView); } } else /* on est dans une regle Content d'un element reference ou paire, on */ /* refuse: seules les constantes sont acceptees dans cette regle */ CompilerMessage (wi, PRS, FATAL, FORBIDDEN_IN_A_REF, inputLine, LineNum); } break; case RULE_BoxName: /* BoxName */ if (PresBoxDef && !InRule) /* definition de boite */ { if (pPSchema->PsNPresentBoxes >= MAX_PRES_BOX) CompilerMessage (wi, PRS, FATAL, MAX_BOXES_OVERFLOW, inputLine, LineNum); else if (GetTypeNumber (wl, wi, n) != 0) /* ce nom de boite de presentation est deja un nom de type */ /* d'element, erreur */ CompilerMessage (wi, PRS, FATAL, CANT_USE_TYPE_NAME_FOR_A_BOX, inputLine, LineNum); else if (Identifier[identnum].SrcIdentDefRule == 0) NewBoxName (wl, wi, identnum); else if (pPSchema->PsPresentBox[Identifier[identnum].SrcIdentDefRule - 1].PbName[0] != ' ') CompilerMessage (wi, PRS, FATAL, CANT_REDECLARE_NAME, inputLine, LineNum); /* nom deja rencontre' dans une declaration de vue, de */ /* compteur ou dans une instruction Forward */ else { pPresBox = &pPSchema->PsPresentBox[Identifier[identnum].SrcIdentDefRule - 1]; CopyName (pPresBox->PbName, wi, wl); pPresBox->PbFirstPRule = NextRule; FirstRule = NextRule; CurPresBox = Identifier[identnum].SrcIdentDefRule; } } else /* utilisation d'une boite */ { if (Identifier[identnum].SrcIdentDefRule == 0) /* ce nom n'a pas ete declare comme identificateur de boite */ { i = 1; if (CurRule->PrType == PtFunction && CurRule->PrPresFunction == FnCopy) /* on est dans une regle Copy */ { i = GetTypeNumber (wl, wi, n); if (i == 0) /* ce n'est pas un identificateur de type d'element */ /* defini dans le schema de structure */ { /* il s'agit peut-etre d'un type externe, ou d'une */ /* boite de presentation externe; on garde ce nom */ /* en attendant le nom de la structure externe */ CopyName (CopyType, wi, wl); BeginCopyType = wi; } } if ((prevRule == RULE_BoxType || prevRule == RULE_BoxTypeCopied) && i != 0) /* si on vient de la regle BoxType ou BoxTypeCopied, */ /* voyons si ce n'est pas un identificateur de type */ { ProcessTypeName (prevRule, n, wi, wl); Identifier[identnum].SrcIdentCode = RULE_TypeName; /* changement de type, c'est */ /* maintenant un identificateur de type structure */ } else if (i != 0) CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); } else /* c'est une boite declaree */ if ((CurRule->PrType == PtVertRef || CurRule->PrType == PtHorizRef) && CurRule->PrPosRule.PoRelation != RlEnclosed) CompilerMessage (wi, PRS, FATAL, ONLY_ENCLOSED_AND_ARE_ALLOWED, inputLine, LineNum); else switch (CurRule->PrType) { case PtVertRef: case PtHorizRef: case PtVertPos: case PtHorizPos: CurRule->PrPosRule.PoRefElem = False; CurRule->PrPosRule.PoRefPresBox = Identifier[identnum].SrcIdentDefRule; break; case PtWidth: case PtHeight: if (CurRule->PrDimRule.DrPosition) { CurRule->PrDimRule.DrPosRule.PoRefElem = False; CurRule->PrDimRule.DrPosRule.PoRefPresBox = Identifier[identnum].SrcIdentDefRule; } else { CurRule->PrDimRule.DrRefElement = False; CurRule->PrDimRule.DrRefPresBox = Identifier[identnum].SrcIdentDefRule; } break; case PtFunction: if (CurRule->PrNPresBoxes >= MAX_COLUMN_PAGE) CompilerMessage (wi, PRS, FATAL, MAX_COLUMNS_OVERFLOW, inputLine, LineNum); else if (CurRule->PrPresFunction == FnCopy && pSSchema->SsRule[CurType - 1].SrConstruct == CsReference) /* on est dans une regle FnCopy pour une reference */ if (CurRule->PrNPresBoxes != 0) /* deja une boite dans la regle, on refuse */ CompilerMessage (wi, PRS, FATAL, UNDECLARED_IDENTIFIER, inputLine, LineNum); else { CurRule->PrNPresBoxes = 1; CurRule->PrPresBox[0] = Identifier[identnum].SrcIdentDefRule; } else { CurRule->PrPresBox[CurRule->PrNPresBoxes] = Identifier[identnum].SrcIdentDefRule; CurRule->PrNPresBoxes++; if (CurRule->PrPresFunction == FnCreateFirst || CurRule->PrPresFunction == FnCreateLast || CurRule->PrPresFunction == FnCreateBefore || CurRule->PrPresFunction == FnCreateWith || CurRule->PrPresFunction == FnCreateAfter) { /* on est dans une regle de creation */ /* teste si on a deja cette regle de creation dans */ /* la chaine de regles courante */ pPRule = FirstRule; while (pPRule != NULL && pPRule != CurRule) { if (pPRule->PrViewNum == CurRule->PrViewNum) /* la regle concerne la meme vue */ if (pPRule->PrType == PtFunction) if (pPRule->PrPresFunction == CurRule->PrPresFunction) /* meme operation de creation */ if (pPRule->PrPresBox[0] == CurRule->PrPresBox[0]) /* meme boite creee */ if (SameConditions (pPRule->PrCond, CurRule->PrCond)) CompilerMessage (wi, PRS, FATAL, RULE_ALREADY_DEFINED, inputLine, LineNum); /* regle suivante dans la chaine */ pPRule = pPRule->PrNextPRule; } /* cherche les compteurs qui controlent la */ /* creation de cette boite */ pCond = CurRule->PrCond; while (pCond != NULL) /* teste toutes les conditions de creation */ { if (pCond->CoCondition == PcEven || pCond->CoCondition == PcOdd || pCond->CoCondition == PcOne || pCond->CoCondition == PcInterval) /* c'est une condition sur un compteur, */ /* indique dans le compteur qu'il controle la */ /* creation de ce type de boite, si ce n'est */ /* deja fait. */ { pCntr = &pPSchema->PsCounter[pCond->CoCounter - 1]; new = True; for (j = 0; j < pCntr->CnNCreatedBoxes; j++) if (pCntr->CnCreatedBox[j] == Identifier[identnum].SrcIdentDefRule) new = False; if (new) { /* Si la boite est creee sur une condition de min ou de max, on le note */ if (pCond->CoValCounter == CntMinVal || pCond->CoValCounter == CntMaxVal) pCntr->CnMinMaxCreatedBox[pCntr->CnNCreatedBoxes] = True; else pCntr->CnMinMaxCreatedBox[pCntr->CnNCreatedBoxes] = False; pCntr->CnCreatedBox[pCntr->CnNCreatedBoxes] = Identifier[identnum].SrcIdentDefRule; pCntr->CnNCreatedBoxes++; } } pCond = pCond->CoNextCondition; } } } break; default: break; } /* le cas AttrName a ete deplace' plus haut (cas 19:) */ } break; case RULE_FontStyleName: if (CurRule->PrType == PtFillPattern) { /* cherche le nom dans le tableau des trames Thot */ CopyName (n, wi, wl); i = 0; ok = False; do if (strcmp (n, Name_patterns[i]) == 0) ok = True; else i++; while (!ok && i < sizeof (Name_patterns) / sizeof (char *)); if (!ok) CompilerMessage (wi, PRS, FATAL, MISSING_PATTERN, inputLine, LineNum); else /* on met le rang du pattern dans la regle */ { CurRule->PrAttrValue = False; CurRule->PrIntValue = i; } } else if (CurRule->PrType == PtBackground || CurRule->PrType == PtForeground) { i = 0; CopyName (n, wi, wl); while (i < MAX_COLOR && strcmp (Name_colors[i], n)) i++; if (i == MAX_COLOR) CompilerMessage (wi, PRS, FATAL, MISSING_COLOR, inputLine, LineNum); else { CurRule->PrAttrValue = False; CurRule->PrIntValue = i; } } else /* FontStyleName */ CurRule->PrChrValue = inputLine[wi - 1]; break; case RULE_AttrVal: /* AttrVal */ /* cherche cette valeur parmi celles de l'attribut */ /* precedemment trouve */ CopyName (n, wi, wl); pAttr = &pSSchema->SsAttribute[CurAttrNum - 1]; if (pAttr->AttrType != AtEnumAttr) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* ce n'est pas un attribut a valeur enumerees */ else { i = 1; while (strcmp (n, pAttr->AttrEnumValue[i - 1]) && i < pAttr->AttrNEnumValues) i++; if (strcmp (n, pAttr->AttrEnumValue[i - 1])) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* on ne trouve pas cette valeur, erreur */ else CurAttrVal = i; /* on garde le numero de cette valeur */ } break; case RULE_ExternalAttr: /* un nom d'attribut externe dans une regle Transmit */ if (TransmittedCounter > 0) /* c'est une regle transmit pour un compteur */ { pCntr = &pPSchema->PsCounter[TransmittedCounter - 1]; CopyName (pCntr->CnTransmAttr[pCntr->CnNTransmAttrs - 1], wi, wl); } else if (TransmittedElem > 0) /* c'est une regle transmit pour un contenu d'element */ CopyName (pPSchema->PsTransmElem[pPSchema->PsNTransmElems - 1].TeTargetAttr, wi, wl); break; default: break; } } /*---------------------------------------------------------------------- ProcessInteger traite un nombre. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessInteger (SyntacticCode gCode, indLine wl, indLine wi) #else /* __STDC__ */ static void ProcessInteger (gCode, wl, wi) SyntacticCode gCode; indLine wl; indLine wi; #endif /* __STDC__ */ { int n; Counter *pCntr; n = AsciiToInt (wi, wl); switch (gCode) { /* r= numero de la regle ou apparait le nombre */ case RULE_RelLevel: Conditions->CoRelation = n; if (!SignGreaterOrLess) /* le nombre d'ancetres n'est pas precede' du signe > ou < */ Conditions->CoAncestorRel = CondEquals; break; case RULE_CountValue: /* CountValue */ pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiParamValue = n; break; case RULE_AncestorLevel: /* AncestorLevel */ pCntr = &pPSchema->PsCounter[pPSchema->PsNCounters - 1]; pCntr->CnItem[pCntr->CnNItems - 1].CiAscendLevel = n * AncestorSign; break; case RULE_DimRatio: /* DimRatio */ CurUnit = Percent; LatestNumber = n * 1000; LatestNumberAttr = False; PrevSign = 1; /* signe positif */ CurRule->PrDimRule.DrUnit = UnPercent; break; case RULE_IntPart: /* IntPart */ LatestNumber = n * 1000; /* LatestNumber est exprime' en 1/1000 */ LatestNumberAttr = False; break; case RULE_DecimPart: /* DecimPart */ /* on convertit la partie apres la virgule en milliemes */ switch (wl) /* selon le nombre de chiffres apres la virgule */ { case 1: n = n * 100; break; case 2: n = n * 10; break; case 3: n = n * 1; break; case 4: n = n / 10; break; default: /* trop de decimales */ CompilerMessage (wi, PRS, FATAL, MAX_AFTER_DIGITS_OVERFLOW, inputLine, LineNum); break; } /* on ajoute cette partie a la partie entiere deja convertie en milliemes */ LatestNumber += n; break; case RULE_PosInteger: /* PosInteger */ CurRule->PrInhDelta = n; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = False; break; case RULE_NegInteger: /* NegInteger */ CurRule->PrInhDelta = -n; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = False; break; case RULE_maximum: /* maximum */ CurRule->PrInhMinOrMax = n; CurRule->PrMinMaxAttr = False; break; case RULE_minimum: /* minimum */ CurRule->PrInhMinOrMax = n; CurRule->PrMinMaxAttr = False; break; case RULE_Integer: /* Integer */ CurRule->PrIntValue = n; CurRule->PrAttrValue = False; break; case RULE_Size: /* Size */ CurRule->PrMinValue = n; CurRule->PrMinAttr = False; CurRule->PrMinUnit = UnRelative; break; case RULE_PosSize: /* PosSize */ CurRule->PrInhDelta = n; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = False; break; case RULE_NegSize: /* NegSize */ CurRule->PrInhDelta = -n; CurRule->PrInhUnit = UnRelative; CurRule->PrInhAttr = False; break; case RULE_MaxSize: /* MaxSize */ CurRule->PrInhMinOrMax = n; CurRule->PrMinMaxAttr = False; break; case RULE_MinSize: /* MinSize */ CurRule->PrInhMinOrMax = n; CurRule->PrMinMaxAttr = False; break; case RULE_MinVal: /* MinVal */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtNumAttr || n >= MAX_INT_ATTR_VAL) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* ce n'est pas un attribut a valeur numerique */ else { CurAttrLowerBound = n * AttrValSign + 1; AttrValSign = 1; } break; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ case RULE_MaxVal: /* MaxVal */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtNumAttr || n >= MAX_INT_ATTR_VAL) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* ce n'est pas un attribut a valeur numerique */ else { CurAttrUpperBound = n * AttrValSign - 1; AttrValSign = 1; } break; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ case RULE_MinInterval: /* MinInterval */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtNumAttr || n >= MAX_INT_ATTR_VAL) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* ce n'est pas un attribut a valeur numerique */ else { CurAttrLowerBound = n * AttrValSign; AttrValSign = 1; } break; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ case RULE_MaxInterval: /* MaxInterval */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtNumAttr || n >= MAX_INT_ATTR_VAL) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* ce n'est pas un attribut a valeur numerique */ else { if (CurAttrLowerBound > n * AttrValSign) CompilerMessage (wi, PRS, FATAL, INVALID_LOWER_BOUND, inputLine, LineNum); else CurAttrUpperBound = n * AttrValSign; AttrValSign = 1; } break; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ case RULE_ValEqual: /* ValEqual */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtNumAttr || n >= MAX_INT_ATTR_VAL) CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); /* ce n'est pas un attribut a valeur numerique */ else { CurAttrUpperBound = CurAttrLowerBound = n * AttrValSign; AttrValSign = 1; } break; /* a priori, la prochaine valeur */ /* d'attribut numerique sera positive */ case RULE_MinCounterVal: if (n >= MAX_COUNTER_VAL) CompilerMessage (wi, PRS, FATAL, BAD_COUNTER_VALUE, inputLine, LineNum); else { Conditions->CoMinCounter = n * CurCondCntSign + 1; /* a priori, la prochaine borne sera positive */ CurCondCntSign = 1; } break; case RULE_MaxCounterVal: if (n >= MAX_COUNTER_VAL) CompilerMessage (wi, PRS, FATAL, BAD_COUNTER_VALUE, inputLine, LineNum); else { Conditions->CoMaxCounter = n * CurCondCntSign - 1; /* a priori, la prochaine borne sera positive */ CurCondCntSign = 1; } break; case RULE_MinCounterInter: if (n >= MAX_COUNTER_VAL) CompilerMessage (wi, PRS, FATAL, BAD_COUNTER_VALUE, inputLine, LineNum); else { Conditions->CoMinCounter = n * CurCondCntSign; /* a priori, la prochaine borne sera positive */ CurCondCntSign = 1; } break; case RULE_MaxCounterInter: if (n >= MAX_COUNTER_VAL) CompilerMessage (wi, PRS, FATAL, BAD_COUNTER_VALUE, inputLine, LineNum); else if (Conditions->CoMinCounter > n * CurCondCntSign) CompilerMessage (wi, PRS, FATAL, INVALID_LOWER_BOUND, inputLine, LineNum); else { Conditions->CoMaxCounter = n * CurCondCntSign; /* a priori, la prochaine borne sera positive */ CurCondCntSign = 1; } break; case RULE_CounterValEqual: if (n >= MAX_COUNTER_VAL) CompilerMessage (wi, PRS, FATAL, BAD_COUNTER_VALUE, inputLine, LineNum); else { Conditions->CoMaxCounter = Conditions->CoMinCounter = n * CurCondCntSign; /* a priori, la prochaine borne sera positive */ CurCondCntSign = 1; } break; case RULE_ImageType: /* c'est le type d'une image */ pPSchema->PsConstant[pPSchema->PsNConstants - 1].PdAlphabet = n; break; default: break; } } /*---------------------------------------------------------------------- ProcessString traitee une chaine de caracteres. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessString (SyntacticCode gCode, indLine wl, indLine wi) #else /* __STDC__ */ static void ProcessString (gCode, wl, wi) SyntacticCode gCode; indLine wl; indLine wi; #endif /* __STDC__ */ { int i; PresConstant *pPresConst; if (gCode == RULE_ConstValue || gCode == RULE_FileName) /* c'est une valeur de constante ou le nom de fichier d'une image de fond */ if (wl > MAX_PRES_CONST_LEN) CompilerMessage (wi, PRS, FATAL, MAX_CHAR_STRING_SIZE_OVERFLOW, inputLine, LineNum); else { pPresConst = &pPSchema->PsConstant[pPSchema->PsNConstants - 1]; for (i = 0; i < wl - 1; i++) pPresConst->PdString[i] = inputLine[wi + i - 1]; pPresConst->PdString[wl - 1] = '\0'; } else if (gCode == RULE_TextEqual) /* TextEqual c'est une valeur d'attribut */ if (pSSchema->SsAttribute[CurAttrNum - 1].AttrType != AtTextAttr) /* ce n'est pas un attribut a valeur textuelle */ CompilerMessage (wi, PRS, FATAL, INVALID_ATTR_VALUE, inputLine, LineNum); else if (wl > MAX_NAME_LENGTH) CompilerMessage (wi, PRS, FATAL, MAX_CHAR_STRING_SIZE_OVERFLOW, inputLine, LineNum); else { for (i = 0; i < wl - 1; i++) CurTextEqual[i] = inputLine[wi + i - 1]; CurTextEqual[wl - 1] = '\0'; } } /*---------------------------------------------------------------------- ProcessToken traite le token commencant a la position wi dans la ligne courante, de longueur wl et de code grammatical c. Si c'est un identificateur, nb contient son rang dans la table des identificateurs. r est le numero de la regle dans laquelle apparait ce mot, pr est le numero de la regle precedente, celle qui a appele la regle r. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void ProcessToken (indLine wi, indLine wl, SyntacticCode c, SyntacticCode r, int identnum, SyntacticCode pr) #else /* __STDC__ */ static void ProcessToken (wi, wl, c, r, identnum, pr) indLine wi; indLine wl; SyntacticCode c; SyntacticCode r; int identnum; SyntacticCode pr; #endif /* __STDC__ */ { if (c < 1000) /* symbole intermediaire de la grammaire, erreur */ CompilerMessage (wi, PRS, FATAL, INTERMEDIATE_SYMBOL, inputLine, LineNum); else if (c < 1100) /* mot-cle court */ ProcessShortKeyWord (c, wi, r); else if (c < 2000) /* mot-cle long */ ProcessLongKeyWord (c, r, wi); else /* type de base */ switch (c) { case 3001: /* un nom */ ProcessName (r, identnum, pr, wl, wi); break; case 3002: /* un nombre */ ProcessInteger (r, wl, wi); break; case 3003: /* une chaine de caracteres */ ProcessString (r, wl, wi); break; } } /*---------------------------------------------------------------------- RuleBefore ----------------------------------------------------------------------*/ #ifdef __STDC__ static boolean RuleBefore (PtrPRule pPRule1, PtrPRule pPRule2) #else /* __STDC__ */ static boolean RuleBefore (pPRule1, pPRule2) PtrPRule pPRule1; PtrPRule pPRule2; #endif /* __STDC__ */ { boolean ret; /* on classe d'abord dans l'ordre des types de regle */ if (pPRule1->PrType != pPRule2->PrType) ret = pPRule1->PrType < pPRule2->PrType; else /* meme type */ if (pPRule1->PrType == PtFunction) { /* c'est une fonction de presentation, on classe */ /* d'abord dans l'ordre des codes de fonction. */ if (pPRule1->PrPresFunction != pPRule2->PrPresFunction) { #ifdef __COLPAGE__ if (((pPRule1->PrPresFunction == FnPage) || (pPRule1->PrPresFunction == FnColumn) || (pPRule1->PrPresFunction == FnSubColumn)) && ((pPRule2->PrPresFunction == FnPage) || (pPRule2->PrPresFunction == FnColumn) || (pPRule2->PrPresFunction == FnSubColumn))) /* fonctions equivalentes (Page, Column, Included Column), on */ /* classe dans l'ordre des vues */ ret = pPRule1->PrViewNum < pPRule2->PrViewNum; else #endif /* __COLPAGE__ */ ret = pPRule1->PrPresFunction < pPRule2->PrPresFunction; } else { /* meme fonction, on classe dans l'ordre des vues */ ret = pPRule1->PrViewNum < pPRule2->PrViewNum; } } else { /* ce n'est pas une fonction de presentation, on classe */ /* dans l'ordre des vues */ ret = pPRule1->PrViewNum < pPRule2->PrViewNum; } return ret; } /*---------------------------------------------------------------------- SortPresRules ----------------------------------------------------------------------*/ #ifdef __STDC__ static void SortPresRules (PtrPRule * firstPRule) #else /* __STDC__ */ static void SortPresRules (firstPRule) PtrPRule *firstPRule; #endif /* __STDC__ */ { PtrPRule oldPRule, curOldPRule, newPRule, curNewPRule, newAnchor; boolean done, stop; if (*firstPRule != NULL) { oldPRule = *firstPRule; newAnchor = NULL; /* parcourt l'ancienne chaine des regles pointee par firstPRule */ while (oldPRule != NULL) { curOldPRule = oldPRule; /* regle courante de l'ancienne chaine */ oldPRule = oldPRule->PrNextPRule; if (newAnchor == NULL) { newAnchor = curOldPRule; curOldPRule->PrNextPRule = NULL; } else { newPRule = NULL; curNewPRule = newAnchor; done = False; stop = False; /* parcourt la nouvelle chaine */ while (!stop) if (RuleBefore (curOldPRule, curNewPRule)) { if (newPRule == NULL) /* insere curOldPRule en tete */ { curOldPRule->PrNextPRule = newAnchor; newAnchor = curOldPRule; } else /* insere curOldPRule apres newPRule */ { curOldPRule->PrNextPRule = newPRule->PrNextPRule; newPRule->PrNextPRule = curOldPRule; } done = True; stop = True; } else { newPRule = curNewPRule; curNewPRule = curNewPRule->PrNextPRule; if (curNewPRule == NULL) stop = True; } if (!done) /* ajoute curOldPRule a la fin de la nouvelle chaine, apres newPRule */ { if (newPRule != NULL) newPRule->PrNextPRule = curOldPRule; else newAnchor = oldPRule; curOldPRule->PrNextPRule = NULL; } } } *firstPRule = newAnchor; } } /*---------------------------------------------------------------------- SortAllPRules met les regles de presentation dans le bon ordre pour l'application des regles lors de la production des images abstraites. ----------------------------------------------------------------------*/ #ifdef __STDC__ void SortAllPRules () #else /* __STDC__ */ void SortAllPRules () #endif /* __STDC__ */ { int j, l; int k; AttributePres *pPRuleA; /* ordonne les regles par defaut */ SortPresRules (&pPSchema->PsFirstDefaultPRule); /* ordonne les regles des boites de presentation */ for (j = 0; j < pPSchema->PsNPresentBoxes; j++) SortPresRules (&pPSchema->PsPresentBox[j].PbFirstPRule); /* ordonne les regles des valeurs d'attribut */ for (j = 0; j < pSSchema->SsNAttributes; j++) { /* pour chaque paquet de regles */ pPRuleA = pPSchema->PsAttrPRule[j]; for (l = pPSchema->PsNAttrPRule[j]; l-- > 0; pPRuleA = pPRuleA->ApNextAttrPres) { /* selon le type de l'attribut */ switch (pSSchema->SsAttribute[j].AttrType) { case AtNumAttr: for (k = 0; k < pPRuleA->ApNCases; k++) SortPresRules (&pPRuleA->ApCase[k].CaFirstPRule); break; case AtTextAttr: SortPresRules (&pPRuleA->ApTextFirstPRule); break; case AtReferenceAttr: SortPresRules (&pPRuleA->ApRefFirstPRule); break; case AtEnumAttr: for (k = 0; k <= pSSchema->SsAttribute[j].AttrNEnumValues; k++) SortPresRules (&pPRuleA->ApEnumFirstPRule[k]); break; default: break; } } } /* ordonne les regles des elements structures */ for (j = 0; j < MAX_RULES_SSCHEMA; j++) SortPresRules (&pPSchema->PsElemPRule[j]); } /*---------------------------------------------------------------------- PageCounter determine si le compteur de numero counter est un compteur de page. Retourne Vrai si c'est un compteur de pages, Faux sinon. ----------------------------------------------------------------------*/ #ifdef __STDC__ static boolean PageCounter (int counter) #else /* __STDC__ */ static boolean PageCounter (counter) int counter; #endif /* __STDC__ */ { Counter *pCntr; boolean ret; pCntr = &pPSchema->PsCounter[counter - 1]; ret = ((pCntr->CnItem[0].CiCntrOp == CntrRank && pCntr->CnItem[0].CiElemType == PageBreak + 1) || (pCntr->CnItem[0].CiCntrOp == CntrSet && pCntr->CnItem[1].CiElemType == PageBreak + 1)); return ret; } /*---------------------------------------------------------------------- SearchPRule cherche pour la vue view une regle de type ruleType dans la chaine de regles dont l'ancre est firstRule. Retourne un pointeur sur cette regle si elle existe ou insere une regle de ce type dans la chaine et retourne un pointeur sur la regle creee. ----------------------------------------------------------------------*/ #ifdef __STDC__ static PtrPRule SearchPRule (PtrPRule * firstRule, PRuleType ruleType, int view) #else /* __STDC__ */ static PtrPRule SearchPRule (firstRule, ruleType, view) PtrPRule *firstRule; PRuleType ruleType; int view; #endif /* __STDC__ */ { PtrPRule pR, pPRule; boolean stop, cree; pR = *firstRule; pPRule = NULL; stop = False; do { if (pR == NULL) stop = True; else if (pR->PrType >= ruleType) stop = True; if (!stop) { pPRule = pR; pR = pR->PrNextPRule; } } while (!stop); stop = False; do { if (pR == NULL) stop = True; else if (pR->PrType != ruleType || pR->PrViewNum >= view) stop = True; if (!stop) { pPRule = pR; pR = pR->PrNextPRule; } } while (!stop); if (pR == NULL) cree = True; else if (pR->PrType > ruleType || pR->PrViewNum > view) cree = True; else cree = False; if (cree) /* il n'y a pas de regle de ce type, on en cree une */ { GetPresentRule (&pR); if (pR == NULL) TtaDisplaySimpleMessage (FATAL, PRS, NO_MORE_MEM_LEFT); pR->PrType = ruleType; /* on insere la regle cree */ if (pPRule == NULL) { pR->PrNextPRule = *firstRule; *firstRule = pR; } else { pR->PrNextPRule = pPRule->PrNextPRule; pPRule->PrNextPRule = pR; } pR->PrCond = NULL; pR->PrViewNum = view; pR->PrSpecifAttr = 0; pR->PrSpecifAttrSSchema = NULL; } return pR; } /*---------------------------------------------------------------------- CheckPageBoxes verifie que toutes les boites de presentation declarees pour les pages sont bien utilisees et adapte les regles des boites pages. ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CheckPageBoxes () #else /* __STDC__ */ static void CheckPageBoxes () #endif /* __STDC__ */ { PtrPRule pR, pHeadR, pPRule, pRule; int b, hfB, el, view, footHeight, headHeight, h, i, counter; boolean stop, stop1, exist; PresentationBox *pPresBox; PresVariable *pPresVar; PtrCondition pCond; int viewOfBox[MAX_PRES_BOX]; #ifdef __COLPAGE__ int bc; PtrPRule pRC; #else /* __COLPAGE__ */ PtrPRule pRLarg; #endif /* __COLPAGE__ */ /* a priori les boites de presentation ne sont pas des boites pages */ for (b = 0; b < pPSchema->PsNPresentBoxes; b++) { viewOfBox[b] = 0; pPresBox = &pPSchema->PsPresentBox[b]; pPresBox->PbPageBox = False; pPresBox->PbPageFooter = False; pPresBox->PbPageHeader = False; } /* a priori les compteurs ne sont pas utilise's en bas de page */ for (b = 0; b < pPSchema->PsNCounters; b++) pPSchema->PsCounter[b].CnPageFooter = False; /* recherche toutes les regles PAGE dans le schema de presentation */ /* et marque les boites pages utilisees par ces regles. */ for (el = 0; el < pSSchema->SsNRules; el++) /* cherche dans les regles de */ /* presentation de chaque type d'element */ { pR = pPSchema->PsElemPRule[el]; /* 1ere regle de pres. du type */ stop = False; do { if (pR == NULL) stop = True; else if (pR->PrType > PtFunction) stop = True; if (!stop) { if (pR->PrType == PtFunction && pR->PrPresFunction == FnPage) /* c'est une regle Page */ /* marque la boite page */ { b = pR->PrPresBox[0]; /* b: numero de la boite page */ /* note la vue concernee par cette boite page, si */ /* elle n'est pas deja notee */ if (viewOfBox[b - 1] == 0) viewOfBox[b - 1] = pR->PrViewNum; pPSchema->PsPresentBox[b - 1].PbPageBox = True; pPSchema->PsPresentBox[b - 1].PbPageCounter = 0; /* verifie que la boite page a une largeur et une hauteur */ /* absolues */ /* cherche la regle de hauteur d'abord */ pRule = pPSchema->PsPresentBox[b - 1].PbFirstPRule; stop1 = False; exist = False; do { if (pRule == NULL) stop1 = True; else if (pRule->PrType > PtHeight) stop1 = True; else if (pRule->PrType == PtHeight) { stop1 = True; exist = True; } if (!stop1) pRule = pRule->PrNextPRule; } while (!stop1); if (!exist) /* il n'y a pas de regle de hauteur, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[b - 1].PbName); else if (!pRule->PrDimRule.DrAbsolute || pRule->PrDimRule.DrUnit == UnRelative || pRule->PrDimRule.DrPosition) /* ce n'est pas une hauteur absolue fixe, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[b - 1].PbName); /* cherche la regle de largeur */ pRule = pPSchema->PsPresentBox[b - 1].PbFirstPRule; stop1 = False; exist = False; do { if (pRule == NULL) stop1 = True; else if (pRule->PrType > PtWidth) stop1 = True; else if (pRule->PrType == PtWidth) { stop1 = True; exist = True; } if (!stop1) pRule = pRule->PrNextPRule; } while (!stop1); if (!exist) /* il n'y a pas de regle de largeur, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_WIDTH_RULE), pPSchema->PsPresentBox[b - 1].PbName); else if (!pRule->PrDimRule.DrAbsolute || pRule->PrDimRule.DrUnit == UnRelative || pRule->PrDimRule.DrPosition) /* ce n'est pas une largeur absolue fixe, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_WIDTH_RULE), pPSchema->PsPresentBox[b - 1].PbName); /* cherche la regle de largeur de la boite qui porte la */ /* regle Page, ou cree une regle s'il n'y a pas de regle de */ /* largeur */ #ifndef __COLPAGE__ /* supprime pour les colonnes */ pRLarg = SearchPRule (&pPSchema->PsElemPRule[el], PtWidth, pR->PrViewNum); /* modifie la regle de largeur: meme regle que la boite page */ pRLarg->PrPresMode = PresImmediate; pRLarg->PrDimRule = pRule->PrDimRule; #endif /* __COLPAGE__ */ /* cherche la regle de position verticale */ /* de la boite page */ pRule = pPSchema->PsPresentBox[b - 1].PbFirstPRule; stop1 = False; exist = False; do { if (pRule == NULL) stop1 = True; else if (pRule->PrType > PtVertPos) stop1 = True; else if (pRule->PrType == PtVertPos) { stop1 = True; exist = True; } if (!stop1) pRule = pRule->PrNextPRule; } while (!stop1); if (!exist) /* il n'y a pas de regle de position verticale, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_VERTPOS_RULE), pPSchema->PsPresentBox[b - 1].PbName); else { #ifdef __COLPAGE__ if (pRule->PrPosRule.PoPosDef != Top /* position du cote superieur */ || pRule->PrPosRule.PoPosRef != Bottom /* par rapport au cote inf. */ || pRule->PrPosRule.PoRelation != RlPrevious /* du precedent */ || (pRule->PrPosRule.PoDistUnit == UnRelative && pRule->PrPosRule.PoDistance != 0)) #else /* __COLPAGE__ */ if (pRule->PrPosRule.PoPosDef != Top /* position du cote superieur */ || pRule->PrPosRule.PoPosRef != Top /* par rapport au cote sup. */ || pRule->PrPosRule.PoRelation != RlEnclosing /* de l'englobant */ || (pRule->PrPosRule.PoDistUnit == UnRelative && pRule->PrPosRule.PoDistance != 0)) #endif /* __COLPAGE__ */ /* et distance absolue */ /* ce n'est pas un positionnement correct, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_VERTPOS_RULE), pPSchema->PsPresentBox[b - 1].PbName); } /* cherche la regle de position horizontale */ pRule = pPSchema->PsPresentBox[b - 1].PbFirstPRule; stop1 = False; exist = False; do { if (pRule == NULL) stop1 = True; else if (pRule->PrType > PtHorizPos) stop1 = True; else if (pRule->PrType == PtHorizPos) { stop1 = True; exist = True; } if (!stop1) pRule = pRule->PrNextPRule; } while (!stop1); if (!exist) /* il n'y a pas de regle de position horiz., erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HORIZPOS_RULE), pPSchema->PsPresentBox[b - 1].PbName); else { if (pRule->PrPosRule.PoPosDef != Left /* position du cote gauche */ || pRule->PrPosRule.PoPosRef != Left /* par rapport au cote gauche */ || pRule->PrPosRule.PoRelation != RlEnclosing /* de l'englobant */ || (pRule->PrPosRule.PoDistUnit == UnRelative && pRule->PrPosRule.PoDistance != 0)) /* et distance absolue */ /* ce n'est pas un positionnement correct, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HORIZPOS_RULE), pPSchema->PsPresentBox[b - 1].PbName); } } pR = pR->PrNextPRule; /* passe a la regle suivante */ } } while (!stop); } /* Toutes les boites pages sont maintenant marquees */ /* Cherche les boites creees par les boites pages (ce sont les */ /* boites de haut et de bas de page) et marque ces boites. Calcule la */ /* hauteur minimum des bas de page. */ for (b = 0; b < pPSchema->PsNPresentBoxes; b++) /* examine chaque boite */ if (pPSchema->PsPresentBox[b].PbPageBox) /* c'est une boite page */ { footHeight = 0; headHeight = 0; /* cherche les regles de creation de la boite page */ pR = pPSchema->PsPresentBox[b].PbFirstPRule; /* 1ere regle de presentation */ /* parcourt les premieres regles de la boite page */ stop = False; do { if (pR == NULL) stop = True; else if (pR->PrType > PtFunction) stop = True; if (!stop) { if (pR->PrType == PtFunction && (pR->PrPresFunction == FnCreateBefore || pR->PrPresFunction == FnCreateWith || pR->PrPresFunction == FnCreateFirst || pR->PrPresFunction == FnCreateLast || pR->PrPresFunction == FnCreateAfter)) /* c'est une regle de creation */ if (!(pR->PrPresFunction == FnCreateBefore || pR->PrPresFunction == FnCreateAfter)) /* ce n'est pas une regle de creation autorisee, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, FORBIDDEN_CREA_RULE), pPSchema->PsPresentBox[b].PbName); else /* la regle pR est une regle CreateAfter ou */ /* a CreateBefore */ { hfB = pR->PrPresBox[0] - 1; /* numero de la boite de haut ou de bas de page */ /* la boite de haut ou de bas de page appartient */ /* la meme vue que la boite page qui la cree */ viewOfBox[hfB] = viewOfBox[b]; #ifdef __COLPAGE__ /* type de boite : haut (CreateBefore) ou bas */ /*(CreateAfter) */ if (pR->PrPresFunction == FnCreateBefore) pPSchema->PsPresentBox[hfB].PbPageHeader = True; else pPSchema->PsPresentBox[hfB].PbPageFooter = True; #endif /* __COLPAGE__ */ /* cherche la regle de positionnement vertical de */ /* la boite creee par la boite page */ pPRule = pPSchema->PsPresentBox[hfB].PbFirstPRule; stop1 = False; exist = False; do { if (pPRule == NULL) stop1 = True; else if (pPRule->PrType > PtVertPos) stop1 = True; else if (pPRule->PrType == PtVertPos) { stop1 = True; exist = True; } if (!stop1) pPRule = pPRule->PrNextPRule; } while (!stop1); if (!exist) /* pas de regle de positionnement vertical, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, MISSING_VERTIC_POS_IN_THE_PAGE), pPSchema->PsPresentBox[hfB].PbName); else { #ifdef __COLPAGE__ if (!(pPRule->PrPosRule.PoPosDef == Top || pPRule->PrPosRule.PoPosDef == Bottom || pPRule->PrPosRule.PoPosDef == HorizMiddle)) /* on ne teste plus PoPosDef,PoNotRel et PoRefElem */ /* suppression test elt ref. != marque de page */ #else /* __COLPAGE__ */ if (!(pPRule->PrPosRule.PoPosDef == Top || pPRule->PrPosRule.PoPosDef == Bottom || pPRule->PrPosRule.PoPosDef == HorizMiddle) || pPRule->PrPosRule.PoNotRel || !pPRule->PrPosRule.PoRefElem || pPRule->PrPosRule.PoTypeRefElem != PageBreak + 1) #endif /* __COLPAGE__ */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, INVALID_VERTIC_POS_IN_PAGE), pPSchema->PsPresentBox[hfB].PbName); if (pPRule->PrPosRule.PoDistance != 0) if (pPRule->PrPosRule.PoDistUnit == UnRelative) TtaDisplayMessage (FATAL, TtaGetMessage (PRS, VERTIC_DIST_ISNT_CONSTANT), pPSchema->PsPresentBox[hfB].PbName); #ifdef __COLPAGE__ if (pPRule->PrPosRule.PoRelation != RlPrevious) TtaDisplayMessage (FATAL, TtaGetMessage (PRS, INVALID_VERTIC_POS_IN_PAGE), pPSchema->PsPresentBox[hfB].PbName); else /* la boite creee est positionnee par rapport */ /* a la boite precedente : seul cas autorise */ { #else /* __COLPAGE__ */ if (pPRule->PrPosRule.PoRelation == RlPrevious) /* la boite creee est positionnee par rapport */ /* au haut de la page */ { pPSchema->PsPresentBox[hfB].PbPageHeader = True; /* cherche la regle de hauteur de la boite de */ /* haut de page */ pHeadR = pPSchema->PsPresentBox[hfB].PbFirstPRule; stop1 = False; exist = False; do { if (pHeadR == NULL) stop1 = True; else if (pHeadR->PrType > PtHeight) stop1 = True; else if (pHeadR->PrType == PtHeight) { stop1 = True; exist = True; } if (!stop1) pHeadR = pHeadR->PrNextPRule; } while (!stop1); /* si pas de regle de hauteur, pas d'erreur */ if (exist) if (pHeadR->PrDimRule.DrPosition) /* c'est une hauteur elastique, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); else if (!pHeadR->PrDimRule.DrAbsolute) /* c'est une hauteur relative, on n'accepte */ /* que la hauteur du contenu */ { if (pHeadR->PrDimRule.DrRelation != RlEnclosed) TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); } else /* regle de hauteur absolue */ if (pHeadR->PrDimRule.DrUnit == UnRelative) /* la hauteur n'est pas en unites fixes */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); else /* calcule la distance entre le bas de la */ /* boite de haut de page et le haut de la page */ /* calcule la distance entre le bas de la */ /* boite de precedente et le bas de la */ /* boite creee (haut ou bas) */ /* ce code n'a plus vraiment de sens car */ /* le plus souvent, la hauteur des hauts et */ /* et bas de page est donnee par leur contenu */ /* (plusieurs boites filles) */ /* donc, c'est le mediateur qui peut calculer */ /* ces valeurs (cf. code de page.c) */ { switch (pPRule->PrPosRule.PoPosDef) { case Bottom: h = pPRule->PrPosRule.PoDistance; break; case Top: h = pPRule->PrPosRule.PoDistance + pHeadR->PrDimRule.DrValue; break; case HorizMiddle: h = pPRule->PrPosRule.PoDistance + pHeadR->PrDimRule.DrValue / 2; break; default: h = 0; break; } if (h > headHeight) headHeight = h; } } /* fin boite haut de page */ else if (pPRule->PrPosRule.PoRelation == RlNext) /* la boite creee est positionnee par rapport */ /* au bas de la page, c'est une boite de bas de page */ { pPSchema->PsPresentBox[hfB].PbPageFooter = True; #endif /* __COLPAGE__ */ /* cherche la regle de hauteur de la boite de */ /* bas de page */ pHeadR = pPSchema->PsPresentBox[hfB].PbFirstPRule; stop1 = False; exist = False; do { if (pHeadR == NULL) stop1 = True; else if (pHeadR->PrType > PtHeight) stop1 = True; else if (pHeadR->PrType == PtHeight) { stop1 = True; exist = True; } if (!stop1) pHeadR = pHeadR->PrNextPRule; } while (!stop1); #ifdef __COLPAGE__ /* si pas de regle de hauteur, pas d'erreur */ if (exist) #else /* __COLPAGE__ */ if (!exist) /* il n'y a pas de regle de hauteur, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); else #endif /* __COLPAGE__ */ if (pHeadR->PrDimRule.DrPosition) /* c'est une hauteur elastique, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); else if (!pHeadR->PrDimRule.DrAbsolute) /* c'est une hauteur relative, on n'accepte */ /* que la hauteur du contenu */ { if (pHeadR->PrDimRule.DrRelation != RlEnclosed) TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); } else /* regle de hauteur absolue */ if (pHeadR->PrDimRule.DrUnit == UnRelative) /* la hauteur n'est pas en unites fixes */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_HEIGHT_RULE), pPSchema->PsPresentBox[hfB].PbName); else /* calcule la distance entre le haut de la */ /* boite de bas de page et le bas de la page */ /* calcule la distance entre le bas de la */ /* boite de precedente et le bas de la */ /* boite creee (haut ou bas) */ /* ce code n'a plus vraiment de sens car */ /* le plus souvent, la hauteur des hauts et */ /* et bas de page est donnee par leur contenu */ /* (plusieurs boites filles) */ /* donc, c'est le mediateur qui peut calculer */ /* ces valeurs (cf. code de page.c) */ { switch (pPRule->PrPosRule.PoPosDef) { case Top: h = pPRule->PrPosRule.PoDistance; break; case Bottom: h = pPRule->PrPosRule.PoDistance + pHeadR->PrDimRule.DrValue; break; case HorizMiddle: h = pPRule->PrPosRule.PoDistance + pHeadR->PrDimRule.DrValue / 2; break; default: h = 0; break; } if (h > footHeight) footHeight = h; } } #ifndef __COLPAGE__ else /* la boite creee n'est pas positionnee par */ /* rapport a la page, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, INVALID_VERTIC_POS_IN_PAGE), pPSchema->PsPresentBox[hfB].PbName); #endif /* __COLPAGE__ */ /* examine les conditions de creation de la boite de */ /* haut ou de bas de page, a la recherche d'un */ /* compteur de page qui determine la creation de la */ /* boite de haut ou de bas de page. */ pCond = pR->PrCond; while (pCond != NULL) { if (pCond->CoCondition == PcInterval || pCond->CoCondition == PcEven || pCond->CoCondition == PcOdd || pCond->CoCondition == PcOne) { counter = pCond->CoCounter; if (PageCounter (counter)) /* c'est un compteur de pages */ if (pPSchema->PsPresentBox[b].PbPageCounter > 0) /* il y a deja un compteur de page */ { if (pPSchema->PsPresentBox[b].PbPageCounter != counter) /* ce n'est pas le meme compteur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, USES_DIFFERENT_PAGE_COUNTERS), pPSchema->PsPresentBox[b].PbName); } else /* on a trouve' le compteur de pages associe' */ /* a ce type de page */ pPSchema->PsPresentBox[b].PbPageCounter = counter; } pCond = pCond->CoNextCondition; } /* la boite de haut ou de bas de page contient-elle */ /* le numero de page ? */ if (pPSchema->PsPresentBox[hfB].PbContent == ContVariable) /* la boite contient une variable */ { pPresVar = &pPSchema->PsVariable[pPSchema->PsPresentBox[hfB].PbContVariable - 1]; for (i = 0; i < pPresVar->PvNItems; i++) if (pPresVar->PvItem[i].ViType == VarCounter) /* la variable contient une valeur de */ /* compteur, on examine ce compteur */ { counter = pPresVar->PvItem[i].ViCounter; if (PageCounter (counter)) /* c'est un compteur de pages */ { if (pPSchema->PsPresentBox[b].PbPageCounter > 0) /* il y a deja un compteur de page */ { if (pPSchema->PsPresentBox[b].PbPageCounter != counter) /* ce n'est pas le meme compteur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, TWO_DIFFERENT_PAGE_NUMBERS), pPSchema->PsPresentBox[hfB].PbName); } else /* on trouve' le compteur de pages */ pPSchema->PsPresentBox[b].PbPageCounter = counter; pPSchema->PsCounter[counter - 1].CnPageFooter = pPSchema->PsPresentBox[hfB].PbPageFooter; } } } #ifdef __COLPAGE__ /* le numero de page peut etre fils de la boite */ /* haut ou bas de page, il faut donc chercher */ /* a un niveau plus bas (boites creees par hfB */ else { pRC = pPSchema->PsPresentBox[hfB].PbFirstPRule; /* 1ere regle de presentation */ /* parcourt les premieres regles de la boite hfB */ stop1 = False; do { if (pRC == NULL) stop1 = True; else if (pRC->PrType > PtFunction) stop1 = True; if (!stop1) { if (pRC->PrType == PtFunction && (pRC->PrPresFunction == FnCreateBefore || pRC->PrPresFunction == FnCreateFirst || pRC->PrPresFunction == FnCreateLast || pRC->PrPresFunction == FnCreateAfter)) /* c'est une regle de creation */ if (pRC->PrPresFunction == FnCreateBefore || pRC->PrPresFunction == FnCreateAfter) /* ce n'est pas une regle de creation autorisee, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, FORBIDDEN_CREA_RULE), pPSchema->PsPresentBox[hfB].PbName); else /* la regle pRC est une regle CreatePremFils ou */ /* CreateDerFils */ { bc = pRC->PrPresBox[0]; /* numero de la boite fille. Contient-elle un compteur ? */ /* cette boite appartient a la meme vue que la boite */ /* qui la cree */ viewOfBox[bc - 1] = viewOfBox[hfB]; /* contient-elle le numero de page ? */ if (pPSchema->PsPresentBox[bc - 1].PbContent == ContVariable) /* la boite contient une variable */ { pPresVar = &pPSchema->PsVariable[pPSchema->PsPresentBox[bc - 1].PbContVariable - 1]; for (i = 0; i < pPresVar->PvNItems; i++) if (pPresVar->PvItem[i].ViType == VarCounter) /* la variable contient une valeur de */ /* compteur, on examine ce compteur */ { counter = pPresVar->PvItem[i].ViCounter; if (PageCounter (counter)) /* c'est un compteur de pages */ { if (pPSchema->PsPresentBox[b].PbPageCounter > 0) /* il y a deja un compteur de page */ { if (pPSchema->PsPresentBox[b].PbPageCounter != counter) /* ce n'est pas le meme compteur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, TWO_DIFFERENT_PAGE_NUMBERS), pPSchema->PsPresentBox[hfB].PbName); } else /* on a trouve' le compteur de pages */ pPSchema->PsPresentBox[b].PbPageCounter = counter; pPSchema->PsCounter[counter - 1].CnPageFooter = pPSchema->PsPresentBox[hfB].PbPageFooter; } } } } /* fin regle creation fille */ } /* fin parcours regle creation de hfB */ /* passe a la regle suivante de hfB */ pRC = pRC->PrNextPRule; } /* fin parcours regle creation de hfB */ while (!stop1); } /* fin recherche compteur chez les filles */ #endif /* __COLPAGE__ */ } /* fin regle de position verticale OK */ } pR = pR->PrNextPRule; /* passe a la regle suivante de b */ } } while (!stop); /* on a traite' toutes les boites de haut et de bas de page de */ /* cette boite page */ pPSchema->PsPresentBox[b].PbFooterHeight = footHeight; pPSchema->PsPresentBox[b].PbHeaderHeight = headHeight; /* prevoir d'ajouter le positionnement de RPDimMin du corps */ /* de page */ } /* les boites de haut et de bas de page sont maintenant marquees */ /* verifie que seules les boites pages et les boites de haut et de */ /* bas de page creent d'autres boites */ /* verifie egalement les regles Content de toutes les boites */ for (b = 0; b < pPSchema->PsNPresentBoxes; b++) { /* examine chaque boite */ pPresBox = &pPSchema->PsPresentBox[b]; if (!(pPresBox->PbPageHeader || pPresBox->PbPageFooter)) /* ce n'est pas une boite de haut ou bas de page, */ /* verifie sa regle Content */ if (pPresBox->PbContent == ContElement) /* le contenu est un type d'element, erreur */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, BAD_CONTENT_RULE), pPSchema->PsPresentBox[b].PbName); if (pPresBox->PbPageHeader || pPresBox->PbPageFooter) /* c'est une boite de haut ou bas de page, */ if (pPresBox->PbContent == ContElement) /* son contenu est un type d'element */ if (viewOfBox[b] != 1) /* elle n'est pas creee par une page de la vue 1 */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, FORBIDDEN_OUTSIDE_OF_MAIN_VIEW), pPSchema->PsPresentBox[b].PbName); /* cherche les regles de creation de la boite */ pR = pPresBox->PbFirstPRule; /* 1ere regle de presentation */ /* parcourt les premieres regles de la boite */ stop = False; do { if (pR == NULL) stop = True; else if (pR->PrType > PtFunction) stop = True; if (!stop) { if (pR->PrType == PtFunction && (pR->PrPresFunction == FnCreateBefore || pR->PrPresFunction == FnCreateAfter)) /* ce n'est pas une regle de creation autorisee */ if (!pPresBox->PbPageBox) TtaDisplayMessage (FATAL, TtaGetMessage (PRS, FORBIDDEN_CREA_RULE), pPSchema->PsPresentBox[b].PbName); pR = pR->PrNextPRule; /* passe a la regle suivante */ } } while (!stop); } /* verifie les regles de l'element PAGE_UNIT */ for (view = 1; view <= pPSchema->PsNViews; view++) /* cherche la regle de positionnement vertical */ { pR = SearchPRule (&pPSchema->PsElemPRule[PageBreak], PtVertPos, view); /* modifie la regle: positionnement au-dessous de l'element */ /* precedent */ pR->PrPresMode = PresImmediate; pR->PrPosRule.PoPosDef = Top; pR->PrPosRule.PoPosRef = Bottom; pR->PrPosRule.PoDistUnit = UnPoint; pR->PrPosRule.PoDistance = 0; pR->PrPosRule.PoRelation = RlPrevious; pR->PrPosRule.PoNotRel = False; pR->PrPosRule.PoRefElem = True; pR->PrPosRule.PoUserSpecified = False; pR->PrPosRule.PoTypeRefElem = 0; /* cherche la regle de positionnement horizontal */ pR = SearchPRule (&pPSchema->PsElemPRule[PageBreak], PtHorizPos, view); /* modifie la regle: positionnement sur le bord gauche de la */ /* boite racine */ pR->PrPresMode = PresImmediate; pR->PrPosRule.PoPosDef = Left; pR->PrPosRule.PoPosRef = Left; pR->PrPosRule.PoDistUnit = UnPoint; pR->PrPosRule.PoDistance = 0; pR->PrPosRule.PoRelation = RlRoot; pR->PrPosRule.PoNotRel = False; pR->PrPosRule.PoRefElem = True; pR->PrPosRule.PoUserSpecified = False; pR->PrPosRule.PoTypeRefElem = 0; /* cherche la regle de largeur */ pR = SearchPRule (&pPSchema->PsElemPRule[PageBreak], PtWidth, view); /* modifie la regle: largeur du contenu */ pR->PrPresMode = PresImmediate; pR->PrDimRule.DrPosition = False; pR->PrDimRule.DrAbsolute = False; pR->PrDimRule.DrSameDimens = True; pR->PrDimRule.DrUnit = UnRelative; pR->PrDimRule.DrValue = 0; pR->PrDimRule.DrRelation = RlEnclosed; pR->PrDimRule.DrNotRelat = False; pR->PrDimRule.DrRefElement = True; pR->PrDimRule.DrUserSpecified = False; pR->PrDimRule.DrTypeRefElem = 0; /* cherche la regle de hauteur */ pR = SearchPRule (&pPSchema->PsElemPRule[PageBreak], PtHeight, view); /* modifie la regle: hauteur du contenu */ pR->PrPresMode = PresImmediate; pR->PrDimRule.DrPosition = False; pR->PrDimRule.DrAbsolute = False; pR->PrDimRule.DrSameDimens = True; pR->PrDimRule.DrUnit = UnRelative; pR->PrDimRule.DrValue = 0; pR->PrDimRule.DrRelation = RlEnclosed; pR->PrDimRule.DrNotRelat = False; pR->PrDimRule.DrRefElement = True; pR->PrDimRule.DrUserSpecified = False; pR->PrDimRule.DrTypeRefElem = 0; /* modifie la regle: HorizOverflow: True; */ pR = SearchPRule (&pPSchema->PsElemPRule[PageBreak], PtHorizOverflow, view); pR->PrType = PtHorizOverflow; pR->PrPresMode = PresImmediate; pR->PrJustify = True; } } /*---------------------------------------------------------------------- CheckUsedBoxes parcourt la chaine de regles de presentation commencant par la regle pointee par pRule et cherche toutes les regles de creation ou de mise en page. Marque utilisee la boite de presentation utilisee dans ces regles ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CheckUsedBoxes (PtrPRule pRule, boolean usedBox[MAX_PRES_BOX]) #else /* __STDC__ */ static void CheckUsedBoxes (pRule, usedBox) PtrPRule pRule; boolean usedBox[MAX_PRES_BOX]; #endif /* __STDC__ */ { boolean stop; int i; stop = False; do { if (pRule == NULL) stop = True; /* derniere regle de la chaine */ else if (pRule->PrType > PtFunction) stop = True; /* on a vu la partie interessante de la chaine */ if (!stop) { if (pRule->PrType == PtFunction && (pRule->PrPresFunction == FnPage || pRule->PrPresFunction == FnCreateEnclosing || pRule->PrPresFunction == FnCreateBefore || pRule->PrPresFunction == FnCreateWith || pRule->PrPresFunction == FnCreateFirst || pRule->PrPresFunction == FnCreateLast || pRule->PrPresFunction == FnCreateAfter)) /* c'est une regle de creation ou une regle Page */ /* marque la boite utilisee */ usedBox[pRule->PrPresBox[0] - 1] = True; else if (pRule->PrType == PtFunction && (pRule->PrPresFunction == FnColumn || pRule->PrPresFunction == FnSubColumn)) /* c'est une regle de colonnage */ for (i = 0; i < pRule->PrNPresBoxes; i++) usedBox[pRule->PrPresBox[i] - 1] = True; pRule = pRule->PrNextPRule; /* passe a la regle suivante */ } } while (!stop); } /*---------------------------------------------------------------------- CheckAllBoxesUsed verifie que toutes les boites de presentation declarees dans le schema sont bien utilisees dans une regle de creation ou une regle Page ----------------------------------------------------------------------*/ #ifdef __STDC__ static void CheckAllBoxesUsed () #else /* __STDC__ */ static void CheckAllBoxesUsed () #endif /* __STDC__ */ { int b, el, att, k, l; boolean usedBox[MAX_PRES_BOX]; AttributePres *pPRuleA; /* marque d'abord qu'aucune boite de presentation n'est utilisee */ for (b = 0; b < pPSchema->PsNPresentBoxes; b++) usedBox[b] = False; /* recherche toutes les regles de creation associees aux boites de */ /* presentation et marque les boites utilisees par ces regles. */ for (b = 0; b < pPSchema->PsNPresentBoxes; b++) CheckUsedBoxes (pPSchema->PsPresentBox[b].PbFirstPRule, usedBox); /* recherche toutes les regles de creation et les regles PAGE associees aux */ /* types d'elements et marque les boites utilisees par ces regles. */ for (el = 0; el < pSSchema->SsNRules; el++) /* cherche dans les regles de */ /* presentation de chaque type d'element */ CheckUsedBoxes (pPSchema->PsElemPRule[el], usedBox); /* recherche toutes les regles de creation associees aux attributs et */ /* marque les boites utilisees par ces regles. */ for (att = 0; att < pSSchema->SsNAttributes; att++) /* cherche dans les regles de presentation des attributs */ { pPRuleA = pPSchema->PsAttrPRule[att]; for (l = pPSchema->PsNAttrPRule[att]; l-- > 0; pPRuleA = pPRuleA->ApNextAttrPres) { /* selon le type de l'attribut */ switch (pSSchema->SsAttribute[att].AttrType) { case AtNumAttr: for (k = 0; k < pPRuleA->ApNCases; k++) CheckUsedBoxes (pPRuleA->ApCase[k].CaFirstPRule, usedBox); break; case AtTextAttr: CheckUsedBoxes (pPRuleA->ApTextFirstPRule, usedBox); break; case AtReferenceAttr: CheckUsedBoxes (pPRuleA->ApRefFirstPRule, usedBox); break; case AtEnumAttr: for (k = 0; k <= pSSchema->SsAttribute[att].AttrNEnumValues; k++) CheckUsedBoxes (pPRuleA->ApEnumFirstPRule[k], usedBox); break; default: break; } } } /* sort un message pour chaque boite inutilisee */ for (b = 0; b < pPSchema->PsNPresentBoxes; b++) if (!usedBox[b]) TtaDisplayMessage (INFO, TtaGetMessage (PRS, UNUSED_BOX), pPSchema->PsPresentBox[b].PbName); } /*---------------------------------------------------------------------- main ----------------------------------------------------------------------*/ #ifdef __STDC__ void main (int argc, char **argv) #else /* __STDC__ */ void main (argc, argv) int argc; char **argv; #endif /* __STDC__ */ { FILE *infile; boolean fileOK; char fname[200], buffer[200], cmd[800]; char *pwd, *ptr; Name srceFileName; /* nom du fichier a compiler */ indLine wi; /* position du debut du mot courant dans la ligne en cours */ indLine wl; /* longueur du mot courant */ SyntacticType wn; /* SyntacticType grammaticale du mot courant */ SyntRuleNum r; /* numero de regle de grammaire */ SyntRuleNum pr; /* numero de la regle de grammaire precedente */ SyntacticCode c; /* code grammatical du mot trouve */ int nb; /* indice dans Identifier du mot trouve', si identificateur */ int i; int param; TtaInitializeAppRegistry (argv[0]); i = TtaGetMessageTable ("libdialogue", TMSG_LIB_MSG_MAX); COMPIL = TtaGetMessageTable ("compildialogue", COMP_MSG_MAX); PRS = TtaGetMessageTable ("prsdialogue", PRS_MSG_MAX); error = False; /* initialize the parser */ InitParser (); /* load the compiler grammar */ InitSyntax ("PRESEN.GRM"); if (!error) { /* prepare the cpp command */ strcpy (cmd, "cpp "); param = 1; while (param < argc && argv[param][0] == '-') { /* keep cpp params */ strcat (cmd, argv[param]); strcat (cmd, " "); param++; } /* recupere d'abord le nom du schema a compiler */ if (param >= argc) { TtaDisplaySimpleMessage (FATAL, PRS, UNKNOWN_FILE); exit (1); } strncpy (srceFileName, argv[param], MAX_NAME_LENGTH - 1); srceFileName[MAX_NAME_LENGTH - 1] = '\0'; param++; strcpy (fname, srceFileName); /* check if the name contains a suffix */ ptr = strrchr(fname, '.'); nb = strlen (srceFileName); if (!ptr) /* there is no suffix */ strcat (srceFileName, ".P"); else if (strcmp(ptr, ".P")) { /* it's not the valid suffix */ TtaDisplayMessage (FATAL, TtaGetMessage (PRS, INVALID_FILE), srceFileName); exit (1); } else { /* it's the valid suffix, cut the srcFileName here */ ptr[0] = '\0'; nb -= 2; /* length without the suffix */ } /* add the suffix .SCH in srceFileName */ strcat (fname, ".SCH"); /* does the file to compile exist */ if (TtaFileExist (srceFileName) == 0) TtaDisplaySimpleMessage (FATAL, PRS, UNKNOWN_FILE); else { /* provide the real source file */ TtaFileUnlink (fname); pwd = TtaGetEnvString ("PWD"); i = strlen (cmd); if (pwd != NULL) sprintf (&cmd[i], "-I%s -C %s > %s", pwd, srceFileName, fname); else sprintf (&cmd[i], "-C %s > %s", srceFileName, fname); i = system (cmd); if (i == -1) { /* cpp is not available, copy directely the file */ TtaDisplaySimpleMessage (INFO, PRS, CPP_NOT_FOUND); TtaFileCopy (srceFileName, fname); } infile = TtaReadOpen (fname); if (param == argc) /* the output name is equal to the input name */ /*suppress the suffix ".SCH" */ srceFileName[nb] = '\0'; else /* read the output name */ strncpy (srceFileName, argv[param], MAX_NAME_LENGTH - 1); /* le fichier a compiler est ouvert */ NIdentifiers = 0; /* table des identificateurs vide */ LineNum = 0; /* encore aucune ligne lue */ pSSchema = NULL; /* pas (encore) de schema de structure */ /* lit tout le fichier et fait l'analyse */ fileOK = True; while (fileOK && !error) { /* lit une ligne */ LineNum++; /* incremente le compteur de lignes lues */ i = 0; do { fileOK = TtaReadByte (infile, &inputLine[i]); i++; } while (i < LINE_LENGTH && inputLine[i - 1] != '\n' && fileOK); /* marque la fin reelle de la ligne */ inputLine[i - 1] = '\0'; if (i >= LINE_LENGTH) /* ligne trop longue */ CompilerMessage (1, PRS, FATAL, MAX_LINE_SIZE_OVERFLOW, inputLine, LineNum); else if (inputLine[0] == '#') /* cette ligne contient une directive du preprocesseur cpp */ { sscanf (inputLine, "# %d %s", &LineNum, buffer); LineNum--; } else /* traduit tous les caracteres de la ligne */ { OctalToChar (); /* analyse la ligne */ wi = 1; wl = 0; /* analyse tous les mots de la ligne courante */ do { i = wi + wl; GetNextToken (i, &wi, &wl, &wn); /* mot suivant */ if (wi > 0) /* word found */ { AnalyzeToken (wi, wl, wn, &c, &r, &nb, &pr); /* analyze the word */ if (!error) ProcessToken (wi, wl, c, r, nb - 1, pr); /* on le traite */ } } while (wi != 0 && !error); /* il n'y a plus de mots a analyser dans la ligne */ } } /* end of file */ TtaReadClose (infile); if (!error) ParserEnd (); /* fin d'analyse */ if (!error) { SortAllPRules (); /* met les regles de presentation dans le bon ordre. */ /* si aucune vue n'est definie, cree la vue par defaut avec un nom */ /* standard */ if (pPSchema->PsNViews == 0) { pPSchema->PsNViews = 1; strcpy (pPSchema->PsView[0], TtaGetMessage (PRS, SINGLE_VIEW)); } /* verifie que toutes les boites de presentation declarees pour les */ /* pages sont bien utilisees et adapte les regles. */ /* cela ne peut se faire qu'apres avoir ajoute' la vue par defaut */ CheckPageBoxes (); /* verifie que toutes les boites de presentation sont bien utilisees */ CheckAllBoxesUsed (); /* write the compiled schema into the output file */ /* remove temporary file */ TtaFileUnlink (fname); strcat (srceFileName, ".PRS"); fileOK = WritePresentationSchema (srceFileName, pPSchema, pSSchema); if (!fileOK) TtaDisplayMessage (FATAL, TtaGetMessage (PRS, WRITE_ERROR), srceFileName); } } } fflush (stdout); TtaSaveAppRegistry (); exit (0); }