블로그 이미지
안녕1999

카테고리

전체 (3067)
자바스크립트 (20)
안드로이드 (14)
WebGL (4)
변비 (17)
정치,경제 (35)
C언어,ARM (162)
컴퓨터(PC, Note Book, 윈.. (41)
전자회로, PCB (27)
유머,안웃긴,GIF,동영상 (118)
국부론60 (71)
모듈(PCB) (3)
건강 (2)
FreeCAD (25)
PADS (43)
퇴직,퇴사,구직,취업 활동 (3)
C# (86)
엑셀 (8)
워드 (0)
LabView (6)
레고 (30)
FPGA (0)
Total
Today
Yesterday

달력

« » 2024.5
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

공지사항

최근에 올라온 글

2015년에 유행했던 광고프로그램에 걸렸다.

멀 하다가 걸린거지?

은행계좌확인하려고 한것 뿐인데...


증상

- 구글 크롬 브라우져가 계속 오류로 꺼진다.

- IE창에서 광고가 나타난다.

- 작업관리자에 Plugin.exe가 3개 나타난다.

  죽여도 죽여도, 계속 나타남.




아래처럼 가짜 치료페이지가 나타났다.

해당 사이트 관련자 모두 잡아서 조사해야함...


19금 광고 포함.(좀 이쁘고 큰 사진으로...쿨럭...)



자가 치료방법

V3도 없고해서, 제어판에서 이상한거 몇개 지우고, 크롬 브라우져 삭제했다.

크롬 브라우져 지우니, 모든게 해결됨.

Posted by 안녕1999
, |

mini_file_system

C언어,ARM / 2016. 2. 1. 14:20

'C언어,ARM' 카테고리의 다른 글

ARM Cortex M0 - W7500 인터럽트  (0) 2016.03.07
CMSIS-DAP  (0) 2016.03.07
ARM Cortex M0 - GPIO  (0) 2016.03.07
Tightly Coupled Memory  (0) 2016.02.29
C언어 함수  (1) 2016.01.31
Posted by 안녕1999
, |

이건 너무 쉬워서, 큰 돈은 안됩니다만,

전국민이, 전세계사람들이 좀더 나은 삶을 살았으면 하는 생각입니다.

제조 가격은 500원 수준으로 예상합니다.

물론, 국내에서는 어렵습니다.

판매가는 1000원 예상합니다.


이 또한 제가 간이 작아서 시작을 못합니다. ㅎㅎ


관심있으신분 연락 바랍니다.

감사합니다.

Posted by 안녕1999
, |

지하로 고속도로를 파는것은 엄청난 돈이 들어갑니다.

산하나 터널 뚫는데만, 몇년이 걸립니다.

요즘에 1~2년이면 되더군요.

터널 뚫는 비용도 어마어마 한데, 수백 km의 고속도로는 어찌 뚫겠습니까? ㅎㅎ

그러나, 현재 고속도로의 교통체증을 보면, 뚫을 가치는 확실합니다.

지하 고속도로는 전국의 각지역을 1:1로 직통으로 연결이 가능합니다.

그냥 최소 100km 로 달리기만 하면 됩니다.

완공시, 예상 속도는 400 km  정도 되지 않을까 싶습니다.(근거 없는 추론)

하이퍼루프라는 시스템으로 시속 1000 km  이상도 가능하다고 합니다.

물론 제 머리속에는 하이퍼루프 기사가 나오기전부터, 계획에 다 들어 있었습니다.

그런데, 하이퍼루프에는 문제점이 있습니다. 그걸 어떻게 해결하느냐가 관건입니다.


어쨌든 지하 수백미터에서 암반을 뚫어서 고속도로를 만드는것은 수년이 아닌 수십년이 걸립니다.


어떻게 빨리, 저 비용으로 뚫을 것이냐?

이게 핵심입니다.


이것도, 제가 먹고살기 바쁘다보니, 또, 돈이 없다보니, 할 수 없는 일이 되가고 있습니다.

지하로 전국 도시를 1:1로 연결하는 고속도로 개통이 제 목표입니다.

물론, 이거 가지고 또 왈가왈부 하는 사람들 나옵니다.

안전이 어떻고, 지진나면 어쩔거냐, 부터, 도로에 구멍 생기면 어쩔거냐? 등등

물론, 그럴 가능성이 높습니다만,

이 계획은 지하 수십미터가 아니고, 수백미터 밑 암반에서 진행되어야 합니다.

더 궁금하시면 연락주세요.


터널 굴착 관련 업체에서 제 자리좀 만들어 주시면, 감사하겠습니다.

월급은 보통으로 주시고, 스톡옵션만 주세요. ㅎㅎ


관련 업체분들의 연락 기다리겠습니다.

감사합니다.


Posted by 안녕1999
, |

수년전 정부가 태양광에서 발전하는 전기가격을 높게 책정했을때는

수익성이 있었습니다. 그렇다고 큰 수익은 아닙니다.

하지만, 2016년 1월인 지금은 없다고 봅니다.

설치비만 수억이 들어가고,

예상대로 발전이 안되거나, 풍수해를 입을 경우, 막대한 피해를 고스란히 입게될 수 도 있습니다.

그러니 보험은 들어야 겠습니다.

수익이 생긴다고 해도, 투자비대비 큰수익은 아닐거라는것이 시장의 중론입니다.

왜냐면, 달려드는 사람이 없으니까요.(물어보는 사람은 많죠.)

할게 없으니, 또는 관련 사기꾼들이 유망하다고 꼬시니.... 해보는거죠.


기술적인 문제

===============

현재의 발전시스템으로는 매우 어렵다고 봅니다.

발전 효율을 2배이상 올려야 합니다.

투자비 대비 효율을 올려야 합니다.

1) 태양광 패널에 거울을 설치해서, 광량을 2배이상 높이는것입니다.

2) 태양추적 시스템

  물론 투자비가 엄청나게 불어납니다.

  추적시스템을 경제적으로 설계하고, 운영해야 합니다.

3) 송배전 시설 효율

   220 V로 출력한다면, 입력전압을 220V 보다 조금 높게 해서, 220 V 로 낮추어야

   가장 효율적입니다. 이또한 쉬운 문제는 아닙니다만, 제 머리속에는 그림이 있습니다. ㅎㅎ


