示例#1
0
static void
btsco_sco_disconnected(void *arg, int err)
{
	struct btsco_softc *sc = arg;

	DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state);

	KASSERT(sc->sc_sco != NULL);

	sc->sc_err = err;
	sco_detach_pcb(&sc->sc_sco);

	switch (sc->sc_state) {
	case BTSCO_CLOSED:		/* dont think this can happen */
		break;

	case BTSCO_WAIT_CONNECT:	/* connect failed */
		cv_broadcast(&sc->sc_connect);
		break;

	case BTSCO_OPEN:		/* link lost */
		/*
		 * If IO is in progress, tell the audio driver that it
		 * has completed so that when it tries to send more, we
		 * can indicate an error.
		 */
		mutex_enter(&sc->sc_intr_lock);
		if (sc->sc_tx_pending > 0) {
			sc->sc_tx_pending = 0;
			(*sc->sc_tx_intr)(sc->sc_tx_intrarg);
		}
		if (sc->sc_rx_want > 0) {
			sc->sc_rx_want = 0;
			(*sc->sc_rx_intr)(sc->sc_rx_intrarg);
		}
		mutex_exit(&sc->sc_intr_lock);
		break;

	default:
		UNKNOWN(sc->sc_state);
	}

	sc->sc_state = BTSCO_CLOSED;
}
示例#2
0
文件: create.c 项目: thequux/pcb
/* ---------------------------------------------------------------------------
 * creates a new pin in an element
 */
PinTypePtr
CreateNewPin (ElementTypePtr Element,
	      LocationType X, LocationType Y,
	      BDimension Thickness, BDimension Clearance, BDimension Mask,
	      BDimension DrillingHole, char *Name, char *Number,
	      FlagType Flags)
{
  PinTypePtr pin = GetPinMemory (Element);

  /* copy values */
  pin->X = X;
  pin->Y = Y;
  pin->Thickness = Thickness;
  pin->Clearance = Clearance;
  pin->Mask = Mask;
  pin->Name = STRDUP (Name);
  pin->Number = STRDUP (Number);
  pin->Flags = Flags;
  CLEAR_FLAG (WARNFLAG, pin);
  SET_FLAG (PINFLAG, pin);
  pin->ID = ID++;
  pin->Element = Element;

  /* 
   * If there is no vendor drill map installed, this will simply
   * return DrillingHole.
   */
  pin->DrillingHole = vendorDrillMap (DrillingHole);

  /* Unless we should not map drills on this element, map them! */
  if (vendorIsElementMappable (Element))
    {
      if (pin->DrillingHole < MIN_PINORVIASIZE)
	{
	  Message (_
		   ("Did not map pin #%s (%s) drill hole because %6.2f mil is below the minimum allowed size\n"),
		   UNKNOWN (Number), UNKNOWN (Name),
		   0.01 * pin->DrillingHole);
	  pin->DrillingHole = DrillingHole;
	}
      else if (pin->DrillingHole > MAX_PINORVIASIZE)
	{
	  Message (_
		   ("Did not map pin #%s (%s) drill hole because %6.2f mil is above the maximum allowed size\n"),
		   UNKNOWN (Number), UNKNOWN (Name),
		   0.01 * pin->DrillingHole);
	  pin->DrillingHole = DrillingHole;
	}
      else if (!TEST_FLAG (HOLEFLAG, pin)
	       && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER))
	{
	  Message (_
		   ("Did not map pin #%s (%s) drill hole because %6.2f mil does not leave enough copper\n"),
		   UNKNOWN (Number), UNKNOWN (Name),
		   0.01 * pin->DrillingHole);
	  pin->DrillingHole = DrillingHole;
	}
    }
  else
    {
      pin->DrillingHole = DrillingHole;
    }

  if (pin->DrillingHole != DrillingHole)
    {
      Message (_
	       ("Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n"),
	       0.01 * pin->DrillingHole, 0.01 * DrillingHole);
    }

  return (pin);
}
示例#3
0
文件: bom.c 项目: bgamari/geda-pcb
static int
PrintBOM (void)
{
  char utcTime[64];
  Coord x, y;
  double theta = 0.0;
  double sumx, sumy;
  int pinfound[MAXREFPINS];
  double pinx[MAXREFPINS];
  double piny[MAXREFPINS];
  double pinangle[MAXREFPINS];
  double padcentrex, padcentrey;
  double centroidx, centroidy;
  double pin1x, pin1y;
  int pin_cnt;
  int found_any_not_at_centroid;
  int found_any;
  time_t currenttime;
  FILE *fp;
  BomList *bom = NULL;
  char *name, *descr, *value,*fixed_rotation;
  int rpindex;

  fp = fopen (xy_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", xy_filename);
      return 1;
    }

  /* Create a portable timestamp. */
  currenttime = time (NULL);
  {
    /* avoid gcc complaints */
    const char *fmt = "%c UTC";
    strftime (utcTime, sizeof (utcTime), fmt, gmtime (&currenttime));
  }
  fprintf (fp, "# PcbXY Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n");
  /* don't use localized xy_unit->in_suffix here since */
  /* the line itself is not localized and not for GUI  */
  fprintf (fp, "# X,Y in %s.  rotation in degrees.\n", xy_unit->suffix);
  fprintf (fp, "# --------------------------------------------\n");

  /*
   * For each element we calculate the centroid of the footprint.
   * In addition, we need to extract some notion of rotation.
   * While here generate the BOM list
   */

  ELEMENT_LOOP (PCB->Data);
  {

    /* Initialize our pin count and our totals for finding the centroid. */
    pin_cnt = 0;
    sumx = 0.0;
    sumy = 0.0;
    for (rpindex = 0; rpindex < MAXREFPINS; rpindex++)
      pinfound[rpindex] = 0;

    /* Insert this component into the bill of materials list. */
    bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)),
                      (char *)UNKNOWN (DESCRIPTION_NAME (element)),
                      (char *)UNKNOWN (VALUE_NAME (element)), bom);


    /*
     * Iterate over the pins and pads keeping a running count of how
     * many pins/pads total and the sum of x and y coordinates
     *
     * While we're at it, store the location of pin/pad #1 and #2 if
     * we can find them.
     */

    PIN_LOOP (element);
    {
      sumx += (double) pin->X;
      sumy += (double) pin->Y;
      pin_cnt++;

      for (rpindex = 0; reference_pin_names[rpindex]; rpindex++)
        {
          if (NSTRCMP (pin->Number, reference_pin_names[rpindex]) == 0)
            {
                pinx[rpindex] = (double) pin->X;
                piny[rpindex] = (double) pin->Y;
                pinangle[rpindex] = 0.0; /* pins have no notion of angle */
                pinfound[rpindex] = 1;
            }
        }
    }
    END_LOOP;

    PAD_LOOP (element);
    {
      sumx += (pad->Point1.X + pad->Point2.X) / 2.0;
      sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0;
      pin_cnt++;

      for (rpindex = 0; reference_pin_names[rpindex]; rpindex++)
        {
          if (NSTRCMP (pad->Number, reference_pin_names[rpindex]) == 0)
            {
              padcentrex = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
              padcentrey = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
              pinx[rpindex] = padcentrex;
              piny[rpindex] = padcentrey;
              /*
               * NOTE: We swap the Y points because in PCB, the Y-axis
               * is inverted.  Increasing Y moves down.  We want to deal
               * in the usual increasing Y moves up coordinates though.
               */
              pinangle[rpindex] = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y,
                pad->Point2.X - pad->Point1.X);
              pinfound[rpindex]=1;
            }
        }
    }
    END_LOOP;

    if (pin_cnt > 0)
      {
	centroidx = sumx / (double) pin_cnt;
	centroidy = sumy / (double) pin_cnt;
	      
	if (NSTRCMP( AttributeGetFromList (&element->Attributes,"xy-centre"), "origin") == 0 )
	  {
            x = element->MarkX;
            y = element->MarkY;
	  }
	else
	  {
            x = centroidx;
            y = centroidy;
	  }
	
	fixed_rotation = AttributeGetFromList (&element->Attributes, "xy-fixed-rotation");
	if (fixed_rotation)
	  {	
            /* The user specified a fixed rotation */
            theta = atof (fixed_rotation);
            found_any_not_at_centroid = 1;
            found_any = 1;
	  } 
	else
	  {
            /* Find first reference pin not at the  centroid  */
            found_any_not_at_centroid = 0;
            found_any = 0;
            theta = 0.0;
            for (rpindex = 0;
                 reference_pin_names[rpindex] && !found_any_not_at_centroid;
                 rpindex++)
              {
		if (pinfound[rpindex])
		  {
                    found_any = 1;

                    /* Recenter pin "#1" onto the axis which cross at the part
                       centroid */
                    pin1x = pinx[rpindex] - x;
                    pin1y = piny[rpindex] - y;

                    /* flip x, to reverse rotation for elements on back */
                    if (FRONT (element) != 1)
                        pin1x = -pin1x;

                    /* if only 1 pin, use pin 1's angle */
                    if (pin_cnt == 1)
                      {
                        theta = pinangle[rpindex];
                        found_any_not_at_centroid = 1;
                      }
                    else if ((pin1x != 0.0) || (pin1y != 0.0))
                      {
                        theta = xyToAngle (pin1x, pin1y, pin_cnt > 2);
                        found_any_not_at_centroid = 1;
                      }
                  }
              }

            if (!found_any)
              {
                Message
                  ("PrintBOM(): unable to figure out angle because I could\n"
                   "     not find a suitable reference pin of element %s\n"
                   "     Setting to %g degrees\n",
                   UNKNOWN (NAMEONPCB_NAME (element)), theta);
              }
            else if (!found_any_not_at_centroid)
              {
                Message
                      ("PrintBOM(): unable to figure out angle of element\n"
                       "     %s because the reference pin(s) are at the centroid of the part.\n"
                       "     Setting to %g degrees\n",
                       UNKNOWN (NAMEONPCB_NAME (element)), theta);
	      }
          }
	name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element)));
	descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element)));
	value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element)));

 	y = PCB->MaxHeight - y;
	pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%.2mS,%.2mS,%g,%s\n",
		     xy_unit->allow, name, descr, value, x, y,
		     theta, FRONT (element) == 1 ? "top" : "bottom");
	free (name);
	free (descr);
	free (value);
      }
  }
  END_LOOP;

  fclose (fp);

  /* Now print out a Bill of Materials file */

  fp = fopen (bom_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", bom_filename);
      print_and_free (NULL, bom);
      return 1;
    }

  fprintf (fp, "# PcbBOM Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# Quantity, Description, Value, RefDes\n");
  fprintf (fp, "# --------------------------------------------\n");

  print_and_free (fp, bom);

  fclose (fp);

  return (0);
}
示例#4
0
/*!
 * \brief Creates a new pin in an element.
 */
