Exemplo n.º 1
0
int server(int sock){
    int nstep;
    int nmin;
    int nmax;
    int nrep;
    if(stread(sock, &nstep, sizeof(int))
       || stread(sock, &nmin, sizeof(int))
       || stread(sock, &nmax, sizeof(int))
       || stread(sock, &nrep, sizeof(int))){
	return -1;
    }
    info("nstep=%d, nmin=%d, nmax=%d, nrep=%d\n", nstep,nmin, nmax, nrep);
    buf2=(char*)malloc(nmax*nstep);
    //warm up
    for(int i=0; i<10; i++){
	if(stread(sock, buf2, nmax) || stwrite(sock, buf2, 64)){
	    close(sock);
	    return -1;
	}
    }
    for(int len=nmin; len<=nmax; len+=nstep){
	for(int irep=0; irep<nrep; irep++){
	    if(stread(sock, buf2, len) || stwrite(sock, buf2, 64)){
		close(sock);
		return -1;
	    }
	}
    }
    return -1;
}
Exemplo n.º 2
0
/**
   Write a string to socket
*/
int stwritestr(int sfd, const char *str){
    if(str){
	int len=strlen(str)+1;
	return stwriteint(sfd, len) || stwrite(sfd, str, len);
    }else{
	return stwriteint(sfd, 0);
    }
}
Exemplo n.º 3
0
int client(const char *hostname, int port, int nmin, int nmax, int nstep, int nrep){
    int sock=connect_port(hostname, port, 0, 1);
    if(sock<0 || stwriteint(sock, nstep) 
       || stwriteint(sock, nmin)
       || stwriteint(sock, nmax)
       || stwriteint(sock, nrep)) {
	warning("Unable to connecto to %s\n", hostname);
	close(sock); return 1;
    }
    buf1=(char*)malloc(nmax*nstep);
    for(int i=0;i<10;i++){//warm up
	stwrite(sock, buf1, nmax);
	stread(sock, buf1, 64);
	usleep(500);
    }
    double tim1, tim2, tim3;
    int nlen=(nmax-nmin+nstep)/nstep;
    dmat *timing=dnew(nrep, nlen);
    dmat *timing2=dnew(nrep, nlen);
    int ilen=-1;
    for(int len=nmin; len<=nmax; len+=nstep){
	ilen++;
	info("len=%d\n", len);
	for(int irep=0; irep<nrep; irep++){
	    if(irep%800==0){
		info("irep=%d of %d\n", irep, nrep);
	    }
	    usleep(500);
	    tim1=myclockd();
	    stwrite(sock, buf1, len);
	    tim2=myclockd();
	    stread(sock, buf1, 64);
	    tim3=myclockd();
	    timing->p[irep+ilen*nrep]=tim3-tim1;
	    timing2->p[irep+ilen*nrep]=tim2-tim1;
	}
    }
    close(sock);
    writebin(timing, "pix_timing_%s_%d_%d_%d", HOST, nmin, nmax, nstep);
    writebin(timing2, "pix_timing2_%s_%d_%d_%d", HOST, nmin, nmax, nstep);
    dbg("done\n");
    return 0;
}
Exemplo n.º 4
0
int main(int argc, char *argv[]){
    enum{
	P_EXE,
	P_FRAC,
	P_NSTEP,
	P_TOT,
    };
    if(argc!=P_TOT){
	info2("Usage: \n\tenv MVM_CLIENT=hostname MVM_PORT=port MVM_SASTEP=sastep ./mvm_cpu fraction nstep\n");
	_Exit(0);
    }
    int fraction=strtol(argv[P_FRAC], NULL, 10);
    int nstep=strtol(argv[P_NSTEP], NULL, 10);
    int nstep0=nstep>1?20:0;//warm up
    dmat *d_saind=dread("NFIRAOS_saind");
    const int nsa=(d_saind->nx-1)/fraction;
    int *saind=mymalloc((1+nsa),int);
    for(int i=0; i<nsa+1; i++){
	saind[i]=(int)d_saind->p[i];
    }
    dfree(d_saind);
    const int totpix=saind[nsa];
    const int nact=6981;//active subapertures.
    int ng=nsa*2;
    float FSMdelta=-0.2;
    smat *dm=snew(nact,1);
    smat *mvm=snew(nact, ng);
    smat *mtch=snew(totpix*2,1);
    smat *grad=snew(ng,1);
    smat *im0=snew(totpix,3);
    short *pix=mymalloc(totpix,short);
    short *pixbias=mymalloc(totpix,short);
    {
	rand_t rseed;
	seed_rand(&rseed, 1);
	srandu(mvm, 1e-7, &rseed);
	srandu(mtch, 1, &rseed);
	for(int i=0; i<totpix; i++){
	    pix[i]=(short)(randu(&rseed)*25565);
	    pixbias[i]=(short)(randu(&rseed)*1000);
	}
    }
    smat *mvmt=strans(mvm);
    int sastep=200;//how many subapertures each time
    int nrep=1;
    if(getenv("MVM_NREP")){
	nrep=strtol(getenv("MVM_NREP"), NULL, 10);
    }
    if(getenv("MVM_SECT")){
	sastep=nsa/strtol(getenv("MVM_SECT"), NULL, 10);
    }
    if(getenv("MVM_TRANS")){
	use_trans=strtol(getenv("MVM_TRANS"), NULL, 10);
    }
    if(getenv("MVM_SASTEP")){
	sastep=strtol(getenv("MVM_SASTEP"), NULL, 10);
    }
    info2("use_trans=%d, nrep=%d, sastep=%d\n", use_trans, nrep, sastep);
    int sock=-1;
    char* MVM_CLIENT=getenv("MVM_CLIENT");
    if(MVM_CLIENT){
	short port=(short)strtol(getenv("MVM_PORT"), NULL, 10);
	sock=connect_port(MVM_CLIENT, port, 0 ,1);
	if(sock!=-1) {
	    info2("Connected\n");
	    int cmd[7];
	    cmd[0]=nact;
	    cmd[1]=nsa;
	    cmd[2]=sastep;
	    cmd[3]=totpix;
	    cmd[4]=nstep;
	    cmd[5]=nstep0;
	    cmd[6]=2;
	    if(stwriteintarr(sock, cmd, 7) 
	       || stwriteintarr(sock, saind, nsa+1)
	       || stwrite(sock, pix, sizeof(short)*totpix)){
		close(sock); sock=-1;
		warning("Failed: %s\n", strerror(errno));
	    }
	}
    }
    int ready=0;
    if(sock!=-1 && stwriteint(sock, ready)){
	warning("error send ready signal: %s\n", strerror(errno));
	close(sock); sock=-1;
    }
    smat *timing=snew(nstep, 1);
    TIC;
    float timtot=0, timmax=0, timmin=INFINITY;
    set_realtime(-1, -20);
    for(int jstep=-nstep0; jstep<nstep; jstep++){
	int istep=jstep<0?0:jstep;
	tic;
	double theta=M_PI*0.5*istep+FSMdelta;
	float cd=cos(theta);
	float sd=cos(theta);
	szero(dm);
	for(int isa=0; isa<nsa; isa+=sastep){
	    int npixleft;
	    int nsaleft;
	    if(nsa<isa+sastep){//terminate
		npixleft=totpix-saind[isa];
		nsaleft=nsa-isa;
	    }else{
		npixleft=saind[isa+sastep]-saind[isa];
		nsaleft=sastep;
	    }

	    short *pcur=pix+saind[isa];
	    if(sock!=-1){
		if(stread(sock, pcur, sizeof(short)*npixleft)){
		    warning("failed: %s\n", strerror(errno));
		    close(sock); sock=-1;
		    _Exit(1);
		}
		if(isa==0) tic;
	    }
	    //Matched filter
	    mtch_do(mtch->p, pix, pixbias, 
		    grad->p+isa*2, im0->p, im0->p+totpix, im0->p+totpix*2,
		    saind+isa, nsaleft, cd, sd);
	    //MVM
	    for(int irep=0; irep<nrep; irep++){
		if(use_trans){
		    mvmt_do(mvmt->p+isa*2, grad->p+isa*2,dm->p, nact, nsaleft*2, ng);
		}else{
		    mvm_do(mvm->p+isa*2*nact, grad->p+isa*2, dm->p, nact, nsaleft*2);
		}
	    }
	}//for isa
	if(sock!=-1){
	    if(stwrite(sock, dm->p, sizeof(float)*nact)){
		warning("error write dmres: %s\n", strerror(errno));
		close(sock); sock=-1;
		_Exit(1);
	    }
	    if(streadint(sock, &ready)){//acknowledgement.
		warning("error read ack failed: %s\n", strerror(errno));
		close(sock), sock=-1;
		_Exit(1);
	    }
	    timing->p[istep]=ready*1.e-6;
	}else{
	    timing->p[istep]=toc3;//do not tic.
	}
	if(jstep==istep){
	    timtot+=timing->p[istep];
	    if(timmax<timing->p[istep]){
		timmax=timing->p[istep];
	    }
	    if(timmin>timing->p[istep]){
		timmin=timing->p[istep];
	    }
	}
    }//for istep
    float timmean=timtot/nstep;
    info2("Timing is mean %.3f, max %.3f min %.3f. BW is %.1f of 51.2GB/s\n",
	  timmean*1e3, timmax*1e3, timmin*1e3, nrep*(nact*ng+nact+ng)*sizeof(float)/timmean/(1024*1024*1024));
    writebin(timing, "cpu_timing_%s", HOST);
    if(nstep==1){
	writearr("cpu_pix", 1, sizeof(short), M_INT16, NULL, pix, totpix, 1);
	writearr("cpu_pixbias", 1, sizeof(short), M_INT16, NULL, pixbias, totpix, 1);
	writebin(dm, "cpu_dm");
	writebin(grad, "cpu_grad");
	writebin(mvm, "cpu_mvm");
	writebin(mtch, "cpu_mtch");
    }
   
}
Exemplo n.º 5
0
int
fsdump(int argc, char *argv[])
{
    int i, j, io;
    int status;
    int block, bytes;
    int scsi_id, blk, nblks, size, mark;
    struct stat boot_stat;
    struct	partition *pp;
    scsi_id = scsi_device;

    printf("Current SCSI device = ID %d\n", scsi_id);
    getline("Is it sure ? (y/n) ", cons_buf);

    if ((cons_buf[0] != 'y') && (cons_buf[0] != 'Y'))
        return ST_ERROR;

    scsi_read_raw(scsi_id, 0, 1, index, LABEL_SIZE);

    for (i = 0; i < MAXPARTITIONS; i++) {
        pp = &(lp->d_partitions[i]);
        if ((i != 0) &&
                (i != 3) &&
                (i != 4) &&
                (i != 5)) {
            pp->p_size = 0;
        }
        if (i == 5 && argc > 1 && !strcmp(argv[1], "tailor"))
            pp->p_size = 0;
    }

    st_rewind(rst0);

    printf("Boot Program		");
    io = open("sd(0,0)boot", 0);
    if (io >= 0) {
        printf("read ... ");
        size = read(io, dump_buf, 1048576);
        close(io);
        printf("%d bytes ... ", size);
        if (size <= 0) {
            printf("failed\n");
            return ST_ERROR;
        }
        boot_stat.st_size = size;
    }

    printf("write ... ");
    status = stwrite(rst0, dump_buf, size);
    st_write_EOF(rst0);

    if (status < size) {
        printf("failed\n");
        return ST_ERROR;
    }

    printf("done\n");

    printf("disklabel (index)\t");

    printf("write ... ");
    status = stwrite(rst0, index, LABEL_SIZE);
    st_write_EOF(rst0);

    if (status < LABEL_SIZE) {
        printf("failed\n");
        return ST_ERROR;
    }

    printf("done\n\n");

    for (i = 0; i < MAXPARTITIONS; i++) {
        pp = &(lp->d_partitions[i]);
        if (pp->p_size > 0) {
            printf("%c: ", i + 'A');
            printf("size = %d(0x%s), ",
                   pp->p_size, hexstr(pp->p_size, 8));
            printf("offset = %d(0x%s)\n",
                   pp->p_offset, hexstr(pp->p_offset, 8));

            blk   = pp->p_offset;
            nblks = pp->p_size;
            size  = nblks << DEV_BSHIFT;

            block = BUF_BLOCK;
            bytes = BUF_BYTES;

            mark = nblks / block;
            if (nblks % block)
                mark++;
            for (j = 0; j < mark; j++)
                printf("-");
            for (j = 0; j < mark; j++)
                printf("%c", '\x08');

            while (nblks > 0) {
                if (nblks < block) {
                    block = nblks;
                    bytes = nblks << DEV_BSHIFT;
                }

                if (!scsi_read_raw(scsi_id, blk, block,
                                   dump_buf, bytes)) {
                    printf("disk read failed !!!\n");
                    return ST_ERROR;
                }

                if (stwrite(rst0, dump_buf, bytes) < bytes) {
                    printf("tape write failed !!!\n");
                    return ST_ERROR;
                }

                blk   += block;
                nblks -= block;
                size  -= bytes;

                printf("#");
            }

            st_write_EOF(rst0);
            printf("\n\n");
        }
    }
    return ST_NORMAL;
}
Exemplo n.º 6
0
Arquivo: sock.c Projeto: lianqiw/maos
/**
   Open a port and listen to it. Calls respond(sock) to handle data. If
   timeout_fun is not NULL, it will be called when 1) connection is
   establed/handled, 2) every timeout_sec if timeout_sec>0. This function only
   return at error.
   if localpath is not null and start with /, open the local unix port also
   if localpath is not null and contains ip address, only bind to that ip address
 */
