----------------------------------------------------------------------------------
@MSGID:
<dc2163fa-b747-4298-aaab-1b4be80389een@googlegroups.com> ce54c33d
@REPLY: 2@dont-email.me> 6047cfae
@REPLYADDR wij <wyniijj5@gmail.com>
@REPLYTO 2:5075/128 wij
@CHRS: CP866 2
@RFC: 1 0
@RFC-References:
<40b905c7-54ae-4e9f-bd6c-990f8e0e804an@googlegroups.com> 1@dont-email.me>
<124e2b02-b26c-48be-9d84-d18bc2322b86n@googlegroups.com> 2@dont-email.me>
@RFC-Message-ID:
<dc2163fa-b747-4298-aaab-1b4be80389een@googlegroups.com>
@TZUTC: -0700
@PID: G2/1.0
@TID: FIDOGATE-5.12-ge4e8b94
On Monday, August 21, 2023 at 10:14:10 PM UTC+8, Lew Pitcher wrote:
> On Mon, 21 Aug 2023 06:30:04 -0700, wij wrote:
>
> > On Monday, August 21, 2023 at 8:28:18 PM UTC+8, Lew Pitcher wrote:
> >> On Sun, 20 Aug 2023 23:05:31 -0700, wij wrote:
> >>
> >> > manpage of hsearch(3) says:
> >> > ...
> >> > The argument action determines what hsearch() does after an unsuccess-
> >> > ful search. This argument must either have the value ENTER, meaning
> >> > insert a copy of item (and return a pointer to the new hash table entry
> >> > as the function result), or the value FIND, meaning that NULL should be
> >> > returned. (If action is FIND, then data is ignored.)
> >> > ...
> >> >
> >> > When I want to insert an item into the hash table, I
invokes hsearch(item,ENTER).
> >> > But I only want to insert the item when it is not in
the hash table. How can I
> >> > do (Only invokes hsearch once. The manpage seems not
mentioning the condition I
> >> > am looking for)?
> >[snip]
> >> It seems pretty clear: hsearch() will either
> >> a) find the matching entry in the hash table, and return a pointer to the
> >> struct entry that defines the key and data of the matching entry, or
> >> b) not find the matching entry, and return NULL (when ACTION
is set to FIND), or
> >> c) not find the matching entry, insert the supplied struct entry into the
> >> hash table, and return a pointer to it (when ACTION is set to ENTER)
> >>
> >> I believe that you are looking for the (c) behaviour; set ACTION to ENTER
> >> when you "want to insert an item into the hash table", and
to FIND when you
> >> want to retrieve it.
>
> >
> > None of the a,b,c option would work.
> Let me make sure that I understand the issue here
> > The usecase is like I am writting some kind of interpreter:
> >
> > Type a=1;
> > Type a=2;
> >
> > When the first "a=1" is encountered, I ENTER "a" into the hash table.
> So, at the first call to hsearch(,ENTER), you supply a pointer to a
> struct entry {
> char *key;
> void *data;
> } something;
> initialized so that something.key points to the name "a", and something.data
> points to the data you want to set "a" to (presumably, 1). That hsearch()
> function returns a non-NULL value (which should be a pointer to your
> struct entry something;) indicating that it saved the given hashtable entry.
> > When the second "a=2" is encountered, the ENTER (because the
parser saw `Type`)
> > should fail because it declares the same name of variable twice.
> Here, you should either first FIND, and decide what to do if
FIND is successful,
> or ENTER and just re-use the struct entry * that hsearch() returned to you.
>
> I guess the choice depends on what your interpreter is expecting to do:
> If
> Type a=2;
> is supposed to define a new something, and fail if that something already
> exists, then you should hsearch(,FIND), and fail if FIND succeeded (or,
> alternately, hsearch(,ENTER), and check whether the returned pointer has
> a ->data that differs from the value you prepared for the hsearch() call).
>
> OTOH, if
> Type a=2;
> is permitted to update/replace/overwrite the prior
> Type a=1;
> then you just hsearch(,ENTER) and update the returned ->data with the
> new value for the key "a".
> HTH
> --
> Lew Pitcher
> "In Skills We Trust"
class HSearch {
::hsearch data m htab;
size t m maxe;
public:
//....
template
WY WARNRET Errno declare(const char* key, T data) {
static assert(sizeof(T)<=sizeof(void*));
static char kbuf[256];
if(key==NULL) {
WY RETURN( EFAULT );
}
if(m maxe==0) {
WY RETURN( EBADF);
}
const size t klen= strlen(key);
if(klen>=sizeof(kbuf)) {
WY RETURN( ENAMETOOLONG );
}
memcpy(kbuf,key,klen);
kbuf[klen]=0;
::ENTRY item,*retv;
item.key= const cast(kbuf);
if(::hsearch r(item, ENTER,&retv,&m htab)==0) {
WY RETURN(errno);
}
if(retv->key!=kbuf) {
WY RETURN(EEXIST);
}
union {
void * ptr;
T val;
} tt;
tt.val=data;
retv->key= const cast(key);
retv->data= tt.ptr;
return Ok;
};
};
I think hsearch can`t do what I want (directly). The work-around is copy the
key to a static buffer. The overhead is equ. to a single strcmp, so, fine.
The limit is string length.
I think the implement of declare(..) should comply with the spec. of hsearch
(to be exactly, hsearch r), though such compliance is not explicitly stated.
How do you think?
--- G2/1.0
* Origin: usenet.network (2:5075/128)
SEEN-BY: 5001/100 5005/49 5010/352 5015/255 5019/40
5020/715 848 1042 4441
SEEN-BY: 5020/12000 5030/49 1081 5075/128
@PATH: 5075/128 5020/1042 4441