위의 3가지만 잘하면, 확실히 남는 장사가 되겠네요.

저는 먹고 살기 바빠서, 돈이없어 못뛰어들고 있습니다만,

언젠가 기회가 되면, 사업을 구체화 시키고 싶네요.


관심이 있으신, 관련 업체분은 연락주세요.

물론 공짜로 다 털어 놓지 않습니다. ㅎㅎ


감사합니다.


Posted by 안녕1999
, |

FIFO

카테고리 없음 / 2016. 1. 31. 17:40

sFIFO.zip

머리속의 생각을 기록해보겠습니다.

Posted by 안녕1999
, |

C언어 함수

C언어,ARM / 2016. 1. 31. 01:42
#ifdef _DEBUG
#ifndef DEBUG_if_err
#define DEBUG_if_err(a)	if(a){on_err();}else{}
#endif
#include "windows.h"
void DEBUG_puts(char *s)
{
	OutputDebugString(s);
	OutputDebugString("\r\n");
}
void DEBUG_puts_int(char *s, int a)
{
	char buf[1024];
	sprintf(buf, "%s=%d", s, a);
	DEBUG_puts(buf);
}
void DEBUG_puts_int_str(char *s, int a,char *s2)
{
	char buf[1024];
	sprintf(buf, "%s=%d%s", s, a, s2);
	DEBUG_puts(buf);
}
void DEBUG_puts_str(char *s, char *a)
{
	char buf[1024];
	sprintf(buf, "%s=\"%s\"", s, a);
	DEBUG_puts(buf);
}
void DEBUG_puts_char_str(char *s, char c, char *a)
{
	char buf[1024];
	sprintf(buf, "%s=%c%s", s, c,a);
	DEBUG_puts(buf);
}
void DEBUG_puts_float(char *s, float a)
{
	char buf[1024];
	sprintf(buf, "%s=%f", s, a);
	DEBUG_puts(buf);
}
void DEBUG_puts_double(char *s, double a)
{
	char buf[1024];
	sprintf(buf, "%s=%f", s, a);
	DEBUG_puts(buf);
}
void on_err()
{
	DEBUG_puts("ERR : on_err");
}
#else
#ifndef DEBUG_if_err
#define DEBUG_if_err(a)
#endif
#ifndef DEBUG_puts
#define DEBUG_puts(a)
#define DEBUG_puts_int(s,a)
#define DEBUG_puts_str(s,a)
#define DEBUG_puts_float(s,a)
#endif
#endif


int isspace(char a)//isspace에서 큰값(한글 일부)을 넣으면 오류발생하여 추가
{
	int ret = 0;
	switch (a)
	{
	case ' ':case '\t':case '\r':case '\n':
		ret = 1;
		break;
	default:
		break;
	}
	return ret;
}

char *skip_space(char *s)
{
	char a;
	while (s)
	{
		a = *s;
		if (strchr(" \t\r\n", a) == 0)
		{
			break;
		}
		else
		{
			s++;
		}
	}
	return s;
}
char *del_space_all(char *s,char *out)
{
	char a,*w=out;
	//DEBUG_puts_str("del_space_all()", s);
	if (s)
	{
		while (1)
		{
			a = *s;
			if (a == 0)
			{
				break;
			}
			else
			{
				switch (a)
				{
				case ' ':case '\r':case '\n':case '\t':
					//del
					break;
				default:
					*w = a;
					w++;
					break;
				}
			}
			s++;
		}
	}
	*w = 0;
	//DEBUG_puts_str("del_space_all() out", out);
	return w;
}
char *skip_space_rev(char *str,char *pNow)//ret=뒷쪽의 첫 스페이스 문자
{
	while (pNow > str)
	{
		if (isspace(*pNow))
		{
			pNow--;
		}
		else
		{
			pNow++;
			break;
		}
	}
	return pNow;
}

//+,- e지수, 소수점 숫자 문자열 처음 찾기(strtof)
//pNow는 앞쪽 숫자의 일부여야한다.
char *find_number_str_start_rev(char *str, char *pNow,int *err)
{
	char a; int e_cnt = 0, e_num_cnt=0,dot_cnt=0,pluse_cnt=0, minus_cnt=0, pluse_minus_cnt = 0 ;
	*err = 0;
	if (str == pNow)
	{
		//pNow = str;
	}
	else
	{
		while (isspace(*pNow))
		{
			pNow--;
		}
		while (pNow >= str)
		{
			a = *pNow;
			if (isdigit(a))
			{
				//ok
				if (e_cnt == 0)
				{
					//e 지수 뒷쪽 숫자
					e_num_cnt++;
				}
				else
				{
					//e 지수 앞쪽 숫자
				}
			}
			else if ((a == '-') || (a == '+'))
			{
				if (pNow != str)
				{
					if ((pNow[-1] == 'e') || (pNow[-1] == 'E'))
					{
						//e지수.계속
						pNow--;
						e_cnt++;
					}
					else if (isdigit(pNow[-1]))
					{
						//앞은 숫자. 부호는 남겨놓아야한다.
						pNow++;
						break;
					}
					else
					{
						//e지수 아님.부호로 처리
						break;
					}
				}
				else
				{
					//첫문자.부호
					break;
				}
			}
			else if ((a == 'e') || (a == 'E'))
			{
				e_cnt++;
				if (e_cnt == 1)
				{
					//ok
					pluse_minus_cnt = 0;
					minus_cnt = 0;
					pluse_cnt = 0;
				}
				else
				{
					//err. e가 2번이상 나옴
					*err = 1;
					DEBUG_puts_str("ERR : 숫자 에러. 지수문자'e'가 2번이상 나옴", str);
					break;
				}
			}
			else if (a == '.')
			{
				if (dot_cnt == 0)
				{
					//ok
					dot_cnt = 1;
				}
				else
				{
					//.이 2번이상 나옴
					*err = 1;
					DEBUG_puts_str("ERR : 숫자 에러. '.'이 2번이상 나옴", str);
					break;
				}
			}
			else if (strchr(" \t\r\n", a) == 0)
			{
				//space
				pNow++;
				break;
			}
			else
			{
				pNow++;
				break;
			}
			if (pNow > str)
			{
				pNow--;
			}
			else
			{ 
				break;
			}
		}
	}
	DEBUG_if_err(pNow < str);
	return pNow;
}
char *find_number_str_end(char *str, int *err)//숫자 문자열의 마지막 찾기
{
	char a,*pNow= str; int e_cnt = 0, e_num_cnt = 0, dot_cnt = 0;
	*err = 0;
	while (1)
	{
		a = *pNow;
		if (a == 0)
		{
			break;
		}
		else
		{
			if (isdigit(a))
			{
				//ok
				if (e_cnt == 0)
				{
					//e 지수 앞쪽 숫자
					e_num_cnt++;
				}
				else
				{
					//e 지수 뒷쪽 숫자
				}
			}
			else if (strchr(" \t\r\n", a) == 0)
			{
				//space
				break;
			}
			else if ((a == 'e') || (a == 'E'))
			{
				if (e_cnt == 0)
				{
					//ok
					e_cnt = 1;
				}
				else
				{
					//err. e가 2번이상 나옴
					*err = 1;
					DEBUG_puts_str("ERR : 숫자 에러. 지수문자'e'가 2번이상 나옴", str);
					break;
				}
			}
			else if (a == '.')
			{
				if (dot_cnt == 0)
				{
					//ok
					dot_cnt = 1;
				}
				else
				{
					//.이 2번이상 나옴
					*err = 1;
					DEBUG_puts_str("ERR : 숫자 에러. '.'이 2번이상 나옴", str);
					break;
				}
			}
			else
			{
				break;
			}
		}
		pNow++;
	}
	return pNow;
}
void strcpy_wc(wchar_t *buf, char *s)
{
	int nLen = MultiByteToWideChar(CP_ACP,
		0,
		s, -1,
		NULL,
		NULL);

	MultiByteToWideChar(CP_ACP,
		0,
		s, -1,
		buf,
		nLen);
}
void strcpy_cw(char *buf, wchar_t *s)//max=1024
{
	if (buf)if (s)
	{
		WideCharToMultiByte(CP_ACP,
			0,
			s, -1,
			buf, 1024,
			NULL,
			NULL);
	}
}
void strcat_wc(wchar_t *buf, char *s)
{
	if (buf)if (s)
	{
		while (*buf)buf++;
		int nLen = MultiByteToWideChar(CP_ACP,
			0,
			s, -1,
			NULL,
			NULL);

		MultiByteToWideChar(CP_ACP,
			0,
			s, -1,
			buf,
			nLen);
	}
}
void strcat_cw(char *buf, wchar_t *s)//max=1024
{
	if (buf)if (s)
	{
		WideCharToMultiByte(CP_ACP,
			0,
			s, -1,
			buf, 1024,
			NULL,
			NULL);
	}
}

int is_all_spcace(char *s)
{
	int bSpace = 1;
	while (*s)
	{
		if (isspace(*s))
		{
			//bSpace = 1;
		}
		else
		{
			bSpace = 0;
			break;
		}
		s++;
	}
	return bSpace;
}
char *get_line(char *str, char *buf)//\r\n포함
{
	char a;
	while (1)
	{
		a = *str;
		*buf = a;
		if (a == 0)break;
		if (a == '\n')
		{
			str++;
			break;
		}
		else
		{
			buf++;
			str++;
		}
	}
	*buf = 0;
	return str;
}

char *skip_empty_1line(char *s)//1줄만 skip
{
	char *p = s,*p_old=s;
	while (*s)
	{
		if (isspace(*s))
		{
			if (*s == '\n')
			{
				s++;//1줄만 skip
				break;
			}
			else
			{
				s++;
			}
		}
		else
		{
			s = p_old;//빈줄이 아닐때, 앞부분 공백문자들 삭제 안함
			break;
		}
	}
	return s;
}
char *skip_empty_line_all(char *s)//빈줄 모두 skip
{
	char *p;
	while (*s)
	{
		p = skip_empty_1line(s);
		if (p != s)
		{
			s = p;
		}
		else
		{
			s = p;
			break;
		}
	}
	return s;
}

//spilt문자로 구분된 문자열에서, i0번째 문자열의 시작주소를 얻음
char *spilt_str_get_i(char *s, int i0,char *buf,char spilt)
{
	char *p = s, *pf;
	*buf = 0;
	while(*p)
	{
		if (i0 == 0)
		{
			break;
		}
		else
		{
			pf = strchr(p, spilt);
			if (pf)
			{
				p = pf + 1;
				i0--;
			}
			else
			{
				//더이상 없음
				p = 0;
				break;
			}
		}
	}
	if (p)
	{
		p=strcpy_while_not_char(p, buf, spilt);
	}
	else
	{

	}
	return p;
}
int spilt_str_get_i_int(char *s, int i0, char spilt)
{
	char buf[1024];
	spilt_str_get_i(s, i0, buf, spilt);
	return atoi(buf);
}
double spilt_str_get_i_double(char *s, int i0, char spilt)
{
	char buf[1024];
	spilt_str_get_i(s, i0, buf, spilt);
	return ATOF(buf);
}
//탭문자로 구분된 문자열에서, i0번째 문자열의 시작주소를 얻음
char *tab_str_get_i(char *s, int i0, char *buf)
{
	return spilt_str_get_i(s, i0,buf, '\t');
}

char *skip_tab(char *p, int n)
{
	if (p)
	{
		while (n > 0)
		{
			p = strchr(p, '\t');
			if (p == 0)break;
			p++;
			n--;
		}
	}
	else
	{
		//NULL
	}
	return p;
}
char *strcpy_while_not_char(char *s, char *buf, char c)
{
	while (*s)
	{
		if (*s == c)
		{
			s++;
			break;
		}
		else
		{
			*buf = *s;
			buf++;
			s++;
		}
	}
	*buf = 0;
	return s;
}
char *strcpy_while_not_chars(char *s, char *buf, char *c)
{
	char a;
	while (*s)
	{
		a = *s;
		s++;
		*buf = a;
		if (strchr(c,a))
		{
			
			break;
		}
		else
		{
			buf++;
		}
	}
	*buf = 0;
	return s;
}
char *strcpy_while_not_chars_num(char *s, char *buf, char *c)//+,-를 가지는 숫자인 경우,+,-도 포함한다.
{
	char a;
	if (s)
	{
		s = skip_space(s);

		//첫번째 문자가 c에 있는 문자라면 포함된다.
		if (strchr(c, *s))
		{
			*buf = *s;
			buf++;
			s++;
		}
		else
		{

		}

		while (*s)
		{
			a = *s;
			*buf = a;
			if (strchr(c, a))
			{
				//2번째 문자인 경우, 다음번에 넣는다.
				//s++;
				break;
			}
			else
			{
				buf++;
				s++;
			}
		}
	}
	else
	{

	}
	*buf = 0;
	return s;
}
int str_cnt(char *str, char *a)
{
	int cnt = 0,len_a;
	char *p=str;
	if (p)
	{
		if (a)
		{
			len_a = strlen(a);
			while (*p)
			{
				p = strstr(p, a);
				if (p == 0)
				{
					break;
				}
				else
				{
					cnt++;
					p += len_a;
				}
			}
		}
		else
		{ }
	}
	else
	{ }
	return cnt;
}
int str_change(char *str, char *a, char *b, char *out_buf)//str==out_buf인 경우, 크기가 증가하면 에러 발생
{
	int cnt = 0, len, len_a;
	char *p, *pend,*pfree=0;
	if (str)
	{
		p = strstr(str, a);
		if (p)
		{
			/*DEBUG_puts("@str");
			DEBUG_puts(str);
			DEBUG_puts("@p");
			DEBUG_puts(p);
			DEBUG_puts("@a");
			DEBUG_puts(a);*/

			len = p - str;
			len_a = strlen(a);
			pend = p + len_a;

			if (((int)strlen(b)) > len_a)
			{
				pend = strdup(pend);
				pfree = pend;
			}
			else
			{

			}

			strncpy(out_buf, str, len);
			strcpy(out_buf+ len, b);
			strcat(out_buf, pend);

			cnt = 1;
			free(pfree);
		}
		else
		{
			if(out_buf!= str)
			{
				strcpy(out_buf, str);
			}
			else
			{
				//동일한 버퍼임
			}
		}
	}
	else
	{
		if (out_buf)
		{
			*out_buf = 0;
		}
		else
		{

		}
	}
	return cnt;
}
int str_change_all(char *str, char *a, char *b, char *out_buf)
{
	int cnt = 0;
	while (str_change(str,a,b,out_buf))
	{
		str = out_buf;
		cnt++;
	}
	return cnt;
}
char *strchr_rev(char *s, char *pnow, char find)
{
	char *p = 0;
	while (pnow >= s)
	{
		if (*pnow == find)
		{
			p = pnow;
			break;
		}
		else
		{
			pnow--;
		}
	}
	return p;
}
char *strchr_first(char *s, char *find)//find문자들 중에 첫번째 나오는 문자를 찾는다.
{
	char *ret = 0;
	while (*s)
	{
		if (strchr(find, *s))
		{
			//found
			ret = s;
			break;
		}
		else
		{
			//not found
		}
		s++;
	}
	return ret;
}
char *strdup1024(char *s)//할당된 메모리에 문자열을 추가할 경우에만 사용
{
	int len;
	char *p = 0;
	if (s)
	{
		len = strlen(s) + 1024;
		p = (char*)malloc(len);
		strcpy(p, s);
	}
	else
	{

	}
	return p;
}

int double_is_EQ(double a, double b)
{
	/*부동소수점 계산 오류로 인해, 소수점 5자리이하가 int형변환 해도 계속 1씩 틀리는 문제가 있음.
	int ia, ib;
	ia = (int)(a * 10000);
	ib = (int)(b * 10000);
	return ia == ib;*/
	char bufa[32], bufb[32];

	//계산순서에 따라, 소수점 6째자리숫자가 다를 수 도 있다.(부동소수점 오류) "/1000"해줌
	//sprintf(bufa, "%f", a);
	//sprintf(bufb, "%f", b);

	sprintf(bufa, "%f", a / 1000);
	sprintf(bufb, "%f", b / 1000);
	return strcmp(bufa, bufb) == 0;
}




char *ToUpperstr(char *s,char *buf)
{
	while (*s)
	{
		*buf = toupper(*s);
		s++;
		buf++;
	}
	*buf = 0;
	return s;
}
char *stristr(char *s,char *find)
{
	char *p;
	p = strstr(s, find);
	if (p == 0)
	{
		char *s2, *find2;
		s2 = strdup(s);
		find2 = strdup(find);

		ToUpperstr(s2, s2);
		ToUpperstr(find2, find2);
		p = strstr(s2, find2);
		if (p)
		{
			p = s + (p - s2);
		}
		else
		{
		}
		
		free(s2);
		free(find2);
	}
	else
	{

	}
	return p;
}
char *trim(char *s,char *buf)
{
	char a,*p;
	s = skip_space(s);
	if (s)
	{
		strcpy(buf, s);
		p = buf + strlen(buf)-1;
		while (p>buf)
		{
			a = *p;
			if (a == 0)
			{
				break;
			}
			else
			{
				if (isspace(a))
				{
					//skip
					*p = 0;
				}
				else
				{
					break;
				}
			}
			p--;
		}
	}
	else
	{
		*buf = 0;
	}
	return buf;
}
char *strcpy_if_not_same(char *dst, char *src)
{
	char *ret = 0;
	if (dst != src)
	{
		ret=strcpy(dst, src);
	}
	else
	{
		ret = dst;
	}
	return ret;
}
double ATOF(char *s)//지수 e를 포함하는 문자열을 double로 변환
{
	char *pend;
	return strtof(s, &pend);
}
char *get_brace_str_out(char *s, char strat, char end, s_get_brace_str *pret)//괄호 안쪽 문자열 얻기(중복괄호 허용)
{
	char *p,*ps,*pe,a,*pfree;
	int len, strat_cnt;
	memset(pret, 0, sizeof(s_get_brace_str));
	p = strchr(s, strat);
	if (p)
	{
		ps = p+1;
		while (1)
		{
			a = *p;
			if (a == 0)
			{
				break;
			}
			else
			{
				if (a == strat)
				{
					strat_cnt++;
				}
				else if (a == end)
				{
					strat_cnt--;
					if (strat_cnt == 1)
					{
						//ok
						pe = p-1;
						len = pe - ps;
						pfree= (char*)malloc(len + 1);
						if (pfree)
						{
							strncpy(pfree, p, len);
							pfree[len] = 0;

							//ok
							pret->len = len;
							pret->ps = ps;
							pret->pe = pe;
							pret->pfree = pfree;
							break;
						}
						else
						{
							//err
						}
						break;
					}
					else
					{
						//계속
					}
				}
			}
			p++;
		}
	}
	else
	{

	}
	return p;
}
//괄호 안쪽 문자열 얻기(중복괄호 허용. 안쪽 괄호문자.중첩된 괄호는 없다.)
char *get_brace_str_in(char *s, char strat, char end, s_get_brace_str *pret)
{
	char *p, *ps, *pe, *pfree;
	int len;
	memset(pret, 0, sizeof(s_get_brace_str));
	p = strrchr(s, strat);
	if (p)
	{
		ps = p ;
		pe =strchr(p + 1, end);
		if(pe)
		{
			//ok
			len = pe+1 - ps;
			pfree = (char*)malloc(len + 1);
			if (pfree)
			{
				strncpy(pfree, p, len);
				pfree[len] = 0;

				//ok
				pret->len = len;
				pret->ps = ps;
				pret->pe = pe;
				pret->pfree = pfree;
			}
			else
			{
				//err
			}
		}
		else
		{ }
	}
	else
	{

	}
	return p;
}
void trim_and_del_str_mark(char *s)//문자열 따옴표 제거
{
	char *p = s;
	trim(p, p);
	if (*p == '\"')
	{
		strcpy(s, p + 1);
		p = strrchr(s, '\"');
		if (p)
		{
			strcpy(p, p + 1);
		}
		else
		{
		}
	}
	else
	{
	}
	trim(s,s);
}
void del_str_mark(char *s)//문자열 따옴표 제거
{
	char *p = s;
	p = strchr(s, '\"');
	if (p)
	{
		strcpy(p, p + 1);
	}
	else
	{ }
	p = strrchr(s, '\"');
	if (p)
	{
		strcpy(p, p + 1);
	}
	else
	{
	}
}
static char *bht = "0123456789ABCDEF";
char *BinToHEX(void *pbin, int len, char *buf)
{
	byte1 *p = (byte1*)pbin, a;
	char *pbuf = buf;
	while (len)
	{
		a = *p;
		pbuf[0] = bht[a >> 4];
		pbuf[1] = bht[a & 0x0f];
		pbuf[2] = ' ';
		pbuf += 3;
		len--;
		p++;
	}
	*pbuf = 0;
	return pbuf;
}
int HEX1_to_bin(char a, byte1 *b)
{
	int bok = 1;
	if (('0' <= a) && (a <= '9'))
	{
		*b = a - '0';
		//bok=1;
	}
	else if (('A' <= a) && (a <= 'F'))
	{
		*b = a - 'A' + 10;
		//bok=1;
	}
	else if (('a' <= a) && (a <= 'f'))
	{
		*b = a - 'a' + 10;
		//bok=1;
	}
	else
	{
		bok = 0;
	}
	return bok;
}
char *HEX_str_to_bin(char *hex_str, byte1 *buf, int *len)
{
	int rlen = 0;
	byte1 b, s = 0, cnt = 0, temp;
	char c, *p;
	while (1)
	{
		c = *hex_str;
		if (c == 0)break;
		if (c == '\n')
		{
			hex_str++;
			break;
		}
		else if (c == ' ')
		{
			//next
			if (cnt)
			{
				*buf = b;
				buf++;
				//b=0;
				rlen++;
				cnt = 0;
			}
			else
			{
				//skip
			}
		}
		else if (c == '\t')
		{
			//next
			if (cnt)
			{
				*buf = b;
				buf++;
				//b=0;
				rlen++;
				cnt = 0;
			}
			else
			{
				//skip
			}
		}
		else if (c == ';')//주석문
		{
			p = strchr(hex_str + 1, '\n');
			if (p)
			{
				hex_str = p + 1;
			}
			else
			{
				hex_str = 0;
				break;
			}
		}
		else
		{
			if (HEX1_to_bin(c, &temp) == 0)
			{
				break;
			}
			else
			{
				//ok
				if (cnt == 0)
				{
					b = temp;
					cnt++;
				}
				else
				{
					*buf = (byte1)((b << 4) | temp);
					//b=0;
					buf++;
					rlen++;
					cnt = 0;//reset
				}
			}
		}
		hex_str++;
	}
	if (cnt)
	{
		*buf = b;
		buf++;
		//b=0;
		rlen++;
		cnt = 0;
	}
	*len = rlen;
	return hex_str;
}
int str_has_alphabet(char *s)
{
	int ret = 0;
	while (*s)
	{
		if (isalpha(*s))
		{
			ret = 1;
			break;
		}
		else
		{
			s++;
		}
	}
	return ret;
}








wchar_t *strrchr(wchar_t *s,wchar_t ch) { if(s==0)return 0; if(*s==0)return 0; return wcsrchr(s,ch); } wchar_t *strcpy(wchar_t *dest,wchar_t *src) { wchar_t *pd=dest,*p=src; if(pd==0)return 0; if(p) { while(*p) { *pd=*p; p++; pd++; } } *pd=0; return pd; } int strlen(const wchar_t *s) { if(s==0)return 0; if(*s==0)return 0; return wcslen(s); } int _unlink(wchar_t *file) { return _wunlink(file); } inline FILE *fopen(wchar_t *filename,wchar_t *mode) { return _wfopen(filename,mode); } WIN32_FIND_DATA *GetFileInfo(TCHAR *file,WIN32_FIND_DATA *fd) { __int64 len=0;HANDLE h;WIN32_FIND_DATA *ret=0; h=FindFirstFile(file,fd); if((h==INVALID_HANDLE_VALUE) && (::GetLastError()==ERROR_FILE_NOT_FOUND)) { //CD롬에서 일부 파일이 복사가 안되는 문제로 추가 //err } else { ret=fd;//ok } if(h!=INVALID_HANDLE_VALUE) { FindClose(h); } return ret; } __int64 GetFileSize(TCHAR *file) { __int64 len=0;WIN32_FIND_DATA fd; if(GetFileInfo(file,&fd)) { len=(__int64)fd.nFileSizeHigh*(__int64)fd.nFileSizeLow; } return len; } void FILETIME_to_SYSTEMTIME(FILETIME *ft,SYSTEMTIME *st) { SYSTEMTIME ust; FileTimeToSystemTime(ft,&ust); SystemTimeToTzSpecificLocalTime(0,&ust,st);//파일은 Localtime사용하지 말라 }

src.zip


#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "Lib.h"
#include "string.h"
#pragma warning(disable:4996)

void str_cal_change_all_meanless_str(char *s, char *buf);//의미없는 문자들을 제거한다.
char *ftoa(double v, char *buf)
{
	sprintf(buf, "%f", v);
	//불필요한 소수점 제거
	str_change_all(buf, ".000000", "", buf);
	return buf;
}
void double_to_str_add_str(char *buf,double b,char *padd)//double을 문자열로 바꾸고, 불필요한 소수점이하 0을 제거, 문자열 추가
{
	char *pfree = 0;
	//buf가 문자열이고, padd가 문자열의 뒷부분인 경우. 겹쳐쓰기가 될 수 있다.
	if ((padd >= buf) && ((padd - buf) < 16))//부동소수점 문자열 길이
	{
		padd = strdup1024(padd);//문자열을 추가할 여분의 버퍼
		pfree = padd;
	}
	else
	{
	}
	
	//sprintf(buf, "%f", b);
	//불필요한 소수점 제거
	//str_change_all(buf, ".000000", "", buf);
	ftoa(b, buf);

	strcat(buf, padd);
	if (pfree)
	{
		free(pfree);
	}

	str_cal_change_all_meanless_str(buf, buf);//의미없는 문자들을 제거한다.
}


int function_to_str(char *str, char *buf);
double str_to_double(char *s)//변수, 함수가 들어 있는 문자열을 double로 변환
{
	DEBUG_puts("작성중...");
	return atof(s);
}

//치환할 변수,함수,괄호가 없는 문자열에 대해서 사칙연산 수행
double no_variable_no_brace_str_calculation(char *str)
{
	double result = 0, a, b;
	int err = 0;
	char *p, op, *pa, *pend, buf[64];
	if (str)
	{
		/*효과가 별로 없다. if ((strchr(str, '+') == 0) && 
			(strchr(str, '-') == 0) && 
			(strchr(str, '*') == 0) && 
			(strchr(str, '/') == 0) && 
			(strchr(str, '%') == 0))
		{
			//연산자가 없다.
			result = atof(buf);//"+ 2.0"은 0이 된다.
		}
		else*/
		{
			str = strdup1024(str);//짧은 문자열 할당후 긴문장을 쓰는 경우 에러
			//del_space_all(str, str);
			str_cal_change_all_meanless_str(str, str);//의미없는 문자들을 제거한다.

			DEBUG_if_err(strchr(str, '{'));
			DEBUG_if_err(strchr(str, '}'));
			DEBUG_if_err(strchr(str, '('));
			DEBUG_if_err(strchr(str, ')'));
			//곱셈,나눗셈,나머지연산 먼져 수행.빠른것 부터 계산
			while (1)
			{
				DEBUG_puts_str("str", str);
				p = strchr_first(str, "*/%");
				if (p)
				{
					op = *p;
					*p = 0;
					pa = find_number_str_start_rev(str, p - 1, &err);
					if (err == 0)
					{
						a = strtof(pa, &pend);
						b = strtof(p + 1, &pend);
						switch (op)
						{
						case '*':
							result = a * b;
							break;
						case '/':
							if (b == 0)
							{
								b = 0.00000000000001f;
							}
							else
							{

							}
							result = a / b;
							break;
						case '%':
							result = ((int)a) % ((int)b);
							break;
						default:
							//err
							on_err();
							break;
						}
						double_to_str_add_str(pa, result, pend);//double을 문자열로 바꾸고, 불필요한 소수점이하 0을 제거, 문자열 추가
					}
					else
					{
						//err
						on_err();
						break;
					}

				}
				else
				{
					break;
				}
			}
			
			str_cal_change_all_meanless_str(str, str);//의미없는 문자들을 제거한다.

			result = 0;//str안에 값이 들어 있다.
			//첫번째 +/-가 연산자라고 보기는 어렵다.
			//+/-로 문자열을 나누고, 각 숫자를 모두 합한다.
			p = str;
			while (*p)
			{
				p = strcpy_while_not_chars_num(p, buf, "+- ");
				result += atof(buf);//"+ 2.0"은 0이 된다.
			}
			free(str);
		}
	}
	else
	{
	}
	return result;
}

//str은 {...{..(...)...}...}...
//{},()가 있는 연산식 계산.중첩 허용
double no_variable_str_calculation_with_brace(char *str)
{
	double ret=0,a=0,b = 0;
	char *pb, *pc, *p;// , *pfree = 0;
	p = str;
	if (str)
	{
		DEBUG_puts_str("no_variable_str_calculation_with_brace()", str);
		if (*str)
		{
			//문자열을 {}또는 ()를 기준으로 3개로 나누어 계산한다.
			//예) A{B}C
			//{}먼져 처리해야한다.
			//{..{..}..}...{..{..}..}

			//{}처리
			p = str;//p = pfree;
			//{}괄호처리
			while (*p)
			{
				DEBUG_puts_str("\r\nno_variable_str_calculation_with_brace()", str);
				pb = strrchr(p, '{');//마지막
				if (pb)
				{
					*pb = 0;
					pc = strchr(pb+1, '}');//첫번째
					if (pc == 0)
					{
						//마지막 괄호 없음. 끝까지 모두 계산
						pc = "";
					}
					else
					{
						*pc = 0;
						pc++;
					}
					b = no_variable_str_calculation_with_brace(pb + 1);//{} 계산

					double_to_str_add_str(pb, b, pc);//double을 문자열로 바꾸고, 불필요한 소수점이하 0을 제거, 문자열 추가
				}
				else
				{
					//{}없음
					break;
				}
			}

			//{}괄호 없음
			//()괄호처리
			while(*p)
			{
				DEBUG_puts_str("\r\nno_variable_str_calculation_with_brace()", str);
				pb = strrchr(p, '(');
				if (pb)
				{
					*pb = 0;
					pc = strchr(pb+1, ')');
					if (pc == 0)
					{
						//마지막 괄호 없음. 끝까지 모두 계산
						pc = "";
					}
					else
					{
						*pc = 0;
						pc++;
					}
					b = no_variable_str_calculation_with_brace(pb + 1);//() 계산
					double_to_str_add_str(pb, b, pc);
				}
				else
				{
					//()괄호 없음
					break;
				}
			}
			ret = no_variable_no_brace_str_calculation(p);//모든 식 계산
			//free(pfree);
		}
		else
		{
			//""
		}
	}
	else
	{
		//NULL
	}
	DEBUG_puts_double("ret", ret);
	return ret;
}
void variable_to_str(char *s, char *buf);//변수를 변수값문자열로 변환
void str_cal_change_all_meanless_str(char *s, char *buf)//의미없는 문자들을 제거한다.
{
	del_space_all(s, buf);//s = skip_space(s);
	if (strlen(buf) > 2)
	{
		str_change_all(buf, "--", "+", buf);
		str_change_all(buf, "+-", "-", buf);

		str_change_all(buf, "++", "+", buf);
		str_change_all(buf, "-+", "-", buf);
		str_change_all(buf, "*+", "*", buf);
		str_change_all(buf, "/+", "/", buf);
		str_change_all(buf, "%+", "%", buf);

		str_change_all(buf, "E+", "E", buf);
		str_change_all(buf, "e+", "e", buf);

		str_change_all(buf, "(+", "(", buf);
		str_change_all(buf, "[+", "[", buf);
		str_change_all(buf, "{+", "{", buf);
	}
	else
	{

	}
}
//괄호, 변수, 함수를 포함하는 사칙연산 연산식을 계산한다
double str_calculation_with_brace_func_variable(char *s)
{
	char buf[1024], buf2[1024];
	//함수의()와 산술식의 ()를 구분해야한다.
	//함수의()를 먼져 계산
	str_cal_change_all_meanless_str(s, buf2);

	s = buf2;
	variable_to_str(s, buf);//변수를 변수값문자열로 변환
	//식은 사칙연산이나 함수를 포함할 수 있습니다.
	//함수를 결과값으로 변환합니다.
	function_to_str(buf, buf2);

	//괄호를 포함하는 식 계산
	return no_variable_str_calculation_with_brace(buf2);
}



#ifdef _DEBUG
class DEBUG_test_cal
{
public:
	void test1()
	{
		sStr_double a[] = {
			//문제	정답
			//나눗셈의 분자나 분모중 하나는 실수여야한다.
			{" (  + 11 )   +  (  - 2 )  ",	 (+11) + (-2)  },
			{" (  + 12 )   -  (  + 9 )  ",	 (+12) - (+9)  },
			{" (  + 7 )   *  (  - 8 )  ",	 (+7)   *  (-8)  },
			{" (  + 7 )   *  (  - 2 )  ",	 (+7)   *  (-2)  },
			{" (  - 10 )   +  (  - 10 )  ",	 (-10) + (-10)  },
			{" (  - 4 )   *  (  - 14 )  ",	 (-4)   *  (-14)  },
			{" (  - 13 )   +  (  - 4 )  ",	 (-13) + (-4)  },
			{" (  + 7 )   +  (  - 2 )  ",	 (+7) + (-2)  },
			{" (  + 14 )  / (  - 9 )  ",	 (+14) / (-9.0f)  },
			{" (  - 14 )   *  (  - 14 )  ",	 (-14)   *  (-14)  },

			{" (  + 11 )   +  ( -2 )  ",	 (+11) + (-2)  },
			{" (  + 12 )  - (  + 9 )  ",	 (+12) - (+9)  },
			{" (  + 7 )  * ( -8 )  ",	 (+7)  * (-8)  },
			{" (  + 7 )  * ( -2 )  ",	 (+7)  * (-2)  },
			{" ( -10 )   +  ( -10 )  ",	 (-10) + (-10)  },
			{" ( -4 )  * ( -14 )  ",	 (-4)  * (-14)  },
			{" ( -13 )   +  ( -4 )  ",	 (-13) + (-4)  },
			{" (  + 7 )   +  ( -2 )  ",	 (+7) + (-2)  },
			{" (  + 14 )  / ( -9 )  ",	 (+14) / (-9.0f)  },
			{" ( -14 )  * ( -14 )  ",	 (-14)  * (-14)  },

			{" ( +11 )  + ( -2 )  ",	 (+11) + (-2)  },
			{" ( +12 )  - ( +9 )  ",	 (+12) - (+9)  },
			{" ( +7 )  * ( -8 )  ",	 (+7)  * (-8)  },
			{" ( +7 )  * ( -2 )  ",	 (+7)  * (-2)  },
			{" ( -10 )  + ( -10 )  ",	 (-10) + (-10)  },
			{" ( -4 )  * ( -14 )  ",	 (-4)  * (-14)  },
			{" ( -13 )  + ( -4 )  ",	 (-13) + (-4)  },
			{" ( +7 )  + ( -2 )  ",	 (+7) + (-2)  },
			{" ( +14 )  / ( -9 )  ",	 (+14) / (-9.0f)  },
			{" ( -14 )  * ( -14 )  ",	 (-14)  * (-14)  },

			{"(+11)+(-2)",	(+11) + (-2)},
			{"(+12)-(+9)",	(+12) - (+9)},
			{"(+7)*(-8)",	(+7)*(-8)},
			{"(+7)*(-2)",	(+7)*(-2)},
			{"(-10)+(-10)",	(-10) + (-10)},
			{"(-4)*(-14)",	(-4)*(-14)},
			{"(-13)+(-4)",	(-13) + (-4)},
			{"(+7)+(-2)",	(+7) + (-2)},
			{"(+14)/(-9)",	(+14) / (-9.0f)},
			{"(-14)*(-14)",	(-14)*(-14)},


			{"(+11)+(-2)*(+12)-(+9)",	(+11) + (-2)*(+12) - (+9)},
			{"(+12)-(+9)/(+7)*(-8)",	(+12) - (+9) / (+7.0f)*(-8.0f)},
			{"(+7)*(-8)*(+7)*(-2)",		(+7)*(-8)*(+7)*(-2)},
			{"(+7)*(-2)/(-10)+(-10)",	(+7)*(-2) / (-10.0f) + (-10)},
			{"(-10)+(-10)-(-4)*(-14)",	(-10) + (-10) - (-4)*(-14)},
			{"(-4)*(-14)+(-13)+(-4)",	(-4)*(-14) + (-13) + (-4)},
			{"(-13)+(-4)*(+14)/(-9)/(+7)+(-2)",	(-13) + (-4)*(+14) / (-9.0f) / (+7.0f) + (-2)},
			{"(-14)*(-14)+(+14) / (-9)-(+7) + (-2)",	(-14)*(-14) + (+14) / (-9.0f) - (+7) + (-2)},

			{"+11+-2*+12-+9",	+11 + -2 * +12 - +9},
			{"+12-+9/+7*-8",	+12 - +9 / +7.0f*-8},
			{"+7*-8*+7*-2",		+7 * -8 * +7 * -2},
			{"+7*-2/-10+-10",	+7 * -2 / -10.0f + -10},
			{"-10+-10--4*-14",	-10 + -10 - -4 * -14},
			{"-4*-14+-13+-4",	-4 * -14 + -13 + -4},
			{"-13+-4*+14/-9/+7+-2",	-13 + -4 * +14 / -9.0f / +7.0f + -2},
			{"-14*-14+ +14 / -9-+7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14 + +14 / -9-+7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14 + + 14 / -9-+7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14++ 14 / -9-+7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14 ++14 / -9-+7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14++14 / -9 -+7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14++14 / -9- +7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14++14 / -9-+ 7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14++14 / -9 -+ 7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},
			{"-14*-14++14 / -9  -  +  7 + -2",	-14 * -14 + +14 / -9.0f - +7 + -2},

			{"((+11)+(-2))*(+12)-(+9)",		((+11) + (-2))*(+12) - (+9)},
			{"(+12)-((+9)/(+7))*(-8)",		(+12) - ((+9) / (+7.0f))*(-8)},
			{"(+7)*((-8)*(+7)*(-2))",		(+7)*((-8)*(+7)*(-2))},
			{"((+7)*(-2))/((-10)+(-10))",	((+7)*(-2)) / ((-10.0f) + (-10))},
			{"((-10)+(-10)-(-4)*(-14))",	((-10) + (-10) - (-4)*(-14))},
			{"((-4)*(-14))+(-13)+(-4)",		((-4)*(-14)) + (-13) + (-4)},
			{"(((-13)+(-4))*(+14))/(-9)/(+7)+(-2)",			(((-13) + (-4))*(+14)) / (-9.0f) / (+7) + (-2)},
			{"((-14)*(-14))+((+14) / (-9)-(+7) + (-2))",	((-14)*(-14)) + ((+14) / (-9.0f) - (+7) + (-2))},

			{"((+11.3)+(-2.3))*(+12.3)-(+9.3)",		((+11.3) + (-2.3))*(+12.3) - (+9.3)},
			{"(+12.3)-((+9.3)/(+7.3))*(-8.3)",		(+12.3) - ((+9.3) / (+7.3f))*(-8.3)},
			{"(+7.3)*((-8.3)*(+7.3)*(-2.3))",		(+7.3)*((-8.3)*(+7.3)*(-2.3))},
			{"((+7.3)*(-2.3))/((-10.3)+(-10.3))",	((+7.3)*(-2.3)) / ((-10.3f) + (-10.3))},
			{"((-10.3)+(-10.3)-(-4.3)*(-14.3))",	((-10.3) + (-10.3) - (-4.3)*(-14.3))},
			{"((-4.3)*(-14.3))+(-13.3)+(-4.3)",		((-4.3)*(-14.3)) + (-13.3) + (-4.3)},
			{"(((-13.3)+(-4.3))*(+14.3))/(-9.3)/(+7.3)+(-2.3)",			(((-13.3) + (-4.3))*(+14.3)) / (-9.3f) / (+7.3) + (-2.3)},
			{"((-14.3)*(-14.3))+((+14.3) / (-9.3)-(+7.3) + (-2.3))",	((-14.3)*(-14.3)) + ((+14.3) / (-9.3f) - (+7.3) + (-2.3))},

			{" 1 ",	1},
			{" +1 ",	1},
			{" -1 ",	-1},
			{" 1+1 ",1 + 1},
			{" 1+2+ 3 ",	1 + 2 + 3},
			{" 1+-1 ",	1 + -1},
			{" 2*\t3 ",	2 * 3},
			{" (1+2)*2 ",	(1 + 2) * 2},
			{" (1*2+2) ",	(1 * 2 + 2)},
			{" (35 + 1) * 2",	(35 + 1) * 2},
			{" 35 + 1 * 2 ",	35 + 1 * 2},
			{" 48/2*(9+3) ",	48 / 2.0f * (9 + 3)},
			{" (6/2)*(1+2) ",	(6 / 2.0f)*(1 + 2)},
			{" (6/(2*(1+2))) ",	(6 / (2.0f * (1 + 2)))},
			{" 1/2*3 ",	1 / 2.0f * 3},
			{" 1+2*3 ",	1 + 2 * 3},
			{" {1+2*3}+{1+2*3} ",	(1 + 2 * 3) * 2},
			{" {1+2*3}+{1+2*3}+(1+2*3) ",	(1 + 2 * 3) * 3}
		};
		int i;
		for (i = 0; i < countof(a); i++)
		{
			DEBUG_puts_double(a[i].s, a[i].f);
			//DEBUG_if_err(!double_cmp(FORMULA_str_to_double(a[i].s) ,a[i].f));
			DEBUG_if_err(!double_is_EQ(str_calculation_with_brace_func_variable(a[i].s), a[i].f));//변수가 없는 문자열에대해서 사칙연산 수행
		}
	}
	DEBUG_test_cal()
	{
		//test1();
		
	}
};
DEBUG_test_cal _DEBUG_test_cal;

#else
#define DEBUG_test_excel()
#endif

MessageWnd.zip



'C언어,ARM' 카테고리의 다른 글

ARM Cortex M0 - W7500 인터럽트  (0) 2016.03.07
CMSIS-DAP  (0) 2016.03.07
ARM Cortex M0 - GPIO  (0) 2016.03.07
Tightly Coupled Memory  (0) 2016.02.29
mini_file_system  (0) 2016.02.01
Posted by 안녕1999
, |

최근에 달린 댓글

글 보관함