PinType *
CreateNewPin (ElementType *Element,
	      Coord X, Coord Y,
	      Coord Thickness, Coord Clearance, Coord Mask,
	      Coord DrillingHole, char *Name, char *Number,
	      FlagType Flags)
{
  PinType *pin = GetPinMemory (Element);

  /* copy values */
  pin->X = X;
  pin->Y = Y;
  pin->Thickness = Thickness;
  pin->Clearance = Clearance;
  pin->Mask = Mask;
  pin->Name = STRDUP (Name);
  pin->Number = STRDUP (Number);
  pin->Flags = Flags;
  CLEAR_FLAG (WARNFLAG, pin);
  SET_FLAG (PINFLAG, pin);
  pin->ID = ID++;
  pin->Element = Element;

  /* 
   * If there is no vendor drill map installed, this will simply
   * return DrillingHole.
   */
  pin->DrillingHole = vendorDrillMap (DrillingHole);

  /* Unless we should not map drills on this element, map them! */
  if (vendorIsElementMappable (Element))
    {
      if (pin->DrillingHole < MIN_PINORVIASIZE)
	{
	  Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS is below the minimum allowed size\n"),
		   Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole);
	  pin->DrillingHole = DrillingHole;
	}
      else if (pin->DrillingHole > MAX_PINORVIASIZE)
	{
	  Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS is above the maximum allowed size\n"),
		   Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole);
	  pin->DrillingHole = DrillingHole;
	}
      else if (!TEST_FLAG (HOLEFLAG, pin)
	       && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER))
	{
	  Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS does not leave enough copper\n"),
		   Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole);
	  pin->DrillingHole = DrillingHole;
	}
    }
  else
    {
      pin->DrillingHole = DrillingHole;
    }

  if (pin->DrillingHole != DrillingHole)
    {
      Message (_("%m+Mapped pin drill hole to %$mS from %$mS per vendor table\n"),
	       Settings.grid_unit->allow, pin->DrillingHole, DrillingHole);
    }

  return (pin);
}
示例#5
0
文件: main.c 项目: bert/pcb-rnd
int
main (int argc, char *argv[])
{
  int i;

  /* init application:
   * - make program name available for error handlers
   * - evaluate special options
   * - initialize toplevel shell and resources
   * - create an empty PCB with default symbols
   * - initialize all other widgets
   * - update screen and get size of drawing area
   * - evaluate command-line arguments
   * - register 'call on exit()' function
   */

  setbuf (stdout, 0);
  InitPaths (argv[0]);

#ifdef LOCALEDIR
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  textdomain(GETTEXT_PACKAGE);
  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
  setlocale(LC_ALL,"");
#endif

  srand ( time(NULL) ); /* Set seed for rand() */

  initialize_units();
  polygon_init ();
  hid_init ();

  hid_load_settings ();

  program_name = argv[0];
  program_basename = strrchr (program_name, PCB_DIR_SEPARATOR_C);
  if (program_basename)
    {
      program_directory = strdup (program_name);
      *strrchr (program_directory, PCB_DIR_SEPARATOR_C) = 0;
      program_basename++;
    }
  else
    {
      program_directory = ".";
      program_basename = program_name;
    }
  Progname = program_basename;

  /* Print usage or version if requested.  Then exit.  */  
  if (argc > 1 &&
      (strcmp (argv[1], "-h") == 0 ||
       strcmp (argv[1], "-?") == 0 ||
       strcmp (argv[1], "--help") == 0))
    usage ();
  if (argc > 1 && strcmp (argv[1], "-V") == 0)
    print_version ();
  /* Export pcb from command line if requested.  */
  if (argc > 1 && strcmp (argv[1], "-p") == 0)
    {
      exporter = gui = hid_find_printer ();
      argc--;
      argv++;
    }
  else if (argc > 2 && strcmp (argv[1], "-x") == 0)
    {
      exporter = gui = hid_find_exporter (argv[2]);
      argc -= 2;
      argv += 2;
    }
    /* Otherwise start GUI. */
  else if (argc > 2 && strcmp (argv[1], "--gui") == 0)
  {
    gui = hid_find_gui (argv[2]);
    if (gui == NULL) {
      Message("Can't find the gui requested.\n");
      exit(1);
    }
    argc -= 2;
    argv += 2;
  }
  else {
    const char **g;

    gui = NULL;
    for(g = try_gui_hids; (*g != NULL) && (gui == NULL); g++) {
      gui = hid_find_gui (*g);
    }

    /* try anything */
    if (gui == NULL) {
      Message("Warning: can't find any of the preferred GUIs, falling back to anything available...\n");
      gui = hid_find_gui (NULL);
    }
  }

  /* Exit with error if GUI failed to start. */
  if (!gui)
    exit (1);

/* Initialize actions only when the gui is already known so only the right
   one is registered (there can be only one GUI). */
#include "action_list.h"


  /* Set up layers. */
  for (i = 0; i < MAX_LAYER; i++)
    {
      char buf[20];
      sprintf (buf, "signal%d", i + 1);
      Settings.DefaultLayerName[i] = strdup (buf);
      Settings.LayerColor[i] = "#c49350";
      Settings.LayerSelectedColor[i] = "#00ffff";
    }

  gui->parse_arguments (&argc, &argv);

  if (show_help || (argc > 1 && argv[1][0] == '-'))
    usage ();
  if (show_version)
    print_version ();
  if (show_defaults)
    print_defaults ();
  if (show_copyright)
    copyright ();

  settings_post_process ();


  if (show_actions)
    {
      print_actions ();
      exit (0);
    }

  if (do_dump_actions)
    {
      extern void dump_actions (void);
      dump_actions ();
      exit (0);
    }

  set_fontfile();

  /* Create a new PCB object in memory */
  PCB = CreateNewPCB ();

	if (PCB == NULL) {
		Message("Can't load the default pcb (%s) for creating an empty layout\n", Settings.DefaultPcbFile);
		exit(1);
	}

  /* Add silk layers to newly created PCB */
  CreateNewPCBPost (PCB, 1);
  if (argc > 1)
    command_line_pcb = argv[1];

  ResetStackAndVisibility ();

  if (gui->gui)
    InitCrosshair ();
  InitHandler ();
  InitBuffers ();
  SetMode (ARROW_MODE);

  if (command_line_pcb)
    {
      /* keep filename even if initial load command failed;
       * file might not exist
       */
      if (LoadPCB (command_line_pcb))
	PCB->Filename = strdup (command_line_pcb);
    }

  if (Settings.InitialLayerStack
      && Settings.InitialLayerStack[0])
    {
      LayerStringToLayerStack (Settings.InitialLayerStack);
    }

  /* This must be called before any other atexit functions
   * are registered, as it configures an atexit function to
   * clean up and free various items of allocated memory,
   * and must be the last last atexit function to run.
   */
  leaky_init ();

  /* Register a function to be called when the program terminates.
   * This makes sure that data is saved even if LEX/YACC routines
   * abort the program.
   * If the OS doesn't have at least one of them,
   * the critical sections will be handled by parse_l.l
   */
  atexit (EmergencySave);

  /* read the library file and display it if it's not empty
   */
  if (!ReadLibraryContents () && Library.MenuN)
    hid_action ("LibraryChanged");

#ifdef HAVE_LIBSTROKE
  stroke_init ();
#endif

  if (Settings.ScriptFilename)
    {
      Message (_("Executing startup script file %s\n"),
	       Settings.ScriptFilename);
      hid_actionl ("ExecuteFile", Settings.ScriptFilename, NULL);
    }
  if (Settings.ActionString)
    {
      Message (_("Executing startup action %s\n"), Settings.ActionString);
      hid_parse_actions (Settings.ActionString);
    }

  if (gui->printer || gui->exporter)
    {
      // Workaround to fix batch output for non-C locales
      setlocale(LC_NUMERIC,"C");
      gui->do_export (0);
      exit (0);
    }

#if HAVE_DBUS
  pcb_dbus_setup();
#endif

  EnableAutosave ();

#ifdef DEBUG
  printf ("Settings.FontPath            = \"%s\"\n", 
          Settings.FontPath);
  printf ("Settings.ElementPath         = \"%s\"\n", 
          Settings.ElementPath);
  printf ("Settings.LibrarySearchPaths  = \"%s\"\n", 
          Settings.LibrarySearchPaths);
  printf ("Settings.LibraryShell        = \"%s\"\n", 
          Settings.LibraryShell);
  printf ("Settings.MakeProgram = \"%s\"\n",
          UNKNOWN (Settings.MakeProgram));
  printf ("Settings.GnetlistProgram = \"%s\"\n",
          UNKNOWN (Settings.GnetlistProgram));
#endif

	buildin_init();

  gui->do_export (0);
#if HAVE_DBUS
  pcb_dbus_finish();
#endif

  return (0);
}
示例#6
0
/*
 * User Request.
 * up is socket
 * m is either
 *	optional mbuf chain containing message
 *	ioctl command (PRU_CONTROL)
 * nam is either
 *	optional mbuf chain containing an address
 *	ioctl data (PRU_CONTROL)
 *	optionally protocol number (PRU_ATTACH)
 *	message flags (PRU_RCVD)
 * ctl is either
 *	optional mbuf chain containing socket options
 *	optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
 * l is pointer to process requesting action (if any)
 *
 * we are responsible for disposing of m and ctl if
 * they are mbuf chains
 */
int
rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
		struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
{
	struct rfcomm_dlc *pcb = up->so_pcb;
	struct sockaddr_bt *sa;
	struct mbuf *m0;
	int err = 0;

	DPRINTFN(2, "%s\n", prurequests[req]);

	switch (req) {
	case PRU_CONTROL:
		return EPASSTHROUGH;

	case PRU_PURGEIF:
		return EOPNOTSUPP;

	case PRU_ATTACH:
		if (up->so_lock == NULL) {
			mutex_obj_hold(bt_lock);
			up->so_lock = bt_lock;
			solock(up);
		}
		KASSERT(solocked(up));
		if (pcb != NULL)
			return EINVAL;
		/*
		 * Since we have nothing to add, we attach the DLC
		 * structure directly to our PCB pointer.
		 */
		err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace);
		if (err)
			return err;

		err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb,
					&rfcomm_proto, up);
		if (err)
			return err;

		err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv));
		if (err) {
			rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
			return err;
		}

		return 0;
	}

	if (pcb == NULL) {
		err = EINVAL;
		goto release;
	}

	switch(req) {
	case PRU_DISCONNECT:
		soisdisconnecting(up);
		return rfcomm_disconnect(pcb, up->so_linger);

	case PRU_ABORT:
		rfcomm_disconnect(pcb, 0);
		soisdisconnected(up);
		/* fall through to */
	case PRU_DETACH:
		return rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);

	case PRU_BIND:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		return rfcomm_bind(pcb, sa);

	case PRU_CONNECT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		soisconnecting(up);
		return rfcomm_connect(pcb, sa);

	case PRU_PEERADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return rfcomm_peeraddr(pcb, sa);

	case PRU_SOCKADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return rfcomm_sockaddr(pcb, sa);

	case PRU_SHUTDOWN:
		socantsendmore(up);
		break;

	case PRU_SEND:
		KASSERT(m != NULL);

		if (ctl)	/* no use for that */
			m_freem(ctl);

		m0 = m_copypacket(m, M_DONTWAIT);
		if (m0 == NULL)
			return ENOMEM;

		sbappendstream(&up->so_snd, m);

		return rfcomm_send(pcb, m0);

	case PRU_SENSE:
		return 0;		/* (no release) */

	case PRU_RCVD:
		return rfcomm_rcvd(pcb, sbspace(&up->so_rcv));

	case PRU_RCVOOB:
		return EOPNOTSUPP;	/* (no release) */

	case PRU_LISTEN:
		return rfcomm_listen(pcb);

	case PRU_ACCEPT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return rfcomm_peeraddr(pcb, sa);

	case PRU_CONNECT2:
	case PRU_SENDOOB:
	case PRU_FASTTIMO:
	case PRU_SLOWTIMO:
	case PRU_PROTORCV:
	case PRU_PROTOSEND:
		err = EOPNOTSUPP;
		break;

	default:
		UNKNOWN(req);
		err = EOPNOTSUPP;
		break;
	}

release:
	if (m) m_freem(m);
	if (ctl) m_freem(ctl);
	return err;
}
示例#7
0
/*
 * User Request.
 * up is socket
 * m is either
 *	optional mbuf chain containing message
 *	ioctl command (PRU_CONTROL)
 * nam is either
 *	optional mbuf chain containing an address
 *	ioctl data (PRU_CONTROL)
 * ctl is optional mbuf chain containing socket options
 * l is pointer to process requesting action (if any)
 *
 * we are responsible for disposing of m and ctl if
 * they are mbuf chains
 */
