/* * ebsmod.c * $Id: ebsmod.c,v 1.3 1993/10/27 20:14:21 mskuhn Exp $ */ #include #include #include #include #include #include #include #include "ebs.h" #include "ebshead.h" #ifndef SEEK_CUR #define SEEK_CUR 1 #endif typedef struct pre_entry { void *mempos; unsigned long memlength; } pre_entry; typedef struct uni_entry { double value; char text[10]; } uni_entry; char *upcase(char *text) { int i; i = 0; while (text[i] != 0) { if ((text[i] >= 'a') && (text[i] <= 'z')) text[i] = text[i] + 'A' - 'a'; i++; } return(text); } unsigned long string2ul(char *stnum) { unsigned long tagnum, y; y = 0; if (stnum[0] >= 'A') { /* it is a string */ if (stnum[0] == 'D') tagnum = EBS_DESCRIPTION; else if (stnum[0] == 'E') tagnum = EBS_EVENTS; else if (stnum[0] == 'I') tagnum = EBS_INSTITUTION; else if (stnum[0] == 'R') tagnum = EBS_RECORDING_TIME; else if (stnum[0] == 'U') tagnum = EBS_UNITS; else if (stnum[0] == 'P') { while ((stnum[y] != '_') && (y < strlen(stnum))) y++; y++; if (stnum[y] == 'N') tagnum = EBS_PATIENT_NAME; else if (stnum[y] == 'B') tagnum = EBS_PATIENT_BIRTHDAY; else if (stnum[y] == 'S') tagnum = EBS_PATIENT_SEX; else if (stnum[y] == 'H') tagnum = EBS_PROCESSING_HISTORY; else { while ((stnum[y] != '_') && (y < strlen(stnum))) y++; if (y == strlen(stnum)) tagnum = EBS_PATIENT_ID; else tagnum = EBS_PREFERRED_INTEGER_RANGE; } } else if (stnum[0] == 'S') { while ((stnum[y] != '_') && (y < strlen(stnum))) y++; y++; if (stnum[y] == 'D') tagnum = EBS_SHORT_DESCRIPTION; else tagnum = EBS_SAMPLE_RATE; } else if (stnum[0] == 'C') { while ((stnum[y] != '_') && (y < strlen(stnum))) y++; y++; if (stnum[y] == 'D') tagnum = EBS_CHANNEL_DESCRIPTION; else tagnum = EBS_CHANNEL_GROUPS; } else tagnum = EBS_ILLEGAL_TAG; } /* if (strcmp(stnum,"PATIENT_NAME") == 0) tagnum = EBS_PATIENT_NAME; else if (strcmp(stnum,"PATIENT_ID") == 0) tagnum = EBS_PATIENT_ID; else if (strcmp(stnum,"PATIENT_BIRTHDAY") == 0) tagnum = EBS_PATIENT_BIRTHDAY; else if (strcmp(stnum,"PATIENT_SEX") == 0) tagnum = EBS_PATIENT_SEX; else if (strcmp(stnum,"SHORT_DESCRIPTION") == 0) tagnum = EBS_SHORT_DESCRIPTION; else if (strcmp(stnum,"DESCRIPTION") == 0) tagnum = EBS_DESCRIPTION; else if (strcmp(stnum,"SAMPLE_RATE") == 0) tagnum = EBS_SAMPLE_RATE; else if (strcmp(stnum,"INSTITUTION") == 0) tagnum = EBS_INSTITUTION; else if (strcmp(stnum,"PROCESSING_HISTORY") == 0) tagnum = EBS_PROCESSING_HISTORY; else if ((strcmp(stnum,"PREFERRED_INTEGER_RANGE") == 0) || (strcmp(stnum,"P_I_R")) == 0) tagnum = EBS_PREFERRED_INTEGER_RANGE; else if (strcmp(stnum,"UNITS") == 0) tagnum = EBS_UNITS; else if (strcmp(stnum,"CHANNEL_DESCRIPTION") == 0) tagnum = EBS_CHANNEL_DESCRIPTION; else if (strcmp(stnum,"CHANNEL_GROUPS") == 0) tagnum = EBS_CHANNEL_GROUPS; else if (strcmp(stnum,"EVENTS") == 0) tagnum = EBS_EVENTS; else if (strcmp(stnum,"RECORDING_TIME") == 0) tagnum = EBS_RECORDING_TIME; else tagnum = EBS_ILLEGAL_TAG; */ else { /* it is a number */ tagnum = strtoul(stnum, NULL, 0); } return(tagnum); } int selectchannels(int *concern, char **argu, unsigned long channels) { int i, out, first, second, forall; char *posin, *endpos; posin = *argu; i = 0; forall = 0; out = 0; if (posin[0] != '{') forall = 1; posin++; first = 1; while ((strlen(posin) > 0) && (forall == 0) && (out == 0)) { while (posin[0] == ' ') posin++; if (posin[0] == 'n') { first = channels; posin++; concern[first-1] = 1; } else { first = strtol(posin, &posin, 0); if (first == 0) /* there was not a number but there should one */ return(-1); if (first > channels) { fprintf(stderr, "Biggest channel number %ld and not %ld\n",channels, first); first = channels; } concern[first-1] = 1; } while (posin[0] == ' ') posin++; if (posin[0] == ',') { posin++; } else if (posin[0] == '-') { posin++; if (posin[0] == 'n') { second = channels; posin++; } else { second = strtol(posin, &posin, 0); if (second > channels) { fprintf(stderr, "Biggest channel number %ld and not %ld\n",channels, second); second = channels; } } for (i = first-1; i < second; i++) { concern[i] = 1; } while (posin[0] == ' ') posin++; if (posin[0] == '}') { posin++; out = 1; } else if (posin[0] == ',') { posin++; } else { fprintf(stderr, "Can't manage input string!\n"); return(-1); } } else if (posin[0] == '}') { posin++; out = 1; } else { fprintf(stderr, "Can't manage input string!\n"); return(-1); } } if (forall == 1) for (i = 0; i < channels; i++) concern[i] = 1; *argu = posin; return(0); } int setattr(EBS_FILE *fec, unsigned long tagnumber, char *argu) { unsigned long len, taglen, channels, i, val, y, diff, size; double sam, value; FILE *fd; char *filebuf, sex[4] = {0, 0, 0, 0}; struct stat buf; void *mempos, *point, *memput, *help, *help2; long min, max; char *text; int out, nan, *concern; pre_entry *pentry; uni_entry *uentry; channels = fec->fixedheader.channels; mempos = ebs_getattr(fec, tagnumber, &taglen); switch (tagnumber) { case EBS_PATIENT_NAME: case EBS_PATIENT_ID: case EBS_SHORT_DESCRIPTION: case EBS_INSTITUTION: len = s4len(argu); if (strlen(argu) > 64) /* argument ist zu gross */ fprintf(stderr, "Single-line text-strings should not have more than " "64 characters!\n"); point = (void *) malloc(4 * len); if (point == NULL) { fprintf(stderr,"Can't get memory!\n"); return(-1); } memput = point; puts4(argu, &point); ebs_putattr(fec, tagnumber, memput, len); free(memput); return(0); case EBS_DESCRIPTION: if ((argu[0] == ',') && (argu[1] == 'f')) { argu++; argu++; while(argu[0] == ' ') argu++; fd = fopen(argu, "r"); if (fd == NULL) { fprintf(stderr,"Can't open file %s.\n", argu); return(-1); } fstat(fileno(fd), &buf); size = buf.st_size; filebuf = (char *)malloc(size+1); fread(filebuf, size, sizeof(char), fd); while (filebuf[size-1] == '\n') size--; filebuf[size] = '\0'; len = s4len(filebuf); memput = malloc(len * 4); if (memput == NULL) { fprintf(stderr, "Can't get memory!\n"); return(-1); } help = memput; puts4(filebuf, &help); ebs_putattr(fec, tagnumber, memput, len); free(memput); free(filebuf); return(0); } case EBS_PROCESSING_HISTORY: len = s4len(argu); point = (void *) malloc(len * 4); if (point == NULL) { fprintf(stderr,"Can't get memory!\n"); return(-1); } memput = point; puts4(argu, &point); ebs_putattr(fec, tagnumber, memput, len); free(memput); return(0); case EBS_PATIENT_BIRTHDAY: if (strlen(argu) == 8 && isdigit(argu[ 0]) && isdigit(argu[ 1]) && isdigit(argu[ 2]) && isdigit(argu[ 3]) && isdigit(argu[ 4]) && isdigit(argu[ 5]) && isdigit(argu[ 6]) && isdigit(argu[ 7])) ebs_putattr(fec, tagnumber, (void *)argu, 2); else { fprintf(stderr, "Error: patient birthday '%s' has strange format!\n" "Use 'yyyymmdd'.\n", argu); return(-1); } return(0); case EBS_PATIENT_SEX: if ((argu[0] == '1') || (argu[0] == 'm') || (argu[0] == 'M')) sex[3] = 1; else if ((argu[0] == '2') || (argu[0] == 'f') || (argu[0] == 'F')) sex[3] = 2; else { fprintf(stderr, "Error: patient sex '%s' has unknown format!\n" "Use '1' or 'm' for male and '2' or 'f' for female.\n", argu); return(-1); } ebs_putattr(fec,tagnumber, sex, 1); return(0); case EBS_SAMPLE_RATE: sam = strtod(argu, NULL); len = f4len(sam); point = malloc(len * 4); if (point == NULL) { fprintf(stderr,"Can't get memory!\n"); return(-1); } memput = point; putf4(sam, &point); ebs_putattr(fec, tagnumber, memput, len); free(memput); return(0); case EBS_PREFERRED_INTEGER_RANGE: concern = (int *)(malloc(channels*sizeof(int))); pentry = (pre_entry *)(malloc(channels*sizeof(pre_entry))); if (mempos == NULL) /* then default */ for (i = 0; i < channels; i++) { concern[i] = 0; pentry[i].mempos = malloc(2*sizeof(unsigned long)); pentry[i].memlength = 2; help = pentry[i].mempos; puti32(0,&help); puti32(0,&help); } else { help2 = mempos; for (i = 0; i < channels; i++) { concern[i] = 0; pentry[i].mempos = malloc(2*sizeof(unsigned long)); pentry[i].memlength = 2; help = pentry[i].mempos; val = geti32(&help2); puti32(val, &help); val = geti32(&help2); puti32(val, &help); } } if (selectchannels(concern, &argu, channels) != 0) { free(pentry); free(concern); return(-1); } min = strtol(argu, &argu, 0); max = strtol(argu, &argu, 0); help2 = mempos; for (i = 0; i < channels; i++) { if (concern[i] == 1) { puti32(min,&help2); puti32(max,&help2); } else { help = pentry[i].mempos; puti32(geti32(&help), &help2); puti32(geti32(&help), &help2); } } for (i = 0; i < channels; i++) free(pentry[i].mempos); free(pentry); free(concern); ebs_putattr(fec, tagnumber, mempos, taglen); return(0); case EBS_UNITS: concern = (int *)(malloc(channels*sizeof(int))); uentry = (uni_entry *)(malloc(channels*sizeof(uni_entry))); if ((concern == NULL) || (uentry == NULL)) { fprintf(stderr, "Can't get memory!\n"); free(concern); free(uentry); return(-1); } if (mempos == NULL) /* then default */ for (i = 0; i < channels; i++) { concern[i] = 0; uentry[i].value = 0.0; uentry[i].text[0] = '\n'; } else { help2 = mempos; for (i = 0; i < channels; i++) { uentry[i].value = getf4(&help2, &nan); if (nan != 0) { uentry[i].value = 0.0; } gets4(uentry[i].text, 8, &help2); } } if (selectchannels(concern, &argu, channels) != 0) { free(uentry); free(concern); return(-1); } value = strtod(argu, &argu); while (argu[0] == ' ') argu++; text = argu; if (strlen(argu) > 8) /* shorting string to length of 8 */ argu[8] = 0; mempos = malloc(channels*2*sizeof(unsigned long)); /* min for each chan.*/ taglen = channels*2; help2 = mempos; for (i = 0; i < channels; i++) { if (concern[i] == 1) { /* add new values */ y = f4len(value); y = y + s4len(text); if (y > 2) { diff = (char *)help2 - (char *)mempos; taglen = taglen - 2 + y; mempos = realloc(mempos,taglen*sizeof(unsigned long)); if (mempos == NULL) { fprintf(stderr, "Can't get enough memory!\n"); return(-1); } help2 =(char *)mempos + diff; } putf4(value, &help2); puts4(text, &help2); } else { /* add old values */ y = f4len(uentry[i].value); y = y + s4len(uentry[i].text); if (y > 2) { diff = (char *)help2 - (char *)mempos; taglen = taglen - 2 + y; mempos = realloc(mempos,taglen*sizeof(unsigned long)); if (mempos == NULL) { fprintf(stderr, "Can't get enough memory!\n"); return(-1); } help2 = (char *)mempos + diff; } putf4(uentry[i].value, &help2); puts4(uentry[i].text, &help2); } } free(uentry); free(concern); ebs_putattr(fec, tagnumber, mempos, taglen); free(mempos); return(0); case EBS_CHANNEL_GROUPS: fprintf(stderr, "Not yet implemented!\n"); return(-1); case EBS_RECORDING_TIME: while (argu[0] == ' ') argu++; if (strlen(argu) == 15 && argu[8] == 'T' && isdigit(argu[ 0]) && isdigit(argu[ 1]) && isdigit(argu[ 2]) && isdigit(argu[ 3]) && isdigit(argu[ 4]) && isdigit(argu[ 5]) && isdigit(argu[ 6]) && isdigit(argu[ 7]) && isdigit(argu[ 9]) && isdigit(argu[10]) && isdigit(argu[11]) && isdigit(argu[12]) && isdigit(argu[13]) && isdigit(argu[14])) ebs_putattr(fec, tagnumber, (void *)argu, 4); else if (strlen(argu) == 8 && isdigit(argu[ 0]) && isdigit(argu[ 1]) && isdigit(argu[ 2]) && isdigit(argu[ 3]) && isdigit(argu[ 4]) && isdigit(argu[ 5]) && isdigit(argu[ 6]) && isdigit(argu[ 7])) ebs_putattr(fec, tagnumber, (void *)argu, 2); else { fprintf(stderr, "Error: recording time '%s' has strange format!\n" "Use 'yyyymmdd' or 'yyyymmddThhmmss'.\n", argu); return(-1); } return(0); case EBS_CHANNEL_DESCRIPTION: case EBS_EVENTS: case EBS_FILTERS: case EBS_CHANNEL_LOCATIONS: case EBS_LOCATION_DIAGRAM: fprintf(stderr, "Not yet implemented!\n"); return(-1); default: return(-1); } } int appattr(EBS_FILE *fec, unsigned long tagnumber, char *argu) { unsigned long len, taglen, sex; void *mempos, *memput, *help; char *entry; mempos = ebs_getattr(fec, tagnumber, &taglen); if (mempos == NULL) return(setattr(fec, tagnumber, argu)); switch (tagnumber) { case EBS_PATIENT_NAME: case EBS_PATIENT_ID: case EBS_SHORT_DESCRIPTION: case EBS_INSTITUTION: help = mempos; entry = (char *)malloc(taglen*sizeof(unsigned long)); gets4(entry, taglen*4,&help); strcat(entry, " "); strcat(entry, argu); len = s4len(entry); memput = malloc(len*sizeof(unsigned long)); help = memput; puts4(entry, &help); ebs_putattr(fec, tagnumber, memput, len); free(memput); free(entry); return(0); case EBS_DESCRIPTION: help = mempos; entry = (char *)malloc(taglen*sizeof(unsigned long)); gets4(entry, taglen*4,&help); strcat(entry, "\n"); strcat(entry, argu); len = s4len(entry); memput = malloc(len*sizeof(unsigned long)); help = memput; puts4(entry, &help); ebs_putattr(fec, tagnumber, memput, len); free(memput); free(entry); return(0); case EBS_PROCESSING_HISTORY: len = s4len(argu); memput = ebs_appattr(fec, tagnumber, len); puts4(argu, &memput); return(0); case EBS_PATIENT_BIRTHDAY: case EBS_PATIENT_SEX: case EBS_SAMPLE_RATE: case EBS_PREFERRED_INTEGER_RANGE: case EBS_UNITS: case EBS_CHANNEL_GROUPS: case EBS_RECORDING_TIME: case EBS_CHANNEL_DESCRIPTION: case EBS_EVENTS: return(setattr(fec, tagnumber, argu)); default: return(-1); } } /* how to use ebsmod */ void prinusage(char *name) { fprintf(stderr, "Usage:\n %s option:attrname[,f[,s] file] [\"{a,b,c-d}\"] [attrentry] \n", name); fprintf(stderr, "option:\n"); fprintf(stderr, " -s set attributeentry new\n"); fprintf(stderr, " -d delete attribute\n"); fprintf(stderr, " -a append attributeentry\n"); fprintf(stderr, "\n ,f is only for attribute description and\n"); fprintf(stderr, " cause that the text is taken from the file.\n"); fprintf(stderr, " In the brackets { } are the channels named for which the\n"); fprintf(stderr, " attribute entry should changed.\n"); fprintf(stderr, " The attribute name could be abbreviated, but the underscores\n"); fprintf(stderr, " and the first character after it must be written. You can\n"); fprintf(stderr, " also use a the tag number instead of the attribute name.\n"); fprintf(stderr, " Samples:\n"); fprintf(stderr, " ebsmod file.ebs -d:patient_name /* deletes the patient name /*\n"); fprintf(stderr, " ebsmod file.ebs -s:patient_name Hans Muster /* sets a new patient name */\n"); fprintf(stderr, " ebsmod file.ebs -a:processing_history Channel one changed by rphase.\n"); fprintf(stderr, " /* adds text to processing history */\n"); fprintf(stderr, " ebsmod file.ebs -s:description,f file.txt\n"); fprintf(stderr, " /* sets the description new to the text in the file file.txt */\n"); } /* splites argv into tagnumber and attribute, and finaly sets y to next option position in argv */ void split(int argc, char *argv[], int *y, unsigned long *tagnumber, char *argu) { char *posin; unsigned long tag; char tagstring[50]; int i; posin = (argv[*y])+3; if (posin == "") { *y += 1; posin = argv[*y]; } *y += 1; i = 0; while ((i < 49) && (posin[i] != '{') && (posin[i] != 0) && (posin[i] != ',')) { tagstring[i] = posin[i]; i++; } tagstring[i] = 0; upcase(tagstring); tag = string2ul(tagstring); posin += i; argu[0] = 0; if (posin[0] != 0) { argu = strcat(argu,posin); argu = strcat(argu," "); } if (*y < argc) while ((argv[*y][0] != '-') || (argv[*y][2] != ':')) { argu = strcat(argu,argv[*y]); argu = strcat(argu," "); *y += 1; if (*y >= argc) break; } argu[strlen(argu)-1] = 0; *tagnumber = tag; } /* *********************************************************************** */ /* ** main program ** */ /***************************************************************************/ int main(int argc, char *argv[]) { EBS_FILE *fec, *feo; int err, cond, y, e; unsigned long tagnumber; char argu[5120]; if (argc <= 1) { prinusage(argv[0]); exit(1); } fec = ebs_open(argv[1], 'm'); /* open for modify */ if (fec == NULL) { fprintf(stderr, "ebs - file not found!\n"); prinusage(argv[0]); exit(1); } y = 2; while(y < argc) { e = y; split(argc, argv, &y, &tagnumber, argu); if (tagnumber != EBS_ILLEGAL_TAG) { switch (argv[e][1]) { case 's': case 'S': err = setattr(fec, tagnumber, argu); if (err != 0) fprintf(stderr, "error in: %s %s\n", argv[e], argv[e+1]); err = 0; break; case 'd': case 'D': err = ebs_clearattr(fec, tagnumber); if (err != 0) fprintf(stderr, "error in: %s\n", argv[e], argv[e+1]); err = 0; break; case 'a': case 'A': err = appattr(fec, tagnumber, argu); if (err != 0) fprintf(stderr, "error in: %s %s\n", argv[e], argv[e+1]); err = 0; break; default: fprintf(stderr,"Unkown option\n"); prinusage(argv[0]); ebs_close(fec); exit(1); break; } } } if (ebs_flush(fec) != 0) ebs_mak2varheader(fec); ebs_close(fec); return(0); }