void listen_port(uint16_t port, char *localpath, int (*responder)(int),
		 double timeout_sec, void (*timeout_fun)(), int nodelay){
    register_signal_handler(scheduler_signal_handler);

    fd_set read_fd_set;
    fd_set active_fd_set;
    FD_ZERO (&active_fd_set);
    char *ip=0;
    int sock_local=-1;
    if(localpath){
	if(localpath[0]=='/'){
	    //also bind to AF_UNIX
	    sock_local = bind_socket_local(localpath);
	    if(sock_local==-1){
		dbg("bind to %s failed\n", localpath);
	    }else{
		if(!listen(sock_local, 1)){
		    FD_SET(sock_local, &active_fd_set);
		}else{
		    perror("listen");
		    close(sock_local);
		sock_local=-1;
		}
	    }
	}else{
	    ip=localpath;
	}
    }

    int sock = bind_socket (ip, port);
    if(nodelay){//turn off tcp caching.
	socket_tcp_nodelay(sock);
    }
    if (listen (sock, 1) < 0){
	perror("listen");
	exit(EXIT_FAILURE);
    }

    FD_SET (sock, &active_fd_set);
 
    while(quit_listen!=2){
	if(quit_listen==1){
	    /*
	      shutdown(sock, SHUT_WR) sends a FIN to the peer, therefore
	      initialize a active close and the port will remain in TIME_WAIT state.

	      shutdown(sock, SHUT_RD) sends nother, just mark the scoket as not readable.

	      accept() create a new socket on the existing port. A socket is identified by client ip/port and server ip/port.
	      
	      It is the port that remain in TIME_WAIT state.
	     */
	    //shutdown(sock, SHUT_RDWR);
	    //shutdown(sock_local, SHUT_RDWR);
	    /*Notice existing client to shutdown*/
	    for(int i=0; i<FD_SETSIZE; i++){
		if(FD_ISSET(i, &active_fd_set) && i!=sock && i!=sock_local){
		    int cmd[3]={-1, 0, 0};
		    stwrite(i, cmd, 3*sizeof(int)); //We ask the client to actively close the connection
		    //shutdown(i, SHUT_WR);
		}
	    }
	    usleep(1e5);
	    quit_listen=2;
	    //don't break. Listen for connection close events.
	}
	if(timeout_fun){
	    timeout_fun();
	}

	struct timeval timeout;
	timeout.tv_sec=timeout_sec;
	timeout.tv_usec=(timeout_sec-timeout.tv_sec)*1e6;
	read_fd_set = active_fd_set;
	if(select(FD_SETSIZE, &read_fd_set, NULL, NULL, timeout_sec>0?&timeout:0)<0){
	    if(errno==EINTR){
		warning("select failed: %s\n", strerror(errno));
		continue;
	    }else if(errno==EBADF){
		warning("bad file descriptor: %s\n", strerror(errno));
		break;//bad file descriptor
	    }else{
		warning("unknown error: %s\n", strerror(errno));
		break;
	    }
	}
	for(int i=0; i<FD_SETSIZE; i++){
	    if(FD_ISSET(i, &read_fd_set)){
		if(i==sock){
		    /* Connection request on original socket. */
		    socklen_t size=sizeof(struct sockaddr_in);
		    struct sockaddr_in clientname;
    		    int port2=accept(i, (struct sockaddr*)&clientname, &size);
		    if(port2<0){
			warning("accept failed: %s. close port %d\n", strerror(errno), i);
			FD_CLR(i, &active_fd_set);
			close(i);
		    }else{
			info("port %d is connected\n", port2);
			FD_SET(port2, &active_fd_set);
		    }
		}else if(i==sock_local){
		    socklen_t size=sizeof(struct sockaddr_un);
		    struct sockaddr_un clientname;
		    int port2=accept(i, (struct sockaddr*)&clientname, &size);
		    if(port2<0){
			warning("accept failed: %s. close port %d\n", strerror(errno), i);
			FD_CLR(i, &active_fd_set);
			close(i);
		    }else{
			info("port %d is connected locally\n", port2);
			FD_SET(port2, &active_fd_set);
		    }
		}else{
		    /* Data arriving on an already-connected socket. Call responder to handle.
		       On return:
		       negative value: Close read of socket. 
		       -1: also close the socket.
		     */
		    int ans=responder(i);
		    if(ans<0){
			FD_CLR(i, &active_fd_set);
			if(ans==-1){
			    warning("close port %d\n", i);
			    close(i);
			}else{
			    warning("ans=%d is not understood.\n", ans);
			}
		    }
		}
	    }
	}
    }
    /* Error happened. We close all connections and this server socket.*/
    close(sock);
    close(sock_local);
    FD_CLR(sock, &active_fd_set);
    FD_CLR(sock_local, &active_fd_set);
    warning("listen_port exited\n");
    for(int i=0; i<FD_SETSIZE; i++){
	if(FD_ISSET(i, &active_fd_set)){
	    warning("sock %d is still connected\n", i);
	    close(i);
	    FD_CLR(i, &active_fd_set);
	}
    }
    usleep(100);
    sync();
}
Exemplo n.º 7
0
//server for mvmfull_real
int mvm_server(int sock){
    int cmd[7];
    if(streadintarr(sock, cmd, 7)){
	return -1;
    }
    int nact=cmd[0];
    int nsa=cmd[1];
    int sastep=cmd[2];
    int totpix=cmd[3];
    int pixpsa=totpix;
    int nstep=cmd[4];
    int nstep0=cmd[5];
    int type=cmd[6];
    dbg("type=%d, nact=%d, nsa=%d, sastep=%d, %s=%d, nstep=%d\n",type,
	 nact, nsa, sastep, type==1?"pixpsa":"totpix", totpix, nstep);
    int *saind=NULL;
    if(type==1){//mvmfull_iwfs
	totpix=pixpsa*nsa;
    }else{//mvmfull_real
	saind=mymalloc((nsa+1),int);
	if(streadintarr(sock, saind, nsa+1)){
	    return -1;
	}
    }
    short *pix=mymalloc(totpix,short);
    if(type==1){
	rand_t rseed;
	seed_rand(&rseed, 1);
	for(int i=0; i<totpix; i++){
	    pix[i]=(short)randu(&rseed);
	}
    }else{
	if(stread(sock, pix, totpix*sizeof(short))){
	    return -1;
	}
    }
    smat *dmres=snew(nact, 1);
    int ready;
    streadint(sock, &ready); //wait for client to be ready.
#if __linux__
    struct timespec ct;
    clock_gettime(CLOCK_MONOTONIC, &ct);
    int readtime_ns=500000;//500 micro-second read out time. 
    int frametime_ns=1250000;//frame time.
    int nsend=((nsa+sastep-1)/sastep);//number of segments sent along read out
    int int1_ns=readtime_ns/nsend;//interval between segment sending
    int int2_ns=frametime_ns-readtime_ns;//interval after last segment.
#endif
    TIC;tic;
    for(int istep=-nstep0; istep<nstep; istep++){
	//info("\rSend trigger ");
#if __linux__
	//scheduled start time of the frame.
	double tk0=(double)ct.tv_sec+(double)ct.tv_nsec*1.e-9;
#else
	tic;
#endif
	for(int isa=0; isa<nsa; isa+=sastep){
#if __linux__
	    if(clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ct, NULL)){
		warning("clock_nanosleep is interrupted\n");
	    }
	    if(isa==0){
		tic;
	    }
#endif
	    int nleft;
	    if(type==1){
		nleft=((nsa-isa)<sastep?(nsa-isa):sastep)*pixpsa;
	    }else{
		if(nsa<isa+sastep){//terminate
		    nleft=totpix-saind[isa];
		}else{
		    nleft=saind[isa+sastep]-saind[isa];
		}
	    }
	    if(stwrite(sock, pix+(type==1?pixpsa*isa:saind[isa]), 2*nleft)){//2 byte data.
		warning("failed: %s\n", strerror(errno));
		return -1;
	    }
#if __linux__
	    ct.tv_nsec+=int1_ns;
	    while(ct.tv_nsec>=1000000000){
		ct.tv_nsec-=1000000000;
		ct.tv_sec++;
	    }
#endif
	}
	if(stread(sock, dmres->p, sizeof(float)*nact)){
	    warning("read dmres failed: %s\n", strerror(errno));
	    return -1;
	}
	ready=(int)(toc3*1e6);//mvm is finished.
#if __linux__
	if(nstep<100){
	    dbg("tk=%.6f tic=%.6f, toc=%.6f, ready=%.6f\n", tk0, tk, myclockd(), ready*1e-6);
	}
#endif
	if(stwriteint(sock, ready)){
	    warning("write ready failed: %s\n", strerror(errno));
	    return -1;
	}
	//set next frame start time.
#if __linux__
	ct.tv_nsec+=int2_ns;
	while(ct.tv_nsec>=1000000000){
	    ct.tv_nsec-=1000000000;
	    ct.tv_sec++;
	}
#endif
	if((istep & 0xFF) == 0xFF){
	    info("%d %d us.\n", istep, ready);
	}

    }
    info("\n");
    return -1;
}
Exemplo n.º 8
0
void dolmove_drawline(long i)
{
  /* draws one row of the tree diagram by moving up tree */
  node *p, *q, *r, *first =NULL, *last =NULL;
  long n, j, pos;
  boolean extra, done;
  Char s, cc;
  chartype c, d;

  pos = 1;
  p = nuroot;
  q = nuroot;
  extra = false;
  if (i == (long)p->ycoord && (p == root || subtree)) {
    c = overt;
    if (display) {
      if (p == root)
        cc = guess[dispchar - 1];
      else
        cc = p->state;
      switch (cc) {

      case '1':
        c = onne;
        break;

      case '0':
        c = zerro;
        break;

      case '?':
        c = question;
        break;

      case 'P':
        c = polym;
        break;
      }
    }
    
    if ((subtree))
      stwrite("Subtree:", 8, &pos, leftedge, screenwidth);
    if (p->index >= 100)
      nnwrite(p->index, 3, &pos, leftedge, screenwidth);
    else if (p->index >= 10) {
      grwrite(c, 1, &pos);
      nnwrite(p->index, 2, &pos, leftedge, screenwidth);
    } else {
      grwrite(c, 2, &pos);
      nnwrite(p->index, 1, &pos, leftedge, screenwidth);
    }
    extra = true;
  } else {
    if (subtree)
      stwrite("          ", 10, &pos, leftedge, screenwidth);
    else
      stwrite("  ", 2, &pos, leftedge, screenwidth);
  }
  do {
    if (!p->tip) {
      r = p->next;
      done = false;
      do {
        if (i >= r->back->ymin && i <= r->back->ymax) {
          q = r->back;
          done = true;
        }
        r = r->next;
      } while (!(done || r == p));
      first = p->next->back;
      r = p->next;
      while (r->next != p)
        r = r->next;
      last = r->back;
    }
    done = (p == q);
    n = (long)p->xcoord - (long)q->xcoord;
    if (n < 3 && !q->tip)
      n = 3;
    if (extra) {
      n--;
      extra = false;
    }
    if ((long)q->ycoord == i && !done) {
      if ((long)q->ycoord > (long)p->ycoord)
        d = upcorner;
      else
        d = downcorner;
      c = overt;
      s = q->state;
      if (s == 'P' && p->state != 'P')
        s = p->state;
      if (display) {
        switch (s) {

        case '1':
          c = onne;
          break;

        case '0':
          c = zerro;
          break;

        case '?':
          c = question;
          break;

        case 'P':
          c = polym;
          break;
        }
        d = c;
      }
      if (n > 1) {
        grwrite(d, 1, &pos);
        grwrite(c, n - 3, &pos);
      }
      if (q->index >= 100)
        nnwrite(q->index, 3, &pos, leftedge, screenwidth);
      else if (q->index >= 10) {
        grwrite(c, 1, &pos);
        nnwrite(q->index, 2, &pos, leftedge, screenwidth);
      } else {
        grwrite(c, 2, &pos);
        nnwrite(q->index, 1, &pos, leftedge, screenwidth);
      }
      extra = true;
    } else if (!q->tip) {
      if ((long)last->ycoord > i && (long)first->ycoord < i
        && i != (long)p->ycoord) {
        c = up;
        if (i < (long)p->ycoord)
          s = p->next->back->state;
        else
          s = p->next->next->back->state;
        if (s == 'P' && p->state != 'P')
          s = p->state;
        if (display) {
          switch (s) {

          case '1':
            c = onne;
            break;

          case '0':
            c = zerro;
            break;

          case '?':
            c = question;
            break;

          case 'P':
            c = polym;
            break;
          }
        }
        grwrite(c, 1, &pos);
        chwrite(' ', n - 1, &pos, leftedge, screenwidth);
      } else
        chwrite(' ', n, &pos, leftedge, screenwidth);
    } else
      chwrite(' ', n, &pos, leftedge, screenwidth);
    if (p != q)
      p = q;
  } while (!done);
  if ((long)p->ycoord == i && p->tip) {
    n = 0;
    for (j = 1; j <= nmlngth; j++) {
      if (nayme[p->index - 1][j - 1] != '\0')
        n = j;
    }
    chwrite(':', 1, &pos, leftedge, screenwidth);
    for (j = 0; j < n; j++)
      chwrite(nayme[p->index - 1][j], 1, &pos, leftedge, screenwidth);
  }
  putchar('\n');
}  /* dolmove_drawline */