manager.c
1 /* Classic Ladder Project */ 2 /* Copyright (C) 2001 Marc Le Douarain */ 3 /* mavati@club-internet.fr */ 4 /* http://www.multimania.com/mavati/classicladder */ 5 /* August 2002 */ 6 /* ---------------------------- */ 7 /* Sections fonctions utilities */ 8 /* ---------------------------- */ 9 /* This library is free software; you can redistribute it and/or */ 10 /* modify it under the terms of the GNU Lesser General Public */ 11 /* License as published by the Free Software Foundation; either */ 12 /* version 2.1 of the License, or (at your option) any later version. */ 13 14 /* This library is distributed in the hope that it will be useful, */ 15 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 16 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 17 /* Lesser General Public License for more details. */ 18 19 /* You should have received a copy of the GNU Lesser General Public */ 20 /* License along with this library; if not, write to the Free Software */ 21 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ 22 #ifdef HAL_SUPPORT 23 #include "rtapi.h" 24 #include "rtapi_string.h" 25 #else 26 #include <string.h> 27 #endif 28 29 30 #include "classicladder.h" 31 #include "global.h" 32 #include "edit.h" 33 #include "manager.h" 34 35 void InitSections( void ) 36 { 37 StrSection * pSection; 38 int NumSec; 39 for ( NumSec=0; NumSec<NBR_SECTIONS; NumSec++ ) 40 { 41 pSection = &SectionArray[ NumSec ]; 42 pSection->Used = FALSE; 43 strcpy( pSection->Name, "" ); 44 pSection->Language = SECTION_IN_LADDER; 45 pSection->SubRoutineNumber = -1; 46 pSection->FirstRung = 0; 47 pSection->LastRung = 0; 48 pSection->SequentialPage = 0; 49 } 50 51 // we directly create one section in ladder... 52 // at least for compatibility with our old progs ! 53 pSection = &SectionArray[ 0 ]; 54 pSection->Used = TRUE; 55 strcpy( pSection->Name, "Prog1" ); 56 pSection->Language = SECTION_IN_LADDER; 57 pSection->SubRoutineNumber = -1; 58 pSection->FirstRung = 0; 59 pSection->LastRung = 0; 60 pSection->SequentialPage = 0; 61 } 62 63 int SearchSubRoutineWithItsNumber( int SubRoutineNbrToFind ) 64 { 65 StrSection * pSection; 66 int NumSec; 67 int Found = FALSE; 68 NumSec = 0; 69 do 70 { 71 pSection = &SectionArray[ NumSec ]; 72 if ( pSection->Used ) 73 { 74 if ( pSection->SubRoutineNumber==SubRoutineNbrToFind ) 75 Found = TRUE; 76 else 77 NumSec++; 78 } 79 else 80 { 81 NumSec++; 82 } 83 } 84 while( NumSec<NBR_SECTIONS && !Found ); 85 if ( Found ) 86 return NumSec; 87 else 88 return -1; 89 } 90 91 92 /* All the following stuff is not used for real-time working and embedded version... */ 93 #if !defined( __RTL__ ) && defined( GTK_INTERFACE ) 94 int SearchSectionWithName( char * SectionNameToFind ) 95 { 96 StrSection * pSection; 97 int NumSec; 98 int Found = FALSE; 99 NumSec = 0; 100 do 101 { 102 pSection = &SectionArray[ NumSec ]; 103 if ( pSection->Used ) 104 { 105 if ( strcmp( pSection->Name, SectionNameToFind )==0 ) 106 Found = TRUE; 107 else 108 NumSec++; 109 } 110 else 111 { 112 NumSec++; 113 } 114 } 115 while( NumSec<NBR_SECTIONS && !Found ); 116 if ( Found ) 117 return NumSec; 118 else 119 return -1; 120 } 121 122 void SectionSelected( char * SectionName ) 123 { 124 StrSection * pSection; 125 int NumSec = SearchSectionWithName( SectionName ); 126 if ( NumSec>=0 ) 127 { 128 pSection = &SectionArray[ NumSec ]; 129 InfosGene->FirstRung = pSection->FirstRung; 130 InfosGene->LastRung = pSection->LastRung; 131 InfosGene->CurrentRung = InfosGene->FirstRung; 132 133 InfosGene->CurrentSection = NumSec; 134 } 135 } 136 137 int AddSection( char * NewSectionName, int TypeLanguageSection, int SubRoutineNbr ) 138 { 139 StrSection * pSection; 140 int NumSec; 141 int FreeFound = FALSE; 142 // Search a free available section 143 NumSec = 0; 144 do 145 { 146 pSection = &SectionArray[ NumSec ]; 147 if ( !pSection->Used ) 148 FreeFound = TRUE; 149 else 150 NumSec++; 151 } 152 while( NumSec<NBR_SECTIONS && !FreeFound ); 153 if ( FreeFound ) 154 { 155 int NumFreeRung; 156 strcpy( pSection->Name, NewSectionName ); 157 pSection->Language = TypeLanguageSection; 158 pSection->FirstRung = 0; 159 pSection->LastRung = 0; 160 pSection->SequentialPage = 0; 161 if ( TypeLanguageSection==SECTION_IN_LADDER ) 162 { 163 pSection->SubRoutineNumber = SubRoutineNbr; 164 NumFreeRung = FindFreeRung( ); 165 if ( NumFreeRung>=0 ) 166 { 167 pSection->Used = TRUE; 168 pSection->FirstRung = NumFreeRung; 169 pSection->LastRung = NumFreeRung; 170 InitBufferRungEdited( &RungArray[ NumFreeRung ] ); 171 } 172 else 173 { 174 FreeFound = FALSE; 175 } 176 } 177 #ifdef SEQUENTIAL_SUPPORT 178 if ( TypeLanguageSection==SECTION_IN_SEQUENTIAL ) 179 { 180 int NumFreePage; 181 NumFreePage = FindFreeSequentialPage( ); 182 if ( NumFreePage>=0 ) 183 { 184 pSection->Used = TRUE; 185 pSection->SequentialPage = NumFreePage; 186 } 187 else 188 { 189 FreeFound = FALSE; 190 } 191 } 192 #endif 193 } 194 return FreeFound; 195 } 196 197 int NbrSectionsDefined( void ) 198 { 199 StrSection * pSection; 200 int NumSec; 201 int NbrSectionsDefined = 0; 202 for ( NumSec=0; NumSec<NBR_SECTIONS; NumSec++ ) 203 { 204 pSection = &SectionArray[ NumSec ]; 205 if ( pSection->Used ) 206 NbrSectionsDefined++; 207 } 208 return NbrSectionsDefined; 209 } 210 211 int VerifyIfSectionNameAlreadyExist( char * Name ) 212 { 213 int NumSec; 214 if ( Name[0]=='\0' ) 215 return TRUE; 216 NumSec = SearchSectionWithName( Name ); 217 return( NumSec>=0?TRUE:FALSE ); 218 } 219 220 int VerifyIfSubRoutineNumberExist( int SubRoutineNbr ) 221 { 222 int NumSec; 223 NumSec = SearchSubRoutineWithItsNumber( SubRoutineNbr ); 224 return( NumSec>=0?TRUE:FALSE ); 225 } 226 227 void DelSection( char * SectionNameToErase ) 228 { 229 StrSection * pSection; 230 int NumSec; 231 NumSec = SearchSectionWithName( SectionNameToErase ); 232 if ( NumSec>=0 ) 233 { 234 pSection = &SectionArray[ NumSec ]; 235 pSection->Used = FALSE; 236 // free the rungs used in this section 237 if ( pSection->Language==SECTION_IN_LADDER ) 238 { 239 int ScanRung = InfosGene->FirstRung; 240 while ( ScanRung!=InfosGene->LastRung ) 241 { 242 RungArray[ ScanRung ].Used = FALSE; 243 ScanRung = RungArray[ ScanRung ].NextRung; 244 } 245 RungArray[ InfosGene->LastRung ].Used = FALSE; 246 } 247 } 248 } 249 250 void SwapSections( char * SectionName1, char * SectionName2 ) 251 { 252 StrSection * pSection1; 253 StrSection * pSection2; 254 StrSection SectionTemp; 255 StrSection * pSectionTemp = &SectionTemp; 256 int NumSec1; 257 int NumSec2; 258 NumSec1 = SearchSectionWithName( SectionName1 ); 259 NumSec2 = SearchSectionWithName( SectionName2 ); 260 if ( NumSec1>=0 && NumSec2>=0 ) 261 { 262 pSection1 = &SectionArray[ NumSec1 ]; 263 pSection2 = &SectionArray[ NumSec2 ]; 264 265 memcpy( pSectionTemp, pSection1, sizeof(StrSection) ); 266 memcpy( pSection1, pSection2, sizeof(StrSection) ); 267 memcpy( pSection2, pSectionTemp, sizeof(StrSection) ); 268 } 269 } 270 271 #ifdef SEQUENTIAL_SUPPORT 272 int FindFreeSequentialPage( void ) 273 { 274 int FreePage = -1; 275 // to mark the pages used 276 char PageUsed[ NBR_SEQUENTIAL_PAGES ]; 277 int ScanPage; 278 int ScanSection; 279 StrSection * pSection; 280 for ( ScanPage=0; ScanPage<NBR_SEQUENTIAL_PAGES; ScanPage++ ) 281 PageUsed[ ScanPage ] = FALSE; 282 // scan each section and mark the pages used 283 for ( ScanSection=0; ScanSection<NBR_SECTIONS; ScanSection++ ) 284 { 285 pSection = &SectionArray[ ScanSection ]; 286 if ( pSection->Used ) 287 { 288 if ( pSection->Language==SECTION_IN_SEQUENTIAL ) 289 PageUsed[ pSection->SequentialPage ] = TRUE; 290 } 291 } 292 // find the first free page 293 ScanPage = 0; 294 do 295 { 296 if ( !PageUsed[ ScanPage ] ) 297 FreePage = ScanPage; 298 ScanPage++; 299 } 300 while( ScanPage<NBR_SEQUENTIAL_PAGES && FreePage==-1 ); 301 return FreePage; 302 } 303 #endif 304 305 #endif