چرا گنو/لینوکس را دوست دارم؟

15 01 2013
چرا گنو/لینوکس را دوست دارم؟

چرا گنو/لینوکس را دوست دارم؟

وقتی برای اولین بار گنو/لینوکس نصب کردم، شاید به خاطر تغییر، احساس راحتی با سیستم‌عامل جدیدم نداشتم ولی همینطور که زمان می‌گذشت همه چیز راحت‌تر از حتی ویندوز بود که فکر می‌کردم بهترین سیستم‌عامل دنیاست. اوبونتوی ۷.۰۴ اولین توزیعی نبود که نصب کردم ولی همین توزیع باعث شد گنو/لینوکس رو به عنوان سیستم‌عامل مورد علاقم انتخاب کنم. نزدیک به ۶ سال می‌گذره و امروز به بهانهٔ مسابقهٔ «چرا گنو/لینوکس را دوست دارم؟» تصمیم گرفتم دلایل خودم رو برای گنو/لینوکسی بودن بنویسم.

پیش از این بارها در در مورد گنو/لینوکس نوشتم، مطالبی که شاید برای خودم جذابیت داشتن، مثل «کامپایلر و IDE پاسکال برای گنو/لینوکس» یا جذابیت‌های گرافیکی گنو/لینوکس و البته «تغییر تصویر زمینه‌ی صفحه‌ی بوت سیستم» یا حتی از ابزار‌هایی که گنو/لینوکس در اختیار کاربر می‌ذاره مثل «split» و «mencoder» و «aria2» و «youtube-dl» و «wget» یا حتی عمیق‌تر شدم به موضوع‌هایی که شاید فراتر از یک نرم‌افزار بوده؛ مثل «Slax، سیستم عامل جیبی شما» یا در مورد «FriendFeed در خط‌فرمان» نوشتم یا حتی وقتی بیشتر یاد گرفتم، خودم اسکریپت‌های مختلفی نوشتم که کار‌های روزمره رو برای من ساده تر کنه. مثل «dentinal». و خیلی از چیز‌ها رو هم توی گنو/لینوکس برای خودم شخصی کردم که در موردشون ننوشتم. به عنوان مثال این که زبان صفحه‌کلیدم با Caps Lock عوض بشه چون به نظرم هیچوقت از Caps Lock استفاده نمی‌کردم. یا با ترکیب md5sum و split و با کمک diff وقتی یک فایل بد دانلود شده بود، قسمت ناقص فایل رو پیدا می‌کردم و فقط اون قسمت رو دانلود مجدد می‌کردم. یا حتی اسکرپیت‌هایی که فیلم‌ها من رو مرتب کنه و مشخصات اون‌ها رو از IMDB بگیره و کنار فیلم بذاره. یا اسکریپتی که زیر‌نویس‌هایی که از اینترنت برای فیلم‌ها می‌گیرم رو مرتب می‌کنه، انکدینگشون رو عوض می‌کنه و کاراکترهای فارسی رو جایگذین غیر فارسی‌ها می‌کنه.

اما این‌ها جذابیت‌هایی نیستن که بگم گنو/لینوکس رو فقط به خاطر این‌ها دوست دارم. اگر مثل یک هکر عمیق‌تر نگاه کنیم، انجام تمام این کارها توی هر سیستم‌عاملی ممکنه؛ حتی سیستم‌عاملی به جالبی Femto OS. خیلی از نرم‌افزار‌های آزاد که به صورت روزمره استفاده می‌کنیم، برای سیستم‌عامل‌های دیگه هم وجود دارن. نرم‌افزار‌های بسته هم زیاد هستن که خیلی از نیاز‌های ما رو برطرف می‌کنن؛ ولی در بد ترین حالت، نرم‌افزار‌های آزاد رو برای سیستم‌عامل مقصد کامپایل و اجرا می‌کنیم. پیش‌تر هم در این مورد نوشتم: «چگونه از کامپایلر‌های متن باز در ویندوز استفاده کنیم».

اما مهم‌ترین دلیل من برای دوست‌داشتن گنو/لینوکس، «آزاد بودن» اونه. شاید اگر بنویسم آزادی یعنی:

  • آزادی برای اجرای برنامه برای هر منظوری (آزادی ۰)
  • آزادی برای مطالعه و بررسی چگونگی عملکرد برنامه و تغییر آن برای نیاز خود (آزادی ۱). دسترسی به کد منبع یک پیش‌شرط برای این آزادی می‌باشد.
  • آزادی برای توزیع مجدد کپی‌هایی از آن، بنابراین شما می‌توانید به همسایگان خود کمک کنید (آزادی ۲).
  • آزادی برای بهبود برنامه و انتشار این تغییرات برای عموم، بنابراین تمام جامعه از آن بهره می‌برند (آزادی ۳). دسترسی به کد منبع یک پیش‌شرط برای این آزادی می‌باشد.

خیلی تکراری حرف زده باشم. ولی باور کنید این چیزیه که خیلی از سیستم‌عامل‌های دیگه (و البته نه همه) ندارن. وارد بحث‌های جانبی که آزادی باعث پیشرفت علم کامپیوتر شده و موارد مشابه نمی‌شم. خیلی وقتا، حتی با کسانی که تازه گنو/لینوکسی شدن، این بحث پیش میاد که این سطوح آزادی آیا به درد ما می‌خوره؟ ما می‌خوایم سیستم‌عامل کار کنه و بقیه هم کار می‌کنن. اما برای من موردی پیش اومد که آزاد بودن سیستم‌عامل به من کمک کرد تا به هدف برسم و بدون آزادی سیستم‌عامل این کار غیر ممکن بود.

بذارین با یکم توضیح شروع کنم. اطلاعاتی که به لایهٔ TCP شبکه فرستاده می‌شن، تو یک غلاف جا می‌گیرن و اطلاعات لازم برای رسیدن به پروسهٔ مقصد بهشون اضافه می‌شه. بیت‌های ۱۰۰، ۱۰۱ و ۱۰۲ (اگر شماره رو اشتباه نگفته باشم) رزرو شده هستن و صفر در اون‌ها قرار می‌گیره. تو دانشگاه یک بار بحث پیش اومد که از این بیت‌ها می‌شه استفاده‌های مختلفی کرد. به عنوان مثال این بیت‌ها می‌تونن شمارهٔ کلید رمز‌نگاری/رمز‌گشایی بسته‌ای باشن که توی یک سازمان تعریف شده؛ بسته‌هایی که روی شبکه قرار می‌گیرن، بر اساس مقصد رمز‌نگاری خاصی داشته باشن. از طرفی روند عادی شبکه نباید تغییر کنه و به عنوان مثال مدیر که به همهٔ کلید‌ها دسترسی داره باز هم باید بتونه بسته‌های عادی خودش رو به شبکه (مثل اینترنت، با بیت‌های رزرو شدهٔ صفر) ارسال کنه. از نظر فنی، سیستم‌عامل وظیفهٔ بسته بندی اطلاعات رو بر عهده داره پس ایجاد این روند برای یک سازمان نیاز به تغییر سیستم‌عامل و البته بازنویسی یا تغییر کد اون قسمت از سیستم‌عامله.

TCP Header

هدر بستهٔ TCP

اما آیا این کار عملیه یا فقط در سطح ادعاست؟

من شروع به مطالعه کردم و به این نتیجه رسیدم که یک جائی از کد سیستم‌عامل باید اینطور چیزی نوشته شده باشه (البته این کد خاص، قسمتی از کدیه که به عنوان پروتوتایپ نوشتم و البته همونطور که معلومه قسمتی از رفتار سیستم‌عامل برای مدیریت TCP رو نشون می‌ده):

	// TCP Header
	tcpheader->seq = seq; // Sequence Number
	tcpheader->ack_seq = 0; // Acknowledgment Number
	tcpheader->doff = 5; // Segment offset (Length of the header)
	tcpheader->window = htons(4500) + rand() % 1000;// Window size
	tcpheader->urg_ptr = 0; // Urgent pointer.
	tcpheader->source = saddr.sin_port; // Source Port
	tcpheader->dest = daddr.sin_port; // Destination Port
	tcpheader->check = 0; // Checksum. (Zero until computed)
	tcpheader->syn = 1;

و کاری که من باید انجام بدم اینه که بیام به اینطور رفتار، چیزی مثل کد زیر رو اضافه کنم:

	tcpheader->res1 = key_index;

و البته پیلود رو هم با کلید encrypt کنم و فیلد‌های بسته رو بر اساس تغییر پیلود تغییر بدم. لینوکس (کرنل) آزاد بود پس به راحتی می‌شد سورس‌کدش رو دید، تغییر داد و منتشر کرد. پس این کار رو کردم. آخرین نسخهٔ کرنل رو از سایت Kernel.org دانلود کردم و تو کد قستمی که بسته‌های TCP رو اداره می‌کنه پیدا کردم.

ramin@ramin-host:~/programming/kernel/linux-3.7.2/net/ipv4$ ls tcp*
tcp_bic.c   tcp_cubic.c     tcp_highspeed.c  tcp_illinois.c  tcp_lp.c          tcp_minisocks.c  tcp_scalable.c  tcp_vegas.h     tcp_yeah.c
tcp.c       tcp_diag.c      tcp_htcp.c       tcp_input.c     tcp_memcontrol.c  tcp_output.c     tcp_timer.c     tcp_veno.c
tcp_cong.c  tcp_fastopen.c  tcp_hybla.c      tcp_ipv4.c      tcp_metrics.c     tcp_probe.c      tcp_vegas.c     tcp_westwood.c

و البته از اونجا که کد به اندازهٔ خوبی مستند شده، قستم‌هائی رو که می‌خواستم پیدا کردم. به عنوان مثال کد زیر قستمی از کد کرنله که بسته با فلگ ACK رو ارسال می‌کنه :


/* The code following below sending ACKs in SYN-RECV and TIME-WAIT states
   outside socket context is ugly, certainly. What can I do?
 */

