1 /*****************************************************************************
2 Major portions of this software are copyrighted by the Medical College
3 of Wisconsin, 1994-2000, and are released under the Gnu General Public
4 License, Version 2. See the file README.Copyright for details.
5 ******************************************************************************/
6
7 #include "mrilib.h"
8 /**************************
9 * 3dNotes - T. Ross 8/99 *
10 * adapted by RWCox 9/99 *
11 **************************/
12
13 #include <sys/utsname.h>
14 #include <sys/time.h>
15 #include <time.h>
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <ctype.h>
19
20 /*---------------------------------------------------------------------------*/
21 /*! Assemble a sort-of command line string from the arguments;
22 free() this when done.
23 -----------------------------------------------------------------------------*/
24
tross_commandline(char * pname,int argc,char ** argv)25 char * tross_commandline( char *pname , int argc , char **argv )
26 {
27 char *ch ;
28 int ii , ll ;
29
30 if( argc < 1 || argv == NULL ) return NULL ; /* ZSS, changed argc < 2 to argc < 1 */
31
32 if( pname == NULL ) pname = argv[0] ;
33
34 ii = strlen(pname) ; ch = AFMALL(char, ii+4) ; strcpy(ch,pname) ;
35 if (argc < 2) { /* ZSS */
36 /* no options, get the hell outa here */
37 return ch ;
38 }
39 for( ii=1 ; ii < argc ; ii++ ){
40 if( argv[ii] == NULL || argv[ii][0] == '\0' ) continue ; /* skip */
41
42 ll = strlen(argv[ii]) ;
43 ch = AFREALL(ch ,char, strlen(ch)+ll+4 ) ; /* expand output array */
44
45 if( !THD_filename_ok(argv[ii]) ){ /* bad characters? */
46 int jj ; char * aa = AFMALL(char, ll+1) ;
47
48 strcpy(aa,argv[ii]) ; /* edit out bad characters */
49 for( jj=0 ; jj < ll ; jj++ )
50 if( iscntrl(aa[jj]) ||
51 isspace(aa[jj]) || (aa[jj] & 128) != 0 ) aa[jj] = ' ' ;
52
53 strcat(ch," '") ; strcat(ch,aa) ; strcat(ch,"'") ; free(aa) ;
54
55 } else {
56 strcat(ch," ") ; strcat(ch,argv[ii]) ; /* just copy it */
57 }
58 }
59
60 return ch ;
61 }
62
63 /*---------------------------------------------------------------------------*/
64 /*! Get the current date/time string; free() this when done.
65 -----------------------------------------------------------------------------*/
66
tross_datetime(void)67 char * tross_datetime(void)
68 {
69 time_t tnow = time(NULL) ; int i ; char * qh , * ch ;
70
71 ch=ctime(&tnow); i=strlen(ch); qh=AFMALL(char, i+2);
72 strcpy(qh,ch); qh[i-1]='\0';
73 return qh ;
74 }
75
76 /*---------------------------------------------------------------------------*/
77
78 #undef NNAME
79 #define NNAME 1025
tross_hostname(void)80 char * tross_hostname(void) /* 19 Sep 1999 */
81 {
82 char * cn = AFMALL(char, NNAME) ;
83 gethostname( cn , NNAME ) ;
84 return cn ;
85 }
86
87 /*---------------------------------------------------------------------------*/
88
89 #include <pwd.h>
90
tross_username(void)91 char * tross_username(void) /* 20 Sep 1999 */
92 {
93 uid_t uu = getuid() ;
94 struct passwd * pwd = getpwuid(uu) ;
95 char * cn = AFMALL(char, NNAME) ;
96
97 if( pwd == NULL ) strcpy(cn,"nobody") ;
98 else strcpy(cn,pwd->pw_name) ;
99 return cn ;
100 }
101
102 /*---------------------------------------------------------------------------*/
103 /*! Add a note after the last current note
104 -----------------------------------------------------------------------------*/
105
tross_Add_Note(THD_3dim_dataset * dset,char * cn)106 void tross_Add_Note( THD_3dim_dataset *dset, char *cn )
107 {
108 ATR_int *notecount;
109 int num_notes;
110 char note_name[20], *ch ;
111
112 if( !ISVALID_DSET(dset) || cn == NULL || cn[0] == '\0' ) return ;
113
114 notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
115 if (notecount == NULL) {
116 num_notes = 1;
117 THD_set_int_atr(dset->dblk, "NOTES_COUNT", 1, &num_notes);
118 } else {
119 num_notes = notecount->in[0] + 1;
120 if( num_notes > MAX_DSET_NOTES ){
121 fprintf(stderr,"*** attempt to add too many notes to dataset!\n") ;
122 return ;
123 }
124 notecount->in[0]++;
125 }
126
127 sprintf(note_name, "NOTE_NUMBER_%03d", num_notes);
128 ch = tross_Encode_String(cn) ; if( ch == NULL ) return ;
129 THD_set_string_atr(dset->dblk, note_name, ch);
130 free(ch) ;
131
132 ch = tross_datetime() ;
133 sprintf(note_name, "NOTE_DATE_%03d", num_notes) ;
134 THD_set_string_atr(dset->dblk, note_name, ch);
135 free(ch);
136
137 return ;
138 }
139
140 /*---------------------------------------------------------------------------*/
141 /*! Delete a particular note
142 -----------------------------------------------------------------------------*/
143
tross_Delete_Note(THD_3dim_dataset * dset,int inote)144 void tross_Delete_Note(THD_3dim_dataset *dset, int inote)
145 {
146 ATR_int *notecount;
147 int num_notes;
148 ATR_string *note_text;
149 char note_name[20];
150
151 if( !ISVALID_DSET(dset) || inote <= 0 || inote > MAX_DSET_NOTES ) return ;
152
153 notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
154 if (notecount == NULL) return ;
155
156 num_notes = notecount->in[0];
157 if (inote > num_notes) return ;
158
159 sprintf(note_name, "NOTE_NUMBER_%03d", inote);
160 note_text = THD_find_string_atr(dset->dblk, note_name);
161 if( note_text == NULL ) return ;
162 THD_erase_one_atr( dset->dblk , note_name );
163
164 sprintf(note_name, "NOTE_DATE_%03d", inote);
165 note_text = THD_find_string_atr(dset->dblk, note_name);
166 if( note_text != NULL ) THD_erase_one_atr( dset->dblk , note_name );
167
168 notecount->in[0]-- ; /* where the note count is reduced */
169
170 /* Slide the higher numbered notes down */
171
172 while (inote < num_notes) {
173 /* find the next note */
174 sprintf(note_name, "NOTE_NUMBER_%03d", inote+1);
175 note_text=THD_find_string_atr(dset->dblk, note_name);
176 if (note_text != NULL){
177 /* rename to the previous name */
178 sprintf(note_name, "NOTE_NUMBER_%03d", inote);
179 strcpy(note_text->name, note_name);
180 }
181
182 sprintf(note_name,"NOTE_DATE_%03d",inote+1) ;
183 note_text = THD_find_string_atr(dset->dblk, note_name);
184 if (note_text != NULL){
185 /* rename to the previous name */
186 sprintf(note_name, "NOTE_DATE_%03d", inote);
187 strcpy(note_text->name, note_name);
188 }
189
190 inote++ ;
191 }
192
193 /* No notes left, so remove count attribute */
194 if (num_notes == 1)
195 THD_erase_one_atr( dset->dblk, "NOTES_COUNT");
196 return ;
197 }
198
199 /*---------------------------------------------------------------------------*/
200 /*! Get the number of Notes currently attached to the dataset.
201 Doesn't include the History note.
202 -----------------------------------------------------------------------------*/
203
tross_Get_Notecount(THD_3dim_dataset * dset)204 int tross_Get_Notecount( THD_3dim_dataset * dset )
205 {
206 ATR_int *notecount;
207
208 if( !ISVALID_DSET(dset) ) return -1 ;
209
210 notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
211 if (notecount == NULL) return 0 ;
212 return notecount->in[0];
213 }
214
215 /*---------------------------------------------------------------------------*/
216 /*! Get the inote-th Note attached to the dataset.
217 free() this string when done with it - it is a copy
218 -----------------------------------------------------------------------------*/
219
tross_Get_Note(THD_3dim_dataset * dset,int inote)220 char * tross_Get_Note( THD_3dim_dataset * dset , int inote )
221 {
222 ATR_int *notecount;
223 int num_notes;
224 ATR_string *note ;
225 char note_name[20], * ch ;
226
227 if( !ISVALID_DSET(dset) || inote <= 0 || inote > MAX_DSET_NOTES ) return NULL ;
228
229 notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
230 if (notecount == NULL) return NULL ;
231 num_notes = notecount->in[0];
232 if( inote > num_notes ) return NULL ;
233
234 sprintf(note_name, "NOTE_NUMBER_%03d", inote);
235 note = THD_find_string_atr(dset->dblk, note_name);
236 if (note == NULL ) return NULL ;
237 ch = tross_Expand_String( note->ch ) ;
238 return ch ;
239 }
240
241 /*------------------------------------------------------------------------------*/
242
tross_Get_Notedate(THD_3dim_dataset * dset,int inote)243 char * tross_Get_Notedate( THD_3dim_dataset * dset , int inote )
244 {
245 ATR_int *notecount;
246 int num_notes;
247 ATR_string *note ;
248 char note_name[20];
249
250 if( !ISVALID_DSET(dset) || inote <= 0 || inote > MAX_DSET_NOTES ) return NULL ;
251
252 notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
253 if (notecount == NULL) return NULL ;
254 num_notes = notecount->in[0];
255 if( inote > num_notes ) return NULL ;
256
257 sprintf(note_name, "NOTE_DATE_%03d", inote);
258 note = THD_find_string_atr(dset->dblk, note_name);
259 if (note == NULL ) return NULL ;
260 return tross_Expand_String( note->ch ) ;
261 }
262
263 /*---------------------------------------------------------------------------*/
264 /*! Add the history from the command line to the dataset.
265 -----------------------------------------------------------------------------*/
266
267 #ifndef AFNI_VERSION_LABEL
268 # include "AFNI_version.h"
269 #endif
270
271 #ifndef AFNI_VERSION_PLATFORM
272 # ifdef SHOWOFF
273 # undef SHSH
274 # undef SHSHSH
275 # define SHSH(x) #x
276 # define SHSHSH(x) SHSH(x)
277 # define AFNI_VERSION_PLATFORM SHSHSH(SHOWOFF) /* now in "quotes" */
278 # undef SHSHSH
279 # undef SHSH
280 # else
281 # define AFNI_VERSION_PLATFORM "unknown"
282 # endif
283 #endif
284
tross_Make_History(char * pname,int argc,char ** argv,THD_3dim_dataset * dset)285 void tross_Make_History( char *pname, int argc, char **argv, THD_3dim_dataset *dset )
286 {
287 char *ch ;
288
289 if( argc < 2 || argv == NULL || !ISVALID_DSET(dset) ) return ;
290
291 ch = tross_commandline( pname , argc , argv ) ; if( ch == NULL ) return ;
292
293 /* Prepend AFNI version information */
294
295 #if defined(AFNI_VERSION_LABEL) && defined(AFNI_VERSION_PLATFORM)
296 { char cv[256] , *qh ;
297 sprintf(cv,"{%s:%s} ",AFNI_VERSION_LABEL,AFNI_VERSION_PLATFORM) ;
298 qh = (char *)malloc(sizeof(char)*(strlen(ch)+256)) ;
299 strcpy(qh,cv) ; strcat(qh,ch) ; free(ch) ; ch = qh ;
300 }
301 #endif
302
303 tross_Append_History( dset , ch ) ;
304 free(ch) ; return ;
305 }
306
307 /*---------------------------------------------------------------------------*/
308 /*! Replace the History in new_dset with that from old_dset
309 -----------------------------------------------------------------------------*/
310
tross_Copy_History(THD_3dim_dataset * old_dset,THD_3dim_dataset * new_dset)311 void tross_Copy_History( THD_3dim_dataset * old_dset , THD_3dim_dataset * new_dset )
312 {
313 char * ch , * cn ;
314
315 if( !ISVALID_DSET(old_dset) || !ISVALID_DSET(new_dset) ) return ;
316
317 ch = tross_Get_History( old_dset ) ; if( ch == NULL ) return ;
318 cn = tross_Encode_String(ch) ; free(ch) ; if( cn == NULL ) return;
319 THD_set_string_atr(new_dset->dblk, "HISTORY_NOTE", cn);
320 free(cn) ; return ;
321 }
322
323 /*---------------------------------------------------------------------------*/
324 /*! Add the History in old_dset to that in new_dset [27 Feb 2003]
325 -----------------------------------------------------------------------------*/
326
tross_Addto_History(THD_3dim_dataset * old_dset,THD_3dim_dataset * new_dset)327 void tross_Addto_History( THD_3dim_dataset *old_dset , THD_3dim_dataset *new_dset )
328 {
329 char *ch ;
330
331 if( !ISVALID_DSET(old_dset) || !ISVALID_DSET(new_dset) ) return ;
332
333 ch = tross_Get_History( old_dset ) ; if( ch == NULL ) return ;
334 tross_Append_History( new_dset , ch ) ; free(ch) ; return ;
335 }
336
337 /*---------------------------------------------------------------------------*/
338 /*! Erase the old History and replace it with this one.
339 09 Dec 2000 - use this wisely.
340 -----------------------------------------------------------------------------*/
341
tross_Replace_History(THD_3dim_dataset * dset,char * ch)342 void tross_Replace_History( THD_3dim_dataset * dset , char * ch )
343 {
344 char * cn ;
345
346 if( !ISVALID_DSET(dset) || ch == NULL ) return ;
347
348 cn = tross_Encode_String(ch) ; if( cn == NULL ) return ;
349 THD_set_string_atr(dset->dblk, "HISTORY_NOTE", cn);
350 free(cn) ; return ;
351 }
352
353 /*---------------------------------------------------------------------------*/
354 /*! Append a string to the dataset history (create the history if need be).
355 -----------------------------------------------------------------------------*/
356
tross_Append_History(THD_3dim_dataset * dset,char * cn)357 void tross_Append_History( THD_3dim_dataset *dset, char *cn )
358 {
359 ATR_string * hist ;
360 char *ch , *chold , *cdate , *cname , *cuser , *cenv ;
361 int idate , iname , iuser ;
362
363 if( !ISVALID_DSET(dset) || cn == NULL || cn[0] == '\0' ) return ;
364
365 hist = THD_find_string_atr(dset->dblk,"HISTORY_NOTE") ;
366
367 /* maybe the user does not want any history 28 Jun 2013 [rickr] */
368 if( AFNI_noenv("AFNI_INCLUDE_HISTORY") ) {
369 if( hist ) THD_erase_one_atr(dset->dblk, "HISTORY_NOTE") ;
370 return ;
371 }
372
373 cdate = tross_datetime() ; idate = strlen(cdate) ;
374
375 cenv = getenv("AFNI_HISTORY_NAME") ;
376 if( cenv == NULL ) cenv = getenv("AFNI_HISTORY_USERNAME") ;
377
378 if( cenv != NULL ){ /* 24 Jun 2013 */
379 cuser = strdup(cenv) ; iuser = strlen(cuser) ;
380 cname = strdup("\0") ; iname = 0 ;
381 } else {
382 cname = tross_hostname() ; iname = strlen(cname) ; /* 19 Sep 1999 */
383 cuser = tross_username() ; iuser = strlen(cuser) ; /* 19 Sep 1999 */
384 }
385
386 /*- add to the history -*/
387
388 if( hist != NULL ){
389
390 chold = tross_Expand_String(hist->ch) ; if( chold == NULL ) return ;
391 chold = AFREALL( chold, char,
392 strlen(chold)+idate+iuser+iname+strlen(cn)+16 ) ;
393
394 strcat(chold,"\n") ;
395 strcat(chold,"[") ;
396 if( iuser > 0 ){ strcat(chold,cuser); }
397 if( iname > 0 ){ strcat(chold,"@") ; strcat(chold,cname) ; }
398 if( *cuser != '\0' ){ strcat(chold,": ") ; }
399 strcat(chold,cdate);
400 strcat(chold,"] ") ;
401 strcat(chold,cn) ;
402 ch = tross_Encode_String(chold) ; if( ch == NULL ){ free(chold); return; }
403 THD_set_string_atr(dset->dblk, "HISTORY_NOTE", ch);
404 free(ch) ; free(chold) ;
405
406 /*- create the history -*/
407
408 } else {
409 chold = AFMALL(char, idate+iuser+iname+strlen(cn)+12 ) ;
410 sprintf(chold,"[%s@%s: %s] %s",cuser,cname,cdate,cn) ;
411 ch = tross_Encode_String(chold) ; if( ch == NULL ){ free(chold); return; }
412 THD_set_string_atr(dset->dblk, "HISTORY_NOTE", ch);
413 free(ch) ; free(chold) ;
414 }
415
416 free(cdate) ; free(cname) ; free(cuser) ; return ;
417 }
418
419 /*----------------------------------------------------------------------------*/
420 /*! Append multiple strings to the History, all on one line. Usage:
421 - tross_multi_Append_History(dset,str1,str2,str3,NULL) ;
422 - As many str variables as desired (at least 1), of type char *, can be
423 passed in.
424 - The last one must be NULL.
425 ------------------------------------------------------------------------------*/
426
427 #include <stdarg.h>
428
tross_multi_Append_History(THD_3dim_dataset * dset,...)429 void tross_multi_Append_History( THD_3dim_dataset *dset, ... )
430 {
431 va_list vararg_ptr ;
432 int nstr=0 , nc , first=1 , ii ;
433 char * str , * cpt ;
434
435 va_start( vararg_ptr , dset ) ;
436
437 str = AFMALL(char, 4) ; nstr = 0 ; str[0] = '\0' ;
438 while(1){
439 cpt = va_arg( vararg_ptr , char * ) ; if( cpt == NULL ) break ;
440 nc = strlen(cpt) ; if( nc == 0 ) continue ;
441 nstr += nc ; str = AFREALL(str, char, nstr+8 ) ;
442 if( !first ) strcat(str," ; ") ;
443 strcat(str,cpt) ; first = 0 ;
444 }
445
446 va_end( vararg_ptr ) ;
447
448 nstr = strlen(str) ;
449 if( nstr > 0 ){
450 for( ii=0 ; ii < nstr ; ii++ )
451 if( str[ii]=='\n' || str[ii]=='\f' || str[ii]=='\r' || str[ii]=='\v' )
452 str[ii] = ' ' ;
453
454 tross_Append_History( dset , str ) ;
455 }
456
457 free(str) ; return ;
458 }
459
460 /*----------------------------------------------------------------------------*/
461 /*! Get the history string; free() this when done. If NULL is returned,
462 there is no history (cf. Santayana).
463 ------------------------------------------------------------------------------*/
464
tross_Get_History(THD_3dim_dataset * dset)465 char * tross_Get_History( THD_3dim_dataset *dset )
466 {
467 ATR_string * hist ;
468 char * ch ;
469
470 if( !ISVALID_DSET(dset) ) return NULL ;
471
472 hist = THD_find_string_atr(dset->dblk,"HISTORY_NOTE") ;
473 if( hist == NULL ) return NULL ;
474
475 ch = tross_Expand_String(hist->ch) ; return ch ;
476 }
477
478 /*-----------------------------------------------------------------------------*/
479 /*! Store string at location inote;
480 if inote > number of notes now present, gets added at the end of the list;
481 otherwise, replaces existing note
482 -------------------------------------------------------------------------------*/
483
tross_Store_Note(THD_3dim_dataset * dset,int inote,char * cn)484 void tross_Store_Note( THD_3dim_dataset * dset , int inote , char * cn )
485 {
486 ATR_int *notecount;
487 int num_notes;
488 ATR_string *note ;
489 char note_name[20], *ch ;
490
491 if( !ISVALID_DSET(dset) || inote <= 0 || inote > MAX_DSET_NOTES ||
492 cn == NULL || cn[0] == '\0' ) return ;
493
494 notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
495 if (notecount == NULL){ tross_Add_Note( dset , cn ) ; return ; }
496 num_notes = notecount->in[0];
497 if( inote > num_notes ){ tross_Add_Note( dset , cn ) ; return ; }
498
499 sprintf(note_name, "NOTE_NUMBER_%03d", inote);
500 ch = tross_Encode_String(cn) ; if( ch == NULL ) return ;
501 THD_set_string_atr(dset->dblk, note_name, ch);
502 free(ch) ;
503
504 ch = tross_datetime() ;
505 sprintf(note_name, "NOTE_DATE_%03d", inote) ;
506 THD_set_string_atr(dset->dblk, note_name, ch);
507 free(ch);
508
509 return ;
510 }
511
512 /*-----------------------------------------------------------------------*/
513 /*! Break a string up into lines of length between lbot and ltop bytes;
514 free() the result when done with it.
515 NULL return means illegal input was found.
516 -------------------------------------------------------------------------*/
517
tross_breakup_string(char * str,int lbot,int ltop)518 char * tross_breakup_string( char * str , int lbot , int ltop )
519 {
520 char * sout ;
521 int slen , ii , ibot,itop , ldif ;
522
523 if( str == NULL || str[0] == '\0' || lbot > ltop || lbot < 4 ) return NULL ;
524
525 slen = strlen(str) ; sout = AFMALL(char, slen+4) ;
526
527 while( slen > lbot && isspace(str[slen-1]) ) slen-- ; /* trim blanks off end */
528
529 ibot = 0 ; ldif = ltop-lbot ;
530 while(1){
531 itop = ibot + ltop-1 ; /* want to output str[ibot..itop] */
532
533 /* if past end of str, then just output the rest and exit */
534
535 if( itop >= slen ){
536 memcpy( sout+ibot , str+ibot , slen-ibot ) ;
537 sout[slen] = '\0' ;
538 return sout ;
539 }
540
541 /* scan forwards to find a newline character before itop; */
542 /* if one is present, output the string up to there, */
543 /* and continue again starting after the newline */
544
545 for( ii=ibot ; ii <= itop ; ii++ )
546 if( str[ii] == '\n' ) break ;
547
548 if( ii <= itop ){ /* found it! */
549 memcpy( sout+ibot , str+ibot , ii-ibot+1 ) ;
550 ibot = ii+1 ;
551 if( ibot >= slen ){ sout[slen] = '\0'; return sout; }
552 continue ;
553 }
554
555 /* scan backwards to find a whitespace character */
556
557 for( ii=itop ; ii > itop-ldif ; ii-- )
558 if( isspace(str[ii]) ) break ;
559
560 /* found one before the minimum location */
561 /* copy up to the previous char into output, */
562 /* then put a newline in for the whitespace */
563
564 if( ii > itop-ldif ){
565 memcpy( sout+ibot , str+ibot , ii-ibot ) ;
566 sout[ii] = '\n' ;
567 ibot = ii+1 ;
568 continue ; /* try to do next line */
569 }
570
571 /* scan ahead to next whitespace instead */
572
573 for( ii=itop ; ii < slen ; ii++ )
574 if( isspace(str[ii]) ) break ;
575
576 /* found one */
577
578 if( ii < slen ){
579 memcpy( sout+ibot , str+ibot , ii-ibot ) ;
580 sout[ii] = '\n' ;
581 ibot = ii+1 ;
582 continue ;
583 }
584
585 /* copy rest of input and exit */
586
587 memcpy( sout+ibot , str+ibot , slen-ibot ) ;
588 sout[slen] = '\0' ;
589 return sout ;
590 }
591 }
592
593 /*-----------------------------------------------------------------------*/
594 /*! Return a printable version of a note string; free() this when done
595 -------------------------------------------------------------------------*/
596
tross_Expand_String(char * ch)597 char * tross_Expand_String( char * ch )
598 {
599 char * cn = NULL ;
600 int i, j, num_char;
601
602 if( ch == NULL || ch[0] == '\0' ) return NULL ;
603
604 num_char = strlen(ch) ;
605 cn = (char *) malloc( sizeof(char) * (num_char+4) ) ;
606 for( i=j=0 ; j < num_char ; j++ ){
607 if( ch[j] != '\\' ){
608 cn[i++] = ch[j] ;
609 } else {
610 switch (ch[++j] ){
611 case 'r' : cn[i++] = '\r' ; break;
612 case 'n' : cn[i++] = '\n' ; break;
613 case '\\' : cn[i++] = '\\' ; break;
614 case '"' : cn[i++] = '\"' ; break;
615 case 't' : cn[i++] = '\t' ; break;
616 case 'a' : cn[i++] = '\a' ; break;
617 case 'v' : cn[i++] = '\v' ; break;
618 case 'b' : cn[i++] = '\b' ; break;
619 default: cn[i++] = '\\' ; /* 13 Mar 2003 */
620 cn[i++] = ch[j]; break;
621 }
622 }
623 }
624 cn[i] = '\0' ; return cn ;
625 }
626
627 /*--------------------------------------------------------------------------*/
628
629 static int Dont_Encode_Slash = 0 ;
630
tross_Dont_Encode_Slash(int q)631 void tross_Dont_Encode_Slash( int q ){ Dont_Encode_Slash = q ; return ; }
632
633 /*--------------------------------------------------------------------------*/
634 /*! Reverse of tross_Expand_String
635 ----------------------------------------------------------------------------*/
636
tross_Encode_String(char * cn)637 char * tross_Encode_String( char * cn )
638 {
639 char * ch = NULL ;
640 int i , j , num_char ;
641
642 if( cn == NULL || cn[0] == '\0' ) return NULL ;
643
644 num_char = strlen(cn) ;
645 ch = (char *) malloc( sizeof(char) * (2*num_char+4) ) ;
646 for( i=j=0 ; j < num_char ; j++ ){
647 switch( cn[j] ){
648 default: ch[i++] = cn[j] ; break ;
649 case '\r': ch[i++] = '\\' ; ch[i++] = 'r' ; break ;
650 case '\n': ch[i++] = '\\' ; ch[i++] = 'n' ; break ;
651 case '\"': ch[i++] = '\\' ; ch[i++] = '\"'; break ;
652 case '\t': ch[i++] = '\\' ; ch[i++] = 't' ; break ;
653 case '\a': ch[i++] = '\\' ; ch[i++] = 'a' ; break ;
654 case '\v': ch[i++] = '\\' ; ch[i++] = 'v' ; break ;
655 case '\b': ch[i++] = '\\' ; ch[i++] = 'b' ; break ;
656
657 case '\\': ch[i++] = '\\';
658 if( !Dont_Encode_Slash ) ch[i++] = '\\';
659 break ;
660 }
661 }
662 ch[i] = '\0' ;
663 for( i-- ; i > 0 ; i-- ) if( isspace(ch[i]) ) ch[i] = '\0' ; else break ;
664 return ch ;
665 }
666