Commit 59307314 authored by Ulrich Sibiller's avatar Ulrich Sibiller

update all files with NX relevant changes to libX11 1.3.4

parent a053df0a
......@@ -23,28 +23,27 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
/* $XFree86$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Xlibint.h"
/*
/*
* Check existing events in queue to find if any match. If so, return.
* If not, flush buffer and see if any more events are readable. If one
* matches, return. If all else fails, tell the user no events found.
*/
Bool XCheckIfEvent (dpy, event, predicate, arg)
register Display *dpy;
Bool XCheckIfEvent (
register Display *dpy,
register XEvent *event, /* XEvent to be filled in. */
Bool (*predicate)(
Display* /* display */,
XEvent* /* event */,
char* /* arg */
); /* function to call */
register XEvent *event; /* XEvent to be filled in. */
char *arg;
), /* function to call */
char *arg)
{
register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0;
......@@ -60,6 +59,7 @@ Bool XCheckIfEvent (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event;
_XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy);
return True;
}
......@@ -90,15 +90,16 @@ Bool XCheckIfEvent (dpy, event, predicate, arg)
* events.
*/
Bool XCheckIfEventNoFlush (dpy, event, predicate, arg)
register Display *dpy;
Bool XCheckIfEventNoFlush (
register Display *dpy,
register XEvent *event, /* XEvent to be filled in. */
Bool (*predicate)(
Display* /* display */,
XEvent* /* event */,
char* /* arg */
); /* function to call */
register XEvent *event; /* XEvent to be filled in. */
char *arg;
), /* function to call */
char *arg)
{
register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0;
......@@ -114,6 +115,7 @@ Bool XCheckIfEventNoFlush (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event;
_XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy);
return True;
}
......
......@@ -29,25 +29,25 @@ in this Software without prior written authorization from The Open Group.
#endif
#include "Xlibint.h"
/*
/*
* Flush output and (wait for and) return the next event matching the
* predicate in the queue.
*/
int
XIfEvent (dpy, event, predicate, arg)
register Display *dpy;
XIfEvent (
register Display *dpy,
register XEvent *event,
Bool (*predicate)(
Display* /* display */,
XEvent* /* event */,
char* /* arg */
); /* function to call */
register XEvent *event;
char *arg;
), /* function to call */
char *arg)
{
register _XQEvent *qelt, *prev;
unsigned long qe_serial = 0;
LockDisplay(dpy);
prev = NULL;
while (1) {
......@@ -58,6 +58,7 @@ XIfEvent (dpy, event, predicate, arg)
&& (*predicate)(dpy, &qelt->event, arg)) {
*event = qelt->event;
_XDeq(dpy, prev, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy);
return 0;
}
......
......@@ -34,28 +34,32 @@ extern long const _Xevent_to_mask[];
#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
Button4MotionMask|Button5MotionMask)
/*
/*
* return the next event in the queue matching one of the events in the mask.
* If no event, flush output, and wait until match succeeds.
* Events earlier in the queue are not discarded.
*/
int
XMaskEvent (dpy, mask, event)
register Display *dpy;
long mask; /* Selected event mask. */
register XEvent *event; /* XEvent to be filled in. */
XMaskEvent (
register Display *dpy,
long mask, /* Selected event mask. */
register XEvent *event) /* XEvent to be filled in. */
{
register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0;
LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
prev = NULL;
while (1) {
for (qelt = prev ? prev->next : dpy->head;
qelt;
prev = qelt, qelt = qelt->next) {
if ((qelt->event.type < LASTEvent) &&
if ((qelt->event.type < GenericEvent) &&
(_Xevent_to_mask[qelt->event.type] & mask) &&
((qelt->event.type != MotionNotify) ||
(mask & AllPointers) ||
......
......@@ -29,20 +29,23 @@ in this Software without prior written authorization from The Open Group.
#endif
#include "Xlibint.h"
/*
/*
* Return next event in queue, or if none, flush output and wait for
* events.
*/
int
XNextEvent (dpy, event)
register Display *dpy;
register XEvent *event;
XNextEvent (
register Display *dpy,
register XEvent *event)
{
register _XQEvent *qelt;
LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
if (dpy->head == NULL)
_XReadEvents(dpy);
#ifdef NX_TRANS_SOCKET
......@@ -54,6 +57,7 @@ XNextEvent (dpy, event)
qelt = dpy->head;
*event = qelt->event;
_XDeq(dpy, NULL, qelt);
_XStoreEventCookie(dpy, event);
UnlockDisplay(dpy);
return 0;
}
......
......@@ -29,17 +29,18 @@ in this Software without prior written authorization from The Open Group.
#endif
#include "Xlibint.h"
/*
/*
* Return the next event in the queue,
* BUT do not remove it from the queue.
* If none found, flush and wait until there is an event to peek.
*/
int
XPeekEvent (dpy, event)
register Display *dpy;
register XEvent *event;
XPeekEvent (
register Display *dpy,
register XEvent *event)
{
XEvent copy;
LockDisplay(dpy);
if (dpy->head == NULL)
_XReadEvents(dpy);
......@@ -47,9 +48,13 @@ XPeekEvent (dpy, event)
if (_XGetIOError(dpy)) {
UnlockDisplay(dpy);
return 1;
}
}
#endif
*event = (dpy->head)->event;
if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
_XStoreEventCookie(dpy, &copy);
*event = copy;
}
UnlockDisplay(dpy);
return 1;
}
......
......@@ -36,15 +36,15 @@ in this Software without prior written authorization from The Open Group.
*/
int
XPeekIfEvent (dpy, event, predicate, arg)
register Display *dpy;
register XEvent *event;
XPeekIfEvent (
register Display *dpy,
register XEvent *event,
Bool (*predicate)(
Display* /* display */,
XEvent* /* event */,
char* /* arg */
);
char *arg;
),
char *arg)
{
register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0;
......@@ -57,7 +57,12 @@ XPeekIfEvent (dpy, event, predicate, arg)
prev = qelt, qelt = qelt->next) {
if(qelt->qserial_num > qe_serial
&& (*predicate)(dpy, &qelt->event, arg)) {
XEvent copy;
*event = qelt->event;
if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
_XStoreEventCookie(dpy, &copy);
*event = copy;
}
UnlockDisplay(dpy);
return 0;
}
......
......@@ -33,9 +33,9 @@ in this Software without prior written authorization from The Open Group.
/* Read in pending events if needed and return the number of queued events. */
int XEventsQueued (dpy, mode)
register Display *dpy;
int mode;
int XEventsQueued (
register Display *dpy,
int mode)
{
int ret_val;
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
......@@ -54,8 +54,7 @@ int XEventsQueued (dpy, mode)
return ret_val;
}
int XPending (dpy)
register Display *dpy;
int XPending (register Display *dpy)
{
int ret_val;
LockDisplay(dpy);
......
......@@ -34,7 +34,7 @@ extern long const _Xevent_to_mask[];
#define AllButtons (Button1MotionMask|Button2MotionMask|Button3MotionMask|\
Button4MotionMask|Button5MotionMask)
/*
/*
* Return the next event in the queue
* for the given window matching one of the events in the mask.
* Events earlier in the queue are not discarded.
......@@ -43,23 +43,27 @@ extern long const _Xevent_to_mask[];
*/
int
XWindowEvent (dpy, w, mask, event)
register Display *dpy;
Window w; /* Selected window. */
long mask; /* Selected event mask. */
register XEvent *event; /* XEvent to be filled in. */
XWindowEvent (
register Display *dpy,
Window w, /* Selected window. */
long mask, /* Selected event mask. */
register XEvent *event) /* XEvent to be filled in. */
{
register _XQEvent *prev, *qelt;
unsigned long qe_serial = 0;
LockDisplay(dpy);
/* Delete unclaimed cookies */
_XFreeEventCookies(dpy);
prev = NULL;
while (1) {
for (qelt = prev ? prev->next : dpy->head;
qelt;
prev = qelt, qelt = qelt->next) {
if ((qelt->event.xany.window == w) &&
(qelt->event.type < LASTEvent) &&
(qelt->event.type < GenericEvent) &&
(_Xevent_to_mask[qelt->event.type] & mask) &&
((qelt->event.type != MotionNotify) ||
(mask & AllPointers) ||
......
......@@ -59,12 +59,12 @@ from The Open Group.
/*ARGSUSED*/
Bool
_XAsyncErrorHandler(dpy, rep, buf, len, data)
register Display *dpy;
register xReply *rep;
char *buf;
int len;
XPointer data;
_XAsyncErrorHandler(
register Display *dpy,
register xReply *rep,
char *buf,
int len,
XPointer data)
{
register _XAsyncErrorState *state;
......@@ -87,9 +87,9 @@ _XAsyncErrorHandler(dpy, rep, buf, len, data)
return False;
}
void _XDeqAsyncHandler(dpy, handler)
Display *dpy;
register _XAsyncHandler *handler;
void _XDeqAsyncHandler(
Display *dpy,
register _XAsyncHandler *handler)
{
register _XAsyncHandler **prev;
register _XAsyncHandler *async;
......@@ -103,14 +103,14 @@ void _XDeqAsyncHandler(dpy, handler)
}
char *
_XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
register Display *dpy;
register char *replbuf; /* data is read into this buffer */
register xReply *rep; /* value passed to calling handler */
char *buf; /* value passed to calling handler */
int len; /* value passed to calling handler */
int extra; /* extra words to read, ala _XReply */
Bool discard; /* discard after extra?, ala _XReply */
_XGetAsyncReply(
register Display *dpy,
register char *replbuf, /* data is read into this buffer */
register xReply *rep, /* value passed to calling handler */
char *buf, /* value passed to calling handler */
int len, /* value passed to calling handler */
int extra, /* extra words to read, ala _XReply */
Bool discard) /* discard after extra?, ala _XReply */
{
if (extra == 0) {
if (discard && (rep->generic.length << 2) > len)
......@@ -125,6 +125,11 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
_XRead(dpy, replbuf + len, size - len);
buf = replbuf;
len = size;
#ifdef MUSTCOPY
} else {
memcpy(replbuf, buf, size);
buf = replbuf;
#endif
}
if (discard && rep->generic.length > extra &&
......@@ -133,9 +138,9 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
return buf;
}
/*
/*
*if we get here, then extra > rep->generic.length--meaning we
* read a reply that's shorter than we expected. This is an
* read a reply that's shorter than we expected. This is an
* error, but we still need to figure out how to handle it...
*/
if ((rep->generic.length << 2) > len)
......@@ -153,15 +158,15 @@ _XGetAsyncReply(dpy, replbuf, rep, buf, len, extra, discard)
}
void
_XGetAsyncData(dpy, data, buf, len, skip, datalen, discardtotal)
Display *dpy;
char *data; /* data is read into this buffer */
char *buf; /* value passed to calling handler */
int len; /* value passed to calling handler */
int skip; /* number of bytes already read in previous
_XGetAsyncData(
Display *dpy,
char *data, /* data is read into this buffer */
char *buf, /* value passed to calling handler */
int len, /* value passed to calling handler */
int skip, /* number of bytes already read in previous
_XGetAsyncReply or _XGetAsyncData calls */
int datalen; /* size of data buffer in bytes */
int discardtotal; /* min. bytes to consume (after skip) */
int datalen, /* size of data buffer in bytes */
int discardtotal) /* min. bytes to consume (after skip) */
{
buf += skip;
len -= skip;
......
/* Copyright (C) 2008 Jamey Sharp, Josh Triplett
* This file is licensed under the MIT license. See the file COPYING.
*
* As Xlibint.h has long become effectively public API, this header exists
* for new private functions that nothing outside of libX11 should call.
*/
#ifndef XPRIVATE_H
#define XPRIVATE_H
extern void _XIDHandler(Display *dpy);
extern void _XSeqSyncFunction(Display *dpy);
extern void _XSetPrivSyncFunction(Display *dpy);
extern void _XSetSeqSyncFunction(Display *dpy);
#ifdef XTHREADS
#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
#define InternalLockDisplay(d,wskip) if ((d)->lock) \
(*(d)->lock->internal_lock_display)(d,wskip,__FILE__,__LINE__)
#else
#define InternalLockDisplay(d,wskip) if ((d)->lock) \
(*(d)->lock->internal_lock_display)(d,wskip)
#endif
#else /* XTHREADS else */
#define InternalLockDisplay(d,wskip)
#endif /* XTHREADS else */
#endif /* XPRIVATE_H */
......@@ -13,7 +13,7 @@
* software without specific, written prior permission.
*
* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
* NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
* IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
......@@ -32,11 +32,7 @@
#include "Xlibint.h"
#include "XlcPubI.h"
#include <nx-X11/Xos.h>
#if 0
#include <unistd.h> /* in theory delivers getresuid/gid prototypes,
* in practice only the Linux syscall wrapper is there. */
#endif
#include <unistd.h>
/************************************************************************/
......@@ -221,7 +217,7 @@ _XlcParsePath(
#define XLOCALEDIR "/usr/lib/X11/locale"
#endif
static void
void
xlocaledir(
char *buf,
int buf_len)
......@@ -268,7 +264,7 @@ xlocaledir(
priv = 0;
} else {
if (seteuid(oldeuid) == -1) {
/* XXX ouch, coudn't get back to original uid
/* XXX ouch, coudn't get back to original uid
what can we do ??? */
_exit(127);
}
......@@ -299,6 +295,84 @@ xlocaledir(
buf[buf_len-1] = '\0';
}
static void
xlocalelibdir(
char *buf,
int buf_len)
{
char *p = buf;
int len = 0;
#ifndef NO_XLOCALEDIR
char *dir;
int priv = 1;
dir = getenv("XLOCALELIBDIR");
if (dir) {
#ifndef WIN32
/*
* Only use the user-supplied path if the process isn't priviledged.
*/
if (getuid() == geteuid() && getgid() == getegid()) {
#if defined(HASSETUGID)
priv = issetugid();
#elif defined(HASGETRESUID)
{
uid_t ruid, euid, suid;
gid_t rgid, egid, sgid;
if ((getresuid(&ruid, &euid, &suid) == 0) &&
(getresgid(&rgid, &egid, &sgid) == 0))
priv = (euid != suid) || (egid != sgid);
}
#else
/*
* If there are saved ID's the process might still be priviledged
* even though the above test succeeded. If issetugid() and
* getresgid() aren't available, test this by trying to set
* euid to 0.
*
* Note: this only protects setuid-root clients. It doesn't
* protect other setuid or any setgid clients. If this tradeoff
* isn't acceptable, set DisableXLocaleDirEnv to YES in host.def.
*/
unsigned int oldeuid;
oldeuid = geteuid();
if (seteuid(0) != 0) {
priv = 0;
} else {
if (seteuid(oldeuid) == -1) {
/* XXX ouch, coudn't get back to original uid
what can we do ??? */
_exit(127);
}
priv = 1;
}
#endif
}
#else
priv = 0;
#endif
if (!priv) {
len = strlen(dir);
strncpy(p, dir, buf_len);
if (len < buf_len) {
p[len++] = LC_PATHDELIM;
p += len;
}
}
}
#endif /* NO_XLOCALEDIR */
if (len < buf_len)
#ifndef __UNIXOS2__
strncpy(p, XLOCALELIBDIR, buf_len - len);
#else
strncpy(p,__XOS2RedirRoot(XLOCALELIBDIR), buf_len - len);
#endif
buf[buf_len-1] = '\0';
}
/* Mapping direction */
typedef enum {
LtoR, /* Map first field to second field */
......@@ -387,11 +461,11 @@ normalize_lcname (const char *name)
{
char *p, *ret;
const char *tmp = name;
p = ret = Xmalloc(strlen(name) + 1);
if (!p)
return NULL;
if (tmp) {
while (*tmp && *tmp != '.' && *tmp != '@')
*p++ = *tmp++;
......@@ -428,7 +502,10 @@ _XlcFileName(
siname = XLC_PUBLIC(lcd, siname);
lowercase(cat, category);
if (category)
lowercase(cat, category);
else
cat[0] = '\0';
xlocaledir(dir,XLC_BUFSIZE);
n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
for (i = 0; i < n; ++i) {
......@@ -483,7 +560,7 @@ _XlcResolveLocaleName(
xlocaledir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, NUM_LOCALEDIR);
for (i = 0; i < n; ++i) {
if ((2 + (args[i] ? strlen (args[i]) : 0) +
if ((2 + (args[i] ? strlen (args[i]) : 0) +
strlen (locale_alias)) < PATH_MAX) {
sprintf (buf, "%s/%s", args[i], locale_alias);
name = resolve_name (lc_name, buf, LtoR);
......@@ -515,7 +592,7 @@ _XlcResolveLocaleName(
return 1;
}
/*
/*
* pub->siname is in the format <lang>_<terr>.<codeset>, typical would
* be "en_US.ISO8859-1", "en_US.utf8", "ru_RU.KOI-8", or ja_JP.SJIS,
* although it could be ja.SJIS too.
......@@ -551,9 +628,7 @@ _XlcResolveLocaleName(
/************************************************************************/
int
_XlcResolveI18NPath(buf, buf_len)
char *buf;
int buf_len;
_XlcResolveI18NPath(char *buf, int buf_len)
{
if (buf != NULL) {
xlocaledir(buf, buf_len);
......@@ -562,10 +637,7 @@ _XlcResolveI18NPath(buf, buf_len)
}
char *
_XlcLocaleDirName(dir_name, dir_len, lc_name)
char *dir_name;
size_t dir_len;
char *lc_name;
_XlcLocaleDirName(char *dir_name, size_t dir_len, char *lc_name)
{
char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
int i, n;
......@@ -574,12 +646,121 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
char *target_name = (char*)0;
char *target_dir = (char*)0;
char *nlc_name = NULL;
static char* last_dir_name = 0;
static size_t last_dir_len = 0;
static char* last_lc_name = 0;
if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
&& dir_len >= last_dir_len) {
strcpy (dir_name, last_dir_name);
return dir_name;
}
xlocaledir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256);
for (i = 0; i < n; ++i) {
if ((2 + (args[i] ? strlen(args[i]) : 0) +
if ((2 + (args[i] ? strlen(args[i]) : 0) +
strlen(locale_alias)) < PATH_MAX) {
sprintf (buf, "%s/%s", args[i], locale_alias);
name = resolve_name(lc_name, buf, LtoR);
if (!name) {
if (!nlc_name)
nlc_name = normalize_lcname(lc_name);
if (nlc_name)
name = resolve_name (nlc_name, buf, LtoR);
}
}
/* If name is not an alias, use lc_name for locale.dir search */
if (name == NULL)
name = lc_name;
/* look at locale.dir */
target_dir = args[i];
if (!target_dir) {
/* something wrong */
if (name != lc_name)
Xfree(name);
continue;
}
if ((1 + (target_dir ? strlen (target_dir) : 0) +
strlen("locale.dir")) < PATH_MAX) {
sprintf(buf, "%s/locale.dir", target_dir);
target_name = resolve_name(name, buf, RtoL);
}
if (name != lc_name)
Xfree(name);
if (target_name != NULL) {
char *p = 0;
if ((p = strstr(target_name, "/XLC_LOCALE"))) {
*p = '\0';
break;
}
Xfree(target_name);
target_name = NULL;
}
name = NULL;
}
if (nlc_name) Xfree(nlc_name);
if (target_name == NULL) {
/* vendor locale name == Xlocale name, no expansion of alias */
target_dir = args[0];
target_name = lc_name;
}
/* snprintf(dir_name, dir_len, "%s/%", target_dir, target_name); */
strncpy(dir_name, target_dir, dir_len - 1);
if (strlen(target_dir) >= dir_len - 1) {
dir_name[dir_len - 1] = '\0';
} else {
strcat(dir_name, "/");
strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1);
if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
dir_name[dir_len - 1] = '\0';
}
if (target_name != lc_name)
Xfree(target_name);
if (last_dir_name != 0)
Xfree (last_dir_name);
if (last_lc_name != 0)
Xfree (last_lc_name);
last_dir_len = strlen (dir_name) + 1;
last_dir_name = Xmalloc (last_dir_len);
strcpy (last_dir_name, dir_name);
last_lc_name = Xmalloc (strlen (lc_name) + 1);
strcpy (last_lc_name, lc_name);
return dir_name;
}
char *
_XlcLocaleLibDirName(char *dir_name, size_t dir_len, char *lc_name)
{
char dir[PATH_MAX], buf[PATH_MAX], *name = NULL;
int i, n;
char *args[NUM_LOCALEDIR];
static char locale_alias[] = LOCALE_ALIAS;
char *target_name = (char*)0;
char *target_dir = (char*)0;
char *nlc_name = NULL;
static char* last_dir_name = 0;
static size_t last_dir_len = 0;
static char* last_lc_name = 0;
if (last_lc_name != 0 && strcmp (last_lc_name, lc_name) == 0
&& dir_len >= last_dir_len) {
strcpy (dir_name, last_dir_name);
return dir_name;
}
xlocalelibdir (dir, PATH_MAX);
n = _XlcParsePath(dir, args, 256);
for (i = 0; i < n; ++i) {
if ((2 + (args[i] ? strlen(args[i]) : 0) +
strlen(locale_alias)) < PATH_MAX) {
sprintf (buf, "%s/%s", args[i], locale_alias);
name = resolve_name(lc_name, buf, LtoR);
......@@ -590,13 +771,13 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
name = resolve_name (nlc_name, buf, LtoR);
}
}
/* If name is not an alias, use lc_name for locale.dir search */
if (name == NULL)
name = lc_name;
/* look at locale.dir */
target_dir = args[i];
if (!target_dir) {
/* something wrong */
......@@ -636,10 +817,21 @@ _XlcLocaleDirName(dir_name, dir_len, lc_name)
} else {
strcat(dir_name, "/");
strncat(dir_name, target_name, dir_len - strlen(dir_name) - 1);
if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
if (strlen(target_name) >= dir_len - strlen(dir_name) - 1)
dir_name[dir_len - 1] = '\0';
}
if (target_name != lc_name)
Xfree(target_name);
if (last_dir_name != 0)
Xfree (last_dir_name);
if (last_lc_name != 0)
Xfree (last_lc_name);
last_dir_len = strlen (dir_name) + 1;
last_dir_name = Xmalloc (last_dir_len);
strcpy (last_dir_name, dir_name);
last_lc_name = Xmalloc (strlen (lc_name) + 1);
strcpy (last_lc_name, lc_name);
return dir_name;
}
/*
Copyright (c) 2007-2009, Troy D. Hanson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTLIST_H
#define UTLIST_H
#define UTLIST_VERSION 1.7
/* From: http://uthash.sourceforge.net/utlist.html */
/*
* This file contains macros to manipulate singly and doubly-linked lists.
*
* 1. LL_ macros: singly-linked lists.
* 2. DL_ macros: doubly-linked lists.
* 3. CDL_ macros: circular doubly-linked lists.
*
* To use singly-linked lists, your structure must have a "next" pointer.
* To use doubly-linked lists, your structure must "prev" and "next" pointers.
* Either way, the pointer to the head of the list must be initialized to NULL.
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
* struct item *prev, *next;
* }
*
* struct item *list = NULL:
*
* int main() {
* struct item *item;
* ... allocate and populate item ...
* DL_APPEND(list, item);
* }
* --------------------------------------------------
*
* For doubly-linked lists, the append and delete macros are O(1)
* For singly-linked lists, append and delete are O(n) but prepend is O(1)
* The sort macro is O(n log(n)) for all types of single/double/circular lists.
*/
/******************************************************************************
* doubly linked list macros (non-circular) *
*****************************************************************************/
#define DL_PREPEND(head,add) \
do { \
(add)->next = head; \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev = (add); \
} else { \
(add)->prev = (add); \
} \
(head) = (add); \
} while (0)
#define DL_APPEND(head,add) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev->next = (add); \
(head)->prev = (add); \
(add)->next = NULL; \
} else { \
(head)=(add); \
(head)->prev = (head); \
(head)->next = NULL; \
} \
} while (0);
#define DL_DELETE(head,del) \
do { \
if ((del)->prev == (del)) { \
(head)=NULL; \
} else if ((del)==(head)) { \
(del)->next->prev = (del)->prev; \
(head) = (del)->next; \
} else { \
(del)->prev->next = (del)->next; \
if ((del)->next) { \
(del)->next->prev = (del)->prev; \
} else { \
(head)->prev = (del)->prev; \
} \
} \
} while (0);
#define DL_FOREACH(head,el) \
for(el=head;el;el=el->next)
#define DL_FOREACH_SAFE(head,el,tmp) \
for(el=head,tmp=el->next;el;el=tmp,tmp=(el) ? (el->next) : NULL)
#endif /* UTLIST_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment