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

📄 vstrbuild.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-1999  Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdarg.h>#include <stdio.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#include "tds.h"#include "replacements.h"TDS_RCSID(var, "$Id: vstrbuild.c,v 1.14 2007/10/16 15:12:23 freddy77 Exp $");struct string_linked_list{	char *str;	struct string_linked_list *next;};/* * XXX The magic use of \xFF is bletcherous, but I can't think of anything *     better right now. */static char *norm_fmt(const char *fmt, int fmtlen){	char *newfmt;	char *cp;	char skip = 0;	if (fmtlen == TDS_NULLTERM) {		fmtlen = strlen(fmt);	}	if ((newfmt = (char *) malloc(fmtlen + 1)) == NULL) {		return TDS_FAIL;	}	for (cp = newfmt; fmtlen > 0; fmtlen--, fmt++) {		switch (*fmt) {		case ',':		case ' ':			if (!skip) {				*cp++ = '\377';				skip = 1;			}			break;		default:			skip = 0;			*cp++ = *fmt;			break;		}	}	*cp = '\0';	return newfmt;}inttds_vstrbuild(char *buffer, int buflen, int *resultlen, char *text, int textlen, const char *formats, int formatlen, va_list ap){	char *newformat;	char *params;	char *token;	const char *sep = "\377";	char *lasts;	int tokcount = 0;	struct string_linked_list *head = NULL;	struct string_linked_list *item = NULL;	struct string_linked_list **tail = &head;	int i;	int state;	char **string_array = NULL;	int pnum = 0;	int pdigit;	char *paramp = NULL;	int rc = TDS_FAIL;	*resultlen = 0;	if (textlen == TDS_NULLTERM) {		textlen = strlen(text);	}	if ((newformat = norm_fmt(formats, formatlen)) == NULL) {		return TDS_FAIL;	}	if (vasprintf(&params, newformat, ap) < 0) {		free(newformat);		return TDS_FAIL;	}	free(newformat);	for (token = strtok_r(params, sep, &lasts); token != NULL; token = strtok_r(NULL, sep, &lasts)) {		if ((*tail = (struct string_linked_list *) malloc(sizeof(struct string_linked_list))) == NULL) {			goto out;		}		(*tail)->str = token;		(*tail)->next = NULL;		tail = &((*tail)->next);		tokcount++;	}	if ((string_array = (char **) malloc((tokcount + 1) * sizeof(char *))) == NULL) {		goto out;	}	for (item = head, i = 0; i < tokcount; item = item->next, i++) {		if (item == NULL) {			goto out;		}		string_array[i] = item->str;		while (*(string_array[i]) == ' ') {			string_array[i]++;		}	}#define COPYING 1#define CALCPARAM 2#define OUTPARAM 3	state = COPYING;	while ((buflen > 0) && (textlen > 0)) {		switch (state) {		case COPYING:			switch (*text) {			case '%':				state = CALCPARAM;				text++;				textlen--;				pnum = 0;				break;			default:				*buffer++ = *text++;				buflen--;				textlen--;				(*resultlen)++;				break;			}			break;		case CALCPARAM:			switch (*text) {			case '!':				if (pnum <= tokcount) {					paramp = string_array[pnum - 1];					state = OUTPARAM;				}				text++;				textlen--;				break;			default:				pdigit = *text++ - '0';				if ((pdigit >= 0) && (pdigit <= 9)) {					pnum *= 10;					pnum += pdigit;				}				textlen--;				break;			}			break;		case OUTPARAM:			switch (*paramp) {			case 0:				state = COPYING;				break;			default:				*buffer++ = *paramp++;				buflen--;				(*resultlen)++;			}			break;		default:			/* unknown state */			goto out;			break;		}	}	rc = TDS_SUCCEED;      out:	free(string_array);	for (item = head; item != NULL; item = head) {		head = head->next;		free(item);	}	free(params);	va_end(ap);	return rc;}

⌨️ 快捷键说明

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