fixgobo.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <processno.h>
  26. #include <standalone.h>
  27. #define NUMBER_OF_GOBOS (41)
  28. #define ENDOFSTR ('\0')
  29. #define MAX_TEMPROC_AREA (288)
  30. #define MIN_TEMPROC_AREA (287)
  31. static int check_flags(char *str,int **flags,int max_gobos);
  32. static int check_progno(int *progno, int system_update);
  33. static int make_next_gobo_name_and_number(int *gobo_number, int *goboname_len, char **comp, char *pretext, int max_gobos);
  34. static int count_gobo_array_elements_in_first_gobo(char *gobo_line, char *comp, int progno, int new_element_cnt);
  35. static int altergobo(char **gobo_line,int existing_element_cnt,int make_new_array_element,int gobo_array_element,
  36. int gobo_element_mask,int substitute,int setval);
  37. static int count_gobo_array_elements(char *gobo_line);
  38. //TW UPDATE
  39. int deleter = 0;
  40. int substitute = 0;
  41. char pretext[] = "int "; /* text occuring before goboname, on gobo defining lines in gobo.c */
  42. const char* cdp_version = "7.1.0";
  43. int main(int argc, char *argv[])
  44. {
  45. FILE *fpi, *fpo;
  46. char *gobo_line, *comp;
  47. //TW UPDATE
  48. int gobo_number = 0, goboname_len = 10, setval = 0, *flags;
  49. int max_gobos = NUMBER_OF_GOBOS + 2;
  50. int finished_fixing_gobos = 0, progno;
  51. int gobo_array_element, gobo_array_element_index, gobo_element_mask, first_gobostring = 1;
  52. int existing_element_cnt = 0, new_element_cnt, make_new_array_element = 0;
  53. int system_update = 0;
  54. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  55. fprintf(stdout,"%s\n",cdp_version);
  56. fflush(stdout);
  57. return 0;
  58. }
  59. if(argc==4) {
  60. if(strcmp(argv[3],"SYSTEM_UPDATE")) {
  61. fprintf(stdout,"ERROR: Bad call to fixgobo.\n");
  62. fflush(stdout);
  63. exit(1);
  64. } else {
  65. system_update = 1;
  66. }
  67. } else if(argc!=3) {
  68. fprintf(stdout,"ERROR: Bad call to fixgobo.\n");
  69. fflush(stdout);
  70. exit(1);
  71. }
  72. if(sscanf(argv[2],"%d",&progno)!=1) {
  73. fprintf(stdout,"ERROR: Cannot read process number.\n");
  74. fflush(stdout);
  75. exit(1);
  76. }
  77. if((substitute = check_progno(&progno,system_update)) < 0)
  78. exit(1);
  79. if(check_flags(argv[1],&flags,max_gobos) < 0)
  80. exit(1);
  81. progno--; /* progs count from 1, gob flags indexed from 0 */
  82. gobo_array_element = progno/32;
  83. gobo_array_element_index = progno%32;
  84. progno++;
  85. gobo_element_mask = 1 << gobo_array_element_index;
  86. if((fpi = fopen("gobo.c","r"))==NULL) {
  87. fprintf(stdout,"ERROR: Cannot open the existing gobo file, to update it.\n");
  88. fflush(stdout);
  89. exit(1);
  90. }
  91. if((fpo = fopen("temp.c","w"))==NULL) {
  92. fprintf(stdout,"ERROR: Cannot open temporary file 'temp.c', to write revised gobo.\n");
  93. fclose(fpi);
  94. fflush(stdout);
  95. exit(1);
  96. }
  97. if((gobo_line = malloc(512 * sizeof(char)))==NULL) {
  98. fprintf(stdout,"ERROR: Out of memory to create gobo line store, in fixgobo.\n");
  99. fflush(stdout);
  100. exit(1);
  101. }
  102. if((comp = malloc(24 * sizeof(char)))==NULL) {
  103. fprintf(stdout,"ERROR: Out of memory to create gobo name comaparator, in fixgobo.\n");
  104. fflush(stdout);
  105. exit(1);
  106. }
  107. new_element_cnt = ((MAX_PROCESS_NO - 1)/32) + 1;
  108. make_next_gobo_name_and_number(&gobo_number,&goboname_len,&comp,pretext,max_gobos);
  109. setval = flags[gobo_number];
  110. while(fgets(gobo_line,200,fpi)!=NULL) {
  111. if(!finished_fixing_gobos && !strncmp(gobo_line,comp,goboname_len)) {
  112. if(first_gobostring) {
  113. existing_element_cnt = count_gobo_array_elements_in_first_gobo(gobo_line,comp,progno,new_element_cnt);
  114. if(existing_element_cnt <= 0)
  115. exit(1);
  116. if(new_element_cnt > existing_element_cnt)
  117. make_new_array_element = 1;
  118. first_gobostring = 0;
  119. } else if(count_gobo_array_elements(gobo_line) != existing_element_cnt) {
  120. fprintf(stdout, "ERROR: Anomalous count of array members in gobo %s.\n",comp);
  121. fflush(stdout);
  122. exit(1);
  123. }
  124. if(!altergobo
  125. (&gobo_line,existing_element_cnt,make_new_array_element,gobo_array_element,gobo_element_mask,substitute,setval)) {
  126. exit(1);
  127. }
  128. if(fputs(gobo_line,fpo)==EOF) {
  129. fprintf(stdout,"ERROR: Failed to write new line of gobo data to the new temporary file.\n");
  130. fflush(stdout);
  131. exit(1);
  132. }
  133. finished_fixing_gobos = make_next_gobo_name_and_number(&gobo_number,&goboname_len,&comp,pretext,max_gobos);
  134. setval = flags[gobo_number];
  135. } else {
  136. if(fputs(gobo_line,fpo)==EOF) {
  137. fprintf(stdout,"ERROR: Failed to write original line of gobo data to the new temporary file.\n");
  138. fflush(stdout);
  139. exit(1);
  140. }
  141. }
  142. }
  143. fclose(fpi);
  144. fclose(fpo);
  145. fprintf(stdout,"END: \n");
  146. fflush(stdout);
  147. return 0;
  148. }
  149. /*********************************** COUNT_GOBO_ARRAY_ELEMENTS ******************************/
  150. int count_gobo_array_elements(char *gobo_line)
  151. {
  152. char *p;
  153. int existing_element_cnt = 0, OK = 0;
  154. p = gobo_line;
  155. while(*p != '{') { /* search for start of array */
  156. p++;
  157. if(*p==ENDOFSTR) {
  158. fprintf(stdout,"ERROR: Failed to find gobo array in string.\n");
  159. fflush(stdout);
  160. return(0);
  161. }
  162. }
  163. p++;
  164. while(isspace(*p))
  165. p++; /* check for inappropriate end of array */
  166. if(*p=='}') {
  167. fprintf(stdout,"ERROR: First gobo array is empty.\n");
  168. fflush(stdout);
  169. return(0);
  170. }
  171. while(*p != '}') { /* until array end is found */
  172. if(isdigit(*p))
  173. OK = 1; /* check that each array element contains numeric data */
  174. if(*p == ',') { /* count array elements, by counting separating commas */
  175. existing_element_cnt++;
  176. if(!OK) {
  177. fprintf(stdout,"ERROR: First-gobo array-element %d is missing.\n",existing_element_cnt);
  178. fflush(stdout);
  179. return(0);
  180. }
  181. OK = 0;
  182. }
  183. p++;
  184. if(*p==ENDOFSTR) {
  185. fprintf(stdout,"ERROR: Failed to find gobo element in array, in string.\n");
  186. fflush(stdout);
  187. return(0);
  188. }
  189. }
  190. existing_element_cnt++; /* count last array elements */
  191. if(!OK) { /* and check that it contains numeric data */
  192. fprintf(stdout,"ERROR: First-gobo, last array-element is missing.\n");
  193. fflush(stdout);
  194. return(0);
  195. }
  196. return(existing_element_cnt);
  197. }
  198. /*********************************** ALTERGOBO ******************************/
  199. int altergobo
  200. (char **gobo_line,int existing_element_cnt,int make_new_array_element,
  201. int gobo_array_element,int gobo_element_mask,int substitute, int setval)
  202. {
  203. char *p, *gobo_pointer, gobo_string[24], end_part[512];
  204. int goboval, n, zero_mask;
  205. p = *gobo_line;
  206. while(*p != '{') { /* search for start of array */
  207. p++;
  208. if(*p==ENDOFSTR) {
  209. fprintf(stdout,"ERROR: Failed to find gobo array in string.\n");
  210. fflush(stdout);
  211. return(0);
  212. }
  213. } /* CREATING NEW ARRAY ELEMENT */
  214. if(make_new_array_element) {
  215. while(*p != '}') { /* search for end of array */
  216. p++;
  217. if(*p==ENDOFSTR) {
  218. fprintf(stdout,"ERROR: Failed to find gobo array in string.\n");
  219. fflush(stdout);
  220. return(0);
  221. }
  222. }
  223. strcpy(end_part,p); /* store characters at end of array */
  224. *p++ = ','; /* enter new separating comma */
  225. *p = ENDOFSTR; /* cut array at this point */
  226. goboval = 0; /* PRESET NEW ARRAY ELEMENT TO 0 */
  227. //TW UPDATE
  228. if(!deleter && (setval==1)) /* put in value 1, only if flag set */
  229. goboval |= gobo_element_mask;
  230. /* & store the new value in a string */
  231. sprintf(gobo_string,"%d",goboval);
  232. } else { /* ELSE, SUBSTITUTING NEW VALUE IN EXISTING LOCATION */
  233. if(gobo_array_element>0) {
  234. for(n=0;n<gobo_array_element;n++) {
  235. while(*p != ',') { /* search for the array element by counting separating commas */
  236. p++;
  237. if(*p==ENDOFSTR || *p == '}') {
  238. fprintf(stdout,"ERROR: Failed to find gobo element in array, in string.\n");
  239. fflush(stdout);
  240. return(0);
  241. }
  242. }
  243. p++;
  244. }
  245. } else
  246. p++;
  247. gobo_pointer = p; /* point to the start of the array element wanted */
  248. if(gobo_array_element == existing_element_cnt-1) {
  249. while(*p != '}') { /* if we're working on the last element in the array */
  250. p++; /* look for the array end */
  251. if(*p==ENDOFSTR) {
  252. fprintf(stdout,"ERROR: Failed to find last gobo element in array, in string.\n");
  253. fflush(stdout);
  254. return(0);
  255. }
  256. }
  257. } else { /* else */
  258. while(*p != ',') { /* look for the next separating comma */
  259. p++;
  260. if(*p==ENDOFSTR || *p == '}') {
  261. fprintf(stdout,"ERROR: Failed to find gobo element in array, in string.\n");
  262. fflush(stdout);
  263. return(0);
  264. }
  265. }
  266. }
  267. strcpy(end_part,p); /* keep the remaining characters of the array */
  268. *p = ENDOFSTR; /* cut the array at this point */
  269. /* read the existing array element */
  270. if(sscanf(gobo_pointer,"%d",&goboval)!=1) {
  271. fprintf(stdout,"ERROR: Failed to read value of existing gobo element in array %s, in string.\n",gobo_pointer);
  272. fflush(stdout);
  273. return(0);
  274. }
  275. *gobo_pointer = ENDOFSTR;
  276. /* If existing value to be changed */
  277. if(substitute) { /* zero the value at gobo_element_mask position */
  278. zero_mask = ~gobo_element_mask;
  279. goboval &= zero_mask;
  280. } /* put in value 1, only if flag set */
  281. if(!deleter && (setval==1)) /* & store the new value in a string */
  282. goboval |= gobo_element_mask;
  283. sprintf(gobo_string,"%d",goboval);
  284. }
  285. strcat(*gobo_line,gobo_string); /* put new value on end of (cut) original string */
  286. strcat(*gobo_line,end_part); /* replace end characters of array, at end of string */
  287. return(1);
  288. }
  289. /******************************** COUNT_GOBO_ARRAY_ELEMENTS_IN_FIRST_GOBO ******************************/
  290. int count_gobo_array_elements_in_first_gobo(char *gobo_line, char *comp, int progno, int new_element_cnt)
  291. {
  292. int existing_element_cnt, next_available_progno;
  293. if((existing_element_cnt = count_gobo_array_elements(gobo_line))<=0)
  294. return(0);
  295. if(new_element_cnt > existing_element_cnt) {
  296. if(new_element_cnt > existing_element_cnt + 1) {
  297. fprintf(stdout,
  298. "ERROR: MAX_PROCESS_NO is TOO HIGH to tally with the existing gobo count in gobo %s.\n",comp);
  299. fflush(stdout);
  300. return(0);
  301. }
  302. next_available_progno = ((new_element_cnt - 1) * 32) + 1;
  303. if(progno < next_available_progno) {
  304. fprintf(stdout,
  305. "ERROR: MAX_PROCESS_NO is TOO HIGH to tally with the existing gobo count in gobo %s.\n",comp);
  306. return(0);
  307. }
  308. if(progno > next_available_progno) {
  309. fprintf(stdout,
  310. "ERROR: The process-number being entered creates a gap in numbering of processes on the system.\n");
  311. fflush(stdout);
  312. return(0);
  313. }
  314. } else if(new_element_cnt < existing_element_cnt) {
  315. fprintf(stdout,
  316. "ERROR: new_element_cnt %d existing_element_cnt %d\n",new_element_cnt,existing_element_cnt);
  317. fprintf(stdout,
  318. "ERROR: MAX_PROCESS_NO is TOO LOW to tally with the existing gobo count in gobo %s.\n",comp);
  319. fflush(stdout);
  320. return(0);
  321. }
  322. return(existing_element_cnt);
  323. }
  324. /******************************** MAKE_NEXT_GOBO_NAME_AND_NUMBER ******************************/
  325. int make_next_gobo_name_and_number(int *gobo_number, int *goboname_len, char **comp, char *pretext, int max_gobos)
  326. {
  327. int finished_fixing_gobos = 0;
  328. char num[4];
  329. (*gobo_number)++;
  330. (*comp)[0] = ENDOFSTR;
  331. strcat(*comp,pretext);
  332. strcat(*comp,"gobo");
  333. if(*gobo_number == max_gobos-1) {
  334. *goboname_len +=2;
  335. strcat(*comp,"_any");
  336. } else if(*gobo_number == max_gobos) {
  337. strcat(*comp,"zero");
  338. } else if(*gobo_number > max_gobos) {
  339. finished_fixing_gobos = 1;
  340. } else {
  341. if(*gobo_number == 10)
  342. (*goboname_len)++;
  343. sprintf(num,"%d",*gobo_number);
  344. strcat(*comp,num);
  345. }
  346. return finished_fixing_gobos;
  347. }
  348. /******************************** CHECK_PROGNO ******************************/
  349. int check_progno(int *progno, int system_update)
  350. {
  351. // int is_new = 0;
  352. if(system_update) {
  353. /* TEST */
  354. if(*progno == 0) {
  355. *progno = MAX_PROCESS_NO;
  356. //TW UPDATES
  357. fprintf(stdout,"INFO: using the value %d for the MAX_PROCESS_NO: If this is incorrect, recompile fixgobo, and start again.\n",MAX_PROCESS_NO);
  358. fprintf(stdout,"INFO: If you do not do this, the gobo data for program %d will be overwritten!!\n",MAX_PROCESS_NO);
  359. fflush(stdout);
  360. // is_new = 1;
  361. }
  362. // if((*progno >= MIN_TEMPROC_AREA) && (*progno <= MAX_TEMPROC_AREA)) {
  363. // if(is_new)
  364. // fprintf(stdout,"ERROR: Invalid MAX_PROCESS_NO for new system processes.\n");
  365. // else
  366. // fprintf(stdout,"ERROR: Invalid process number for new system processes.\n");
  367. // fprintf(stdout,"Cannot be between %d and %d inclusive\n",MIN_TEMPROC_AREA,MAX_TEMPROC_AREA);
  368. // fprintf(stdout,"as these are reserved for private user processes.\n");
  369. // fflush(stdout);
  370. // return(-1);
  371. // } else
  372. if(*progno > MAX_PROCESS_NO) {
  373. fprintf(stdout,"ERROR: The process number entered is above MAX_PROCESS_NO\n");
  374. fflush(stdout);
  375. return(-1);
  376. //TW UPDATE
  377. } else if(*progno <= MAX_PROCESS_NO) {
  378. fprintf(stdout,"WARNING: REDEFINING THE GOBO FOR AN EXISTING PROCESS.\n");
  379. fflush(stdout);
  380. return(1);
  381. }
  382. } else {
  383. if(*progno == 0) {
  384. *progno = MAX_TEMP_PROCESS_NO;
  385. // is_new = 1;
  386. }
  387. // if((*progno > MAX_TEMPROC_AREA) || (*progno < MIN_TEMPROC_AREA)) {
  388. // if(is_new)
  389. // fprintf(stdout,"ERROR: Invalid MAX_TEMP_PROCESS_NO for new processes.\n");
  390. // else
  391. // fprintf(stdout,"ERROR: Invalid process number for new processes.\n");
  392. // fprintf(stdout,"Private user processes must lie between %d and %d\n",MIN_TEMPROC_AREA,MAX_TEMPROC_AREA);
  393. // fprintf(stdout,"If you have run out of space for new processes,\n");
  394. // fprintf(stdout,"perhaps you should install some of them as common CDP system processes\n");
  395. // fprintf(stdout,"by contacting the CDP.\n");
  396. // fflush(stdout);
  397. // return(-1);
  398. // } else
  399. if(*progno < MAX_TEMP_PROCESS_NO) {
  400. fprintf(stdout,"WARNING: OVERWRITING AN EXISTING PROCESS.\n");
  401. fflush(stdout);
  402. return(1);
  403. }
  404. }
  405. return(0);
  406. }
  407. /******************************** CHECK_FLAGS ******************************/
  408. int check_flags(char *str,int **flags,int max_gobos)
  409. {
  410. char *p;
  411. int n;
  412. //TW UPDATE
  413. if(!strcmp(str,"0")) {
  414. deleter = 1;
  415. } else if(strlen(str) != (unsigned int)max_gobos) {
  416. fprintf(stdout,"ERROR: Bad data string sent to fixgobo.\n");
  417. fflush(stdout);
  418. return(-1);
  419. }
  420. if((*flags = malloc((max_gobos+2) * sizeof(int)))==NULL) {
  421. fprintf(stdout,"ERROR: Out of memory to store flags, in fixgobo.\n");
  422. fflush(stdout);
  423. return(-1);
  424. }
  425. p = str;
  426. for(n=1;n<=max_gobos;n++) {
  427. switch(*p) {
  428. case('0'): (*flags)[n] = 0; break;
  429. case('1'): (*flags)[n] = 1; break;
  430. default:
  431. fprintf(stdout,"ERROR: Bad character (ascii %d) in gobo-flag string sent to fixgobo.\n",*p);
  432. fflush(stdout);
  433. return(-1);
  434. }
  435. //TW UPDATE
  436. if(!deleter)
  437. p++;
  438. }
  439. return(1);
  440. }