// File: tutorialchecker.c // // Author: Francois Coupleux (coupleux@eleve.emn.fr) // // Date: 7-8-1996 // // Description: Programs which generates a file called tutorialdescription.dat. #include #include #define NBWORDS 31 #define WORDSIZE 51 #define TEXTSIZE 1001 #define NBPARAMETERS 30 #define NBSUBSECTIONS 20 #define NBWINDOWS 200 char words[NBWORDS][WORDSIZE]; /* Function which returns 1 if the word is a parameter name */ char isParameterName(char* word) { char i; char* parameters[27] = {"NAME" , "WINDOWTITLE" , "BACKGROUNDCOLOR" , "FOREGROUNDCOLOR" , "TITLECOLOR" , "TEXTCOLOR" , "BUTTONCOLOR" , "LABELCOLOR" , "SPECIALBUTTONCOLOR" , "SPECIALLABELCOLOR" , "TEXTFIELDCOLOR" , "CENTER" , "TITLESIZE" , "TEXTWIDTH" , "MAXCONTENTHEIGHT" , "XGAP" , "YGAP", "IMAGENAME" , "IMAGEWIDTH" , "IMAGEHEIGHT" , "FIGURENUMBER" , "GRAPHTITLE" , "XTITLE" , "YTITLE" , "XVARIABLE" , "YVARIABLE" , "XVARIABLEUNIT"}; for(i = 0 ; i < 27 ; i++) { if(! strcmp(parameters[i] , word)) { return 1; } } return 0; } /* Function which returns 1 if the word is a section delimiter (sections + subsections) */ char isSectionDelimiter(char* word) { char i; char* delimiters[22] = {"DEFAULTVALUES" , "ENDDEFAULTVALUES" , "MAINMENU" , "ENDMAINMENU" , "WINDOW" , "ENDWINDOW" , "MENU" , "ENDMENU" , "PLOTTINGSYSTEM" , "ENDPLOTTINGSYSTEM" , "TITLE" , "ENDTITLE" , "TEXT" , "ENDTEXT" , "NAVIGATOR" , "ENDNAVIGATOR" , "PICTURE" , "ENDPICTURE" , "PARAMETERS" , "ENDPARAMETERS" , "EQUATIONS" , "ENDEQUATIONS"}; for(i = 0 ; i < 22 ; i++) { if(! strcmp(delimiters[i] , word)) { return 1; } } return 0; } /* Function which returns 1 if the word is a subsection delimiter */ char isSubsectionDelimiter(char* word) { char i; char* delimiters[12] = {"TITLE" , "ENDTITLE" , "TEXT" , "ENDTEXT" , "NAVIGATOR" , "ENDNAVIGATOR" , "PICTURE" , "ENDPICTURE" , "PARAMETERS" , "ENDPARAMETERS" , "EQUATIONS" , "ENDEQUATIONS"}; for(i = 0 ; i < 12 ; i++) { if(! strcmp(delimiters[i] , word)) { return 1; } } return 0; } /* Function which returns 1 if the word opens a section or a subsection */ char isOpener(char* word) { char i; char* delimiters[11] = {"DEFAULTVALUES" , "MAINMENU" , "WINDOW" , "MENU" , "PLOTTINGSYSTEM" , "TITLE" , "TEXT" , "NAVIGATOR" , "PICTURE" , "PARAMETERS" , "EQUATIONS"}; for(i = 0 ; i < 11 ; i++) { if(! strcmp(delimiters[i] , word)) { return 1; } } return 0; } /* Function which returns the number of the arguments needed to set a parameter */ char nbOfArguments(char* word) { char i; char* parameters[27] = {"NAME" , "WINDOWTITLE" , "BACKGROUNDCOLOR" , "FOREGROUNDCOLOR" , "TITLECOLOR" , "TEXTCOLOR" , "BUTTONCOLOR" , "LABELCOLOR" , "SPECIALBUTTONCOLOR" , "SPECIALLABELCOLOR" , "TEXTFIELDCOLOR" , "CENTER" , "TITLESIZE" , "TEXTWIDTH" , "MAXCONTENTHEIGHT" , "XGAP" , "YGAP", "IMAGENAME" , "IMAGEWIDTH" , "IMAGEHEIGHT" , "FIGURENUMBER" , "GRAPHTITLE" , "XTITLE" , "YTITLE" , "XVARIABLE" , "YVARIABLE" , "XVARIABLEUNIT"}; char nbArguments[27] = {1 , -1 ,3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , -1 , -1 , -1 , -1 , 1 , 1 , 1}; for(i = 0 ; i < 27 ; i++) { if(! strcmp(parameters[i] , word)) { return nbArguments[i]; } } } /* Function which returns 1 if this section or subsection is authorized */ char isDelimiterAuthorized(char* word , char* section , char* subsection) { char i , sectionNumber , subsectionNumber; char* sections[6] = {"DEFAULTVALUES" , "MAINMENU" , "WINDOW" , "MENU" , "PLOTTINGSYSTEM" , ""}; char* subsectionOpeners[6] = {"TITLE" , "TEXT" , "NAVIGATOR" , "PICTURE" , "PARAMETERS" , "EQUATIONS"}; char* subsectionClosers[6] = {"ENDTITLE" , "ENDTEXT" , "ENDNAVIGATOR" , "ENDPICTURE" , "ENDPARAMETERS" , "ENDEQUATIONS"}; char* sectionOpeners[5] = {"DEFAULTVALUES" , "MAINMENU" , "WINDOW" , "MENU" , "PLOTTINGSYSTEM"}; char* sectionClosers[5] = {"ENDDEFAULTVALUES" , "ENDMAINMENU" , "ENDWINDOW" , "ENDMENU" , "ENDPLOTTINGSYSTEM"}; char authorizedSubsections[6][6] = {{0 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 0 , 0}, {1 , 1 , 1 , 1 , 0 , 0}, {0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 1}, {0 , 0 , 0 , 0 , 0 , 0}}; if(isSubsectionDelimiter(word)) { if(isOpener(word)) { for(i = 0 ; i < 6 ; i++) { if(! strcmp(section , sections[i])) { sectionNumber = i; break; } } for(i = 0 ; i < 6 ; i++) { if(! strcmp(word , subsectionOpeners[i])) { subsectionNumber = i; break; } } return authorizedSubsections[sectionNumber][subsectionNumber]; } else { for(i = 0 ; i < 6 ; i++) { if(! strcmp(subsection , subsectionOpeners[i])) { subsectionNumber = i; break; } } for(i = 0 ; i < 6 ; i++) { if(! strcmp(word , subsectionClosers[i])) { break; } } return subsectionNumber == i; } } else { if(isOpener(word)) { if(! strcmp(section , "")) { return 1; } return 0; } else { for(i = 0 ; i < 5 ; i++) { if(! strcmp(section , sectionOpeners[i])) { sectionNumber = i; break; } } for(i = 0 ; i < 5 ; i++) { if(! strcmp(word , sectionClosers[i])) { break; } } return sectionNumber == i; } } } /* Function which returns 1 if the parameter is authorized in the current section */ char isParameterAuthorized(char* word , char* section , char* subsection) { char parameterNumber , sectionNumber , subsectionNumber , i; char* parameters[27] = {"NAME" , "WINDOWTITLE" , "BACKGROUNDCOLOR" , "FOREGROUNDCOLOR" , "TITLECOLOR" , "TEXTCOLOR" , "BUTTONCOLOR" , "LABELCOLOR" , "SPECIALBUTTONCOLOR" , "SPECIALLABELCOLOR" , "TEXTFIELDCOLOR" , "CENTER" , "TITLESIZE" , "TEXTWIDTH" , "MAXCONTENTHEIGHT" , "XGAP" , "YGAP", "IMAGENAME" , "IMAGEWIDTH" , "IMAGEHEIGHT" , "FIGURENUMBER" , "GRAPHTITLE" , "XTITLE" , "YTITLE" , "XVARIABLE" , "YVARIABLE" , "XVARIABLEUNIT"}; char* sections[11] = {"DEFAULTVALUES" , "MAINMENU" , "WINDOW" , "MENU" , "PLOTTINGSYSTEM" , "TITLE" , "TEXT" , "NAVIGATOR" , "PICTURE" , "PARAMETERS" , "EQUATIONS"}; char authorizedParameters[27][11] = {{0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0}, {1 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0}, {1 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0}, {1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}, {1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0}, {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0}, {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0}, {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}, {0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0}}; for(i = 0 ; i < 27 ; i++) { if(! strcmp(parameters[i] , word)) { parameterNumber = i; break; } } if(! strcmp(subsection , "")) { for(i = 0 ; i < 5 ; i++) { if(! strcmp(sections[i] , section)) { break; } } } else { for(i = 5 ; i < 11 ; i++) { if(! strcmp(sections[i] , subsection)) { break; } } } return authorizedParameters[parameterNumber][i]; } /* Procedure which checks if arguments are correct */ void checkArguments(int line , int nbWords , char* isNumber , char* nbDots , char* isTime , char* isDivide , char* isPow) { char i; char* parameters[12] = {"NAME" , "TITLESIZE" , "TEXTWIDTH" , "MAXCONTENTHEIGHT" , "XGAP" , "YGAP" , "IMAGENAME" , "IMAGEWIDTH" , "IMAGEHEIGHT" , "XVARIABLE" , "YVARIABLE" , "XVARIABLEUNIT"}; char argumentType[12] = {1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 1}; if(nbWords != 1 && nbOfArguments(words[0]) != -1) { if(nbWords == 4) { for(i = 1 ; i < 4 ; i++) { if(! isNumber[i]) { printf("Line %d Word %d: Incorrect argument.\n" , line , i + 1); exit(0); } if(atoi(words[i]) > 255) { printf("Line %d Word %d: Value out of bounds.\n" , line , i + 1); exit(0); } } } else { for(i = 0 ; i < 12 ; i++) { if(! strcmp(words[0] , parameters[i])) { break; } } if(argumentType[i] == 0 && ! isNumber[1]) { printf("Line %d Word %d: Number expected.\n" , line , i + 1); exit(0); } if(argumentType[i] == 1) { if(isNumber[1]) { printf("Line %d Word 2: Word expected.\n" , line); exit(0); } if(! strcmp(words[0] , "NAME")) { if(nbDots[1] != 0 || isTime[1] || isDivide[1] || isPow[1]) { printf("Line %d Word 2: Incorrect argument.\n" , line); exit(0); } } else if(! strcmp(words[0] , "TITLESIZE")) { if(nbDots[1] != 0 || isTime[1] || isDivide[1] || isPow[1]) { printf("Line %d Word 2: Incorrect argument.\n" , line); exit(0); } i = 0; while(words[1][i] != 0) { words[1][i] = toupper(words[1][i]); i++; } if(strcmp(words[1] , "NORMAL") && strcmp(words[1] , "MEDIUM") && strcmp(words[1] , "LARGE")) { printf("Line %d Word 2: This size is not recognized.\n" , line); exit(0); } } else if(! strcmp(words[0] , "IMAGENAME")) { if(nbDots[1] != 1 || isTime[1] || isDivide[1] || isPow[1]) { printf("Line %d Word 2: Incorrect argument.\n" , line); exit(0); } i = 0; while(words[1][i] != '.') { i++; } if(words[1][i + 1] != 'g' || words[1][i + 2] != 'i' || words[1][i + 3] != 'f' || words[1][i + 4] != 0) { printf("Line %d Word 2: This is not a gif image.\n" , line); exit(0); } } else if(! strcmp(words[0] , "XVARIABLE")) { if(nbDots[1] != 0 || isTime[1] || isDivide[1] || isPow[1]) { printf("Line %d Word 2: Incorrect argument.\n" , line); exit(0); } } else if(! strcmp(words[0] , "YVARIABLE")) { if(nbDots[1] != 0 || isTime[1] || isDivide[1] || isPow[1]) { printf("Line %d Word 2: Incorrect argument.\n" , line); exit(0); } } else if(! strcmp(words[0] , "XVARIABLEUNIT")) { if(nbDots[1] != 0) { printf("Line %d Word 2: There is a '.' in the unit.\n" , line); exit(0); } } } } } } /* Function which returns 1 if non optional parameters of the subsection are set */ char checkSubsectionParameters(char* subsection , char nbParameters , char parameters[NBPARAMETERS][WORDSIZE] , char isSpecialLine) { char i , j; char* pictureParameters[3] = {"IMAGENAME" , "IMAGEWIDTH" , "IMAGEHEIGHT"}; if(! isSpecialLine && (! strcmp(subsection , "TITLE") || ! strcmp(subsection , "TEXT") || ! strcmp(subsection , "NAVIGATOR") || ! strcmp(subsection , "PARAMETERS") || ! strcmp(subsection , "EQUATIONS"))) { return 0; } if(! strcmp(subsection , "PICTURE")) { for(i = 0 ; i < 3 ; i++) { for(j = 0 ; j < nbParameters ; j++) { if(! strcmp(pictureParameters[i] , parameters[j])) { break; } } if(j == nbParameters) { return 0; } } } return 1; } /* Function which returns 1 if non optional parameters of the section are set */ char checkSectionParameters(char* section , char nbParameters , char parameters[NBPARAMETERS][WORDSIZE] , char nbSubsections , char subsections[NBSUBSECTIONS][WORDSIZE] , char isSpecialLine) { char i , j; char* windowParameters[2] = {"NAME" , "WINDOWTITLE"}; char* plottingSystemParameters[2] = {"XVARIABLE" , "YVARIABLE"}; char* plottingSystemSubsections[2] = {"PARAMETERS" , "EQUATIONS"}; if(! isSpecialLine && (! strcmp(section , "MAINMENU") || ! strcmp(section , "MENU"))) { return 0; } if(! strcmp(section , "MENU") || ! strcmp(section , "PLOTTINGSYSTEM") || ! strcmp(section , "WINDOW")) { for(i = 0 ; i < 2 ; i++) { for(j = 0 ; j < nbParameters ; j++) { if(! strcmp(windowParameters[i] , parameters[j])) { break; } } if(j == nbParameters) { return 0; } } } if(! strcmp(section , "PLOTTINGSYSTEM")) { for(i = 0 ; i < 2 ; i++) { for(j = 0 ; j < nbParameters ; j++) { if(! strcmp(plottingSystemParameters[i] , parameters[j])) { break; } } if(j == nbParameters) { return 0; } } for(i = 0 ; i < 2 ; i++) { for(j = 0 ; j < nbSubsections ; j++) { if(! strcmp(plottingSystemSubsections[i] , subsections[j])) { break; } } if(j == nbSubsections) { return 0; } } } return 1; } int main(int nb_arg , char* arg[]) { FILE* inputFile; FILE* outputFile; char c ; char section[WORDSIZE]; char subsection[WORDSIZE]; char isNumber[NBWORDS]; char isAuthorizedCharacter[NBWORDS]; char text[TEXTSIZE]; char nbDots[NBWORDS]; char isTime[NBWORDS]; char isDivide[NBWORDS]; char isPow[NBWORDS]; char parametersInSection[NBPARAMETERS][WORDSIZE]; char parametersInSubsection[NBPARAMETERS][WORDSIZE]; char subsectionsInSection[NBSUBSECTIONS][WORDSIZE]; char declaredWindows[NBWINDOWS][WORDSIZE]; char destinationWindows[NBWINDOWS][WORDSIZE]; char destinationWindowName[WORDSIZE]; char isFirstSection , isFirstLetter , isFirstSeparator; char isAfterAnd , isAfterAt , isAfterUnderscore , isNumberAfterAt , isNumberAfterUnderscore; char isDollar , isFirstTextDescription , isSpecialLineInSection , isSpecialLineInSubsection; char isDefaultValues , isMainMenu , isEquation; int line , nbDeclaredWindows , nbDestinationWindows , indexDeclaredWindow; int indexDestinationWindow , i , nbSpaces , nbWords , indexWord , indexCharacter , nbLines , nbAnds , nbAts; int nbUnderscores , nbWordsAfterAnd , nbParametersInSection , nbParametersInSubsection; int nbSubsectionsInSection; /* Checks the number of parameters */ if(nb_arg != 2) { puts("Incorrect number of arguments."); exit(0); } /* Opens input file */ inputFile = fopen(arg[1] , "r"); if(inputFile == NULL) { printf("Impossible to read %s.\n" , arg[1]); exit(0); } /* Opens output file */ outputFile = fopen("tutorialdescription.dat" , "w"); if(outputFile == NULL) { puts("Impossible to open tutorialdescription.dat."); exit(0); } /* This is the first line */ line = 1; /* Sets current section delimiters */ section[0] = 0; subsection[0] = 0; isFirstSection = 1; isDefaultValues = 0; isMainMenu = 0; nbDeclaredWindows = 0; nbDestinationWindows = 0; /* Scans the file */ while(1) { /* Skips first non significent characters */ while((c = fgetc(inputFile)) == '\n' || c == '\t' || c == ' ') { if(c == '\n') { line++; } } /* If the line begins with '#' this is a comment line */ if(c == '#') { while((c = fgetc(inputFile)) != '\n' && c != EOF) { ; } if(c == EOF) { break; } else { line++; } } /* If the line begins with '{' this a text description */ else if(c == '{') { if(! isFirstTextDescription && (! strcmp(subsection , "TITLE") || ! strcmp(subsection , "TEXT"))) { printf("Line %d: This section must contain a single text description.\n" , line); exit(0); } if(! strcmp(subsection , "")) { isSpecialLineInSection = 1; } else { isSpecialLineInSubsection = 1; } /* Initializes the values of parameters */ nbLines = 1; nbAnds = 0; nbAts = 0; nbUnderscores = 0; isDollar = 0; isAfterAnd = 0; isAfterAt = 0; isAfterUnderscore = 0; indexCharacter = 0; isFirstLetter = 1; isFirstSeparator = 0; while((c = fgetc(inputFile)) != '}' && c != EOF) { if(indexCharacter == TEXTSIZE - 1) { printf("Line %d: Line too long.\n" , line); exit(0); } if((c == ' ' || c == '\t')) { if(isFirstSeparator) { text[indexCharacter] = ' '; indexCharacter++; isFirstSeparator = 0; isFirstLetter = 1; isAfterAt = 0; isAfterUnderscore = 0; } } else if(c == '\n') { line++; nbLines++; if(isFirstSeparator) { text[indexCharacter] = c; indexCharacter++; isFirstSeparator = 0; isFirstLetter = 1; isAfterAt = 0; isAfterUnderscore = 0; } } else { if(! isdigit(c) && isAfterAt) { isNumberAfterAt = 0; } if(! isdigit(c) && isAfterUnderscore) { isNumberAfterUnderscore = 0; } if(isFirstLetter) { isFirstSeparator = 1; isFirstLetter = 0; if(isAfterAnd) { nbWordsAfterAnd++; } } if(c == '&') { nbAnds++; isAfterAnd = 1; isFirstSeparator = 0; isFirstLetter = 1; nbWordsAfterAnd = 0; } else if(c == '@') { nbAts++; isAfterAt = 1; isNumberAfterAt = 1; isFirstSeparator = 0; isFirstLetter = 1; } else if(c == '_') { nbUnderscores++; isAfterUnderscore = 1; isNumberAfterUnderscore = 1; isFirstSeparator = 0; isFirstLetter = 1; } else if(c == '$') { isDollar = 1; if(indexCharacter >= TEXTSIZE - 2) { printf("Line %d: Line too long.\n" , line); exit(0); } text[indexCharacter] = c; text[indexCharacter + 1] = '\n'; indexCharacter += 2; isFirstSeparator = 0; isFirstLetter = 1; } if(c != '$') { text[indexCharacter] = c; indexCharacter++; } } } text[indexCharacter] = 0; if(c == EOF) { printf("Line %d: '}' expected.\n" , line); exit(0); } /* Checks if this line is correct */ if(! strcmp(subsection , "TITLE")) { if(nbLines > 1) { printf("Line %d: A title must be declared on a single line.\n" , line); exit(0); } if(nbAnds != 0) { printf("Line %d: There is a '&' in the title.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the title.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the title.\n" , line); exit(0); } if(isDollar) { printf("Line %d: There is a '$' in the title.\n" , line); exit(0); } } else if(! strcmp(subsection , "TEXT")) { if(nbAts > 1) { printf("Line %d: Too many '@' in this text line.\n" , line); exit(0); } if(nbUnderscores > 1) { printf("Line %d: Too many '_' in this text line.\n" , line); exit(0); } if(nbAts == 1) { if(! isNumberAfterAt) { printf("Line %d: A number is expected after a '@'.\n" , line); exit(0); } if(text[0] != '@') { printf("Line %d: A '@' must be placed at the beginning of the text line.\n" , line); exit(0); } } if(nbUnderscores == 1) { if(! isNumberAfterUnderscore) { printf("Line %d: A number is expected after a '_'.\n" , line); exit(0); } if(text[0] != '_') { printf("Line %d: A '_' must be placed at the beginning of the text line.\n" , line); exit(0); } } if(nbAnds != 0) { printf("Line %d: There is a '&' in the text.\n" , line); exit(0); } if(text[strlen(text) - 2] != '$' || text[strlen(text) - 1] != '\n') { printf("Line %d: A text must end with a '$'\n" , line); exit(0); } } else if(! strcmp(subsection , "PICTURE")) { if(nbLines > 1) { printf("Line %d: A caption must be declared on a single line.\n" , line); exit(0); } if(nbAnds != 0) { printf("Line %d: There is a '&' in the caption.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the caption.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the caption.\n" , line); exit(0); } if(isDollar) { printf("Line %d: There is a '$' in the caption.\n" , line); exit(0); } } else if(! strcmp(subsection , "NAVIGATOR")) { if(nbLines > 1) { printf("Line %d: A button must be declared on a single line.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the description of this button.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the description of this button.\n" , line); exit(0); } if(isDollar) { printf("Line %d: There is a '$' in the description of this button.\n" , line); exit(0); } if(nbAnds == 0) { printf("Line %d: A '&' is expected in this line.\n" , line); exit(0); } if(nbAnds > 1) { printf("Line %d: Too many '&'.\n" , line); exit(0); } if(nbWordsAfterAnd > 1) { printf("Line %d: Too many words after '&'.\n" , line); exit(0); } } else if(! strcmp(subsection , "PARAMETERS")) { if(nbLines > 1) { printf("Line %d: A parameter must be declared on a single line.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the description of this parameter.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the description of this parameter.\n" , line); exit(0); } if(isDollar) { printf("Line %d: There is a '$' in the description of this parameter.\n" , line); exit(0); } if(nbAnds == 0) { printf("Line %d: A '&' is expected in this line.\n" , line); exit(0); } if(nbAnds > 1) { printf("Line %d: Too many '&'.\n" , line); exit(0); } if(nbWordsAfterAnd > 1) { printf("Line %d: Too many words after '&'.\n" , line); exit(0); } } else if(! strcmp(subsection , "EQUATIONS")) { if(nbLines > 1) { printf("Line %d: An equation must be declared on a single line.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the description of this equation.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the description of this equation.\n" , line); exit(0); } if(nbAnds != 0) { printf("Line %d: There is a '&' in the equation.\n" , line); exit(0); } } else if(! strcmp(section , "MAINMENU")) { if(nbLines > 1) { printf("Line %d: A button must be declared on a single line.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the description of this button.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the description of this button.\n" , line); exit(0); } if(isDollar) { printf("Line %d: There is a '$' in the description of this button.\n" , line); exit(0); } if(nbAnds == 0) { printf("Line %d: A '&' is expected in this line.\n" , line); exit(0); } if(nbAnds > 1) { printf("Line %d: Too many '&'.\n" , line); exit(0); } if(nbWordsAfterAnd > 1) { printf("Line %d: Too many words after '&'.\n" , line); exit(0); } } else if(! strcmp(section , "MENU")) { if(nbLines > 1) { printf("Line %d: A button must be declared on a single line.\n" , line); exit(0); } if(nbAts != 0) { printf("Line %d: There is a '@' in the description of this button.\n" , line); exit(0); } if(nbUnderscores != 0) { printf("Line %d: There is a '_' in the description of this button.\n" , line); exit(0); } if(isDollar) { printf("Line %d: There is a '$' in the description of this button.\n" , line); exit(0); } if(nbAnds == 0) { printf("Line %d: A '&' is expected in this line.\n" , line); exit(0); } if(nbAnds > 1) { printf("Line %d: Too many '&'.\n" , line); exit(0); } if(nbWordsAfterAnd > 1) { printf("Line %d: Too many words after '&'.\n" , line); exit(0); } } else { printf("Line %d: The section %s does not support this type of line.\n" , line , section); exit(0); } /* If everything is OK this writes the line in the output file */ if(text[0] == '@' || text[0] == '_') { fputc(text[0] , outputFile); indexCharacter = 1; nbSpaces = 0; while(isdigit(text[indexCharacter])) { nbSpaces = nbSpaces*10 + text[indexCharacter] - '0'; indexCharacter++; } for(i = 0 ; i < nbSpaces - 1 ; i++) { fputc('@' , outputFile); } fputs(text + indexCharacter , outputFile); } else if(nbAnds == 1) { indexCharacter = 0; while(text[indexCharacter] != '&') { if(text[indexCharacter] == ' ') { nbSpaces = 1; } if(nbSpaces != 0 && text[indexCharacter] != ' ') { nbSpaces = 0; } fputc(text[indexCharacter] , outputFile); indexCharacter++; } if(indexCharacter == 0) { printf("Line %d: There must be a word before a '&'.\n" , line); exit(0); } fseek(outputFile , -nbSpaces , 2); fputc('&' , outputFile); indexCharacter++; i = 0; while(text[indexCharacter] != ' ' && text[indexCharacter] != 0) { fputc(text[indexCharacter] , outputFile); destinationWindowName[i] = text[indexCharacter]; indexCharacter++; i++; } destinationWindowName[i] = 0; if(nbDestinationWindows == NBWINDOWS) { puts("Too many windows are declared in this tutorial."); exit(0); } if(strcmp(subsection , "PARAMETERS")) { if(strlen(destinationWindowName) >= WORDSIZE) { printf("Line %d: The name of the next window is too long.\n" , line); exit(0); } for(indexDestinationWindow = 0 ; indexDestinationWindow < nbDestinationWindows ; indexDestinationWindow++) { if(! strcmp(destinationWindowName , destinationWindows[indexDestinationWindow])) { printf("Line %d: The window called %s is already linked to an existing window.\n" , line , destinationWindows[indexDestinationWindow]); exit(0); } } strcpy(destinationWindows[nbDestinationWindows] , destinationWindowName); nbDestinationWindows++; } } else { fputs(text , outputFile); } if(strcmp(subsection , "TEXT")) { fputc('\n' , outputFile); } } /* If it's a parameter declaration */ else { if(c != EOF) { /* Initializes the values of parameters */ for(indexWord = 0 ; indexWord < NBWORDS ; indexWord++) { isNumber[indexWord] = 1; nbDots[indexWord] = 0; isTime[indexWord] = 0; isDivide[indexWord] = 0; isPow[indexWord] = 0; isAuthorizedCharacter[indexWord] = 1; } nbWords = 0; indexWord = 0; indexCharacter = 0; isFirstSeparator = 1; isFirstLetter = 1; do { if(indexWord == WORDSIZE - 1) { printf("Line %d Word %d: Word too long.\n" , line , indexWord + 1); exit(0); } if((c == ' ' || c == '\t')) { if(isFirstSeparator) { if(indexWord == NBWORDS) { printf("Line %d: Too many words.\n" , line); exit(0); } words[indexWord][indexCharacter] = 0; isFirstSeparator = 0; isFirstLetter = 1; indexWord++; indexCharacter = 0; } } else { if(indexWord == NBWORDS) { printf("Line %d: Too many words.\n" , line); exit(0); } if(! isdigit(c)) { isNumber[indexWord] = 0; } if(c == '.') { nbDots[indexWord]++; } else if(c == '*' && ! isTime[indexWord]) { isTime[indexWord] = 1; } else if(c == '/' && ! isDivide[indexWord]) { isDivide[indexWord] = 1; } else if(c == '^' && ! isPow[indexWord]) { isPow[indexWord] = 1; } else { if(! isalpha(c) && ! isdigit(c)) { printf("Line %d Word %d: The character '%c' can't be used.\n" , line , indexWord + 1 , c); exit(0); } } if(isFirstLetter) { nbWords++; isFirstSeparator = 1; isFirstLetter = 0; } if(indexWord == 0) { c = toupper(c); } words[indexWord][indexCharacter] = c; indexCharacter++; } } while((c = fgetc(inputFile)) != '\n' && c != EOF); words[indexWord][indexCharacter] = 0; /* Checks if the line is correct */ if(! isParameterName(words[0]) && ! isSectionDelimiter(words[0])) { printf("Line %d Word 0: This word is not recognized.\n" , line); exit(0); } if(isSectionDelimiter(words[0])) { if(nbWords > 1) { printf("Line %d: A section delimiter does not need arguments.\n" , line); exit(0); } if(! isDelimiterAuthorized(words[0] , section , subsection)) { printf("Line %d Word 0: This section delimiter can't be declared here.\n" , line); exit(0); } if(! isOpener(words[0])) { if(! isSubsectionDelimiter(words[0])) { if(strcmp(subsection , "") && strcmp(words[0] + 3 , subsection)) { printf("Line %d: A subsection is not closed.\n" , line); exit(0); } if(! strcmp(section , "DEFAULTVALUES") && nbParametersInSection == 0) { printf("Line %d: There is no declaration in DEFAULTVALUES.\n" , line); exit(0); } if(! checkSectionParameters(section , nbParametersInSection , parametersInSection , nbSubsectionsInSection , subsectionsInSection , isSpecialLineInSection)) { printf("Line %d: A declaration is missing in the current section.\n" , line); exit(0); } section[0] = 0; subsection[0] = 0; } else { if(! checkSubsectionParameters(subsection , nbParametersInSubsection , parametersInSubsection , isSpecialLineInSubsection)) { printf("Line %d: A declaration is missing in the current subsection.\n" , line); exit(0); } subsection[0] = 0; } } else { isFirstTextDescription = 1; if(! isSubsectionDelimiter(words[0])) { if((! strcmp(words[0] , "DEFAULTVALUES") && isDefaultValues) || (! strcmp(words[0] , "MAINMENU") && isMainMenu)) { printf("Line %d: The section %s is already declared.\n" , line , words[0]); exit(0); } if(! strcmp(words[0] , "DEFAULTVALUES") && ! isFirstSection) { printf("Line %d Word 0: This section must be the first one.\n" , line); exit(0); } if(strcmp(words[0] , "DEFAULTVALUES") && strcmp(words[0] , "MAINMENU") && ! isMainMenu) { printf("Line %d Word 0: The section MAINMENU must be defined before this section.\n" , line); exit(0); } if(isFirstSection) { isFirstSection = 0; } if(! strcmp(words[0] , "DEFAULTVALUES")) { isDefaultValues = 1; } if(! strcmp(words[0] , "MAINMENU")) { isMainMenu = 1; } if(! strcmp(words[0] , "PLOTTINGSYSTEM")) { isEquation = 0; } strcpy(section , words[0]); subsection[0] = 0; isSpecialLineInSection = 0; nbParametersInSection = 0; nbSubsectionsInSection = 0; } else { if(! strcmp(words[0] , "PARAMETERS") && ! isEquation) { printf("Line %d Word 1: The subsection EQUATIONS must be declared before this subsection.\n" , line); exit(0); } if(! strcmp(words[0] , "EQUATIONS") && ! isEquation) { isEquation = 1; } strcpy(subsection , words[0]); isSpecialLineInSubsection = 0; nbParametersInSubsection = 0; if(nbSubsectionsInSection == NBSUBSECTIONS) { printf("Line %d: Too many subsections in this section.\n" , line); exit(0); } strcpy(subsectionsInSection[nbSubsectionsInSection] , words[0]); nbSubsectionsInSection++; } } } else { if(! isParameterAuthorized(words[0] , section , subsection)) { printf("Line %d Word 0: This parameter can't be defined here.\n" , line); exit(0); } if(nbOfArguments(words[0]) != -1 && nbOfArguments(words[0]) != nbWords - 1) { printf("Line %d: This parameter needs %d argument(s) to be set.\n" , line , nbOfArguments(words[0])); exit(0); } checkArguments(line , nbWords , isNumber , nbDots , isTime , isDivide , isPow); if(! strcmp(subsection , "")) { if(nbParametersInSection == NBPARAMETERS) { printf("Line %d: Too many parameters in this section.\n" , line); exit(0); } strcpy(parametersInSection[nbParametersInSection] , words[0]); nbParametersInSection++; if(! strcmp(words[0] , "NAME")) { if(nbDeclaredWindows == NBWINDOWS) { puts("Too many windows are declared in this tutorial."); exit(0); } for(indexDeclaredWindow = 0 ; indexDeclaredWindow < nbDeclaredWindows ; indexDeclaredWindow++) { if(! strcmp(declaredWindows[indexDeclaredWindow] , words[1])) { printf("Line %d: A window with this name already exists.\n" , line); exit(0); } } strcpy(declaredWindows[nbDeclaredWindows] , words[1]); nbDeclaredWindows++; } } else { if(nbParametersInSubsection == NBPARAMETERS) { printf("Line %d: Too many parameters in this subsection.\n" , line); exit(0); } strcpy(parametersInSubsection[nbParametersInSubsection] , words[0]); nbParametersInSubsection++; } } /* If everything is OK this writes the line in the output file */ for(indexWord = 0 ; indexWord < nbWords ; indexWord++) { fputs(words[indexWord] , outputFile); if(indexWord == nbWords - 1) { fputc('\n' , outputFile); } else { fputc(' ' , outputFile); } } if(c == '\n') { line++; } else { break; } } else { break; } } } if(strcmp(section , "") || strcmp(subsection , "")) { printf("Line %d: End of section expected.\n" , line); exit(0); } /* Closes files */ close(inputFile); close(outputFile); /* Checks window connections */ for(indexDestinationWindow = 0 ; indexDestinationWindow < nbDestinationWindows ; indexDestinationWindow++) { for(indexDeclaredWindow = 0 ; indexDeclaredWindow < nbDeclaredWindows ; indexDeclaredWindow++) { if(! strcmp(declaredWindows[indexDeclaredWindow] , destinationWindows[indexDestinationWindow])) { break; } } if(indexDeclaredWindow == nbDeclaredWindows) { printf("The window called %s does not exist.\n" , destinationWindows[indexDestinationWindow]); exit(0); } } return 0; }