static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
			    u32 win, u32 ts, int oif,
			    struct tcp_md5sig_key *key,
			    int reply_flags, u8 tos)
{
	const struct tcphdr *th = tcp_hdr(skb);
	struct {
		struct tcphdr th;
		__be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2)
#ifdef CONFIG_TCP_MD5SIG
			   + (TCPOLEN_MD5SIG_ALIGNED >> 2)
#endif
			];
	} rep;
	struct ip_reply_arg arg;
	struct net *net = dev_net(skb_dst(skb)->dev);

	memset(&rep.th, 0, sizeof(struct tcphdr));
	memset(&arg, 0, sizeof(arg));

	arg.iov[0].iov_base = (unsigned char *)&rep;
	arg.iov[0].iov_len  = sizeof(rep.th);
	if (ts) {
		rep.opt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
				   (TCPOPT_TIMESTAMP <source;
	rep.th.source  = th->dest;
	rep.th.doff    = arg.iov[0].iov_len / 4;
	rep.th.seq     = htonl(seq);
	rep.th.ack_seq = htonl(ack);
	rep.th.ack     = 1;
	rep.th.window  = htons(win);

#ifdef CONFIG_TCP_MD5SIG
	if (key) {
		int offset = (ts) ? 3 : 0;

		rep.opt[offset++] = htonl((TCPOPT_NOP << 24) |
					  (TCPOPT_NOP << 16) |
					  (TCPOPT_MD5SIG <saddr,
				    ip_hdr(skb)->daddr, &rep.th);
	}
#endif
	arg.flags = reply_flags;
	arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
				      ip_hdr(skb)->saddr, /* XXX */
				      arg.iov[0].iov_len, IPPROTO_TCP, 0);
	arg.csumoffset = offsetof(struct tcphdr, check) / 2;
	if (oif)
		arg.bound_dev_if = oif;
	arg.tos = tos;
	ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr,
			      ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len);

	TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
}

با کمی دقت کد زیر شبیه که به کدی که انتظار داشتم، پیدا می‌شه:

	/* Swap the send and the receive. */
	rep.th.dest    = th->source;
	rep.th.source  = th->dest;
	rep.th.doff    = arg.iov[0].iov_len / 4;
	rep.th.seq     = htonl(seq);
	rep.th.ack_seq = htonl(ack);
	rep.th.ack     = 1;
	rep.th.window  = htons(win);

در هر صورت، وارد بحث‌های فنی و جزئیات پیاده سازی نمی‌شم. ولی هدفم از این مثال تاکید به آزادی برای مطالعه و بررسی چگونگی عملکرد برنامه و تغییر آن برای نیاز خود به عنوان یکی از سطوح آزادی سیستم‌عامل بود. چیزی که خیلی از سیستم‌عامل‌ها، حتی اگر بهتر باشن، قوی‌تر باشن، زیبا تر باشن، نرم‌افزار‌های بهتری داشته باشن، بازی‌های بهتری روی اون‌ها اجرا بشه و… از اون بی‌بهره هستن.

شاید این تصور به وجود بیاد که این آزادی‌ها، برای من به عنوان یک برنامه‌نویس مفید بوده. ولی می‌شه به این فکر کرد که اگر من، یک دانشجوی کامپیوتر، تونستم به این قسمت از سیستم‌عامل برسم، اون رو بخونم و یاد‌بگیرم، بر اساس نیاز تغییرش بدم و اون رو منتشر کنم، پس خیلی از حرفه‌ای‌ها تو دنیا هم می‌تونن این کار رو انجام بدن. از ۱۹۹۱ که لینوکس ساخته شده تا به امروز هزاران نفر این سیستم‌رو مرور کردن و تغییر دادن و بهینه کردن. پس با خیال راحت می‌تونم به سیستم‌عاملم اعتماد کنم و یقین داشته باشم که یکی از بهینه‌ترین سیستم‌عامل‌های ساخته شده رو در اختیار دارم. بدون دغدغه‌های مثل بد افزار‌ها. این درحالیه که تعداد خیلی کمتری از آدما کد سیستم‌عامل‌های بسته رو دیدن و مرور کردن، از کلی بد‌افزار که وجود دارن اگر بگذریم، مواردی مثل «قهرمان‌ باگ‌های امنیتی ویندوز: اجرای کد ریموت با TCP/IP» وجود دارن که شاید برای یک گنو/لینوکسی غیر قابل باور باشن.

پس با افتخار می‌نویسم: گنو/لینوکس رو دوست دارم چون آزاده و به آزادی کاربرش احترام می‌ذاره.

و در درجهٔ بعد قدرت، امکانات، جامعهٔ کاربری، امنیت، بهینگی و البته مواردی که هرچقدر بیشتر یاد‌می‌گیرم، بیشتر می‌شن؛ دلایلی هستن که من گنو/لینوکسی هستم و اون رو دوست دارم.

پـ. نـ.: دروغ چرا، وقتی توی سیستم‌عاملی هستم که چیزی مثل ترمینال گنو/لینوکس نداره (یعنی تو ویندوزم!) کامپیوتر یه موجود غریبه می‌شه برام. دست توسعه‌دهنده‌های Cygwin درد نکنه.
پـ. نـ.: یه ضرب‌المثل هست که می‌گه یه گیک یک کار رو ۳ بار انجام نمی‌ده، یه اسکریپت می‌نویسه.

چرا گنو/لینوکس را دوست دارم؟





اسکریپت نویسی برای Grease Monkey

1 04 2012

این متن برای کسانی نوشته شده که با برنامه‌نویسی آشنا هستند و دوست دارن وب را آن‌طور که می‌خواهند ببینند.
شاید برای شما هم پیش اومده باشه که همیشه از یک سایت سرویس بگیرین یا خیلی بهش سر می‌زنین و دوست دارین امکانی که شما می‌خواین رو داشته باشه.
با یه مثال جلو برم: من از سایت mediafiredowns.com همیشه فیلم‌های خوبی دانلود می‌کنم. ولی یه چیز توی این سایت من رو آزار می‌ده و اون اینه که وقتی روی لینک دانلود کلیک می‌کنم، من رو می‌فرسته به یه قسمت که راهنمایی می‌کنه که چطور دانلود کنم و بعد من رو می‌فرسته به قسمت تبلیغات و بعد تازه می‌رسم به Media Fire و باید از اونجا دانلود کنم.
خیلی خوب می‌شد اگر این مراحل تکراری و خسته کننده کمتر بودن. از اونجا که به قول جادی من اولین نفری نیستم که به این مشکل بر خوردم، یه سرچ کوچیک من رو به یه اسکریپت خوب برای Grease Monkey رسوند که صفحه‌ی تبلیغات رو بایپس می‌کرد. ولی خب من هنوز با اون صفحه راهنمای دانلود مشکل داشتم و توی یوزر اسکریپت‌های Grease Monkey هم چیزی پیدا نکردم. این شد که خودم یکی نوشتم تا نفر بعدی که دنبال یه روش برای اصلاح این وضع می‌ره، اولین نفر نباشه.
خب بد نیست روش کار رو توضیح بدم، شاید شما هم اسکریپت‌هایی نوشتین و در اختیار دیگران گذاشتین.

با این صفحه شروع می‌کنیم.
فیلم ۴ قسمت شده و بدیهیه که هر لینک باید آدرس مرحله‌ی بعد رو داشته باشه. آدرس قسمت ۱ اینطوره:

http://5ed2208c.linkbucks.com/url/http://mediafiredowns.info/download.php?link=aHR0cDovL3EuZ3Mvc1Ntag==

می‌بینیم که توی آدرس یه آدرس دیگه هست:

http://mediafiredowns.info/download.php?link=aHR0cDovL3EuZ3Mvc1Ntag==

ولی باز این همون آدرسی نیست که ما دنبالش هستیم و دقیقن آدرس همون صفحه‌ی راهنمای دانلوده، ولی باید این آدرس یه طوری لینک نهایی یا یه روش برای رسیدن به اون رو توی خودش داشته باشه که به نظر میاد اون پارامتریه که ارسال می‌کنه:

aHR0cDovL3EuZ3Mvc1Ntag==

خب تجربه بهم می‌گه این روش کد گذاری رو می‌شناسم و اون دوتا مساوی انتها، نظر من رو که این یه کد Base64 هست رو پر رنگ‌تر می‌کنه. پس یک بار امتحان می‌کنم. ترمینال لینوکس رو باز می‌کنم و می‌نویسم:

$ echo "aHR0cDovL3EuZ3Mvc1Ntag==" | base64 -d
http://q.gs/sSmj

پس به نظر میاد حدس من درسته و این لینک صفحه‌ی تبلیغاته که اون اسکریپت برای من بای‌پس می‌کرد.
پس روش کار معلوم شد. من باید برنامه‌ای بنویسم که لینک‌های صفحه رو بگرده و هرکدوم از این لینک‌ها به این شکل بودن رو دی‌کد کنه و جایگزین لینک اصلی کنه. ولی خب من که صاحب Mediafiredowns نیستم! اینجاست که به سراغ Grease Monkey می‌رم و یه اسکریپت برای اون می‌نویسم.
گریس‌مانکی برای من اون اسکریپت رو روی آدرس‌هایی که من بهش می‌دم، اجرا می‌کنه پس چی از این بهتر.
تو Firefox از منوی Tools قسمت Greasemonkey گزینه New User Script رو انتخاب می‌کنم و نام و توضیح و چیزای دیگه رو هم پر می‌کنم.
تو قسمت include می‌نویسم:

http://*mediafiredowns.com/*

ویرایشگر متن باز می‌شه. اولین کار اینه که توضیحاتی رو بالای اون اضافه کنم.

// ==UserScript==
// @name           Mediafiredowns Links Changer
// @namespace      https://saarblog.wordpress.com
// @description    Change base64ed links in mediafiredowns.com to simple link. I recommend you to use iHatePaidLinks (greasemonkey user script #105301) beside this script.
// @author         Saar <saarblog [at] gmail [dot] com , identi.ca: @saar>
// @version        0.1
// @license        Gnu General Public License Version 3
// @run-at         document-end
// @include        http://*mediafiredowns.com/*
// ==/UserScript==

/*
    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 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/

فک می‌کنم معلومه که این توضیحال چی هستن. این رو هم اضافه کنم که می‌شه چندین قسمت include داشت. و اون run-at مشخص می‌کنه که بعد از کامل شدن document (و نه load شدن!) این اسکریپت اجرا بشه.
قدم بعدی اینه که تمام لینک‌ها رو پیدا کنیم:

var allLinks, thisLink;
allLinks = document.getElementsByTagName('a');

و این که چک کنیم که آیا به همون سبکی که ما فکر می‌کردیم هست یا نه. چه چیز بهتر از عبارات با قاعده؟

var findLinkRegexp = /.*http:\/\/mediafiredowns\.[^\/]*\/download\.php\?link=(.*)/g;
for (var i = 0; i < allLinks.length; i++) {
    if (allLinks[i].href && allLinks[i].href.match(findLinkRegexp))
        thisLink = allLinks[i];
    else
        continue;
}

در نهایت باید قسمت کد شده رو پیدا کنیم و اون رو دی‌کد کنیم. خب از اونجا که من اولین نفری نیستم که به دی‌کد کردن base64 تو زبون جاوا اسکریپت نیاز دارم، پس گوگل می‌کنم و به این می‌رسم: http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
از همین تابع استفاده می‌کنم:

var match = findLinkRegexp.exec(thisLink.href);
if (match != null) {
    thisLink.href = decode64(match[1]);
    thisLink.style.color = "red";
}

برای این که متوجه بشم لینک اصلاح شده، رنگ اون رو هم قرمز کردم. کار تمومه و کد رو برای استفاده‌ی دیگران منتشر می‌کنم. نسخه‌ی نهایی هم به این شکله:

// ==UserScript==
// @name           Mediafiredowns Links Changer
// @namespace      https://saarblog.wordpress.com
// @description    Change base64ed links in mediafiredowns.com to simple link.  I recommend you to use iHatePaidLinks (greasemonkey user script #105301) beside this script.
// @author         Saar 
// @version        0.1
// @license        Gnu General Public License Version 3
// @run-at         document-end
// @include        http://*mediafiredowns.com/*
// ==/UserScript==

/*
 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 3 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see .
 */



//decode64 function from http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
var keyStr = "ABCDEFGHIJKLMNOP" +
    "QRSTUVWXYZabcdef" +
    "ghijklmnopqrstuv" +
    "wxyz0123456789+/" +
    "=";

