| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- /*
- * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
- * http://www.trevorwishart.co.uk
- * http://www.composersdesktop.com
- *
- This file is part of the CDP System.
- The CDP System is free software; you can redistribute it
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The CDP System is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the CDP System; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <processno.h>
- #include <standalone.h>
- #define NUMBER_OF_GOBOS (41)
- #define ENDOFSTR ('\0')
- #define MAX_TEMPROC_AREA (288)
- #define MIN_TEMPROC_AREA (287)
- static int check_flags(char *str,int **flags,int max_gobos);
- static int check_progno(int *progno, int system_update);
- static int make_next_gobo_name_and_number(int *gobo_number, int *goboname_len, char **comp, char *pretext, int max_gobos);
- static int count_gobo_array_elements_in_first_gobo(char *gobo_line, char *comp, int progno, int new_element_cnt);
- static int altergobo(char **gobo_line,int existing_element_cnt,int make_new_array_element,int gobo_array_element,
- int gobo_element_mask,int substitute,int setval);
- static int count_gobo_array_elements(char *gobo_line);
- //TW UPDATE
- int deleter = 0;
- int substitute = 0;
- char pretext[] = "int "; /* text occuring before goboname, on gobo defining lines in gobo.c */
- const char* cdp_version = "7.1.0";
- int main(int argc, char *argv[])
- {
- FILE *fpi, *fpo;
- char *gobo_line, *comp;
- //TW UPDATE
- int gobo_number = 0, goboname_len = 10, setval = 0, *flags;
- int max_gobos = NUMBER_OF_GOBOS + 2;
- int finished_fixing_gobos = 0, progno;
- int gobo_array_element, gobo_array_element_index, gobo_element_mask, first_gobostring = 1;
- int existing_element_cnt = 0, new_element_cnt, make_new_array_element = 0;
- int system_update = 0;
-
- if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
- fprintf(stdout,"%s\n",cdp_version);
- fflush(stdout);
- return 0;
- }
- if(argc==4) {
- if(strcmp(argv[3],"SYSTEM_UPDATE")) {
- fprintf(stdout,"ERROR: Bad call to fixgobo.\n");
- fflush(stdout);
- exit(1);
- } else {
- system_update = 1;
- }
- } else if(argc!=3) {
- fprintf(stdout,"ERROR: Bad call to fixgobo.\n");
- fflush(stdout);
- exit(1);
- }
- if(sscanf(argv[2],"%d",&progno)!=1) {
- fprintf(stdout,"ERROR: Cannot read process number.\n");
- fflush(stdout);
- exit(1);
- }
- if((substitute = check_progno(&progno,system_update)) < 0)
- exit(1);
- if(check_flags(argv[1],&flags,max_gobos) < 0)
- exit(1);
- progno--; /* progs count from 1, gob flags indexed from 0 */
- gobo_array_element = progno/32;
- gobo_array_element_index = progno%32;
- progno++;
- gobo_element_mask = 1 << gobo_array_element_index;
- if((fpi = fopen("gobo.c","r"))==NULL) {
- fprintf(stdout,"ERROR: Cannot open the existing gobo file, to update it.\n");
- fflush(stdout);
- exit(1);
- }
- if((fpo = fopen("temp.c","w"))==NULL) {
- fprintf(stdout,"ERROR: Cannot open temporary file 'temp.c', to write revised gobo.\n");
- fclose(fpi);
- fflush(stdout);
- exit(1);
- }
- if((gobo_line = malloc(512 * sizeof(char)))==NULL) {
- fprintf(stdout,"ERROR: Out of memory to create gobo line store, in fixgobo.\n");
- fflush(stdout);
- exit(1);
- }
- if((comp = malloc(24 * sizeof(char)))==NULL) {
- fprintf(stdout,"ERROR: Out of memory to create gobo name comaparator, in fixgobo.\n");
- fflush(stdout);
- exit(1);
- }
- new_element_cnt = ((MAX_PROCESS_NO - 1)/32) + 1;
- make_next_gobo_name_and_number(&gobo_number,&goboname_len,&comp,pretext,max_gobos);
- setval = flags[gobo_number];
- while(fgets(gobo_line,200,fpi)!=NULL) {
- if(!finished_fixing_gobos && !strncmp(gobo_line,comp,goboname_len)) {
- if(first_gobostring) {
- existing_element_cnt = count_gobo_array_elements_in_first_gobo(gobo_line,comp,progno,new_element_cnt);
- if(existing_element_cnt <= 0)
- exit(1);
- if(new_element_cnt > existing_element_cnt)
- make_new_array_element = 1;
- first_gobostring = 0;
- } else if(count_gobo_array_elements(gobo_line) != existing_element_cnt) {
- fprintf(stdout, "ERROR: Anomalous count of array members in gobo %s.\n",comp);
- fflush(stdout);
- exit(1);
- }
- if(!altergobo
- (&gobo_line,existing_element_cnt,make_new_array_element,gobo_array_element,gobo_element_mask,substitute,setval)) {
- exit(1);
- }
- if(fputs(gobo_line,fpo)==EOF) {
- fprintf(stdout,"ERROR: Failed to write new line of gobo data to the new temporary file.\n");
- fflush(stdout);
- exit(1);
- }
- finished_fixing_gobos = make_next_gobo_name_and_number(&gobo_number,&goboname_len,&comp,pretext,max_gobos);
- setval = flags[gobo_number];
- } else {
- if(fputs(gobo_line,fpo)==EOF) {
- fprintf(stdout,"ERROR: Failed to write original line of gobo data to the new temporary file.\n");
- fflush(stdout);
- exit(1);
- }
- }
- }
- fclose(fpi);
- fclose(fpo);
- fprintf(stdout,"END: \n");
- fflush(stdout);
- return 0;
- }
- /*********************************** COUNT_GOBO_ARRAY_ELEMENTS ******************************/
- int count_gobo_array_elements(char *gobo_line)
- {
- char *p;
- int existing_element_cnt = 0, OK = 0;
- p = gobo_line;
- while(*p != '{') { /* search for start of array */
- p++;
- if(*p==ENDOFSTR) {
- fprintf(stdout,"ERROR: Failed to find gobo array in string.\n");
- fflush(stdout);
- return(0);
- }
- }
- p++;
- while(isspace(*p))
- p++; /* check for inappropriate end of array */
- if(*p=='}') {
- fprintf(stdout,"ERROR: First gobo array is empty.\n");
- fflush(stdout);
- return(0);
- }
- while(*p != '}') { /* until array end is found */
- if(isdigit(*p))
- OK = 1; /* check that each array element contains numeric data */
- if(*p == ',') { /* count array elements, by counting separating commas */
- existing_element_cnt++;
- if(!OK) {
- fprintf(stdout,"ERROR: First-gobo array-element %d is missing.\n",existing_element_cnt);
- fflush(stdout);
- return(0);
- }
- OK = 0;
- }
- p++;
- if(*p==ENDOFSTR) {
- fprintf(stdout,"ERROR: Failed to find gobo element in array, in string.\n");
- fflush(stdout);
- return(0);
- }
- }
- existing_element_cnt++; /* count last array elements */
- if(!OK) { /* and check that it contains numeric data */
- fprintf(stdout,"ERROR: First-gobo, last array-element is missing.\n");
- fflush(stdout);
- return(0);
- }
- return(existing_element_cnt);
- }
- /*********************************** ALTERGOBO ******************************/
- int altergobo
- (char **gobo_line,int existing_element_cnt,int make_new_array_element,
- int gobo_array_element,int gobo_element_mask,int substitute, int setval)
- {
- char *p, *gobo_pointer, gobo_string[24], end_part[512];
- int goboval, n, zero_mask;
- p = *gobo_line;
- while(*p != '{') { /* search for start of array */
- p++;
- if(*p==ENDOFSTR) {
- fprintf(stdout,"ERROR: Failed to find gobo array in string.\n");
- fflush(stdout);
- return(0);
- }
- } /* CREATING NEW ARRAY ELEMENT */
- if(make_new_array_element) {
- while(*p != '}') { /* search for end of array */
- p++;
- if(*p==ENDOFSTR) {
- fprintf(stdout,"ERROR: Failed to find gobo array in string.\n");
- fflush(stdout);
- return(0);
- }
- }
- strcpy(end_part,p); /* store characters at end of array */
- *p++ = ','; /* enter new separating comma */
- *p = ENDOFSTR; /* cut array at this point */
- goboval = 0; /* PRESET NEW ARRAY ELEMENT TO 0 */
- //TW UPDATE
- if(!deleter && (setval==1)) /* put in value 1, only if flag set */
- goboval |= gobo_element_mask;
- /* & store the new value in a string */
- sprintf(gobo_string,"%d",goboval);
- } else { /* ELSE, SUBSTITUTING NEW VALUE IN EXISTING LOCATION */
- if(gobo_array_element>0) {
- for(n=0;n<gobo_array_element;n++) {
- while(*p != ',') { /* search for the array element by counting separating commas */
- p++;
- if(*p==ENDOFSTR || *p == '}') {
- fprintf(stdout,"ERROR: Failed to find gobo element in array, in string.\n");
- fflush(stdout);
- return(0);
- }
- }
- p++;
- }
- } else
- p++;
- gobo_pointer = p; /* point to the start of the array element wanted */
-
- if(gobo_array_element == existing_element_cnt-1) {
- while(*p != '}') { /* if we're working on the last element in the array */
- p++; /* look for the array end */
- if(*p==ENDOFSTR) {
- fprintf(stdout,"ERROR: Failed to find last gobo element in array, in string.\n");
- fflush(stdout);
- return(0);
- }
- }
- } else { /* else */
- while(*p != ',') { /* look for the next separating comma */
- p++;
- if(*p==ENDOFSTR || *p == '}') {
- fprintf(stdout,"ERROR: Failed to find gobo element in array, in string.\n");
- fflush(stdout);
- return(0);
- }
- }
- }
- strcpy(end_part,p); /* keep the remaining characters of the array */
- *p = ENDOFSTR; /* cut the array at this point */
- /* read the existing array element */
- if(sscanf(gobo_pointer,"%d",&goboval)!=1) {
- fprintf(stdout,"ERROR: Failed to read value of existing gobo element in array %s, in string.\n",gobo_pointer);
- fflush(stdout);
- return(0);
- }
- *gobo_pointer = ENDOFSTR;
- /* If existing value to be changed */
- if(substitute) { /* zero the value at gobo_element_mask position */
- zero_mask = ~gobo_element_mask;
- goboval &= zero_mask;
- } /* put in value 1, only if flag set */
- if(!deleter && (setval==1)) /* & store the new value in a string */
- goboval |= gobo_element_mask;
- sprintf(gobo_string,"%d",goboval);
- }
- strcat(*gobo_line,gobo_string); /* put new value on end of (cut) original string */
- strcat(*gobo_line,end_part); /* replace end characters of array, at end of string */
- return(1);
- }
- /******************************** COUNT_GOBO_ARRAY_ELEMENTS_IN_FIRST_GOBO ******************************/
- int count_gobo_array_elements_in_first_gobo(char *gobo_line, char *comp, int progno, int new_element_cnt)
- {
- int existing_element_cnt, next_available_progno;
- if((existing_element_cnt = count_gobo_array_elements(gobo_line))<=0)
- return(0);
- if(new_element_cnt > existing_element_cnt) {
- if(new_element_cnt > existing_element_cnt + 1) {
- fprintf(stdout,
- "ERROR: MAX_PROCESS_NO is TOO HIGH to tally with the existing gobo count in gobo %s.\n",comp);
- fflush(stdout);
- return(0);
- }
- next_available_progno = ((new_element_cnt - 1) * 32) + 1;
- if(progno < next_available_progno) {
- fprintf(stdout,
- "ERROR: MAX_PROCESS_NO is TOO HIGH to tally with the existing gobo count in gobo %s.\n",comp);
- return(0);
- }
- if(progno > next_available_progno) {
- fprintf(stdout,
- "ERROR: The process-number being entered creates a gap in numbering of processes on the system.\n");
- fflush(stdout);
- return(0);
- }
- } else if(new_element_cnt < existing_element_cnt) {
- fprintf(stdout,
- "ERROR: new_element_cnt %d existing_element_cnt %d\n",new_element_cnt,existing_element_cnt);
- fprintf(stdout,
- "ERROR: MAX_PROCESS_NO is TOO LOW to tally with the existing gobo count in gobo %s.\n",comp);
- fflush(stdout);
- return(0);
- }
- return(existing_element_cnt);
- }
- /******************************** MAKE_NEXT_GOBO_NAME_AND_NUMBER ******************************/
- int make_next_gobo_name_and_number(int *gobo_number, int *goboname_len, char **comp, char *pretext, int max_gobos)
- {
- int finished_fixing_gobos = 0;
- char num[4];
- (*gobo_number)++;
- (*comp)[0] = ENDOFSTR;
- strcat(*comp,pretext);
- strcat(*comp,"gobo");
- if(*gobo_number == max_gobos-1) {
- *goboname_len +=2;
- strcat(*comp,"_any");
- } else if(*gobo_number == max_gobos) {
- strcat(*comp,"zero");
- } else if(*gobo_number > max_gobos) {
- finished_fixing_gobos = 1;
- } else {
- if(*gobo_number == 10)
- (*goboname_len)++;
- sprintf(num,"%d",*gobo_number);
- strcat(*comp,num);
- }
- return finished_fixing_gobos;
- }
- /******************************** CHECK_PROGNO ******************************/
- int check_progno(int *progno, int system_update)
- {
- // int is_new = 0;
- if(system_update) {
- /* TEST */
- if(*progno == 0) {
- *progno = MAX_PROCESS_NO;
- //TW UPDATES
- 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);
- fprintf(stdout,"INFO: If you do not do this, the gobo data for program %d will be overwritten!!\n",MAX_PROCESS_NO);
- fflush(stdout);
- // is_new = 1;
- }
- // if((*progno >= MIN_TEMPROC_AREA) && (*progno <= MAX_TEMPROC_AREA)) {
- // if(is_new)
- // fprintf(stdout,"ERROR: Invalid MAX_PROCESS_NO for new system processes.\n");
- // else
- // fprintf(stdout,"ERROR: Invalid process number for new system processes.\n");
- // fprintf(stdout,"Cannot be between %d and %d inclusive\n",MIN_TEMPROC_AREA,MAX_TEMPROC_AREA);
- // fprintf(stdout,"as these are reserved for private user processes.\n");
- // fflush(stdout);
- // return(-1);
- // } else
- if(*progno > MAX_PROCESS_NO) {
- fprintf(stdout,"ERROR: The process number entered is above MAX_PROCESS_NO\n");
- fflush(stdout);
- return(-1);
- //TW UPDATE
- } else if(*progno <= MAX_PROCESS_NO) {
- fprintf(stdout,"WARNING: REDEFINING THE GOBO FOR AN EXISTING PROCESS.\n");
- fflush(stdout);
- return(1);
- }
- } else {
- if(*progno == 0) {
- *progno = MAX_TEMP_PROCESS_NO;
- // is_new = 1;
- }
- // if((*progno > MAX_TEMPROC_AREA) || (*progno < MIN_TEMPROC_AREA)) {
- // if(is_new)
- // fprintf(stdout,"ERROR: Invalid MAX_TEMP_PROCESS_NO for new processes.\n");
- // else
- // fprintf(stdout,"ERROR: Invalid process number for new processes.\n");
- // fprintf(stdout,"Private user processes must lie between %d and %d\n",MIN_TEMPROC_AREA,MAX_TEMPROC_AREA);
- // fprintf(stdout,"If you have run out of space for new processes,\n");
- // fprintf(stdout,"perhaps you should install some of them as common CDP system processes\n");
- // fprintf(stdout,"by contacting the CDP.\n");
- // fflush(stdout);
- // return(-1);
- // } else
- if(*progno < MAX_TEMP_PROCESS_NO) {
- fprintf(stdout,"WARNING: OVERWRITING AN EXISTING PROCESS.\n");
- fflush(stdout);
- return(1);
- }
- }
- return(0);
- }
- /******************************** CHECK_FLAGS ******************************/
- int check_flags(char *str,int **flags,int max_gobos)
- {
- char *p;
- int n;
- //TW UPDATE
- if(!strcmp(str,"0")) {
- deleter = 1;
- } else if(strlen(str) != (unsigned int)max_gobos) {
- fprintf(stdout,"ERROR: Bad data string sent to fixgobo.\n");
- fflush(stdout);
- return(-1);
- }
- if((*flags = malloc((max_gobos+2) * sizeof(int)))==NULL) {
- fprintf(stdout,"ERROR: Out of memory to store flags, in fixgobo.\n");
- fflush(stdout);
- return(-1);
- }
- p = str;
- for(n=1;n<=max_gobos;n++) {
- switch(*p) {
- case('0'): (*flags)[n] = 0; break;
- case('1'): (*flags)[n] = 1; break;
- default:
- fprintf(stdout,"ERROR: Bad character (ascii %d) in gobo-flag string sent to fixgobo.\n",*p);
- fflush(stdout);
- return(-1);
- }
- //TW UPDATE
- if(!deleter)
- p++;
- }
- return(1);
- }
|