static int
sco_usrreq(struct socket *up, int req, struct mbuf *m,
    struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
{
	struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb;
	struct sockaddr_bt *sa;
	struct mbuf *m0;
	int err = 0;

	DPRINTFN(2, "%s\n", prurequests[req]);
	KASSERT(req != PRU_ATTACH);
	KASSERT(req != PRU_DETACH);

	switch(req) {
	case PRU_CONTROL:
		return EOPNOTSUPP;

	case PRU_PURGEIF:
		return EOPNOTSUPP;
	}

	/* anything after here *requires* a pcb */
	if (pcb == NULL) {
		err = EINVAL;
		goto release;
	}

	switch(req) {
	case PRU_DISCONNECT:
		soisdisconnecting(up);
		return sco_disconnect(pcb, up->so_linger);

	case PRU_ABORT:
		sco_disconnect(pcb, 0);
		soisdisconnected(up);
		sco_detach(up);
		return 0;

	case PRU_BIND:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		return sco_bind(pcb, sa);

	case PRU_CONNECT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		soisconnecting(up);
		return sco_connect(pcb, sa);

	case PRU_PEERADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return sco_peeraddr(pcb, sa);

	case PRU_SOCKADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return sco_sockaddr(pcb, sa);

	case PRU_SHUTDOWN:
		socantsendmore(up);
		break;

	case PRU_SEND:
		KASSERT(m != NULL);
		if (m->m_pkthdr.len == 0)
			break;

		if (m->m_pkthdr.len > pcb->sp_mtu) {
			err = EMSGSIZE;
			break;
		}

		m0 = m_copypacket(m, M_DONTWAIT);
		if (m0 == NULL) {
			err = ENOMEM;
			break;
		}

		if (ctl) /* no use for that */
			m_freem(ctl);

		sbappendrecord(&up->so_snd, m);
		return sco_send(pcb, m0);

	case PRU_SENSE:
		return 0;		/* (no sense - Doh!) */

	case PRU_RCVD:
	case PRU_RCVOOB:
		return EOPNOTSUPP;	/* (no release) */

	case PRU_LISTEN:
		return sco_listen(pcb);

	case PRU_ACCEPT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return sco_peeraddr(pcb, sa);

	case PRU_CONNECT2:
	case PRU_SENDOOB:
	case PRU_FASTTIMO:
	case PRU_SLOWTIMO:
	case PRU_PROTORCV:
	case PRU_PROTOSEND:
		err = EOPNOTSUPP;
		break;

	default:
		UNKNOWN(req);
		err = EOPNOTSUPP;
		break;
	}

release:
	if (m) m_freem(m);
	if (ctl) m_freem(ctl);
	return err;
}
示例#8
0
文件: report.c 项目: veox/pcb
static int
ReportDialog (int argc, char **argv, Coord x, Coord y)
{
  void *ptr1, *ptr2, *ptr3;
  int type;
  char report[2048];

  type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3);
  if (type == NO_TYPE)
    type =
      SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3);

  switch (type)
    {
    case VIA_TYPE:
      {
	PinType *via;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->via_tree->root, 0);
	    return 0;
	  }
#endif
	via = (PinType *) ptr2;
	if (TEST_FLAG (HOLEFLAG, via))
	  pcb_snprintf (report, sizeof (report), _("%m+VIA ID# %ld; Flags:%s\n"
		   "(X,Y) = %$mD.\n"
		   "It is a pure hole of diameter %$mS.\n"
		   "Name = \"%s\"."
		   "%s"), USER_UNITMASK, via->ID, flags_to_string (via->Flags, VIA_TYPE),
		   via->X, via->Y, via->DrillingHole, EMPTY (via->Name),
		   TEST_FLAG (LOCKFLAG, via) ? _("It is LOCKED.\n") : "");
	else
	  pcb_snprintf (report, sizeof (report), _("%m+VIA ID# %ld;  Flags:%s\n"
		   "(X,Y) = %$mD.\n"
		   "Copper width = %$mS. Drill width = %$mS.\n"
		   "Clearance width in polygons = %$mS.\n"
		   "Annulus = %$mS.\n"
		   "Solder mask hole = %$mS (gap = %$mS).\n"
		   "Name = \"%s\"."
		   "%s"), USER_UNITMASK, via->ID, flags_to_string (via->Flags, VIA_TYPE),
		   via->X, via->Y,
		   via->Thickness,
		   via->DrillingHole,
		   via->Clearance / 2,
		   (via->Thickness - via->DrillingHole) / 2,
		   via->Mask,
		   (via->Mask - via->Thickness) / 2,
		   EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ?
		   _("It is LOCKED.\n") : "");
	break;
      }
    case PIN_TYPE:
      {
	PinType *Pin;
	ElementType *element;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->pin_tree->root, 0);
	    return 0;
	  }
#endif
	Pin = (PinType *) ptr2;
	element = (ElementType *) ptr1;

	PIN_LOOP (element);
	{
	  if (pin == Pin)
	    break;
	}
	END_LOOP;
	if (TEST_FLAG (HOLEFLAG, Pin))
	  pcb_snprintf (report, sizeof (report), _("%m+PIN ID# %ld; Flags:%s\n"
		   "(X,Y) = %$mD.\n"
		   "It is a mounting hole. Drill width = %$mS.\n"
		   "It is owned by element %$mS.\n"
		   "%s"), USER_UNITMASK, Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE),
		   Pin->X, Pin->Y, Pin->DrillingHole,
		   EMPTY (element->Name[1].TextString),
		   TEST_FLAG (LOCKFLAG, Pin) ? _("It is LOCKED.\n") : "");
	else
	  pcb_snprintf (report, sizeof (report),
		   _("%m+PIN ID# %ld;  Flags:%s\n" "(X,Y) = %$mD.\n"
		   "Copper width = %$mS. Drill width = %$mS.\n"
		   "Clearance width to Polygon = %$mS.\n"
		   "Annulus = %$mS.\n"
		   "Solder mask hole = %$mS (gap = %$mS).\n"
		   "Name = \"%s\".\n"
		   "It is owned by element %s\n as pin number %s.\n"
		   "%s"), USER_UNITMASK,
		   Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE),
		   Pin->X, Pin->Y, Pin->Thickness,
		   Pin->DrillingHole,
		   Pin->Clearance / 2,
		   (Pin->Thickness - Pin->DrillingHole) / 2,
		   Pin->Mask,
		   (Pin->Mask - Pin->Thickness) / 2,
		   EMPTY (Pin->Name),
		   EMPTY (element->Name[1].TextString), EMPTY (Pin->Number),
		   TEST_FLAG (LOCKFLAG, Pin) ? _("It is LOCKED.\n") : "");
	break;
      }
    case LINE_TYPE:
      {
	LineType *line;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    LayerType *layer = (LayerType *) ptr1;
	    __r_dump_tree (layer->line_tree->root, 0);
	    return 0;
	  }
#endif
	line = (LineType *) ptr2;
	pcb_snprintf (report, sizeof (report), _("%m+LINE ID# %ld;  Flags:%s\n"
		 "FirstPoint(X,Y)  = %$mD, ID = %ld.\n"
		 "SecondPoint(X,Y) = %$mD, ID = %ld.\n"
		 "Width = %$mS.\nClearance width in polygons = %$mS.\n"
		 "It is on layer %d\n"
		 "and has name \"%s\".\n"
		 "%s"), USER_UNITMASK,
		 line->ID, flags_to_string (line->Flags, LINE_TYPE),
		 line->Point1.X, line->Point1.Y, line->Point1.ID,
		 line->Point2.X, line->Point2.Y, line->Point2.ID,
		 line->Thickness, line->Clearance / 2,
		 GetLayerNumber (PCB->Data, (LayerType *) ptr1),
		 UNKNOWN (line->Number),
		 TEST_FLAG (LOCKFLAG, line) ? _("It is LOCKED.\n") : "");
	break;
      }
    case RATLINE_TYPE:
      {
	RatType *line;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->rat_tree->root, 0);
	    return 0;
	  }
#endif
	line = (RatType *) ptr2;
	pcb_snprintf (report, sizeof (report), _("%m+RAT-LINE ID# %ld;  Flags:%s\n"
		 "FirstPoint(X,Y)  = %$mD; ID = %ld; "
		 "connects to layer group %d.\n"
		 "SecondPoint(X,Y) = %$mD; ID = %ld; "
		 "connects to layer group %d.\n"),
		 USER_UNITMASK, line->ID, flags_to_string (line->Flags, LINE_TYPE),
		 line->Point1.X, line->Point1.Y,
		 line->Point1.ID, line->group1,
		 line->Point2.X, line->Point2.Y,
		 line->Point2.ID, line->group2);
	break;
      }
    case ARC_TYPE:
      {
	ArcType *Arc;
	BoxType *box;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    LayerType *layer = (LayerType *) ptr1;
	    __r_dump_tree (layer->arc_tree->root, 0);
	    return 0;
	  }
#endif
	Arc = (ArcType *) ptr2;
	box = GetArcEnds (Arc);

	pcb_snprintf (report, sizeof (report), _("%m+ARC ID# %ld;  Flags:%s\n"
		 "CenterPoint(X,Y) = %$mD.\n"
		 "Radius = %$mS, Thickness = %$mS.\n"
		 "Clearance width in polygons = %$mS.\n"
		 "StartAngle = %ma degrees, DeltaAngle = %ma degrees.\n"
		 "Bounding Box is %$mD, %$mD.\n"
		 "That makes the end points at %$mD and %$mD.\n"
		 "It is on layer %d.\n"
		 "%s"), USER_UNITMASK, Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE),
		 Arc->X, Arc->Y,
		 Arc->Width, Arc->Thickness,
		 Arc->Clearance / 2, Arc->StartAngle, Arc->Delta,
		 Arc->BoundingBox.X1, Arc->BoundingBox.Y1,
		 Arc->BoundingBox.X2, Arc->BoundingBox.Y2,
		 box->X1, box->Y1,
		 box->X2, box->Y2,
		 GetLayerNumber (PCB->Data, (LayerType *) ptr1),
		 TEST_FLAG (LOCKFLAG, Arc) ? _("It is LOCKED.\n") : "");
	break;
      }
    case POLYGON_TYPE:
      {
	PolygonType *Polygon;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    LayerType *layer = (LayerType *) ptr1;
	    __r_dump_tree (layer->polygon_tree->root, 0);
	    return 0;
	  }
#endif
	Polygon = (PolygonType *) ptr2;

	pcb_snprintf (report, sizeof (report), _("%m+POLYGON ID# %ld;  Flags:%s\n"
		 "Its bounding box is %$mD %$mD.\n"
		 "It has %d points and could store %d more\n"
		 "  without using more memory.\n"
		 "It has %d holes and resides on layer %d.\n"
		 "%s"), USER_UNITMASK, Polygon->ID,
		 flags_to_string (Polygon->Flags, POLYGON_TYPE),
		 Polygon->BoundingBox.X1, Polygon->BoundingBox.Y1,
		 Polygon->BoundingBox.X2, Polygon->BoundingBox.Y2,
		 Polygon->PointN, Polygon->PointMax - Polygon->PointN,
		 Polygon->HoleIndexN,
		 GetLayerNumber (PCB->Data, (LayerType *) ptr1),
		 TEST_FLAG (LOCKFLAG, Polygon) ? _("It is LOCKED.\n") : "");
	break;
      }
    case PAD_TYPE:
      {
	Coord len;
	PadType *Pad;
	ElementType *element;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->pad_tree->root, 0);
	    return 0;
	  }
#endif
	Pad = (PadType *) ptr2;
	element = (ElementType *) ptr1;

	PAD_LOOP (element);
	{
	  {
	    if (pad == Pad)
	      break;
	  }
	}
	END_LOOP;
	len = Distance (Pad->Point1.X, Pad->Point1.Y, Pad->Point2.X, Pad->Point2.Y);
	pcb_snprintf (report, sizeof (report), _("%m+PAD ID# %ld;  Flags:%s\n"
		 "FirstPoint(X,Y)  = %$mD; ID = %ld.\n"
		 "SecondPoint(X,Y) = %$mD; ID = %ld.\n"
		 "Width = %$mS.  Length = %$mS.\n"
		 "Clearance width in polygons = %$mS.\n"
		 "Solder mask = %$mS x %$mS (gap = %$mS).\n"
		 "Name = \"%s\".\n"
		 "It is owned by SMD element %s\n"
		 "  as pin number %s and is on the %s\n"
		 "side of the board.\n"
		 "%s"), USER_UNITMASK, Pad->ID,
		 flags_to_string (Pad->Flags, PAD_TYPE),
		 Pad->Point1.X, Pad->Point1.Y, Pad->Point1.ID,
		 Pad->Point2.X, Pad->Point2.Y, Pad->Point2.ID,
		 Pad->Thickness, len + Pad->Thickness,
		 Pad->Clearance / 2,
		 Pad->Mask, len + Pad->Mask,
		 (Pad->Mask - Pad->Thickness) / 2,
		 EMPTY (Pad->Name),
		 EMPTY (element->Name[1].TextString),
		 EMPTY (Pad->Number),
		 TEST_FLAG (ONSOLDERFLAG,
			    Pad) ? _("solder (bottom)") : _("component"),
		 TEST_FLAG (LOCKFLAG, Pad) ? _("It is LOCKED.\n") : "");
	break;
      }
    case ELEMENT_TYPE:
      {
	ElementType *element;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->element_tree->root, 0);
	    return 0;
	  }
#endif
	element = (ElementType *) ptr2;
	pcb_snprintf (report, sizeof (report), _("%m+ELEMENT ID# %ld;  Flags:%s\n"
		 "BoundingBox %$mD %$mD.\n"
		 "Descriptive Name \"%s\".\n"
		 "Name on board \"%s\".\n"
		 "Part number name \"%s\".\n"
		 "It is %$mS tall and is located at (X,Y) = %$mD %s.\n"
		 "Mark located at point (X,Y) = %$mD.\n"
		 "It is on the %s side of the board.\n"
		 "%s"), USER_UNITMASK,
		 element->ID, flags_to_string (element->Flags, ELEMENT_TYPE),
		 element->BoundingBox.X1, element->BoundingBox.Y1,
		 element->BoundingBox.X2, element->BoundingBox.Y2,
		 EMPTY (element->Name[0].TextString),
		 EMPTY (element->Name[1].TextString),
		 EMPTY (element->Name[2].TextString),
		 SCALE_TEXT (FONT_CAPHEIGHT, element->Name[1].Scale),
		 element->Name[1].X, element->Name[1].Y,
		 TEST_FLAG (HIDENAMEFLAG, element) ? _(",\n  but it's hidden") : "",
		 element->MarkX, element->MarkY,
		 TEST_FLAG (ONSOLDERFLAG, element) ? _("solder (bottom)") : _("component"),
		 TEST_FLAG (LOCKFLAG, element) ? _("It is LOCKED.\n") : "");
	break;
      }
    case TEXT_TYPE:
#ifndef NDEBUG
      if (gui->shift_is_pressed ())
	{
	  LayerType *layer = (LayerType *) ptr1;
	  __r_dump_tree (layer->text_tree->root, 0);
	  return 0;
	}
#endif
    case ELEMENTNAME_TYPE:
      {
	char laynum[32];
	TextType *text;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0);
	    return 0;
	  }
#endif
	text = (TextType *) ptr2;

	if (type == TEXT_TYPE)
	  sprintf (laynum, _("It is on layer %d."),
		   GetLayerNumber (PCB->Data, (LayerType *) ptr1));
	pcb_snprintf (report, sizeof (report), _("%m+TEXT ID# %ld;  Flags:%s\n"
		 "Located at (X,Y) = %$mD.\n"
		 "Characters are %$mS tall.\n"
		 "Value is \"%s\".\n"
		 "Direction is %d.\n"
		 "The bounding box is %$mD %$mD.\n"
		 "%s\n"
		 "%s"), USER_UNITMASK, text->ID, flags_to_string (text->Flags, TEXT_TYPE),
		 text->X, text->Y, SCALE_TEXT (FONT_CAPHEIGHT, text->Scale),
		 text->TextString, text->Direction,
		 text->BoundingBox.X1, text->BoundingBox.Y1,
		 text->BoundingBox.X2, text->BoundingBox.Y2,
		 (type == TEXT_TYPE) ? laynum : _("It is an element name."),
		 TEST_FLAG (LOCKFLAG, text) ? _("It is LOCKED.\n") : "");
	break;
      }
    case LINEPOINT_TYPE:
    case POLYGONPOINT_TYPE:
      {
	PointType *point = (PointType *) ptr2;
	pcb_snprintf (report, sizeof (report), _("%m+POINT ID# %ld.\n"
		 "Located at (X,Y) = %$mD.\n"
		 "It belongs to a %s on layer %d.\n"), USER_UNITMASK, point->ID,
		 point->X, point->Y,
		 (type == LINEPOINT_TYPE) ?
		     C_("report", "line") : C_("report", "polygon"),
		 GetLayerNumber (PCB->Data, (LayerType *) ptr1));
	break;
      }
    case NO_TYPE:
      report[0] = '\0';
      break;

    default:
      sprintf (report, _("Unknown\n"));
      break;
    }

  if (report[0] == '\0')
    {
      Message (_("Nothing found to report on\n"));
      return 1;
    }
  /* create dialog box */
  gui->report_dialog (_("Report"), report);

  return 0;
}
示例#9
0
static void
apply_vendor_map (void)
{
  int i;
  int changed, tot;
  bool state;

  state = vendorMapEnable;

  /* enable mapping */
  vendorMapEnable = true;

  /* reset our counts */
  changed = 0;
  tot = 0;

  /* If we have loaded vendor drills, then apply them to the design */
  if (n_vendor_drills > 0)
    {

      /* first all the vias */
      VIA_LOOP (PCB->Data);
      {
	tot++;
	if (via->DrillingHole != vendorDrillMap (via->DrillingHole))
	  {
	    /* only change unlocked vias */
	    if (!TEST_FLAG (LOCKFLAG, via))
	      {
		if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL,
					 vendorDrillMap (via->DrillingHole),
					 true, false))
		  changed++;
		else
		  {
		    Message (_
			     ("Via at %.2f, %.2f not changed.  Possible reasons:\n"
			      "\t- pad size too small\n"
			      "\t- new size would be too large or too small\n"),
			     0.01 * via->X, 0.01 * via->Y);
		  }
	      }
	    else
	      {
		Message (_("Locked via at %.2f, %.2f not changed.\n"),
			 0.01 * via->X, 0.01 * via->Y);
	      }
	  }
      }
      END_LOOP;

      /* and now the pins */
      ELEMENT_LOOP (PCB->Data);
      {
	/*
	 * first figure out if this element should be skipped for some
	 * reason
	 */
	if (vendorIsElementMappable (element))
	  {
	    /* the element is ok to modify, so iterate over its pins */
	    PIN_LOOP (element);
	    {
	      tot++;
	      if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole))
		{
		  if (!TEST_FLAG (LOCKFLAG, pin))
		    {
		      if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL,
					       vendorDrillMap (pin->
							       DrillingHole),
					       true, false))
			changed++;
		      else
			{
			  Message (_
				   ("Pin %s (%s) at %.2f, %.2f (element %s, %s, %s) not changed.\n"
				    "\tPossible reasons:\n"
				    "\t- pad size too small\n"
				    "\t- new size would be too large or too small\n"),
				   UNKNOWN (pin->Number), UNKNOWN (pin->Name),
				   0.01 * pin->X, 0.01 * pin->Y,
				   UNKNOWN (NAMEONPCB_NAME (element)),
				   UNKNOWN (VALUE_NAME (element)),
				   UNKNOWN (DESCRIPTION_NAME (element)));
			}
		    }
		  else
		    {
		      Message (_
			       ("Locked pin at %-6.2f, %-6.2f not changed.\n"),
			       0.01 * pin->X, 0.01 * pin->Y);
		    }
		}
	    }
	    END_LOOP;
	  }
      }
      END_LOOP;

      Message (_("Updated %d drill sizes out of %d total\n"), changed, tot);

      /* Update the current Via */
      if (Settings.ViaDrillingHole !=
	  vendorDrillMap (Settings.ViaDrillingHole))
	{
	  changed++;
	  Settings.ViaDrillingHole =
	    vendorDrillMap (Settings.ViaDrillingHole);
	  Message (_("Adjusted active via hole size to be %6.2f mils\n"),
		   0.01 * Settings.ViaDrillingHole);
	}

      /* and update the vias for the various routing styles */
      for (i = 0; i < NUM_STYLES; i++)
	{
	  if (PCB->RouteStyle[i].Hole !=
	      vendorDrillMap (PCB->RouteStyle[i].Hole))
	    {
	      changed++;
	      PCB->RouteStyle[i].Hole =
		vendorDrillMap (PCB->RouteStyle[i].Hole);
	      Message (_
		       ("Adjusted %s routing style via hole size to be %6.2f mils\n"),
		       PCB->RouteStyle[i].Name,
		       0.01 * PCB->RouteStyle[i].Hole);
	      if (PCB->RouteStyle[i].Diameter <
		  PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER)
		{
		  PCB->RouteStyle[i].Diameter =
		    PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER;
		  Message (_
			   ("Increased %s routing style via diameter to %6.2f mils\n"),
			   PCB->RouteStyle[i].Name,
			   0.01 * PCB->RouteStyle[i].Diameter);
		}
	    }
	}

      /* 
       * if we've changed anything, indicate that we need to save the
       * file, redraw things, and make sure we can undo.
       */
      if (changed)
	{
	  SetChangedFlag (true);
	  Redraw ();
	  IncrementUndoSerialNumber ();
	}
    }

  /* restore mapping on/off */
  vendorMapEnable = state;
}
示例#10
0
int
ActionLoadVendorFrom (int argc, char **argv, Coord x, Coord y)
{
  int i;
  char *fname = NULL;
  static char *default_file = NULL;
  char *sval;
  Resource *res, *drcres, *drlres;
  int type;
  bool free_fname = false;

  cached_drill = -1;

  fname = argc ? argv[0] : 0;

  if (!fname || !*fname)
    {
      fname = gui->fileselect (_("Load Vendor Resource File..."),
			       _("Picks a vendor resource file to load.\n"
				 "This file can contain drc settings for a\n"
				 "particular vendor as well as a list of\n"
				 "predefined drills which are allowed."),
			       default_file, ".res", "vendor",
			       HID_FILESELECT_READ);
      if (fname == NULL)
	AFAIL (load_vendor);

      free_fname = true;

      free (default_file);
      default_file = NULL;

      if (fname && *fname)
	default_file = strdup (fname);
    }

  /* Unload any vendor table we may have had */
  n_vendor_drills = 0;
  n_refdes = 0;
  n_value = 0;
  n_descr = 0;
  FREE (vendor_drills);
  FREE (ignore_refdes);
  FREE (ignore_value);
  FREE (ignore_descr);


  /* load the resource file */
  res = resource_parse (fname, NULL);
  if (res == NULL)
    {
      Message (_("Could not load vendor resource file \"%s\"\n"), fname);
      return 1;
    }

  /* figure out the vendor name, if specified */
  vendor_name = (char *)UNKNOWN (resource_value (res, "vendor"));

  /* figure out the units, if specified */
  sval = resource_value (res, "units");
  if (sval == NULL)
    {
      sf = MIL_TO_COORD(1);
    }
  else if ((NSTRCMP (sval, "mil") == 0) || (NSTRCMP (sval, "mils") == 0))
    {
      sf = MIL_TO_COORD(1);
    }
  else if ((NSTRCMP (sval, "inch") == 0) || (NSTRCMP (sval, "inches") == 0))
    {
      sf = INCH_TO_COORD(1);
    }
  else if (NSTRCMP (sval, "mm") == 0)
    {
      sf = MM_TO_COORD(1);
    }
  else
    {
      Message ("\"%s\" is not a supported units.  Defaulting to inch\n",
	       sval);
      sf = INCH_TO_COORD(1);
    }


  /* default to ROUND_UP */
  rounding_method = ROUND_UP;

  /* extract the drillmap resource */
  drlres = resource_subres (res, "drillmap");
  if (drlres == NULL)
    {
      Message (_("No drillmap resource found\n"));
    }
  else
    {
      sval = resource_value (drlres, "round");
      if (sval != NULL)
	{
	  if (NSTRCMP (sval, "up") == 0)
	    {
	      rounding_method = ROUND_UP;
	    }
	  else if (NSTRCMP (sval, "nearest") == 0)
	    {
	      rounding_method = CLOSEST;
	    }
	  else
	    {
	      Message (_
		       ("\"%s\" is not a valid rounding type.  Defaulting to up\n"),
		       sval);
	      rounding_method = ROUND_UP;
	    }
	}

      process_skips (resource_subres (drlres, "skips"));

      for (i = 0; i < drlres->c; i++)
	{
	  type = resource_type (drlres->v[i]);
	  switch (type)
	    {
	    case 10:
	      /* just a number */
	      add_to_drills (drlres->v[i].value);
	      break;

	    default:
	      break;
	    }
	}
    }

  /* Extract the DRC resource */
  drcres = resource_subres (res, "drc");

  sval = resource_value (drcres, "copper_space");
  if (sval != NULL)
    {
      PCB->Bloat = floor (sf * atof (sval) + 0.5);
      Message (_("Set DRC minimum copper spacing to %.2f mils\n"),
	       0.01 * PCB->Bloat);
    }

  sval = resource_value (drcres, "copper_overlap");
  if (sval != NULL)
    {
      PCB->Shrink = floor (sf * atof (sval) + 0.5);
      Message (_("Set DRC minimum copper overlap to %.2f mils\n"),
	       0.01 * PCB->Shrink);
    }

  sval = resource_value (drcres, "copper_width");
  if (sval != NULL)
    {
      PCB->minWid = floor (sf * atof (sval) + 0.5);
      Message (_("Set DRC minimum copper spacing to %.2f mils\n"),
	       0.01 * PCB->minWid);
    }

  sval = resource_value (drcres, "silk_width");
  if (sval != NULL)
    {
      PCB->minSlk = floor (sf * atof (sval) + 0.5);
      Message (_("Set DRC minimum silk width to %.2f mils\n"),
	       0.01 * PCB->minSlk);
    }

  sval = resource_value (drcres, "min_drill");
  if (sval != NULL)
    {
      PCB->minDrill = floor (sf * atof (sval) + 0.5);
      Message (_("Set DRC minimum drill diameter to %.2f mils\n"),
	       0.01 * PCB->minDrill);
    }

  sval = resource_value (drcres, "min_ring");
  if (sval != NULL)
    {
      PCB->minRing = floor (sf * atof (sval) + 0.5);
      Message (_("Set DRC minimum annular ring to %.2f mils\n"),
	       0.01 * PCB->minRing);
    }

  Message (_("Loaded %d vendor drills from %s\n"), n_vendor_drills, fname);
  Message (_("Loaded %d RefDes skips, %d Value skips, %d Descr skips\n"),
	   n_refdes, n_value, n_descr);

  vendorMapEnable = true;
  apply_vendor_map ();
  if (free_fname)
    free (fname);
  return 0;
}
示例#11
0
static int
btsco_open(void *hdl, int flags)
{
	struct sockaddr_bt sa;
	struct btsco_softc *sc = hdl;
	struct sockopt sopt;
	int err, timo;

	DPRINTF("%s flags 0x%x\n", sc->sc_name, flags);
	/* flags FREAD & FWRITE? */

	if (sc->sc_sco != NULL || sc->sc_sco_l != NULL)
		return EIO;

	KASSERT(mutex_owned(bt_lock));

	memset(&sa, 0, sizeof(sa));
	sa.bt_len = sizeof(sa);
	sa.bt_family = AF_BLUETOOTH;
	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);

	if (sc->sc_flags & BTSCO_LISTEN) {
		err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc);
		if (err)
			goto done;

		err = sco_bind_pcb(sc->sc_sco_l, &sa);
		if (err) {
			sco_detach_pcb(&sc->sc_sco_l);
			goto done;
		}

		err = sco_listen_pcb(sc->sc_sco_l);
		if (err) {
			sco_detach_pcb(&sc->sc_sco_l);
			goto done;
		}

		timo = 0;	/* no timeout */
	} else {
		err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc);
		if (err)
			goto done;

		err = sco_bind_pcb(sc->sc_sco, &sa);
		if (err) {
			sco_detach_pcb(&sc->sc_sco);
			goto done;
		}

		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
		err = sco_connect_pcb(sc->sc_sco, &sa);
		if (err) {
			sco_detach_pcb(&sc->sc_sco);
			goto done;
		}

		timo = BTSCO_TIMEOUT;
	}

	sc->sc_state = BTSCO_WAIT_CONNECT;
	while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT)
		err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo);

	switch (sc->sc_state) {
	case BTSCO_CLOSED:		/* disconnected */
		err = sc->sc_err;

		/* fall through to */
	case BTSCO_WAIT_CONNECT:	/* error */
		if (sc->sc_sco != NULL)
			sco_detach_pcb(&sc->sc_sco);

		if (sc->sc_sco_l != NULL)
			sco_detach_pcb(&sc->sc_sco_l);

		break;

	case BTSCO_OPEN:		/* hurrah */
		sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0);
		(void)sco_getopt(sc->sc_sco, &sopt);
		(void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu));
		sockopt_destroy(&sopt);
		break;

	default:
		UNKNOWN(sc->sc_state);
		break;
	}

done:
	DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n",
			err, sc->sc_state, sc->sc_mtu);
	return err;
}
示例#12
0
文件: bom.c 项目: BenBergman/geda-pcb
static int
PrintBOM (void)
{
  char utcTime[64];
  Coord x, y;
  double theta = 0.0;
  double sumx, sumy;
  double pin1x = 0.0, pin1y = 0.0, pin1angle = 0.0;
  double pin2x = 0.0, pin2y = 0.0;
  int found_pin1;
  int found_pin2;
  int pin_cnt;
  time_t currenttime;
  FILE *fp;
  BomList *bom = NULL;
  char *name, *descr, *value;

  fp = fopen (xy_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", xy_filename);
      return 1;
    }

  /* Create a portable timestamp. */
  currenttime = time (NULL);
  {
    /* avoid gcc complaints */
    const char *fmt = "%c UTC";
    strftime (utcTime, sizeof (utcTime), fmt, gmtime (&currenttime));
  }
  fprintf (fp, "# PcbXY Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n");
  fprintf (fp, "# X,Y in %s.  rotation in degrees.\n", xy_unit->in_suffix);
  fprintf (fp, "# --------------------------------------------\n");

  /*
   * For each element we calculate the centroid of the footprint.
   * In addition, we need to extract some notion of rotation.  
   * While here generate the BOM list
   */

  ELEMENT_LOOP (PCB->Data);
  {

    /* initialize our pin count and our totals for finding the
       centriod */
    pin_cnt = 0;
    sumx = 0.0;
    sumy = 0.0;
    found_pin1 = 0;
    found_pin2 = 0;

    /* insert this component into the bill of materials list */
    bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)),
		      (char *)UNKNOWN (DESCRIPTION_NAME (element)),
		      (char *)UNKNOWN (VALUE_NAME (element)), bom);


    /*
     * iterate over the pins and pads keeping a running count of how
     * many pins/pads total and the sum of x and y coordinates
     * 
     * While we're at it, store the location of pin/pad #1 and #2 if
     * we can find them
     */

    PIN_LOOP (element);
    {
      sumx += (double) pin->X;
      sumy += (double) pin->Y;
      pin_cnt++;

      if (NSTRCMP (pin->Number, "1") == 0)
	{
	  pin1x = (double) pin->X;
	  pin1y = (double) pin->Y;
	  pin1angle = 0.0;	/* pins have no notion of angle */
	  found_pin1 = 1;
	}
      else if (NSTRCMP (pin->Number, "2") == 0)
	{
	  pin2x = (double) pin->X;
	  pin2y = (double) pin->Y;
	  found_pin2 = 1;
	}
    }
    END_LOOP;

    PAD_LOOP (element);
    {
      sumx += (pad->Point1.X + pad->Point2.X) / 2.0;
      sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0;
      pin_cnt++;

      if (NSTRCMP (pad->Number, "1") == 0)
	{
	  pin1x = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
	  pin1y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
	  /*
	   * NOTE:  We swap the Y points because in PCB, the Y-axis
	   * is inverted.  Increasing Y moves down.  We want to deal
	   * in the usual increasing Y moves up coordinates though.
	   */
	  pin1angle = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y,
					      pad->Point2.X - pad->Point1.X);
	  found_pin1 = 1;
	}
      else if (NSTRCMP (pad->Number, "2") == 0)
	{
	  pin2x = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
	  pin2y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
	  found_pin2 = 1;
	}

    }
    END_LOOP;

    if (pin_cnt > 0)
      {
	x = sumx / (double) pin_cnt;
	y = sumy / (double) pin_cnt;

	if (found_pin1)
	  {
	    /* recenter pin #1 onto the axis which cross at the part
	       centroid */
	    pin1x -= x;
	    pin1y -= y;
	    pin1y = -1.0 * pin1y;

	    /* if only 1 pin, use pin 1's angle */
	    if (pin_cnt == 1)
	      theta = pin1angle;
	    else
	      {
		/* if pin #1 is at (0,0) use pin #2 for rotation */
		if ((pin1x == 0.0) && (pin1y == 0.0))
		  {
		    if (found_pin2)
		      theta = xyToAngle (pin2x, pin2y);
		    else
		      {
			Message
			  ("PrintBOM(): unable to figure out angle of element\n"
			   "     %s because pin #1 is at the centroid of the part.\n"
			   "     and I could not find pin #2's location\n"
			   "     Setting to %g degrees\n",
			   UNKNOWN (NAMEONPCB_NAME (element)), theta);
		      }
		  }
		else
		  theta = xyToAngle (pin1x, pin1y);
	      }
	  }
	/* we did not find pin #1 */
	else
	  {
	    theta = 0.0;
	    Message
	      ("PrintBOM(): unable to figure out angle because I could\n"
	       "     not find pin #1 of element %s\n"
	       "     Setting to %g degrees\n",
	       UNKNOWN (NAMEONPCB_NAME (element)), theta);
	  }

	name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element)));
	descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element)));
	value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element)));

 	y = PCB->MaxHeight - y;
	pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%mS,%.2mS,%g,%s\n",
		     xy_unit->allow, name, descr, value, x, y,
		     theta, FRONT (element) == 1 ? "top" : "bottom");
	free (name);
	free (descr);
	free (value);
      }
  }
  END_LOOP;

  fclose (fp);

  /* Now print out a Bill of Materials file */

  fp = fopen (bom_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", bom_filename);
      print_and_free (NULL, bom);
      return 1;
    }

  fprintf (fp, "# PcbBOM Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# Quantity, Description, Value, RefDes\n");
  fprintf (fp, "# --------------------------------------------\n");

  print_and_free (fp, bom);

  fclose (fp);

  return (0);
}
示例#13
0
/*
 * User Request.
 * up is socket
 * m is either
 *	optional mbuf chain containing message
 *	ioctl command (PRU_CONTROL)
 * nam is either
 *	optional mbuf chain containing an address
 *	ioctl data (PRU_CONTROL)
 *	optionally protocol number (PRU_ATTACH)
 *	message flags (PRU_RCVD)
 * ctl is either
 *	optional mbuf chain containing socket options
 *	optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
 * l is pointer to process requesting action (if any)
 *
 * we are responsible for disposing of m and ctl if
 * they are mbuf chains
 */
int
l2cap_usrreq(struct socket *up, int req, struct mbuf *m,
    struct mbuf *nam, struct mbuf *ctl, struct proc *p)
{
	struct l2cap_channel *pcb = up->so_pcb;
	struct sockaddr_bt *sa;
	struct mbuf *m0;
	int err = 0;

#ifdef notyet			/* XXX */
	DPRINTFN(2, "%s\n", prurequests[req]);
#endif

	switch (req) {
	case PRU_CONTROL:
		return EPASSTHROUGH;

#ifdef notyet			/* XXX */
	case PRU_PURGEIF:
		return EOPNOTSUPP;
#endif

	case PRU_ATTACH:
		/* XXX solock() and bt_lock fiddling in NetBSD */
		if (pcb != NULL)
			return EINVAL;
		/*
		 * For L2CAP socket PCB we just use an l2cap_channel structure
		 * since we have nothing to add..
		 */
		err = soreserve(up, l2cap_sendspace, l2cap_recvspace);
		if (err)
			return err;

		return l2cap_attach((struct l2cap_channel **)&up->so_pcb,
					&l2cap_proto, up);
	}

