1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/names.c,v 1.10 2011/05/16 16:21:58 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_NAMES_C_
22 
23 #include "tgifdefs.h"
24 #include "cmdids.h"
25 
26 #include "auxtext.e"
27 #include "box.e"
28 #include "button.e"
29 #include "choose.e"
30 #include "cutpaste.e"
31 #include "cursor.e"
32 #include "dialog.e"
33 #include "drawing.e"
34 #include "file.e"
35 #include "font.e"
36 #include "import.e"
37 #include "ini.e"
38 #include "mainloop.e"
39 #include "mainmenu.e"
40 #include "menu.e"
41 #include "msg.e"
42 #include "names.e"
43 #include "navigate.e"
44 #include "raster.e"
45 #include "rect.e"
46 #include "remote.e"
47 #include "setup.e"
48 #include "strtbl.e"
49 #include "util.e"
50 #include "xpixmap.e"
51 
52 char curDomainName[MAXPATHLENGTH+1];
53 char curDomainPath[MAXPATHLENGTH+1];
54 char curDir[MAXPATHLENGTH+1];
55 char curLocalDir[MAXPATHLENGTH+1];
56 char curSymDir[MAXPATHLENGTH+1];
57 
58 int doubleClickInterval=300;
59 int importFromLibrary=FALSE;
60 int importingFromExec=FALSE;
61 int curDirIsLocal=TRUE;
62 
63 int ignoreDirectoryFlag=FALSE;
64 
65 static int domainInIni=FALSE;
66 static int domainInResource=TRUE;
67 
68 static char curImportDir[MAXPATHLENGTH+1];
69 
70 static DspList *symbolList=NULL;
71 static int numSymbols=0;
72 static DspList *dirList=NULL;
73 static int numDirEntries=0;
74 
75 static DspList *topOfSymLinkList=NULL, *topOfDirLinkList=NULL;
76 
77 static
CleanUpDirList()78 void CleanUpDirList()
79 {
80    DspList *dsp_ptr=NULL, *next_dsp=NULL;
81 
82    for (dsp_ptr=topOfDirLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
83       next_dsp = dsp_ptr->next;
84       free(dsp_ptr);
85    }
86    topOfDirLinkList = NULL;
87 }
88 
89 static
CleanUpSymList()90 void CleanUpSymList()
91 {
92    DspList *dsp_ptr=NULL, *next_dsp=NULL;
93 
94    for (dsp_ptr=topOfSymLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
95       next_dsp = dsp_ptr->next;
96       free(dsp_ptr);
97    }
98    topOfSymLinkList = NULL;
99 }
100 
101 static
ReadPath(path_str,dir_str)102 char *ReadPath(path_str, dir_str)
103    char *path_str, *dir_str;
104 {
105    register char *s1, *s2;
106 
107    s1 = path_str;
108    while (*s1==' ' || *s1=='\t' || *s1=='\n') s1++;
109    if (*s1 == '~') {
110       strcpy(dir_str, homeDir);
111       s2 = &dir_str[strlen(dir_str)];
112       s1++;
113    } else {
114       s2 = dir_str;
115    }
116    for ( ; *s1 != '\0' && *s1 != ':'; s1++) {
117       if (*s1 == '\\') {
118          UtilStrCpy(s1, s1+1);
119       } else {
120          *s2++ = *s1;
121       }
122    }
123    *s2 = '\0';
124    if (*s1 == ':') s1++;
125    return s1;
126 }
127 
128 static
CleanUpSymPath()129 void CleanUpSymPath()
130 {
131    if (symPath != NULL) {
132       int i;
133 
134       for (i=0; i < symPathNumEntries; i++) {
135          if (symPath[i] != NULL) {
136             free(symPath[i]);
137          }
138       }
139       if (symPath != NULL) free(symPath);
140       symPath = NULL;
141    }
142 }
143 
ParseSymPath(path_str)144 void ParseSymPath(path_str)
145    char *path_str;
146 {
147    int i, path_len=0;
148    char *s, dir_str[MAXPATHLENGTH+1];
149 
150    CleanUpSymPath();
151 
152    for (i=0, s=path_str; *s != '\0'; ) {
153       s = ReadPath(s, dir_str);
154       UtilTrimBlanks(dir_str);
155       if (*dir_str != '\0') i++;
156    }
157    symPath = (char**)malloc(i*sizeof(char*));
158    if (symPath == NULL) FailAllocMessage();
159    symPathNumEntries = i;
160    *curDomainPath = '\0';
161    for (i=0, s=path_str; *s != '\0'; ) {
162       s = ReadPath(s, dir_str);
163       UtilTrimBlanks(dir_str);
164       if (*dir_str != '\0') {
165          symPath[i] = (char*)malloc((MAXPATHLENGTH+1)*sizeof(char));
166          if (symPath[i] == NULL) FailAllocMessage();
167          strcpy(symPath[i], dir_str);
168          if (path_len == 0) {
169             sprintf(&curDomainPath[path_len], "%s", dir_str);
170             path_len += strlen(dir_str);
171          } else {
172             sprintf(&curDomainPath[path_len], ":%s", dir_str);
173             path_len += strlen(dir_str)+1;
174          }
175          i++;
176       }
177    }
178 }
179 
180 static
LargerStr(S1,S2)181 int LargerStr(S1, S2)
182    register char *S1, *S2;
183    /* returns TRUE if S1 > S2 */
184 {
185    while (*S1 == *S2 && *S1 != '\0' && *S2 != '\0') { S1++; S2++; }
186 
187    return (*S1 > *S2);
188 }
189 
190 static
SymbolListing()191 DspList *SymbolListing()
192 {
193    int len, path_index, count = 0, reject, sym_ext_len, pin_ext_len;
194    char path[MAXPATHLENGTH], sym_ext_str[MAXSTRING], pin_ext_str[MAXSTRING];
195    DspList *dsp_ptr, *head_ptr, *tail_ptr, *p, *p1;
196    DIR *dirp;
197    DIR_ENTRY *d;
198 
199    head_ptr = tail_ptr = NULL;
200 
201    sprintf(sym_ext_str, ".%s", SYM_FILE_EXT);
202    sym_ext_len = strlen(sym_ext_str);
203    sprintf(pin_ext_str, ".%s", PIN_FILE_EXT);
204    pin_ext_len = strlen(pin_ext_str);
205    for (path_index = 0; path_index < symPathNumEntries; path_index++) {
206       strcpy(path, symPath[path_index]);
207       if (strcmp(".", path) == 0) {
208          if (curDirIsLocal) {
209             strcpy(path, curDir);
210          } else {
211             strcpy(path, curLocalDir);
212          }
213       }
214       if ((dirp=opendir(path)) == NULL) {
215          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_DIR_FOR_READING),
216                path);
217          Msg(gszMsgBox);
218          continue;
219       }
220       while ((d=readdir(dirp)) != NULL) {
221          int symbol_is_pin=FALSE;
222 
223          len = strlen(d->d_name);
224          if (len > sym_ext_len &&
225                (strcmp(sym_ext_str, &d->d_name[len-sym_ext_len]) == 0)) {
226             d->d_name[len-sym_ext_len] = '\0';
227          } else if (len > pin_ext_len &&
228                (strcmp(pin_ext_str, &d->d_name[len-pin_ext_len]) == 0)) {
229             d->d_name[len-pin_ext_len] = '\0';
230             symbol_is_pin = TRUE;
231          } else {
232             continue;
233          }
234          if (head_ptr == NULL) {
235             head_ptr = tail_ptr = (DspList*)malloc(sizeof(DspList));
236             if (head_ptr == NULL) FailAllocMessage();
237             memset(head_ptr, 0, sizeof(DspList));
238             UtilStrCpyN(head_ptr->itemstr, sizeof(head_ptr->itemstr),
239                   d->d_name);
240             UtilStrCpyN(head_ptr->pathstr, sizeof(head_ptr->pathstr), path);
241             /* The directory field is TRUE if the entry has PIN_FILE_EXT. */
242             head_ptr->directory = symbol_is_pin;
243          } else {
244             p1 = NULL;
245             reject = FALSE;
246             for (p=head_ptr; p != NULL; p = p->next) {
247                if (strcmp(d->d_name, p->itemstr) == 0) {
248                   reject = TRUE;
249                   break;
250                } else if (LargerStr(d->d_name, p->itemstr)) {
251                   p1 = p;
252                } else {
253                   break;
254                }
255             }
256             if (reject) continue;
257 
258             dsp_ptr = (DspList*)malloc(sizeof(DspList));
259             if (dsp_ptr == NULL) FailAllocMessage();
260             memset(dsp_ptr, 0, sizeof(DspList));
261             dsp_ptr->next = p;
262             UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), d->d_name);
263             UtilStrCpyN(dsp_ptr->pathstr, sizeof(dsp_ptr->pathstr), path);
264             /* The directory field is TRUE if the entry has PIN_FILE_EXT. */
265             dsp_ptr->directory = symbol_is_pin;
266 
267             if (p == NULL) {
268                /* dsp_ptr has the largest element */
269                tail_ptr->next = dsp_ptr;
270                tail_ptr = dsp_ptr;
271             } else if (p1 == NULL) {
272                head_ptr = dsp_ptr;
273             } else {
274                p1->next = dsp_ptr;
275             }
276          }
277          count++;
278       }
279       closedir(dirp);
280    }
281    numSymbols = count;
282    return head_ptr;
283 }
284 
285 static
BuildSymbolList()286 void BuildSymbolList()
287 {
288    int i=0, watch_cursor=watchCursorOnMainWindow;
289    DspList *dsp_ptr=NULL, *next_dsp=NULL;
290 
291    if (topOfSymLinkList == NULL) {
292       if (!watch_cursor) {
293          SetWatchCursor(drawWindow);
294          SetWatchCursor(mainWindow);
295       }
296       if ((topOfSymLinkList = SymbolListing()) != NULL) BuildSymbolList();
297       if (!watch_cursor) {
298          SetDefaultCursor(mainWindow);
299          ShowCursor();
300       }
301    }
302    if (topOfSymLinkList != NULL) {
303       if (symbolList != NULL) free(symbolList);
304 
305       symbolList = (DspList*)malloc(numSymbols*sizeof(DspList));
306       if (symbolList == NULL) FailAllocMessage();
307       memset(symbolList, 0, numSymbols*sizeof(DspList));
308       dsp_ptr = topOfSymLinkList;
309       for (i=0; i < numSymbols; i++, dsp_ptr = next_dsp) {
310          next_dsp = dsp_ptr->next;
311          UtilStrCpyN(symbolList[i].itemstr, sizeof(symbolList[i].itemstr),
312                dsp_ptr->itemstr);
313          UtilStrCpyN(symbolList[i].pathstr, sizeof(symbolList[i].pathstr),
314                dsp_ptr->pathstr);
315          symbolList[i].directory = dsp_ptr->directory;
316          symbolList[i].next = &symbolList[i+1];
317          free(dsp_ptr);
318       }
319       symbolList[numSymbols-1].next = NULL;
320       topOfSymLinkList = NULL;
321    }
322 }
323 
324 static
DirListing(Path,ExtStr,OtherExtStr)325 DspList *DirListing(Path, ExtStr, OtherExtStr)
326    char *Path, *ExtStr, *OtherExtStr;
327 {
328    DspList *dsp_ptr, *head_ptr, *tail_ptr, *p, *p1;
329    DIR *dirp;
330    DIR_ENTRY *d;
331    int len, ext_len, count = 0;
332    char path[MAXPATHLENGTH], s[MAXPATHLENGTH], *ext_str=NULL;
333    struct stat stat_buf;
334 
335    if (ExtStr != NULL && *ExtStr != '\0') {
336       if (OtherExtStr != NULL && *OtherExtStr != '\0') {
337          ext_len = (strlen(ExtStr)<<1)+3+strlen(OtherExtStr);
338          if ((ext_str=SetUpExtStr(ext_len, ExtStr, OtherExtStr)) == NULL) {
339             return NULL;
340          }
341       } else {
342          ext_len = (strlen(ExtStr)<<1)+3;
343          if ((ext_str=SetUpExtStr(ext_len, ExtStr, "")) == NULL) {
344             return NULL;
345          }
346       }
347    } else if (OtherExtStr != NULL && *OtherExtStr != '\0') {
348       ext_len = strlen(OtherExtStr)+3;
349       if ((ext_str=SetUpExtStr(ext_len, "", OtherExtStr)) == NULL) {
350          return NULL;
351       }
352    }
353    ext_len = (ext_str == NULL ? 0 : strlen(ext_str));
354    if (*Path == '\0') {
355       strcpy(path, DIR_SEP_STR);
356       if ((dirp=opendir(path)) == NULL) {
357          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_DIR_FOR_READING),
358                path);
359          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
360          if (ext_str != NULL) free(ext_str);
361          return NULL;
362       }
363    } else {
364       strcpy(path, Path);
365       if ((dirp=opendir(path)) == NULL) {
366          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_DIR_FOR_READING),
367                path);
368          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
369          if (ext_str != NULL) free(ext_str);
370          return NULL;
371       }
372 #ifdef __CYGWIN__
373       if (path[strlen(path)-1] != DIR_SEP) {
374          strcat(path, DIR_SEP_STR);
375       }
376 #else /* ~__CYGWIN__ */
377       strcat(path, DIR_SEP_STR);
378 #endif /* __CYGWIN__ */
379    }
380 
381 #ifdef VMS
382    /* Fake the .. entry for VMS */
383    head_ptr = tail_ptr = (DspList*)malloc(sizeof(DspList));
384    if (head_ptr == NULL) FailAllocMessage();
385    memset(head_ptr, 0, sizeof(DspList));
386    head_ptr->directory = TRUE;
387    UtilStrCpyN(head_ptr->itemstr, sizeof(head_ptr->itemstr), "../");
388    head_ptr->next = NULL;
389    count = 1;
390 #else
391    head_ptr = tail_ptr = NULL;
392 #endif /* VMS */
393 
394    while ((d=readdir(dirp)) != NULL) {
395       len = strlen(d->d_name);
396       if (ext_len == 0) {
397 #ifdef VMS
398          if (len > 4 && (strcmp(".dir", &d->d_name[len-4]) == 0)) {
399             d->d_name[len-4] = DIR_SEP;
400             d->d_name[len-4+1] = '\0';
401             dsp_ptr = (DspList*)malloc(sizeof(DspList));
402             if (dsp_ptr == NULL) FailAllocMessage();
403             memset(dsp_ptr, 0, sizeof(DspList));
404             dsp_ptr->directory = TRUE;
405             UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), d->d_name);
406          } else if (strcmp(d->d_name, ".") == 0) {
407 #else
408          if (strcmp(d->d_name, ".") == 0) {
409 #endif /* VMS */
410             continue;
411          } else {
412             sprintf(s, "%s%s", path, d->d_name);
413             if (stat(s, &stat_buf) != 0) {
414                int show_msg=TRUE;
415 #ifndef _NO_LSTAT
416                if (lstat(s, &stat_buf) == 0 &&
417                      ((stat_buf.st_mode & S_IFLNK) == S_IFLNK)) {
418                   show_msg = FALSE;
419                }
420 #endif /* _NO_LSTAT */
421                if (show_msg) {
422                   sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_STAT_GIVEN_FILE),
423                         s);
424                   Msg(gszMsgBox);
425                }
426                continue;
427             } else {
428                dsp_ptr = (DspList*)malloc(sizeof(DspList));
429                if (dsp_ptr == NULL) FailAllocMessage();
430                memset(dsp_ptr, 0, sizeof(DspList));
431                if (stat_buf.st_mode & S_IFDIR) {
432                   dsp_ptr->directory = TRUE;
433                   strcat(d->d_name, DIR_SEP_STR);
434                } else {
435                   dsp_ptr->directory = FALSE;
436                }
437                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr),
438                      d->d_name);
439             }
440          }
441       } else if (ExtensionMatch(ext_str, d->d_name)) {
442          dsp_ptr = (DspList*)malloc(sizeof(DspList));
443          if (dsp_ptr == NULL) FailAllocMessage();
444          memset(dsp_ptr, 0, sizeof(DspList));
445          dsp_ptr->directory = FALSE;
446          UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), d->d_name);
447 #ifdef VMS
448       } else if (len > 4 && (strcmp(".dir", &d->d_name[len-4]) == 0)) {
449          d->d_name[len-4] = DIR_SEP;
450          d->d_name[len-4+1] = '\0';
451          dsp_ptr = (DspList*)malloc(sizeof(DspList));
452          if (dsp_ptr == NULL) FailAllocMessage();
453          memset(dsp_ptr, 0, sizeof(DspList));
454          dsp_ptr->directory = TRUE;
455          UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), d->d_name);
456 #endif /* VMS */
457       } else if (strcmp(d->d_name, ".") == 0) {
458          continue;
459       } else {
460          sprintf(s, "%s%s", path, d->d_name);
461          if (stat(s, &stat_buf) != 0) {
462             int show_msg=TRUE;
463 #ifndef _NO_LSTAT
464             if (lstat(s, &stat_buf) == 0 &&
465                   ((stat_buf.st_mode & S_IFLNK) == S_IFLNK)) {
466                show_msg = FALSE;
467             }
468 #endif /* _NO_LSTAT */
469             if (show_msg) {
470                sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_STAT_GIVEN_FILE),
471                      s);
472                Msg(gszMsgBox);
473             }
474             continue;
475          } else if (stat_buf.st_mode & S_IFDIR) {
476             dsp_ptr = (DspList*)malloc(sizeof(DspList));
477             if (dsp_ptr == NULL) FailAllocMessage();
478             memset(dsp_ptr, 0, sizeof(DspList));
479             dsp_ptr->directory = TRUE;
480             strcat(d->d_name, DIR_SEP_STR);
481             UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), d->d_name);
482          } else {
483             continue;
484          }
485       }
486       if (head_ptr == NULL) {
487          head_ptr = tail_ptr = dsp_ptr;
488       } else {
489          p1 = NULL;
490          for (p = head_ptr; p != NULL; p = p->next) {
491             if (LargerStr(d->d_name, p->itemstr)) {
492                p1 = p;
493             } else {
494                break;
495             }
496          }
497          dsp_ptr->next = p;
498          if (p == NULL) {
499             /* dsp_ptr has the largest element */
500             tail_ptr->next = dsp_ptr;
501             tail_ptr = dsp_ptr;
502          } else if (p1 == NULL) {
503             head_ptr = dsp_ptr;
504          } else {
505             p1->next = dsp_ptr;
506          }
507       }
508       count++;
509    }
510    closedir(dirp);
511    numDirEntries = count;
512    if (ext_str != NULL) free(ext_str);
513    return head_ptr;
514 }
515 
516 static
BuildDirList()517 void BuildDirList()
518 {
519    int i=0, watch_cursor=watchCursorOnMainWindow;
520    DspList *dsp_ptr=NULL, *next_dsp=NULL;
521 
522    if (topOfDirLinkList == NULL) {
523       if (!watch_cursor) {
524          SetWatchCursor(drawWindow);
525          SetWatchCursor(mainWindow);
526       }
527       if (curDirIsLocal) {
528          if ((topOfDirLinkList=DirListing(curDir, OBJ_FILE_EXT, "")) != NULL) {
529             BuildDirList();
530          }
531       } else if ((topOfDirLinkList=DirListing(curLocalDir, OBJ_FILE_EXT, "")) !=
532             NULL) {
533          BuildDirList();
534       }
535       if (!watch_cursor) {
536          SetDefaultCursor(mainWindow);
537          ShowCursor();
538       }
539    }
540    if (topOfDirLinkList != NULL) {
541       if (dirList != NULL) free(dirList);
542 
543       dirList = (DspList*)malloc(numDirEntries*sizeof(DspList));
544       if (dirList == NULL) FailAllocMessage();
545       memset(dirList, 0, numDirEntries*sizeof(DspList));
546       dsp_ptr = topOfDirLinkList;
547       for (i=0; i < numDirEntries; i++, dsp_ptr = next_dsp) {
548          next_dsp = dsp_ptr->next;
549          UtilStrCpyN(dirList[i].itemstr, sizeof(dirList[i].itemstr),
550                dsp_ptr->itemstr);
551          UtilStrCpyN(dirList[i].pathstr, sizeof(dirList[i].pathstr),
552                dsp_ptr->pathstr);
553          dirList[i].directory = dsp_ptr->directory;
554          dirList[i].next = &dirList[i+1];
555          free(dsp_ptr);
556       }
557       dirList[numDirEntries-1].next = NULL;
558       topOfDirLinkList = NULL;
559    }
560 }
561 
562 static char gszDefaultDomainSec[]="DefaultDomain";
563 static char gszDomainPathsSec[]="DomainPaths";
564 static char gszDomainIniFile[MAXPATHLENGTH];
565 
566 static
InitDomain()567 void InitDomain()
568 {
569    char *c_ptr=NULL, domain_str[20], sym_path[80], cap_tool_name[MAXSTRING];
570    int default_found=FALSE, need_to_copy_domain_into_ini=FALSE;
571    char *pszDomainNames=NULL, *psz_default_path=NULL;
572 
573    sprintf(gszDomainIniFile, "%s%cdomain.ini", tgifDir, DIR_SEP);
574 
575    domainInIni = FALSE;
576    domainInResource = TRUE;
577    if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "DomainInIni")) != NULL &&
578          UtilStrICmp(c_ptr, "true") == 0) {
579       if ((pszDomainNames=tgGetProfileString(gszDomainPathsSec, NULL,
580             gszDomainIniFile)) != NULL) {
581          domainInIni = TRUE;
582          domainInResource = FALSE;
583          tgFreeProfileString(pszDomainNames);
584       } else {
585          need_to_copy_domain_into_ini = TRUE;
586       }
587    }
588    if (domainInIni && (pszDomainNames=tgGetProfileString(gszDomainPathsSec,
589          NULL, gszDomainIniFile)) != NULL) {
590       char *pszKeys=NULL;
591 
592       if ((pszKeys=tgGetProfileString(gszDefaultDomainSec, NULL,
593             gszDomainIniFile)) != NULL) {
594          char *pszKey=pszKeys;
595          char *pszPath=tgGetProfileString(gszDomainPathsSec, pszKey,
596                gszDomainIniFile);
597 
598          if (pszPath != NULL || strcmp(pszKey, "Examples") == 0) {
599             psz_default_path = UtilStrDup(pszPath==NULL ? TGIF_PATH : pszPath);
600             if (psz_default_path == NULL) FailAllocMessage();
601 
602             UtilStrCpyN(curDomainName, sizeof(curDomainName), pszKey);
603             default_found = TRUE;
604             tgFreeProfileString(pszPath);
605          }
606          tgFreeProfileString(pszKeys);
607       }
608       if (!default_found) {
609          /* just pick the first one */
610          char *pszKey=pszDomainNames;
611          char *pszPath=tgGetProfileString(gszDomainPathsSec, pszKey,
612                gszDomainIniFile);
613 
614          if (pszPath != NULL) {
615             psz_default_path = UtilStrDup(pszPath);
616             if (psz_default_path == NULL) FailAllocMessage();
617 
618             UtilStrCpyN(curDomainName, sizeof(curDomainName), pszKey);
619             default_found = TRUE;
620             tgFreeProfileString(pszPath);
621          }
622          tgFreeProfileString(pszKeys);
623       }
624       tgFreeProfileString(pszDomainNames);
625    }
626    if (domainInResource && (c_ptr=XGetDefault(mainDisplay, TOOL_NAME,
627          "DefaultDomain")) != NULL) {
628       int default_domain=atoi(c_ptr);
629 
630       sprintf(domain_str, "DomainPath%1d", default_domain);
631       if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, domain_str)) != NULL) {
632          char *c_ptr1;
633 
634          while (*c_ptr==' ' || *c_ptr=='\t' || *c_ptr=='\n') c_ptr++;
635          if (*c_ptr != '\0' && (c_ptr1=strchr(c_ptr, ':')) != NULL) {
636             int len=c_ptr1-c_ptr;
637 
638             strncpy(curDomainName, c_ptr, len);
639             curDomainName[len] = '\0';
640             psz_default_path = UtilStrDup(++c_ptr1);
641             if (psz_default_path == NULL) FailAllocMessage();
642             default_found = TRUE;
643          }
644       } else {
645          sprintf(domain_str, "Domain%1d", default_domain);
646          if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, domain_str)) != NULL) {
647             if (*c_ptr != '\0') {
648                strcpy(cap_tool_name, TOOL_NAME);
649                UtilStrUpper(cap_tool_name);
650                strcpy(curDomainName, c_ptr);
651                sprintf(sym_path, "%s_%s", cap_tool_name, c_ptr);
652                default_found = TRUE;
653                domainInResource = FALSE;
654             }
655          }
656       }
657    }
658    if (default_found) {
659       if (domainInIni || domainInResource) {
660          ParseSymPath(psz_default_path);
661       } else if ((c_ptr=getenv(sym_path)) == NULL ||
662             ((int)strlen(c_ptr)) >= MAXPATHLENGTH-1) {
663          ParseSymPath(".");
664       } else {
665          ParseSymPath(c_ptr);
666       }
667    } else {
668       char buf[MAXPATHLENGTH];
669 
670       strcpy(buf, ".:");
671       UtilStrCpyN(&buf[2], sizeof(buf)-2, TGIF_PATH);
672       ParseSymPath(buf);
673    }
674    if (need_to_copy_domain_into_ini) {
675       CopyDomainInfoToIni();
676       tgWriteProfileString(gszDefaultDomainSec, curDomainName, "",
677             gszDomainIniFile);
678       tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
679 
680       if ((pszDomainNames=tgGetProfileString(gszDomainPathsSec, NULL,
681             gszDomainIniFile)) != NULL) {
682          domainInIni = TRUE;
683          domainInResource = FALSE;
684          tgFreeProfileString(pszDomainNames);
685       }
686    }
687    UtilFree(psz_default_path);
688 }
689 
InitNames()690 void InitNames()
691 {
692    char *c_ptr=NULL;
693 
694    if (mainDisplay != NULL) InitNamesInfo();
695 
696    ignoreDirectoryFlag = FALSE;
697 
698    symbolList = dirList = NULL;
699    numSymbols = numDirEntries = 0;
700    topOfSymLinkList = topOfDirLinkList = NULL;
701 
702    *curDomainName = '\0';
703    *curDomainPath = '\0';
704    *curSymDir = '\0';
705    strcpy(curDir, bootDir);
706    strcpy(curLocalDir, bootDir);
707    strcpy(curImportDir, bootDir);
708 
709    if (mainDisplay == NULL) return;
710 
711    if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "DoubleClickInterval")) !=
712          NULL) {
713       doubleClickInterval = atoi(c_ptr);
714    } else {
715       doubleClickInterval = 300;
716    }
717    warpToWinCenter = TRUE;
718    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"WarpToWinCenter")) != NULL) {
719       if (UtilStrICmp(c_ptr, "false") == 0) {
720          warpToWinCenter = FALSE;
721       }
722    }
723    importFromLibrary = FALSE;
724    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ImportFromLibrary")) != NULL) {
725       if (UtilStrICmp(c_ptr, "true") == 0) {
726          importFromLibrary = TRUE;
727       }
728    }
729    InitDomain();
730 }
731 
UpdateDirInfo()732 void UpdateDirInfo()
733 {
734    CleanUpDirList();
735 }
736 
UpdateSymInfo()737 void UpdateSymInfo()
738 {
739    CleanUpSymList();
740 }
741 
CleanUpNames()742 void CleanUpNames()
743 {
744    CleanUpNamesInfo();
745 
746    CleanUpSymPath();
747    if (symbolList != NULL) free(symbolList);
748    if (dirList != NULL) free(dirList);
749    symbolList = dirList = NULL;
750    ignoreDirectoryFlag = FALSE;
751 }
752 
MakeNameDspItemArray(Entries,DLPtr)753 char **MakeNameDspItemArray(Entries, DLPtr)
754    int Entries;
755    DspList *DLPtr;
756 {
757    int i, j, len;
758    char **dsp_ptr, *c_ptr;
759 
760    if (Entries == 0) return NULL;
761 
762    dsp_ptr = (char**)malloc(Entries*sizeof(char*));
763    if (dsp_ptr == NULL) FailAllocMessage();
764    c_ptr = (char*)malloc(Entries*(MAXPATHLENGTH+1)*sizeof(char));
765    if (c_ptr == NULL) FailAllocMessage();
766    for (i=0; i < Entries; i++, DLPtr=DLPtr->next) {
767       dsp_ptr[i] = c_ptr;
768       len = strlen(DLPtr->itemstr);
769       if (!ignoreDirectoryFlag && !DLPtr->directory) {
770          for (j = len; j >= 0 && DLPtr->itemstr[j] != DIR_SEP; j--) ;
771          if (j >= 0) {
772             strcpy(c_ptr, (&(DLPtr->itemstr[j]))+1);
773          } else {
774             strcpy(c_ptr, DLPtr->itemstr);
775          }
776       } else {
777          strcpy(c_ptr, DLPtr->itemstr);
778       }
779       c_ptr += MAXPATHLENGTH;
780    }
781    return dsp_ptr;
782 }
783 
DirInSymPath(DirName)784 int DirInSymPath(DirName)
785    char *DirName;
786 {
787    register int i;
788 
789    if (symPath == NULL) return FALSE;
790 
791    for (i = 0; i < symPathNumEntries; i++) {
792       if (strcmp(DirName, symPath[i]) == 0) {
793          return TRUE;
794       }
795    }
796    return FALSE;
797 }
798 
799 static int lengthOfLongestItem=INVALID;
800 
801 static
MakeLongNameDspItemArray(Entries,DLPtr)802 char **MakeLongNameDspItemArray(Entries, DLPtr)
803    int Entries;
804    DspList *DLPtr;
805 {
806    int i, len;
807    char **dsp_ptr, *c_ptr;
808 
809    lengthOfLongestItem = INVALID;
810 
811    if (Entries == 0) return NULL;
812 
813    dsp_ptr = (char**)malloc(Entries*sizeof(char*));
814    if (dsp_ptr == NULL) FailAllocMessage();
815    c_ptr = (char*)malloc(Entries*(MAXPATHLENGTH+1)*sizeof(char));
816    if (c_ptr == NULL) FailAllocMessage();
817    for (i=0; i < Entries; i++, DLPtr=DLPtr->next) {
818       dsp_ptr[i] = c_ptr;
819       len = strlen(DLPtr->itemstr);
820       strcpy(c_ptr, DLPtr->itemstr);
821       if (len > lengthOfLongestItem) lengthOfLongestItem = len;
822 
823       c_ptr += MAXPATHLENGTH;
824    }
825    return dsp_ptr;
826 }
827 
828 struct DirNamesInfoRec {
829    char ext_str[81], other_ext_str[81];
830 } dirNamesInfo;
831 
832 static
GetNamesEntries(p_dsp_ptr,p_entries,pn_num_entries,pn_marked_index,pp_check_array,cur_buf,p_void)833 int GetNamesEntries(p_dsp_ptr, p_entries, pn_num_entries, pn_marked_index,
834       pp_check_array, cur_buf, p_void)
835    DspList **p_dsp_ptr;
836    char ***p_entries, *cur_buf;
837    int *pn_num_entries, *pn_marked_index;
838    struct CheckArrayRec **pp_check_array;
839    void *p_void;
840 {
841    struct DirNamesInfoRec *p_dninfo=(struct DirNamesInfoRec*)p_void;
842    DspList *dsp_ptr, *next_dsp;
843 
844    for (dsp_ptr=topOfDirLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
845       next_dsp = dsp_ptr->next;
846       free(dsp_ptr);
847    }
848    topOfDirLinkList = NULL;
849 
850    *p_dsp_ptr = NULL;
851    *p_entries = NULL;
852    *pn_num_entries = 0;
853    *pn_marked_index = INVALID;
854 
855    if (*cur_buf == '\0') {
856       /* this can only happen if the change_to_root */
857       return TRUE;
858    } else {
859       char status_buf[MAX_STATUS_BTNS+1][MAXSTRING+1];
860       int one_line_status=FALSE;
861 
862       SaveStatusStringsIntoBuf(status_buf, &one_line_status);
863       sprintf(gszMsgBox, TgLoadCachedString(CSTID_GET_DIR_LIST_PLEASE_WAIT),
864             cur_buf);
865       SetStringStatus(gszMsgBox);
866       XSync(mainDisplay, False);
867 
868       if ((topOfDirLinkList=DirListing(cur_buf,
869             p_dninfo->ext_str, p_dninfo->other_ext_str)) == NULL) {
870          RestoreStatusStringsFromBuf(status_buf, one_line_status);
871          return FALSE;
872       }
873       RestoreStatusStringsFromBuf(status_buf, one_line_status);
874       *pn_num_entries = numDirEntries;
875       if (topOfDirLinkList == NULL) {
876          *p_entries = MakeNameDspItemArray(*pn_num_entries, dirList);
877       } else {
878          *p_entries = MakeNameDspItemArray(*pn_num_entries, topOfDirLinkList);
879       }
880    }
881    return TRUE;
882 }
883 
884 static
NamesAfterLoop(p_dsp_ptr,p_entries,pn_num_entries,pn_marked_index,pp_check_array,cur_buf,btn_id,selected_index,p_void)885 int NamesAfterLoop(p_dsp_ptr, p_entries, pn_num_entries, pn_marked_index,
886       pp_check_array, cur_buf, btn_id, selected_index, p_void)
887    DspList **p_dsp_ptr;
888    char ***p_entries, *cur_buf;
889    int *pn_num_entries, *pn_marked_index, btn_id, selected_index;
890    struct CheckArrayRec **pp_check_array;
891    void *p_void;
892 {
893    if (*p_dsp_ptr != NULL) free(*p_dsp_ptr);
894    if (*p_entries != NULL) {
895       free(**p_entries);
896       free(*p_entries);
897    }
898    *p_dsp_ptr = NULL;
899    *p_entries = NULL;
900    *pn_num_entries = 0;
901 
902    switch (btn_id) {
903    case BUTTON_OK: break;
904    case BUTTON_SETDIR:
905       if (cur_buf != NULL) {
906          int len=strlen(cur_buf);
907 
908          if (len > 4 && cur_buf[len-4] == DIR_SEP && cur_buf[len-3] == '.' &&
909                cur_buf[len-2] == '.' && cur_buf[len-1] == DIR_SEP) {
910             break;
911          }
912       }
913       return FALSE;
914    case BUTTON_CANCEL: break;
915    }
916    return TRUE;
917 }
918 
919 static
DirNames(TopStr,ExtStr,SelStr,JustSetDir)920 int DirNames(TopStr, ExtStr, SelStr, JustSetDir)
921    char *TopStr, *ExtStr, *SelStr;
922    int *JustSetDir;
923 {
924    char win_name[128], selected_str[MAXSTRING+1];
925    int selected_index=INVALID, selected_btn_id;
926    struct DirNamesInfoRec dninfo;
927 
928    *SelStr = '\0';
929    *JustSetDir = FALSE;
930 
931    memset(&dninfo, 0, sizeof(struct DirNamesInfoRec));
932 
933    UtilStrCpyN(dirNamesInfo.ext_str, sizeof(dirNamesInfo.ext_str), ExtStr);
934    UtilStrCpyN(dirNamesInfo.other_ext_str, sizeof(dirNamesInfo.other_ext_str),
935          ExtStr);
936 
937    if (ExtStr != NULL && strcmp(ExtStr, EPSF_FILE_EXT) == 0) {
938       sprintf(dirNamesInfo.other_ext_str, ".%s;.epsi", PS_FILE_EXT);
939    } else if (ExtStr != NULL && strcmp(ExtStr, OBJ_FILE_EXT) == 0) {
940       sprintf(dirNamesInfo.other_ext_str, ".%s;.%s", SYM_FILE_EXT,
941             PIN_FILE_EXT);
942       if (strstr(dirNamesInfo.other_ext_str, ".obj") == NULL) {
943          strcat(dirNamesInfo.other_ext_str, ";.obj");
944       }
945       if (strstr(dirNamesInfo.other_ext_str, ".sym") == NULL) {
946          strcat(dirNamesInfo.other_ext_str, ";.sym");
947       }
948       if (strstr(dirNamesInfo.other_ext_str, ".pin") == NULL) {
949          strcat(dirNamesInfo.other_ext_str, ";.pin");
950       }
951       if (strstr(dirNamesInfo.other_ext_str, ".tgo") == NULL) {
952          strcat(dirNamesInfo.other_ext_str, ";.tgo");
953       }
954       if (strstr(dirNamesInfo.other_ext_str, ".tgs") == NULL) {
955          strcat(dirNamesInfo.other_ext_str, ";.tgs");
956       }
957       if (strstr(dirNamesInfo.other_ext_str, ".tgp") == NULL) {
958          strcat(dirNamesInfo.other_ext_str, ";.tgp");
959       }
960       sprintf(selected_str, ";.obj.gz;.tgo.gz;.%s.gz", OBJ_FILE_EXT);
961       strcat(dirNamesInfo.other_ext_str, selected_str);
962    } else if (ExtStr != NULL && strcmp(ExtStr, "gif") == 0) {
963       strcpy(dirNamesInfo.other_ext_str, ".GIF");
964    } else if (ExtStr != NULL && strcmp(ExtStr, "png") == 0) {
965       strcpy(dirNamesInfo.other_ext_str, ".PNG");
966    } else if (ExtStr != NULL && strcmp(ExtStr, "jpeg") == 0) {
967       strcpy(dirNamesInfo.other_ext_str, ".JPEG;.jpg;.JPG");
968    } else {
969       *dirNamesInfo.other_ext_str = '\0';
970    }
971    ResetNamesInfo();
972    NamesSetTitle(TopStr);
973    NamesAddButton(TgLoadCachedString(CSTID_OK), BUTTON_OK);
974    if (!(importingFile || (curFileDefined && curDirIsLocal))) {
975       NamesAddButton(TgLoadString(STID_SET_WORKING_DIR), BUTTON_SETDIR);
976    }
977    NamesAddButton(TgLoadCachedString(CSTID_CANCEL), BUTTON_CANCEL);
978    NamesSetEntries(NULL, NULL, 0, NULL, TRUE, INVALID, 0);
979    NamesSetStyle(NAMES_SELECT_FILE, NAMES_LOOP_MANY);
980    NamesSetCallback((GetEntriesFunc*)GetNamesEntries,
981          (AfterLoopFunc*)NamesAfterLoop, NULL);
982    if (importingFile) {
983       NamesSetDir(curImportDir);
984    } else if (curDirIsLocal) {
985       NamesSetDir(curDir);
986    } else {
987       NamesSetDir(curLocalDir);
988    }
989    if (!(importingFile || (curFileDefined && curDirIsLocal))) {
990       Msg(TgLoadString(STID_CLICK_SETWORKDIR_TO_SET_DIR));
991    }
992    *selected_str = '\0';
993 
994    sprintf(win_name, "%s - %s", TOOL_NAME, TopStr);
995    selected_btn_id = Names(win_name, &selected_index,
996          selected_str, sizeof(selected_str), &dirNamesInfo);
997    if (selected_btn_id == BUTTON_OK) {
998       *JustSetDir = FALSE;
999       strcpy(SelStr, selected_str);
1000       if (FileIsRemote(selected_str)) {
1001          /* index != INVALID means SelStr is valid */
1002          return 0;
1003       }
1004       return selected_index;
1005    } else if (selected_btn_id == BUTTON_SETDIR) {
1006       if (DirIsRemote(selected_str)) {
1007          *SelStr = '\0';
1008          *JustSetDir = FALSE;
1009          sprintf(gszMsgBox, TgLoadString(STID_SETWORKDIR_NOT_SUP_FOR_STR),
1010                selected_str);
1011          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1012       } else {
1013          int len=strlen(selected_str);
1014 
1015          if (len > 0 && selected_str[len-1] == DIR_SEP) {
1016             UtilShrinkName(selected_str);
1017             len = strlen(selected_str);
1018          }
1019          if (len > 0) {
1020             if (selected_str[len-1] == DIR_SEP) {
1021                selected_str[--len] = '\0';
1022             } else {
1023                while (len > 0 && selected_str[len-1] != DIR_SEP) {
1024                   selected_str[--len] = '\0';
1025                }
1026                if (len > 0) selected_str[--len] = '\0';
1027             }
1028          }
1029          strcpy(SelStr, selected_str);
1030          *JustSetDir = TRUE;
1031       }
1032    }
1033    return INVALID;
1034 }
1035 
1036 static
ChooseAName(TopStr,entries,num_entries,marked_index)1037 int ChooseAName(TopStr, entries, num_entries, marked_index)
1038    char *TopStr, **entries;
1039    int num_entries, marked_index;
1040 {
1041    char win_name[128];
1042    int selected_index=INVALID;
1043 
1044    ResetNamesInfo();
1045    NamesSetTitle(TopStr);
1046    NamesAddButton(TgLoadCachedString(CSTID_OK), BUTTON_OK);
1047    NamesAddButton(TgLoadCachedString(CSTID_CANCEL), BUTTON_CANCEL);
1048    NamesSetEntries(NULL, entries, num_entries, NULL, TRUE, marked_index, 0);
1049    NamesSetStyle(NAMES_COMPLEX_SELECT_NAME, NAMES_LOOP_ONCE);
1050    sprintf(win_name, "%s - %s", TOOL_NAME, TopStr);
1051    if (Names(win_name, &selected_index, NULL, 0, NULL) == BUTTON_OK) {
1052       return selected_index;
1053    }
1054    return INVALID;
1055 }
1056 
SelectFileName(MsgStr,SelStr)1057 int SelectFileName(MsgStr, SelStr)
1058    char *MsgStr, *SelStr;
1059 {
1060    int index, saved_num_dir_entries, just_set_dir;
1061    DspList *dsp_ptr, *next_dsp;
1062    char saved_cur_dir[MAXPATHLENGTH];
1063 
1064    if (curDirIsLocal) {
1065       strcpy(saved_cur_dir, curDir);
1066    } else {
1067       strcpy(saved_cur_dir, curLocalDir);
1068    }
1069    saved_num_dir_entries = numDirEntries;
1070    if ((index=DirNames(MsgStr,OBJ_FILE_EXT,SelStr,&just_set_dir)) == INVALID) {
1071       if (just_set_dir) {
1072          if (curDirIsLocal) {
1073             strcpy(curDir, SelStr);
1074          } else {
1075             strcpy(curLocalDir, SelStr);
1076          }
1077          BuildDirList();
1078          if (strcmp(saved_cur_dir, curDir) != 0 && DirInSymPath(".")) {
1079             UpdateSymInfo();
1080          }
1081          RedrawTitleWindow();
1082          sprintf(gszMsgBox, TgLoadString(STID_OPENSAVE_DIR_CHANGE_TO_REMAIN),
1083                curDir, curImportDir);
1084          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1085          Msg("");
1086       } else {
1087          numDirEntries = saved_num_dir_entries;
1088          for (dsp_ptr=topOfDirLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
1089             next_dsp = dsp_ptr->next;
1090             free(dsp_ptr);
1091          }
1092          topOfDirLinkList = NULL;
1093       }
1094       *SelStr = '\0';
1095       return INVALID;
1096    }
1097    BuildDirList();
1098    Msg("");
1099    return index;
1100 }
1101 
SelectFileNameToPaste(MsgStr,SelStr)1102 int SelectFileNameToPaste(MsgStr, SelStr)
1103    char *MsgStr, *SelStr;
1104 {
1105    int index, saved_num_dir_entries, just_set_dir;
1106    DspList *dsp_ptr, *next_dsp;
1107    char saved_cur_dir[MAXPATHLENGTH];
1108 
1109    if (curDirIsLocal) {
1110       strcpy(saved_cur_dir, curDir);
1111    } else {
1112       strcpy(saved_cur_dir, curLocalDir);
1113    }
1114    saved_num_dir_entries = numDirEntries;
1115    if ((index=DirNames(MsgStr,NULL,SelStr,&just_set_dir)) == INVALID) {
1116       if (just_set_dir) {
1117          if (curDirIsLocal) {
1118             strcpy(curDir, SelStr);
1119          } else {
1120             strcpy(curLocalDir, SelStr);
1121          }
1122          BuildDirList();
1123          if (strcmp(saved_cur_dir, curDir) != 0 && DirInSymPath(".")) {
1124             UpdateSymInfo();
1125          }
1126          RedrawTitleWindow();
1127          sprintf(gszMsgBox, TgLoadString(STID_OPENSAVE_DIR_CHANGE_TO_REMAIN),
1128                curDir, curImportDir);
1129          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1130          Msg("");
1131       } else {
1132          numDirEntries = saved_num_dir_entries;
1133          for (dsp_ptr=topOfDirLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
1134             next_dsp = dsp_ptr->next;
1135             free(dsp_ptr);
1136          }
1137          topOfDirLinkList = NULL;
1138       }
1139       *SelStr = '\0';
1140       return INVALID;
1141    }
1142    BuildDirList();
1143    Msg("");
1144    return index;
1145 }
1146 
SelectFileNameToImport(MsgStr,ExtStr,SelStr)1147 int SelectFileNameToImport(MsgStr, ExtStr, SelStr)
1148    char *MsgStr, *ExtStr, *SelStr;
1149 {
1150    int index, saved_num_dir_entries, just_set_dir;
1151    DspList *dsp_ptr, *next_dsp;
1152 
1153    saved_num_dir_entries = numDirEntries;
1154    if ((index=DirNames(MsgStr, ExtStr, SelStr, &just_set_dir)) == INVALID) {
1155       if (just_set_dir) {
1156          /* This should not happen since SetDir is removed during importing. */
1157          strcpy(curImportDir, SelStr);
1158          sprintf(gszMsgBox, TgLoadString(STID_IMPORT_DIR_CHANGED_TO_REMAIN),
1159                curImportDir, curDir);
1160          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1161       }
1162       *SelStr = '\0';
1163    } else {
1164       Msg("");
1165    }
1166    numDirEntries = saved_num_dir_entries;
1167    for (dsp_ptr=topOfDirLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
1168       next_dsp = dsp_ptr->next;
1169       free(dsp_ptr);
1170    }
1171    topOfDirLinkList = NULL;
1172 
1173    return index;
1174 }
1175 
GetSymbolPath(SymName,Pin,PathName)1176 int GetSymbolPath(SymName, Pin, PathName)
1177    char *SymName, *PathName;
1178    int Pin;
1179 {
1180    int i;
1181 
1182    if (topOfSymLinkList == NULL) {
1183       if ((topOfSymLinkList=SymbolListing()) != NULL) BuildSymbolList();
1184    }
1185    if (symbolList == NULL) return FALSE;
1186 
1187    for (i = 0; i < numSymbols; i++) {
1188       /* The directory field is TRUE if the entry has PIN_FILE_EXT. */
1189       if (symbolList[i].directory == Pin &&
1190             strcmp(SymName, symbolList[i].itemstr) == 0) {
1191          strcpy(PathName, symbolList[i].pathstr);
1192          return TRUE;
1193       }
1194    }
1195    return FALSE;
1196 }
1197 
NameInCurDir(FileName)1198 int NameInCurDir(FileName)
1199    char *FileName;
1200 {
1201    int i;
1202 
1203    if (dirList == NULL) return FALSE;
1204 
1205    for (i = 0; i < numDirEntries; i++) {
1206       if (dirList[i].directory && strcmp(FileName, dirList[i].itemstr) == 0) {
1207          return TRUE;
1208       }
1209    }
1210    return FALSE;
1211 }
1212 
1213 static char **tmpDomainName=NULL;
1214 static char **tmpDomainPath=NULL;
1215 static int numTmpDomainNames=0;
1216 
1217 static
CleanUpTmpDomainName()1218 void CleanUpTmpDomainName()
1219 {
1220    if (tmpDomainName != NULL) {
1221       int i=0;
1222 
1223       for (i=0; i < numTmpDomainNames; i++) {
1224          UtilFree(tmpDomainName[i]);
1225          UtilFree(tmpDomainPath[i]);
1226       }
1227       free(tmpDomainName);
1228       free(tmpDomainPath);
1229       tmpDomainName = tmpDomainPath = NULL;
1230    }
1231 }
1232 
1233 static
DomainListing(pn_num_entries,name_only)1234 DspList *DomainListing(pn_num_entries, name_only)
1235    int *pn_num_entries, name_only;
1236    /*
1237     * If (name_only == TRUE) returned DspList only has names.
1238     * If (name_only == FALSE) returned DspList has name=path.
1239     */
1240 {
1241    int i=0, seen_examples=FALSE;
1242    char s[MAXSTRING], *c_ptr=NULL, **ppsz_keys=NULL;
1243    DspList *dsp_ptr=NULL, *head_ptr=NULL, *tail_ptr=NULL, *p=NULL, *p1=NULL;
1244    DspList *next_dsp=NULL;
1245    int one_line_status=FALSE;
1246    char status_buf[MAX_STATUS_BTNS+1][MAXSTRING+1];
1247 
1248    SaveStatusStringsIntoBuf(status_buf, &one_line_status);
1249    SetStringStatus(TgLoadString(STID_GEN_LIST_OF_DOMAIN_NAMES_WAIT));
1250    *pn_num_entries = 0;
1251    if (domainInIni) {
1252       char *pszKeys=tgGetProfileString(gszDomainPathsSec, NULL,
1253             gszDomainIniFile);
1254 
1255       if (pszKeys != NULL) {
1256          int count=1;
1257          char *pszKey=NULL;
1258 
1259          ppsz_keys = (char**)malloc(sizeof(char*));
1260          if (ppsz_keys == NULL) FailAllocMessage();
1261          ppsz_keys[count-1] = NULL;
1262          for (pszKey=pszKeys; *pszKey != '\0'; pszKey++) {
1263             ppsz_keys = (char**)realloc(ppsz_keys, (++count)*sizeof(char*));
1264             if (ppsz_keys == NULL) FailAllocMessage();
1265             ppsz_keys[count-1] = NULL;
1266 
1267             ppsz_keys[count-2] = UtilStrDup(pszKey);
1268             if (ppsz_keys[count-2] == NULL) FailAllocMessage();
1269 
1270             pszKey += strlen(pszKey);
1271          }
1272          *pn_num_entries = count;
1273          tgFreeProfileString(pszKeys);
1274       }
1275    } else {
1276       if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "MaxDomains")) == NULL) {
1277          *pn_num_entries = 1;
1278       } else {
1279          *pn_num_entries = atoi(c_ptr)+1;
1280       }
1281    }
1282    if (*pn_num_entries == 0) {
1283       RestoreStatusStringsFromBuf(status_buf, one_line_status);
1284       return NULL;
1285    }
1286    numTmpDomainNames = (*pn_num_entries);
1287    tmpDomainName = (char**)malloc((*pn_num_entries)*sizeof(char*));
1288    tmpDomainPath = (char**)malloc((*pn_num_entries)*sizeof(char*));
1289    if (tmpDomainName == NULL || tmpDomainPath == NULL) FailAllocMessage();
1290    memset(tmpDomainName, 0, (*pn_num_entries)*sizeof(char*));
1291    memset(tmpDomainPath, 0, (*pn_num_entries)*sizeof(char*));
1292 
1293    head_ptr = tail_ptr = NULL;
1294    for (i = 0; i < (*pn_num_entries); i++) {
1295       if (i != (*pn_num_entries)-1) {
1296          char *c_ptr1=NULL, *psz_path_in_ini=NULL;
1297 
1298          if (domainInIni) {
1299             if ((psz_path_in_ini=tgGetProfileString(gszDomainPathsSec,
1300                   ppsz_keys[i], gszDomainIniFile)) != NULL) {
1301                c_ptr = psz_path_in_ini;
1302                while (*c_ptr==' ' || *c_ptr=='\t' || *c_ptr=='\n') c_ptr++;
1303             }
1304          } else if (domainInResource) {
1305             sprintf(s, "DomainPath%1d", i);
1306             if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, s)) != NULL) {
1307                while (*c_ptr==' ' || *c_ptr=='\t' || *c_ptr=='\n') c_ptr++;
1308             }
1309          } else {
1310             sprintf(s, "Domain%1d", i);
1311             c_ptr = XGetDefault(mainDisplay, TOOL_NAME, s);
1312          }
1313          if (c_ptr == NULL || *c_ptr == '\0') {
1314             if (domainInIni) {
1315                sprintf(gszMsgBox,
1316                      TgLoadString(STID_CANT_GEN_DOM_NAMES_INI_ENTRY),
1317                      ppsz_keys[i], gszDomainPathsSec, gszDomainIniFile);
1318             } else if (domainInResource) {
1319                sprintf(gszMsgBox,
1320                      TgLoadString(STID_CANT_GEN_DOM_NAMES_XDEF), TOOL_NAME,
1321                      "DomainPath", i);
1322             } else {
1323                sprintf(gszMsgBox,
1324                      TgLoadString(STID_CANT_GEN_DOM_NAMES_XDEF), TOOL_NAME,
1325                      "Domain", i);
1326             }
1327             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1328             for ( ; head_ptr != NULL; head_ptr = next_dsp) {
1329                next_dsp = head_ptr->next;
1330                free(head_ptr);
1331             }
1332             if (ppsz_keys != NULL) {
1333                for (i=0; i < *pn_num_entries; i++) {
1334                   tgFreeProfileString(ppsz_keys[i]);
1335                }
1336                free(ppsz_keys);
1337             }
1338             tgFreeProfileString(psz_path_in_ini);
1339             RestoreStatusStringsFromBuf(status_buf, one_line_status);
1340             return NULL;
1341          }
1342          dsp_ptr = (DspList*)malloc(sizeof(DspList));
1343          if (dsp_ptr == NULL) FailAllocMessage();
1344          memset(dsp_ptr, 0, sizeof(DspList));
1345          if (domainInIni) {
1346             if (name_only) {
1347                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr),
1348                      ppsz_keys[i]);
1349             } else {
1350                sprintf(gszMsgBox, "%s=%s", ppsz_keys[i],
1351                      psz_path_in_ini==NULL ? "" : psz_path_in_ini);
1352                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr),
1353                      gszMsgBox);
1354             }
1355             tmpDomainName[i] = UtilStrDup(ppsz_keys[i]);
1356             tmpDomainPath[i] = UtilStrDup(psz_path_in_ini==NULL ? "" :
1357                   psz_path_in_ini);
1358             if (tmpDomainName[i] == NULL || tmpDomainPath[i] == NULL) {
1359                FailAllocMessage();
1360             }
1361          } else if ((c_ptr1=strchr(c_ptr, ':')) != NULL) {
1362             *c_ptr1 = '\0';
1363             if (name_only) {
1364                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), c_ptr);
1365             } else {
1366                sprintf(gszMsgBox, "%s=%s", c_ptr, &c_ptr1[1]);
1367                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr),
1368                      gszMsgBox);
1369             }
1370             tmpDomainName[i] = UtilStrDup(c_ptr);
1371             tmpDomainPath[i] = UtilStrDup(&c_ptr1[1]);
1372             if (tmpDomainName[i] == NULL || tmpDomainPath[i] == NULL) {
1373                FailAllocMessage();
1374             }
1375             *c_ptr1 = ':';
1376          } else {
1377             if (name_only) {
1378                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), c_ptr);
1379             } else {
1380                sprintf(gszMsgBox, "%s=", c_ptr);
1381                UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr),
1382                      gszMsgBox);
1383             }
1384             tmpDomainName[i] = UtilStrDup(c_ptr);
1385             tmpDomainPath[i] = UtilStrDup("");
1386             if (tmpDomainName[i] == NULL || tmpDomainPath[i] == NULL) {
1387                FailAllocMessage();
1388             }
1389          }
1390          /* do not translate -- program constants */
1391          if (strcmp(tmpDomainName[i], "Examples") == 0) {
1392             seen_examples = TRUE;
1393          }
1394          tgFreeProfileString(psz_path_in_ini);
1395       } else if (seen_examples) {
1396          (*pn_num_entries)--;
1397          numTmpDomainNames--;
1398          break;
1399       } else {
1400          dsp_ptr = (DspList*)malloc(sizeof(DspList));
1401          if (dsp_ptr == NULL) FailAllocMessage();
1402          memset(dsp_ptr, 0, sizeof(DspList));
1403          /* do not translate -- program constants */
1404          if (name_only) {
1405             UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), "Examples");
1406          } else {
1407             sprintf(gszMsgBox, "Examples=%s", TGIF_PATH);
1408             UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), gszMsgBox);
1409          }
1410          tmpDomainName[i] = UtilStrDup("Examples");
1411          tmpDomainPath[i] = UtilStrDup(TGIF_PATH);
1412          if (tmpDomainName[i] == NULL || tmpDomainPath[i] == NULL) {
1413             FailAllocMessage();
1414          }
1415       }
1416       if (head_ptr == NULL) {
1417          head_ptr = tail_ptr = dsp_ptr;
1418       } else {
1419          p1 = NULL;
1420          for (p = head_ptr; p != NULL; p = p->next) {
1421             if (LargerStr(dsp_ptr->itemstr, p->itemstr)) {
1422                p1 = p;
1423             } else {
1424                break;
1425             }
1426          }
1427          dsp_ptr->next = p;
1428          if (p == NULL) {  /* dsp_ptr has the largest element */
1429             tail_ptr->next = dsp_ptr;
1430             tail_ptr = dsp_ptr;
1431          } else if (p1 == NULL) {
1432             head_ptr = dsp_ptr;
1433          } else {
1434             p1->next = dsp_ptr;
1435          }
1436       }
1437    }
1438    if (ppsz_keys != NULL) {
1439       for (i=0; i < *pn_num_entries; i++) {
1440          tgFreeProfileString(ppsz_keys[i]);
1441       }
1442       free(ppsz_keys);
1443    }
1444    RestoreStatusStringsFromBuf(status_buf, one_line_status);
1445 
1446    return head_ptr;
1447 }
1448 
1449 static
SelectDomain(SelStr)1450 int SelectDomain(SelStr)
1451    char *SelStr;
1452 {
1453    int i, index=INVALID, num_entries=0;
1454    char **entries=NULL;
1455    DspList *dsp_ptr=NULL, *next_dsp=NULL;
1456 
1457    if ((dsp_ptr=DomainListing(&num_entries, TRUE)) == NULL) {
1458       CleanUpTmpDomainName();
1459       MsgBox(TgLoadString(STID_CANT_GET_LIST_OF_DOM_NAMES), TOOL_NAME, INFO_MB);
1460       *SelStr = '\0';
1461       return INVALID;
1462    }
1463    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
1464    if ((index=ChooseAName(TgLoadString(STID_PLEASE_SELECT_A_NEW_DOMAIN),
1465          entries, num_entries, INVALID)) == INVALID) {
1466       *SelStr = '\0';
1467    } else {
1468       strcpy(SelStr, entries[index]);
1469    }
1470    for ( ; dsp_ptr != NULL; dsp_ptr = next_dsp) {
1471       next_dsp = dsp_ptr->next;
1472       free(dsp_ptr);
1473    }
1474    free(*entries);
1475    free(entries);
1476 
1477    Msg("");
1478 
1479    index = INVALID;
1480    if (*SelStr != '\0' && num_entries > 0 && tmpDomainName != NULL) {
1481       for (i=0; i < num_entries; i++) {
1482          if (tmpDomainName[i] != NULL && strcmp(tmpDomainName[i],SelStr)==0) {
1483             index = i;
1484             break;
1485          }
1486       }
1487    }
1488    CleanUpTmpDomainName();
1489    return index;
1490 }
1491 
ChangeDomain()1492 void ChangeDomain()
1493 {
1494    char *c_ptr=NULL, domain_name[MAXPATHLENGTH+1], env_str[MAXPATHLENGTH+1];
1495    char s[MAXSTRING+1], s1[MAXSTRING+1], cap_tool_name[MAXSTRING+1];
1496    int index=0;
1497    XEvent ev;
1498 
1499    *domain_name = '\0';
1500    index = SelectDomain(domain_name);
1501    if (index == INVALID || *domain_name == '\0') return;
1502 
1503    XSync(mainDisplay, False);
1504    if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
1505       ExposeEventHandler(&ev, TRUE);
1506    }
1507    if (domainInIni) {
1508       char *pszPath=tgGetProfileString(gszDomainPathsSec, domain_name,
1509             gszDomainIniFile);
1510 
1511       if (pszPath != NULL) {
1512          ParseSymPath(pszPath);
1513          tgFreeProfileString(pszPath);
1514       } else if (strcmp(domain_name, "Examples") == 0) {
1515          ParseSymPath(TGIF_PATH);
1516       } else {
1517          ParseSymPath(".");
1518       }
1519    } else if (domainInResource) {
1520       sprintf(s, "DomainPath%1d", index);
1521       if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,s)) != NULL) {
1522          char *c_ptr1;
1523 
1524          while (*c_ptr==' ' || *c_ptr=='\t' || *c_ptr=='\n') c_ptr++;
1525          if (*c_ptr != '\0' && (c_ptr1=strchr(c_ptr, ':')) != NULL) {
1526             c_ptr = &c_ptr1[1];
1527          }
1528          ParseSymPath(c_ptr);
1529       } else if (strcmp(domain_name, "Examples") == 0) {
1530          ParseSymPath(TGIF_PATH);
1531       } else {
1532          ParseSymPath(".");
1533       }
1534    } else {
1535       strcpy(cap_tool_name, TOOL_NAME);
1536       UtilStrUpper(cap_tool_name);
1537       sprintf(env_str, "%s_%s", cap_tool_name, domain_name);
1538       if ((c_ptr=getenv(env_str)) == NULL) {
1539          if (strcmp(domain_name, "Examples") == 0) {
1540             ParseSymPath(TGIF_PATH);
1541          } else {
1542             ParseSymPath(".");
1543          }
1544       } else {
1545          ParseSymPath(c_ptr);
1546       }
1547    }
1548    UpdateSymInfo();
1549 
1550    strcpy(curDomainName, domain_name);
1551    sprintf(s, TgLoadString(STID_CURRENT_DOMAIN_IS), curDomainName);
1552    sprintf(s1, TgLoadString(STID_SYMBOL_PATH_SET_TO), curDomainPath);
1553    TwoLineMsg(s, s1);
1554    RedrawTitleWindow();
1555 }
1556 
1557 static char *oldDomain=NULL, *oldDir=NULL;
1558 
1559 static
SymDirListing(pn_marked_index,pn_num_entries)1560 DspList *SymDirListing(pn_marked_index, pn_num_entries)
1561    int *pn_marked_index, *pn_num_entries;
1562 {
1563    int i, checking=FALSE;
1564    DspList *dsp_ptr, *head_ptr, *tail_ptr;
1565 
1566    *pn_marked_index = INVALID;
1567    if (oldDomain!=NULL && oldDir!=NULL && strcmp(oldDomain,curDomainName)==0) {
1568       checking = TRUE;
1569    }
1570    head_ptr = tail_ptr = NULL;
1571    for (i = 0; i < symPathNumEntries; i++) {
1572       dsp_ptr = (DspList*)malloc(sizeof(DspList));
1573       if (dsp_ptr == NULL) FailAllocMessage();
1574       memset(dsp_ptr, 0, sizeof(DspList));
1575       dsp_ptr->next = NULL;
1576       UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), symPath[i]);
1577 
1578       if (head_ptr == NULL) {
1579          head_ptr = tail_ptr = dsp_ptr;
1580       } else {
1581          tail_ptr->next = dsp_ptr;
1582          tail_ptr = dsp_ptr;
1583       }
1584       if (checking && strcmp(oldDir, symPath[i]) == 0) {
1585          checking = FALSE;
1586          *pn_marked_index = i;
1587       }
1588    }
1589    *pn_num_entries = symPathNumEntries;
1590    return head_ptr;
1591 }
1592 
SelectSymDir(SelStr)1593 int SelectSymDir(SelStr)
1594    char *SelStr;
1595 {
1596    int index, num_entries=0, marked_index=INVALID;
1597    char **entries=NULL, msg[MAXSTRING+1];
1598    DspList *dsp_ptr, *next_dsp;
1599 
1600    *SelStr = '\0';
1601    if ((dsp_ptr=SymDirListing(&marked_index, &num_entries)) == NULL) {
1602       return INVALID;
1603    }
1604    entries = MakeLongNameDspItemArray(num_entries, dsp_ptr);
1605 
1606    sprintf(msg, TgLoadString(STID_PLS_SEL_A_DIR_IN_GIVEN_DOMAIN),
1607          curDomainName);
1608    if ((index=ChooseAName(msg, entries, num_entries, marked_index)) !=
1609          INVALID) {
1610       strcpy(SelStr, entries[index]);
1611       if (oldDomain != NULL) free(oldDomain);
1612       if (oldDir != NULL) free(oldDir);
1613       oldDomain = (char*)malloc((strlen(curDomainName)+1)*sizeof(char));
1614       if (oldDomain == NULL) FailAllocMessage();
1615       oldDir = (char*)malloc((strlen(SelStr)+1)*sizeof(char));
1616       if (oldDir == NULL) FailAllocMessage();
1617       strcpy(oldDomain, curDomainName);
1618       strcpy(oldDir, SelStr);
1619    }
1620    for ( ; dsp_ptr != NULL; dsp_ptr = next_dsp) {
1621       next_dsp = dsp_ptr->next;
1622       free(dsp_ptr);
1623    }
1624    free(*entries);
1625    free(entries);
1626 
1627    Msg("");
1628    return index;
1629 }
1630 
1631 static
BitmapListing(ExtStr,OtherExtStr)1632 DspList *BitmapListing(ExtStr, OtherExtStr)
1633    char *ExtStr, *OtherExtStr;
1634 {
1635    int len, path_index, count = 0, reject, ext_len;
1636    char path[MAXPATHLENGTH], ext_str[MAXSTRING];
1637    DspList *head_ptr=NULL, *tail_ptr=NULL;
1638    DIR *dirp=NULL;
1639    DIR_ENTRY *d=NULL;
1640 
1641    head_ptr = tail_ptr = NULL;
1642 
1643    sprintf(ext_str, ".%s", ExtStr);
1644    ext_len = strlen(ext_str);
1645    for (path_index=0; path_index < symPathNumEntries; path_index++) {
1646       strcpy(path, symPath[path_index]);
1647       if (strcmp(".", path) == 0) {
1648          if (curDirIsLocal) {
1649             strcpy(path, curDir);
1650          } else {
1651             strcpy(path, curLocalDir);
1652          }
1653       }
1654       if ((dirp=opendir(path)) == NULL) {
1655          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_DIR_FOR_READING),
1656                path);
1657          Msg(gszMsgBox);
1658          continue;
1659       }
1660       while ((d=readdir(dirp)) != NULL) {
1661          len = strlen(d->d_name);
1662          if (!((len > ext_len &&
1663                UtilStrICmp(ext_str,&d->d_name[len-ext_len]) == 0) ||
1664                ExtensionMatch(OtherExtStr, d->d_name))) {
1665             continue;
1666          }
1667          if (head_ptr == NULL) {
1668             head_ptr = tail_ptr = (DspList*)malloc(sizeof(DspList));
1669             if (head_ptr == NULL) FailAllocMessage();
1670             memset(head_ptr, 0, sizeof(DspList));
1671             UtilStrCpyN(head_ptr->itemstr, sizeof(head_ptr->itemstr),
1672                   d->d_name);
1673             UtilStrCpyN(head_ptr->pathstr, sizeof(head_ptr->pathstr), path);
1674          } else {
1675             DspList *dsp_ptr=NULL, *p=NULL, *p1=NULL;
1676 
1677             p1 = NULL;
1678             reject = FALSE;
1679             for (p=head_ptr; p != NULL; p = p->next) {
1680                if (strcmp(d->d_name, p->itemstr) == 0) {
1681                   reject = TRUE;
1682                   break;
1683                } else if (LargerStr(d->d_name, p->itemstr)) {
1684                   p1 = p;
1685                } else {
1686                   break;
1687                }
1688             }
1689             if (reject) continue;
1690 
1691             dsp_ptr = (DspList*)malloc(sizeof(DspList));
1692             if (dsp_ptr == NULL) FailAllocMessage();
1693             memset(dsp_ptr, 0, sizeof(DspList));
1694             dsp_ptr->next = p;
1695             UtilStrCpyN(dsp_ptr->itemstr, sizeof(dsp_ptr->itemstr), d->d_name);
1696             UtilStrCpyN(dsp_ptr->pathstr, sizeof(dsp_ptr->pathstr), path);
1697 
1698             if (p == NULL) {
1699                /* dsp_ptr has the largest element */
1700                tail_ptr->next = dsp_ptr;
1701                tail_ptr = dsp_ptr;
1702             } else if (p1 == NULL) {
1703                head_ptr = dsp_ptr;
1704             } else {
1705                p1->next = dsp_ptr;
1706             }
1707          }
1708          count++;
1709       }
1710       closedir(dirp);
1711    }
1712    numSymbols = count;
1713    return head_ptr;
1714 }
1715 
SelectFromLibrary(MsgStr,ExtStr,SelStr,PathStr)1716 int SelectFromLibrary(MsgStr, ExtStr, SelStr, PathStr)
1717    char *MsgStr, *ExtStr, *SelStr, *PathStr;
1718 {
1719    int index, num_entries=0;
1720    char **entries=NULL;
1721    char other_ext_str[MAXSTRING];
1722    DspList *dsp_ptr, *next_dsp;
1723 
1724    *other_ext_str = '\0';
1725 
1726    if (strcmp(ExtStr, XBM_FILE_EXT) == 0) {
1727       Msg(TgLoadString(STID_GEN_LIST_XBM_NAMES_WAIT));
1728    } else if (strcmp(ExtStr, XPM_FILE_EXT) == 0) {
1729       Msg(TgLoadString(STID_GEN_LIST_XPM_NAMES_WAIT));
1730    } else if (strcmp(ExtStr, OBJ_FILE_EXT) == 0) {
1731       Msg(TgLoadString(STID_GEN_LIST_OBJ_NAMES_WAIT));
1732       sprintf(other_ext_str, ".%s;.%s", SYM_FILE_EXT, PIN_FILE_EXT);
1733    } else if (strcmp(ExtStr, SYM_FILE_EXT) == 0) {
1734       Msg(TgLoadString(STID_GEN_LIST_SYM_NAMES_WAIT));
1735       sprintf(other_ext_str, ".%s", PIN_FILE_EXT);
1736    } else if (strcmp(ExtStr, EPSF_FILE_EXT) == 0) {
1737       sprintf(gszMsgBox, TgLoadString(STID_GEN_LIST_TYPE_FILE_NAMES_WAIT),
1738             "EPS");
1739       sprintf(other_ext_str, ".%s;.epsi", PS_FILE_EXT);
1740    } else {
1741       sprintf(gszMsgBox, TgLoadString(STID_GEN_LIST_TYPE_FILE_NAMES_WAIT),
1742             ExtStr);
1743       Msg(gszMsgBox);
1744       sprintf(other_ext_str, ".GIF");
1745    }
1746    if ((topOfSymLinkList=BitmapListing(ExtStr,other_ext_str)) == NULL) {
1747       sprintf(gszMsgBox, TgLoadString(STID_NO_GIVEN_TYPE_FILE_FOUND), ExtStr);
1748       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1749       *SelStr = *PathStr = '\0';
1750       return INVALID;
1751    }
1752    BuildSymbolList();
1753 
1754    num_entries = numSymbols;
1755    entries = MakeNameDspItemArray(num_entries, symbolList);
1756 
1757    if ((index=ChooseAName(MsgStr, entries, num_entries, INVALID)) == INVALID) {
1758       *SelStr = *PathStr = '\0';
1759    } else {
1760       strcpy(SelStr, entries[index]);
1761       strcpy(PathStr, symbolList[index].pathstr);
1762    }
1763 
1764    for (dsp_ptr=topOfSymLinkList; dsp_ptr != NULL; dsp_ptr=next_dsp) {
1765       next_dsp = dsp_ptr->next;
1766       free(dsp_ptr);
1767    }
1768    free(*entries);
1769    free(entries);
1770 
1771    Msg("");
1772    UpdateSymInfo();
1773    return index;
1774 }
1775 
SetCurDir(FileName)1776 void SetCurDir(FileName)
1777    char *FileName;
1778 {
1779    char file_name[MAXPATHLENGTH+1], *psz=NULL;
1780 
1781    strcpy(file_name, FileName);
1782    UtilShrinkName(file_name);
1783 
1784    if (curDirIsLocal && FileIsRemote(FileName)) {
1785       strcpy(curLocalDir, curDir);
1786       if (autoHyperSpaceOnRemote) {
1787          inHyperSpace = TRUE;
1788          Msg(TgLoadCachedString(CSTID_ENTERING_HYPERSPACE));
1789       }
1790    } else if (!curDirIsLocal && !FileIsRemote(FileName)) {
1791       *curLocalDir = '\0';
1792    }
1793    if ((psz=UtilStrRChr(file_name, DIR_SEP)) == NULL) {
1794       sprintf(gszMsgBox, TgLoadString(STID_NO_DIR_SEP_IN_FUNC_WORK_DIR),
1795             "SetDurDir()", bootDir);
1796       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1797       strcpy(curDir, bootDir);
1798       strcpy(curFileName, FileName);
1799    } else {
1800       *psz++ = '\0';
1801       strcpy(curFileName, psz);
1802       strcpy(curDir, file_name);
1803    }
1804    curDirIsLocal = (!DirIsRemote(curDir));
1805    RedrawDummyWindow1();
1806 }
1807 
SetCurSymDir(FileName)1808 void SetCurSymDir(FileName)
1809    char *FileName;
1810 {
1811    char file_name[MAXPATHLENGTH+1], *psz=NULL;
1812 
1813    strcpy(file_name, FileName);
1814    UtilShrinkName(file_name);
1815 
1816    if ((psz=UtilStrRChr(file_name, DIR_SEP)) == NULL) {
1817       sprintf(gszMsgBox, TgLoadString(STID_NO_DIR_SEP_IN_FUNC_SYM_DIR),
1818             "SetDurSymDir()", bootDir);
1819       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1820       strcpy(curSymDir, bootDir);
1821       strcpy(curFileName, FileName);
1822    } else {
1823       *psz++ = '\0';
1824       strcpy(curFileName, psz);
1825       strcpy(curSymDir, file_name);
1826    }
1827 }
1828 
SetCurImportDir(FileName)1829 void SetCurImportDir(FileName)
1830    char *FileName;
1831 {
1832    char file_name[MAXPATHLENGTH+1], *psz=NULL;
1833 
1834    strcpy(file_name, FileName);
1835    UtilShrinkName(file_name);
1836 
1837    if ((psz=UtilStrRChr(file_name, DIR_SEP)) == NULL) {
1838       sprintf(gszMsgBox, TgLoadString(STID_NO_DIR_SEP_IN_FUNC_IMPORT_DIR),
1839             "SetDurImportir()", bootDir);
1840       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1841       strcpy(curImportDir, bootDir);
1842    } else {
1843       *psz = '\0';
1844       strcpy(curImportDir, file_name);
1845    }
1846 }
1847 
1848 /* ---------------------- Additional Domain Functions ---------------------- */
1849 
1850 static
FreeDspLinkedList(dsp_ptr)1851 DspList *FreeDspLinkedList(dsp_ptr)
1852    DspList *dsp_ptr;
1853 {
1854    DspList *next_dsp=NULL;
1855 
1856    for ( ; dsp_ptr != NULL; dsp_ptr=next_dsp) {
1857       next_dsp = dsp_ptr->next;
1858       free(dsp_ptr);
1859    }
1860    return NULL;
1861 }
1862 
CopyDomainInfoToIni()1863 void CopyDomainInfoToIni()
1864 {
1865    int i=0, num_entries=0;
1866    DspList *dsp_ptr=NULL;
1867 
1868    tgWriteProfileString(gszDomainPathsSec, NULL, NULL, gszDomainIniFile);
1869    if ((dsp_ptr=DomainListing(&num_entries, TRUE)) == NULL) {
1870       CleanUpTmpDomainName();
1871       return;
1872    }
1873    dsp_ptr = FreeDspLinkedList(dsp_ptr);
1874 
1875    for (i=0; i < num_entries; i++) {
1876       /* do not translate -- program constants */
1877       if (strcmp(tmpDomainName[i], "Examples") != 0) {
1878          tgWriteProfileString(gszDomainPathsSec, tmpDomainName[i],
1879                tmpDomainPath[i], gszDomainIniFile);
1880       }
1881    }
1882    tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
1883    CleanUpTmpDomainName();
1884 }
1885 
1886 static
DomainListToDomainArray(dsp_ptr,num_entries,set_directory)1887 DspList *DomainListToDomainArray(dsp_ptr, num_entries, set_directory)
1888    DspList *dsp_ptr;
1889    int num_entries, set_directory;
1890 {
1891    int i=0;
1892    DspList *dsp_ptr1=NULL, *new_dsp=NULL, *pdl=NULL;
1893 
1894    new_dsp = (DspList*)malloc(num_entries*sizeof(DspList));
1895    if (new_dsp == NULL) FailAllocMessage();
1896    memset(new_dsp, 0, num_entries*sizeof(DspList));
1897    for (i=0, pdl=new_dsp, dsp_ptr1=dsp_ptr; i < num_entries;
1898          i++, pdl++, dsp_ptr1=dsp_ptr1->next) {
1899       UtilStrCpyN(pdl->itemstr, sizeof(pdl->itemstr), dsp_ptr1->itemstr);
1900       /* use the directory field for inherited */
1901       if (set_directory) pdl->directory = TRUE;
1902       pdl->next = (&pdl[1]);
1903    }
1904    new_dsp[num_entries-1].next = NULL;
1905    FreeDspLinkedList(dsp_ptr);
1906 
1907    return new_dsp;
1908 }
1909 
1910 static
EditDomainPathsAfterLoop(pp_dsp_ptr,ppsz_entries,pn_num_entries,pn_marked_index,pp_check_array,cur_buf,btn_id,selected_index,p_void)1911 int EditDomainPathsAfterLoop(pp_dsp_ptr, ppsz_entries, pn_num_entries,
1912       pn_marked_index, pp_check_array, cur_buf, btn_id, selected_index, p_void)
1913    DspList **pp_dsp_ptr;
1914    char ***ppsz_entries, *cur_buf;
1915    int *pn_num_entries, *pn_marked_index, btn_id, selected_index;
1916    struct CheckArrayRec **pp_check_array;
1917    void *p_void;
1918    /*
1919     * Returns FALSE if the content of the dialogbox is acceptable and
1920     *       the dialogbox will be closed.
1921     * Returns TRUE to tell the dialogbox to continue to loop.  In this case,
1922     *       this function should call MsgBox() to let the user know why
1923     *       the dialogbox is not closed.
1924     */
1925 {
1926    int i=0, num_entries=(*pn_num_entries);
1927 
1928    if (btn_id == BUTTON_CANCEL) {
1929       return FALSE;
1930    }
1931    for (i=0; i < num_entries; i++) {
1932       char *psz_key=(*ppsz_entries)[i], *psz_value=NULL;
1933       char *psz=strchr(psz_key, '=');
1934 
1935       *psz = '\0';
1936       psz_value = UtilStrDup(&psz[1]);
1937       if (psz_value == NULL) FailAllocMessage();
1938       *psz = '=';
1939       UtilTrimBlanks(psz_value);
1940       if (*psz_value == '\0') {
1941          int len=strlen(psz_key);
1942 
1943          if (len > 0 && psz_key[len-1] == '=') psz_key[len-1] = '\0';
1944          sprintf(gszMsgBox, TgLoadString(STID_EMPTY_PATH_DISALLOW_FOR_DOM),
1945                psz_key);
1946          if (len > 0 && psz_key[len-1] == '\0') psz_key[len-1] = '=';
1947          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1948          UtilFree(psz_value);
1949          return TRUE;
1950       }
1951       UtilFree(psz_value);
1952    }
1953    /* everything is fine */
1954    return FALSE;
1955 }
1956 
1957 static
DoEditDomainPaths(psz_title,dsp_ptr,entries,num_entries,pf_after_loop)1958 int DoEditDomainPaths(psz_title, dsp_ptr, entries, num_entries,
1959       pf_after_loop)
1960    char *psz_title, **entries;
1961    DspList *dsp_ptr;
1962    int num_entries;
1963    AfterLoopFunc *pf_after_loop;
1964 {
1965    char win_name[128];
1966 
1967    sprintf(win_name, TgLoadString(STID_TOOL_EDIT_DOM_PATHS), TOOL_NAME);
1968    ResetNamesInfo();
1969    NamesSetTitle(psz_title);
1970    NamesAddButton(TgLoadCachedString(CSTID_OK), BUTTON_OK);
1971    NamesAddButton(TgLoadCachedString(CSTID_CANCEL), BUTTON_CANCEL);
1972    /* ignore double-click and <CR> */
1973    NamesSetDefaultBtnId(BUTTON_OK, INVALID);
1974    NamesSetStyle(NAMES_EDIT_ATTR, NAMES_LOOP_MANY);
1975    NamesSetCallback(NULL, pf_after_loop, NULL);
1976    NamesSetEntries(dsp_ptr, entries, num_entries, NULL, TRUE, INVALID, 0);
1977    return (Names(win_name, NULL, NULL, 0, NULL)==BUTTON_OK);
1978 }
1979 
EditDomainPaths()1980 void EditDomainPaths()
1981 {
1982    int num_entries=0;
1983    DspList *dsp_ptr=NULL;
1984    char *pszKeys=NULL, **entries=NULL;
1985 
1986    if ((pszKeys=tgGetProfileString(gszDomainPathsSec, NULL,
1987          gszDomainIniFile)) == NULL) {
1988       CopyDomainInfoToIni();
1989    } else {
1990       tgFreeProfileString(pszKeys);
1991    }
1992    if ((dsp_ptr=DomainListing(&num_entries, FALSE)) == NULL) {
1993       MsgBox(TgLoadString(STID_CANT_GET_LIST_OF_DOM_NAMES), TOOL_NAME, INFO_MB);
1994       return;
1995    }
1996    CleanUpTmpDomainName();
1997 
1998    dsp_ptr = DomainListToDomainArray(dsp_ptr, num_entries, TRUE);
1999 
2000    ignoreDirectoryFlag = TRUE;
2001    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
2002    ignoreDirectoryFlag = FALSE;
2003 
2004    if (DoEditDomainPaths(TgLoadString(STID_EDIT_DOMAIN_PATHS_DOTS), dsp_ptr,
2005          entries, num_entries,
2006          (AfterLoopFunc*)EditDomainPathsAfterLoop)) {
2007       int i=0;
2008 
2009       tgWriteProfileString(gszDomainPathsSec, NULL, NULL, gszDomainIniFile);
2010       for (i=0; i < num_entries; i++) {
2011          char *psz=strchr(entries[i], '=');
2012 
2013          *psz++ = '\0';
2014          tgWriteProfileString(gszDomainPathsSec, entries[i], psz,
2015                gszDomainIniFile);
2016       }
2017       tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
2018    }
2019    free(dsp_ptr);
2020    free(*entries);
2021    free(entries);
2022 }
2023 
2024 static
DoSelectDefaultDomain(psz_title,dsp_ptr,entries,num_entries,selected_str,selected_str_sz)2025 int DoSelectDefaultDomain(psz_title, dsp_ptr, entries, num_entries,
2026       selected_str, selected_str_sz)
2027    char *psz_title, **entries, *selected_str;
2028    DspList *dsp_ptr;
2029    int num_entries, selected_str_sz;
2030 {
2031    char win_name[128];
2032 
2033    sprintf(win_name, TgLoadString(STID_TOOL_SEL_DEFAULT_DOMAIN), TOOL_NAME);
2034    ResetNamesInfo();
2035    NamesSetTitle(psz_title);
2036    NamesAddButton(TgLoadCachedString(CSTID_OK), BUTTON_OK);
2037    NamesAddButton(TgLoadCachedString(CSTID_CANCEL), BUTTON_CANCEL);
2038    /* ignore double-click and <CR> */
2039    NamesSetDefaultBtnId(BUTTON_OK, BUTTON_OK);
2040    NamesSetStyle(NAMES_SIMPLE_SELECT_NAME, NAMES_LOOP_ONCE);
2041    NamesSetEntries(dsp_ptr, entries, num_entries, NULL, TRUE, INVALID, 0);
2042    return (Names(win_name, NULL, selected_str, selected_str_sz,
2043          NULL)==BUTTON_OK);
2044 }
2045 
SelectDefaultDomain()2046 void SelectDefaultDomain()
2047 {
2048    int num_entries=0;
2049    DspList *dsp_ptr=NULL;
2050    char *pszKeys=NULL, **entries=NULL, selected_domain[MAXSTRING];
2051 
2052    if ((pszKeys=tgGetProfileString(gszDomainPathsSec, NULL,
2053          gszDomainIniFile)) == NULL) {
2054       CopyDomainInfoToIni();
2055    } else {
2056       tgFreeProfileString(pszKeys);
2057    }
2058    if ((dsp_ptr=DomainListing(&num_entries, TRUE)) == NULL) {
2059       MsgBox(TgLoadString(STID_CANT_GET_LIST_OF_DOM_NAMES), TOOL_NAME, INFO_MB);
2060       return;
2061    }
2062    CleanUpTmpDomainName();
2063 
2064    dsp_ptr = DomainListToDomainArray(dsp_ptr, num_entries, FALSE);
2065 
2066    ignoreDirectoryFlag = TRUE;
2067    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
2068    ignoreDirectoryFlag = FALSE;
2069 
2070    *selected_domain = '\0';
2071    if (!DoSelectDefaultDomain(TgLoadString(STID_SEL_DEFAULT_DOMAIN_DOTS),
2072          dsp_ptr, entries, num_entries, selected_domain,
2073          sizeof(selected_domain))) {
2074       *selected_domain = '\0';
2075    }
2076    free(dsp_ptr);
2077    free(*entries);
2078    free(entries);
2079    if (*selected_domain != '\0') {
2080       tgWriteProfileString(gszDefaultDomainSec, NULL, NULL, gszDomainIniFile);
2081       tgWriteProfileString(gszDefaultDomainSec, selected_domain, "",
2082             gszDomainIniFile);
2083       tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
2084    }
2085 }
2086 
AddADomain()2087 void AddADomain()
2088 {
2089    int num_entries=0;
2090    DspList *dsp_ptr=NULL;
2091    char *pszKeys=NULL, **entries=NULL, spec[MAXSTRING];
2092 
2093    if ((pszKeys=tgGetProfileString(gszDomainPathsSec, NULL,
2094          gszDomainIniFile)) == NULL) {
2095       CopyDomainInfoToIni();
2096    } else {
2097       tgFreeProfileString(pszKeys);
2098    }
2099    if ((dsp_ptr=DomainListing(&num_entries, TRUE)) == NULL) {
2100       MsgBox(TgLoadString(STID_CANT_GET_LIST_OF_DOM_NAMES), TOOL_NAME, INFO_MB);
2101       return;
2102    }
2103    CleanUpTmpDomainName();
2104 
2105    dsp_ptr = DomainListToDomainArray(dsp_ptr, num_entries, FALSE);
2106 
2107    ignoreDirectoryFlag = TRUE;
2108    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
2109    ignoreDirectoryFlag = FALSE;
2110 
2111    *spec = '\0';
2112    if (Dialog(TgLoadString(STID_PLS_SPEC_A_NEW_DOMAIN_NAME), NULL, spec) !=
2113          INVALID) {
2114       UtilTrimBlanks(spec);
2115       if (*spec != '\0') {
2116          int i=0, dup_found=FALSE;
2117 
2118          for (i=0; i < num_entries; i++) {
2119             if (UtilStrICmp(dsp_ptr[i].itemstr, spec) == 0) {
2120                sprintf(gszMsgBox,
2121                      TgLoadString(STID_GIVEN_DOMAIN_ALREADY_EXISTS), spec);
2122                MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2123                dup_found = TRUE;
2124                break;
2125             }
2126          }
2127          if (!dup_found) {
2128             tgWriteProfileString(gszDomainPathsSec, spec, ".",
2129                   gszDomainIniFile);
2130             tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
2131             sprintf(gszMsgBox, TgLoadString(STID_GIVEN_DOM_ADDED_PATH_SET_TO),
2132                   spec, ".");
2133             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2134          }
2135       }
2136    }
2137    free(dsp_ptr);
2138    free(*entries);
2139    free(entries);
2140 }
2141 
DeleteADomain()2142 void DeleteADomain()
2143 {
2144    int num_entries=0;
2145    DspList *dsp_ptr=NULL;
2146    char *pszKeys=NULL, **entries=NULL, selected_domain[MAXSTRING];
2147 
2148    if ((pszKeys=tgGetProfileString(gszDomainPathsSec, NULL,
2149          gszDomainIniFile)) == NULL) {
2150       CopyDomainInfoToIni();
2151    } else {
2152       tgFreeProfileString(pszKeys);
2153    }
2154    if ((dsp_ptr=DomainListing(&num_entries, TRUE)) == NULL) {
2155       MsgBox(TgLoadString(STID_CANT_GET_LIST_OF_DOM_NAMES), TOOL_NAME, INFO_MB);
2156       return;
2157    }
2158    CleanUpTmpDomainName();
2159 
2160    dsp_ptr = DomainListToDomainArray(dsp_ptr, num_entries, FALSE);
2161 
2162    ignoreDirectoryFlag = TRUE;
2163    entries = MakeNameDspItemArray(num_entries, dsp_ptr);
2164    ignoreDirectoryFlag = FALSE;
2165 
2166    *selected_domain = '\0';
2167    if (!DoSelectDefaultDomain(TgLoadString(STID_SEL_DOMAIN_TO_DELETE_DOTS),
2168          dsp_ptr, entries, num_entries, selected_domain,
2169          sizeof(selected_domain))) {
2170       *selected_domain = '\0';
2171    }
2172    free(dsp_ptr);
2173    free(*entries);
2174    free(entries);
2175    if (*selected_domain != '\0') {
2176       sprintf(gszMsgBox, TgLoadString(STID_OK_TO_DELETE_NAMED_DOMAIN_YNC),
2177             selected_domain);
2178       if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) == MB_ID_YES) {
2179          tgWriteProfileString(gszDomainPathsSec, selected_domain, NULL,
2180                gszDomainIniFile);
2181          tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
2182       }
2183    }
2184 }
2185 
ReloadDomainInfoFromX()2186 void ReloadDomainInfoFromX()
2187 {
2188    if (MsgBox(TgLoadString(STID_OK_TO_RELOAD_DOM_INFO_FROM_X), TOOL_NAME,
2189          YNC_MB) == MB_ID_YES) {
2190       tgWriteProfileString(gszDefaultDomainSec, NULL, NULL, gszDomainIniFile);
2191       tgWriteProfileString(gszDomainPathsSec, NULL, NULL, gszDomainIniFile);
2192       tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
2193       InitDomain();
2194       CopyDomainInfoToIni();
2195       tgWriteProfileString(gszDefaultDomainSec, curDomainName, "",
2196             gszDomainIniFile);
2197       tgWriteProfileString(NULL, NULL, NULL, gszDomainIniFile);
2198    }
2199 }
2200 
RefreshDomainMenu(menu)2201 int RefreshDomainMenu(menu)
2202    TgMenu *menu;
2203 {
2204    int ok=TRUE;
2205 
2206    /* EditDomainPaths */
2207    ok &= TgEnableMenuItemById(menu, CMDID_EDITDOMAINPATHS, domainInIni);
2208    /* SelectDefaultDomain */
2209    ok &= TgEnableMenuItemById(menu, CMDID_SELECTDEFAULTDOMAIN, domainInIni);
2210    /* AddADomain */
2211    ok &= TgEnableMenuItemById(menu, CMDID_ADDADOMAIN, domainInIni);
2212    /* DeleteADomain */
2213    ok &= TgEnableMenuItemById(menu, CMDID_DELETEADOMAIN, domainInIni);
2214    /* ReloadDomainInfoFromX */
2215    ok &= TgEnableMenuItemById(menu, CMDID_RELOADDOMAININFOFROMX, domainInIni);
2216 
2217    return ok;
2218 }
2219 
CreateDomainMenu(parent_menu,x,y,menu_info,status_str_xlated)2220 TgMenu *CreateDomainMenu(parent_menu, x, y, menu_info, status_str_xlated)
2221    TgMenu *parent_menu;
2222    int x, y;
2223    TgMenuInfo *menu_info;
2224    int status_str_xlated; /* ignored, always 0 */
2225 {
2226    TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, x, y, menu_info, FALSE);
2227 
2228    if (menu != NULL) {
2229       menu->track_menubar = TRUE;
2230       if (!RefreshDomainMenu(menu)) {
2231          return TgDestroyMenu(menu, TRUE);
2232       }
2233       menu->refresh_proc = ((RefreshMenuFunc*)RefreshDomainMenu);
2234    }
2235    return menu;
2236 }
2237