mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-12-22 18:28:59 +02:00
genex/: generate expanded component view (WIP)
This commit is contained in:
parent
aa2fe3ef16
commit
4902886baa
40
genex/Makefile
Normal file
40
genex/Makefile
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# Makefile - Expanded component view generator
|
||||
#
|
||||
# Copyright 2012 by Werner Almesberger
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
|
||||
CFLAGS = -Wall -g
|
||||
OBJS = genex.o comp.o libs.o pdf.o
|
||||
|
||||
CC_normal := $(CC)
|
||||
DEPEND_normal := $(CPP) $(CFLAGS) -MM -MG
|
||||
|
||||
CC_quiet = @echo " CC " $@ && $(CC_normal)
|
||||
GEN_quiet = @echo " GENERATE " $@ &&
|
||||
DEPEND_quiet = @$(DEPEND_normal)
|
||||
|
||||
ifeq ($(V),1)
|
||||
CC = $(CC_normal)
|
||||
GEN =
|
||||
DEPEND = $(DEPEND_normal)
|
||||
else
|
||||
CC = $(CC_quiet)
|
||||
GEN = $(GEN_quiet)
|
||||
DEPEND = $(DEPEND_quiet)
|
||||
endif
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: genex
|
||||
|
||||
genex: $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
125
genex/comp.c
Normal file
125
genex/comp.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* comp.c - Component hierarchy
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "comp.h"
|
||||
|
||||
|
||||
struct node *tree = NULL;
|
||||
|
||||
|
||||
void read_tree(FILE *file)
|
||||
{
|
||||
char buf[1100]; /* more than enough */
|
||||
struct node *last = NULL, *node;
|
||||
int depth = -1;
|
||||
const char *s, *p, *e;
|
||||
char *name;
|
||||
int n;
|
||||
|
||||
next:
|
||||
while (fgets(buf, sizeof(buf), file)) {
|
||||
n = 0;
|
||||
s = buf;
|
||||
while (1) {
|
||||
switch (*s++) {
|
||||
case ' ':
|
||||
n++;
|
||||
continue;
|
||||
case '\t':
|
||||
n = (n+8) & ~7;
|
||||
continue;
|
||||
case 0:
|
||||
case '#':
|
||||
goto next;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (p = e = s--; *p && *p != '#' && *p != '\n'; p++)
|
||||
if (*p != ' ' && *p != '\t')
|
||||
e = p;
|
||||
if (!last && n) {
|
||||
fprintf(stderr, "first entry must not be intended\n");
|
||||
exit(1);
|
||||
}
|
||||
name = malloc(e-s+2);
|
||||
if (!name) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(name, s, e-s+1);
|
||||
name[e-s+1] = 0;
|
||||
node = alloc_type(struct node);
|
||||
node->name = name;
|
||||
node->lib = NULL;
|
||||
node->indent = n;
|
||||
node->child = node->next = NULL;
|
||||
if (n > depth) {
|
||||
if (last)
|
||||
last->child = node;
|
||||
else
|
||||
tree = node;
|
||||
node->parent = last;
|
||||
} else {
|
||||
while (last && last->indent != n)
|
||||
last = last->parent;
|
||||
if (!last && n) {
|
||||
fprintf(stderr, "indentation error\n");
|
||||
exit(1);
|
||||
}
|
||||
last->next = node;
|
||||
node->parent = last->parent;
|
||||
}
|
||||
last = node;
|
||||
depth = n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_libs(struct node *node,
|
||||
const char *(*find_lib)(const char *sym, const char **canon))
|
||||
{
|
||||
while (node) {
|
||||
if (!node->child) {
|
||||
node->lib = find_lib(node->name, &node->canon);
|
||||
if (!node->lib) {
|
||||
fprintf(stderr, "symbol %s not found\n",
|
||||
node->name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
set_libs(node->child, find_lib);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dump_level(const struct node *tree, int level)
|
||||
{
|
||||
const struct node *n;
|
||||
|
||||
for (n = tree; n; n = n->next) {
|
||||
printf("%*s%s\n", 4*level, "", n->name);
|
||||
dump_level(n->child, level+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dump_tree(void)
|
||||
{
|
||||
dump_level(tree, 0);
|
||||
}
|
34
genex/comp.h
Normal file
34
genex/comp.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* comp.h - Component hierarchy
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef COMP_H
|
||||
#define COMP_H
|
||||
|
||||
struct node {
|
||||
const char *name;
|
||||
const char *lib; /* NULL if not intermediate node */
|
||||
const char *canon; /* canonical name of component */
|
||||
int indent; /* level of indentation (characters) */
|
||||
struct node *parent;
|
||||
struct node *child;
|
||||
struct node *next;
|
||||
};
|
||||
|
||||
|
||||
extern struct node *tree;
|
||||
|
||||
|
||||
void read_tree(FILE *file);
|
||||
void set_libs(struct node *node,
|
||||
const char *(*find_lib)(const char *sym, const char **canon));
|
||||
void dump_tree(void);
|
||||
|
||||
#endif /* !COMP_H */
|
85
genex/expand-pintype
Executable file
85
genex/expand-pintype
Executable file
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# expand-pintype - Expand pin types of symbols in a Kicad library
|
||||
#
|
||||
# Copyright 2010, 2012 by Werner Almesberger
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
|
||||
#
|
||||
# usage:
|
||||
#
|
||||
# expand-pintype input.lib
|
||||
# expand-pintype input.lib output.lib
|
||||
#
|
||||
|
||||
|
||||
$GAP = 50; # gap between pin and type, in mil
|
||||
$CHAR_WIDTH = 66; # default character width, in mil
|
||||
$NAME_WIDTH = 15; # name field width in ASCII mode, in characters
|
||||
|
||||
|
||||
%map = (
|
||||
"I" => "Input",
|
||||
"O" => "Output",
|
||||
"B" => "BiDi",
|
||||
"T" => "3-state",
|
||||
"P" => "Passive",
|
||||
"U" => "Unspec",
|
||||
"W" => "Pwr In",
|
||||
"w" => "Pwr Out",
|
||||
"C" => "OC",
|
||||
"E" => "OE",
|
||||
);
|
||||
|
||||
if (@ARGV < 2) {
|
||||
$out = 0;
|
||||
} elsif (@ARGV == 2) {
|
||||
$file = pop @ARGV;
|
||||
$out = 1;
|
||||
open(FILE, ">$file") || die "$file: $!";
|
||||
} else {
|
||||
print STDERR "usage: expand-pintype input.lib [output.lib]\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (<>) {
|
||||
if ($out) {
|
||||
# make name differ so that KiCad's cache doesn't get confused
|
||||
s/^DEF\s+/$&X/;
|
||||
s/^F1\s+"+/$&X/;
|
||||
print FILE || die;
|
||||
}
|
||||
next unless /^X/;
|
||||
@a = split(/\s+/);
|
||||
($name, $pin, $x, $y, $dir, $unit, $pt) = @a[1, 2, 3, 4, 6, 9, 11];
|
||||
$type = $map{$pt};
|
||||
$type = "???" unless defined $type;
|
||||
if ($out) {
|
||||
$off = $GAP+(length $type)*$CHAR_WIDTH/2;
|
||||
if ($dir eq "U") {
|
||||
($a, $y) = (90, $y-$off);
|
||||
} elsif ($dir eq "D") {
|
||||
($a, $y) = (90, $y+$off);
|
||||
} elsif ($dir eq "R") {
|
||||
($a, $x) = (0, $x-$off);
|
||||
} else {
|
||||
($a, $x) = (0, $x+$off);
|
||||
}
|
||||
$type =~ y/ /~/;
|
||||
print FILE sprintf("T %d %d %d 60 0 %d 0 %s Normal 0\n",
|
||||
$a*10, $x, $y, $unit, $type);
|
||||
} else {
|
||||
$s = "$name ($pin)";
|
||||
$f = $NAME_WIDTH-length $s;
|
||||
$f = "-" x ($f > 0 ? $f : 0);
|
||||
print "$s $f $type\n";
|
||||
}
|
||||
}
|
||||
if ($out) {
|
||||
close FILE || die;
|
||||
}
|
61
genex/genex.c
Normal file
61
genex/genex.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* genex.c - Generate expanded component view
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "comp.h"
|
||||
#include "libs.h"
|
||||
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-L libdir ...] [-l lib ...] hierarchy\n",
|
||||
name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *file;
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "L:l:")) != EOF)
|
||||
switch (c) {
|
||||
case 'L':
|
||||
add_libdir(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
add_lib(optarg);
|
||||
break;
|
||||
default:
|
||||
usage(*argv);
|
||||
}
|
||||
|
||||
|
||||
if (argc-optind != 1)
|
||||
usage(*argv);
|
||||
|
||||
file = fopen(argv[optind], "r");
|
||||
if (!file) {
|
||||
perror(argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
read_tree(file);
|
||||
set_libs(tree, lookup_sym);
|
||||
fclose(file);
|
||||
// dump_tree();
|
||||
make_pdf();
|
||||
return 0;
|
||||
}
|
119
genex/libs.c
Normal file
119
genex/libs.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* libs.c - Component libraries
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "libs.h"
|
||||
|
||||
|
||||
struct entry {
|
||||
const char *name;
|
||||
struct entry *next;
|
||||
};
|
||||
|
||||
static struct lib {
|
||||
const char *path;
|
||||
struct entry *comps;
|
||||
struct lib *next;
|
||||
} *libs = NULL;
|
||||
|
||||
|
||||
const char *lookup_sym(const char *name, const char **canon)
|
||||
{
|
||||
const struct lib *lib;
|
||||
const struct entry *e;
|
||||
|
||||
for (lib = libs; lib; lib = lib->next)
|
||||
for (e = lib->comps; e; e = e->next)
|
||||
if (!strcasecmp(e->name, name)) {
|
||||
if (canon)
|
||||
*canon = e->name;
|
||||
return lib->path;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void add_lib(const char *path)
|
||||
{
|
||||
FILE *file;
|
||||
struct lib *lib;
|
||||
struct entry *e;
|
||||
char buf[1024]; /* @@@ */
|
||||
char *spc;
|
||||
|
||||
|
||||
file = fopen(path, "r");
|
||||
if (!file) {
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lib = alloc_type(struct lib);
|
||||
lib->path = stralloc(path);
|
||||
lib->comps = NULL;
|
||||
lib->next = libs;
|
||||
libs = lib;
|
||||
|
||||
while (fgets(buf, sizeof(buf), file)) {
|
||||
if (strncmp(buf, "DEF ", 4))
|
||||
continue;
|
||||
spc = strchr(buf+4, ' ');
|
||||
if (!spc) {
|
||||
fprintf(stderr, "invalid DEF line in %s\n", path);
|
||||
exit(1);
|
||||
}
|
||||
*spc = 0;
|
||||
e = alloc_type(struct entry);
|
||||
e->name = stralloc(buf+4);
|
||||
e->next = lib->comps;
|
||||
lib->comps = e;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
||||
void add_libdir(const char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
const struct dirent *de;
|
||||
size_t len;
|
||||
char *tmp;
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
perror(path);
|
||||
exit(1);
|
||||
}
|
||||
while (1) {
|
||||
de = readdir(dir);
|
||||
if (!de)
|
||||
break;
|
||||
len = strlen(de->d_name);
|
||||
if (len < 4)
|
||||
continue;
|
||||
if (strcmp(de->d_name+len-4, ".lib"))
|
||||
continue;
|
||||
if (asprintf(&tmp, "%s/%s", path, de->d_name) < 0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
}
|
||||
add_lib(tmp);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
19
genex/libs.h
Normal file
19
genex/libs.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* libs.h - Component libraries
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef LIBS_H
|
||||
#define LIBS_H
|
||||
|
||||
const char *lookup_sym(const char *name, const char **canon);
|
||||
void add_lib(const char *path);
|
||||
void add_libdir(const char *path);
|
||||
|
||||
#endif /* !LIBS_H */
|
96
genex/pdf.c
Normal file
96
genex/pdf.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* pdf.c - Generate PDF
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "comp.h"
|
||||
#include "pdf.h"
|
||||
|
||||
|
||||
static int children(const struct node *node)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while (node) {
|
||||
n++;
|
||||
node = node->next;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void convert_comp(const struct node *node, FILE *out)
|
||||
{
|
||||
char *tmp;
|
||||
int res;
|
||||
|
||||
if (asprintf(&tmp, "./sym2xps '%s' '%s' '%s' '%s'",
|
||||
node->lib, node->canon, "tmp", "tmp.ps") < 0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
}
|
||||
res = system(tmp);
|
||||
if (res < 0) {
|
||||
perror("system");
|
||||
exit(1);
|
||||
}
|
||||
if (res) {
|
||||
fprintf(stderr, "sym2xps returned %d\n", res);
|
||||
exit(1);
|
||||
}
|
||||
fflush(out);
|
||||
system("cat tmp.ps");
|
||||
}
|
||||
|
||||
|
||||
static void convert_tree(const struct node *node, FILE *out)
|
||||
{
|
||||
while (node) {
|
||||
fprintf(out, "[ /Title (%s) /Count %d /OUT pdfmark\n",
|
||||
node->name, -children(node->child));
|
||||
if (node->child)
|
||||
convert_tree(node->child, out);
|
||||
else
|
||||
convert_comp(node, out);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void make_pdf(void)
|
||||
{
|
||||
FILE *out;
|
||||
int res;
|
||||
|
||||
#if 0
|
||||
out = popen(
|
||||
"gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=- -f -",
|
||||
"w");
|
||||
#else
|
||||
out = popen("cat", "w");
|
||||
#endif
|
||||
if (!out) {
|
||||
perror("gs");
|
||||
exit(1);
|
||||
}
|
||||
convert_tree(tree, out);
|
||||
res = pclose(out);
|
||||
if (res < 0) {
|
||||
perror("pclose");
|
||||
exit(1);
|
||||
}
|
||||
if (res) {
|
||||
fprintf(stderr, "exit status %d\n", res);
|
||||
exit(1);
|
||||
}
|
||||
}
|
17
genex/pdf.h
Normal file
17
genex/pdf.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* pdf.h - Generate PDF
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef PDF_H
|
||||
#define PDF_H
|
||||
|
||||
void make_pdf(void);
|
||||
|
||||
#endif /* !PDF_H */
|
8
genex/run
Executable file
8
genex/run
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
# Hack: ps2pdf is happy with the PS generate, but if we invoke gs diretctly,
|
||||
# isn't. Some voodoo is still missing ...
|
||||
PATH=$PATH:. ./genex \
|
||||
-L /home/qi/kicad-libs/components \
|
||||
/home/qi/kicad-libs/components/EXPAND >out.ps
|
||||
ps2pdf out.ps out.pdf
|
||||
rm -f out.ps
|
75
genex/sym2xps
Executable file
75
genex/sym2xps
Executable file
@ -0,0 +1,75 @@
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# sym2xps - Convert a symbol from a Kicad library to Postscript with expanded
|
||||
# pin types
|
||||
#
|
||||
# Copyright 2012 by Werner Almesberger
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "usage: $0 library symbol tmpdir outfile" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
lib=$1
|
||||
sym=$2
|
||||
tmp=$3
|
||||
out=$4
|
||||
|
||||
[ "$lib" ] && [ "$sym" ] && [ "$tmp" ] && [ "$out" ] || usage
|
||||
|
||||
[ -r "$lib" ] || {
|
||||
echo "$lib: not found" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep "^DEF $sym " "$lib" >/dev/null || {
|
||||
echo "\"$sym\" not found in $lib" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ "${tmp#/}" = "$tmp" ] && tmp=`pwd`/$tmp
|
||||
[ "${out#/}" = "$out" ] && out=`pwd`/$out
|
||||
|
||||
mkdir "$tmp"
|
||||
|
||||
trap "rm -rf '$tmp'" 0
|
||||
|
||||
expand-pintype "$lib" "$tmp"/tmp.lib
|
||||
|
||||
cat <<EOF >"$tmp"/tmp.pro
|
||||
[eeschema]
|
||||
version=1
|
||||
[eeschema/libraries]
|
||||
LibName1=./tmp
|
||||
EOF
|
||||
|
||||
X=6000
|
||||
Y=4000
|
||||
|
||||
cat <<EOF >"$tmp"/tmp.sch
|
||||
EESchema Schematic File Version 2 date Mon Mar 26 09:29:33 2012
|
||||
LIBS:dummy
|
||||
EELAYER 43 0
|
||||
EELAYER END
|
||||
\$Comp
|
||||
L X$sym ??
|
||||
U 1 1 00000000
|
||||
P $X $Y
|
||||
1 $X $Y
|
||||
1 0 0 -1
|
||||
\$EndComp
|
||||
\$EndSCHEMATC
|
||||
EOF
|
||||
|
||||
cd "$tmp"
|
||||
eeschema --plot=ps "$tmp/tmp.sch"
|
||||
mv tmp.ps "$out"
|
39
genex/util.h
Normal file
39
genex/util.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* util.h - Utility functions
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define alloc_size(s) \
|
||||
({ void *alloc_size_tmp = malloc(s); \
|
||||
if (!alloc_size_tmp) \
|
||||
abort(); \
|
||||
alloc_size_tmp; })
|
||||
|
||||
#define alloc_type(t) ((t *) alloc_size(sizeof(t)))
|
||||
|
||||
|
||||
static inline char *stralloc(const char *s)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = strdup(s);
|
||||
if (t)
|
||||
return t;
|
||||
perror("strdup");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#endif /* !UTIL_H */
|
Loading…
Reference in New Issue
Block a user