function decode64(input) {
    var output = "";
    var chr1, chr2, chr3 = "";
    var enc1, enc2, enc3, enc4 = "";
    var i = 0;

    // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
    var base64test = /[^A-Za-z0-9\+\/\=]/g;
    if (base64test.exec(input)) {
        alert("There were invalid base64 characters in the input text.\n" +
            "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
            "Expect errors in decoding.");
    }
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

    do {
        enc1 = keyStr.indexOf(input.charAt(i++));
        enc2 = keyStr.indexOf(input.charAt(i++));
        enc3 = keyStr.indexOf(input.charAt(i++));
        enc4 = keyStr.indexOf(input.charAt(i++));

        chr1 = (enc1 <> 4);
        chr2 = ((enc2 & 15) <> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;

        output = output + String.fromCharCode(chr1);

        if (enc3 != 64) {
            output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
            output = output + String.fromCharCode(chr3);
        }

        chr1 = chr2 = chr3 = "";
        enc1 = enc2 = enc3 = enc4 = "";

    } while (i < input.length);

    return unescape(output);
}

var allLinks, thisLink;
allLinks = document.getElementsByTagName('a');
var findLinkRegexp = /.*http:\/\/mediafiredowns\.[^\/]*\/download\.php\?link=(.*)/g;
for (var i = 0; i < allLinks.length; i++) {
    if (allLinks[i].href && allLinks[i].href.match(findLinkRegexp))
        thisLink = allLinks[i];
    else
        continue;
    var match = findLinkRegexp.exec(thisLink.href);
    if (match != null) {
        thisLink.href = decode64(match[1]);
        thisLink.style.color = "red";
    }
}

در انتها هم بگم که اگر متوجه نشدید که چطور قسمت کد شده از لینک رو بدست آوردم، این مطلب می‌تونه بهتون کمک کنه: Regex، ابزاری کاربردی در ویرایشگر‌های متنی





ترکیب چندین فایل ویدئویی با mencoder

26 03 2012

شاید برای شما هم پیش اومده باشه که بخواین چندین فایل ویدئو رو به  به یک فایل ویدئو تبدیل کنید. مثلن وقتی که فیلم از روی ۲ تا CD کپی شده:

$ ls
Citizen Kane cd1.avi
Citizen Kane cd2.avi

خب به راحتی می‌زنم:

$ mencoder -oac copy -ovc copy -forceidx \
"Citizen Kane cd1.avi" \
"Citizen Kane cd2.avi" \
-o "Citizen Kane.avi"

توضیح هم این که این برنامه‌ی mencoder یک برنامست که MPlayer ایجاد کرده برای انکد کردن محتوا‌های چند رسانه‌ای.

آپشن‌هایی هم که استفاده شده به این معنی هستن:

  • oac: کدک صدای خروجی. copy هم به این معنیه که کدک فایل منبع حفظ بشه.
  • ovc: کدک ویدئوی خروجی. copy هم به این معنیه که کدک فایل منبع حفظ بشه.
  • o: فایل خروجی
  • forceindex: ساخت مجدد فایل index.




رخداد‌ها در جاوا

30 04 2010

Clickیکی از بازدید کننده‌های «سار»، از من خواسته که در مورد ActionListener ها توی جاوا بگم. بهانه‌ی خوبیه برای یک پست. مطالبی رو که می‌گم، عمدتن از کتاب Core Java جلد ۱ و ۲ گرفته شده و تجربه‌ی شخصیم رو کمتر توی اون دخالت می‌دم.

تمام محیط‌های عامل که از رابط گرافیکی پشتیبانی می‌کنن، به صورت دائم به رخداد‌هایی مثل کلیک شدن موس یا فشردن کلید صفحه‌کیلد نظارت می‌کنن و رخداد این عوامل رو به برنامه‌های درحال اجرا گزارش می‌دن. هر برنامه تصمیم می‌گیره که چطور به اون رخداد (مثل کلیک شدن موس) پاسخ بده (و شاید هم پاسخی در کار نباشه).

توی زبون‌هایی مثل Visual Basic رابطه‌ی بین رخداد و کد مربوط به اون کاملن مشخصه. یک کد برای یک مشخصه‌ی خاص نوشته می‌شه و اون در جایی به نام «روال رخداد» قرار داده می‌شه. کد این رول بعد از رخ دادن رخداد مورد نظر، اجرا می‌شه.

در سمت مقابل، زبون‌هایی مثل C خام، برای این کار باید به صورت مستمر باید صف رخداد‌هایی که محیط عامل گزارش داده چک بشه. این شیوه به صورت کاملن آشکار زشت و در بعضی از موارد خیلی سخت و پیچیده می‌شه.

جاوا روشی بین روش Visual Basic و C خام رو در پیش می‌گیره که قدرت بیشتر و پیچیدگی کمتری رو داره.

ما یه عنصر داریم که می‌شه منبع رخداد که به اون می‌گیم Event Source و یک شنونده‌ی که به اون می‌گیم Event Listener. وقتی از سمت منبع یک رخداد رخ می‌ده، شنونده اون رو می‌شنوه و فعالیت اقدام لازم رو انجام می‌ده. هر منبع رخداد یک سری متد داره برای ثبت کردن یک شنونده. یعنی شما باید یک شنونده رو برای یک منبع رخداد ثبت کنید تا بتونید رخداد رو به اون شنونده گزارش بدین.

همونطور که از زبون‌های شیء گرا مثل جاوا انتظار می‌ره، اطلاعات مربوط به رخداد‌ها، توی یک شیء Event کپسوله می‌شه. توی جاوا تمام شیء های رخداد سرانجام از java.util.EventObject مشتق می‌شن. البته زیر کلاس‌هایی هم برای منظور‌های مختلف مثل WindowEvent و ActionEvent وجود داره. منابع مختلف رخداد می‌تونن انواع مختلفی از اون رو به وجود بیارن. به عنوان مثال یک دکمه شیء ActionEvent رو ارسال می‌کنه در صورتی که یک پنجره شیء WindowEvent رو.

در نهایت مثال زیر یک نمونه از کنترل رخداد برای یک دکمست:

ActionListener listener = . . .;
JButton button = new JButton("Ok");
button.addActionListener(listener);

با این حساب، وقتی یک رخداد از سمت button رخ بده، listener از اون آگاه می‌شه. همونطور که ممکنه متوجه شده باشید، این یک کنترل رخداد فشردن دکمست.

برای پیاده کردن یک واسط ActionListener کلاس شنونده باید یک متد با نام actionPerformed داشته باشکه که یک شیء ActionEvent رو به عنوان پارامتر قبول کنه، کد زیر رو ببینید:

class MyListener implements ActionListener
{
    . . .
    public void actionPerformed(ActionEvent event)
    {
        // reaction to button click goes here
        . . .
    }
}

خب، حالا وقتی کاربر روی button کلیک کنه، اون یک شیء ActionEvent می‌سازه و به listener.actionPerformed می‌فرسته. اشیائی مثل JButton می‌تونن تعدادی شنونده داشته باشن که وقتی رخداد رخ می‌ده، همه از اون آگاه می‌شن.

خب، Inner Classes چیزیه که اینجا به درد می‌خوره. ما می‌تونیم به جای این که یک کلاس بسازیم برای پیاده سازی واسط مثلن ActionEvent بیایم و واسط رو هرجا که خواستیم پیاده کنیم. یعنی کد بالا اینطور می‌شه:

JButton button = new JButton("Ok");
button.addActionListener(new ActionListener()
{
    . . .
    public void actionPerformed(ActionEvent event)
    {
        // reaction to button click goes here
        . . .
    }
});

و اما یه تجربه‌ی شخصی به من می‌گه که به جای این کارا از Action استفاده بشه، هم کار زیبا تر درمیاد، هم راحت تره و هم تعمیم پذیری کار بالا می‌ره. در این مورد هم یکم توضیح بدم. در نظر بگیرید که قراره توی یه طراحی، منو باشه، پاپ‌آپ منو هم باشه، نوار ابزار هم باشه. خب ممکنه، و به احتمال زیاد، گزینه‌هایی وجود خواهد داشت که توی هر سه تای این‌ها باشه. مثلن یک ویرایشگر متن، و گزینه‌ی کپی که هم توی منوی راست‌کلیک هست، هم توی منوی Edit و هم توی نوار ابزار. رفتار هر سه‌تای این گزینه‌ها یکیه، آیکنشون هم همینطور. و وقتی مثلن برای کپی نوشته‌ای وجود نداره، باید این ۳ تا غیر فعال بشن و …

خب اگر ما ۳ تای این‌ها رو جدا جدا داشته باشیم، مدیریتشون سخت می‌شه. اما با یک Action واحد می‌شه این کار رو به راحتی انجام داد. تمرکز رو روی یک Action می‌ذاریم و بعد از اون تمام عناصر گرافیکی مربوطه ساخته می‌شه. مثال گویا تر خواهد بود:

Action action = new AbstractAction()
{
    public void actionPerformed(ActionEvent event)
    {
        // reaction to button click goes here
        . . .
    }
};
action.putValue(Action.NAME, "OK");
action.putValue(Action.SMALL_ICON, smallIcon); //The menu will use this icon
action.putValue(Action.LARGE_ICON_KEY, largeIcon); //The button will use this icon
action.putValue(Action.SHORT_DESCRIPTION, "A short description for display in a tooltip");
JButton button = new JButton (action);
JMenuItem menuItem = new JMenuItem (action);

خب به همین راحتی! در کل بحث رخداد‌ها توی جاوا بحث شیرین، مهم و جالبیه. اگر درک نشه، خیلی سخت خواهد بود! در کل کتاب Core Java, Volume I یک فصل رو بهش اختصاص داده که در مورد خیلی از رخداد‌ها مثل رخداد‌های پنجره و موس بحث شده توش.

=-=-=-=-=
Powered by
Bilbo Blogger





Regex، ابزاری کاربردی در ویرایشگر‌های متنی

4 03 2010

یکی از امکانات جالبی که ویرایشگر‌های متن پیشرفته دارن، جستجو برای «عبارات منظم» که خیلی به درد برنامه نویسی و کلن ویرایش متن می‌خوره. با این امکان می‌شه به جای جست و جو برای یک متن، یک الگو رو جست و جو کرد. بذارین با یک مثال نشون بدم بهتون. کد زیر رو (کد جاوا) ببینید (این کد فقط برای مثاله، از نظر منطقی ممکنه به درد نخوره):

public class StatePropertiesPanel extends JPanel implements StateProperties {
  
        private JComboBox statesComboBox;
        private JComboBox zeroStateComboBox;
        private JButton zeroStateColorButton;
        private JComboBox oneStateComboBox;
        private JButton oneStateColorButton;
        private JTextField nameTextField;
        private JCheckBox isFinalStateCheckBox;
        private JButton addButton;
        private JButton removeButton;
        private JButton applyButton;
        private Graph graph;
        private JButton openButton;
        private JButton saveButton;
        private Action openAction;
        private Action saveAction;
  
}

خب می‌خوایم برای این class یک سازنده بسازیم که توی اون، این مقادیر رو هم مقدار دهی کنیم با پارامترهای متد سازنده، یعنی نتیجه‌ی خروجی باید این شکلی بشه:

public class StatePropertiesPanel extends JPanel implements StateProperties {
  
        private JComboBox statesComboBox;
        private JComboBox zeroStateComboBox;
        private JButton zeroStateColorButton;
        private JComboBox oneStateComboBox;
        private JButton oneStateColorButton;
        private JTextField nameTextField;
        private JCheckBox isFinalStateCheckBox;
        private JButton addButton;
        private JButton removeButton;
        private JButton applyButton;
        private Graph graph;
        private JButton openButton;
        private JButton saveButton;
        private Action openAction;
        private Action saveAction;
  
        public StatePropertiesPanel(JComboBox statesComboBox,
                                JComboBox zeroStateComboBox,
                                JButton zeroStateColorButton,
                                JComboBox oneStateComboBox,
                                JButton oneStateColorButton,
                                JTextField nameTextField,
                                JCheckBox isFinalStateCheckBox,
                                JButton addButton,
                                JButton removeButton,
                                JButton applyButton,
                                Graph graph,
                                JButton openButton,
                                JButton saveButton,
                                Action openAction,
                                Action saveAction) {
                this.statesComboBox = statesComboBox;
                this.zeroStateComboBox = zeroStateComboBox;
                this.zeroStateColorButton = zeroStateColorButton;
                this.oneStateComboBox = oneStateComboBox;
                this.oneStateColorButton = oneStateColorButton;
                this.nameTextField = nameTextField;
                this.isFinalStateCheckBox = isFinalStateCheckBox;
                this.addButton = addButton;
                this.removeButton = removeButton;
                this.applyButton = applyButton;
                this.graph = graph;
                this.openButton = openButton;
                this.saveButton = saveButton;
                this.openAction = openAction;
                this.saveAction = saveAction;
        }
}

خب اگر بخوایم دستی این تغییرات رو اعمال کنیم، هم وقت گیر می‌شه و هم احتمال خطا بالا می‌ره. اما استفاده از «عبارت منظم» کار رو برای ما خیلی راحت می‌کنه. بذارین قبل از این، چند‌تا نرم افزار که این قابلیت رو پشتیبانی می‌کنن، معرفی کنم.

برای ویندوز اول:

  • Notepad++ برنامه‌ی خیلی قوی و متن باز و البته رایگان.
  • Geany که یک برنامه‌ی در ابتدا گنو/لینوکسی بوده ولی به لطف متن‌باز بودن، نسخه‌ی ویندوزی اون هم وجود داره.
  • MEdit که برنامه‌ی بدی به نظر نمیاد. گنو/لینوکسیه ولی برای ویندوز کامپایل شده.
  • Netbeans هم که یک محیط مجتمع قوی به حساب میاد.
  • Vim که هرچی در موردش بگم کم گفتم. البته خودم خیلی خوب بلد نسیتم باهاش کار کنم، ولی میلاد توی وبلاگش متن‌های خوبی در این مورد نوشته
  • و خیلی برنامه‌های دیگه و تقریبن تمام برنامه‌هایی که این پایین برای لینوکس معرفی می‌کنم که نسخه‌ی ویندوزی هم دارن. فعلن همینا کافیه.

و برای لینوکس:

  • Geany
  • MEdit
  • Kate
  • KWrite
  • Netbeans
  • Vim
  • Bluefish
  • و خیلی‌های دیگه.

خب اول یه فایل جدید باز می‌کنم و این مقادیر رو توی اون کپی می‌کنم:

private JComboBox statesComboBox;
private JComboBox zeroStateComboBox;
private JButton zeroStateColorButton;
private JComboBox oneStateComboBox;
private JButton oneStateColorButton;
private JTextField nameTextField;
private JCheckBox isFinalStateCheckBox;
private JButton addButton;
private JButton removeButton;
private JButton applyButton;
private Graph graph;
private JButton openButton;
private JButton saveButton;
private Action openAction;
private Action saveAction;

از منوی Edit ویرایشگر متنم که الان Kate است، Replace رو انتخاب می‌کنم. برای نرم‌افزار‌هایی که معرفی کردم، ممکنه این گزینه توی منو‌هایی مثل Search یا Find هم باشه. من باید این کار رو کنم، اول private‌ها حذف بشه، بعد «;» رو باید با «,» تعویض کنم، در آخر هم public StatePropertiesPanel( رو به ابتدا و ({} رو به انتها اضافه کنم. این کار آخر که آسونه و می‌شه با دست انجام داد، اما برای بقیه‌ی کار، Replace رو باز می‌کنم، گزینه‌ی Regular expression رو فعال می‌کنم و توی کادر Find عبارت زیر رو می‌نویسم (بعد از این توضیح می‌دم که معانی این عبارات چی هستن):

private (.*);

و توی کادر Replace مقدار زیر رو می‌نویسم:

\t\1,

و در انتها دکمه‌ی Replace All رو می‌زنم. نتیجه به شکل زیر می‌شه:

        JComboBox statesComboBox,
        JComboBox zeroStateComboBox,
        JButton zeroStateColorButton,
        JComboBox oneStateComboBox,
        JButton oneStateColorButton,
        JTextField nameTextField,
        JCheckBox isFinalStateCheckBox,
        JButton addButton,
        JButton removeButton,
        JButton applyButton,
        Graph graph,
        JButton openButton,
        JButton saveButton,
        Action openAction,
        Action saveAction,

خب، کامای خط آخر رو پاک می‌کنم و به جای اون می‌نویسم ({} و ابتدای خط اول public StatePropertiesPanel( رو اضافه می‌کنم. تا اینجا که متد سازنده‌ی من شکل کلی رو به خودش گرفت. پس متن رو کپی می‌کنم به سورس فایلم. اما حالا محتوایت این متد سازنده. دوباره مقایر رو مثل چند مرحله قبل به یک فایل جدید (و موقت، راه‌های دیگه هم هست، ولی این از همه دم دست تره!) انتقال می‌دم و مراحل رو اینبار به این شکل تکرار می‌کنم. استراتژی کار این بار به این شکله. private ها و اسم کلاس‌هایی که شیء از اون ساخته می‌شه باید حذف بشه، اسم شیء باید با اسم فیلد تغییر کنه (یعنی یه this. بیاد قبلش) و بعد مساوی و باز اسم شیء به عنوان پارامتر متد. پس توی کادر Find این رو می‌نویسم:

private .* (.*);

و بعد توی کادر Replace می‌نویسم:

\t\tthis.\1 = \1;

و Raplace all رو می‌زنم. نتیجه می‌شه:

                this.statesComboBox = statesComboBox;
                this.zeroStateComboBox = zeroStateComboBox;
                this.zeroStateColorButton = zeroStateColorButton;
                this.oneStateComboBox = oneStateComboBox;
                this.oneStateColorButton = oneStateColorButton;
                this.nameTextField = nameTextField;
                this.isFinalStateCheckBox = isFinalStateCheckBox;
                this.addButton = addButton;
                this.removeButton = removeButton;
                this.applyButton = applyButton;
                this.graph = graph;
                this.openButton = openButton;
                this.saveButton = saveButton;
                this.openAction = openAction;
                this.saveAction = saveAction;

خب، به همین راحتی این‌ها هم تولید شد.

با یک مثال شروع کردم که حرف‌هام ملموس باشه. این الگو، قواعد خودش رو داره و قواعد متفاوتی داره. من POSIX Basic Regular Expressions همراه با POSIX Extended Regular Expressions رو توضیح می‌دم. یک عبارت منظم یک مجموعه از رشته‌ها رو مطابق می‌شه که می‌تونیم از این مجموعه برای پیدا کردن متن مورد نظر استفاده کنیم. ما یک سری Metacharacter (که حالا فارسی بگیم ابرحرف) داریم که معنی خاصی دارن. اولی این‌ها رو یاد بگیریم:

  • «.» مطابق می‌شه با یک حرف. البته در اکثر بنامه‌ها این حرف شامل خط جدید نمی‌شه
  • «[ ]» مطابق یکی از حروف مشخص‌شده یا شامل شده می‌شه. مثلن [abc] مطابق می‌شه با حرف a یا b یا c و [a-z] مطابق هر حرف از حروف کوچیک الفبای انگلیسی می‌شه. [abx-z] مطابق a یا b یا x یا y یا z می‌شه. [a\-b] هم مطابق a یا – یا b می‌شه. \ اینجا برای تغییر معنی به کار می‌ره. [a-dx-z] هم مطابق می‌شه با a یا b یا c یا d یا x یا y یا z می‌شه. یعنی می‌شه بازه‌ها رو ترکیب کرد.
  • «[^ ]» مطابق هر حرفی به‌جز حرف‌های درون براکت می‌شه. به عنوان مثال [^abc] تمام حروف به‌جز a و b و c خواهد بود. قواعد براکت معمولی رو هم می‌شه به کار برد
  • «^» معنی موقعیت یک رشته درون رشته‌ی دیگه رو می‌ده که این معنی برای ابزار‌هایی که خط در اونها معنی داره (مثل ویرایشگر‌های متنی) به معنی شروع خط خواهد بود.
  • «$» معنی موقعیت پایان رشته و در ابزار‌های خطی، به معنی پایان خط هست. مثال‌های انتها معنی رو بهتر روشن می‌کنه.
  • «()» یک عبارت علامتگذاری شده رو مشخص می‌کنه. شما می‌تونید توی پرانتز یک عبارت منظم رو که براتون مهمه، مثل نام شیء تو مثال اول مطلب، علامت بزنید تا از اون استفاده کنید. قسمت زیر هم مرتبط با این قستمه.
  • «\n» که n یک عدد بین ۱ تا ۹ هست که مطابق می‌شه با nامین رشته‌ی علامت گذاری شده با پرانتز. بعضی ابزار ها اجازه‌ی گستش این دستور رو بیشتر از ۹ فراهم می‌کنن.
  • «*» مطابق می‌شه با رخداد ۰ یا بیشتر از حرف ماقبل این علامت. به این معنی که ab*c رو اگر برای عبارت منظم داشته باشیم، مطابق می‌شه با ac و abc و abbc و abbbc و….
  • «+» مطابق می‌شه با رخداد ۱ یا بیشتر از حرف ماقبل این علامت. به این معنی که ab+c رو اگر برای عبارت منظم داشته باشیم، مطابق می‌شه با abc و abbc و abbbc و….
  • «?» مطابق می‌شه با رخداد ۰ یا یک باز از حرف ماقبل این علامت. به این معنی که ab? مطابق a و ab خواهد بود.
  • «|» برای اجتماع کردن دو عبارت منظم می‌شه. یا به عبارتی برای انتخاب بین دو عبارت منظم به کار می‌ره. مثلن abc|def مطابق abc و def می‌شه.
  • «{n,m}» هم مطابق با n تا m تکرار از حرف ما قبل خودش می‌شه. این عبارت ممکنه توسط ابزار‌های قدیمی تر پشتیبانی نشه. مثال هم: ab{1,3} مطابق می‌شه با ab و abb و abbb.

و البته اگر برنامه‌نویسی هم کرده باشین، مژده اینه که می‌تونید از حروف خاص مثل \t یا \n هم استفاده کنید.

اما با چند مثال بیشتر مفهوم رو گسترش می‌دم.

.at

مطابق تمام رشته‌های ۳ حرفی شامل at می‌شه. مثل cat و bat و hat و حتی 2at

[hc]at

مطابق hat و cat می‌شه و نه چیز دیگه‌ای.

[^b]at

مطابق تمام رشته‌های ۳ حرفی به‌جز bat می‌شه.

^[hc]at

مطابق تمام cat و hat ها در اول خط می‌شه.

[hc]at$

مطابق تمام cat و hat های انهای خط می‌شه.

[hc]?at

مطابق hat و cat و at می‌شه.

.*=

مطابق تمام رشته‌هایی که به = ختم می‌شن، می‌شه.

و برای پراتز‌. کاربرد عبارت علامت گذاری شده برای جایگزین کردن یک رشته است. بذارین با یه مثال بیشتر شرح بدم. من عبارت منظمی می‌خوام بنویسم که کلمات قبل از یک «=» رو با کلمات بعد از اون عوض کنم و بلعکس. پس عبارت منظم زیر رو باید برای پیدا کردن کلمات به کار ببرم (فعلن فرض کنیم که تمام متن قبل از مساوی یک کلمه و بعد از اون هم یک کلمه است):

(.*)=(.*)

طبق فرض، پرانتز اول برابر کلمه‌ی اول و پرانتز دوم برابر کلمه‌ی دومه. حالا برای جایگزینی، کادر Replace رو با عبارت زیر پر می‌کنم:

\2=\1

به همین راحتی. بذارین یه مثال خیلی کاربردی برای وبلاگ نویسا بگم. می‌خوایم قبل تمام لینک‌های موجود توی یک متن، favicon اون رو (همون آیکون کوچیکه که کنار نوار آدرس توی مرورگر دیده می‌شه) رو با استفاده از «سرویس گوگل برای بدست آوردن favicon ها و اعمال آن بر لینک های خارجی» قرار بدیم. تقریبن تمام ابزار‌هایی که برای نوشتن وبلاگ استفاده می‌شه (مثل ویرایشگر خود وبلاگ(ها) و Bilbo Blogger) این امکان رو به شما می‌دن که بعد از نوشتن متن، کد HTML اون رو ببینید. پس شما اول متن رو بنویسید و کد HTML اون رو به یک ویرایشگر متن انتقال بدین تغییرات رو اعمال کنید و باز کد رو از ویرایشگر متن به وبلاگ منتقل کنید. خب اول در مورد لینک برای کسانی که آشنایی ندارن، این رو بگم.

وقتی شما یک لینک می‌سازین، برچسبی قبل و بعد اون قسمت لینک اضافه می‌شه. به عنوان مثال لینک «سار» رو شرح می‌دم:

<a href="https://saarblog.wordpress.com">سار</a>

خب، برچسب <a> معرفی کننده‌ی شروع یک لینکه. خصوصیت href از اون مشخص کننده‌ی آدرس لینکه. و برچسب با </a> تموم می‌شه. ما باید domain مربوط رو پیدا کنیم. این domain قسمت ابتدای URL آدرس ماست و یا تا اولین / و در صورت نبودن اولین /، تا آخر URL ادامه داره. از اونجا که حروف بزرگ و کوچیک تفاوتی ایجاد نمی‌کنه، پس می‌تونیم برچسب <A> رو هم داشته باشیم. اول عبارت منظم:

<[aA] ([^>]*[hH][rR][eE][fF]="?[hH][tT][tT][pP][sS]?)://([^/" ]+)("?[^>]*)>

خب برای این که یک لینک شروع بشه، باید <a یا <A رو داشته باشیم که من از <[aA] استفاده کردم. بعد از اون می‌تونه هر عبارتی بیاد به‌جز «>» و عبارت هم برای ما اهمیت داره (برای این که ساختار لینک از بین نره) ولی حتمن باید یک فاصله بعد از a یا A باشه (وگرنه ممکنه یه برچسب دیگه باشه!). عبارت href= شروع آدرس URL رو نشون می‌ده که ممکنه (و در اکثر موارد) این URL بین دو «»» قرار داره. برای همین بعد از «»» یک علامت سوال قرار دادم. پروتکل می‌تونه http یا https باشه، و از اونجا که می‌شه اینطور هم نوشت: HtTpS، من کاراکتر به کاراکتر اون‌ها رو توی براکت قرار دادم. بعد از اون حتمن باید :// وجود داشته باشه، بعد Domain از اینجا تا اولین «/» یا «»» یا فاصله ادامه خواد داشت. و بعد ادامه تا علامت «>». خب، حالا عبارت Replace باید به این شکل ساخته بشه:

<a \1://\2\3><img src="http://www.google.com/s2/favicons?domain=\2" />

پرانز دوم Domain بود، برای همین جاهایی که نیاز بود، \2 رو استفاده کردم. جالب بود، نه؟

فکر می‌کنم الآن می‌تونید مثال‌های برنامه نویسی رو متوجه بشین.
پ‌ن: این ترفند favicon رو برای این پست اعمال کردم.

=-=-=-=-=
Powered by Bilbo Blogger, Made with Bluefish HTML editor.





برنامه نویسی، جاوا و معرفی چند کتاب

2 03 2010

Books Photoخیلی وقتا از من سوال می‌شه که «چه کتابی رو برای یادگیری جاوا خوبه؟» یا حتی «چه‌کار کنیم که برنامه‌نویسی یاد بگیریم؟» و از این قبیل سوال‌ها. مدت‌هاست می‌خوام در این مورد یه مطلب بنویسم.

اگه بخوام به کسی که از برنامه‌نویسی هیچ‌چیز بلد نیست، برنامه نویسی یاد بدم، خب اول از خوندن کتاب‌های آقای جعفر نژاد منعش می‌کنم. با کمال احترامی که برای ایشون قائلم، و البته که خیلی از کتاب‌هاشون رو خوندم، این نظر رو دارم و معتقدم کتاب‌های ایشون از نظر علمی در سطح خیلی پایینی هستن در حدی که کتاب جاوا ایشون رو نخوندن، یک گام به جلو برای یاد گرفتن جاواست. البته با کمال تاسف باید بگم که اساتید محترم رشته‌ی کامپیوتر در اغلب موارد کتاب‌های ایشون رو معرفی می‌کنن (مخصوصاً برای درس‌های پایه‌ای) و دانش‌جوی تازه کار رو دور تر از حدی که هست می‌برن.

برای شروع برنامه نویسی، فکر می‌کنم زبون C++ گزینه‌ی خوبی باشه. در حال حاضر پاسکال رو خیلی‌ها توصیه می‌کنن که من با این زبون مخالفم (البته به عنوان واحد دانشگاهی این درس رو پاس کردم). سنتی بودن این زبون و قدیمی بودنش دلیل اصلی این حرف منه. دانشجوی ترم اولی پاسکال می‌خونه، ترم بعد همون پاسکالی رو که خونده به زبون C++ می‌خونه. این یعنی یک گام درجا زدن.

برای شروع یادگیری C++ من کتاب «C++: a beginner’s guide» و بعد از اون کتاب خوب «C++ nuts & bolts: for experienced programmers» که نسخه‌ی ترجمه شده‌ی تقریباً خوبی با نام «راهنمای سریع C++» داره. البته به نظر من کتاب دوم هم می‌تونه برای شروع C++ مورد استفاده قرار بگیره. برای مرجع هم دو کتاب «C++: The Complete Reference» و کتاب معروف «C++ how to program» که ترجمه‌های زیادی هم از این کتاب وجود داره. من یکی از این ترجمه‌ها رو با نام «چگونه با C++ برنامه بنویسیم» از نشر «سیمای دانش» رو خودم گرفتم که نگارش خوبی نداشت و اون رو پیشنهاد نمی‌کنم. این دو کتاب رو به عنوان مرجع گفتم ونه به عنوان محور آموزش. دقت کنید که اگر همین الان یکی از این دوتا رو باز کنید و از اولی بخونید، از برنامه نویسی زده می‌شین. درست مثل اینه که شما یک فرهنگ لغت رو بشینید از اول بخونید.

اما جاوا، راستشو بخواین دیشب که به پادکست دوم رادیو لینوکس (که کار بسیار جالبیه) گوش می‌کردم، حس حسادت به برنامه نویس‌های C++ توی من به وجود اومد. البته هرچند به زودی چیچک رو به عنوان یه پروژه‌ی ابتکاری توسعه می‌دم ولی خب برای این که بشه یه برنامه طوری که بتونه مورد اسفتاده‌ی عموم قرار بگیره نوشت، بهترین زبون C++ خواهد بود. ولی به شخصه، من دوست دارم با زبونی برنامه بنویسم که ابهام آمیز نباشه. همه چیز اون طبق قاعده و مستند شده باشه و تفاوت میون Compilerها در ترجمه‌ی برنامه وجود نداشته باشه. برای من سخته از کدی به شکل String.compareTo در جاوا دل بکنم و اون رو با strcmp از C++ تعویض کنم. همونقدر که از مستقل از بستر بودن جاوا نمی‌شه گذشت، از قدرت C++ هم نمی‌شه گذشت و خوشبختانه اگر در جاوا به قدرت C++ نیاز شد، می‌شه با Native نویسی اون رو بدست آورد.

اما برای کسانی که مایل هستن جاوا رو یاد بگیرن بگم که بهترین کتابی که من می‌تونم معرفی کنم، دو جلد کتاب «Core Java» از نشر «Prentice Hall» هست که به نظر من خوندن این دو جلد کتاب برای یاد گیری جاوا از هر کتابی بهتره. «The Java Tutorials» هم منبع خیلی مفیدی برای یاد گیری جاوا، به خصوص رابط گرافیکی توی اونه. اما کتاب‌های «آموزش جاوا در 21 روز» از نشر «نص» رو به عنوان یه کتاب برای شروع به زبون فارسی بد نمی‌دونم. کتاب «جاوا، جاوا، جاوا: رهیافتی شی ء گرا در حل مسائل » از نشر «جنگل» هم کتاب خوبی به حساب میاد. و البته کتاب «راهنمای جامع Java» از نشر «کانون نشر علوم» هم کتاب خوبیه و به قول میلاد، مختصر و مفید توضیح داده و برای مرجع فارسی کتاب خوبیه. البته من نسخه‌ی اصلی این کتاب یعنی «Java™ 2: The Complete Reference» رو مرجع خوبی نمی‌دونم. برای مرجع بهترین چیز، مستندات جاواست که از هر کتابی می‌تونه مفید باشه. برای تمام مباحث جاوا هم کتابای خوبی پیدا می‌شه. مثلاً کتاب «Computer Graphics Using Java™ 2D and 3D» و یا کتاب «Java Network Programming».

دو چیز رو با تاکید بگم:

  1. برنامه‌نویس با کتاب خوندن برنامه نویس نشده. بدونید که تمرین و از اون مهم تر، کد خوندن، تاثیر زیادی توی تجربه‌ی برنامه نویسی می‌ذاره.
  2. اگر فکر می‌کنید که نمی‌تونید کتاب‌های زبان اصلی رو بخونید و دنبال کتاب فارسی می‌گردین، راه رو اشتباه دارین طی می‌کنید. برگردین و یا از برنامه نویسی دست بکشین، یا زبانتون رو قوی کنید و بعد برنامه نویسی بخونید. بعد از اونه که می‌فهمید آقای جعفر نژاد چه مزخرفاتی مخصوصاً توی کتاب جاوا، به خورد شما می‌ده.

و چیزی که من خودم هم باهاش مشکل دارم و به قول همین پادکست دوم رادیو لینوکس، مستند سازیه. از همین اولی عادت کنید که برنامه‌هاتون رو مستند کنید. راهنما برای اون‌ها بنویسید. منظورم راهنمای کاربر نیست، راهنمایی برای کد هاتونه.

اما جزئیات بیشتر از کتاب‌هایی که توی این مطلب نامشون رو بردم:

C++ how to program

Title: C++ how to program
Authors: Paul J. Deitel, Harvey M. Deitel
Publisher: Prentice Hall
ISBN: 0136152503, 9780136152507


C++ A Beginner's Guide

Title: C++: a beginner’s guide
Author: Herbert Schildt
Publisher: McGraw-Hill/Osborne
ISBN: 0072194677, 9780072194678


C++ Nuts & Bolts

Title: C++ nuts & bolts: for experienced programmers
Author: Herbert Schildt
Publisher: Osborne McGraw-Hill
ISBN: 0078821401, 9780078821400


C++ The Complete Reference

Title: C++: The Complete Reference
Author: Herbert Schildt
Publisher: McGraw-Hill Osborne Media
ISBN: 0072226803, 9780072226805


Core Java, Vol. 1 Fundamentals

Title: Core Java, Vol. 1: Fundamentals
Authors: Cay S. Horstmann, Gary Cornell
Publisher: Prentice Hall PTR
ISBN: 0132354764, 9780132354769


Core Java, Vol. 2 Advanced Features

Title: Core Java, Vol. 2: Advanced Features
Authors: Cay S. Horstmann, Gary Cornell
Publisher: Prentice Hall PTR
ISBN: 0132354799, 9780132354790


Computer graphics using Java 2D and 3D

Title: Computer graphics using Java 2D and 3D
Authors: Hong Zhang, Y. Daniel Liang
Publisher: Prentice Hall
ISBN: 0130351180, 9780130351180


Java network programming

Title: Java network programming
Author: Elliotte Rusty Harold
Publisher: O’Reilly Media, Inc.
ISBN: 0596007213, 9780596007218


Java 2: the complete reference

Title: Java 2: the complete reference
Author: Herbert Schildt
Publisher: Osborne/McGraw-Hill
ISBN: 0072130849, 9780072130843


عنوان: جاوا، جاوا، جاوا: رهیافتی شی ء گرا در حل مسائل
تالیف: رالف مورلی، هادی محمدزاده (مترجم)، علی جهانیان (مترجم)
نشر: چنگل
شابک: 978-964-981-065-2

عنوان: چگونه با C++ برنامه نویسی کنیم
تالیف: هاروی دیتل، پل دیتل، علیرضا انصاری (مترجم)
نشر: زانیس
شابک: 978-964-377-302-1

عنوان: راهنمای سریع C++
تالیف: هربرت شیلد، ابوالقاسم شادمان پور (مترجم)
نشر: دانشگاه هرمزگان
شابک: 964-6426-31-X

عنوان: راهنمای جامع Java
تالیف: هربرت شیلد، فرهاد قلی زاده نوری (مترجم)، علی اصغر شریف پور (مترجم)
نشر: کانون نشر علوم
شابک: 964-8587-21-3

عنوان: برنامه نویسی جاوا: خودآموز سریع در 21 روز
تالیف: چارلز پرکینز، لورا لمی، علیرضا زارع پور (مترجم)
نشر: نص
شابک: 964-6264-21-2





Slax، سیستم عامل جیبی شما

27 02 2010

خیلی وقتا بحث پیش میاد که «سیستم‌عامل زنده به چه دردی می‌خوره. حالا گیریم که اوبونتو از روی CD هم بالا اومد، غیر از نجات سیسم معیوب، چه دردیو دوا می‌کنه». اما خب از بحث‌های تکنیکی که بگذریم، گاهی این زنده بودن سیستم‌عامل می‌تونه خیلی به درد بخور باشه. شما یه فلش یا حد اقل پخش کننده‌ی موسیقی همراهتون هست همیشه ولی اگرم Laptop داشته باشین، همه‌جا که همراهتون نیست ولی خیلی چیزای اون رو همه جا نیاز دارین. مثل Firefox و برنامه‌های دیگه. خیلی جاها نیاز به سیستم امنی دارین تا با خیال راحت و دوری از هر Keylogger بتونید یه ایمیل چک کنید و خیلی محاسن دیگه. بد نیست که با سیستم عامل جیبی Slax آشناتون کنم. اول از توضیحات وب‌سایت اون شروع می‌کنم:

Slax، سیستم‌عامل لینوکس مدرن، قابل حمل، کوچک و سریع با رویکرد ماژولار و طراحی برجسته است. با وجود اندازه‌ی کوچک آن، Slax یک مجموعه‌ی وسیعی از نرم‌افزار‌های از پیش نصب شده را برای استفاده‌ی روزانه، از جمله رابط گرافیکی سازمان‌دهی شده‌ی خوب و ابزار‌های بازیابی مفید برای مدیران سیسم، فراهم می‌کند.

رویکرد ماژولار این امکار را به شما می‌دهد که به راحتی نرم‌افزار‌های دیگر را به Slax اضافه کنید. اگر فقدان ویرایشگر متن، ابزار شبکه یا بازی مورد علاقه‌ی خود را احساس می‌کنید، به راحتی ماژول آن نرم‌افزار را دریافت کرده و آن را در Slax کپی کنید، نیازی به نصب و تنظیم نیست.

خب فکر می‌کنم توضیحات کامل بود. اما حالا برای داشتن یه Slax روی حافظه‌ی قابل حملمون چکار باید کرد؟ به چیا نیاز داریم؟

  • یک رسانه‌ی حافظه مثل USB Flash یا Music Player
  • فایل slax-6.1.2.tar که در حال حاظر آخرین نسخست و می‌تونید به حجم 200 مگا بایت اون رو از این پیوند دریافت کنید.
  • یک برنامه برای باز کردن فایل‌های tar. اگر نمی‌شناسین باید بگم که تقریبن تمام برنامه‌هایی که فایل رو فشرده می‌کنن می‌تونن این مدل آرشیو رو باز کنن. می‌تونید از اینجا برنامه‌ی رایگان و متن باز 7-Zip رو دریافت کنید.

برای شروع، اول راه اندازی توی Windows رو توضیح می‌دم:

  • اول رسانه‌ی حافظه رو که به عنوان مثال USB Flash شماست رو به کامپیوتر متصل کنید و در صورت لزوم منتظر بمونید تا نصب شه. به عنوان مثال یک درایو به نام F: به کامپیوتر شما اضافه می‌شه.
  • برنامه‌ی 7-Zip رو باز کنید (یا برنامه‌ی فشرده ساز خودتون رو) و فایل slax-6.1.2.tar رو باز کنید. (برای 7-Zip می‌تونید از قسمت مدیریت فایل که مرکز صفحست استفاده کنید).
  • فایل رو Extract کنید به درایو USB Flash که برای مثال ما آدرس F:\ خواهد بود.
  • به درایو مورد نظر برین (برای مثال ما، درایو F:) و بعد پوشه‌ی boot.
  • توی اون پوشه، فایل bootinst.bat رو باز کنید. دقت کنید که با نام bootinst دو تا فایل وجود داره، ما به فایلی نیاز داریم که در انتهاش نوشته شده باشه .bat یا این که چیزی نوشته نشده باشه.
  • یک صفحه‌ی مشکی نشون داده می‌شه که توضیحاتی در مورد نصبه:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
                         Welcome to Slax boot installer
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  
This installer will setup disk F: to boot only Slax.
  
Warning! Master Boot Record (MBR) of the device F: will be overwritten.
If F: is a partition on the same disk drive like your Windows installation,
then your Windows will not boot anymore. Be careful!
  
Press any key to continue, or kill this window [x] to abort…

  • بعد از خوندن توضیحات می‌تونید یک کلید رو از روی صفحه‌کلید فشار بدین تا نصب انجام بشه.

Setting up boot record for F:, wait please…
Disk F: should be bootable now. Installation finished.
  
Read the information above and then press any key to exit…

  • اگر ماژول خاصی رو هم دریافت کردین، می‌تونید اون رو به پوشه‌ی F:\slax\modules انتقال بدین.
  • کار تمومه. کافیه کامپیوتر رو Restart کنید و بهش بگین که می‌خواین سیستم‌عامل از روی حافظه‌های خارجی بارگذاری بشه. معمولاً وقتی که کامپیوتر روشن می‌شه می‌تونید از کلید F12 استفاده کنید یا از کلیدی که خود سیستم به شما معرفی می‌کنه توی همون صفحه‌ی ابتدایی استفاده کنید. در نهایت می‌تونید با زدن Delete یا F1 وارد تنظیمات Bios بشین و اولویت Boot رو برای دستگاه‌های خارجی یا USB ها بالا ببرین تا ابتدا برای بارگذاری سیستم، Bios سراغ رسانه‌های خارجی بره.
  • کار تمومه! خسته نباشین. صفحه‌ی سبز و سفید Slax جلوی روی شماست.

اما کاربرای گنو/لینوکس چکار باید کنن؟ خیلی با مراحل بالا تفاوتی وجود نداره الا این که هر مرحله به جای برنامه‌ها و آدرس‌های ویندوزی، از معادل گنو/لینوکسی اون استفاده کنن.

  • برای فایل tar در تقریبن تمام گنو/لینوکس‌ها ابزار گرافیکی و در تمام اونها ابزار خط فرمانی tar وجود داره و نیازی به 7-Zip نیست.
  • در پوشه‌ی boot باید Script نصب که bootinst.sh هست رو با مجوز کاربر ریشه اجرا کرد.

اما بذارین از قابلیت‌ها و امکاناتی که می‌تونید با Slax داشته باشین بگم.

شاید جذاب ترین قابلیتی که یه Slax می‌تونه برای یه دانشجوی نرم‌افزار داشته باشه، داشتن یک Compiler به روز وقوی GCC برای Compile کردن برنامه‌هایی که به زبون C++ استاندارد نوشته می‌شه، باشه. من ترم 2 برای پروژه‌ی C++ برنامه‌ای که نوشتم، تمام و کمال با ابزار‌های Slax بود (از جمله ویرایشگر متن قوی kate) و برای ارائه هم، متن برنامه و فایل اجرایی اون رو، روی میزکار یه Slax گذاشتم و از اون با ابزاری که توی پوشه‌ی slax به نام make_iso هست، یک CD زنده درست کردم و به استاد دادم. با این کار هم نمره‌ی خودم رو گرفتم و گنو/لینوکس رو ترویج دادم!

این که شما می‌تونید به راحتی برنامه به Slax اضافه کنید و یک مجموعه‌ی بزرگ از نرم‌افزارها رو داشته باشین، شاید یک امکان بسیار خوب برای هر کاربر و نه تنها یک دانشجوی نرم‌افزاره. می‌تونید ماژول‌های Slax رو از این آدرس دریافت کنید.

یکی از قابلیت‌های جالب Slax امکانیه به نام PXE که هنگام بارگذاری سیستم‌عامل می‌شه با نام «Slax as PXE server» اون رو استفاده کرد. اگر بخوام به زبون ساده این امکان رو شرح بدم، اینه که اگر این قابلیت رو توی یک شبکه استفاده کنید، می‌تونید بدون هیچ رسانه‌ای و فقط از طریق شبکه، یک سیستم دیگه‌ای رو با Slax بارگذاری کنید. شاید بار‌ها مثل من براتون سوال پیش اومده باشه که Boot From Network رو چطور می‌شه به کار برد. جواب همین قابلیته.

یکی دیگه از قابلیت‌های Slax انعطاف پذیر بودن اونه. یعنی بدون این که از برنامه نویسی دانشی داشته باشین، می‌تونید Slax رو برای خودتون تغییر بدین. به عنوان مثال پوشه‌ی rootcopy که توی پوشه‌ی slax وجود داره یک نمونه از این انعطاف پذیریه. وقتی سیستم بارگذاری می‌شه، فایل‌های این پوشه به پوشه‌ی ریشه (/) کپی‌میشن. به عنوان مثال اگر توی همین rootcopy یه پوشه با نام Desktop درست کنیم و توی Desktop یک فایل به نام saar.txt داشته باشیم، وقتی سیستم‌عامل بارگذاری می‌شه، روی میز‌کار فایل saar.txt وجود خواهد داشت. برای پروژه‌ی ترم 2 که قبل از این گفتم، من متن و فایل اجرایی پروژه رو به این پوشه انتقال دادم تا وقتی سیستم‌عامل بارگذاری می‌شه روی میز کار باشه این فایل‌ها.

و در نهایت برای آموزش فوق‌العادست. شما هر بلایی که دلت خواست سر این Slax بیار. بعد وقت بارگذاری اون، گزینه‌ی «Slax Always Fresh» رو بزن. به همین راحتی یه Slax تازه دم دست شماست!

و در نهایت بگم این رو که باید Slax رو امتحان کرد تا از امکاناتش و حتی به قول خود Slax از Cheat Codes هاش آگاه شد. Slax رو حتی می‌شه روی Hard دیسک نصب کرد (چیزی که من پیشنهاد نمی‌کنم) و از اون روی Hard Disk استفاده کرد. ساختار Slax ساختار مناسبیه برای کسانی که می‌خوان روی تولید یک سیستم‌عامل وقت بذارن و می‌تونه منبع اطلاعاتی خوبی برای اون‌ها باشه.


پ.ن: امیدوارم تونسته باشم جواب این دیدگاه رو بدم.

به‌روز رسانی:

من نمی‌دونستم که قبل از این هم در مورد Slax نوشتم.





تبدیل فایل‌های اجرایی جاوا به فایل‌های اجرایی محلی سیستم‌عامل

24 02 2010

مدت زیادیه که مشغله‌ی زیادی دارم و خیلی کم‌تر می‌تونم به «سار» برسم. اما بهونه‌ی این پست کامنت دوستم، علی، در مورد تبدیل فایل «JAR» به فایل اجرایی ویندوز «EXE» است:

… یکی از دوستام روانی ساختن فایل exe برای نرم افزارهای جاوایی که درست می‌کنه. وقتی دقت کردم دیدم چیچک رو اینجوری ساختی. اگه می‌شه درمورد ساختن فایل‌های stand alone با پسوند exe برای ویندوز من و در واقع دوستم رو راهنمایی کن.

خب من در این مورد کتاب «Core Java: Volume I-Fundamentals» توی صفحه‌ی «497» مطلبی رو نوشته بود که به نظر مفید میاد:

However, a Java program in a JAR file does not have the same feel as a native application. On Windows, you can use third-party wrapper utilities that turn JAR files into Windows executables. A wrapper is a Windows program with the familiar .exe extension that locates and launches the Java virtual machine (JVM), or tells the user what to do when no JVM is found. There are a number of commercial and open source products, such as JSmooth ( http://jsmooth.sourceforge.net) and Launch4J (http://launch4j.sourceforge.net). The open source installer generator IzPack (http://izpack.org) also contains a native launcher. For more information on this topic, see http://www.javalobby.org/articles/java2exe.

برای «چیچک» من از «JSmooth» استفاده کردم. کار کردن باهاش آسون بود و به مشکلی هم بر نخوردم. ولی با این همه علاوه بر نمونه‌هایی که توی متن بالا هست، چند مورد دیگه هم وجود داره:

    • نمونه‌های تجاری
    1. JEXECreator
    2. exe4J
    3. NativeJ
    4. execJava
    5. Executor
    6. JExePack
    7. Jlaunch
    • نمونه‌های رایگان و متن باز
    1. JSmooth
    2. Launch4j
    3. jstart32
    4. exeJ
    5. Janel
    6. jstart
    7. Roxes Ant Tasks
    8. Marner Java Launcher
    9. jelude

    امیدوارم تونسته باشم جواب سوال رو داده باشم.





    نرم‌افزار‌های غیر آزاد من

    24 12 2009

    روزبه عزیز، تقریبن اواخر شهریور ماه، من رو به یه کار جمعی دعوت کرده تا به قول خودش:

    در آستانه جشن روز آزادی نرم افزار ( شنبه هفته آینده در تمام نقاط دنیا و امروز در اصفهان ) مثل سال گدشته وبلاگ نویسان لینوکسی نویس را به این حرکت دعوت می کنم ! کاری که پارسال هم آنرا انجام دادیم و نسبتا هم با استقبال خوبی مواجه شد . حالا این حرکت ( من اسمش رو می ذارم “جنبش” ) بدین صورت است که : با نصب پکیج vrms هرکسی می تواند پکیج های غیرآزاد (Non-free) را بر روی سیستمش جستجو می کند و نتیجه آن را بر روی وبلاگش منتشر می کند و سعی می کند جایگزین مناسبی برای این پکیج های غیر آزاد پیدا کند .

    البته با عرض تاسف، من اون روز‌ها با یک مشکل دست و پنجره نرم می‌کردم و مشکلم اونقدر بزرگ بود (و هست البته) که خیلی خیلی از دنیای مجازیم فاصله گرفتم. با این همه، امروز که این رو دیدم، دعوتش رو قبول می‌کنم و کاری که گفته رو انجام می‌دم.


                Non-free packages installed on ramin-laptop
      
    opera                     The Opera Web Browser
    rar                       Archiver for .rar files
    sl-modem-daemon           SmartLink software modem daemon
    sun-java6-bin             Sun Java(TM) Runtime Environment (JRE) 6 (architecture
    sun-java6-jdk             Sun Java(TM) Development Kit (JDK) 6
    sun-java6-jre             Sun Java(TM) Runtime Environment (JRE) 6 (architecture
    xmind                     XMind - Brainstorming and Mind Mapping
      
                Contrib packages installed on ramin-laptop
      
    nvidia-common             Find obsolete NVIDIA drivers
      
    Contrib packages with status other than installed on ramin-laptop
      
    flashplugin-installer     ( dei)  Adobe Flash Player plugin installer
      
      7 non-free packages, 0.5% of 1508 installed packages.
      2 contrib packages, 0.1% of 1508 installed packages.

    اما این رو هم اضافه کنم که از این بسته‌هایی که روی سیستمم دارم، شاید خیلیهاشون نسخه‌ی متن باز دارن و البته نسخه‌ی متن بازشون رو هم نصب شده دارم.

    خب از اونجا که از این حرکت خیلی وقته که می‌گذره و احتمالن همه‌ی دوستان این کار رو انجام دادن، من کسی رو دعوت نمی‌کنم. اگر کسی از قلم بقیه‌ی دوستان افتاده، بگه تا من دعوتش کنم :D





    چگونه از کامپایلر‌های متن باز در ویندوز استفاده کنیم

    8 09 2009

    بروز بودن یه برنامه نویس اول از همه نیازمند تلاش خود اون شخصه و در وحله‌ی بعد نیازمند بروز بودن امکانات اونه. چه چیزی بهتر از کامپایلر‌های متن باز و آزاد که هم به روز هستن و هم قوی و در نهایت رایگان.

    gccegg-65کمتر کسی از جامعه‌ی برنامه نویسی اسم gcc رو نشنیده. gcc کامپایلریه که نامش از سر‌کلمه‌های Gnu Compiler Collection گرفته شده و ریچارد استالمن در سال 1985 برای ترجمه‌ی برنامه‌های نوشته شده به زبون c اون شروع به ساخت کرد. (منبع، اطلاعات بیشتر، وب‌سایت پروژه)

    برای داشتن قدرت و امکانات gcc لزومی نداره که کاربر، سیستم‌عامل خاصی، به عنوان مثال gnu/linux یا gnu/hurd داشته باشه.
    توی این پست نحوه‌ی استفاده از GCC توی ویندوز رو توضیح می‌دم.

    قبل از هرچیز به MinGW نیاز داریم. که می‌تونیم از این لینک نسخه‌ی 5.1.4 اون رو دریافت کنید. حجم زیادی هم نداره و در حقیقت یه برنامه برای دانلود بسته‌های مورد نیاز هستش.

    • اون رو اجرا کنید.
    • پنجره‌ی خوشامد گویی رو با کلید Next جواب بدین.
    • اگر روی سیستمی که برنامه رو اجرا کردین می‌خواین برنامه رو نصب کنید که Download and Install رو انتخاب کنید و اگر می‌خواین فقط بسته‌ها رو دانلود کنید، Download only رو انتخاب کنید و کلید Next رو بزنید.
    • با پروانه‌ی استفاده و توزیع مجدد در صورتی که موافقت دارید، با زدن کلید I Agree موافقت کنید.
    • بذارین بسته‌های نسخه‌ی Current نصب شه. پس Next رو کلیک کنید.
    • کامپایلر‌هایی که نیاز دارین رو علامت دار کنید و با Next به صفحه‌ی بعد برین.
    • مکان نصب رو انتخاب کنید و Next رو کلیلک کنید.
    • در انتها هم با زدن کلید Install منتظر دانلود شدن (و احتمالا نصب) بسته‌ها باشید.

    خب تا اینجا که فقط نصب برنامه بود که خیلی آسون هم بود. اما یه کد نویس علاوه بر کامپایلر به محیط توسعه (IDE) هم نیاز داره. ما که همه چیز رو به صورت آزاد داشتیم، بد نیست از IDE های آزاد هم استفاده کنیم. برای کار‌های کوچیک Notepad++ برنامه‌ی خوبیه ولی من به Geany عادت کردم و اون رو هم به شما پیشنهاد می‌کنم.

    اما یه کار کوچولوی دیگه هم اگر انجام بدیم کارمون خیلی راحت تر می‌شه. من فرض رو بر این می‌ذارم که شما این MinGW رو توی درایو C ویندوز نصب کردین. اگر اینطور نیست توی توضیحات به جای این آدرس، محل نصب نرم‌افزار تو سیستمتون رو بذارین. این توضیحات برای ویندوز XP هستش و برای نسخه‌های دیگه‌ی ویندوز روال مشابهی طی می‌شه.

    • به Control Panel برین.
    • اگر گزینه‌ی Performanceand Maintenance رو می‌بینید (کنترل پانل به صورت Category view هست) رو بزنید.
    • System رو انتخاب کنید و اون رو باز کنید.
    • سربرگ Advanced رو انتخاب کنید.
    • از پایین پنجره کلید Environment Variables رو بزنید.
    • از لیست System variables دنبال Path بگردین و از پایین لیست Edit رو کلیک کنید.
    • متن زیر رو که آدرس پوشه‌ی bin نرم‌افزار MinGW نصب شدست رو به همراه یک سیمی‌کالن به ابتداری متن کادر Variable value اضافه کنید:
      C:\MinGW\bin;
    • تمام پنجره‌های باز رو با زدن کلید Ok ببندین.

    خب، از این به بعد می‌تونید بدون تایپ کردن آدرس از g++ و امکانات دیگه استفاده کنید.

    اما اگر Geany رو نصب کردین، از همون تو می‌تونید برنامه رو کامپایل کنید (F8) یا فایل اجرایی رو تولید کنید (F9) و یا برنامه رو اجرا کنید (F5). پس کد زیر رو توی اون کپی کنید، با نام hello.cpp سیو کنید و بعد F9 رو از روی صفحه‌کلید بزنید و بعد برای اجرای اون کلید F5 رو بزنید. به همین راحتی!
    #include<iostream>
    using namespace std;
    int main(int argc, char** argv){
        cout << "Hello MinGW!\tHello Geany!\n";
        return 0;
    }

    خب امیدوارم این پست براتون مفید باشه. بد نیست برنامه‌ی Cygwin رو هم تست کنید!
    محیط توسعه‌ی Netbeans هم خیلی آسون و سریع و قدرتمنه. بد نیست اون رو هم تست کنید.
    پ‌ن: این پست هم تقدیم به ایشون که بسیار با اراده و مصمم دارن برنامه نویسی رو یاد می‌گیرن.
    پ‌ن: یک نمونه‌ی کار بسیار عالی رو هم می‌تونید اینجا ببینید


    بروز رسانی

    توی نظرات بحث گرمی در گرفت. خیلی‌ها از جمله خود من با فایل w32api-3.13-mingw32-dev.tar.gz مشکل داشتن که ساسان عزیز یه راه حل خیلی خوب پیشنهاد داد. Mirror دانلود رو عوض کنید تا مشکل حل بشه!