⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mknb_metacode.c

📁 最著名最快的分子模拟软件
💻 C
字号:
/* * $Id: mknb_metacode.c,v 1.2.2.2 2008/02/29 07:02:44 spoel Exp $ *  *                This source code is part of *  *                 G   R   O   M   A   C   S *  *          GROningen MAchine for Chemical Simulations *  *                        VERSION 3.3.3 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others. * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team, * check out http://www.gromacs.org for more information. * 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. *  * If you want to redistribute modifications, please consider that * scientific software is very special. Version control is crucial - * bugs must be traceable. We will be happy to consider code for * inclusion in the official distribution, but derived work must not * be called official GROMACS. Details are found in the README & COPYING * files - if they are missing, get the official version at www.gromacs.org. *  * To help us fund GROMACS development, we humbly ask that you cite * the papers on the package - you can find them in the top README file. *  * For more info, check our website at http://www.gromacs.org *  * And Hey: * Groningen Machine for Chemical Simulation */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <ctype.h>#include <mknb_metacode.h>/* This file is NOT threadsafe, but it is only used to create * the nonbonded loops during the build process, so it will never be * executed by multiple threads. *//* Global variables: */int                   mknb_fortran=0;  /* 1 if fortran is used  */int                   mknb_double=0;   /* 1 if double precision */int                   mknb_keep_comments=0;int                   mknb_indent_level=0;FILE *                mknb_output=NULL;/* Return the current indentation as a string */static char *mknb_indent(void){  static char buf[255];  int i;  int indent;    if(mknb_fortran)	  indent = 6 + MKNB_FORTRAN_INDENT_STEP * mknb_indent_level;  else      indent = MKNB_C_INDENT_STEP * (mknb_indent_level+1);	      if(indent > 254)      indent = 254;  	  for(i=0; i<indent; i++)      buf[i] = ' ';  buf[i] = '\0';    return buf;}/* Write the provided string as a comment in the file */void mknb_comment(char *s){  if(mknb_keep_comments) {    if(mknb_fortran) {      mknb_indent_level--;      fprintf(mknb_output,"\nC%s%s\n",mknb_indent(),s);      mknb_indent_level++;    } else {      fprintf(mknb_output,"\n%s/* %s */\n",mknb_indent(),s);    }  }}/* We need to separate argument and variable declarations. * The arguments are written directly to the output file, * while  *//* Define a new floating-point variable */voidmknb_declare_real(char *name){  char type_name[255];  if(mknb_fortran)     sprintf(type_name, "%-13s", mknb_double ? "real*8" : "real*4");  else    sprintf(type_name, "%-13s", mknb_double ? "double" : "float");  mknb_code("%s %s%s",type_name,name, mknb_fortran ? "" : ";");}/* Declare a single-precision floating point var. */voidmknb_declare_real4(char *name){  char type_name[255];  sprintf(type_name, "%-13s", mknb_fortran ? "real*4" : "float");  mknb_code("%s %s%s", type_name ,name, mknb_fortran ? "" : ";");}/* Declare a constant fp variable */voidmknb_declare_const_real(char *name, double value){  char type_name[255];  if(mknb_fortran) {    sprintf(type_name, "%-13s", mknb_double ? "real*8" : "real*4");    mknb_code("%s %s",type_name,name);    mknb_code("    parameter (%s = %f)",name,value);  } else {    sprintf(type_name, "%-13s",	    mknb_double ? "const double" : "const float");    mknb_code("%s %s = %.16f;",type_name,name,value);  }}/* Integer */voidmknb_declare_int(char *name){  char type_name[255];  sprintf(type_name, "%-13s", mknb_fortran ? "integer*4" : "int");   mknb_code("%s %s%s", type_name ,name, mknb_fortran ? "" : ";");}/* integer constant */voidmknb_declare_const_int(char *name, int value){  char type_name[255];  sprintf(type_name, "%-13s", mknb_fortran ? "integer*4" : "const int");  if(mknb_fortran) {    mknb_code("%s %s", type_name ,name);    mknb_code("    parameter (%s = %d)",name,value);  } else    mknb_code("%s %s = %d;", type_name ,name, value);}/* 4-byte Integer (same size as single precision fp) */voidmknb_declare_int4(char *name){  char type_name[255];  sprintf(type_name, "%-13s", mknb_fortran ? "integer*4" : "int");   mknb_code("%s %s%s", type_name ,name, mknb_fortran ? "" : ";");}/* Arbitrary declaration */voidmknb_declare_other(char *type_name,char *name){  char tmp[255];  sprintf(tmp,"%-13s", type_name);  mknb_code("%s %s%s", tmp, name, mknb_fortran ? "" : ";");}/* Reference an element in a list */char *mknb_array(char *a, char *idx){  static char buf[1024];    sprintf(buf,"%s%c%s%c",a, mknb_fortran ? '(' : '[',	  idx, mknb_fortran ? ')' : ']');  return buf;}/* Split a line to adhere to the stupid 72 column limits of fortran, * and write it to the output file */static void mknb_fortran_splitline(char *line){  char tmpbuf[4096];  int i,j,maxlen;  int indent;  maxlen=strlen(line);  i=0;    indent = MKNB_FORTRAN_INDENT_STEP*mknb_indent_level;  /* we can write 72-indentation characters on each line */    while(i+72-indent<maxlen) {    /* set j to the last position */    j=i+71-indent;    if (j>=maxlen)      j=maxlen;    while(j>(i+1)) {      if(line[j]=='+' ||         line[j]=='-' ||         line[j]=='/' ||         (line[j]=='*' && line[j-1]!='*') ||  /* dont split "**" */          line[j]==' ')         break;         j--;    }    if(j==i) {    printf("Error: Couldn't break this line:\n%s\n",line);    exit(1);  }  strncpy(tmpbuf,line+i,j-i+1);  tmpbuf[j-i]=0;  fprintf(mknb_output,tmpbuf);  fprintf(mknb_output,"\n");  fprintf(mknb_output,"     &  ");  i=j;  }  fprintf(mknb_output,line+i);}/* Print a line of code to the output file. * This routine does proper indentation, and also supports the * same type of variable-argument lists as printf, apart from * field widths. */voidmknb_code(char *format, ...){  va_list ap;  int d;  double f;  char *s;  char tmp[4096];  char outbuf[4096];  sprintf(outbuf,"%s",mknb_indent());   va_start(ap,format);    while(*format) {    if(*format!='%')       sprintf(tmp,"%c",*format);    else {      switch(*(++format)) {      case 'd': /* read an integer */        d = va_arg(ap, int);        sprintf(tmp,"%d",d);        break;      case 'f': /* read a (double precision) floating point number */        f = va_arg(ap, double);        sprintf(tmp,"%.16f",f);        break;      case 's': /* read a string */        s = va_arg(ap, char *);        sprintf(tmp,s);        break;      default:        fprintf(stderr,		"Error, unsupported format supplied to mknb_code():\nn");	        exit(-1);        break;      }    }    format++;    strcat(outbuf,tmp);  }  va_end(ap);  if(mknb_fortran)    mknb_fortran_splitline(outbuf);  else    fprintf(mknb_output,outbuf);  fprintf(mknb_output,"\n");}  /* Prints an assignment. * This routine does proper indentation, and also supports the * same type of variable-argument lists as printf (both in * the left and right-hand side buffers), apart from field widths. * * a statement like mknb_assign("atom%d","data%d",3,5) will give * * atom3 = data5; * * * In contrast to mknb_code(), mknb_assign() appends a semicolon when the * language is not set to fortran. *  */voidmknb_assign(char *left, char *right, ...){  int i;  char *format;  char buf[4096],tmp[4096];  char outbuf[4096];  va_list ap;  int d;  double f;  char *s;    sprintf(outbuf,"%s",mknb_indent());   va_start(ap,right);    for(i=0;i<=1;i++) {    /* first we do the left buffer, then repeat everything for the right. */    if(i==0)      format=left;    else      format=right;        buf[0]='\0';    while(*format) {      if(*format!='%') 	      sprintf(tmp,"%c",*format);      else {        switch(*(++format)) {          case 'd': /* read an integer */            d = va_arg(ap, int);            sprintf(tmp,"%d",d);            break;          case 'f': /* read a (double precision) floating point number */            f = va_arg(ap, double);            sprintf(tmp,"%.16f",f);            break;          case 's': /* read a string */            s = va_arg(ap, char *);            sprintf(tmp,s);            break;          default:            fprintf(stderr,		    "Error, unsupported format supplied to mknb_assign()\n");            exit(-1);            break;        }      }      strcat(buf,tmp);      format++;    }    if(i==1 && !mknb_fortran)      strcat(buf,";");        sprintf(tmp,"%-16s",buf);    strcat(outbuf,tmp);        if(i==0)      strcat(outbuf," = ");  }  va_end(ap);  if(mknb_fortran)    mknb_fortran_splitline(outbuf);  else    fprintf(mknb_output,outbuf);    fprintf(mknb_output,"\n");}  /* Start a for loop and increase indentation.*/voidmknb_start_loop(char *lvar,char *from,char *to){    mknb_code("");    if(mknb_fortran)    {	    mknb_code("do %s=%s,%s",lvar,from,to);    }	else    {        mknb_code("for(%s=%s; (%s<%s); %s++)", lvar,from,lvar,to,lvar);        mknb_code("{");    }    mknb_indent_level++;}/* decrease indentation and close for loop */voidmknb_end_loop(void){    mknb_indent_level--;    if(mknb_fortran)        mknb_code("end do");    else        mknb_code("}");			mknb_code("");}voidmknb_start_if(char *cond){    mknb_code("");	    if(mknb_fortran)        mknb_code("if (%s) then",cond);    else	{        mknb_code("if(%s)", cond);        mknb_code("{");    }    mknb_indent_level++;}voidmknb_do_else(){    mknb_indent_level--;    if(mknb_fortran)        mknb_code("else");    else	{        mknb_code("}");        mknb_code("else");        mknb_code("{");    }    mknb_indent_level++;}voidmknb_end_if(void){    mknb_indent_level--;    if (mknb_fortran)        mknb_code("endif");    else        mknb_code("}");    mknb_code("");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -