1#!/bin/ch 2/* For creating Ch Ming 1.0, Feb 10, 2006 3 4 this script does the following: 5 + Copies headers from <MING_HOME>/src/include to ./chming/include subfolder 6 + Copies Ming DLLs to ./chming/bin subfolders 7 + Copies C/Ch samples from ./demos/ directory to ./chming/demos 8 + Generates *.h files in ./chfcreate/ directory, those files contain a 9 list of function prototypes for Ming. This list is based off of ming.h. 10 + Processes each function list with c2chf 11 + Moves *.chf files generated by c2chf to ./chming/lib subfolder and 12 *_chdl.c files to ./c subfolder 13 + Builds .dl files using Ch SDK and places them to ./chming/dl 14*/ 15 16#include <unistd.h> // for access() 17#include <dlfcn.h> // for dlopen() 18#include <chshell.h> // for chinfo() 19 20int addChdlHeader(char *headerfile, char *macro, char *chdlheader); 21int removeFuncProto(char *filename, char *funcname, int keepNum); 22int changeChfFiles(char *IncDir, char *LibDir); 23 24string_t pkgname="chming"; // define package name 25chinfo_t info; // for Ch version number 26string_t cwd = _cwd; // the current working directory 27string_t lib_header_dir; // library header files directory 28string_t debugFile; // compilation debug information in Windows 29string_t debug; 30string_t makecmd; 31int i; 32#if defined(_WIN32_) 33 debug=">nul 2>nul"; // surpress messages during cleaning in Windows 34 debugFile =">logfile 2>&1"; // compilation debug information in 'logfile' 35 makecmd = "nmake -f Makefile.win"; 36#else 37 makecmd = "make -f Makefile"; 38#endif 39 40 41//make sure pgkcreate.ch is run from the current working directory 42if(access("pkgcreate.ch", R_OK)) { 43 echo Run ./pkgcreate.ch in the current directory. 44 exit(-1); 45} 46// run this script in proper Ch version 47chinfo(&info); 48if ((info.vermajor*100+ info.verminor*10 + info.vermicro) < 501) { 49 echo "To run this script, you need to install Ch version 5.0.1.12201 or higher" 50 echo "You can download the latest version from http://www.softintegration.com/download" 51 exit(-1); 52} 53 54 55echo Cleaning up existing directories and create new ones ... 56if (!access(pkgname, F_OK)) 57 rm -rf $pkgname 58 59/* create directories */ 60echo create $pkgname directories 61mkdir $pkgname 62mkdir $pkgname/dl $pkgname/lib $pkgname/include $pkgname/demos $pkgname/bin 63if(access("chfcreate", R_OK)) { 64 mkdir chfcreate 65} 66 67echo Copying header files ... 68cp -f ../src/ming.h $pkgname/include 69cp -f ../src/ming_config.h $pkgname/include 70 71// if the original package doesn't have the modiciation for Ch 72if(`grep LOAD_CHDL $pkgname/include/ming.h` == NULL) 73{ 74 echo Adding LOAD_CHDL into ming.h ... 75 char *macro ="#define Ming_H"; 76 char *chdlheader = 77 "\n\n" 78 "#ifdef _CH_\n" 79 "#pragma package <chming> \n" 80 "#include <chdl.h> \n" 81 "LOAD_CHDL(ming); \n" 82 "#endif \n\n"; 83 addChdlHeader(stradd(pkgname, "/include/ming.h"), macro, chdlheader); 84} 85 86echo Copying demo programs ... 87cp -fr demos/* $pkgname/demos 88chmod 755 $pkgname/demos/*.c* 89if(!access(stradd(pkgname, "/demos/CVS"), R_OK)) { 90 rm -rf $pkgname/demos/CVS 91} 92 93//echo copying DLLs ... 94#if defined(_WIN32_) 95 //if there is dynamical library pkgname 96 cp -f ../bin/*.dll $pkgname/bin/ >nul 2>&1 97#endif 98 99/* ming function does not have a common return type */ 100echo Creating a header file containing all functions to export ... 101char *returnTypes[]={"int", "void", "float", 102 "SWFBlock", "SWFMatrix", "SWFInput", "SWFCharacter", "SWFDBLBitmap", 103 "SWFDBLBitmapData", "SWFJpegBitmap", "SWFJpegWithAlpha", "SWFGradient", 104 "SWFFillStyle", "SWFLineStyle", "SWFShape", "SWFMorph", "SWFFont", 105 "SWFText", "SWFBrowserFont", "SWFFontCharacter", "SWFTextField", 106 "SWFSoundStream", "SWFSound", "SWFSoundInstance", "SWFCXform", "SWFAction", 107 "SWFButton", "SWFSprite", "SWFPosition", "SWFDisplayItem", "SWFFill", 108 "SWFMovieClip", "SWFMovie", "SWFVideoStream", NULL}; 109 110char *fileName; 111rm -rf ./chfcreate/ming.h 112 113for(i=0;returnTypes[i]!=NULL;i++) 114{ 115 116 fileName = stradd("chfcreate/", returnTypes[i], ".h"); 117 processhfile(returnTypes[i], 1, ";", stradd(pkgname, "/include/ming.h"), 118 fileName, NULL); 119 cat $fileName >> ./chfcreate/ming.h 120 rm -rf $fileName 121} 122 123 124echo Removing duplicates in ming.h ... 125removeFuncProto("chfcreate/ming.h", "SWFSoundInstance_setNoMultiple", 1); 126 127echo Removing special function prototypes in ming.h ... 128/* depreceated */ 129removeFuncProto("chfcreate/ming.h", "SWFMovie_outputC", 0); 130/* have pointer to function*/ 131removeFuncProto("chfcreate/ming.h", "Ming_setWarnFunction", 0); 132removeFuncProto("chfcreate/ming.h", "Ming_setErrorFunction", 0); 133removeFuncProto("chfcreate/ming.h", "SWFMovie_output", 0); 134 135echo Generating ming_chdl.c in c/ directory and xxx.chf in $pkgname/lib ... 136c2chf chfcreate/ming.h -o c c -o chf $pkgname/lib 137 138echo Patching special .chf files ... 139cp -f chfhandmade/*.chf $pkgname/lib 140chmod 644 $pkgname/lib/*.chf 141 142echo Patching .chf files that return pointer to structure ... 143changeChfFiles("../src", stradd(pkgname, "/lib")); 144 145echo Building the dynamically loaded library ... 146cd c 147$makecmd clean $debug 148$makecmd $debugFile 149 150// go back to original directory 151cd $cwd 152 153echo Adding .DLL path and testing .dl file ... 154#pragma exec _path=stradd(_path, "chming/bin"); 155if (dlopen("c/libming.dl", RTLD_LAZY) == NULL) { 156 printf("Error: test of loading libming.dl: %s\n", dlerror()); 157 exit(-1); 158} 159 160mv -f c/libming.dl "$cwd/$pkgname/dl" 161 162echo package $pkgname created successfully! 163 164 165/******************************************************************* 166 * * This function will add the required preprocessing directives 167 * * needed by Ch to a header file. 168 * * headerfile: header file to be changed 169 * * macro: token to be recoganized for insertion of chdlheader 170 * * chdlheader: preprocessing directives to be inserted 171 * *******************************************************************/ 172int addChdlHeader(char *headerfile, char *macro, char *chdlheader) 173{ 174 char *stop_ptr; 175 string_t tempfile, token; 176 string_t result; 177 FILE *stream; 178 179 tempfile = ``cat $headerfile``; 180 token = strstr( tempfile, macro); 181 stop_ptr = strstr(token, "\n"); 182 strncpy(result, tempfile, strlen(tempfile)-strlen(stop_ptr)); 183 result=stradd(result, chdlheader); 184 result=stradd(result, stop_ptr); 185 if(!(stream = fopen("_tmpfile", "w"))) 186 { 187 perror("_tmpfile"); 188 return -1; 189 } 190 fprintf(stream, "%s", result); 191 fclose(stream); 192 mv -f _tmpfile $(headerfile) 193 return 0; 194} 195 196 197/************************************************************************* 198 * (C) Copyright 2005 SoftIntegration, Inc. 199 * This function is in public domain, use as it is without any warranty. 200 ************************************************************************** 201 * This function removes function prototypes such as 202 * int func1(int i); 203 * from a header file that has already been filtered through processhfile(). 204 * 205 * Argumnets: 206 * filename: name of the file to process 207 * funcname: function name to look for 208 * keepNum: if 0, remove all occurances of this prototype. 209 * if >0 , keep the keepNum desired funcname that is found. 210 * Example: 211 * removeFuncProto("chfcreate/test.h", "func1", 2); 212 * This will remove all instances except for the 2nd instance of the function, 213 * func1(), prototype that is found in the file chfcreate/test.h. 214 ***************************************************************/ 215#define LINESIZE 1024 216int removeFuncProto(char *filename, char *funcname, int keepNum) 217{ 218 char line[LINESIZE], *ptr; 219 string_t filenameout; 220 FILE *stream1, *stream2; 221 int num = 0; 222 223 /* Check to see if the funcname provided is NULL */ 224 if (funcname == NULL) 225 { 226 printf("Error: %s: Null funcname recieved.\n", __func__); 227 return -1; 228 } 229 230 /* Check for access to the file */ 231 if(!(stream1 = fopen(filename, "r"))) 232 { 233 printf("Error: %s: Unable to open '%s' for reading.\n", __func__, filename); 234 return -1; 235 } 236 237 filenameout = tmpnam(NULL); 238 /* Check for access to the file */ 239 if(!(stream2 = fopen(filenameout, "w"))) 240 { 241 printf("Error: %s: Unable to open '%s' for writing.\n", __func__, filenameout); 242 return -1; 243 } 244 245 fgets(line, LINESIZE , stream1); 246 while(!feof(stream1)) { 247 if(ptr = strstr(line, funcname)) { 248 if(*(ptr-1) == ' ' || *(ptr-1) == '\t' || /* find ' ' in "int' 'funcname();" */ 249 *(ptr-1) == '*') /* find * in "int *funcname();" */ 250 { 251 ptr += strlen(funcname); 252 while(*ptr == ' ') /* skip ' ' in "int funcname' '();" */ 253 { 254 ptr++; 255 } 256 if(*ptr == '(') { /* Find '(' in "int funcname();" */ 257 num++; 258 if(num != keepNum) { 259 while(!strchr(line, ';')) /* till find ';' in "int funcname();" */ 260 { 261 fgets(line, LINESIZE , stream1); 262 } 263 fgets(line, LINESIZE , stream1); 264 continue; 265 } 266 } 267 } 268 } 269 fputs(line, stream2); 270 fgets(line, LINESIZE , stream1); 271 } 272 fclose(stream1); 273 fclose(stream2); 274 /* Move the temperary file to the original file. */ 275 mv -f $filenameout $filename 276 return 0; 277} 278 279/******************************************************************* 280* This function will change the chf files so that they return 281* a NULL instead of a -1 when a pointer to structure is returned by the 282* function. 283* The list of known structures are normally provided in the ming.h 284* header file. 285* 286* IncDir: Directory where ming.h is located 287* LibDir: Directory where the chf files should be modified 288*******************************************************************/ 289int changeChfFiles(char *IncDir, char *LibDir) 290{ 291 string_t structList; 292 string_t tempStructList; 293 string_t tempStr; 294 string_t chfList; 295 string_t chfFile; 296 string_t output; 297 string_t workingDir; 298 char *chfFileName; 299 char *tempChrPtr; 300 char *test; 301 char *startChrPtr; 302 char *endChrPtr; 303 char *macro = "return -1;"; 304 char *mingHeaderLocation = stradd(IncDir, "/ming.h"); 305 FILE *fptr; 306 307 workingDir = _cwd; 308 309 if(access(mingHeaderLocation, R_OK)) 310 { 311 printf("Error: Unable to find '%s'.\n" 312 "Chf files will not be modified.\n", 313 mingHeaderLocation); 314 return -1; 315 } 316 317 if(access(LibDir, R_OK)) 318 { 319 printf("Error: Unable to find '%s'.\n" 320 "Chf files will not be modified.\n", 321 LibDir); 322 return -1; 323 } 324 325 tempStructList = `grep "typedef struct" $mingHeaderLocation`; 326 327 foreach(tempChrPtr; tempStructList; NULL; ";") 328 { 329 330 if( (tempChrPtr = strstr(tempChrPtr, "*")) == NULL) 331 { 332 continue; 333 } 334 335 tempChrPtr += 1; 336 endChrPtr = strstr(tempChrPtr, ";"); 337 338 strncpy(tempStr, tempChrPtr, strlen(tempChrPtr)-strlen(endChrPtr)); 339 structList = stradd(structList, tempStr, " "); 340 } 341 342#ifdef DEBUG 343 printf("%s\n", structList); 344#endif 345 346 cd $LibDir 347 348#ifdef DEBUG 349 printf("\tModifying Chf Files...\n"); 350#endif 351 352 foreach(tempChrPtr; structList; NULL; " ") 353 { 354 test = stradd(tempChrPtr, " retval"); 355 chfList = `grep -l "$test" *.chf`; 356 357#ifdef DEBUG 358 printf("looking for %s\n", tempChrPtr); 359 printf("%s\n", chfList); 360#endif 361 362 foreach(chfFileName; chfList; NULL; " ") 363 { 364 365#ifdef DEBUG 366 printf("testing file %s\n", chfFileName); 367#endif 368 369 chfFile = ``cat $chfFileName``; 370 371 if( (startChrPtr = strstr(chfFile, macro)) == NULL) 372 { 373 printf("\t%s not found in %s.\n", macro, chfFileName); 374 continue; 375 } 376 377 strncpy(output, chfFile, strlen(chfFile)-strlen(startChrPtr)); 378 startChrPtr += strlen(macro); 379 output = stradd(output, "return NULL;", startChrPtr); 380 381 fptr = fopen("temp12345.txt", "w"); 382 fprintf(fptr, "%s", output); 383 fclose(fptr); 384 mv -f temp12345.txt $chfFileName 385 } 386 } 387 388 cd $workingDir 389 390 return 0; 391} 392