	if (pcb == NULL) {
		err = EINVAL;
		goto release;
	}

	switch(req) {
	case PRU_DISCONNECT:
		soisdisconnecting(up);
		return l2cap_disconnect(pcb, up->so_linger);

	case PRU_ABORT:
		l2cap_disconnect(pcb, 0);
		soisdisconnected(up);
		/* fall through to */
	case PRU_DETACH:
		return l2cap_detach((struct l2cap_channel **)&up->so_pcb);

	case PRU_BIND:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		return l2cap_bind(pcb, sa);

	case PRU_CONNECT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		soisconnecting(up);
		return l2cap_connect(pcb, sa);

	case PRU_PEERADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return l2cap_peeraddr(pcb, sa);

	case PRU_SOCKADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return l2cap_sockaddr(pcb, sa);

	case PRU_SHUTDOWN:
		socantsendmore(up);
		break;

	case PRU_SEND:
		KASSERT(m != NULL);
		if (m->m_pkthdr.len == 0)
			break;

		if (m->m_pkthdr.len > pcb->lc_omtu) {
			err = EMSGSIZE;
			break;
		}

		m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
		if (m0 == NULL) {
			err = ENOMEM;
			break;
		}

		if (ctl)	/* no use for that */
			m_freem(ctl);

		sbappendrecord(&up->so_snd, m);
		return l2cap_send(pcb, m0);

	case PRU_SENSE:
		return 0;		/* (no release) */

	case PRU_RCVD:
	case PRU_RCVOOB:
		return EOPNOTSUPP;	/* (no release) */

	case PRU_LISTEN:
		return l2cap_listen(pcb);

	case PRU_ACCEPT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return l2cap_peeraddr(pcb, sa);

	case PRU_CONNECT2:
	case PRU_SENDOOB:
	case PRU_FASTTIMO:
	case PRU_SLOWTIMO:
	case PRU_PROTORCV:
	case PRU_PROTOSEND:
		err = EOPNOTSUPP;
		break;

	default:
		UNKNOWN(req);
		err = EOPNOTSUPP;
		break;
	}

release:
	if (m) m_freem(m);
	if (ctl) m_freem(ctl);
	return err;
}
示例#14
0
文件: file.c 项目: bgamari/geda-pcb
/* ---------------------------------------------------------------------------
 * Read contents of the library description file (for M4)
 * and then read in M4 libs.  Then call a fcn to read the newlib
 * footprints.
 */
int
ReadLibraryContents (void)
{
  static char *command = NULL;
  char inputline[MAX_LIBRARY_LINE_LENGTH + 1];
  FILE *resultFP = NULL;
  LibraryMenuType *menu = NULL;
  LibraryEntryType *entry;

  /* If we don't have a command to execute to find the library contents,
   * skip this. This is used by default on Windows builds (set in main.c),
   * as we can't normally run shell scripts or expect to have m4 present.
   */
  if (Settings.LibraryContentsCommand != NULL &&
      Settings.LibraryContentsCommand[0] != '\0')
    {
      /*  First load the M4 stuff.  The variable Settings.LibraryPath
       *  points to it.
       */
      free (command);
      command = EvaluateFilename (Settings.LibraryContentsCommand,
				  Settings.LibraryPath, Settings.LibraryFilename,
				  NULL);

#ifdef DEBUG
      printf("In ReadLibraryContents, about to execute command %s\n", command);
#endif

      /* This uses a pipe to execute a shell script which provides the names of
       * all M4 libs and footprints.  The results are placed in resultFP.
       */
      if (command && *command && (resultFP = popen (command, "r")) == NULL)
	{
	  PopenErrorMessage (command);
	}

      /* the M4 library contents are separated by colons;
       * template : package : name : description
       */
      while (resultFP != NULL && fgets (inputline, MAX_LIBRARY_LINE_LENGTH, resultFP))
	{
	  size_t len = strlen (inputline);

	  /* check for maximum linelength */
	  if (len)
	    {
	      len--;
	      if (inputline[len] != '\n')
		Message
		  ("linelength (%i) exceeded; following characters will be ignored\n",
		   MAX_LIBRARY_LINE_LENGTH);
	      else
		inputline[len] = '\0';
	    }

	  /* if the line defines a menu */
	  if (!strncmp (inputline, "TYPE=", 5))
	    {
	      menu = GetLibraryMenuMemory (&Library);
	      menu->Name = strdup (UNKNOWN (&inputline[5]));
	      menu->directory = strdup (Settings.LibraryFilename);
	    }
	  else
	    {
	      /* allocate a new menu entry if not already done */
	      if (!menu)
		{
		  menu = GetLibraryMenuMemory (&Library);
		  menu->Name = strdup (UNKNOWN ((char *) NULL));
		  menu->directory = strdup (Settings.LibraryFilename);
		}
	      entry = GetLibraryEntryMemory (menu);
	      entry->AllocatedMemory = strdup (inputline);

	      /* now break the line into pieces separated by colons */
	      if ((entry->Template = strtok (entry->AllocatedMemory, ":")) !=
		  NULL)
		if ((entry->Package = strtok (NULL, ":")) != NULL)
		  if ((entry->Value = strtok (NULL, ":")) != NULL)
		    entry->Description = strtok (NULL, ":");

	      /* create the list entry */
	      len = strlen (EMPTY (entry->Value)) +
		strlen (EMPTY (entry->Description)) + 4;
	      entry->ListEntry = (char *)calloc (len, sizeof (char));
	      sprintf (entry->ListEntry,
		       "%s, %s", EMPTY (entry->Value),
		       EMPTY (entry->Description));
	    }
	}
      if (resultFP != NULL)
	pclose (resultFP);
    }

  /* Now after reading in the M4 libs, call a function to
   * read the newlib footprint libraries.  Then sort the whole
   * library.
   */
  if (ParseLibraryTree () > 0 || resultFP != NULL)
    {
      sort_library (&Library);
      return 0;
    }
  
  return (1);
}
示例#15
0
bool
vendorIsElementMappable (ElementType *element)
{
  int i;
  int noskip;

  if (vendorMapEnable == false)
    return false;

  noskip = 1;
  for (i = 0; i < n_refdes; i++)
    {
      if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) ==
	   0)
	  || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element))))
	{
	  Message (_
		   ("Vendor mapping skipped because refdes = %s matches %s\n"),
		   UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]);
	  noskip = 0;
	}
    }
  if (noskip)
    for (i = 0; i < n_value; i++)
      {
	if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0)
	    || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element))))
	  {
	    Message (_
		     ("Vendor mapping skipped because value = %s matches %s\n"),
		     UNKNOWN (VALUE_NAME (element)), ignore_value[i]);
	    noskip = 0;
	  }
      }

  if (noskip)
    for (i = 0; i < n_descr; i++)
      {
	if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i])
	     == 0)
	    || rematch (ignore_descr[i],
			UNKNOWN (DESCRIPTION_NAME (element))))
	  {
	    Message (_
		     ("Vendor mapping skipped because descr = %s matches %s\n"),
		     UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]);
	    noskip = 0;
	  }
      }

  if (noskip && TEST_FLAG (LOCKFLAG, element))
    {
      Message (_("Vendor mapping skipped because element %s is locked\n"),
	       UNKNOWN (NAMEONPCB_NAME (element)));
      noskip = 0;
    }

  if (noskip)
    return true;
  else
    return false;
}
示例#16
0
文件: report.c 项目: thequux/pcb
static int
ReportDialog (int argc, char **argv, int x, int y)
{
  void *ptr1, *ptr2, *ptr3;
  int type, prec = Settings.grid_units_mm? 4: 2;
  char report[2048];

  type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3);
  if (type == NO_TYPE)
    type =
      SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3);

  switch (type)
    {
    case VIA_TYPE:
      {
	PinTypePtr via;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->via_tree->root, 0);
	    return 0;
	  }
#endif
	via = (PinTypePtr) ptr2;
	if (TEST_FLAG (HOLEFLAG, via))
	  sprintf (&report[0], "VIA ID# %ld; Flags:%s\n"
		   "(X,Y) = (%.*f, %.*f) %s.\n"
		   "It is a pure hole of diameter %.*f %s.\n"
		   "Name = \"%s\"."
		   "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE),
		   prec, units (via->X), prec, UNIT (via->Y),
		   prec, UNIT (via->DrillingHole),
		   EMPTY (via->Name), TEST_FLAG (LOCKFLAG,
						 via) ? "It is LOCKED.\n" :
		   "");
	else
	  sprintf (&report[0], "VIA ID# %ld;  Flags:%s\n"
		   "(X,Y) = (%.*f, %.*f) %s.\n"
		   "Copper width = %0.*f %s. Drill width = %0.*f %s.\n"
		   "Clearance width in polygons = %0.*f %s.\n"
		   "Annulus = %0.*f %s.\n"
		   "Solder mask hole = %0.*f %s (gap = %0.*f %s).\n"
		   "Name = \"%s\"."
		   "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE),
		   prec, units (via->X), prec, UNIT (via->Y),
		   prec, UNIT (via->Thickness),
		   prec, UNIT (via->DrillingHole),
		   prec, UNIT (via->Clearance / 2.),
		   prec, UNIT ((via->Thickness - via->DrillingHole)/2),
		   prec, UNIT (via->Mask),
		   prec, UNIT ((via->Mask - via->Thickness)/2),
		   EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ?
		   "It is LOCKED.\n" : "");
	break;
      }
    case PIN_TYPE:
      {
	PinTypePtr Pin;
	ElementTypePtr element;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->pin_tree->root, 0);
	    return 0;
	  }
#endif
	Pin = (PinTypePtr) ptr2;
	element = (ElementTypePtr) ptr1;

	PIN_LOOP (element);
	{
	  if (pin == Pin)
	    break;
	}
	END_LOOP;
	if (TEST_FLAG (HOLEFLAG, Pin))
	  sprintf (&report[0], "PIN ID# %ld; Flags:%s\n"
		   "(X,Y) = (%.*f, %.*f) %s.\n"
		   "It is a mounting hole. Drill width = %0.*f %s.\n"
		   "It is owned by element %s.\n"
		   "%s", Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE),
		   prec, units (Pin->X), prec, UNIT (Pin->Y),
		   prec, UNIT (Pin->DrillingHole),
		   EMPTY (element->Name[1].TextString),
		   TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED.\n" : "");
	else
	  sprintf (&report[0],
		   "PIN ID# %ld;  Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n"
		   "Copper width = %0.*f %s. Drill width = %0.*f %s.\n"
		   "Clearance width to Polygon = %0.*f %s.\n"
		   "Annulus = %0.*f %s.\n"
		   "Solder mask hole = %0.*f %s (gap = %0.*f %s).\n"
		   "Name = \"%s\".\n"
		   "It is owned by element %s\n as pin number %s.\n"
		   "%s",
		   Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE),
		   prec, units(Pin->X), prec, UNIT(Pin->Y),
		   prec, UNIT (Pin->Thickness),
		   prec, UNIT (Pin->DrillingHole),
		   prec, UNIT (Pin->Clearance / 2.),
		   prec, UNIT ((Pin->Thickness - Pin->DrillingHole)/2),
		   prec, UNIT (Pin->Mask),
		   prec, UNIT ((Pin->Mask - Pin->Thickness)/2),
		   EMPTY (Pin->Name),
		   EMPTY (element->Name[1].TextString), EMPTY (Pin->Number),
		   TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED.\n" : "");
	break;
      }
    case LINE_TYPE:
      {
	LineTypePtr line;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    LayerTypePtr layer = (LayerTypePtr) ptr1;
	    __r_dump_tree (layer->line_tree->root, 0);
	    return 0;
	  }
