home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / EEDRW23S.ZIP / EELIBS1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-14  |  29.8 KB  |  846 lines

  1. /*****************************************************************************
  2. *   Module to handle libraries (first part - file and io).             *
  3. *                                         *
  4. * Written by:  Gershon Elber            IBM PC Ver 1.0,    Oct. 1989    *
  5. *****************************************************************************/
  6.  
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <conio.h>
  11. #include <string.h>
  12. #include <dos.h>
  13. #include <dir.h>
  14. #include <alloc.h>
  15. #include <time.h>
  16. #include "Program.h"
  17. #include "Director.h"
  18. #include "PriorQue.h"
  19. #include "EELibs.h"
  20. #include "EELibsL.h"
  21. #include "EEModify.h"
  22. #include "EERedraw.h"
  23. #include "EEString.h"
  24.  
  25. LibraryStruct
  26.     *LibraryList = NULL;            /* All part libs are saved here. */
  27. static IntrCursorShapeStruct Cursor = {
  28.     INTR_CURSOR_ARROW, 0, 0, 0, 0, FALSE, NULL, FALSE
  29. };
  30.  
  31. static char *GetLine(FILE *f, char *Line, int *LineNum);
  32. static PriorQue *LoadLibraryAux(FILE *f, int *NumOfParts);
  33. static char *GetPinsEntry(FILE *f, char *Line, int *LineNum, int NumOfPins);
  34. static int *GetMultiEntry(FILE *f, char *Line, int *LineNum, int NumOfUnits,
  35.                             int PinsPerUnit);
  36. static LibraryDrawEntryStruct *GetDrawEntry(FILE *f, char *Line, int *LineNum,
  37.             BooleanType *HasLines, LibraryEntryStruct *LibEntry);
  38. static void UpdateBBox(LibraryEntryStruct *LibEntry, int x, int y);
  39. static void FreeLibraryEntry(LibraryEntryStruct *Entry);
  40. static LibraryStruct *FindLibrary(char *Name);
  41.  
  42. /*****************************************************************************
  43. * Routine to load a library from the current directory.                 *
  44. *****************************************************************************/
  45. void LoadLibrary(void)
  46. {
  47.     int i, NumOfFiles, NumOfParts;
  48.     char *p, LibName[FILE_NAME_LEN];
  49.     FILE *f;
  50.     FileNameType *FileNames;
  51.     LibraryStruct *NewLib;
  52.     PriorQue *Entries;
  53.  
  54.     if ((FileNames = GetFileNamesDir("*.lib", ".", &NumOfFiles)) != NULL) {
  55.     qsort(FileNames, NumOfFiles, sizeof(FileNameType),
  56.           (int (*)(const void *, const void *)) strcmp);
  57.     if ((i = IntrQueryList("Load Lib", (char **) FileNames,
  58.              sizeof(FileNameType), NumOfFiles, EEListNumDisplayed,
  59.                          EEPopUpFrameColor, EEPopUpBackColor, EEPopUpForeColor,
  60.                          EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  61.                          INTR_WNDW_PLACE_CENTER)) < 0) {
  62.         MyFree((VoidPtr) FileNames);
  63.         return;
  64.     }
  65.     strcpy(LibName, FileNames[i]);
  66.     if ((p = strchr(LibName, '.')) != NULL) p[0] = 0;
  67.     if (FindLibrary(LibName) != NULL) {
  68.         /* Library by that name already exists - kill old one? */
  69.         if (IntrQueryYesNo("Library by that name exists, overwrite?",
  70.               EEPopUpFrameColor, EEPopUpBackColor, EEPopUpForeColor,
  71.                       EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  72.                       INTR_WNDW_PLACE_CENTER)) {
  73.         FreeLibrary(LibName);
  74.         }
  75.         else {
  76.         MyFree((VoidPtr) FileNames);
  77.         return;
  78.         }
  79.     }
  80.     f = fopen(FileNames[i], "rt");
  81.     MyFree((VoidPtr) FileNames);
  82.     if (f == NULL) {
  83.         IntrQueryContinue("Failed to open library", EEPopUpFrameColor,
  84.                           EEPopUpBackColor, EEPopUpForeColor,
  85.                               EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  86.                               INTR_WNDW_PLACE_CENTER);
  87.         return;
  88.     }
  89.     if ((Entries = LoadLibraryAux(f, &NumOfParts)) != NULL) {
  90.         NewLib = (LibraryStruct *) MyMalloc(sizeof(LibraryStruct));
  91.         NewLib -> Entries = Entries;
  92.         NewLib -> NumOfParts = NumOfParts;
  93.         strcpy(NewLib -> Name, LibName);
  94.         NewLib -> Pnext = LibraryList;
  95.         LibraryList = NewLib;
  96.     }
  97.     fclose(f);
  98.     }
  99.     else {
  100.     IntrQueryContinue("No libraries found", EEPopUpFrameColor,
  101.                       EEPopUpBackColor, EEPopUpForeColor,
  102.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  103.                           INTR_WNDW_PLACE_CENTER);
  104.     }
  105. }
  106.  
  107. /*****************************************************************************
  108. * Routine to load the given library name. FullLibName should hold full path  *
  109. * of file name to open, while LibName should hold only its name.         *
  110. * IF library already exists, it is NOT reloaded.                 *
  111. *****************************************************************************/
  112. void LoadLibraryName(char *FullLibName, char *LibName)
  113. {
  114.     int NumOfParts;
  115.     FILE *f;
  116.     LibraryStruct *NewLib;
  117.     PriorQue *Entries;
  118.  
  119.     if (FindLibrary(LibName) != NULL) return;
  120.  
  121.     f = fopen(FullLibName, "rt");
  122.     if (f == NULL) {
  123.     IntrQueryContinue("Failed to open library", EEPopUpFrameColor,
  124.                       EEPopUpBackColor, EEPopUpForeColor,
  125.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  126.                           INTR_WNDW_PLACE_CENTER);
  127.     return;
  128.     }
  129.     if ((Entries = LoadLibraryAux(f, &NumOfParts)) != NULL) {
  130.     NewLib = (LibraryStruct *) MyMalloc(sizeof(LibraryStruct));
  131.     NewLib -> Entries = Entries;
  132.     NewLib -> NumOfParts = NumOfParts;
  133.     strcpy(NewLib -> Name, LibName);
  134.     NewLib -> Pnext = LibraryList;
  135.     LibraryList = NewLib;
  136.     }
  137.     fclose(f);
  138. }
  139.  
  140. /*****************************************************************************
  141. * Routine to load all libraries specified in LoadLibraryList which assumes   *
  142. * to hold names of libraries to load, seperated by commas and with no lib    *
  143. * extension. Note we dont use strtok as LoadLibraryName uses it internally.  *
  144. *****************************************************************************/
  145. void LoadLibraries(char *LoadLibraryList)
  146. {
  147.     char *p, *NextLibName, Name[LINE_LEN_SHORT], Line[LINE_LEN],
  148.     *LibName = LoadLibraryList;
  149.  
  150.     if (!strtok(LibName, "\n\r") || strlen(LibName) == 0) return;
  151.  
  152.     do {
  153.     if ((NextLibName = strchr(LibName, ',')) != NULL) {
  154.         NextLibName[0] = 0;
  155.         NextLibName = &NextLibName[1];
  156.     }
  157.  
  158.     strcpy(Name, LibName);
  159.     if ((p = strrchr(Name, '.')) != NULL && strlen(p) < 5) *p = 0;
  160.     strcat(Name, ".lib");
  161.     p = searchpath(Name);
  162.     if (p != NULL) {
  163.         IntrDrawMessage(p, EEPopUpForeColor, EEPopUpBackColor);
  164.         LoadLibraryName(p, LibName);
  165.         IntrEraseMessage();
  166.     }
  167.     else {
  168.             sprintf(Line, "Failed to find library \"%s\"", Name);
  169.         IntrQueryContinue(Line, EEPopUpFrameColor,
  170.                           EEPopUpBackColor, EEPopUpForeColor,
  171.                               EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  172.                               INTR_WNDW_PLACE_CENTER);
  173.         return;
  174.     }
  175.  
  176.     LibName = NextLibName;
  177.     }
  178.     while (LibName != NULL);
  179. }
  180.  
  181. /*****************************************************************************
  182. * Routine to free a library from the current loaded libraries.             *
  183. * If LibName is NULL, the user is interactively requested for lib name.         *
  184. *****************************************************************************/
  185. void FreeLibrary(char *LibName)
  186. {
  187.     int i,
  188.     NumOfLibs = NumOfLibraries();
  189.     char **Names;
  190.     LibraryStruct *Lib, *TempLib;
  191.  
  192.     if (NumOfLibs == 0) {
  193.     IntrQueryContinue("No libraries are loaded", EEPopUpFrameColor,
  194.                       EEPopUpBackColor, EEPopUpForeColor,
  195.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  196.                           INTR_WNDW_PLACE_CENTER);
  197.     return;
  198.     }
  199.     if (LibName == NULL) {        /* Need to ask for what lib to free: */
  200.     Names = (char **) MyMalloc(sizeof(char *) * NumOfLibs);
  201.     for (i = 0, Lib = LibraryList; Lib != NULL; Lib = Lib -> Pnext, i++)
  202.         Names[i] = Lib -> Name;
  203.         i = IntrQueryList("Free Lib", Names, 0, NumOfLibs,
  204.               EEListNumDisplayed, EEPopUpFrameColor,
  205.                           EEPopUpBackColor, EEPopUpForeColor,
  206.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  207.                           INTR_WNDW_PLACE_CENTER);
  208.     MyFree((VoidPtr) Names);
  209.  
  210.     if (i >= 0)
  211.         for (Lib = LibraryList; i > 0; i--, Lib = Lib -> Pnext);
  212.     else
  213.         return;
  214.     }
  215.     else {                 /* Simply search for this library name: */
  216.     for (Lib = LibraryList;
  217.          Lib != NULL && strcmp(LibName, Lib -> Name) != 0;
  218.          Lib = Lib -> Pnext);
  219.     if (Lib == NULL) return;
  220.     }
  221.  
  222.     if (Lib == LibraryList)
  223.     LibraryList = Lib -> Pnext;
  224.     else {
  225.     for (TempLib = LibraryList;
  226.          TempLib -> Pnext != Lib;
  227.          TempLib = TempLib -> Pnext);
  228.     TempLib -> Pnext = TempLib -> Pnext -> Pnext;
  229.     }
  230.     PQFreeFunc(Lib -> Entries, FreeLibraryEntry);
  231.     MyFree((VoidPtr) Lib);
  232. }
  233.  
  234. /*****************************************************************************
  235. * Routine to return pointers to all library names.                 *
  236. *****************************************************************************/
  237. char **GetLibNames(void)
  238. {
  239.     int i,
  240.     NumOfLibs = NumOfLibraries();
  241.     char **Names;
  242.     LibraryStruct *Lib;
  243.  
  244.     Names = (char **) MyMalloc(sizeof(char *) * (NumOfLibs + 1));
  245.     for (i = 0, Lib = LibraryList; Lib != NULL; Lib = Lib -> Pnext, i++)
  246.     Names[i] = Lib -> Name;
  247.     Names[i] = NULL;
  248.  
  249.     return Names;
  250. }
  251.  
  252. /*****************************************************************************
  253. * Routine to read one line from given file.                     *
  254. *****************************************************************************/
  255. static char *GetLine(FILE *f, char *Line, int *LineNum)
  256. {
  257.     do {
  258.     if (fgets(Line, LINE_LEN - 1, f) == NULL) return NULL;
  259.     ++*LineNum;
  260.     }
  261.     while (Line[0] == '#' || Line[0] == '\n' || Line[0] == 0);
  262.  
  263.     return Line;
  264. }
  265.  
  266. /*****************************************************************************
  267. * Routine to compare two LibraryEntryStruct for the PriorQue module.         *
  268. * Comparison is based on Part name.                         *
  269. *****************************************************************************/
  270. int LibraryEntryCompare(LibraryEntryStruct *LE1,
  271.             LibraryEntryStruct *LE2)
  272. {
  273.     return strcmp(LE1 -> Name, LE2 -> Name);
  274. }
  275.  
  276. /*****************************************************************************
  277. * Routine to load a library from given open file.                 *
  278. *****************************************************************************/
  279. static PriorQue *LoadLibraryAux(FILE *f, int *NumOfParts)
  280. {
  281.     int LineNum = 0;
  282.     char Line[LINE_LEN_LONG], *p, *Name, *Prefix;
  283.     BooleanType Res, HasLines;
  284.     PriorQue
  285.     *PQ = NULL;
  286.     LibraryEntryStruct *LibEntry;
  287.  
  288.     *NumOfParts = 0;
  289.  
  290.     if (GetLine(f, Line, &LineNum) == NULL ||
  291.     strncmp(Line, FILE_IDENT, sizeof(FILE_IDENT) - 1) != 0) {
  292.     IntrQueryContinue("File is NOT EEDRAW library!", EEPopUpFrameColor,
  293.                   EEPopUpBackColor, EEPopUpForeColor,
  294.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  295.                           INTR_WNDW_PLACE_CENTER);
  296.     return NULL;
  297.     }
  298.  
  299.     PQInit(&PQ);
  300.     PQCompFunc((PQCompFuncType) LibraryEntryCompare);
  301.  
  302.     while (GetLine(f, Line, &LineNum)) {
  303.     p = strtok(Line, " \t\n");
  304.  
  305.     if (strcmp(p, "DEF") != 0) {
  306.         sprintf(Line, "DEF command expected in line %d, aborted.",
  307.                                 LineNum);
  308.         IntrQueryContinue(Line, EEPopUpFrameColor,
  309.                       EEPopUpBackColor, EEPopUpForeColor,
  310.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  311.                               INTR_WNDW_PLACE_CENTER);
  312.  
  313.         return PQ;
  314.     }
  315.     else {
  316.         /* Read one DEF/ENDDEF part entry from library: */
  317.         LibEntry = (LibraryEntryStruct *)
  318.                        MyMalloc(sizeof(LibraryEntryStruct));
  319.         LibEntry -> BBoxMinX = LibEntry -> BBoxMaxX =
  320.         LibEntry -> BBoxMinY = LibEntry -> BBoxMaxY = 0;
  321.         LibEntry -> Pins = NULL;
  322.         LibEntry -> Drawings = NULL;
  323.         LibEntry -> Multi = NULL;
  324.  
  325.         if ((Name = strtok(NULL, " \t\n")) == NULL ||      /* Part name: */
  326.         (Prefix = strtok(NULL, " \t\n")) == NULL ||  /* Prefix name: */
  327.         (p = strtok(NULL, " \t\n")) == NULL ||         /* NumOfPins: */
  328.         sscanf(p, "%d", &LibEntry -> NumOfPins) != 1 ||
  329.         (p = strtok(NULL, " \t\n")) == NULL ||        /* TextInside: */
  330.         sscanf(p, "%d", &LibEntry -> TextInside) != 1 ||
  331.         (p = strtok(NULL, " \t\n")) == NULL ||            /* DrawNums: */
  332.         sscanf(p, "%d", &LibEntry -> DrawNums) != 1 ||
  333.         (p = strtok(NULL, " \t\n")) == NULL ||        /* NumOfUnits: */
  334.         sscanf(p, "%d", &LibEntry -> NumOfUnits) != 1 ||
  335.         (LibEntry -> NumOfUnits > 0 &&
  336.          ((p = strtok(NULL, " \t\n")) == NULL ||     /* PinsPerUnit: */
  337.            sscanf(p, "%d", &LibEntry -> PinsPerUnit) != 1)) ||
  338.         strlen(Name) > PART_NAME_LEN ||
  339.         strlen(Prefix) > PREFIX_NAME_LEN) {
  340.         sprintf(Line, "Wrong DEF format in line %d, aborted.",
  341.                                 LineNum);
  342.         IntrQueryContinue(Line, EEPopUpFrameColor,
  343.                       EEPopUpBackColor, EEPopUpForeColor,
  344.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  345.                               INTR_WNDW_PLACE_CENTER);
  346.         FreeLibraryEntry(LibEntry);
  347.         return PQ;
  348.         }
  349.         else {
  350.         /* Copy part name and prefix. */
  351.         strupr(Name);
  352.         if ((LibEntry -> DrawName = Name[0] != '~') != FALSE)
  353.             strcpy(LibEntry -> Name, Name);
  354.         else
  355.             strcpy(LibEntry -> Name, &Name[1]);
  356.         if (strcmp(Prefix, "~") == 0)
  357.             LibEntry -> Prefix[0] = 0;
  358.         else
  359.             strcpy(LibEntry -> Prefix, Prefix);
  360.         }
  361.  
  362.         HasLines = FALSE;
  363.         while (TRUE) {
  364.         GetLine(f, Line, &LineNum);
  365.         p = strtok(Line, " \t\n");
  366.  
  367.         Res = TRUE;
  368.         if (strcmp(p, "ENDDEF") == 0) {
  369.             ++*NumOfParts;
  370.             break;
  371.         }
  372.         else if (strcmp(p, "DRAW") == 0)
  373.             Res = (LibEntry -> Drawings =
  374.                GetDrawEntry(f, Line, &LineNum, &HasLines,
  375.                                LibEntry)) != NULL;
  376.         else if (strcmp(p, "PINS") == 0)
  377.             Res = (LibEntry -> Pins =
  378.                GetPinsEntry(f, Line, &LineNum, LibEntry -> NumOfPins))
  379.                                       != NULL;
  380.         else if (strcmp(p, "MULTI") == 0) {
  381.             if (LibEntry -> NumOfUnits > 0)
  382.             Res = (LibEntry -> Multi = GetMultiEntry(f, Line, &LineNum,
  383.                    LibEntry -> NumOfUnits, LibEntry -> PinsPerUnit))
  384.                                       != NULL;
  385.             else {
  386.             sprintf(Line, "MULTI found in DEF with #Units = 0 in line %d, aborted.",
  387.                                 LineNum);
  388.             IntrQueryContinue(Line, EEPopUpFrameColor,
  389.                       EEPopUpBackColor, EEPopUpForeColor,
  390.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  391.                               INTR_WNDW_PLACE_CENTER);
  392.             FreeLibraryEntry(LibEntry);
  393.             return PQ;
  394.             }
  395.         }
  396.         else {
  397.             sprintf(Line, "Undefined command \"%s\" in line %d, aborted.",
  398.                                 p, LineNum);
  399.             IntrQueryContinue(Line, EEPopUpFrameColor,
  400.                       EEPopUpBackColor, EEPopUpForeColor,
  401.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  402.                               INTR_WNDW_PLACE_CENTER);
  403.             FreeLibraryEntry(LibEntry);
  404.             return PQ;
  405.         }
  406.  
  407.         if (!Res) {              /* Something went wrong there. */
  408.             FreeLibraryEntry(LibEntry);
  409.             return PQ;
  410.         }
  411.         }
  412.         if (LibEntry -> Pins == NULL && HasLines) {
  413.         sprintf(Line, "No PINS defined for part in line %d, aborted.",
  414.                                 LineNum);
  415.         IntrQueryContinue(Line, EEPopUpFrameColor,
  416.                       EEPopUpBackColor, EEPopUpForeColor,
  417.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  418.                               INTR_WNDW_PLACE_CENTER);
  419.         MyFree((VoidPtr) LibEntry);
  420.         return PQ;
  421.         }
  422.         if (LibEntry -> NumOfUnits > 0) {
  423.         if (LibEntry -> Multi == NULL) {
  424.             sprintf(Line, "No MULTI defined for part in line %d, aborted.",
  425.                                 LineNum);
  426.             IntrQueryContinue(Line, EEPopUpFrameColor,
  427.                       EEPopUpBackColor, EEPopUpForeColor,
  428.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  429.                               INTR_WNDW_PLACE_CENTER);
  430.             MyFree((VoidPtr) LibEntry);
  431.             return PQ;
  432.         }
  433.         if (LibEntry -> Drawings == NULL) {
  434.             sprintf(Line, "No DRAW defined for part in line %d, aborted.",
  435.                                 LineNum);
  436.             IntrQueryContinue(Line, EEPopUpFrameColor,
  437.                       EEPopUpBackColor, EEPopUpForeColor,
  438.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  439.                               INTR_WNDW_PLACE_CENTER);
  440.             MyFree((VoidPtr) LibEntry);
  441.             return PQ;
  442.         }
  443.         }
  444.         if (LibEntry -> Drawings == NULL) {
  445.         /* Initialize BBox manually - its only a box with pins: */
  446.         LibEntry -> BBoxMaxX = LibEntry -> BBoxMaxY =
  447.            PIN_WIDTH * LibEntry -> NumOfPins / 2 + PIN_LENGTH;
  448.         LibEntry -> BBoxMinX = LibEntry -> BBoxMinY =
  449.             -LibEntry -> BBoxMaxX;
  450.         }
  451.  
  452.         /* If we are here, this part is O.k. - put it in: */
  453.         PQInsert(&PQ, LibEntry);
  454.     }
  455.     }
  456.  
  457.     return PQ;
  458. }
  459.  
  460. /*****************************************************************************
  461. * Routine to load a PINS definition from given file. Note "PINS" line has    *
  462. * been read already. Reads upto and include ENDPINS, or an error (NULL ret). *
  463. *****************************************************************************/
  464. static char *GetPinsEntry(FILE *f, char *Line, int *LineNum, int NumOfPins)
  465. {
  466.     int i;
  467.     char *p, Pins[LINE_LEN_LONG];
  468.  
  469.     Pins[0] = 0;
  470.     for (i = 0; i < NumOfPins; i++) {
  471.     if (GetLine(f, Line, LineNum) == NULL) {
  472.         IntrQueryContinue("File ended prematurely", EEPopUpFrameColor,
  473.                       EEPopUpBackColor, EEPopUpForeColor,
  474.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  475.                               INTR_WNDW_PLACE_CENTER);
  476.         return NULL;
  477.     }
  478.  
  479.     p = strtok(Line, "\n");             /* Remove the CR from line end. */
  480.     if (strcmp(p, "ENDPINS") == 0) {
  481.         sprintf(Line, "ENDPINS too soon (not enough pins) in line %d, aborted.", *LineNum);
  482.         IntrQueryContinue(Line, EEPopUpFrameColor,
  483.                       EEPopUpBackColor, EEPopUpForeColor,
  484.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  485.                               INTR_WNDW_PLACE_CENTER);
  486.         return NULL;
  487.     }
  488.     if ((p[0] == '~' && strlen(p) == 1))           /* Empty line ("~") ? */
  489.         strcat(Pins, "~");
  490.     else
  491.         strcat(Pins, p);
  492.     strcat(Pins, PIN_SEPERATOR);
  493.     if (strlen(Pins) > LINE_LEN_LONG - 10) {
  494.         sprintf(Line, "Pin definitions are too long in line %d, aborted.",
  495.                                 *LineNum);
  496.         IntrQueryContinue(Line, EEPopUpFrameColor,
  497.                       EEPopUpBackColor, EEPopUpForeColor,
  498.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  499.                               INTR_WNDW_PLACE_CENTER);
  500.         return NULL;
  501.     }
  502.     }
  503.  
  504.     if (GetLine(f, Line, LineNum) == NULL) {
  505.     IntrQueryContinue("File ended prematurely", EEPopUpFrameColor,
  506.                   EEPopUpBackColor, EEPopUpForeColor,
  507.                       EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  508.                           INTR_WNDW_PLACE_CENTER);
  509.     return NULL;
  510.     }
  511.     p = strtok(Line, " \t\n");
  512.     if (strcmp(p, "ENDPINS") != 0) {
  513.     sprintf(Line, "ENDPINS expected in line %d, aborted.", *LineNum);
  514.     IntrQueryContinue(Line, EEPopUpFrameColor,
  515.                   EEPopUpBackColor, EEPopUpForeColor,
  516.                       EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  517.                           INTR_WNDW_PLACE_CENTER);
  518.     return NULL;
  519.     }
  520.  
  521.     return strdup(Pins);
  522. }
  523.  
  524. /*****************************************************************************
  525. * Routine to load a MULTI definition from given file. Note "MULTI" line has  *
  526. * been read already. Reads upto and include ENDMULTI, or an error (NULL ret).*
  527. *****************************************************************************/
  528. static int *GetMultiEntry(FILE *f, char *Line, int *LineNum, int NumOfUnits,
  529.                             int PinsPerUnit)
  530. {
  531.     int i, j, *Array,
  532.     Count = 0;
  533.     char *p;
  534.  
  535.     Array = (int *) MyMalloc(sizeof(int) * NumOfUnits * PinsPerUnit);
  536.  
  537.     for (i = 0; i < NumOfUnits; i++) {
  538.     if (GetLine(f, Line, LineNum) == NULL) {
  539.         IntrQueryContinue("File ended prematurely", EEPopUpFrameColor,
  540.                       EEPopUpBackColor, EEPopUpForeColor,
  541.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  542.                               INTR_WNDW_PLACE_CENTER);
  543.         MyFree((VoidPtr) Array);
  544.         return NULL;
  545.     }
  546.  
  547.     for (p = strtok(Line, " \t\n"), j = 0;
  548.          j < PinsPerUnit;
  549.          p = strtok(NULL, " \t\n"), j++) {
  550.         if (p == NULL ||
  551.         sscanf(p, "%d", &Array[Count++]) != 1) {
  552.         sprintf(Line, "MULTI has less pins than needed in line %d",
  553.                                 *LineNum);
  554.         IntrQueryContinue(Line, EEPopUpFrameColor,
  555.                           EEPopUpBackColor, EEPopUpForeColor,
  556.                               EEPopUpXorColor, EEWindowsFrameWidth,
  557.                                   &Cursor, INTR_WNDW_PLACE_CENTER);
  558.         MyFree((VoidPtr) Array);
  559.         return NULL;
  560.         }
  561.     }
  562.     }
  563.  
  564.     if (GetLine(f, Line, LineNum) == NULL) {
  565.     IntrQueryContinue("File ended prematurely", EEPopUpFrameColor,
  566.                   EEPopUpBackColor, EEPopUpForeColor,
  567.                       EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  568.                           INTR_WNDW_PLACE_CENTER);
  569.     return NULL;
  570.     }
  571.     p = strtok(Line, " \t\n");
  572.     if (strcmp(p, "ENDMULTI") != 0) {
  573.     sprintf(Line, "ENDMULTI expected in line %d, aborted.", *LineNum);
  574.     IntrQueryContinue(Line, EEPopUpFrameColor,
  575.                   EEPopUpBackColor, EEPopUpForeColor,
  576.                       EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  577.                           INTR_WNDW_PLACE_CENTER);
  578.     return NULL;
  579.     }
  580.  
  581.     return Array;
  582. }
  583.  
  584. /*****************************************************************************
  585. * Routine to load a DRAW definition from given file. Note "DRAW" line has    *
  586. * been read already. Reads upto and include ENDDRAW, or an error (NULL ret). *
  587. *****************************************************************************/
  588. static LibraryDrawEntryStruct *GetDrawEntry(FILE *f, char *Line, int *LineNum,
  589.             BooleanType *HasLines, LibraryEntryStruct *LibEntry)
  590. {
  591.     int i;
  592.     char *p, Buffer[LINE_LEN_SHORT];
  593.     RealType r;
  594.     BooleanType
  595.     Error = FALSE;
  596.     LibraryDrawEntryStruct *Tail, *New,
  597.     *Head = NULL;
  598.  
  599.     *HasLines = FALSE;
  600.  
  601.     while (TRUE) {
  602.     if (GetLine(f, Line, LineNum) == NULL) {
  603.         IntrQueryContinue("File ended prematurely", EEPopUpFrameColor,
  604.                       EEPopUpBackColor, EEPopUpForeColor,
  605.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  606.                               INTR_WNDW_PLACE_CENTER);
  607.         return Head;
  608.     }
  609.  
  610.     if (strncmp(Line, "ENDDRAW", 7) == 0) break;
  611.  
  612.     New = (LibraryDrawEntryStruct *)
  613.                    MyMalloc(sizeof(LibraryDrawEntryStruct));
  614.     New -> Pnext = NULL;
  615.  
  616.     switch (Line[0]) {
  617.         case 'A': /* Arc */
  618.         New -> DrawType = ARC_DRAW_TYPE;
  619.         Error = sscanf(&Line[2], "%d %d %d %d %d",
  620.             &New -> U.Arc.x, &New -> U.Arc.y, &New -> U.Arc.r,
  621.             &New -> U.Arc.t1, &New -> U.Arc.t2) != 5;
  622.         New ->U.Arc.x *= LIB_SCALE_DRAW;
  623.         New ->U.Arc.y *= LIB_SCALE_DRAW;
  624.         New ->U.Arc.r *= LIB_SCALE_DRAW;
  625.         NORMALIZE_ANGLE(New -> U.Arc.t1);
  626.         NORMALIZE_ANGLE(New -> U.Arc.t2);
  627.         if (New -> U.Arc.t1 > New -> U.Arc.t2)
  628.             New -> U.Arc.t2 += 360;
  629.         New -> U.Arc.t1 += 1; /* Force arc of 180 degree to be less. */
  630.         New -> U.Arc.t2 -= 1;
  631.  
  632.         /* Update the bbox: */
  633.         UpdateBBox(LibEntry, New -> U.Arc.x - New -> U.Arc.r,
  634.                      New -> U.Arc.y - New -> U.Arc.r);
  635.         UpdateBBox(LibEntry, New -> U.Arc.x + New -> U.Arc.r,
  636.                      New -> U.Arc.y + New -> U.Arc.r);
  637.         break;
  638.         case 'C': /* Circle */
  639.         New -> DrawType = CIRCLE_DRAW_TYPE;
  640.         Error = sscanf(&Line[2], "%d %d %d",
  641.             &New -> U.Circ.x, &New -> U.Circ.y, &New -> U.Circ.r) != 3;
  642.         New ->U.Circ.x *= LIB_SCALE_DRAW;
  643.         New ->U.Circ.y *= LIB_SCALE_DRAW;
  644.         New ->U.Circ.r *= LIB_SCALE_DRAW;
  645.         /* Update the bbox: */
  646.         UpdateBBox(LibEntry, New -> U.Circ.x - New -> U.Circ.r,
  647.                      New -> U.Circ.y - New -> U.Circ.r);
  648.         UpdateBBox(LibEntry, New -> U.Circ.x + New -> U.Circ.r,
  649.                      New -> U.Circ.y + New -> U.Circ.r);
  650.         break;
  651.         case 'T': /* Text */
  652.         New -> DrawType = TEXT_DRAW_TYPE;
  653.         Error = sscanf(&Line[2], "%d %d %d %s",
  654.                    &New -> U.Text.x, &New -> U.Text.y,
  655.                    &New -> U.Text.Horiz, Buffer) != 4;
  656.         if (!Error) {               /* Convert '~' to spaces. */
  657.             for (i = 0; i < strlen(Buffer); i++)
  658.             if (Buffer[i] == '~') Buffer[i] = ' ';
  659.             New -> U.Text.Text = strdup(Buffer);
  660.         }
  661.         New ->U.Text.x *= LIB_SCALE_DRAW;
  662.         New ->U.Text.y *= LIB_SCALE_DRAW;
  663.         break;
  664.         case 'S': /* Square */
  665.         New -> DrawType = SQUARE_DRAW_TYPE;
  666.         Error = sscanf(&Line[2], "%d %d %d %d",
  667.                    &New -> U.Sqr.x1, &New -> U.Sqr.y1,
  668.                    &New -> U.Sqr.x2, &New -> U.Sqr.y2) != 4;
  669.         New ->U.Sqr.x1 *= LIB_SCALE_DRAW;
  670.         New ->U.Sqr.y1 *= LIB_SCALE_DRAW;
  671.         New ->U.Sqr.x2 *= LIB_SCALE_DRAW;
  672.         New ->U.Sqr.y2 *= LIB_SCALE_DRAW;
  673.         break;
  674.         case 'L': /* Line */
  675.         *HasLines = TRUE;
  676.         New -> DrawType = LINE_DRAW_TYPE;
  677.         if ((i = sscanf(&Line[2], "%d %d %d %d %s",
  678.                 &New -> U.Line.x1, &New -> U.Line.y1,
  679.                 &New -> U.Line.x2, &New -> U.Line.y2,
  680.                 Buffer)) != 5)
  681.             i = sscanf(&Line[2], "%d %d %d %d",
  682.                    &New -> U.Line.x1, &New -> U.Line.y1,
  683.                    &New -> U.Line.x2, &New -> U.Line.y2);
  684.         Error = (i != 4 && i != 5) ||
  685.             (New -> U.Line.x1 != New -> U.Line.x2 &&
  686.              New -> U.Line.y1 != New -> U.Line.y2);
  687.         New ->U.Line.x1 *= LIB_SCALE_DRAW;
  688.         New ->U.Line.y1 *= LIB_SCALE_DRAW;
  689.         New ->U.Line.x2 *= LIB_SCALE_DRAW;
  690.         New ->U.Line.y2 *= LIB_SCALE_DRAW;
  691.         UpdateBBox(LibEntry, New -> U.Line.x1, New -> U.Line.y1);
  692.         UpdateBBox(LibEntry, New -> U.Line.x2, New -> U.Line.y2);
  693.         New -> U.Line.Invert = i == 5 && Buffer[0] == 'I';
  694.         break;
  695.         case 'P': /* Polyline */
  696.         New -> DrawType = POLYLINE_DRAW_TYPE;
  697.         New -> U.Poly.PolyList = NULL;
  698.         p = strtok(&Line[2], " \t\n");
  699.         if (sscanf(p, "%d", &New -> U.Poly.n) == 1 &&
  700.             New -> U.Poly.n > 0) {
  701.             New -> U.Poly.PolyList = (int *)
  702.             MyMalloc(sizeof(int) * New -> U.Poly.n * 2);
  703.             for (i = 0; i < New -> U.Poly.n * 2 && !Error; i++) {
  704.             p = strtok(NULL, " \t\n");
  705.             Error = sscanf(p, "%d", &New -> U.Poly.PolyList[i]) !=
  706.                                     1;
  707.             New ->U.Poly.PolyList[i] *= LIB_SCALE_DRAW;
  708.             if (i % 2 != 0)
  709.                 UpdateBBox(LibEntry, New -> U.Poly.PolyList[i-1],
  710.                          New -> U.Poly.PolyList[i]);
  711.             }
  712.             New -> U.Poly.Fill = (p = strtok(NULL, " \t\n")) != NULL &&
  713.                      p[0] == 'F';
  714.         }
  715.         else
  716.             Error = TRUE;
  717.         Error |= New -> U.Poly.Fill &&
  718.             (New -> U.Poly.PolyList[0] != New -> U.Poly.PolyList[i-2] ||
  719.              New -> U.Poly.PolyList[1] != New -> U.Poly.PolyList[i-1]);
  720.         if (Error && New -> U.Poly.PolyList)
  721.             MyFree((VoidPtr) New -> U.Poly.PolyList);
  722.         break;
  723.         default:
  724.         sprintf(Line, "Undefined DRAW command in line %d, aborted.",
  725.                                 *LineNum);
  726.         IntrQueryContinue(Line, EEPopUpFrameColor,
  727.                           EEPopUpBackColor, EEPopUpForeColor,
  728.                               EEPopUpXorColor, EEWindowsFrameWidth,
  729.                                   &Cursor, INTR_WNDW_PLACE_CENTER);
  730.         return Head;
  731.     }
  732.     if (Error) {
  733.         sprintf(Line, "Error in %c DRAW command in line %d, aborted.",
  734.                             Line[0], *LineNum);
  735.         IntrQueryContinue(Line, EEPopUpFrameColor,
  736.                       EEPopUpBackColor, EEPopUpForeColor,
  737.                           EEPopUpXorColor, EEWindowsFrameWidth,
  738.                               &Cursor, INTR_WNDW_PLACE_CENTER);
  739.         MyFree((VoidPtr) New);
  740.         /* FLush till end of draw: */
  741.         do {
  742.         if (GetLine(f, Line, LineNum) == NULL) {
  743.             IntrQueryContinue("File ended prematurely",
  744.                                       EEPopUpFrameColor, EEPopUpBackColor,
  745.                                       EEPopUpForeColor, EEPopUpXorColor,
  746.                                       EEWindowsFrameWidth, &Cursor,
  747.                                       INTR_WNDW_PLACE_CENTER);
  748.             return Head;
  749.         }
  750.         }
  751.         while (strncmp(Line, "ENDDRAW", 7) != 0);
  752.         return Head;
  753.     }
  754.     else {
  755.         if (Head == NULL)
  756.         Head = Tail = New;
  757.         else {
  758.         Tail -> Pnext = New;
  759.         Tail = New;
  760.         }
  761.     }
  762.     }
  763.  
  764.     /* Update the bbox to the maximum extrem as we may rotate the object. */
  765.     r = MAX(ABS(LibEntry->BBoxMinX), ABS(LibEntry->BBoxMaxX));
  766.     r = MAX(r, ABS(LibEntry->BBoxMinY));
  767.     r = MAX(r, ABS(LibEntry->BBoxMaxY));
  768.     LibEntry->BBoxMaxX = LibEntry->BBoxMaxY = r;
  769.     LibEntry->BBoxMinX = LibEntry->BBoxMinY = -r;
  770.  
  771.     return Head;
  772. }
  773.  
  774. /*****************************************************************************
  775. * Routine to update LibEntry bounding box accrding to given x, y value.         *
  776. *****************************************************************************/
  777. static void UpdateBBox(LibraryEntryStruct *LibEntry, int x, int y)
  778. {
  779.     if (LibEntry -> BBoxMinX > x) LibEntry -> BBoxMinX = x;
  780.     if (LibEntry -> BBoxMaxX < x) LibEntry -> BBoxMaxX = x;
  781.     if (LibEntry -> BBoxMinY > y) LibEntry -> BBoxMinY = y;
  782.     if (LibEntry -> BBoxMaxY < y) LibEntry -> BBoxMaxY = y;
  783. }
  784.  
  785. /*****************************************************************************
  786. * Routine to free one library entry.                         *
  787. *****************************************************************************/
  788. static void FreeLibraryEntry(LibraryEntryStruct *Entry)
  789. {
  790.     LibraryDrawEntryStruct *TempDraw,
  791.     *Drawings = Entry -> Drawings;
  792.  
  793.     if (Entry -> Pins) MyFree((VoidPtr) Entry -> Pins);
  794.     if (Entry -> Multi) MyFree((VoidPtr) Entry -> Multi);
  795.     while (Drawings) {
  796.     TempDraw = Drawings;
  797.     Drawings = Drawings -> Pnext;
  798.  
  799.     switch (TempDraw -> DrawType) {
  800.         case ARC_DRAW_TYPE:
  801.         case CIRCLE_DRAW_TYPE:
  802.         case SQUARE_DRAW_TYPE:
  803.         case LINE_DRAW_TYPE:
  804.         break;
  805.         case TEXT_DRAW_TYPE:
  806.         MyFree((VoidPtr) TempDraw -> U.Text.Text);
  807.         break;
  808.         case POLYLINE_DRAW_TYPE:
  809.         MyFree((VoidPtr) TempDraw -> U.Poly.PolyList);
  810.         break;
  811.     }
  812.     MyFree((VoidPtr) TempDraw);
  813.     }
  814.  
  815.     MyFree((VoidPtr) Entry);
  816. }
  817.  
  818. /*****************************************************************************
  819. * Routine to find the library given its name.                     *
  820. *****************************************************************************/
  821. static LibraryStruct *FindLibrary(char *Name)
  822. {
  823.     LibraryStruct
  824.     *Lib = LibraryList;
  825.  
  826.     while (Lib) {
  827.     if (strcmp(Name, Lib -> Name) == 0) return Lib;
  828.     Lib = Lib -> Pnext;
  829.     }
  830.     return NULL;
  831. }
  832.  
  833. /*****************************************************************************
  834. * Routine to find the number of libraries currently loaded.             *
  835. *****************************************************************************/
  836. int NumOfLibraries(void)
  837. {
  838.     int i;
  839.     LibraryStruct
  840.     *Lib = LibraryList;
  841.  
  842.     for (i = 0; Lib != NULL; Lib = Lib -> Pnext) i++;
  843.  
  844.     return i;
  845. }
  846.