#endif
	line = (LineTypePtr) ptr2;
	sprintf (&report[0], "LINE ID# %ld;  Flags:%s\n"
		 "FirstPoint(X,Y)  = (%.*f, %.*f) %s, ID = %ld.\n"
		 "SecondPoint(X,Y) = (%.*f, %.*f) %s, ID = %ld.\n"
		 "Width = %0.*f %s.\nClearance width in polygons = %0.*f %s.\n"
		 "It is on layer %d\n"
		 "and has name \"%s\".\n"
		 "%s",
		 line->ID, flags_to_string (line->Flags, LINE_TYPE),
		 prec, units (line->Point1.X), prec, UNIT (line->Point1.Y),
		 line->Point1.ID, prec, units (line->Point2.X), prec, UNIT (line->Point2.Y),
		 line->Point2.ID, prec, UNIT (line->Thickness),
		 prec, UNIT (line->Clearance / 2.), GetLayerNumber (PCB->Data,
							 (LayerTypePtr) ptr1),
		 UNKNOWN (line->Number), TEST_FLAG (LOCKFLAG,
						    line) ? "It is LOCKED.\n" :
		 "");
	break;
      }
    case RATLINE_TYPE:
      {
	RatTypePtr line;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->rat_tree->root, 0);
	    return 0;
	  }
#endif
	line = (RatTypePtr) ptr2;
	sprintf (&report[0], "RAT-LINE ID# %ld;  Flags:%s\n"
		 "FirstPoint(X,Y)  = (%.*f, %.*f) %s; ID = %ld; "
		 "connects to layer group %d.\n"
		 "SecondPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld; "
		 "connects to layer group %d.\n",
		 line->ID, flags_to_string (line->Flags, LINE_TYPE),
		 prec, units (line->Point1.X), prec, UNIT (line->Point1.Y),
		 line->Point1.ID, line->group1,
		 prec, units (line->Point2.X), prec, UNIT (line->Point2.Y),
		 line->Point2.ID, line->group2);
	break;
      }
    case ARC_TYPE:
      {
	ArcTypePtr Arc;
	BoxTypePtr box;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    LayerTypePtr layer = (LayerTypePtr) ptr1;
	    __r_dump_tree (layer->arc_tree->root, 0);
	    return 0;
	  }
#endif
	Arc = (ArcTypePtr) ptr2;
	box = GetArcEnds (Arc);

	sprintf (&report[0], "ARC ID# %ld;  Flags:%s\n"
		 "CenterPoint(X,Y) = (%.*f, %.*f) %s.\n"
		 "Radius = %0.*f %s, Thickness = %0.*f %s.\n"
		 "Clearance width in polygons = %0.*f %s.\n"
		 "StartAngle = %ld degrees, DeltaAngle = %ld degrees.\n"
		 "Bounding Box is (%.*f,%.*f), (%.*f,%.*f) %s.\n"
		 "That makes the end points at (%.*f,%.*f) %s and (%.*f,%.*f) %s.\n"
		 "It is on layer %d.\n"
		 "%s", Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE),
		 prec, units(Arc->X), prec, UNIT(Arc->Y),
		 prec, UNIT (Arc->Width), prec, UNIT (Arc->Thickness),
		 prec, UNIT (Arc->Clearance / 2.), Arc->StartAngle, Arc->Delta,
		 prec, units (Arc->BoundingBox.X1),
		 prec, units (Arc->BoundingBox.Y1),
		 prec, units (Arc->BoundingBox.X2),
		 prec, UNIT (Arc->BoundingBox.Y2),
		 prec, units (box->X1), prec, UNIT (box->Y1),
		 prec, units (box->X2), prec, UNIT (box->Y2),
		 GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1),
		 TEST_FLAG (LOCKFLAG, Arc) ? "It is LOCKED.\n" : "");
	break;
      }
    case POLYGON_TYPE:
      {
	PolygonTypePtr Polygon;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    LayerTypePtr layer = (LayerTypePtr) ptr1;
	    __r_dump_tree (layer->polygon_tree->root, 0);
	    return 0;
	  }
#endif
	Polygon = (PolygonTypePtr) ptr2;

	sprintf (&report[0], "POLYGON ID# %ld;  Flags:%s\n"
		 "Its bounding box is (%.*f,%.*f) (%.*f,%.*f) %s.\n"
		 "It has %d points and could store %d more\n"
		 "  without using more memory.\n"
		 "It has %d holes and resides on layer %d.\n"
		 "%s", Polygon->ID,
		 flags_to_string (Polygon->Flags, POLYGON_TYPE),
		 prec, units(Polygon->BoundingBox.X1),
		 prec, units(Polygon->BoundingBox.Y1),
		 prec, units(Polygon->BoundingBox.X2),
		 prec, UNIT(Polygon->BoundingBox.Y2),
		 Polygon->PointN, Polygon->PointMax - Polygon->PointN,
		 Polygon->HoleIndexN,
		 GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1),
		 TEST_FLAG (LOCKFLAG, Polygon) ? "It is LOCKED.\n" : "");
	break;
      }
    case PAD_TYPE:
      {
	int len, dx, dy, mgap;
	PadTypePtr Pad;
	ElementTypePtr element;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->pad_tree->root, 0);
	    return 0;
	  }
#endif
	Pad = (PadTypePtr) ptr2;
	element = (ElementTypePtr) ptr1;

	PAD_LOOP (element);
	{
	  {
	    if (pad == Pad)
	      break;
	  }
	}
	END_LOOP;
	dx = Pad->Point1.X - Pad->Point2.X;
	dy = Pad->Point1.Y - Pad->Point2.Y;
	len = sqrt (dx*dx+dy*dy);
	mgap = (Pad->Mask - Pad->Thickness)/2;
	sprintf (&report[0], "PAD ID# %ld;  Flags:%s\n"
		 "FirstPoint(X,Y)  = (%.*f, %.*f) %s; ID = %ld.\n"
		 "SecondPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld.\n"
		 "Width = %0.*f %s.  Length = %0.*f %s.\n"
		 "Clearance width in polygons = %0.*f %s.\n"
		 "Solder mask = %0.*f x %0.*f %s (gap = %0.*f %s).\n"
		 "Name = \"%s\".\n"
		 "It is owned by SMD element %s\n"
		 "  as pin number %s and is on the %s\n"
		 "side of the board.\n"
		 "%s", Pad->ID,
		 flags_to_string (Pad->Flags, PAD_TYPE),
		 prec, units (Pad->Point1.X),
		 prec, UNIT (Pad->Point1.Y), Pad->Point1.ID,
		 prec, units (Pad->Point2.X),
		 prec, UNIT (Pad->Point2.Y), Pad->Point2.ID,
		 prec, UNIT (Pad->Thickness),
		 prec, UNIT (len + Pad->Thickness),
		 prec, UNIT (Pad->Clearance / 2.),
		 prec, units (Pad->Mask), prec, UNIT (Pad->Mask + len),
		 prec, UNIT (mgap),
		 EMPTY (Pad->Name),
		 EMPTY (element->Name[1].TextString),
		 EMPTY (Pad->Number),
		 TEST_FLAG (ONSOLDERFLAG,
			    Pad) ? "solder (bottom)" : "component",
		 TEST_FLAG (LOCKFLAG, Pad) ? "It is LOCKED.\n" : "");
	break;
      }
    case ELEMENT_TYPE:
      {
	ElementTypePtr element;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->element_tree->root, 0);
	    return 0;
	  }
#endif
	element = (ElementTypePtr) ptr2;
	sprintf (&report[0], "ELEMENT ID# %ld;  Flags:%s\n"
		 "BoundingBox (%.*f,%.*f) (%.*f,%.*f) %s.\n"
		 "Descriptive Name \"%s\".\n"
		 "Name on board \"%s\".\n"
		 "Part number name \"%s\".\n"
		 "It is %.*f %s tall and is located at (X,Y) = (%.*f,%.*f)%s.\n"
		 "Mark located at point (X,Y) = (%.*f,%.*f).\n"
		 "It is on the %s side of the board.\n"
		 "%s",
		 element->ID, flags_to_string (element->Flags, ELEMENT_TYPE),
		 prec, units(element->BoundingBox.X1),
		 prec, units (element->BoundingBox.Y1),
		 prec, units(element->BoundingBox.X2),
		 prec, UNIT (element->BoundingBox.Y2),
		 EMPTY (element->Name[0].TextString),
		 EMPTY (element->Name[1].TextString),
		 EMPTY (element->Name[2].TextString),
		 prec, UNIT (0.45 * element->Name[1].Scale * 100.),
		 prec, units(element->Name[1].X),
		 prec, units(element->Name[1].Y),
		 TEST_FLAG (HIDENAMEFLAG, element) ?
		 ",\n  but it's hidden" : "", prec, units(element->MarkX),
		 prec, units(element->MarkY),
		 TEST_FLAG (ONSOLDERFLAG, element) ? "solder (bottom)" :
		 "component", TEST_FLAG (LOCKFLAG, element) ?
		 "It is LOCKED.\n" : "");
	break;
      }
    case TEXT_TYPE:
#ifndef NDEBUG
      if (gui->shift_is_pressed ())
	{
	  LayerTypePtr layer = (LayerTypePtr) ptr1;
	  __r_dump_tree (layer->text_tree->root, 0);
	  return 0;
	}
#endif
    case ELEMENTNAME_TYPE:
      {
	char laynum[32];
	TextTypePtr text;
#ifndef NDEBUG
	if (gui->shift_is_pressed ())
	  {
	    __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0);
	    return 0;
	  }
#endif
	text = (TextTypePtr) ptr2;

	if (type == TEXT_TYPE)
	  sprintf (laynum, "It is on layer %d.",
		   GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1));
	sprintf (&report[0], "TEXT ID# %ld;  Flags:%s\n"
		 "Located at (X,Y) = (%.*f,%.*f) %s.\n"
		 "Characters are %0.*f %s tall.\n"
		 "Value is \"%s\".\n"
		 "Direction is %d.\n"
		 "The bounding box is (%.*f,%.*f) (%.*f, %.*f) %s.\n"
		 "%s\n"
		 "%s", text->ID, flags_to_string (text->Flags, TEXT_TYPE),
		 prec, units(text->X), prec, UNIT (text->Y),
		 prec, UNIT (0.45 * text->Scale * 100.),
		 text->TextString, text->Direction,
		 prec, units(text->BoundingBox.X1),
		 prec, units(text->BoundingBox.Y1),
		 prec, units(text->BoundingBox.X2),
		 prec, UNIT (text->BoundingBox.Y2),
		 (type == TEXT_TYPE) ? laynum : "It is an element name.",
		 TEST_FLAG (LOCKFLAG, text) ? "It is LOCKED.\n" : "");
	break;
      }
    case LINEPOINT_TYPE:
    case POLYGONPOINT_TYPE:
      {
	PointTypePtr point = (PointTypePtr) ptr2;
	sprintf (&report[0], "POINT ID# %ld.\n"
		 "Located at (X,Y) = (%.*f,%.*f) %s.\n"
		 "It belongs to a %s on layer %d.\n", point->ID,
		 prec, units (point->X), prec, UNIT (point->Y),
		 (type == LINEPOINT_TYPE) ? "line" : "polygon",
		 GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1));
	break;
      }
    case NO_TYPE:
      report[0] = '\0';
      break;

    default:
      sprintf (&report[0], "Unknown\n");
      break;
    }

  if (report[0] == '\0')
    {
      Message (_("Nothing found to report on\n"));
      return 1;
    }
  HideCrosshair (false);
  /* create dialog box */
  gui->report_dialog ("Report", &report[0]);

  RestoreCrosshair (false);
  return 0;
}
示例#17
0
文件: rats.c 项目: rlutz/pcb
static bool
CheckShorts (LibraryMenuType *theNet)
{
  bool newone, warn = false;
  PointerListType *generic = (PointerListType *)calloc (1, sizeof (PointerListType));
  /* the first connection was starting point so
   * the menu is always non-null
   */
  void **menu = GetPointerMemory (generic);

  *menu = theNet;
  ALLPIN_LOOP (PCB->Data);
  {
    if (TEST_FLAG (DRCFLAG, pin))
      {
	warn = true;
	if (!pin->Spare)
	  {
	    Message (_("Warning! Net \"%s\" is shorted to %s pin %s\n"),
		     &theNet->Name[2],
		     UNKNOWN (NAMEONPCB_NAME (element)),
		     UNKNOWN (pin->Number));
	    SET_FLAG (WARNFLAG, pin);
	    continue;
	  }
	newone = true;
	POINTER_LOOP (generic);
	{
	  if (*ptr == pin->Spare)
	    {
	      newone = false;
	      break;
	    }
	}
	END_LOOP;
	if (newone)
	  {
	    menu = GetPointerMemory (generic);
	    *menu = pin->Spare;
	    Message (_("Warning! Net \"%s\" is shorted to net \"%s\"\n"),
		     &theNet->Name[2],
		     &((LibraryMenuType *) (pin->Spare))->Name[2]);
	    SET_FLAG (WARNFLAG, pin);
	  }
      }
  }
  ENDALL_LOOP;
  ALLPAD_LOOP (PCB->Data);
  {
    if (TEST_FLAG (DRCFLAG, pad))
      {
	warn = true;
	if (!pad->Spare)
	  {
	    Message (_("Warning! Net \"%s\" is shorted  to %s pad %s\n"),
		     &theNet->Name[2],
		     UNKNOWN (NAMEONPCB_NAME (element)),
		     UNKNOWN (pad->Number));
	    SET_FLAG (WARNFLAG, pad);
	    continue;
	  }
	newone = true;
	POINTER_LOOP (generic);
	{
	  if (*ptr == pad->Spare)
	    {
	      newone = false;
	      break;
	    }
	}
	END_LOOP;
	if (newone)
	  {
	    menu = GetPointerMemory (generic);
	    *menu = pad->Spare;
	    Message (_("Warning! Net \"%s\" is shorted to net \"%s\"\n"),
		     &theNet->Name[2],
		     &((LibraryMenuType *) (pad->Spare))->Name[2]);
	    SET_FLAG (WARNFLAG, pad);
	  }
      }
  }
  ENDALL_LOOP;
  FreePointerListMemory (generic);
  free (generic);
  return (warn);
}
示例#18
0
static char *
describe_location (Coord X, Coord Y)
{
  void *ptr1, *ptr2, *ptr3;
  int type;
  int Range = 0;
  char *elename = "";
  char *pinname;
  char *netname = NULL;
  char *description;

  /* check if there are any pins or pads at that position */

  type = SearchObjectByLocation (PIN_TYPE | PAD_TYPE,
                                 &ptr1, &ptr2, &ptr3, X, Y, Range);
  if (type == NO_TYPE)
    return NULL;

  /* don't mess with silk objects! */
  if (type & SILK_TYPE &&
      GetLayerNumber (PCB->Data, (LayerType *) ptr1) >= max_copper_layer)
    return NULL;

  if (type == PIN_TYPE || type == PAD_TYPE)
    elename = (char *)UNKNOWN (NAMEONPCB_NAME ((ElementType *) ptr1));

  pinname = ConnectionName (type, ptr1, ptr2);

  if (pinname == NULL)
    return NULL;

  /* Find netlist entry */
  MENU_LOOP (&PCB->NetlistLib);
  {
    if (!menu->Name)
    continue;

    ENTRY_LOOP (menu);
    {
      if (!entry->ListEntry)
        continue;

      if (strcmp (entry->ListEntry, pinname) == 0) {
        netname = g_strdup (menu->Name);
        /* For some reason, the netname has spaces in front of it, strip them */
        g_strstrip (netname);
        break;
      }
    }
    END_LOOP;

    if (netname != NULL)
      break;
  }
  END_LOOP;

  description = g_strdup_printf ("Element name: %s\n"
                                 "Pinname : %s\n"
                                 "Netname : %s",
                                 elename,
                                 (pinname != NULL) ? pinname : "--",
                                 (netname != NULL) ? netname : "--");

  g_free (netname);

  return description;
}
示例#19
0
static int
gerber_set_layer (const char *name, int group, int empty)
{
  int want_outline;
  char *cp;
  int idx = (group >= 0
	     && group <
	     max_group) ? PCB->LayerGroups.Entries[group][0] : group;

  if (name == NULL)
    name = PCB->Data->Layer[idx].Name;

  if (idx >= 0 && idx < max_copper_layer && !print_layer[idx])
    return 0;

  if (strcmp (name, "invisible") == 0)
    return 0;
  if (SL_TYPE (idx) == SL_ASSY)
    return 0;

  flash_drills = 0;
  if (strcmp (name, "outline") == 0 ||
      strcmp (name, "route") == 0)
    flash_drills = 1;

  if (is_drill && n_pending_drills)
    {
      int i;
      /* dump pending drills in sequence */
      qsort (pending_drills, n_pending_drills, sizeof (pending_drills[0]),
	     drill_sort);
      for (i = 0; i < n_pending_drills; i++)
	{
	  if (i == 0 || pending_drills[i].diam != pending_drills[i - 1].diam)
	    {
	      Aperture *ap = findAperture (curr_aptr_list, pending_drills[i].diam, ROUND);
	      fprintf (f, "T%02d\r\n", ap->dCode);
	    }
          /* Notice the last zeroes are literal zeroes here, a x10 scale factor.  *
           *                                                      v        v      */
	  pcb_fprintf (f, metric ? "X%06.0muY%06.0mu\r\n" : "X%06.0ml0Y%06.0ml0\r\n",
		   gerberDrX (PCB, pending_drills[i].x),
		   gerberDrY (PCB, pending_drills[i].y));
	}
      free (pending_drills);
      n_pending_drills = max_pending_drills = 0;
      pending_drills = NULL;
    }

  is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL);
  is_mask = (SL_TYPE (idx) == SL_MASK);
  current_mask = 0;
#if 0
  printf ("Layer %s group %d drill %d mask %d\n", name, group, is_drill,
	  is_mask);
#endif

  if (group < 0 || group != lastgroup)
    {
      time_t currenttime;
      char utcTime[64];
#ifdef HAVE_GETPWUID
      struct passwd *pwentry;
#endif
      ApertureList *aptr_list;
      Aperture *search;

      lastgroup = group;
      lastX = -1;
      lastY = -1;
      linewidth = -1;
      lastcap = -1;

      aptr_list = setLayerApertureList (layer_list_idx++);

      if (finding_apertures)
	goto emit_outline;

      if (aptr_list->count == 0 && !all_layers)
	return 0;

      maybe_close_f (f);
      f = NULL;

      pagecount++;
      assign_file_suffix (filesuff, idx);
      f = fopen (filename, "wb");   /* Binary needed to force CR-LF */
      if (f == NULL) 
	{
	  Message ( "Error:  Could not open %s for writing.\n", filename);
	  return 1;
	}

      was_drill = is_drill;

      if (verbose)
	{
	  int c = aptr_list->count;
	  printf ("Gerber: %d aperture%s in %s\n", c,
		  c == 1 ? "" : "s", filename);
	}

      if (is_drill)
	{
	  /* We omit the ,TZ here because we are not omitting trailing zeros.  Our format is
	     always six-digit 0.1 mil or µm resolution (i.e. 001100 = 0.11" or 1.1mm)*/
	  fprintf (f, "M48\r\n");
	  fprintf (f, metric ? "METRIC,000.000\r\n" : "INCH\r\n");
	  for (search = aptr_list->data; search; search = search->next)
		  pcb_fprintf (f, metric ? "T%02dC%.3`mm\r\n" : "T%02dC%.3`mi\r\n", search->dCode, search->width);
	  fprintf (f, "%%\r\n");
	  /* FIXME */
	  return 1;
	}

      fprintf (f, "G04 start of page %d for group %d idx %d *\r\n",
	       pagecount, group, idx);

      /* Create a portable timestamp. */
      currenttime = time (NULL);
      {
	/* avoid gcc complaints */
	const char *fmt = "%c UTC";
	strftime (utcTime, sizeof utcTime, fmt, gmtime (&currenttime));
      }
      /* Print a cute file header at the beginning of each file. */
      fprintf (f, "G04 Title: %s, %s *\r\n", UNKNOWN (PCB->Name),
	       UNKNOWN (name));
      fprintf (f, "G04 Creator: %s " VERSION " *\r\n", Progname);
      fprintf (f, "G04 CreationDate: %s *\r\n", utcTime);

#ifdef HAVE_GETPWUID
      /* ID the user. */
      pwentry = getpwuid (getuid ());
      fprintf (f, "G04 For: %s *\r\n", pwentry->pw_name);
#endif

      fprintf (f, "G04 Format: Gerber/RS-274X *\r\n");
      pcb_fprintf (f, metric ? "G04 PCB-Dimensions (mm): %.2mm %.2mm *\r\n" :
	       "G04 PCB-Dimensions (mil): %.2ml %.2ml *\r\n",
	       PCB->MaxWidth, PCB->MaxHeight);
      fprintf (f, "G04 PCB-Coordinate-Origin: lower left *\r\n");

      /* Signal data in inches. */
      fprintf (f, metric ? "%%MOMM*%%\r\n" : "%%MOIN*%%\r\n");

      /* Signal Leading zero suppression, Absolute Data, 2.5 format in inch, 4.3 in mm */
      fprintf (f, metric ? "%%FSLAX43Y43*%%\r\n" : "%%FSLAX25Y25*%%\r\n");

      /* build a legal identifier. */
      if (layername)
	free (layername);
      layername = strdup (filesuff);
      if (strrchr (layername, '.'))
	* strrchr (layername, '.') = 0;

      for (cp=layername; *cp; cp++)
	{
	  if (isalnum((int) *cp))
	    *cp = toupper((int) *cp);
	  else
	    *cp = '_';
	}
      fprintf (f, "%%LN%s*%%\r\n", layername);
      lncount = 1;

      for (search = aptr_list->data; search; search = search->next)
        fprintAperture(f, search);
      if (aptr_list->count == 0)
	/* We need to put *something* in the file to make it be parsed
	   as RS-274X instead of RS-274D. */
	fprintf (f, "%%ADD11C,0.0100*%%\r\n");
    }

 emit_outline:
  /* If we're printing a copper layer other than the outline layer,
     and we want to "print outlines", and we have an outline layer,
     print the outline layer on this layer also.  */
  want_outline = 0;
  if (copy_outline_mode == COPY_OUTLINE_MASK
      && SL_TYPE (idx) == SL_MASK)
    want_outline = 1;
  if (copy_outline_mode == COPY_OUTLINE_SILK
      && SL_TYPE (idx) == SL_SILK)
    want_outline = 1;
  if (copy_outline_mode == COPY_OUTLINE_ALL
      && (SL_TYPE (idx) == SL_SILK
	  || SL_TYPE (idx) == SL_MASK
	  || SL_TYPE (idx) == SL_FAB
	  || SL_TYPE (idx) == SL_ASSY
	  || SL_TYPE (idx) == 0))
    want_outline = 1;

  if (want_outline
      && strcmp (name, "outline")
      && strcmp (name, "route"))
    {
      if (outline_layer
	  && outline_layer != PCB->Data->Layer+idx)
	DrawLayer (outline_layer, &region);
      else if (!outline_layer)
	{
	  hidGC gc = gui->make_gc ();
	  printf("name %s idx %d\n", name, idx);
	  if (SL_TYPE (idx) == SL_SILK)
	    gui->set_line_width (gc, PCB->minSlk);
	  else if (group >= 0)
	    gui->set_line_width (gc, PCB->minWid);
	  else
	    gui->set_line_width (gc, AUTO_OUTLINE_WIDTH);
	  gui->draw_line (gc, 0, 0, PCB->MaxWidth, 0);
	  gui->draw_line (gc, 0, 0, 0, PCB->MaxHeight);
	  gui->draw_line (gc, PCB->MaxWidth, 0, PCB->MaxWidth, PCB->MaxHeight);
	  gui->draw_line (gc, 0, PCB->MaxHeight, PCB->MaxWidth, PCB->MaxHeight);
	  gui->destroy_gc (gc);
	}
    }

  return 1;
}